@asymmetrik/janusgraph-manager
Version:
Janusgraph management tooling in NodeJS/Typescript
2 lines • 64 kB
JavaScript
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var r in i)("object"==typeof exports?exports:e)[r]=i[r]}}(this,(function(){return(()=>{"use strict";var e={389:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.EdgeBuilder=void 0,t.EdgeBuilder=class{constructor(e){this._label=e,this._multiplicity="MULTI",this._properties=[]}multiplicity(e){return this._multiplicity=e,this}property(e){return this._properties.some((t=>t.key===e.key))||this._properties.push(e),this}build(){let e=`if (!mgmt.containsEdgeLabel('${this._label}')) `;return e+=`mgmt.makeEdgeLabel('${this._label}')`,e+=null!=this._multiplicity?`.multiplicity(${this._multiplicity})`:"",e+=".make();",this._properties.length>0&&(e+="mgmt.addProperties(",e+=`mgmt.getEdgeLabel('${this._label}'), `,e+=[...this._properties].map((e=>`mgmt.getPropertyKey('${e.key}')`)).join(", "),e+=")"),e}}},480:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.EnableIndexBuilder=void 0,t.EnableIndexBuilder=class{constructor(e,t="graph"){this._name=e,this._graph=t,this._action="ENABLE_INDEX"}type(e){return this._type=e,this}label(e){return"VertexCentric"!==this._type&&console.warn(`Label ${e} set on EnableIndex builder. This only applies for VertexCentric indices.`),this._label=e,this}action(e){return this._action=e,this}build(){let e="mgmt.updateIndex(";if("VertexCentric"===this._type){if(null==this._label||""===this._label)throw Error(`Vertex Centric index '${this._name}' attempted to be enabled without a label definition.`);e+=`mgmt.getRelationIndex(mgmt.getEdgeLabel('${this._label}'), '${this._name}')`}else e+=`mgmt.getGraphIndex('${this._name}')`;return e+=`, SchemaAction.${this._action}).get();`,e}}},32:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.GraphIndexBuilder=void 0,t.GraphIndexBuilder=class{constructor(e,t){this._name=e,this._element=t,this._keys=[]}type(e){return this._type=e,this}key(e){return this._keys.some((t=>t.field===e.field))||this._keys.push(e),this}unique(e=!1){return this._unique=e,this}label(e){return this._label=e,this}backend(e){return this._backend=e,this}build(){if(0===this._keys.length)throw Error(`Unable to generate index ${this._name} with no key definitions.`);"Mixed"!==this._type&&null!=this._backend&&console.warn("Composite index type and non-null backend. Will ignore backend.");let e=`if (!mgmt.containsGraphIndex('${this._name}')) `;return e+=`mgmt.buildIndex('${this._name}', ${this._element}.class)`,e+=[...this._keys].map((e=>`.addKey(mgmt.getPropertyKey('${e.field}')${"Mixed"===this._type&&null!=e.mapping?`,Mapping.${e.mapping}.asParameter()`:""})`)).join(""),e+=this._unique?".unique()":"",e+=null!=this._label?`.indexOnly(mgmt.get${this._element}Label('${this._label}'))`:"",e.concat("Mixed"===this._type?`.buildMixedIndex('${this._backend??"search"}');`:".buildCompositeIndex();")}}},638:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.PropertyBuilder=void 0,t.PropertyBuilder=class{constructor(e){this._key=e,this._cardinality="SINGLE"}cardinality(e){return this._cardinality=e,this}datatype(e){return this._datatype=e,this}build(){let e=`if (!mgmt.containsPropertyKey('${this._key}')) `;return e+=`mgmt.makePropertyKey('${this._key}')`,e+=null!=this._datatype?`.dataType(${this._datatype}.class)`:"",e+=null!=this._cardinality?`.cardinality(org.janusgraph.core.Cardinality.${this._cardinality})`:"",e.concat(".make();")}}},513:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.VertexBuilder=void 0,t.VertexBuilder=class{constructor(e){this._label=e,this._properties=[]}property(e){return this._properties.some((t=>t.key===e.key))||this._properties.push(e),this}build(){let e=`if (!mgmt.containsVertexLabel('${this._label}')) `;return e+=`mgmt.makeVertexLabel('${this._label}')`,e+=".make();",this._properties.length>0&&(e+="mgmt.addProperties(",e+=`mgmt.getVertexLabel('${this._label}'), `,e+=[...this._properties].map((e=>`mgmt.getPropertyKey('${e.key}')`)).join(", "),e+=")"),e}}},779:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.VertexCentricIndexBuilder=void 0,t.VertexCentricIndexBuilder=class{constructor(e){this._name=e,this._keys=new Set,this._order="asc"}edgelabel(e){return this._edgelabel=e,this}direction(e){return this._direction=e,this}order(e){return this._order=e,this}key(e){return this._keys.add(e),this}build(){if(0===this._keys.size)throw Error(`Unable to generate vc index ${this._name} with no key definitions.`);if(null==this._direction)throw Error(`Unable to generate vc index ${this._name} with no directionality.`);if(null==this._edgelabel||""===this._edgelabel)throw Error(`Unable to generate vc index ${this._name} with no edge label.`);let e=`if (!mgmt.containsRelationIndex(mgmt.getEdgeLabel('${this._edgelabel}'), '${this._name}')) `;return e+="mgmt.buildEdgeIndex(",e+=`mgmt.getEdgeLabel('${this._edgelabel}'), `,e+=`'${this._name}', `,e+=`Direction.${this._direction}, `,e+=`Order.${this._order}, `,e+=[...this._keys].map((e=>`mgmt.getPropertyKey('${e}')`)).join(", "),e.concat(");0;")}}},915:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.WaitForIndexBuilder=void 0,t.WaitForIndexBuilder=class{constructor(e,t="graph"){this.name=e,this.graph=t}build(){return`ManagementSystem.awaitGraphIndexStatus(${this.graph}, '${this.name}').status(SchemaStatus.ENABLED, SchemaStatus.REGISTERED).call().toString()`}}},463:function(e,t,i){var r=this&&this.__createBinding||(Object.create?function(e,t,i,r){void 0===r&&(r=i),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,r){void 0===r&&(r=i),e[r]=t[i]}),a=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||r(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),a(i(389),t),a(i(480),t),a(i(32),t),a(i(638),t),a(i(915),t),a(i(513),t),a(i(779),t)}},t={};function i(r){var a=t[r];if(void 0!==a)return a.exports;var n=t[r]={exports:{}};return e[r].call(n.exports,n,n.exports,i),n.exports}var r={};return(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.JanusGraphManager=void 0;const t=i(463);e.JanusGraphManager=class{constructor(e,t){this.client=e,this.options=t,this.state="NEW",this.OPEN_MGMT=`mgmt = ${this.options.graphName}.openManagement();0;`,null==t.graphName&&(this.options.graphName="graph"),null==t.useConfiguredGraphFactory&&(this.options.useConfiguredGraphFactory=!1)}async init(){try{return"READY"!==this.state&&(await this.client.submit(`${this.options.graphName}.tx().rollback();`),this.options.useConfiguredGraphFactory?await this.client.submit(`${this.options.graphName} = ConfiguredGraphFactory.open('${this.options.graphName}');0;`):null!=this.options.configPath&&await this.client.submit(`${this.options.graphName} = JanusGraphFactory.open('${this.options.configPath}');0;`),await this.client.submit(this.OPEN_MGMT),this.state="READY"),Promise.resolve(this.state)}catch(e){return this.state="ERROR",Promise.reject(e)}}async createGraphIndex(e,i=!1){await this.init();const r=new t.GraphIndexBuilder(e.name,e.element??"Vertex");r.label(e.label).type(e.type).unique(e.unique).backend(e.backend),e.keys.forEach((e=>r.key(e)));try{return await this.client.submit(r.build()),i&&await this.commit(),Promise.resolve(1)}catch(e){return Promise.reject(e)}}async createVertexCentricIndex(e,i=!1){const r=new t.VertexCentricIndexBuilder(e.name);r.direction(e.direction).edgelabel(e.edgelabel).order(e.order),e.keys.forEach((e=>r.key(e)));try{return await this.init(),await this.client.submit(r.build()),i&&await this.commit(),Promise.resolve(1)}catch(e){return Promise.reject(e)}}async waitForIndices(e,t){try{return await this.init(),(await Promise.all([...e.graphIndices,...e.vcIndices].map((e=>this.waitForIndex(e,t))))).length}catch(e){return Promise.reject(e)}}async waitForIndex(e,i){const r=new t.WaitForIndexBuilder(e.name,i);try{return await this.init(),await this.client.submit(r.build()),Promise.resolve(1)}catch(e){return Promise.reject(e)}}async createIndices(e,t=!1){try{await this.init();let i=0;return i+=(await Promise.all(e.graphIndices.map((e=>this.createGraphIndex(e))))).length,i+=(await Promise.all(e.vcIndices.map((e=>this.createVertexCentricIndex(e))))).length,t&&await this.commit(),Promise.resolve(i)}catch(e){return Promise.reject(e)}}async enableIndices(e,i=!1){try{await this.init();const r=e.graphIndices.map((i=>new t.EnableIndexBuilder(i.name,e.name).action("ENABLE_INDEX").build())),a=e.vcIndices.map((i=>new t.EnableIndexBuilder(i.name,e.name).type("VertexCentric").label(i.edgelabel).action("ENABLE_INDEX").build())),n=(await Promise.all([...r,...a].map((async e=>await this.client.submit(e))))).length;return i&&await this.commit(),Promise.resolve(n)}catch(e){return Promise.reject(e)}}async reindexIndices(e,i=!1){try{await this.init();const r=e.graphIndices.map((i=>new t.EnableIndexBuilder(i.name,e.name).action("REINDEX").build())),a=e.vcIndices.map((i=>new t.EnableIndexBuilder(i.name,e.name).type("VertexCentric").label(i.edgelabel).action("REINDEX").build())),n=(await Promise.all([...r,...a].map((async e=>await this.client.submit(e))))).length;return i&&await this.commit(),Promise.resolve(n)}catch(e){return Promise.reject(e)}}async reindex(e,i,r=!1){try{await this.init();const a=new t.EnableIndexBuilder(i.name,e);null!=i.edgelabel&&a.type("VertexCentric").label(i.edgelabel);const n=a.action("REINDEX").build(),s=await this.client.submit(n);return r&&await this.commit(),Promise.resolve(s)}catch(e){return Promise.reject(e)}}async createSchema(e,i=!1){try{await this.init();let r=0;return r+=(await Promise.all([...e.vertices,...e.edges].flatMap((e=>e.properties)).map((e=>new t.PropertyBuilder(e.key).datatype(e.datatype).cardinality(e.cardinality).build())).map((async e=>await this.client.submit(e))))).length,r+=(await Promise.all(e.vertices.map((e=>{const i=new t.VertexBuilder(e.label);return e.properties.forEach((e=>i.property(e))),i.build()})).map((async e=>await this.client.submit(e))))).length,r+=(await Promise.all(e.edges.map((e=>{const i=new t.EdgeBuilder(e.label);return e.properties.forEach((e=>i.property(e))),i.build()})).map((async e=>await this.client.submit(e))))).length,i&&(await this.commit(),r+=await this.createIndices(e,!0)),Promise.resolve(r)}catch(e){return Promise.reject(e)}}async getIndices(){try{await this.init();const e=await this.client.submit("mgmt.getGraphIndexes(Vertex.class)"),t=await this.client.submit("mgmt.getGraphIndexes(Edge.class)");return Promise.resolve([e._items,t._items])}catch(e){return Promise.reject(e)}}async printSchema(){try{await this.init();const e=await this.client.submit("mgmt.printSchema()");return Promise.resolve(e._items)}catch(e){return Promise.reject(e)}}async commit(e){try{await this.init();const t=await this.client.submit(`${e??""};mgmt.commit();`);return this.state="COMMIT",t}catch(e){return this.state="ERROR",Promise.reject(e)}}async close(){try{if(["CLOSED","ERROR"].some((e=>e===this.state)))return;const e=await this.client.close();return this.state="CLOSED",e}catch(e){return this.state="ERROR",Promise.reject(e)}}}})(),r})()}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYXN5bW1ldHJpay9qYW51c2dyYXBoLW1hbmFnZXIvd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL0Bhc3ltbWV0cmlrL2phbnVzZ3JhcGgtbWFuYWdlci8uL3NyYy9idWlsZGVycy9FZGdlQnVpbGRlci50cyIsIndlYnBhY2s6Ly9AYXN5bW1ldHJpay9qYW51c2dyYXBoLW1hbmFnZXIvLi9zcmMvYnVpbGRlcnMvRW5hYmxlSW5kZXhCdWlsZGVyLnRzIiwid2VicGFjazovL0Bhc3ltbWV0cmlrL2phbnVzZ3JhcGgtbWFuYWdlci8uL3NyYy9idWlsZGVycy9HcmFwaEluZGV4QnVpbGRlci50cyIsIndlYnBhY2s6Ly9AYXN5bW1ldHJpay9qYW51c2dyYXBoLW1hbmFnZXIvLi9zcmMvYnVpbGRlcnMvUHJvcGVydHlCdWlsZGVyLnRzIiwid2VicGFjazovL0Bhc3ltbWV0cmlrL2phbnVzZ3JhcGgtbWFuYWdlci8uL3NyYy9idWlsZGVycy9WZXJ0ZXhCdWlsZGVyLnRzIiwid2VicGFjazovL0Bhc3ltbWV0cmlrL2phbnVzZ3JhcGgtbWFuYWdlci8uL3NyYy9idWlsZGVycy9WZXJ0ZXhDZW50cmljSW5kZXhCdWlsZGVyLnRzIiwid2VicGFjazovL0Bhc3ltbWV0cmlrL2phbnVzZ3JhcGgtbWFuYWdlci8uL3NyYy9idWlsZGVycy9XYWl0Rm9ySW5kZXhCdWlsZGVyLnRzIiwid2VicGFjazovL0Bhc3ltbWV0cmlrL2phbnVzZ3JhcGgtbWFuYWdlci8uL3NyYy9idWlsZGVycy9pbmRleC50cyIsIndlYnBhY2s6Ly9AYXN5bW1ldHJpay9qYW51c2dyYXBoLW1hbmFnZXIvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vQGFzeW1tZXRyaWsvamFudXNncmFwaC1tYW5hZ2VyLy4vc3JjL0phbnVzR3JhcGhNYW5hZ2VyLnRzIl0sIm5hbWVzIjpbInJvb3QiLCJmYWN0b3J5IiwiZXhwb3J0cyIsIm1vZHVsZSIsImRlZmluZSIsImFtZCIsImEiLCJpIiwidGhpcyIsIl9sYWJlbCIsIl9tdWx0aXBsaWNpdHkiLCJfcHJvcGVydGllcyIsIm11bHRpcGxpY2l0eSIsInByb3BlcnR5Iiwic29tZSIsInAiLCJrZXkiLCJwdXNoIiwib3V0cHV0IiwibGVuZ3RoIiwibWFwIiwicHJvcCIsImpvaW4iLCJfbmFtZSIsIl9ncmFwaCIsIl9hY3Rpb24iLCJ0eXBlIiwiX3R5cGUiLCJsYWJlbCIsImNvbnNvbGUiLCJ3YXJuIiwiYWN0aW9uIiwiRXJyb3IiLCJfZWxlbWVudCIsIl9rZXlzIiwiayIsImZpZWxkIiwidW5pcXVlIiwiX3VuaXF1ZSIsImJhY2tlbmQiLCJfYmFja2VuZCIsIm1hcHBpbmciLCJjb25jYXQiLCJfa2V5IiwiX2NhcmRpbmFsaXR5IiwiY2FyZGluYWxpdHkiLCJkYXRhdHlwZSIsIl9kYXRhdHlwZSIsIlNldCIsIl9vcmRlciIsImVkZ2VsYWJlbCIsIl9lZGdlbGFiZWwiLCJkaXJlY3Rpb24iLCJfZGlyZWN0aW9uIiwib3JkZXIiLCJhZGQiLCJzaXplIiwibmFtZSIsImdyYXBoIiwiX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fIiwiX193ZWJwYWNrX3JlcXVpcmVfXyIsIm1vZHVsZUlkIiwiY2FjaGVkTW9kdWxlIiwidW5kZWZpbmVkIiwiX193ZWJwYWNrX21vZHVsZXNfXyIsImNhbGwiLCJjbGllbnQiLCJvcHRpb25zIiwic3RhdGUiLCJPUEVOX01HTVQiLCJncmFwaE5hbWUiLCJ1c2VDb25maWd1cmVkR3JhcGhGYWN0b3J5Iiwic3VibWl0IiwiY29uZmlnUGF0aCIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXJyIiwicmVqZWN0IiwiaW5kZXgiLCJjb21taXQiLCJpbml0IiwiYnVpbGRlciIsIkdyYXBoSW5kZXhCdWlsZGVyIiwiZWxlbWVudCIsImtleXMiLCJmb3JFYWNoIiwiYnVpbGQiLCJWZXJ0ZXhDZW50cmljSW5kZXhCdWlsZGVyIiwic2NoZW1hIiwiYWxsIiwiZ3JhcGhJbmRpY2VzIiwidmNJbmRpY2VzIiwid2FpdEZvckluZGV4IiwiV2FpdEZvckluZGV4QnVpbGRlciIsImNvdW50IiwiY3JlYXRlR3JhcGhJbmRleCIsImNyZWF0ZVZlcnRleENlbnRyaWNJbmRleCIsImdpIiwiRW5hYmxlSW5kZXhCdWlsZGVyIiwidmNpIiwiYXN5bmMiLCJtc2ciLCJncmFwaG5hbWUiLCJpbmRpY2VzIiwidmVydGljZXMiLCJlZGdlcyIsImZsYXRNYXAiLCJ2IiwicHJvcGVydGllcyIsIlByb3BlcnR5QnVpbGRlciIsIlZlcnRleEJ1aWxkZXIiLCJlIiwiRWRnZUJ1aWxkZXIiLCJjcmVhdGVJbmRpY2VzIiwidmluZGljZXMiLCJlaW5kaWNlcyIsIl9pdGVtcyIsImRhdGEiLCJtZXNzYWdlIiwicyIsImNsb3NlIl0sIm1hcHBpbmdzIjoiQ0FBQSxTQUEyQ0EsRUFBTUMsR0FDaEQsR0FBc0IsaUJBQVpDLFNBQTBDLGlCQUFYQyxPQUN4Q0EsT0FBT0QsUUFBVUQsU0FDYixHQUFxQixtQkFBWEcsUUFBeUJBLE9BQU9DLElBQzlDRCxPQUFPLEdBQUlILE9BQ1AsQ0FDSixJQUFJSyxFQUFJTCxJQUNSLElBQUksSUFBSU0sS0FBS0QsR0FBdUIsaUJBQVpKLFFBQXVCQSxRQUFVRixHQUFNTyxHQUFLRCxFQUFFQyxJQVB4RSxDQVNHQyxNQUFNLFdBQ1QsTSw0R0NOQSxvQkFJSSxZQUFvQkMsR0FBQSxLQUFBQSxTQUhaLEtBQUFDLGNBQWtDLFFBQ2xDLEtBQUFDLFlBQTBCLEdBSWxDLGFBQWFDLEdBRVQsT0FEQUosS0FBS0UsY0FBZ0JFLEVBQ2RKLEtBR1gsU0FBU0ssR0FDTCxPQUFJTCxLQUFLRyxZQUFZRyxNQUFNQyxHQUFNQSxFQUFFQyxNQUFRSCxFQUFTRyxPQUNwRFIsS0FBS0csWUFBWU0sS0FBS0osR0FEMkNMLEtBS3JFLFFBQ0ksSUFBSVUsRUFBUyxnQ0FBZ0NWLEtBQUtDLGFBZWxELE9BZEFTLEdBQVUsdUJBQXVCVixLQUFLQyxXQUN0Q1MsR0FDMEIsTUFBdEJWLEtBQUtFLGNBQ0MsaUJBQWlCRixLQUFLRSxpQkFDdEIsR0FD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Y0FBY3pCLEdBQVEsSUFFdkNkLFFBQVFDLFFBQVFtQixHQUN6QixNQUFPbEIsR0FDTCxPQUFPRixRQUFRRyxPQUFPRCxJQVE5QixtQkFDSSxVQUNVcEUsS0FBS3dFLE9BQ1gsTUFBTWtDLFFBQWlCMUcsS0FBSzBELE9BQU9NLE9BQy9CLHNDQUVFMkMsUUFBaUIzRyxLQUFLMEQsT0FBT00sT0FDL0Isb0NBRUosT0FBT0UsUUFBUUMsUUFBUSxDQUFDdUMsRUFBU0UsT0FBUUQsRUFBU0MsU0FDcEQsTUFBT3hDLEdBQ0wsT0FBT0YsUUFBUUcsT0FBT0QsSUFROUIsb0JBQ0ksVUFDVXBFLEtBQUt3RSxPQUNYLE1BQU1xQyxRQUFhN0csS0FBSzBELE9BQU9NLE9BQU8sc0JBQ3RDLE9BQU9FLFFBQVFDLFFBQVEwQyxFQUFLRCxRQUM5QixNQUFPeEMsR0FDTCxPQUFPRixRQUFRRyxPQUFPRCxJQVM5QixhQUFhMEMsR0FDVCxVQUNVOUcsS0FBS3dFLE9BQ1gsTUFBTUQsUUFBZXZFLEtBQUswRCxPQUFPTSxPQUM3QixHQUFHOEMsR0FBVyxxQkFHbEIsT0FEQTlHLEtBQUs0RCxNQUFRLFNBQ05XLEVBQ1QsTUFBT0gsR0FFTCxPQURBcEUsS0FBSzRELE1BQVEsUUFDTk0sUUFBUUcsT0FBT0QsSUFROUIsY0FDSSxJQUNJLEdBQUksQ0FBQyxTQUFVLFNBQVM5RCxNQUFNeUcsR0FBTUEsSUFBTS9HLEtBQUs0RCxRQUFRLE9BQ3ZELE1BQU1vRCxRQUFjaEgsS0FBSzBELE9BQU9zRCxRQUVoQyxPQURBaEgsS0FBSzRELE1BQVEsU0FDTm9ELEVBQ1QsTUFBTzVDLEdBRUwsT0FEQXBFLEtBQUs0RCxNQUFRLFFBQ05NLFFBQVFHLE9BQU9ELE8iLCJmaWxlIjoiaW5kZXgubWluLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIHtcblx0XHR2YXIgYSA9IGZhY3RvcnkoKTtcblx0XHRmb3IodmFyIGkgaW4gYSkgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyA/IGV4cG9ydHMgOiByb290KVtpXSA9IGFbaV07XG5cdH1cbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xucmV0dXJuICIsImltcG9ydCB7IEJ1aWxkZXIgfSBmcm9tICcuL0J1aWxkZXIuaW50ZXJmYWNlJztcbmltcG9ydCB7IEVkZ2VNdWx0aXBsaWNpdHkgfSBmcm9tICcuLi90eXBlcy9FZGdlJztcbmltcG9ydCB7IFByb3BlcnR5IH0gZnJvbSAnLi4vdHlwZXMvUHJvcGVydHknO1xuXG5leHBvcnQgY2xhc3MgRWRnZUJ1aWxkZXIgaW1wbGVtZW50cyBCdWlsZGVyPHN0cmluZz4ge1xuICAgIHByaXZhdGUgX211bHRpcGxpY2l0eTogRWRnZU11bHRpcGxpY2l0eSA9ICdNVUxUSSc7XG4gICAgcHJpdmF0ZSBfcHJvcGVydGllczogUHJvcGVydHlbXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfbGFiZWw6IHN0cmluZykge31cblxuICAgIG11bHRpcGxpY2l0eShtdWx0aXBsaWNpdHk6IEVkZ2VNdWx0aXBsaWNpdHkpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fbXVsdGlwbGljaXR5ID0gbXVsdGlwbGljaXR5O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBwcm9wZXJ0eShwcm9wZXJ0eTogUHJvcGVydHkpOiB0aGlzIHtcbiAgICAgICAgaWYgKHRoaXMuX3Byb3BlcnRpZXMuc29tZSgocCkgPT4gcC5rZXkgPT09IHByb3BlcnR5LmtleSkpIHJldHVybiB0aGlzO1xuICAgICAgICB0aGlzLl9wcm9wZXJ0aWVzLnB1c2gocHJvcGVydHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBidWlsZCgpOiBzdHJpbmcge1xuICAgICAgICBsZXQgb3V0cHV0ID0gYGlmICghbWdtdC5jb250YWluc0VkZ2VMYWJlbCgnJHt0aGlzLl9sYWJlbH0nKSkgYDtcbiAgICAgICAgb3V0cHV0ICs9IGBtZ210Lm1ha2VFZGdlTGFiZWwoJyR7dGhpcy5fbGFiZWx9JylgO1xuICAgICAgICBvdXRwdXQgKz1cbiAgICAgICAgICAgIHRoaXMuX211bHRpcGxpY2l0eSAhPSBudWxsXG4gICAgICAgICAgICAgICAgPyBgLm11bHRpcGxpY2l0eSgke3RoaXMuX211bHRpcGxpY2l0eX0pYFxuICAgICAgICAgICAgICAgIDogJyc7XG4gICAgICAgIG91dHB1dCArPSAnLm1ha2UoKTsnO1xuICAgICAgICBpZiAodGhpcy5fcHJvcGVydGllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBvdXRwdXQgKz0gJ21nbXQuYWRkUHJvcGVydGllcygnO1xuICAgICAgICAgICAgb3V0cHV0ICs9IGBtZ210LmdldEVkZ2VMYWJlbCgnJHt0aGlzLl9sYWJlbH0nKSwgYDtcbiAgICAgICAgICAgIG91dHB1dCArPSBbLi4udGhpcy5fcHJvcGVydGllc11cbiAgICAgICAgICAgICAgICAubWFwKChwcm9wKSA9PiBgbWdtdC5nZXRQcm9wZXJ0eUtleSgnJHtwcm9wLmtleX0nKWApXG4gICAgICAgICAgICAgICAgLmpvaW4oJywgJyk7XG4gICAgICAgICAgICBvdXRwdXQgKz0gJyknO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgSW5kZXhUeXBlIH0gZnJvbSAnLi4vdHlwZXMvR3JhcGhJbmRleCc7XG5pbXBvcnQgeyBCdWlsZGVyIH0gZnJvbSAnLi9CdWlsZGVyLmludGVyZmFjZSc7XG5cbmV4cG9ydCB0eXBlIFNjaGVtYUFjdGlvbiA9ICdFTkFCTEVfSU5ERVgnIHwgJ1JFSU5ERVgnO1xuXG4vKipcbiAqIEJ1aWxkcyBhIG1hbmFnZW1lbnQgc3RyaW5nIHRoYXQgYXR0ZW1wdHMgdG8gZW5hYmxlIGEgc3BlY2lmaWMgaW5kZXguXG4gKi9cbmV4cG9ydCBjbGFzcyBFbmFibGVJbmRleEJ1aWxkZXIgaW1wbGVtZW50cyBCdWlsZGVyPHN0cmluZz4ge1xuICAgIHByaXZhdGUgX3R5cGUhOiBJbmRleFR5cGU7XG4gICAgcHJpdmF0ZSBfbGFiZWwhOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBfYWN0aW9uOiBTY2hlbWFBY3Rpb24gPSAnRU5BQkxFX0lOREVYJztcblxuICAgIC8qKlxuICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuXG4gICAgICogQHBhcmFtIF9uYW1lIEluZGV4IHRvIGF0dGVtcHQgdG8gZW5hYmxlLlxuICAgICAqIEBwYXJhbSBfZ3JhcGggR3JhcGggbmFtZSB0aGF0IHRoZSBpbmRleCByZXNpZGVzIG9uLiBEZWZhdWx0IGBncmFwaGAuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfbmFtZTogc3RyaW5nLCBwcml2YXRlIF9ncmFwaDogc3RyaW5nID0gJ2dyYXBoJykge31cblxuICAgIHR5cGUodHlwZTogSW5kZXhUeXBlKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB2ZXJ0ZXggbGFiZWwgZm9yIFZlcnRleENlbnRyaWMgaW5kaWNpZXMuXG4gICAgICogQHBhcmFtIGxhYmVsIExhYmVsXG4gICAgICogQHJldHVybnMgVGhlIGJ1aWxkZXIuXG4gICAgICovXG4gICAgbGFiZWwobGFiZWw6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICBpZiAodGhpcy5fdHlwZSAhPT0gJ1ZlcnRleENlbnRyaWMnKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgYExhYmVsICR7bGFiZWx9IHNldCBvbiBFbmFibGVJbmRleCBidWlsZGVyLiBUaGlzIG9ubHkgYXBwbGllcyBmb3IgVmVydGV4Q2VudHJpYyBpbmRpY2VzLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbGFiZWwgPSBsYWJlbDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgYWN0aW9uKGFjdGlvbjogU2NoZW1hQWN0aW9uKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2FjdGlvbiA9IGFjdGlvbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnVpbGRzIHRoZSBvdXRwdXQgc3RyaW5nLlxuICAgICAqIEByZXR1cm5zIFN0cmluZyB0aGF0IGNhbGxzIEVOQUJMRV9JTkRFWCBpbiBKRy5cbiAgICAgKiBAdGhyb3dzIEFuIEVycm9yIGlmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBlbmFibGUgYSBWZXJ0ZXhDZW50cmljIGluZGV4IHdpdGhvdXQgYSBsYWJlbC5cbiAgICAgKi9cbiAgICBidWlsZCgpOiBzdHJpbmcge1xuICAgICAgICBsZXQgb3V0cHV0ID0gJ21nbXQudXBkYXRlSW5kZXgoJztcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09ICdWZXJ0ZXhDZW50cmljJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2xhYmVsID09IG51bGwgfHwgdGhpcy5fbGFiZWwgPT09ICcnKVxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICBgVmVydGV4IENlbnRyaWMgaW5kZXggJyR7dGhpcy5fbmFtZX0nIGF0dGVtcHRlZCB0byBiZSBlbmFibGVkIHdpdGhvdXQgYSBsYWJlbCBkZWZpbml0aW9uLmBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgb3V0cHV0ICs9IGBtZ210LmdldFJlbGF0aW9uSW5kZXgobWdtdC5nZXRFZGdlTGFiZWwoJyR7dGhpcy5fbGFiZWx9JyksICcke3RoaXMuX25hbWV9JylgO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3V0cHV0ICs9IGBtZ210LmdldEdyYXBoSW5kZXgoJyR7dGhpcy5fbmFtZX0nKWA7XG4gICAgICAgIH1cbiAgICAgICAgb3V0cHV0ICs9IGAsIFNjaGVtYUFjdGlvbi4ke3RoaXMuX2FjdGlvbn0pLmdldCgpO2A7XG4gICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgQnVpbGRlciB9IGZyb20gJy4vQnVpbGRlci5pbnRlcmZhY2UnO1xuaW1wb3J0IHtcbiAgICBDb21wb3NpdGVPck1peGVkSW5kZXhUeXBlLFxuICAgIEVsZW1lbnRDbGFzcyxcbiAgICBJbmRleEtleSxcbn0gZnJvbSAnLi4vdHlwZXMvR3JhcGhJbmRleCc7XG5cbi8qKlxuICogSW5kZXggQnVpbGRlciBmb3IgQ29tcG9zaXRlIG9yIE1peGVkIGluZGljZXMuXG4gKlxuICogRm9yIFZlcnRleENlbnRyaWMgaW5kaWNpZXMsIHBsZWFzZSB1c2Uge0BsaW5rIFZlcnRleENlbnRyaWNJbmRleEJ1aWxkZXJ9XG4gKi9cbmV4cG9ydCBjbGFzcyBHcmFwaEluZGV4QnVpbGRlciBpbXBsZW1lbnRzIEJ1aWxkZXI8c3RyaW5nPiB7XG4gICAgcHJpdmF0ZSBfdHlwZT86IENvbXBvc2l0ZU9yTWl4ZWRJbmRleFR5cGU7XG4gICAgcHJpdmF0ZSBfa2V5czogSW5kZXhLZXlbXSA9IFtdO1xuICAgIHByaXZhdGUgX3VuaXF1ZT86IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBfbGFiZWw/OiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBfYmFja2VuZD86IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX25hbWU6IHN0cmluZywgcHJpdmF0ZSBfZWxlbWVudDogRWxlbWVudENsYXNzKSB7fVxuXG4gICAgdHlwZSh0eXBlOiBDb21wb3NpdGVPck1peGVkSW5kZXhUeXBlKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBrZXkoa2V5OiBJbmRleEtleSk6IHRoaXMge1xuICAgICAgICBpZiAodGhpcy5fa2V5cy5zb21lKChrKSA9PiBrLmZpZWxkID09PSBrZXkuZmllbGQpKSByZXR1cm4gdGhpcztcbiAgICAgICAgdGhpcy5fa2V5cy5wdXNoKGtleSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHVuaXF1ZSh1bmlxdWUgPSBmYWxzZSk6IHRoaXMge1xuICAgICAgICB0aGlzLl91bmlxdWUgPSB1bmlxdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGxhYmVsKGxhYmVsPzogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2xhYmVsID0gbGFiZWw7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGJhY2tlbmQoYmFja2VuZD86IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLl9iYWNrZW5kID0gYmFja2VuZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgYnVpbGQoKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHRoaXMuX2tleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICBgVW5hYmxlIHRvIGdlbmVyYXRlIGluZGV4ICR7dGhpcy5fbmFtZX0gd2l0aCBubyBrZXkgZGVmaW5pdGlvbnMuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fdHlwZSAhPT0gJ01peGVkJyAmJiB0aGlzLl9iYWNrZW5kICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAnQ29tcG9zaXRlIGluZGV4IHR5cGUgYW5kIG5vbi1udWxsIGJhY2tlbmQuIFdpbGwgaWdub3JlIGJhY2tlbmQuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb3V0cHV0ID0gYGlmICghbWdtdC5jb250YWluc0dyYXBoSW5kZXgoJyR7dGhpcy5fbmFtZX0nKSkgYDtcbiAgICAgICAgb3V0cHV0ICs9IGBtZ210LmJ1aWxkSW5kZXgoJyR7dGhpcy5fbmFtZX0nLCAke3RoaXMuX2VsZW1lbnR9LmNsYXNzKWA7XG4gICAgICAgIG91dHB1dCArPSBbLi4udGhpcy5fa2V5c11cbiAgICAgICAgICAgIC5tYXAoXG4gICAgICAgICAgICAgICAgKGtleSkgPT5cbiAgICAgICAgICAgICAgICAgICAgYC5hZGRLZXkobWdtdC5nZXRQcm9wZXJ0eUtleSgnJHtrZXkuZmllbGR9Jykke1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHlwZSA9PT0gJ01peGVkJyAmJiBrZXkubWFwcGluZyAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBgLE1hcHBpbmcuJHtrZXkubWFwcGluZ30uYXNQYXJhbWV0ZXIoKWBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICcnXG4gICAgICAgICAgICAgICAgICAgIH0pYFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLmpvaW4oJycpO1xuICAgICAgICBvdXRwdXQgKz0gdGhpcy5fdW5pcXVlID8gYC51bmlxdWUoKWAgOiAnJztcbiAgICAgICAgb3V0cHV0ICs9XG4gICAgICAgICAgICB0aGlzLl9sYWJlbCAhPSBudWxsXG4gICAgICAgICAgICAgICAgPyBgLmluZGV4T25seShtZ210LmdldCR7dGhpcy5fZWxlbWVudH1MYWJlbCgnJHt0aGlzLl9sYWJlbH0nKSlgXG4gICAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgcmV0dXJuIG91dHB1dC5jb25jYXQoXG4gICAgICAgICAgICB0aGlzLl90eXBlID09PSAnTWl4ZWQnXG4gICAgICAgICAgICAgICAgPyBgLmJ1aWxkTWl4ZWRJbmRleCgnJHt0aGlzLl9iYWNrZW5kID8/ICdzZWFyY2gnfScpO2BcbiAgICAgICAgICAgICAgICA6ICcuYnVpbGRDb21wb3NpdGVJbmRleCgpOydcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBCdWlsZGVyIH0gZnJvbSAnLi9CdWlsZGVyLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQcm9wZXJ0eUNhcmRpbmFsaXR5LCBQcm9wZXJ0eVR5cGUgfSBmcm9tICcuLi90eXBlcy9Qcm9wZXJ0eSc7XG5cbmV4cG9ydCBjbGFzcyBQcm9wZXJ0eUJ1aWxkZXIgaW1wbGVtZW50cyBCdWlsZGVyPHN0cmluZz4ge1xuICAgIHByaXZhdGUgX2RhdGF0eXBlPzogUHJvcGVydHlUeXBlO1xuICAgIHByaXZhdGUgX2NhcmRpbmFsaXR5PzogUHJvcGVydHlDYXJkaW5hbGl0eSA9ICdTSU5HTEUnO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfa2V5OiBzdHJpbmcpIHt9XG5cbiAgICBjYXJkaW5hbGl0eShjYXJkaW5hbGl0eT86IFByb3BlcnR5Q2FyZGluYWxpdHkpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fY2FyZGluYWxpdHkgPSBjYXJkaW5hbGl0eTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZGF0YXR5cGUoZGF0YXR5cGU/OiBQcm9wZXJ0eVR5cGUpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fZGF0YXR5cGUgPSBkYXRhdHlwZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgYnVpbGQoKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IG91dHB1dCA9IGBpZiAoIW1nbXQuY29udGFpbnNQcm9wZXJ0eUtleSgnJHt0aGlzLl9rZXl9JykpIGA7XG4gICAgICAgIG91dHB1dCArPSBgbWdtdC5tYWtlUHJvcGVydHlLZXkoJyR7dGhpcy5fa2V5fScpYDtcbiAgICAgICAgb3V0cHV0ICs9XG4gICAgICAgICAgICB0aGlzLl9kYXRhdHlwZSAhPSBudWxsID8gYC5kYXRhVHlwZSgke3RoaXMuX2RhdGF0eXBlfS5jbGFzcylgIDogJyc7XG4gICAgICAgIG91dHB1dCArPVxuICAgICAgICAgICAgdGhpcy5fY2FyZGluYWxpdHkgIT0gbnVsbFxuICAgICAgICAgICAgICAgID8gYC5jYXJkaW5hbGl0eShvcmcuamFudXNncmFwaC5jb3JlLkNhcmRpbmFsaXR5LiR7dGhpcy5fY2FyZGluYWxpdHl9KWBcbiAgICAgICAgICAgICAgICA6ICcnO1xuICAgICAgICByZXR1cm4gb3V0cHV0LmNvbmNhdCgnLm1ha2UoKTsnKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBCdWlsZGVyIH0gZnJvbSAnLi9CdWlsZGVyLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQcm9wZXJ0eSB9IGZyb20gJy4uL3R5cGVzL1Byb3BlcnR5JztcblxuZXhwb3J0IGNsYXNzIFZlcnRleEJ1aWxkZXIgaW1wbGVtZW50cyBCdWlsZGVyPHN0cmluZz4ge1xuICAgIHByaXZhdGUgX3Byb3BlcnRpZXM6IFByb3BlcnR5W10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX2xhYmVsOiBzdHJpbmcpIHt9XG5cbiAgICBwcm9wZXJ0eShwcm9wZXJ0eTogUHJvcGVydHkpOiB0aGlzIHtcbiAgICAgICAgaWYgKHRoaXMuX3Byb3BlcnRpZXMuc29tZSgocCkgPT4gcC5rZXkgPT09IHByb3BlcnR5LmtleSkpIHJldHVybiB0aGlzO1xuICAgICAgICB0aGlzLl9wcm9wZXJ0aWVzLnB1c2gocHJvcGVydHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBidWlsZCgpOiBzdHJpbmcge1xuICAgICAgICBsZXQgb3V0cHV0ID0gYGlmICghbWdtdC5jb250YWluc1ZlcnRleExhYmVsKCcke3RoaXMuX2xhYmVsfScpKSBgO1xuICAgICAgICBvdXRwdXQgKz0gYG1nbXQubWFrZVZlcnRleExhYmVsKCcke3RoaXMuX2xhYmVsfScpYDtcbiAgICAgICAgb3V0cHV0ICs9ICcubWFrZSgpOyc7XG4gICAgICAgIGlmICh0aGlzLl9wcm9wZXJ0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIG91dHB1dCArPSAnbWdtdC5hZGRQcm9wZXJ0aWVzKCc7XG4gICAgICAgICAgICBvdXRwdXQgKz0gYG1nbXQuZ2V0VmVydGV4TGFiZWwoJyR7dGhpcy5fbGFiZWx9JyksIGA7XG4gICAgICAgICAgICBvdXRwdXQgKz0gWy4uLnRoaXMuX3Byb3BlcnRpZXNdXG4gICAgICAgICAgICAgICAgLm1hcCgocHJvcCkgPT4gYG1nbXQuZ2V0UHJvcGVydHlLZXkoJyR7cHJvcC5rZXl9JylgKVxuICAgICAgICAgICAgICAgIC5qb2luKCcsICcpO1xuICAgICAgICAgICAgb3V0cHV0ICs9ICcpJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEJ1aWxkZXIgfSBmcm9tICcuL0J1aWxkZXIuaW50ZXJmYWNlJztcbmltcG9ydCB7IERpcmVjdGlvbiwgT3JkZXIgfSBmcm9tICcuLi90eXBlcy9WZXJ0ZXhDZW50cmljSW5kZXgnO1xuXG4vKipcbiAqIEluZGV4IEJ1aWxkZXIgZm9yIFZlcnRleCBDZW50cmljIGluZGljZXMuXG4gKlxuICogRm9yIE1peGVkL0NvbXBvc2l0ZSwgcGxlYXNlIHVzZSB7QGxpbmsgSW5kZXhCdWlsZGVyfVxuICovXG5leHBvcnQgY2xhc3MgVmVydGV4Q2VudHJpY0luZGV4QnVpbGRlciBpbXBsZW1lbnRzIEJ1aWxkZXI8c3RyaW5nPiB7XG4gICAgcHJpdmF0ZSBfa2V5czogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG4gICAgcHJpdmF0ZSBfZGlyZWN0aW9uITogRGlyZWN0aW9uO1xuICAgIHByaXZhdGUgX29yZGVyOiBPcmRlciA9ICdhc2MnO1xuICAgIHByaXZhdGUgX2VkZ2VsYWJlbCE6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX25hbWU6IHN0cmluZykge31cblxuICAgIGVkZ2VsYWJlbChlZGdlbGFiZWw6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLl9lZGdlbGFiZWwgPSBlZGdlbGFiZWw7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGRpcmVjdGlvbihkaXJlY3Rpb246IERpcmVjdGlvbik6IHRoaXMge1xuICAgICAgICB0aGlzLl9kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIG9yZGVyKG9yZGVyOiBPcmRlcik6IHRoaXMge1xuICAgICAgICB0aGlzLl9vcmRlciA9IG9yZGVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBrZXkoa2V5OiBzdHJpbmcpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fa2V5cy5hZGQoa2V5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgYnVpbGQoKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHRoaXMuX2tleXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgYFVuYWJsZSB0byBnZW5lcmF0ZSB2YyBpbmRleCAke3RoaXMuX25hbWV9IHdpdGggbm8ga2V5IGRlZmluaXRpb25zLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbiA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICBgVW5hYmxlIHRvIGdlbmVyYXRlIHZjIGluZGV4ICR7dGhpcy5fbmFtZX0gd2l0aCBubyBkaXJlY3Rpb25hbGl0eS5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9lZGdlbGFiZWwgPT0gbnVsbCB8fCB0aGlzLl9lZGdlbGFiZWwgPT09ICcnKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICBgVW5hYmxlIHRvIGdlbmVyYXRlIHZjIGluZGV4ICR7dGhpcy5fbmFtZX0gd2l0aCBubyBlZGdlIGxhYmVsLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG91dHB1dCA9IGBpZiAoIW1nbXQuY29udGFpbnNSZWxhdGlvbkluZGV4KG1nbXQuZ2V0RWRnZUxhYmVsKCcke3RoaXMuX2VkZ2VsYWJlbH0nKSwgJyR7dGhpcy5fbmFtZX0nKSkgYDtcbiAgICAgICAgb3V0cHV0ICs9IGBtZ210LmJ1aWxkRWRnZUluZGV4KGA7XG4gICAgICAgIG91dHB1dCArPSBgbWdtdC5nZXRFZGdlTGFiZWwoJyR7dGhpcy5fZWRnZWxhYmVsfScpLCBgO1xuICAgICAgICBvdXRwdXQgKz0gYCcke3RoaXMuX25hbWV9JywgYDtcbiAgICAgICAgb3V0cHV0ICs9IGBEaXJlY3Rpb24uJHt0aGlzLl9kaXJlY3Rpb259LCBgO1xuICAgICAgICBvdXRwdXQgKz0gYE9yZGVyLiR7dGhpcy5fb3JkZXJ9LCBgO1xuICAgICAgICBvdXRwdXQgKz0gWy4uLnRoaXMuX2tleXNdXG4gICAgICAgICAgICAubWFwKChrZXkpID0+IGBtZ210LmdldFByb3BlcnR5S2V5KCcke2tleX0nKWApXG4gICAgICAgICAgICAuam9pbignLCAnKTtcbiAgICAgICAgcmV0dXJuIG91dHB1dC5jb25jYXQoJyk7MDsnKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBCdWlsZGVyIH0gZnJvbSAnLi9CdWlsZGVyLmludGVyZmFjZSc7XG5cbi8qKlxuICogQnVpbGRzIGEgc3RyaW5nIHRoYXQgaW5zdHJ1Y3RzIHRoZSBtYW5hZ2VtZW50IHN5c3RlbSB0byB3YWl0IGZvciBhbiBpbmRleCB0byBiZWNvbWUgYXZhaWxhYmxlLlxuICovXG5leHBvcnQgY2xhc3MgV2FpdEZvckluZGV4QnVpbGRlciBpbXBsZW1lbnRzIEJ1aWxkZXI8c3RyaW5nPiB7XG4gICAgLyoqXG4gICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci5cbiAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBpbmRleCB0byB3YWl0IGZvci5cbiAgICAgKiBAcGFyYW0gZ3JhcGggTmFtZSBvZiB0aGUgZ3JhcGggdG8gdXNlLiBEZWZhdWx0IGlzIGBncmFwaGBcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIG5hbWU6IHN0cmluZywgcHJpdmF0ZSBncmFwaDogc3RyaW5nID0gJ2dyYXBoJykge31cblxuICAgIGJ1aWxkKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgTWFuYWdlbWVudFN5c3RlbS5hd2FpdEdyYXBoSW5kZXhTdGF0dXMoJHt0aGlzLmdyYXBofSwgJyR7dGhpcy5uYW1lfScpLnN0YXR1cyhTY2hlbWFTdGF0dXMuRU5BQkxFRCwgU2NoZW1hU3RhdHVzLlJFR0lTVEVSRUQpLmNhbGwoKS50b1N0cmluZygpYDtcbiAgICB9XG59XG4iLCJleHBvcnQgKiBmcm9tICcuL0VkZ2VCdWlsZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vRW5hYmxlSW5kZXhCdWlsZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vR3JhcGhJbmRleEJ1aWxkZXInO1xuZXhwb3J0ICogZnJvbSAnLi9Qcm9wZXJ0eUJ1aWxkZXInO1xuZXhwb3J0ICogZnJvbSAnLi9XYWl0Rm9ySW5kZXhCdWlsZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vVmVydGV4QnVpbGRlcic7XG5leHBvcnQgKiBmcm9tICcuL1ZlcnRleENlbnRyaWNJbmRleEJ1aWxkZXInO1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsImltcG9ydCB7IGRyaXZlciB9IGZyb20gJ2dyZW1saW4nO1xuaW1wb3J0IHsgR3JhcGhTY2hlbWEgfSBmcm9tICcuL3R5cGVzL0dyYXBoU2NoZW1hJztcbmltcG9ydCB7XG4gICAgRWRnZUJ1aWxkZXIsXG4gICAgRW5hYmxlSW5kZXhCdWlsZGVyLFxuICAgIEdyYXBoSW5kZXhCdWlsZGVyLFxuICAgIFByb3BlcnR5QnVpbGRlcixcbiAgICBWZXJ0ZXhCdWlsZGVyLFxuICAgIFZlcnRleENlbnRyaWNJbmRleEJ1aWxkZXIsXG4gICAgV2FpdEZvckluZGV4QnVpbGRlcixcbn0gZnJvbSAnLi9idWlsZGVycyc7XG5pbXBvcnQgeyBHcmFwaEluZGV4LCBWZXJ0ZXhDZW50cmljSW5kZXggfSBmcm9tICcuL3R5cGVzJztcblxudHlwZSBNYW5hZ2VyU3RhdGUgPSAnTkVXJyB8ICdSRUFEWScgfCAnQ09NTUlUJyB8ICdFUlJPUicgfCAnQ0xPU0VEJztcblxuZXhwb3J0IHR5cGUgSmFudXNHcmFwaE1hbmdlck9wdGlvbnMgPSB7XG4gICAgLyoqXG4gICAgICogTmFtZSBvZiB0aGUgZ3JhcGggdG8gdHJhdmVyc2UuXG4gICAgICovXG4gICAgZ3JhcGhOYW1lPzogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgb3Igbm90IHRvIHVzZSB0aGUgQ29uZmlndXJlZEdyYXBoRmFjdG9yeSBmb3IgZHluYW1pYyBncmFwaHMuXG4gICAgICovXG4gICAgdXNlQ29uZmlndXJlZEdyYXBoRmFjdG9yeT86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogUGF0aCB0byBhIEphbnVzR3JhcGhGYWN0b3J5IGNvbmZpZ3VyYXRpb24gb24gdGhlIHJlbW90ZSwgZm9yIHVzZSB3aXRoIEphbnVzR3JhcGhGYWN0b3J5LlxuICAgICAqL1xuICAgIGNvbmZpZ1BhdGg/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgY2xhc3MgSmFudXNHcmFwaE1hbmFnZXIge1xuICAgIHByaXZhdGUgc3RhdGU6IE1hbmFnZXJTdGF0ZSA9ICdORVcnO1xuXG4gICAgcHJpdmF0ZSBPUEVOX01HTVQgPSBgbWdtdCA9ICR7dGhpcy5vcHRpb25zLmdyYXBoTmFtZX0ub3Blbk1hbmFnZW1lbnQoKTswO2A7XG5cbiAgICAvKipcbiAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLlxuICAgICAqIEBwYXJhbSBjbGllbnQgQSBwcmVjb25maWd1cmVkIGdyZW1saW4gY2xpZW50IGZvciBhY2Nlc3NpbmcgZ3JlbWxpbi1zZXJ2ZXIuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgSmFudXNHcmFwaE9wdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgZ3JhcGg6XG4gICAgICogLSBncmFwaE5hbWUgd2lsbCBoYXZlIGEgZGVmYXVsdCBvZiBgJ2dyYXBoJ2AuXG4gICAgICogLSB1c2VDb25maWd1cmVkR3JhcGhGYWN0b3J5IHdpbGwgaGF2ZSBhIGRlZmF1bHQgb2YgYGZhbHNlYFxuICAgICAqIC0gY29uZmlnUGF0aCBoYXMgbm8gZGVmYXVsdC5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBjbGllbnQ6IGRyaXZlci5DbGllbnQsXG4gICAgICAgIHByaXZhdGUgb3B0aW9uczogSmFudXNHcmFwaE1hbmdlck9wdGlvbnNcbiAgICApIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZ3JhcGhOYW1lID09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5ncmFwaE5hbWUgPSAnZ3JhcGgnO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLnVzZUNvbmZpZ3VyZWRHcmFwaEZhY3RvcnkgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLnVzZUNvbmZpZ3VyZWRHcmFwaEZhY3RvcnkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZW5zIHRoZSBtYW5hZ2VtZW50IHN5c3RlbSBmb3IgdGhlIGNsaWVudCBzZXNzaW9uLlxuICAgICAqIFdpbGwgYmUgY2FsbGVkIGludGVybmFsbHkgdG8gcmUtb3BlbiB0aGUgbWFuYWdlbWVudCBzeXN0ZW0gaWYgYSBjb21taXQgb3IgZXJyb3IgY2xvc2VzIGl0LlxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB3aXRoIHRoZSBzdGF0ZSBvZiB0aGUgbWFuYWdlci5cbiAgICAgKi9cbiAgICBwcml2YXRlIGFzeW5jIGluaXQoKTogUHJvbWlzZTxNYW5hZ2VyU3RhdGU+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSAnUkVBRFknKSB7XG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIHRoYXQgdGhlcmUgYXJlIG5vIG9wZW4gdHJhbnNhY3Rpb25zIHdoaWxlIHdlIGFyZSBtYW5hZ2luZyB0aGUgZ3JhcGguXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuc3VibWl0KFxuICAgICAgICAgICAgICAgICAgICBgJHt0aGlzLm9wdGlvbnMuZ3JhcGhOYW1lfS50eCgpLnJvbGxiYWNrKCk7YFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy51c2VDb25maWd1cmVkR3JhcGhGYWN0b3J5KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBcIjswO1wiIHByZXZlbnRzIHRoZSBjbGllbnQgZnJvbSBhdHRlbXB0aW5nIHRvIHNlcmlhbGl6ZSB0aGUgZ3JhcGgvbWFuYWdlbWVudCBzeXN0ZW0uXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LnN1Ym1pdChcbiAgICAgICAgICAgICAgICAgICAgICAgIGAke3RoaXMub3B0aW9ucy5ncmFwaE5hbWV9ID0gQ29uZmlndXJlZEdyYXBoRmFjdG9yeS5vcGVuKCcke3RoaXMub3B0aW9ucy5ncmFwaE5hbWV9Jyk7MDtgXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMuY29uZmlnUGF0aCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LnN1Ym1pdChcbiAgICAgICAgICAgICAgICAgICAgICAgIGAke3RoaXMub3B0aW9ucy5ncmFwaE5hbWV9ID0gSmFudXNHcmFwaEZhY3Rvcnkub3BlbignJHt0aGlzLm9wdGlvbnMuY29uZmlnUGF0aH0nKTswO2BcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuc3VibWl0KHRoaXMuT1BFTl9NR01UKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gJ1JFQURZJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5zdGF0ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9ICdFUlJPUic7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ1aWxkcyBhbmQgcGVyc2lzdHMgYSBzaW5nbGUgZ3JhcGggaW5kZXguXG4gICAgICogQ3VycmVudGx5LCBpZiBhbiBpbmRleCB3aXRoIHRoZSBzYW1lIG5hbWUgaXMgYWxyZWFkeSBjcmVhdGVkLCB0aGlzIHdpbGwgKm5vdCogcmVjcmVhdGUgdGhlIGluZGV4LlxuICAgICAqIEBwYXJhbSBpbmRleCBHcmFwaEluZGV4IHRvIGNyZWF0ZS5cbiAgICAgKiBAcGFyYW0gY29tbWl0IFdoZXRoZXIgb3Igbm90IHRvIGNvbW1pdCB0aGUgY2hhbmdlcy5cbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZUdyYXBoSW5kZXgoaW5kZXg6IEdyYXBoSW5kZXgsIGNvbW1pdCA9IGZhbHNlKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgR3JhcGhJbmRleEJ1aWxkZXIoXG4gICAgICAgICAgICBpbmRleC5uYW1lLFxuICAgICAgICAgICAgaW5kZXguZWxlbWVudCA/PyAnVmVydGV4J1xuICAgICAgICApO1xuICAgICAgICBidWlsZGVyXG4gICAgICAgICAgICAubGFiZWwoaW5kZXgubGFiZWwpXG4gICAgICAgICAgICAudHlwZShpbmRleC50eXBlKVxuICAgICAgICAgICAgLnVuaXF1ZShpbmRleC51bmlxdWUpXG4gICAgICAgICAgICAuYmFja2VuZChpbmRleC5iYWNrZW5kKTtcbiAgICAgICAgaW5kZXgua2V5cy5mb3JFYWNoKChrKSA9PiBidWlsZGVyLmtleShrKSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNsaWVudC5zdWJtaXQoYnVpbGRlci5idWlsZCgpKTtcbiAgICAgICAgICAgIGlmIChjb21taXQpIGF3YWl0IHRoaXMuY29tbWl0KCk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKDEpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnVpbGRzIGFuZCBwZXJzaXN0cyBhIHNpbmdsZSBWZXJ0ZXhDZW50cmljIGluZGV4LlxuICAgICAqIEN1cnJlbnRseSwgaWYgYW4gaW5kZXggd2l0aCB0aGUgc2FtZSBuYW1lIGlzIGFscmVhZHkgY3JlYXRlZCwgdGhpcyB3aWxsICpub3QqIHJlY3JlYXRlIHRoZSBpbmRleC5cbiAgICAgKiBAcGFyYW0gaW5kZXggVmVydGV4Q2VudHJpY0luZGV4IHRvIGNyZWF0ZS5cbiAgICAgKiBAcGFyYW0gY29tbWl0IFdoZXRoZXIgb3Igbm90IHRvIGNvbW1pdCB0aGUgY2hhbmdlcy5cbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVZlcnRleENlbnRyaWNJbmRleChcbiAgICAgICAgaW5kZXg6IFZlcnRleENlbnRyaWNJbmRleCxcbiAgICAgICAgY29tbWl0ID0gZmFsc2VcbiAgICApOiBQcm9taXNlPG51bWJlcj4ge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gbmV3IFZlcnRleENlbnRyaWNJbmRleEJ1aWxkZXIoaW5kZXgubmFtZSk7XG4gICAgICAgIGJ1aWxkZXJcbiAgICAgICAgICAgIC5kaXJlY3Rpb24oaW5kZXguZGlyZWN0aW9uKVxuICAgICAgICAgICAgLmVkZ2VsYWJlbChpbmRleC5lZGdlbGFiZWwpXG4gICAgICAgICAgICAub3JkZXIoaW5kZXgub3JkZXIpO1xuICAgICAgICBpbmRleC5rZXlzLmZvckVhY2goKGspID0+IGJ1aWxkZXIua2V5KGspKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuc3VibWl0KGJ1aWxkZXIuYnVpbGQoKSk7XG4gICAgICAgICAgICBpZiAoY29tbWl0KSBhd2FpdCB0aGlzLmNvbW1pdCgpO1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgxKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdpbGwgcGF1c2UgZXhlY3V0aW9uIHVudGlsIHRoZSBtYW5hZ2VtZW50IHN5c3RlbSByZXBvcnRzIHRoYXQgYWxsIGluZGljZXMgb24gYSBncmFwaCBoYXZlIHJlYWNoZWQgdGhlIFJFR0lTVEVSRUQgb3IgRU5BQkxFRCBzdGF0ZS5cbiAgICAgKiBAcGFyYW0gc2NoZW1hIEdyYXBoU2NoZW1hIHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIGdyYXBoIE5hbWUgb2YgdGhlIHRyYXZlcnNhbCBhbGlhcyB0byBhbmFseXplLiBEZWZhdWx0OiBgZ3JhcGhgXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHdpdGggdGhlIG51bWJlciBvZiBpbmRpY2VzIHRoYXQgcmVhY2hlZCBSRUdJU1RFUkVEIG9yIEVOQUJMRUQgc3RhdGUuXG4gICAgICovXG4gICAgYXN5bmMgd2FpdEZvckluZGljZXMoc2NoZW1hOiBHcmFwaFNjaGVtYSwgZ3JhcGg/OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgICAgICAgICBbLi4uc2NoZW1hLmdyYXBoSW5kaWNlcywgLi4uc2NoZW1hLnZjSW5kaWNlc10ubWFwKChpKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53YWl0Rm9ySW5kZXgoaSwgZ3JhcGgpXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApLmxlbmd0aDtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdpbGwgcGF1c2UgZXhlY3V0aW9uIHVudGlsIHRoZSBtYW5hZ2VtZW50IHN5c3RlbSByZXBvcnRzIHRoYXQgYSBzaW5nbGUgaW5kZXggb24gYSBncmFwaCBoYXMgcmVhY2hlZCB0aGUgUkVHSVNURVJFRCBvciBFTkFCTEVEIHN0YXRlLlxuICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSBncmFwaCBOYW1lIG9mIHRoZSB0cmF2ZXJzYWwgYWxpYXMgdG8gYW5hbHl6ZS4gRGVmYXVsdDogYGdyYXBoYF