src/pyams_gis/resources/js/leaflet-esri-gp-2.0.1.js
changeset 0 c73bb834ccbe
equal deleted inserted replaced
-1:000000000000 0:c73bb834ccbe
       
     1 /* esri-leaflet-gp - v2.0.1 - Fri Sep 09 2016 14:42:04 GMT-0700 (PDT)
       
     2  * Copyright (c) 2016 Environmental Systems Research Institute, Inc.
       
     3  * Apache-2.0 */
       
     4 (function (global, factory) {
       
     5 	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('leaflet'), require('esri-leaflet')) :
       
     6 	typeof define === 'function' && define.amd ? define(['exports', 'leaflet', 'esri-leaflet'], factory) :
       
     7 	(factory((global.L = global.L || {}, global.L.esri = global.L.esri || {}, global.L.esri.GP = global.L.esri.GP || {}),global.L,global.L.esri));
       
     8 }(this, function (exports,L,esriLeaflet) { 'use strict';
       
     9 
       
    10 	L = 'default' in L ? L['default'] : L;
       
    11 
       
    12 	var version = "2.0.1";
       
    13 
       
    14 	var Task$1 = esriLeaflet.Task.extend({
       
    15 
       
    16 	  includes: L.Mixin.Events,
       
    17 
       
    18 	  // setters: {}, we don't use these because we don't know the ParamName OR value of custom GP services
       
    19 	  params: {},
       
    20 	  resultParams: {},
       
    21 
       
    22 	  initialize: function (options) {
       
    23 	    // don't replace parent initialize
       
    24 	    esriLeaflet.Task.prototype.initialize.call(this, options);
       
    25 
       
    26 	    // if path isn't supplied in options, try and determine if its sync or async to set automatically
       
    27 	    if (!this.options.path) {
       
    28 	      // assume initially, that service is synchronous
       
    29 	      this.options.async = false;
       
    30 	      this.options.path = 'execute';
       
    31 
       
    32 	      // the parameters below seem wonky to me, but work for both CORS and JSONP requests
       
    33 	      this._service.metadata(function (error, results) {
       
    34 	        if (!error) {
       
    35 	          if (results.executionType === 'esriExecutionTypeSynchronous') {
       
    36 	            this.options.async = false;
       
    37 	            this.options.path = 'execute';
       
    38 	          } else {
       
    39 	            this.options.async = true;
       
    40 	            this.options.path = 'submitJob';
       
    41 	          }
       
    42 	          this.fire('initialized');
       
    43 	        } else {
       
    44 	          // if check fails, hopefully its synchronous
       
    45 	          this.options.async = false;
       
    46 	          this.options.path = 'execute';
       
    47 	          return;
       
    48 	        }
       
    49 	      }, this);
       
    50 	    } else {
       
    51 	      // if path is custom, hopefully its synchronous
       
    52 	      if (this.options.async !== true && this.options.path !== 'submitJob') {
       
    53 	        this.options.async = false;
       
    54 	      }
       
    55 	    }
       
    56 	  },
       
    57 
       
    58 	  // doc for various GPInput types can be found here
       
    59 	  // http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/GP_Result/02r3000000q7000000/
       
    60 
       
    61 	  // set booleans, numbers, strings
       
    62 	  setParam: function (paramName, paramValue) {
       
    63 	    if (typeof paramValue === 'boolean') {
       
    64 	      this.params[paramName] = paramValue;
       
    65 	      return;
       
    66 	    } else if (typeof paramValue !== 'object') { // strings, numbers
       
    67 	      this.params[paramName] = paramValue;
       
    68 	      return;
       
    69 	    } else {
       
    70 	      // otherwise assume its latlng, marker, bounds or geojson
       
    71 	      this._setGeometry(paramName, paramValue);
       
    72 	    }
       
    73 	  },
       
    74 
       
    75 	  // not sure how best to handle passing more than one parameter at once
       
    76 	  // setParams: function(inputArray) {
       
    77 	  //   if (L.Util.isArray(inputArray)) {
       
    78 	  //     for (var i = 0; i < inputArray.length; i++) {
       
    79 	  //       this.setParam(inputArray[i]);
       
    80 	  //     }
       
    81 	  //   }
       
    82 	  // },
       
    83 
       
    84 	  // give developer opportunity to point out where the output is going to be available
       
    85 	  setOutputParam: function (paramName) {
       
    86 	    this.params.outputParam = paramName;
       
    87 	  },
       
    88 
       
    89 	  /* necessary because of the design requirement that resultParams be specified
       
    90 	  for async elevation services in order to get Zs (unnecessarily confusing)*/
       
    91 	  gpAsyncResultParam: function (paramName, paramValue) {
       
    92 	    this.resultParams[paramName] = paramValue;
       
    93 	  },
       
    94 
       
    95 	  // we currently expect a single geometry or feature (ported from: Tasks.Query._setGeometry)
       
    96 	  _setGeometry: function (paramName, geometry) {
       
    97 	    var processedInput = {
       
    98 	      'geometryType': '',
       
    99 	      'features': []
       
   100 	    };
       
   101 
       
   102 	    // convert bounds to extent and finish
       
   103 	    if (geometry instanceof L.LatLngBounds) {
       
   104 	      // set geometry + type
       
   105 	      processedInput.features.push({'geometry': L.esri.Util.boundsToExtent(geometry)});
       
   106 	      processedInput.geometryType = L.esri.Util.geojsonTypeToArcGIS(geometry.type);
       
   107 	    }
       
   108 
       
   109 	    // convert L.Marker > L.LatLng
       
   110 	    if (geometry.getLatLng) {
       
   111 	      geometry = geometry.getLatLng();
       
   112 	    }
       
   113 
       
   114 	    // convert L.LatLng to a geojson point and continue;
       
   115 	    if (geometry instanceof L.LatLng) {
       
   116 	      geometry = {
       
   117 	        type: 'Point',
       
   118 	        coordinates: [geometry.lng, geometry.lat]
       
   119 	      };
       
   120 	    }
       
   121 
       
   122 	    // handle L.GeoJSON, pull out the first geometry
       
   123 	    if (geometry instanceof L.GeoJSON) {
       
   124 	      // reassign geometry to the GeoJSON value  (we are assuming that only one feature is present)
       
   125 	      geometry = geometry.getLayers()[0].feature.geometry;
       
   126 	      processedInput.features.push({'geometry': esriLeaflet.Util.geojsonToArcGIS(geometry)});
       
   127 	      processedInput.geometryType = esriLeaflet.Util.geojsonTypeToArcGIS(geometry.type);
       
   128 	    }
       
   129 
       
   130 	    // Handle L.Polyline and L.Polygon
       
   131 	    if (geometry.toGeoJSON) {
       
   132 	      geometry = geometry.toGeoJSON();
       
   133 	    }
       
   134 
       
   135 	    // handle GeoJSON feature by pulling out the geometry
       
   136 	    if (geometry.type === 'Feature') {
       
   137 	      // get the geometry of the geojson feature
       
   138 	      geometry = geometry.geometry;
       
   139 	    }
       
   140 
       
   141 	    // confirm that our GeoJSON is a point, line or polygon
       
   142 	    if (geometry.type === 'Point' || geometry.type === 'LineString' || geometry.type === 'Polygon') {
       
   143 	      processedInput.features.push({'geometry': esriLeaflet.Util.geojsonToArcGIS(geometry)});
       
   144 	      processedInput.geometryType = esriLeaflet.Util.geojsonTypeToArcGIS(geometry.type);
       
   145 	    } else {
       
   146 	      if (console && console.warn) {
       
   147 	        console.warn('invalid geometry passed as GP input. Should be an L.LatLng, L.LatLngBounds, L.Marker or GeoJSON Point Line or Polygon object');
       
   148 	      }
       
   149 	    }
       
   150 
       
   151 	    this.params[paramName] = processedInput;
       
   152 	    return;
       
   153 	  },
       
   154 
       
   155 	  run: function (callback, context) {
       
   156 	    this._done = false;
       
   157 
       
   158 	    if (this.options.async === true) {
       
   159 	      /* eslint-disable */
       
   160 	      this._service.request(this.options.path, this.params, function (error, response) {
       
   161 	        this._currentJobId = response.jobId;
       
   162 	        this.checkJob(this._currentJobId, callback, context);
       
   163 	      }, this);
       
   164 	      /* eslint-enable */
       
   165 	    } else {
       
   166 	      return this._service.request(this.options.path, this.params, function (error, response) {
       
   167 	        callback.call(context, error, (response && this.processGPOutput(response)), response);
       
   168 	      }, this);
       
   169 	    }
       
   170 	  },
       
   171 
       
   172 	  checkJob: function (jobId, callback, context) {
       
   173 	    var pollJob = function () {
       
   174 	      /* eslint-disable */
       
   175 	      this._service.request('jobs/' + jobId, {}, function polledJob (error, response) {
       
   176 	        if (response.jobStatus === 'esriJobSucceeded') {
       
   177 	          if (!this._done) {
       
   178 	            this._done = true;
       
   179 	            // to do:
       
   180 	            // refactor to make an array of async requests for output
       
   181 	            this._service.request('jobs/' + jobId + '/results/' + this.params.outputParam, this.resultParams, function processJobResult (error, response) {
       
   182 	              callback.call(context, error, (response && this.processAsyncOutput(response)), response);
       
   183 	            }, this);
       
   184 	          }
       
   185 	          window.clearInterval(counter);
       
   186 	        } else if (response.jobStatus === 'esriJobFailed') {
       
   187 	          callback.call(context, 'Job Failed', null);
       
   188 	          window.clearInterval(counter);
       
   189 	        }
       
   190 	      }, this);
       
   191 	      /* eslint-enable */
       
   192 	    }.bind(this);
       
   193 
       
   194 	    var counter = window.setInterval(pollJob, this._service.options.asyncInterval * 1000);
       
   195 	  },
       
   196 
       
   197 	  processGPOutput: function (response) {
       
   198 	    var processedResponse = {};
       
   199 
       
   200 	    // grab syncronous results
       
   201 	    if (this.options.async === false) {
       
   202 	      // loop through results and pass back, parsing esri json
       
   203 	      for (var i = 0; i < response.results.length; i++) {
       
   204 	        /* jshint ignore:start */
       
   205 	        processedResponse[response.results[i].paramName];
       
   206 	        /* jshint ignore:end */
       
   207 	        if (response.results[i].dataType === 'GPFeatureRecordSetLayer') {
       
   208 	          var featureCollection = esriLeaflet.Util.responseToFeatureCollection(response.results[i].value);
       
   209 	          processedResponse[response.results[i].paramName] = featureCollection;
       
   210 	        } else {
       
   211 	          processedResponse[response.results[i].paramName] = response.results[i].value;
       
   212 	        }
       
   213 	      }
       
   214 	    } else { // grab async results slightly differently
       
   215 	      processedResponse.jobId = this._currentJobId;
       
   216 	      // var responseValue = response.value;
       
   217 	    }
       
   218 
       
   219 	    // if output is a raster layer, we also need to stub out a MapService url using jobid
       
   220 	    if (this.options.async === true && response.dataType === 'GPRasterDataLayer') {
       
   221 	      var baseURL = this.options.url;
       
   222 	      var n = baseURL.indexOf('GPServer');
       
   223 	      var serviceURL = baseURL.slice(0, n) + 'MapServer/';
       
   224 	      processedResponse.outputMapService = serviceURL + 'jobs/' + this._currentJobId;
       
   225 	    }
       
   226 
       
   227 	    return processedResponse;
       
   228 	  },
       
   229 
       
   230 	  processAsyncOutput: function (response) {
       
   231 	    var processedResponse = {};
       
   232 	    processedResponse.jobId = this._currentJobId;
       
   233 
       
   234 	    // if output is a raster layer, we also need to stub out a MapService url using jobid
       
   235 	    if (this.options.async === true && response.dataType === 'GPRasterDataLayer') {
       
   236 	      var baseURL = this.options.url;
       
   237 	      var n = baseURL.indexOf('GPServer');
       
   238 	      var serviceURL = baseURL.slice(0, n) + 'MapServer/';
       
   239 	      processedResponse.outputMapService = serviceURL + 'jobs/' + this._currentJobId;
       
   240 	    }
       
   241 
       
   242 	    // if output is GPFeatureRecordSetLayer, convert to GeoJSON
       
   243 	    if (response.dataType === 'GPFeatureRecordSetLayer') {
       
   244 	      var featureCollection = esriLeaflet.Util.responseToFeatureCollection(response.value);
       
   245 	      processedResponse[response.paramName] = featureCollection;
       
   246 	    } else {
       
   247 	      processedResponse[response.paramName] = response.value;
       
   248 	    }
       
   249 
       
   250 	    return processedResponse;
       
   251 	  }
       
   252 
       
   253 	});
       
   254 
       
   255 	function task (options) {
       
   256 	  return new Task$1(options);
       
   257 	}
       
   258 
       
   259 	var Service$1 = esriLeaflet.Service.extend({
       
   260 	  options: {
       
   261 	    asyncInterval: 1
       
   262 	  },
       
   263 
       
   264 	  createTask: function () {
       
   265 	    return new Task$1(this, this.options);
       
   266 	  }
       
   267 
       
   268 	});
       
   269 
       
   270 	function service (options) {
       
   271 	  return new Service$1(options);
       
   272 	}
       
   273 
       
   274 	exports.VERSION = version;
       
   275 	exports.Task = Task$1;
       
   276 	exports.task = task;
       
   277 	exports.Service = Service$1;
       
   278 	exports.service = service;
       
   279 
       
   280 }));
       
   281 //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNyaS1sZWFmbGV0LWdwLWRlYnVnLmpzIiwic291cmNlcyI6WyIuLi9wYWNrYWdlLmpzb24iLCIuLi9zcmMvVGFza3MvR2VvcHJvY2Vzc2luZy5qcyIsIi4uL3NyYy9TZXJ2aWNlcy9HZW9wcm9jZXNzaW5nLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIntcbiAgXCJuYW1lXCI6IFwiZXNyaS1sZWFmbGV0LWdwXCIsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJBIExlYWZsZXQgcGx1Z2luIGZvciBpbnRlcmFjdGluZyB3aXRoIEFyY0dJUyBnZW9wcm9jZXNzaW5nIHNlcnZpY2VzLlwiLFxuICBcInZlcnNpb25cIjogXCIyLjAuMVwiLFxuICBcImF1dGhvclwiOiBcIkpvaG4gR3Jhdm9pcyA8amdyYXZvaXNAZXNyaS5jb20+IChodHRwOi8vam9obmdyYXZvaXMuY29tKVwiLFxuICBcImJyb3dzZXJcIjogXCJkaXN0L2VzcmktbGVhZmxldC1ncC1kZWJ1Zy5qc1wiLFxuICBcImJ1Z3NcIjoge1xuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2pncmF2b2lzL2VzcmktbGVhZmxldC1ncC9pc3N1ZXNcIlxuICB9LFxuICBcImNvbnRyaWJ1dG9yc1wiOiBbXG4gICAgXCJKb2huIEdyYXZvaXMgPGpncmF2b2lzQGVzcmkuY29tPiAoaHR0cDovL2pvaG5ncmF2b2lzLmNvbSlcIixcbiAgICBcIk5pY2hvbGFzIEZ1cm5lc3MgPG5mdXJuZXNzQGVzcmkuY29tPiAoaHR0cDovL25peHRhLmdpdGh1Yi5pby8pXCIsXG4gICAgXCJQYXRyaWNrIEFybHQgPHBhcmx0QGVzcmkuY29tPiAoaHR0cDovL3BhdHJpY2thcmx0LmNvbSlcIixcbiAgICBcIlJvd2FuIFdpbnNlbWl1c1wiXG4gIF0sXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImxlYWZsZXRcIjogXCJeMS4wLjAtcmMuM1wiLFxuICAgIFwiZXNyaS1sZWFmbGV0XCI6IFwiXjIuMC4wXCJcbiAgfSxcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiY2hhaVwiOiBcIjIuMy4wXCIsXG4gICAgXCJnaC1yZWxlYXNlXCI6IFwiXjIuMC4wXCIsXG4gICAgXCJoaWdobGlnaHQuanNcIjogXCJeOC4wLjBcIixcbiAgICBcImh0dHAtc2VydmVyXCI6IFwiXjAuOC41XCIsXG4gICAgXCJpc3BhcnRhXCI6IFwiXjMuMC4zXCIsXG4gICAgXCJpc3RhbmJ1bFwiOiBcIl4wLjQuMlwiLFxuICAgIFwia2FybWFcIjogXCJeMC4xMi4yNFwiLFxuICAgIFwia2FybWEtY2hhaS1zaW5vblwiOiBcIl4wLjEuM1wiLFxuICAgIFwia2FybWEtY292ZXJhZ2VcIjogXCJeMC41LjNcIixcbiAgICBcImthcm1hLW1vY2hhXCI6IFwiXjAuMS4wXCIsXG4gICAgXCJrYXJtYS1tb2NoYS1yZXBvcnRlclwiOiBcIl4wLjIuNVwiLFxuICAgIFwia2FybWEtcGhhbnRvbWpzLWxhdW5jaGVyXCI6IFwiXjAuMi4wXCIsXG4gICAgXCJrYXJtYS1zb3VyY2VtYXAtbG9hZGVyXCI6IFwiXjAuMy41XCIsXG4gICAgXCJta2RpcnBcIjogXCJeMC41LjFcIixcbiAgICBcInBoYW50b21qc1wiOiBcIl4xLjkuMTdcIixcbiAgICBcInJvbGx1cFwiOiBcIl4wLjI1LjRcIixcbiAgICBcInJvbGx1cC1wbHVnaW4tanNvblwiOiBcIl4yLjAuMFwiLFxuICAgIFwicm9sbHVwLXBsdWdpbi1ub2RlLXJlc29sdmVcIjogXCJeMS40LjBcIixcbiAgICBcInJvbGx1cC1wbHVnaW4tdWdsaWZ5XCI6IFwiXjAuMS4wXCIsXG4gICAgXCJzZW1pc3RhbmRhcmRcIjogXCJeNy4wLjVcIixcbiAgICBcInNpbm9uXCI6IFwiXjEuMTEuMVwiLFxuICAgIFwic2lub24tY2hhaVwiOiBcIjIuNy4wXCIsXG4gICAgXCJzbmF6enlcIjogXCJeMi4wLjFcIixcbiAgICBcInVnbGlmeS1qc1wiOiBcIl4yLjYuMVwiLFxuICAgIFwid2F0Y2hcIjogXCJeMC4xNy4xXCJcbiAgfSxcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9qZ3Jhdm9pcy9lc3JpLWxlYWZsZXQtZ3BcIixcbiAgXCJqc25leHQ6bWFpblwiOiBcInNyYy9Fc3JpTGVhZmxldEdQLmpzXCIsXG4gIFwianNwbVwiOiB7XG4gICAgXCJyZWdpc3RyeVwiOiBcIm5wbVwiLFxuICAgIFwiZm9ybWF0XCI6IFwiZXM2XCIsXG4gICAgXCJtYWluXCI6IFwic3JjL0VzcmlMZWFmbGV0R1AuanNcIlxuICB9LFxuICBcImxpY2Vuc2VcIjogXCJBcGFjaGUtMi4wXCIsXG4gIFwibWFpblwiOiBcImRpc3QvZXNyaS1sZWFmbGV0LWdwLWRlYnVnLmpzXCIsXG4gIFwicmVhZG1lRmlsZW5hbWVcIjogXCJSRUFETUUubWRcIixcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImdpdEBnaXRodWIuY29tOmpncmF2b2lzL2VzcmktbGVhZmxldC1ncC5naXRcIlxuICB9LFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwicHJlYnVpbGRcIjogXCJta2RpcnAgZGlzdFwiLFxuICAgIFwiYnVpbGRcIjogXCJyb2xsdXAgLWMgcHJvZmlsZXMvZGVidWcuanMgJiByb2xsdXAgLWMgcHJvZmlsZXMvcHJvZHVjdGlvbi5qc1wiLFxuICAgIFwibGludFwiOiBcInNlbWlzdGFuZGFyZCBzcmMvKiovKi5qcyB8IHNuYXp6eVwiLFxuICAgIFwicHJlcHVibGlzaFwiOiBcIm5wbSBydW4gYnVpbGRcIixcbiAgICBcInByZXRlc3RcIjogXCJucG0gcnVuIGJ1aWxkXCIsXG4gICAgXCJ0ZXN0XCI6IFwibnBtIHJ1biBsaW50ICYmIGthcm1hIHN0YXJ0XCIsXG4gICAgXCJyZWxlYXNlXCI6IFwiLi9zY3JpcHRzL3JlbGVhc2Uuc2hcIixcbiAgICBcInN0YXJ0XCI6IFwid2F0Y2ggJ25wbSBydW4gYnVpbGQnIHNyYyAmIGh0dHAtc2VydmVyIC1wIDUwMDAgLWMtMSAtb1wiXG4gIH1cbn1cbiIsIi8qXG50byBkbzpcbnNldFBhcmFtKFtdKVxuKi9cblxuaW1wb3J0IEwgZnJvbSAnbGVhZmxldCc7XG5pbXBvcnQgeyBUYXNrIGFzIEJhc2VUYXNrLCBVdGlsIH0gZnJvbSAnZXNyaS1sZWFmbGV0JztcblxuZXhwb3J0IHZhciBUYXNrID0gQmFzZVRhc2suZXh0ZW5kKHtcblxuICBpbmNsdWRlczogTC5NaXhpbi5FdmVudHMsXG5cbiAgLy8gc2V0dGVyczoge30sIHdlIGRvbid0IHVzZSB0aGVzZSBiZWNhdXNlIHdlIGRvbid0IGtub3cgdGhlIFBhcmFtTmFtZSBPUiB2YWx1ZSBvZiBjdXN0b20gR1Agc2VydmljZXNcbiAgcGFyYW1zOiB7fSxcbiAgcmVzdWx0UGFyYW1zOiB7fSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIC8vIGRvbid0IHJlcGxhY2UgcGFyZW50IGluaXRpYWxpemVcbiAgICBCYXNlVGFzay5wcm90b3R5cGUuaW5pdGlhbGl6ZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gICAgLy8gaWYgcGF0aCBpc24ndCBzdXBwbGllZCBpbiBvcHRpb25zLCB0cnkgYW5kIGRldGVybWluZSBpZiBpdHMgc3luYyBvciBhc3luYyB0byBzZXQgYXV0b21hdGljYWxseVxuICAgIGlmICghdGhpcy5vcHRpb25zLnBhdGgpIHtcbiAgICAgIC8vIGFzc3VtZSBpbml0aWFsbHksIHRoYXQgc2VydmljZSBpcyBzeW5jaHJvbm91c1xuICAgICAgdGhpcy5vcHRpb25zLmFzeW5jID0gZmFsc2U7XG4gICAgICB0aGlzLm9wdGlvbnMucGF0aCA9ICdleGVjdXRlJztcblxuICAgICAgLy8gdGhlIHBhcmFtZXRlcnMgYmVsb3cgc2VlbSB3b25reSB0byBtZSwgYnV0IHdvcmsgZm9yIGJvdGggQ09SUyBhbmQgSlNPTlAgcmVxdWVzdHNcbiAgICAgIHRoaXMuX3NlcnZpY2UubWV0YWRhdGEoZnVuY3Rpb24gKGVycm9yLCByZXN1bHRzKSB7XG4gICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICBpZiAocmVzdWx0cy5leGVjdXRpb25UeXBlID09PSAnZXNyaUV4ZWN1dGlvblR5cGVTeW5jaHJvbm91cycpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hc3luYyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBhdGggPSAnZXhlY3V0ZSc7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hc3luYyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMucGF0aCA9ICdzdWJtaXRKb2InO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmZpcmUoJ2luaXRpYWxpemVkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaWYgY2hlY2sgZmFpbHMsIGhvcGVmdWxseSBpdHMgc3luY2hyb25vdXNcbiAgICAgICAgICB0aGlzLm9wdGlvbnMuYXN5bmMgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLm9wdGlvbnMucGF0aCA9ICdleGVjdXRlJztcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBpZiBwYXRoIGlzIGN1c3RvbSwgaG9wZWZ1bGx5IGl0cyBzeW5jaHJvbm91c1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5hc3luYyAhPT0gdHJ1ZSAmJiB0aGlzLm9wdGlvbnMucGF0aCAhPT0gJ3N1Ym1pdEpvYicpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zLmFzeW5jID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8vIGRvYyBmb3IgdmFyaW91cyBHUElucHV0IHR5cGVzIGNhbiBiZSBmb3VuZCBoZXJlXG4gIC8vIGh0dHA6Ly9yZXNvdXJjZXMuYXJjZ2lzLmNvbS9lbi9oZWxwL2FyY2dpcy1yZXN0LWFwaS9pbmRleC5odG1sIy9HUF9SZXN1bHQvMDJyMzAwMDAwMHE3MDAwMDAwL1xuXG4gIC8vIHNldCBib29sZWFucywgbnVtYmVycywgc3RyaW5nc1xuICBzZXRQYXJhbTogZnVuY3Rpb24gKHBhcmFtTmFtZSwgcGFyYW1WYWx1ZSkge1xuICAgIGlmICh0eXBlb2YgcGFyYW1WYWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aGlzLnBhcmFtc1twYXJhbU5hbWVdID0gcGFyYW1WYWx1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwYXJhbVZhbHVlICE9PSAnb2JqZWN0JykgeyAvLyBzdHJpbmdzLCBudW1iZXJzXG4gICAgICB0aGlzLnBhcmFtc1twYXJhbU5hbWVdID0gcGFyYW1WYWx1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gb3RoZXJ3aXNlIGFzc3VtZSBpdHMgbGF0bG5nLCBtYXJrZXIsIGJvdW5kcyBvciBnZW9qc29uXG4gICAgICB0aGlzLl9zZXRHZW9tZXRyeShwYXJhbU5hbWUsIHBhcmFtVmFsdWUpO1xuICAgIH1cbiAgfSxcblxuICAvLyBub3Qgc3VyZSBob3cgYmVzdCB0byBoYW5kbGUgcGFzc2luZyBtb3JlIHRoYW4gb25lIHBhcmFtZXRlciBhdCBvbmNlXG4gIC8vIHNldFBhcmFtczogZnVuY3Rpb24oaW5wdXRBcnJheSkge1xuICAvLyAgIGlmIChMLlV0aWwuaXNBcnJheShpbnB1dEFycmF5KSkge1xuICAvLyAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dEFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gIC8vICAgICAgIHRoaXMuc2V0UGFyYW0oaW5wdXRBcnJheVtpXSk7XG4gIC8vICAgICB9XG4gIC8vICAgfVxuICAvLyB9LFxuXG4gIC8vIGdpdmUgZGV2ZWxvcGVyIG9wcG9ydHVuaXR5IHRvIHBvaW50IG91dCB3aGVyZSB0aGUgb3V0cHV0IGlzIGdvaW5nIHRvIGJlIGF2YWlsYWJsZVxuICBzZXRPdXRwdXRQYXJhbTogZnVuY3Rpb24gKHBhcmFtTmFtZSkge1xuICAgIHRoaXMucGFyYW1zLm91dHB1dFBhcmFtID0gcGFyYW1OYW1lO1xuICB9LFxuXG4gIC8qIG5lY2Vzc2FyeSBiZWNhdXNlIG9mIHRoZSBkZXNpZ24gcmVxdWlyZW1lbnQgdGhhdCByZXN1bHRQYXJhbXMgYmUgc3BlY2lmaWVkXG4gIGZvciBhc3luYyBlbGV2YXRpb24gc2VydmljZXMgaW4gb3JkZXIgdG8gZ2V0IFpzICh1bm5lY2Vzc2FyaWx5IGNvbmZ1c2luZykqL1xuICBncEFzeW5jUmVzdWx0UGFyYW06IGZ1bmN0aW9uIChwYXJhbU5hbWUsIHBhcmFtVmFsdWUpIHtcbiAgICB0aGlzLnJlc3VsdFBhcmFtc1twYXJhbU5hbWVdID0gcGFyYW1WYWx1ZTtcbiAgfSxcblxuICAvLyB3ZSBjdXJyZW50bHkgZXhwZWN0IGEgc2luZ2xlIGdlb21ldHJ5IG9yIGZlYXR1cmUgKHBvcnRlZCBmcm9tOiBUYXNrcy5RdWVyeS5fc2V0R2VvbWV0cnkpXG4gIF9zZXRHZW9tZXRyeTogZnVuY3Rpb24gKHBhcmFtTmFtZSwgZ2VvbWV0cnkpIHtcbiAgICB2YXIgcHJvY2Vzc2VkSW5wdXQgPSB7XG4gICAgICAnZ2VvbWV0cnlUeXBlJzogJycsXG4gICAgICAnZmVhdHVyZXMnOiBbXVxuICAgIH07XG5cbiAgICAvLyBjb252ZXJ0IGJvdW5kcyB0byBleHRlbnQgYW5kIGZpbmlzaFxuICAgIGlmIChnZW9tZXRyeSBpbnN0YW5jZW9mIEwuTGF0TG5nQm91bmRzKSB7XG4gICAgICAvLyBzZXQgZ2VvbWV0cnkgKyB0eXBlXG4gICAgICBwcm9jZXNzZWRJbnB1dC5mZWF0dXJlcy5wdXNoKHsnZ2VvbWV0cnknOiBMLmVzcmkuVXRpbC5ib3VuZHNUb0V4dGVudChnZW9tZXRyeSl9KTtcbiAgICAgIHByb2Nlc3NlZElucHV0Lmdlb21ldHJ5VHlwZSA9IEwuZXNyaS5VdGlsLmdlb2pzb25UeXBlVG9BcmNHSVMoZ2VvbWV0cnkudHlwZSk7XG4gICAgfVxuXG4gICAgLy8gY29udmVydCBMLk1hcmtlciA+IEwuTGF0TG5nXG4gICAgaWYgKGdlb21ldHJ5LmdldExhdExuZykge1xuICAgICAgZ2VvbWV0cnkgPSBnZW9tZXRyeS5nZXRMYXRMbmcoKTtcbiAgICB9XG5cbiAgICAvLyBjb252ZXJ0IEwuTGF0TG5nIHRvIGEgZ2VvanNvbiBwb2ludCBhbmQgY29udGludWU7XG4gICAgaWYgKGdlb21ldHJ5IGluc3RhbmNlb2YgTC5MYXRMbmcpIHtcbiAgICAgIGdlb21ldHJ5ID0ge1xuICAgICAgICB0eXBlOiAnUG9pbnQnLFxuICAgICAgICBjb29yZGluYXRlczogW2dlb21ldHJ5LmxuZywgZ2VvbWV0cnkubGF0XVxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBoYW5kbGUgTC5HZW9KU09OLCBwdWxsIG91dCB0aGUgZmlyc3QgZ2VvbWV0cnlcbiAgICBpZiAoZ2VvbWV0cnkgaW5zdGFuY2VvZiBMLkdlb0pTT04pIHtcbiAgICAgIC8vIHJlYXNzaWduIGdlb21ldHJ5IHRvIHRoZSBHZW9KU09OIHZhbHVlICAod2UgYXJlIGFzc3VtaW5nIHRoYXQgb25seSBvbmUgZmVhdHVyZSBpcyBwcmVzZW50KVxuICAgICAgZ2VvbWV0cnkgPSBnZW9tZXRyeS5nZXRMYXllcnMoKVswXS5mZWF0dXJlLmdlb21ldHJ5O1xuICAgICAgcHJvY2Vzc2VkSW5wdXQuZmVhdHVyZXMucHVzaCh7J2dlb21ldHJ5JzogVXRpbC5nZW9qc29uVG9BcmNHSVMoZ2VvbWV0cnkpfSk7XG4gICAgICBwcm9jZXNzZWRJbnB1dC5nZW9tZXRyeVR5cGUgPSBVdGlsLmdlb2pzb25UeXBlVG9BcmNHSVMoZ2VvbWV0cnkudHlwZSk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIEwuUG9seWxpbmUgYW5kIEwuUG9seWdvblxuICAgIGlmIChnZW9tZXRyeS50b0dlb0pTT04pIHtcbiAgICAgIGdlb21ldHJ5ID0gZ2VvbWV0cnkudG9HZW9KU09OKCk7XG4gICAgfVxuXG4gICAgLy8gaGFuZGxlIEdlb0pTT04gZmVhdHVyZSBieSBwdWxsaW5nIG91dCB0aGUgZ2VvbWV0cnlcbiAgICBpZiAoZ2VvbWV0cnkudHlwZSA9PT0gJ0ZlYXR1cmUnKSB7XG4gICAgICAvLyBnZXQgdGhlIGdlb21ldHJ5IG9mIHRoZSBnZW9qc29uIGZlYXR1cmVcbiAgICAgIGdlb21ldHJ5ID0gZ2VvbWV0cnkuZ2VvbWV0cnk7XG4gICAgfVxuXG4gICAgLy8gY29uZmlybSB0aGF0IG91ciBHZW9KU09OIGlzIGEgcG9pbnQsIGxpbmUgb3IgcG9seWdvblxuICAgIGlmIChnZW9tZXRyeS50eXBlID09PSAnUG9pbnQnIHx8IGdlb21ldHJ5LnR5cGUgPT09ICdMaW5lU3RyaW5nJyB8fCBnZW9tZXRyeS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgIHByb2Nlc3NlZElucHV0LmZlYXR1cmVzLnB1c2goeydnZW9tZXRyeSc6IFV0aWwuZ2VvanNvblRvQXJjR0lTKGdlb21ldHJ5KX0pO1xuICAgICAgcHJvY2Vzc2VkSW5wdXQuZ2VvbWV0cnlUeXBlID0gVXRpbC5nZW9qc29uVHlwZVRvQXJjR0lTKGdlb21ldHJ5LnR5cGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdpbnZhbGlkIGdlb21ldHJ5IHBhc3NlZCBhcyBHUCBpbnB1dC4gU2hvdWxkIGJlIGFuIEwuTGF0TG5nLCBMLkxhdExuZ0JvdW5kcywgTC5NYXJrZXIgb3IgR2VvSlNPTiBQb2ludCBMaW5lIG9yIFBvbHlnb24gb2JqZWN0Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5wYXJhbXNbcGFyYW1OYW1lXSA9IHByb2Nlc3NlZElucHV0O1xuICAgIHJldHVybjtcbiAgfSxcblxuICBydW46IGZ1bmN0aW9uIChjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHRoaXMuX2RvbmUgPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuYXN5bmMgPT09IHRydWUpIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlICovXG4gICAgICB0aGlzLl9zZXJ2aWNlLnJlcXVlc3QodGhpcy5vcHRpb25zLnBhdGgsIHRoaXMucGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRKb2JJZCA9IHJlc3BvbnNlLmpvYklkO1xuICAgICAgICB0aGlzLmNoZWNrSm9iKHRoaXMuX2N1cnJlbnRKb2JJZCwgY2FsbGJhY2ssIGNvbnRleHQpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlICovXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLl9zZXJ2aWNlLnJlcXVlc3QodGhpcy5vcHRpb25zLnBhdGgsIHRoaXMucGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgZXJyb3IsIChyZXNwb25zZSAmJiB0aGlzLnByb2Nlc3NHUE91dHB1dChyZXNwb25zZSkpLCByZXNwb25zZSk7XG4gICAgICB9LCB0aGlzKTtcbiAgICB9XG4gIH0sXG5cbiAgY2hlY2tKb2I6IGZ1bmN0aW9uIChqb2JJZCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgcG9sbEpvYiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlICovXG4gICAgICB0aGlzLl9zZXJ2aWNlLnJlcXVlc3QoJ2pvYnMvJyArIGpvYklkLCB7fSwgZnVuY3Rpb24gcG9sbGVkSm9iIChlcnJvciwgcmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKHJlc3BvbnNlLmpvYlN0YXR1cyA9PT0gJ2VzcmlKb2JTdWNjZWVkZWQnKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLl9kb25lKSB7XG4gICAgICAgICAgICB0aGlzLl9kb25lID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIHRvIGRvOlxuICAgICAgICAgICAgLy8gcmVmYWN0b3IgdG8gbWFrZSBhbiBhcnJheSBvZiBhc3luYyByZXF1ZXN0cyBmb3Igb3V0cHV0XG4gICAgICAgICAgICB0aGlzLl9zZXJ2aWNlLnJlcXVlc3QoJ2pvYnMvJyArIGpvYklkICsgJy9yZXN1bHRzLycgKyB0aGlzLnBhcmFtcy5vdXRwdXRQYXJhbSwgdGhpcy5yZXN1bHRQYXJhbXMsIGZ1bmN0aW9uIHByb2Nlc3NKb2JSZXN1bHQgKGVycm9yLCByZXNwb25zZSkge1xuICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGNvbnRleHQsIGVycm9yLCAocmVzcG9uc2UgJiYgdGhpcy5wcm9jZXNzQXN5bmNPdXRwdXQocmVzcG9uc2UpKSwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKGNvdW50ZXIpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLmpvYlN0YXR1cyA9PT0gJ2VzcmlKb2JGYWlsZWQnKSB7XG4gICAgICAgICAgY2FsbGJhY2suY2FsbChjb250ZXh0LCAnSm9iIEZhaWxlZCcsIG51bGwpO1xuICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKGNvdW50ZXIpO1xuICAgICAgICB9XG4gICAgICB9LCB0aGlzKTtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgKi9cbiAgICB9LmJpbmQodGhpcyk7XG5cbiAgICB2YXIgY291bnRlciA9IHdpbmRvdy5zZXRJbnRlcnZhbChwb2xsSm9iLCB0aGlzLl9zZXJ2aWNlLm9wdGlvbnMuYXN5bmNJbnRlcnZhbCAqIDEwMDApO1xuICB9LFxuXG4gIHByb2Nlc3NHUE91dHB1dDogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIHByb2Nlc3NlZFJlc3BvbnNlID0ge307XG5cbiAgICAvLyBncmFiIHN5bmNyb25vdXMgcmVzdWx0c1xuICAgIGlmICh0aGlzLm9wdGlvbnMuYXN5bmMgPT09IGZhbHNlKSB7XG4gICAgICAvLyBsb29wIHRocm91Z2ggcmVzdWx0cyBhbmQgcGFzcyBiYWNrLCBwYXJzaW5nIGVzcmkganNvblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXNwb25zZS5yZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VbcmVzcG9uc2UucmVzdWx0c1tpXS5wYXJhbU5hbWVdO1xuICAgICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICAgICAgICBpZiAocmVzcG9uc2UucmVzdWx0c1tpXS5kYXRhVHlwZSA9PT0gJ0dQRmVhdHVyZVJlY29yZFNldExheWVyJykge1xuICAgICAgICAgIHZhciBmZWF0dXJlQ29sbGVjdGlvbiA9IFV0aWwucmVzcG9uc2VUb0ZlYXR1cmVDb2xsZWN0aW9uKHJlc3BvbnNlLnJlc3VsdHNbaV0udmFsdWUpO1xuICAgICAgICAgIHByb2Nlc3NlZFJlc3BvbnNlW3Jlc3BvbnNlLnJlc3VsdHNbaV0ucGFyYW1OYW1lXSA9IGZlYXR1cmVDb2xsZWN0aW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByb2Nlc3NlZFJlc3BvbnNlW3Jlc3BvbnNlLnJlc3VsdHNbaV0ucGFyYW1OYW1lXSA9IHJlc3BvbnNlLnJlc3VsdHNbaV0udmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgeyAvLyBncmFiIGFzeW5jIHJlc3VsdHMgc2xpZ2h0bHkgZGlmZmVyZW50bHlcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlLmpvYklkID0gdGhpcy5fY3VycmVudEpvYklkO1xuICAgICAgLy8gdmFyIHJlc3BvbnNlVmFsdWUgPSByZXNwb25zZS52YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBpZiBvdXRwdXQgaXMgYSByYXN0ZXIgbGF5ZXIsIHdlIGFsc28gbmVlZCB0byBzdHViIG91dCBhIE1hcFNlcnZpY2UgdXJsIHVzaW5nIGpvYmlkXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hc3luYyA9PT0gdHJ1ZSAmJiByZXNwb25zZS5kYXRhVHlwZSA9PT0gJ0dQUmFzdGVyRGF0YUxheWVyJykge1xuICAgICAgdmFyIGJhc2VVUkwgPSB0aGlzLm9wdGlvbnMudXJsO1xuICAgICAgdmFyIG4gPSBiYXNlVVJMLmluZGV4T2YoJ0dQU2VydmVyJyk7XG4gICAgICB2YXIgc2VydmljZVVSTCA9IGJhc2VVUkwuc2xpY2UoMCwgbikgKyAnTWFwU2VydmVyLyc7XG4gICAgICBwcm9jZXNzZWRSZXNwb25zZS5vdXRwdXRNYXBTZXJ2aWNlID0gc2VydmljZVVSTCArICdqb2JzLycgKyB0aGlzLl9jdXJyZW50Sm9iSWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb2Nlc3NlZFJlc3BvbnNlO1xuICB9LFxuXG4gIHByb2Nlc3NBc3luY091dHB1dDogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIHByb2Nlc3NlZFJlc3BvbnNlID0ge307XG4gICAgcHJvY2Vzc2VkUmVzcG9uc2Uuam9iSWQgPSB0aGlzLl9jdXJyZW50Sm9iSWQ7XG5cbiAgICAvLyBpZiBvdXRwdXQgaXMgYSByYXN0ZXIgbGF5ZXIsIHdlIGFsc28gbmVlZCB0byBzdHViIG91dCBhIE1hcFNlcnZpY2UgdXJsIHVzaW5nIGpvYmlkXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hc3luYyA9PT0gdHJ1ZSAmJiByZXNwb25zZS5kYXRhVHlwZSA9PT0gJ0dQUmFzdGVyRGF0YUxheWVyJykge1xuICAgICAgdmFyIGJhc2VVUkwgPSB0aGlzLm9wdGlvbnMudXJsO1xuICAgICAgdmFyIG4gPSBiYXNlVVJMLmluZGV4T2YoJ0dQU2VydmVyJyk7XG4gICAgICB2YXIgc2VydmljZVVSTCA9IGJhc2VVUkwuc2xpY2UoMCwgbikgKyAnTWFwU2VydmVyLyc7XG4gICAgICBwcm9jZXNzZWRSZXNwb25zZS5vdXRwdXRNYXBTZXJ2aWNlID0gc2VydmljZVVSTCArICdqb2JzLycgKyB0aGlzLl9jdXJyZW50Sm9iSWQ7XG4gICAgfVxuXG4gICAgLy8gaWYgb3V0cHV0IGlzIEdQRmVhdHVyZVJlY29yZFNldExheWVyLCBjb252ZXJ0IHRvIEdlb0pTT05cbiAgICBpZiAocmVzcG9uc2UuZGF0YVR5cGUgPT09ICdHUEZlYXR1cmVSZWNvcmRTZXRMYXllcicpIHtcbiAgICAgIHZhciBmZWF0dXJlQ29sbGVjdGlvbiA9IFV0aWwucmVzcG9uc2VUb0ZlYXR1cmVDb2xsZWN0aW9uKHJlc3BvbnNlLnZhbHVlKTtcbiAgICAgIHByb2Nlc3NlZFJlc3BvbnNlW3Jlc3BvbnNlLnBhcmFtTmFtZV0gPSBmZWF0dXJlQ29sbGVjdGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VbcmVzcG9uc2UucGFyYW1OYW1lXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9jZXNzZWRSZXNwb25zZTtcbiAgfVxuXG59KTtcblxuZXhwb3J0IGZ1bmN0aW9uIHRhc2sgKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBUYXNrKG9wdGlvbnMpO1xufVxuXG5leHBvcnQgZGVmYXVsdCB0YXNrO1xuIiwiaW1wb3J0IHsgU2VydmljZSBhcyBCYXNlU2VydmljZSB9IGZyb20gJ2VzcmktbGVhZmxldCc7XG5pbXBvcnQgeyBUYXNrIH0gZnJvbSAnLi4vVGFza3MvR2VvcHJvY2Vzc2luZyc7XG5cbmV4cG9ydCB2YXIgU2VydmljZSA9IEJhc2VTZXJ2aWNlLmV4dGVuZCh7XG4gIG9wdGlvbnM6IHtcbiAgICBhc3luY0ludGVydmFsOiAxXG4gIH0sXG5cbiAgY3JlYXRlVGFzazogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBuZXcgVGFzayh0aGlzLCB0aGlzLm9wdGlvbnMpO1xuICB9XG5cbn0pO1xuXG5leHBvcnQgZnVuY3Rpb24gc2VydmljZSAob3B0aW9ucykge1xuICByZXR1cm4gbmV3IFNlcnZpY2Uob3B0aW9ucyk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHNlcnZpY2U7XG4iXSwibmFtZXMiOlsiVGFzayIsIkJhc2VUYXNrIiwiVXRpbCIsIlNlcnZpY2UiLCJCYXNlU2VydmljZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztDQ1FPLElBQUlBLE1BQUksR0FBR0MsZ0JBQVEsQ0FBQyxNQUFNLENBQUM7O0FBRWxDLENBQUEsRUFBRSxRQUFRLEVBQUUsQ0FBQyxD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