Commit e619a3b04c27b680d9afedcb1bf79eb1e9cbb441

Authored by Luigi Serra
1 parent 4963f51a

Controllet cross browser big fix

Showing 534 changed files with 10973 additions and 6512 deletions

Too many changes.

To preserve performance only 100 of 534 files are displayed.

bower_components/google-map/.bower.json 100755 → 100644
1 1 {
2 2 "name": "google-map",
3   - "version": "1.1.0",
  3 + "version": "1.1.2",
4 4 "description": "Google Maps web components",
5 5 "homepage": "https://googlewebcomponents.github.io/google-map",
6 6 "main": [
... ... @@ -36,11 +36,11 @@
36 36 "web-component-tester": "*",
37 37 "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
38 38 },
39   - "_release": "1.1.0",
  39 + "_release": "1.1.2",
40 40 "_resolution": {
41 41 "type": "version",
42   - "tag": "1.1.0",
43   - "commit": "c45ddfa8c48a67dda1b2237589edcd45bc3f7802"
  42 + "tag": "1.1.2",
  43 + "commit": "3567129ffac7df683346b5c9d8ad0c32e9213adb"
44 44 },
45 45 "_source": "git://github.com/GoogleWebComponents/google-map.git",
46 46 "_target": "^1.0.0",
... ...
bower_components/google-map/LICENSE 100755 → 100644
bower_components/google-map/README.md 100755 → 100644
bower_components/google-map/bower.json 100755 → 100644
1 1 {
2 2 "name": "google-map",
3   - "version": "1.1.0",
  3 + "version": "1.1.2",
4 4 "description": "Google Maps web components",
5 5 "homepage": "https://googlewebcomponents.github.io/google-map",
6 6 "main": [
... ...
bower_components/google-map/demo/index.html 100755 → 100644
bower_components/google-map/google-map-directions.html 100755 → 100644
bower_components/google-map/google-map-marker.html 100755 → 100644
... ... @@ -42,8 +42,23 @@ child of `google-map`.
42 42 </dom-module>
43 43  
44 44 <script>
45   -
46 45 (function() {
  46 +
  47 + function setupDragHandler_() {
  48 + if (this.draggable) {
  49 + this.dragHandler_ = google.maps.event.addListener(
  50 + this.marker, 'dragend', onDragEnd_.bind(this));
  51 + } else {
  52 + google.maps.event.removeListener(this.dragHandler_);
  53 + this.dragHandler_ = null;
  54 + }
  55 + }
  56 +
  57 + function onDragEnd_(e, details, sender) {
  58 + this.latitude = e.latLng.lat();
  59 + this.longitude = e.latLng.lng();
  60 + }
  61 +
47 62 Polymer({
48 63  
49 64 is: 'google-map-marker',
... ... @@ -53,45 +68,53 @@ child of `google-map`.
53 68 * @param {google.maps.MouseEvent} event The mouse event.
54 69 * @event google-map-marker-click
55 70 */
  71 +
56 72 /**
57 73 * Fired when the marker icon was double clicked. Requires the clickEvents attribute to be true.
58 74 * @param {google.maps.MouseEvent} event The mouse event.
59 75 * @event google-map-marker-dblclick
60 76 */
  77 +
61 78 /**
62 79 * Fired for a mousedown on the marker. Requires the mouseEvents attribute to be true.
63 80 * @event google-map-marker-mousedown
64 81 * @param {google.maps.MouseEvent} event The mouse event.
65 82 */
  83 +
66 84 /**
67 85 * Fired when the DOM `mousemove` event is fired on the marker. Requires the mouseEvents
68 86 * attribute to be true.
69 87 * @event google-map-marker-mousemove
70 88 * @param {google.maps.MouseEvent} event The mouse event.
71 89 */
  90 +
72 91 /**
73 92 * Fired when the mouse leaves the area of the marker icon. Requires the mouseEvents attribute to be
74 93 * true.
75 94 * @event google-map-marker-mouseout
76 95 * @param {google.maps.MouseEvent} event The mouse event.
77 96 */
  97 +
78 98 /**
79 99 * Fired when the mouse enters the area of the marker icon. Requires the mouseEvents attribute to be
80 100 * true.
81 101 * @event google-map-marker-mouseover
82 102 * @param {google.maps.MouseEvent} event The mouse event.
83 103 */
  104 +
84 105 /**
85 106 * Fired for a mouseup on the marker. Requires the mouseEvents attribute to be true.
86 107 *
87 108 * @event google-map-marker-mouseup
88 109 * @param {google.maps.MouseEvent} event The mouse event.
89 110 */
  111 +
90 112 /**
91 113 * Fired for a rightclick on the marker. Requires the clickEvents attribute to be true.
92 114 * @event google-map-marker-rightclick
93 115 * @param {google.maps.MouseEvent} event The mouse event.
94 116 */
  117 +
95 118 properties: {
96 119 /**
97 120 * A Google Maps marker object.
... ... @@ -161,6 +184,7 @@ child of `google-map`.
161 184 value: null,
162 185 reflectToAttribute: true
163 186 },
  187 +
164 188 /**
165 189 * The marker's latitude coordinate.
166 190 */
... ... @@ -168,6 +192,16 @@ child of `google-map`.
168 192 type: Number,
169 193 value: null,
170 194 reflectToAttribute: true
  195 + },
  196 +
  197 + /**
  198 + * A animation for the marker. "DROP" or "BOUNCE". See
  199 + * https://developers.google.com/maps/documentation/javascript/examples/marker-animations.
  200 + */
  201 + animation: {
  202 + type: String,
  203 + value: null,
  204 + observer: '_animationChanged'
171 205 }
172 206 },
173 207  
... ... @@ -231,6 +265,12 @@ child of `google-map`.
231 265 }
232 266 },
233 267  
  268 + _animationChanged: function() {
  269 + if (this.marker) {
  270 + this.marker.setAnimation(google.maps.Animation[this.animation]);
  271 + }
  272 + },
  273 +
234 274 _iconChanged: function() {
235 275 if (this.marker) {
236 276 this.marker.setIcon(this.icon);
... ... @@ -288,8 +328,12 @@ child of `google-map`.
288 328 this._listeners = {};
289 329 this.marker = new google.maps.Marker({
290 330 map: this.map,
291   - position: {lat: this.latitude, lng: this.longitude},
  331 + position: {
  332 + lat: parseFloat(this.latitude),
  333 + lng: parseFloat(this.longitude)
  334 + },
292 335 title: this.title,
  336 + animation: google.maps.Animation[this.animation],
293 337 draggable: this.draggable,
294 338 visible: !this.hidden,
295 339 icon: this.icon,
... ... @@ -336,19 +380,5 @@ child of `google-map`.
336 380 }
337 381 });
338 382  
339   - function setupDragHandler_() {
340   - if (this.draggable) {
341   - this.dragHandler_ = google.maps.event.addListener(
342   - this.marker, 'dragend', onDragEnd_.bind(this));
343   - } else {
344   - google.maps.event.removeListener(this.dragHandler_);
345   - this.dragHandler_ = null;
346   - }
347   - }
348   -
349   - function onDragEnd_(e, details, sender) {
350   - this.latitude = e.latLng.lat();
351   - this.longitude = e.latLng.lng();
352   - }
353 383 })();
354 384 </script>
... ...
bower_components/google-map/google-map-search.html 100755 → 100644
... ... @@ -11,7 +11,7 @@ information on the API.
11 11 #### Example:
12 12  
13 13 <template is="dom-bind">
14   - <google-map-search map="[[map]]" query="Pizza"
  14 + <google-map-search map="[[map]]" libraries="places" query="Pizza"
15 15 results="{{results}}"></google-map-search>
16 16 <google-map map="{{map}}" latitude="37.779"
17 17 longitude="-122.3892">
... ... @@ -119,7 +119,7 @@ information on the API.
119 119 location: {
120 120 type: Object,
121 121 value: null,
122   - readyOnly: true
  122 + readOnly: true
123 123 }
124 124 },
125 125  
... ... @@ -129,6 +129,13 @@ information on the API.
129 129 ],
130 130  
131 131 /**
  132 + * Fired when the details of a place are returned.
  133 + *
  134 + * @event google-map-search-place-detail
  135 + * @param {google.maps.MarkerPlace} detail The place details.
  136 + */
  137 +
  138 + /**
132 139 * Fired when the search element returns a result.
133 140 *
134 141 * @event google-map-search-results
... ... @@ -166,6 +173,26 @@ information on the API.
166 173 }
167 174 },
168 175  
  176 + /**
  177 + * Fetches details for a given place.
  178 + * @param {String} placeId The place id.
  179 + * @return {Promise} place The place information.
  180 + */
  181 + getDetails: function(placeId) {
  182 + var places = new google.maps.places.PlacesService(this.map);
  183 +
  184 + return new Promise(function(resolve, reject) {
  185 + places.getDetails({placeId: placeId}, function(place, status) {
  186 + if (status === google.maps.places.PlacesServiceStatus.OK) {
  187 + resolve(place);
  188 + this.fire('google-map-search-place-detail', place);
  189 + } else {
  190 + reject(status);
  191 + }
  192 + }.bind(this));
  193 + }.bind(this));
  194 + },
  195 +
169 196 _gotResults: function(results, status) {
170 197 this.results = results.map(function(result) {
171 198 // obtain lat/long from geometry
... ...
bower_components/google-map/google-map.html 100755 → 100644
... ... @@ -204,7 +204,8 @@ The `google-map` element renders a Google Map.
204 204 zoom: {
205 205 type: Number,
206 206 value: 10,
207   - observer: '_zoomChanged'
  207 + observer: '_zoomChanged',
  208 + notify: true
208 209 },
209 210  
210 211 /**
... ... @@ -221,7 +222,8 @@ The `google-map` element renders a Google Map.
221 222 mapType: {
222 223 type: String,
223 224 value: 'roadmap', // roadmap, satellite, hybrid, terrain,
224   - observer: '_mapTypeChanged'
  225 + observer: '_mapTypeChanged',
  226 + notify: true
225 227 },
226 228  
227 229 /**
... ... @@ -671,6 +673,10 @@ The `google-map` element renders a Google Map.
671 673 google.maps.event.addListener(this.map, 'zoom_changed', function() {
672 674 this.zoom = this.map.getZoom();
673 675 }.bind(this));
  676 +
  677 + google.maps.event.addListener(this.map, 'maptypeid_changed', function() {
  678 + this.mapType = this.map.getMapTypeId();
  679 + }.bind(this));
674 680  
675 681 this._clickEventsChanged();
676 682 this._dragEventsChanged();
... ...
bower_components/google-map/index.html 100755 → 100644
bower_components/google-map/metadata.html 100755 → 100644
bower_components/hydrolysis/.bower.json 100755 → 100644
... ... @@ -19,13 +19,13 @@
19 19 "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
20 20 "web-component-tester": "*"
21 21 },
22   - "version": "1.15.2",
  22 + "version": "1.19.0",
23 23 "homepage": "https://github.com/Polymer/hydrolysis",
24   - "_release": "1.15.2",
  24 + "_release": "1.19.0",
25 25 "_resolution": {
26 26 "type": "version",
27   - "tag": "v1.15.2",
28   - "commit": "3b255182fd39a273c255ac2a49db8d06d96f667d"
  27 + "tag": "v1.19.0",
  28 + "commit": "8b0e8410712cc465a35b854ce86bfb6b23e2e9ab"
29 29 },
30 30 "_source": "git://github.com/Polymer/hydrolysis.git",
31 31 "_target": "^1.11",
... ...
bower_components/hydrolysis/.editorconfig 100755 → 100644
bower_components/hydrolysis/.gitattributes 100755 → 100644
bower_components/hydrolysis/API.md 100755 → 100644
... ... @@ -24,31 +24,38 @@ Static analysis for Polymer.
24 24 * [.Analyzer](#hydrolysis.Analyzer)
25 25 * [new Analyzer(attachAST, [loader])](#new_hydrolysis.Analyzer_new)
26 26 * _instance_
27   - * [.elements](#hydrolysis.Analyzer#elements) : <code>Array.&lt;ElementDescriptor&gt;</code>
28   - * [.elementsByTagName](#hydrolysis.Analyzer#elementsByTagName) : <code>Object.&lt;string, ElementDescriptor&gt;</code>
29   - * [.features](#hydrolysis.Analyzer#features) : <code>Array.&lt;FeatureDescriptor&gt;</code>
30   - * [.behaviors](#hydrolysis.Analyzer#behaviors) : <code>Array.&lt;BehaviorDescriptor&gt;</code>
31   - * [.html](#hydrolysis.Analyzer#html) : <code>Object.&lt;string, AnalyzedDocument&gt;</code>
32   - * [.parsedDocuments](#hydrolysis.Analyzer#parsedDocuments) : <code>Object</code>
33   - * [._getDependencies(href, [found], [transitive])](#hydrolysis.Analyzer#_getDependencies) ⇒ <code>Array.&lt;string&gt;</code>
34   - * [.metadataTree(href)](#hydrolysis.Analyzer#metadataTree) ⇒ <code>Promise</code>
35   - * [.nodeWalkDocuments(predicate)](#hydrolysis.Analyzer#nodeWalkDocuments) ⇒ <code>Object</code>
36   - * [.annotate()](#hydrolysis.Analyzer#annotate)
37   - * [.clean()](#hydrolysis.Analyzer#clean)
  27 + * [.elements](#hydrolysis.Analyzer+elements) : <code>Array.&lt;ElementDescriptor&gt;</code>
  28 + * [.elementsByTagName](#hydrolysis.Analyzer+elementsByTagName) : <code>Object.&lt;string, ElementDescriptor&gt;</code>
  29 + * [.features](#hydrolysis.Analyzer+features) : <code>Array.&lt;FeatureDescriptor&gt;</code>
  30 + * [.behaviors](#hydrolysis.Analyzer+behaviors) : <code>Array.&lt;BehaviorDescriptor&gt;</code>
  31 + * [.behaviorsByName](#hydrolysis.Analyzer+behaviorsByName) : <code>Object.&lt;string, BehaviorDescriptor&gt;</code>
  32 + * [.html](#hydrolysis.Analyzer+html) : <code>Object.&lt;string, AnalyzedDocument&gt;</code>
  33 + * [.parsedDocuments](#hydrolysis.Analyzer+parsedDocuments) : <code>Object</code>
  34 + * [.parsedScripts](#hydrolysis.Analyzer+parsedScripts) : <code>Object.&lt;string, Array.&lt;ParsedJS&gt;&gt;</code>
  35 + * [._content](#hydrolysis.Analyzer+_content) : <code>Object</code>
  36 + * [._getDependencies(href, [found], [transitive])](#hydrolysis.Analyzer+_getDependencies) ⇒ <code>Array.&lt;string&gt;</code>
  37 + * [.metadataTree(href)](#hydrolysis.Analyzer+metadataTree) ⇒ <code>Promise</code>
  38 + * [.getLoadedAst(href, [loaded])](#hydrolysis.Analyzer+getLoadedAst) ⇒ <code>Promise.&lt;DocumentAST&gt;</code>
  39 + * [.nodeWalkDocuments(predicate)](#hydrolysis.Analyzer+nodeWalkDocuments) ⇒ <code>Object</code>
  40 + * [.nodeWalkAllDocuments(predicate)](#hydrolysis.Analyzer+nodeWalkAllDocuments) ⇒ <code>Object</code>
  41 + * [.annotate()](#hydrolysis.Analyzer+annotate)
  42 + * [.clean()](#hydrolysis.Analyzer+clean)
38 43 * _static_
39 44 * [.analyze(href, [options])](#hydrolysis.Analyzer.analyze) ⇒ <code>Promise.&lt;Analyzer&gt;</code>
40 45 * [.FileLoader](#hydrolysis.FileLoader)
41 46 * [new FileLoader()](#new_hydrolysis.FileLoader_new)
42   - * [.addResolver(resolver)](#hydrolysis.FileLoader#addResolver)
43   - * [.request(url)](#hydrolysis.FileLoader#request) ⇒ <code>Promise.&lt;string&gt;</code>
  47 + * [.addResolver(resolver)](#hydrolysis.FileLoader+addResolver)
  48 + * [.request(url)](#hydrolysis.FileLoader+request) ⇒ <code>Promise.&lt;string&gt;</code>
44 49 * [.FSResolver](#hydrolysis.FSResolver)
45 50 * [new FSResolver(config)](#new_hydrolysis.FSResolver_new)
46 51 * [.NoopResolver](#hydrolysis.NoopResolver)
47 52 * [new NoopResolver(config)](#new_hydrolysis.NoopResolver_new)
48   - * [.accept(uri, deferred)](#hydrolysis.NoopResolver#accept) ⇒ <code>boolean</code>
  53 + * [.accept(uri, deferred)](#hydrolysis.NoopResolver+accept) ⇒ <code>boolean</code>
49 54 * [.XHRResolver](#hydrolysis.XHRResolver)
50 55 * [new XHRResolver(config)](#new_hydrolysis.XHRResolver_new)
51 56 * [.DocumentAST](#hydrolysis.DocumentAST) : <code>Object</code>
  57 + * [.JSAST](#hydrolysis.JSAST) : <code>Object</code>
  58 + * [.ParsedJS](#hydrolysis.ParsedJS) : <code>Object</code>
52 59 * [.ElementDescriptor](#hydrolysis.ElementDescriptor) : <code>Object</code>
53 60 * [.FeatureDescriptor](#hydrolysis.FeatureDescriptor) : <code>Object</code>
54 61 * [.BehaviorDescriptor](#hydrolysis.BehaviorDescriptor) : <code>Object</code>
... ... @@ -64,17 +71,22 @@ Static analysis for Polymer.
64 71 * [.Analyzer](#hydrolysis.Analyzer)
65 72 * [new Analyzer(attachAST, [loader])](#new_hydrolysis.Analyzer_new)
66 73 * _instance_
67   - * [.elements](#hydrolysis.Analyzer#elements) : <code>Array.&lt;ElementDescriptor&gt;</code>
68   - * [.elementsByTagName](#hydrolysis.Analyzer#elementsByTagName) : <code>Object.&lt;string, ElementDescriptor&gt;</code>
69   - * [.features](#hydrolysis.Analyzer#features) : <code>Array.&lt;FeatureDescriptor&gt;</code>
70   - * [.behaviors](#hydrolysis.Analyzer#behaviors) : <code>Array.&lt;BehaviorDescriptor&gt;</code>
71   - * [.html](#hydrolysis.Analyzer#html) : <code>Object.&lt;string, AnalyzedDocument&gt;</code>
72   - * [.parsedDocuments](#hydrolysis.Analyzer#parsedDocuments) : <code>Object</code>
73   - * [._getDependencies(href, [found], [transitive])](#hydrolysis.Analyzer#_getDependencies) ⇒ <code>Array.&lt;string&gt;</code>
74   - * [.metadataTree(href)](#hydrolysis.Analyzer#metadataTree) ⇒ <code>Promise</code>
75   - * [.nodeWalkDocuments(predicate)](#hydrolysis.Analyzer#nodeWalkDocuments) ⇒ <code>Object</code>
76   - * [.annotate()](#hydrolysis.Analyzer#annotate)
77   - * [.clean()](#hydrolysis.Analyzer#clean)
  74 + * [.elements](#hydrolysis.Analyzer+elements) : <code>Array.&lt;ElementDescriptor&gt;</code>
  75 + * [.elementsByTagName](#hydrolysis.Analyzer+elementsByTagName) : <code>Object.&lt;string, ElementDescriptor&gt;</code>
  76 + * [.features](#hydrolysis.Analyzer+features) : <code>Array.&lt;FeatureDescriptor&gt;</code>
  77 + * [.behaviors](#hydrolysis.Analyzer+behaviors) : <code>Array.&lt;BehaviorDescriptor&gt;</code>
  78 + * [.behaviorsByName](#hydrolysis.Analyzer+behaviorsByName) : <code>Object.&lt;string, BehaviorDescriptor&gt;</code>
  79 + * [.html](#hydrolysis.Analyzer+html) : <code>Object.&lt;string, AnalyzedDocument&gt;</code>
  80 + * [.parsedDocuments](#hydrolysis.Analyzer+parsedDocuments) : <code>Object</code>
  81 + * [.parsedScripts](#hydrolysis.Analyzer+parsedScripts) : <code>Object.&lt;string, Array.&lt;ParsedJS&gt;&gt;</code>
  82 + * [._content](#hydrolysis.Analyzer+_content) : <code>Object</code>
  83 + * [._getDependencies(href, [found], [transitive])](#hydrolysis.Analyzer+_getDependencies) ⇒ <code>Array.&lt;string&gt;</code>
  84 + * [.metadataTree(href)](#hydrolysis.Analyzer+metadataTree) ⇒ <code>Promise</code>
  85 + * [.getLoadedAst(href, [loaded])](#hydrolysis.Analyzer+getLoadedAst) ⇒ <code>Promise.&lt;DocumentAST&gt;</code>
  86 + * [.nodeWalkDocuments(predicate)](#hydrolysis.Analyzer+nodeWalkDocuments) ⇒ <code>Object</code>
  87 + * [.nodeWalkAllDocuments(predicate)](#hydrolysis.Analyzer+nodeWalkAllDocuments) ⇒ <code>Object</code>
  88 + * [.annotate()](#hydrolysis.Analyzer+annotate)
  89 + * [.clean()](#hydrolysis.Analyzer+clean)
78 90 * _static_
79 91 * [.analyze(href, [options])](#hydrolysis.Analyzer.analyze) ⇒ <code>Promise.&lt;Analyzer&gt;</code>
80 92  
... ... @@ -88,38 +100,55 @@ A database of Polymer metadata defined in HTML
88 100 | attachAST | <code>boolean</code> | If true, attach a parse5 compliant AST |
89 101 | [loader] | <code>FileLoader</code> | An optional `FileLoader` used to load external resources |
90 102  
91   -<a name="hydrolysis.Analyzer#elements"></a>
  103 +<a name="hydrolysis.Analyzer+elements"></a>
92 104 #### analyzer.elements : <code>Array.&lt;ElementDescriptor&gt;</code>
93 105 A list of all elements the `Analyzer` has metadata for.
94 106  
95 107 **Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
96   -<a name="hydrolysis.Analyzer#elementsByTagName"></a>
  108 +<a name="hydrolysis.Analyzer+elementsByTagName"></a>
97 109 #### analyzer.elementsByTagName : <code>Object.&lt;string, ElementDescriptor&gt;</code>
98 110 A view into `elements`, keyed by tag name.
99 111  
100 112 **Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
101   -<a name="hydrolysis.Analyzer#features"></a>
  113 +<a name="hydrolysis.Analyzer+features"></a>
102 114 #### analyzer.features : <code>Array.&lt;FeatureDescriptor&gt;</code>
103 115 A list of API features added to `Polymer.Base` encountered by the
104 116 analyzer.
105 117  
106 118 **Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
107   -<a name="hydrolysis.Analyzer#behaviors"></a>
  119 +<a name="hydrolysis.Analyzer+behaviors"></a>
108 120 #### analyzer.behaviors : <code>Array.&lt;BehaviorDescriptor&gt;</code>
109 121 The behaviors collected by the analysis pass.
110 122  
111 123 **Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
112   -<a name="hydrolysis.Analyzer#html"></a>
  124 +<a name="hydrolysis.Analyzer+behaviorsByName"></a>
  125 +#### analyzer.behaviorsByName : <code>Object.&lt;string, BehaviorDescriptor&gt;</code>
  126 +The behaviors collected by the analysis pass by name.
  127 +
  128 +**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
  129 +<a name="hydrolysis.Analyzer+html"></a>
113 130 #### analyzer.html : <code>Object.&lt;string, AnalyzedDocument&gt;</code>
114 131 A map, keyed by absolute path, of Document metadata.
115 132  
116 133 **Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
117   -<a name="hydrolysis.Analyzer#parsedDocuments"></a>
  134 +<a name="hydrolysis.Analyzer+parsedDocuments"></a>
118 135 #### analyzer.parsedDocuments : <code>Object</code>
119 136 A map, keyed by path, of HTML document ASTs.
120 137  
121 138 **Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
122   -<a name="hydrolysis.Analyzer#_getDependencies"></a>
  139 +<a name="hydrolysis.Analyzer+parsedScripts"></a>
  140 +#### analyzer.parsedScripts : <code>Object.&lt;string, Array.&lt;ParsedJS&gt;&gt;</code>
  141 +A map, keyed by path, of JS script ASTs.
  142 +
  143 +If the path is an HTML file with multiple scripts, the entry will be an array of scripts.
  144 +
  145 +**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
  146 +<a name="hydrolysis.Analyzer+_content"></a>
  147 +#### analyzer._content : <code>Object</code>
  148 +A map, keyed by path, of document content.
  149 +
  150 +**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
  151 +<a name="hydrolysis.Analyzer+_getDependencies"></a>
123 152 #### analyzer._getDependencies(href, [found], [transitive]) ⇒ <code>Array.&lt;string&gt;</code>
124 153 List all the html dependencies for the document at `href`.
125 154  
... ... @@ -132,7 +161,7 @@ List all the html dependencies for the document at `href`.
132 161 | [found] | <code>Object.&lt;string, boolean&gt;</code> | An object keyed by URL of the already resolved dependencies. |
133 162 | [transitive] | <code>boolean</code> | Whether to load transitive dependencies. Defaults to true. |
134 163  
135   -<a name="hydrolysis.Analyzer#metadataTree"></a>
  164 +<a name="hydrolysis.Analyzer+metadataTree"></a>
136 165 #### analyzer.metadataTree(href) ⇒ <code>Promise</code>
137 166 Returns a promise that resolves to a POJO representation of the import
138 167 tree, in a format that maintains the ordering of the HTML imports spec.
... ... @@ -143,9 +172,35 @@ tree, in a format that maintains the ordering of the HTML imports spec.
143 172 | --- | --- | --- |
144 173 | href | <code>string</code> | the import to get metadata for. |
145 174  
146   -<a name="hydrolysis.Analyzer#nodeWalkDocuments"></a>
  175 +<a name="hydrolysis.Analyzer+getLoadedAst"></a>
  176 +#### analyzer.getLoadedAst(href, [loaded]) ⇒ <code>Promise.&lt;DocumentAST&gt;</code>
  177 +Returns a promise resolving to a form of the AST with all links replaced
  178 +with the document they link to. .css and .script files become &lt;style&gt; and
  179 +&lt;script&gt;, respectively.
  180 +
  181 +The elements in the loaded document are unmodified from their original
  182 +documents.
  183 +
  184 +**Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
  185 +
  186 +| Param | Type | Description |
  187 +| --- | --- | --- |
  188 +| href | <code>string</code> | The document to load. |
  189 +| [loaded] | <code>Object.&lt;string, boolean&gt;</code> | An object keyed by already loaded documents. |
  190 +
  191 +<a name="hydrolysis.Analyzer+nodeWalkDocuments"></a>
147 192 #### analyzer.nodeWalkDocuments(predicate) ⇒ <code>Object</code>
148   -Calls `dom5.nodeWalk` on each document that `Anayzler` has laoded.
  193 +Calls `dom5.nodeWalkAll` on each document that `Anayzler` has laoded.
  194 +
  195 +**Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
  196 +
  197 +| Param | Type | Description |
  198 +| --- | --- | --- |
  199 +| predicate | <code>Object</code> | A dom5 predicate. |
  200 +
  201 +<a name="hydrolysis.Analyzer+nodeWalkAllDocuments"></a>
  202 +#### analyzer.nodeWalkAllDocuments(predicate) ⇒ <code>Object</code>
  203 +Calls `dom5.nodeWalkAll` on each document that `Anayzler` has laoded.
149 204  
150 205 **Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
151 206  
... ... @@ -153,12 +208,12 @@ Calls `dom5.nodeWalk` on each document that `Anayzler` has laoded.
153 208 | --- | --- | --- |
154 209 | predicate | <code>Object</code> | A dom5 predicate. |
155 210  
156   -<a name="hydrolysis.Analyzer#annotate"></a>
  211 +<a name="hydrolysis.Analyzer+annotate"></a>
157 212 #### analyzer.annotate()
158 213 Annotates all loaded metadata with its documentation.
159 214  
160 215 **Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
161   -<a name="hydrolysis.Analyzer#clean"></a>
  216 +<a name="hydrolysis.Analyzer+clean"></a>
162 217 #### analyzer.clean()
163 218 Removes redundant properties from the collected descriptors.
164 219  
... ... @@ -185,14 +240,14 @@ In order to properly filter paths, `href` _must_ be an absolute URI.
185 240  
186 241 * [.FileLoader](#hydrolysis.FileLoader)
187 242 * [new FileLoader()](#new_hydrolysis.FileLoader_new)
188   - * [.addResolver(resolver)](#hydrolysis.FileLoader#addResolver)
189   - * [.request(url)](#hydrolysis.FileLoader#request) ⇒ <code>Promise.&lt;string&gt;</code>
  243 + * [.addResolver(resolver)](#hydrolysis.FileLoader+addResolver)
  244 + * [.request(url)](#hydrolysis.FileLoader+request) ⇒ <code>Promise.&lt;string&gt;</code>
190 245  
191 246 <a name="new_hydrolysis.FileLoader_new"></a>
192 247 #### new FileLoader()
193 248 A FileLoader lets you resolve URLs with a set of potential resolvers.
194 249  
195   -<a name="hydrolysis.FileLoader#addResolver"></a>
  250 +<a name="hydrolysis.FileLoader+addResolver"></a>
196 251 #### fileLoader.addResolver(resolver)
197 252 Add an instance of a Resolver class to the list of url resolvers
198 253  
... ... @@ -205,7 +260,7 @@ The first resolver to &quot;accept&quot; the url wins.
205 260 | --- | --- | --- |
206 261 | resolver | <code>Resolver</code> | The resolver to add. |
207 262  
208   -<a name="hydrolysis.FileLoader#request"></a>
  263 +<a name="hydrolysis.FileLoader+request"></a>
209 264 #### fileLoader.request(url) ⇒ <code>Promise.&lt;string&gt;</code>
210 265 Return a promise for an absolute url
211 266  
... ... @@ -241,7 +296,7 @@ Resolves requests via the file system.
241 296  
242 297 * [.NoopResolver](#hydrolysis.NoopResolver)
243 298 * [new NoopResolver(config)](#new_hydrolysis.NoopResolver_new)
244   - * [.accept(uri, deferred)](#hydrolysis.NoopResolver#accept) ⇒ <code>boolean</code>
  299 + * [.accept(uri, deferred)](#hydrolysis.NoopResolver+accept) ⇒ <code>boolean</code>
245 300  
246 301 <a name="new_hydrolysis.NoopResolver_new"></a>
247 302 #### new NoopResolver(config)
... ... @@ -252,7 +307,7 @@ A resolver that resolves to null any uri matching config.
252 307 | --- | --- | --- |
253 308 | config | <code>string</code> | The url to `accept`. |
254 309  
255   -<a name="hydrolysis.NoopResolver#accept"></a>
  310 +<a name="hydrolysis.NoopResolver+accept"></a>
256 311 #### noopResolver.accept(uri, deferred) ⇒ <code>boolean</code>
257 312 **Kind**: instance method of <code>[NoopResolver](#hydrolysis.NoopResolver)</code>
258 313 **Returns**: <code>boolean</code> - Whether the URI is handled by this resolver.
... ... @@ -280,6 +335,23 @@ Construct a resolver that requests resources over XHR.
280 335 Parse5's representation of a parsed html document
281 336  
282 337 **Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
  338 +<a name="hydrolysis.JSAST"></a>
  339 +### hydrolysis.JSAST : <code>Object</code>
  340 +espree's representation of a parsed html document
  341 +
  342 +**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
  343 +<a name="hydrolysis.ParsedJS"></a>
  344 +### hydrolysis.ParsedJS : <code>Object</code>
  345 +Package of a parsed JS script
  346 +
  347 +**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
  348 +**Properties**
  349 +
  350 +| Name | Type | Description |
  351 +| --- | --- | --- |
  352 +| ast | <code>JSAST</code> | The script's AST |
  353 +| scriptElement | <code>DocumentAST</code> | If inline, the script's containing tag. |
  354 +
283 355 <a name="hydrolysis.ElementDescriptor"></a>
284 356 ### hydrolysis.ElementDescriptor : <code>Object</code>
285 357 The metadata for a single polymer element
... ...
bower_components/hydrolysis/LICENSE 100755 → 100644
bower_components/hydrolysis/README.md 100755 → 100644
1 1 # hydrolysis
2 2  
3   -Static anlaysis utilities for polymer.
  3 +Static analysis utilities for polymer.
4 4  
5 5 ## Install
6 6 ```
... ...
bower_components/hydrolysis/bower.json 100755 → 100644
... ... @@ -19,5 +19,5 @@
19 19 "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
20 20 "web-component-tester": "*"
21 21 },
22   - "version": "1.15.1"
  22 + "version": "1.19.0"
23 23 }
... ...
bower_components/hydrolysis/hydrolysis-analyzer.html 100755 → 100644
bower_components/hydrolysis/hydrolysis.html 100755 → 100644
bower_components/hydrolysis/hydrolysis.js 100755 → 100644
... ... @@ -13,7 +13,6 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ
13 13 'use strict';
14 14 // jshint -W079
15 15 var Promise = global.Promise || require('es6-promise').Promise;
16   -require("setimmediate");
17 16 // jshint +W079
18 17  
19 18 var dom5 = require('dom5');
... ... @@ -42,6 +41,20 @@ var EMPTY_METADATA = {elements: [], features: [], behaviors: []};
42 41 */
43 42  
44 43 /**
  44 + * espree's representation of a parsed html document
  45 + * @typedef {Object} JSAST
  46 + * @memberof hydrolysis
  47 + */
  48 +
  49 +/**
  50 + * Package of a parsed JS script
  51 + * @typedef {Object} ParsedJS
  52 + * @property {JSAST} ast The script's AST
  53 + * @property {DocumentAST} scriptElement If inline, the script's containing tag.
  54 + * @memberof hydrolysis
  55 + */
  56 +
  57 +/**
45 58 * The metadata for a single polymer element
46 59 * @typedef {Object} ElementDescriptor
47 60 * @memberof hydrolysis
... ... @@ -125,13 +138,18 @@ var Analyzer = function Analyzer(attachAST,
125 138 this.behaviors = [];
126 139  
127 140 /**
  141 + * The behaviors collected by the analysis pass by name.
  142 + *
  143 + * @member {Object<string,BehaviorDescriptor>}
  144 + */
  145 + this.behaviorsByName = {};
  146 +
  147 + /**
128 148 * A map, keyed by absolute path, of Document metadata.
129 149 * @member {Object<string,AnalyzedDocument>}
130 150 */
131 151 this.html = {};
132 152  
133   - this._parsedDocuments = {};
134   -
135 153 /**
136 154 * A map, keyed by path, of HTML document ASTs.
137 155 * @type {Object}
... ... @@ -139,6 +157,17 @@ var Analyzer = function Analyzer(attachAST,
139 157 this.parsedDocuments = {};
140 158  
141 159 /**
  160 + * A map, keyed by path, of JS script ASTs.
  161 + *
  162 + * If the path is an HTML file with multiple scripts, the entry will be an array of scripts.
  163 + *
  164 + * @type {Object<string,Array<ParsedJS>>}
  165 + */
  166 + this.parsedScripts = {};
  167 +
  168 +
  169 +
  170 + /**
142 171 * A map, keyed by path, of document content.
143 172 * @type {Object}
144 173 */
... ... @@ -207,11 +236,14 @@ function _defaultFilter(href) {
207 236 Analyzer.prototype.load = function load(href) {
208 237 return this.loader.request(href).then(function(content) {
209 238 return new Promise(function(resolve, reject) {
210   - setImmediate(function() {
  239 + setTimeout(function() {
211 240 this._content[href] = content;
212 241 resolve(this._parseHTML(content, href));
213   - }.bind(this));
214   - }.bind(this));
  242 + }.bind(this), 0);
  243 + }.bind(this)).catch(function(err){
  244 + console.error("Error processing document at " + href);
  245 + throw err;
  246 + });
215 247 }.bind(this));
216 248 };
217 249  
... ... @@ -240,8 +272,26 @@ Analyzer.prototype._parseHTML = function _parseHTML(htmlImport,
240 272 var htmlLoaded = Promise.resolve(parsed);
241 273 if (parsed.script) {
242 274 metadataLoaded = this._processScripts(parsed.script, href);
243   - depsLoaded.push(metadataLoaded);
244 275 }
  276 + var commentText = parsed.comment.map(function(comment){
  277 + return dom5.getTextContent(comment);
  278 + });
  279 + var pseudoElements = docs.parsePseudoElements(commentText);
  280 + pseudoElements.forEach(function(element){
  281 + element.contentHref = href;
  282 + this.elements.push(element);
  283 + this.elementsByTagName[element.is] = element;
  284 + }.bind(this));
  285 + metadataLoaded = metadataLoaded.then(function(metadata){
  286 + var metadataEntry = {
  287 + elements: pseudoElements,
  288 + features: [],
  289 + behaviors: []
  290 + };
  291 + return [metadata, metadataEntry].reduce(reduceMetadata);
  292 + });
  293 + depsLoaded.push(metadataLoaded);
  294 +
245 295  
246 296 if (this.loader) {
247 297 var baseUri = href;
... ... @@ -278,7 +328,6 @@ Analyzer.prototype._parseHTML = function _parseHTML(htmlImport,
278 328 depsLoaded = Promise.all(depsLoaded)
279 329 .then(function() {return depHrefs;})
280 330 .catch(function(err) {throw err;});
281   - this._parsedDocuments[href] = parsed;
282 331 this.parsedDocuments[href] = parsed.ast;
283 332 this.html[href] = {
284 333 href: href,
... ... @@ -305,7 +354,7 @@ Analyzer.prototype._processScript = function _processScript(script, href) {
305 354 var parsedJs;
306 355 if (!src) {
307 356 try {
308   - parsedJs = jsParse(script.childNodes[0].value);
  357 + parsedJs = jsParse((script.childNodes.length) ? script.childNodes[0].value : '');
309 358 } catch (err) {
310 359 // Figure out the correct line number for the error.
311 360 var line = 0;
... ... @@ -318,7 +367,7 @@ Analyzer.prototype._processScript = function _processScript(script, href) {
318 367 col += err.column;
319 368 var message = "Error parsing script in " + href + " at " + line + ":" + col;
320 369 message += "\n" + err.description;
321   - throw new Error(message);
  370 + return Promise.reject(new Error(message));
322 371 }
323 372 if (parsedJs.elements) {
324 373 parsedJs.elements.forEach(function(element) {
... ... @@ -342,9 +391,22 @@ Analyzer.prototype._processScript = function _processScript(script, href) {
342 391 if (parsedJs.behaviors) {
343 392 parsedJs.behaviors.forEach(function(behavior){
344 393 behavior.contentHref = href;
345   - });
  394 + this.behaviorsByName[behavior.is] = behavior;
  395 + this.behaviorsByName[behavior.symbol] = behavior;
  396 + }.bind(this));
346 397 this.behaviors = this.behaviors.concat(parsedJs.behaviors);
347 398 }
  399 + if (!Object.hasOwnProperty.call(this.parsedScripts, href)) {
  400 + this.parsedScripts[href] = [];
  401 + }
  402 + var scriptElement;
  403 + if (script.__ownerDocument && script.__ownerDocument == href) {
  404 + scriptElement = script;
  405 + }
  406 + this.parsedScripts[href].push({
  407 + ast: parsedJs.parsedScript,
  408 + scriptElement: scriptElement
  409 + });
348 410 return parsedJs;
349 411 }
350 412 if (this.loader) {
... ... @@ -417,6 +479,38 @@ Analyzer.prototype._getDependencies = function _getDependencies(href, found, tra
417 479 });
418 480 };
419 481  
  482 +function matchesDocumentFolder(descriptor, href) {
  483 + if (!descriptor.contentHref) {
  484 + return false;
  485 + }
  486 + var descriptorDoc = url.parse(descriptor.contentHref);
  487 + if (!descriptorDoc || !descriptorDoc.pathname) {
  488 + return false;
  489 + }
  490 + var searchDoc = url.parse(href);
  491 + if (!searchDoc || !searchDoc.pathname) {
  492 + return false;
  493 + }
  494 + var searchPath = searchDoc.pathname;
  495 + var lastSlash = searchPath.lastIndexOf("/");
  496 + if (lastSlash > 0) {
  497 + searchPath = searchPath.slice(0, lastSlash);
  498 + }
  499 + return descriptorDoc.pathname.indexOf(searchPath) === 0;
  500 +}
  501 +
  502 +Analyzer.prototype.elementsForFolder = function elementsForFolder(href) {
  503 + return this.elements.filter(function(element){
  504 + return matchesDocumentFolder(element, href);
  505 + });
  506 +};
  507 +
  508 +Analyzer.prototype.behaviorsForFolder = function behaviorsForFolder(href) {
  509 + return this.behaviors.filter(function(behavior){
  510 + return matchesDocumentFolder(behavior, href);
  511 + });
  512 +};
  513 +
420 514 /**
421 515 * Returns a promise that resolves to a POJO representation of the import
422 516 * tree, in a format that maintains the ordering of the HTML imports spec.
... ... @@ -545,12 +639,12 @@ Analyzer.prototype._inlineImports = function _inlineImports(ast, href, loaded) {
545 639  
546 640 /**
547 641 * Returns a promise resolving to a form of the AST with all links replaced
548   - * with the document they link to. .css and .script files become <style> and
549   - * <script>, respectively.
  642 + * with the document they link to. .css and .script files become &lt;style&gt; and
  643 + * &lt;script&gt;, respectively.
550 644 *
551 645 * The elements in the loaded document are unmodified from their original
552 646 * documents.
553   - *
  647 + *
554 648 * @param {string} href The document to load.
555 649 * @param {Object.<string,boolean>=} loaded An object keyed by already loaded documents.
556 650 * @return {Promise.<DocumentAST>}
... ... @@ -560,9 +654,9 @@ Analyzer.prototype.getLoadedAst = function getLoadedAst(href, loaded) {
560 654 loaded = {};
561 655 }
562 656 loaded[href] = true;
563   - var document = this._parsedDocuments[href];
  657 + var parsedDocument = this.parsedDocuments[href];
564 658 var analyzedDocument = this.html[href];
565   - var astCopy = dom5.parse(dom5.serialize(document.ast));
  659 + var astCopy = dom5.parse(dom5.serialize(parsedDocument));
566 660 // Whenever we inline something, reset inlined to true to know that anoather
567 661 // inlining pass is needed;
568 662 this._inlineStyles(astCopy, href);
... ... @@ -577,8 +671,8 @@ Analyzer.prototype.getLoadedAst = function getLoadedAst(href, loaded) {
577 671 * @return {Object}
578 672 */
579 673 Analyzer.prototype.nodeWalkDocuments = function nodeWalkDocuments(predicate) {
580   - for (var href in this._parsedDocuments) {
581   - var match = dom5.nodeWalk(this._parsedDocuments[href].ast, predicate);
  674 + for (var href in this.parsedDocuments) {
  675 + var match = dom5.nodeWalk(this.parsedDocuments[href], predicate);
582 676 if (match) {
583 677 return match;
584 678 }
... ... @@ -593,8 +687,8 @@ Analyzer.prototype.nodeWalkDocuments = function nodeWalkDocuments(predicate) {
593 687 */
594 688 Analyzer.prototype.nodeWalkAllDocuments = function nodeWalkDocuments(predicate) {
595 689 var results = [];
596   - for (var href in this._parsedDocuments) {
597   - var newNodes = dom5.nodeWalkAll(this._parsedDocuments[href].ast, predicate);
  690 + for (var href in this.parsedDocuments) {
  691 + var newNodes = dom5.nodeWalkAll(this.parsedDocuments[href], predicate);
598 692 results = results.concat(newNodes);
599 693 }
600 694 return results;
... ... @@ -607,9 +701,17 @@ Analyzer.prototype.annotate = function annotate() {
607 701 this.elements.unshift(featureEl);
608 702 this.elementsByTagName[featureEl.is] = featureEl;
609 703 }
610   -
611   - this.elements.forEach(docs.annotateElement);
612   - this.behaviors.forEach(docs.annotateElement); // Same shape.
  704 + var behaviorsByName = this.behaviorsByName;
  705 + var elementHelper = function(descriptor){
  706 + docs.annotateElement(descriptor, behaviorsByName);
  707 + };
  708 + this.elements.forEach(elementHelper);
  709 + this.behaviors.forEach(elementHelper); // Same shape.
  710 + this.behaviors.forEach(function(behavior){
  711 + if (behavior.is !== behavior.symbol && behavior.symbol) {
  712 + this.behaviorsByName[behavior.symbol] = undefined;
  713 + }
  714 + }.bind(this));
613 715 };
614 716  
615 717 function attachDomModule(parsedImport, element) {
... ... @@ -631,8 +733,8 @@ Analyzer.prototype.clean = function clean() {
631 733 module.exports = Analyzer;
632 734  
633 735 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
634   -
635   -},{"./ast-utils/docs":5,"./ast-utils/import-parse":10,"./ast-utils/js-parse":11,"./loader/file-loader":13,"./loader/fs-resolver":14,"./loader/noop-resolver":15,"./loader/xhr-resolver":16,"dom5":38,"es6-promise":60,"setimmediate":74,"url":26}],2:[function(require,module,exports){
  736 +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9hbmFseXplci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgVGhlIFBvbHltZXIgUHJvamVjdCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhpcyBjb2RlIG1heSBvbmx5IGJlIHVzZWQgdW5kZXIgdGhlIEJTRCBzdHlsZSBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9MSUNFTlNFLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBhdXRob3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQVVUSE9SUy50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgY29udHJpYnV0b3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQ09OVFJJQlVUT1JTLnR4dFxuICogQ29kZSBkaXN0cmlidXRlZCBieSBHb29nbGUgYXMgcGFydCBvZiB0aGUgcG9seW1lciBwcm9qZWN0IGlzIGFsc29cbiAqIHN1YmplY3QgdG8gYW4gYWRkaXRpb25hbCBJUCByaWdodHMgZ3JhbnQgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL1BBVEVOVFMudHh0XG4gKi9cbi8vIGpzaGludCBub2RlOiB0cnVlXG4ndXNlIHN0cmljdCc7XG4vLyBqc2hpbnQgLVcwNzlcbnZhciBQcm9taXNlID0gZ2xvYmFsLlByb21pc2UgfHwgcmVxdWlyZSgnZXM2LXByb21pc2UnKS5Qcm9taXNlO1xuLy8ganNoaW50ICtXMDc5XG5cbnZhciBkb201ID0gcmVxdWlyZSgnZG9tNScpO1xudmFyIHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuXG52YXIgZG9jcyA9IHJlcXVpcmUoJy4vYXN0LXV0aWxzL2RvY3MnKTtcbnZhciBGaWxlTG9hZGVyID0gcmVxdWlyZSgnLi9sb2FkZXIvZmlsZS1sb2FkZXInKTtcbnZhciBpbXBvcnRQYXJzZSA9IHJlcXVpcmUoJy4vYXN0LXV0aWxzL2ltcG9ydC1wYXJzZScpO1xudmFyIGpzUGFyc2UgPSByZXF1aXJlKCcuL2FzdC11dGlscy9qcy1wYXJzZScpO1xudmFyIE5vb3BSZXNvbHZlciA9IHJlcXVpcmUoJy4vbG9hZGVyL25vb3AtcmVzb2x2ZXInKTtcblxuZnVuY3Rpb24gcmVkdWNlTWV0YWRhdGEobTEsIG0yKSB7XG4gIHJldHVybiB7XG4gICAgZWxlbWVudHM6ICBtMS5lbGVtZW50cy5jb25jYXQobTIuZWxlbWVudHMpLFxuICAgIGZlYXR1cmVzOiAgbTEuZmVhdHVyZXMuY29uY2F0KG0yLmZlYXR1cmVzKSxcbiAgICBiZWhhdmlvcnM6IG0xLmJlaGF2aW9ycy5jb25jYXQobTIuYmVoYXZpb3JzKSxcbiAgfTtcbn1cblxudmFyIEVNUFRZX01FVEFEQVRBID0ge2VsZW1lbnRzOiBbXSwgZmVhdHVyZXM6IFtdLCBiZWhhdmlvcnM6IFtdfTtcblxuLyoqXG4gKiBQYXJzZTUncyByZXByZXNlbnRhdGlvbiBvZiBhIHBhcnNlZCBodG1sIGRvY3VtZW50XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEb2N1bWVudEFTVFxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqL1xuXG4vKipcbiAqIGVzcHJlZSdzIHJlcHJlc2VudGF0aW9uIG9mIGEgcGFyc2VkIGh0bWwgZG9jdW1lbnRcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEpTQVNUXG4gKiBAbWVtYmVyb2YgaHlkcm9seXNpc1xuICovXG5cbi8qKlxuICogUGFja2FnZSBvZiBhIHBhcnNlZCBKUyBzY3JpcHRcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFBhcnNlZEpTXG4gKiBAcHJvcGVydHkge0pTQVNUfSBhc3QgVGhlIHNjcmlwdCdzIEFTVFxuICogQHByb3BlcnR5IHtEb2N1bWVudEFTVH0gc2NyaXB0RWxlbWVudCBJZiBpbmxpbmUsIHRoZSBzY3JpcHQncyBjb250YWluaW5nIHRhZy5cbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKi9cblxuLyoqXG4gKiBUaGUgbWV0YWRhdGEgZm9yIGEgc2luZ2xlIHBvbHltZXIgZWxlbWVudFxuICogQHR5cGVkZWYge09iamVjdH0gRWxlbWVudERlc2NyaXB0b3JcbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKi9cblxuLyoqXG4gKiBUaGUgbWV0YWRhdGEgZm9yIGEgUG9seW1lciBmZWF0dXJlLlxuICogQHR5cGVkZWYge09iamVjdH0gRmVhdHVyZURlc2NyaXB0b3JcbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKi9cblxuLyoqXG4gKiBUaGUgbWV0YWRhdGEgZm9yIGEgUG9seW1lciBiZWhhdmlvciBtaXhpbi5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IEJlaGF2aW9yRGVzY3JpcHRvclxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqL1xuXG4vKipcbiAqIFRoZSBtZXRhZGF0YSBmb3IgYWxsIGZlYXR1cmVzIGFuZCBlbGVtZW50cyBkZWZpbmVkIGluIG9uZSBkb2N1bWVudFxuICogQHR5cGVkZWYge09iamVjdH0gRG9jdW1lbnREZXNjcmlwdG9yXG4gKiBAbWVtYmVyb2YgaHlkcm9seXNpc1xuICogQHByb3BlcnR5IHtBcnJheTxFbGVtZW50RGVzY3JpcHRvcj59IGVsZW1lbnRzIFRoZSBlbGVtZW50cyBmcm9tIHRoZSBkb2N1bWVudFxuICogQHByb3BlcnR5IHtBcnJheTxGZWF0dXJlRGVzY3JpcHRvcj59ICBmZWF0dXJlcyBUaGUgZmVhdHVyZXMgZnJvbSB0aGUgZG9jdW1lbnRcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RmVhdHVyZURlc2NyaXB0b3I+fSAgYmVoYXZpb3JzIFRoZSBiZWhhdmlvcnMgZnJvbSB0aGUgZG9jdW1lbnRcbiAqL1xuXG4vKipcbiAqIFRoZSBtZXRhZGF0YSBvZiBhbiBlbnRpcmUgSFRNTCBkb2N1bWVudCwgaW4gcHJvbWlzZXMuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBBbmFseXplZERvY3VtZW50XG4gKiBAbWVtYmVyb2YgaHlkcm9seXNpc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IGhyZWYgVGhlIHVybCBvZiB0aGUgZG9jdW1lbnQuXG4gKiBAcHJvcGVydHkge1Byb21pc2U8UGFyc2VkSW1wb3J0Pn0gIGh0bWxMb2FkZWQgVGhlIHBhcnNlZCByZXByZXNlbnRhdGlvbiBvZlxuICogICAgIHRoZSBkb2MuIFVzZSB0aGUgYGFzdGAgcHJvcGVydHkgdG8gZ2V0IHRoZSBmdWxsIGBwYXJzZTVgIGFzdFxuICpcbiAqIEBwcm9wZXJ0eSB7UHJvbWlzZTxBcnJheTxzdHJpbmc+Pn0gZGVwc0xvYWRlZCBSZXNvbHZlcyB0byB0aGUgbGlzdCBvZiB0aGlzXG4gKiAgICAgRG9jdW1lbnQncyB0cmFuc2l0aXZlIGltcG9ydCBkZXBlbmRlbmNpZXNcbiAqXG4gKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IGRlcEhyZWZzIFRoZSBkaXJlY3QgZGVwZW5kZW5jaWVzIG9mIHRoZSBkb2N1bWVudC5cbiAqXG4gKiBAcHJvcGVydHkge1Byb21pc2U8RG9jdW1lbnREZXNjcmlwdG9yPn0gbWV0YWRhdGFMb2FkZWQgUmVzb2x2ZXMgdG8gdGhlIGxpc3Qgb2ZcbiAqICAgICB0aGlzIERvY3VtZW50J3MgaW1wb3J0IGRlcGVuZGVuY2llc1xuICovXG5cbi8qKlxuICogQSBkYXRhYmFzZSBvZiBQb2x5bWVyIG1ldGFkYXRhIGRlZmluZWQgaW4gSFRNTFxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQG1lbWJlck9mIGh5ZHJvbHlzaXNcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGF0dGFjaEFTVCAgSWYgdHJ1ZSwgYXR0YWNoIGEgcGFyc2U1IGNvbXBsaWFudCBBU1RcbiAqIEBwYXJhbSAge0ZpbGVMb2FkZXI9fSBsb2FkZXIgQW4gb3B0aW9uYWwgYEZpbGVMb2FkZXJgIHVzZWQgdG8gbG9hZCBleHRlcm5hbFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvdXJjZXNcbiAqL1xudmFyIEFuYWx5emVyID0gZnVuY3Rpb24gQW5hbHl6ZXIoYXR0YWNoQVNULFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVyKSB7XG4gIHRoaXMubG9hZGVyID0gbG9hZGVyO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgYWxsIGVsZW1lbnRzIHRoZSBgQW5hbHl6ZXJgIGhhcyBtZXRhZGF0YSBmb3IuXG4gICAqIEBtZW1iZXIge0FycmF5LjxFbGVtZW50RGVzY3JpcHRvcj59XG4gICAqL1xuICB0aGlzLmVsZW1lbnRzID0gW107XG5cbiAgLyoqXG4gICAqIEEgdmlldyBpbnRvIGBlbGVtZW50c2AsIGtleWVkIGJ5IHRhZyBuYW1lLlxuICAgKiBAbWVtYmVyIHtPYmplY3QuPHN0cmluZyxFbGVtZW50RGVzY3JpcHRvcj59XG4gICAqL1xuICB0aGlzLmVsZW1lbnRzQnlUYWdOYW1lID0ge307XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBBUEkgZmVhdHVyZXMgYWRkZWQgdG8gYFBvbHltZXIuQmFzZWAgZW5jb3VudGVyZWQgYnkgdGhlXG4gICAqIGFuYWx5emVyLlxuICAgKiBAbWVtYmVyIHtBcnJheTxGZWF0dXJlRGVzY3JpcHRvcj59XG4gICAqL1xuICB0aGlzLmZlYXR1cmVzID0gW107XG5cbiAgLyoqXG4gICAqIFRoZSBiZWhhdmlvcnMgY29sbGVjdGVkIGJ5IHRoZSBhbmFseXNpcyBwYXNzLlxuICAgKlxuICAgKiBAbWVtYmVyIHtBcnJheTxCZWhhdmlvckRlc2NyaXB0b3I+fVxuICAgKi9cbiAgdGhpcy5iZWhhdmlvcnMgPSBbXTtcblxuICAvKipcbiAgICogVGhlIGJlaGF2aW9ycyBjb2xsZWN0ZWQgYnkgdGhlIGFuYWx5c2lzIHBhc3MgYnkgbmFtZS5cbiAgICpcbiAgICogQG1lbWJlciB7T2JqZWN0PHN0cmluZyxCZWhhdmlvckRlc2NyaXB0b3I+fVxuICAgKi9cbiAgdGhpcy5iZWhhdmlvcnNCeU5hbWUgPSB7fTtcblxuICAvKipcbiAgICogQSBtYXAsIGtleWVkIGJ5IGFic29sdXRlIHBhdGgsIG9mIERvY3VtZW50IG1ldGFkYXRhLlxuICAgKiBAbWVtYmVyIHtPYmplY3Q8c3RyaW5nLEFuYWx5emVkRG9jdW1lbnQ+fVxuICAgKi9cbiAgdGhpcy5odG1sID0ge307XG5cbiAgLyoqXG4gICAqIEEgbWFwLCBrZXllZCBieSBwYXRoLCBvZiBIVE1MIGRvY3VtZW50IEFTVHMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLnBhcnNlZERvY3VtZW50cyA9IHt9O1xuXG4gIC8qKlxuICAgKiBBIG1hcCwga2V5ZWQgYnkgcGF0aCwgb2YgSlMgc2NyaXB0IEFTVHMuXG4gICAqXG4gICAqIElmIHRoZSBwYXRoIGlzIGFuIEhUTUwgZmlsZSB3aXRoIG11bHRpcGxlIHNjcmlwdHMsIHRoZSBlbnRyeSB3aWxsIGJlIGFuIGFycmF5IG9mIHNjcmlwdHMuXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLEFycmF5PFBhcnNlZEpTPj59XG4gICAqL1xuICB0aGlzLnBhcnNlZFNjcmlwdHMgPSB7fTtcblxuICBcblxuICAvKipcbiAgICogQSBtYXAsIGtleWVkIGJ5IHBhdGgsIG9mIGRvY3VtZW50IGNvbnRlbnQuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9jb250ZW50ID0ge307XG59O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBBbmFseXplci5hbmFsenllYFxuICogQHR5cGVkZWYge09iamVjdH0gTG9hZE9wdGlvbnNcbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IG5vQW5ub3RhdGlvbnMgV2hldGhlciBgYW5ub3RhdGUoKWAgc2hvdWxkIGJlIHNraXBwZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGNsZWFuIFdoZXRoZXIgdGhlIGdlbmVyYXRlZCBkZXNjcmlwdG9ycyBzaG91bGQgYmUgY2xlYW5lZFxuICogICAgIG9mIHJlZHVuZGFudCBkYXRhLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcpOiBib29sZWFufSBmaWx0ZXIgQSBwcmVkaWNhdGUgZnVuY3Rpb24gdGhhdFxuICogICAgIGluZGljYXRlcyB3aGljaCBmaWxlcyBzaG91bGQgYmUgaWdub3JlZCBieSB0aGUgbG9hZGVyLiBCeSBkZWZhdWx0IGFsbFxuICogICAgIGZpbGVzIG5vdCBsb2NhdGVkIHVuZGVyIHRoZSBkaXJuYW1lIG9mIGBocmVmYCB3aWxsIGJlIGlnbm9yZWQuXG4gKi9cblxuLyoqXG4gKiBTaG9ydGhhbmQgZm9yIHRyYW5zaXRpdmVseSBsb2FkaW5nIGFuZCBwcm9jZXNzaW5nIGFsbCBpbXBvcnRzIGJlZ2lubmluZyBhdFxuICogYGhyZWZgLlxuICpcbiAqIEluIG9yZGVyIHRvIHByb3Blcmx5IGZpbHRlciBwYXRocywgYGhyZWZgIF9tdXN0XyBiZSBhbiBhYnNvbHV0ZSBVUkkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgVGhlIHJvb3QgaW1wb3J0IHRvIGJlZ2luIGxvYWRpbmcgZnJvbS5cbiAqIEBwYXJhbSB7TG9hZE9wdGlvbnM9fSBvcHRpb25zIEFueSBhZGRpdGlvbmFsIG9wdGlvbnMgZm9yIHRoZSBsb2FkLlxuICogQHJldHVybiB7UHJvbWlzZTxBbmFseXplcj59IEEgcHJvbWlzZSB0aGF0IHdpbGwgcmVzb2x2ZSBvbmNlIGBocmVmYCBhbmQgaXRzXG4gKiAgICAgZGVwZW5kZW5jaWVzIGhhdmUgYmVlbiBsb2FkZWQgYW5kIGFuYWx5emVkLlxuICovXG5BbmFseXplci5hbmFseXplID0gZnVuY3Rpb24gYW5hbHl6ZShocmVmLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLmZpbHRlciA9IG9wdGlvbnMuZmlsdGVyIHx8IF9kZWZhdWx0RmlsdGVyKGhyZWYpO1xuXG4gIHZhciBsb2FkZXIgPSBuZXcgRmlsZUxvYWRlcigpO1xuICB2YXIgUHJpbWFyeVJlc29sdmVyID0gdHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZSgnLi9sb2FkZXIvZnMtcmVzb2x2ZXInKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlKCcuL2xvYWRlci94aHItcmVzb2x2ZXInKTtcbiAgbG9hZGVyLmFkZFJlc29sdmVyKG5ldyBQcmltYXJ5UmVzb2x2ZXIob3B0aW9ucykpO1xuICBsb2FkZXIuYWRkUmVzb2x2ZXIobmV3IE5vb3BSZXNvbHZlcih7dGVzdDogb3B0aW9ucy5maWx0ZXJ9KSk7XG5cbiAgdmFyIGFuYWx5emVyID0gbmV3IHRoaXMobnVsbCwgbG9hZGVyKTtcbiAgcmV0dXJuIGFuYWx5emVyLm1ldGFkYXRhVHJlZShocmVmKS50aGVuKGZ1bmN0aW9uKHJvb3QpIHtcbiAgICBpZiAoIW9wdGlvbnMubm9Bbm5vdGF0aW9ucykge1xuICAgICAgYW5hbHl6ZXIuYW5ub3RhdGUoKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuY2xlYW4pIHtcbiAgICAgIGFuYWx5emVyLmNsZWFuKCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoYW5hbHl6ZXIpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBocmVmXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihzdHJpbmcpOiBib29sZWFufVxuICovXG5mdW5jdGlvbiBfZGVmYXVsdEZpbHRlcihocmVmKSB7XG4gIC8vIEV2ZXJ5dGhpbmcgdXAgdG8gdGhlIGxhc3QgYC9gIG9yIGBcXGAuXG4gIHZhciBiYXNlID0gaHJlZi5tYXRjaCgvXiguKj8pW15cXC9cXFxcXSokLylbMV07XG4gIHJldHVybiBmdW5jdGlvbih1cmkpIHtcbiAgICByZXR1cm4gdXJpLmluZGV4T2YoYmFzZSkgIT09IDA7XG4gIH07XG59XG5cbkFuYWx5emVyLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gbG9hZChocmVmKSB7XG4gIHJldHVybiB0aGlzLmxvYWRlci5yZXF1ZXN0KGhyZWYpLnRoZW4oZnVuY3Rpb24oY29udGVudCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuX2NvbnRlbnRbaHJlZl0gPSBjb250ZW50O1xuICAgICAgICByZXNvbHZlKHRoaXMuX3BhcnNlSFRNTChjb250ZW50LCBocmVmKSk7XG4gICAgICB9LmJpbmQodGhpcyksIDApO1xuICAgIH0uYmluZCh0aGlzKSkuY2F0Y2goZnVuY3Rpb24oZXJyKXtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBwcm9jZXNzaW5nIGRvY3VtZW50IGF0IFwiICsgaHJlZik7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYW4gYEFuYWx5emVkRG9jdW1lbnRgIHJlcHJlc2VudGluZyB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGh0bWxJbXBvcnQgUmF3IHRleHQgb2YgYW4gSFRNTCBkb2N1bWVudFxuICogQHBhcmFtICB7c3RyaW5nfSBocmVmICAgICAgIFRoZSBkb2N1bWVudCdzIFVSTC5cbiAqIEByZXR1cm4ge0FuYWx5emVkRG9jdW1lbnR9ICAgICAgIEFuICBgQW5hbHl6ZWREb2N1bWVudGBcbiAqL1xuQW5hbHl6ZXIucHJvdG90eXBlLl9wYXJzZUhUTUwgPSBmdW5jdGlvbiBfcGFyc2VIVE1MKGh0bWxJbXBvcnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhyZWYpIHtcbiAgaWYgKGhyZWYgaW4gdGhpcy5odG1sKSB7XG4gICAgcmV0dXJuIHRoaXMuaHRtbFtocmVmXTtcbiAgfVxuICB2YXIgZGVwc0xvYWRlZCA9IFtdO1xuICB2YXIgZGVwSHJlZnMgPSBbXTtcbiAgdmFyIG1ldGFkYXRhTG9hZGVkID0gUHJvbWlzZS5yZXNvbHZlKEVNUFRZX01FVEFEQVRBKTtcbiAgdmFyIHBhcnNlZDtcbiAgdHJ5IHtcbiAgICBwYXJzZWQgPSBpbXBvcnRQYXJzZShodG1sSW1wb3J0LCBocmVmKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgY29uc29sZS5lcnJvcignRXJyb3IgcGFyc2luZyEnKTtcbiAgICB0aHJvdyBlcnI7XG4gIH1cbiAgdmFyIGh0bWxMb2FkZWQgPSBQcm9taXNlLnJlc29sdmUocGFyc2VkKTtcbiAgaWYgKHBhcnNlZC5zY3JpcHQpIHtcbiAgICBtZXRhZGF0YUxvYWRlZCA9IHRoaXMuX3Byb2Nlc3NTY3JpcHRzKHBhcnNlZC5zY3JpcHQsIGhyZWYpO1xuICB9XG4gIHZhciBjb21tZW50VGV4dCA9IHBhcnNlZC5jb21tZW50Lm1hcChmdW5jdGlvbihjb21tZW50KXtcbiAgICByZXR1cm4gZG9tNS5nZXRUZXh0Q29udGVudChjb21tZW50KTtcbiAgfSk7XG4gIHZhciBwc2V1ZG9FbGVtZW50cyA9IGRvY3MucGFyc2VQc2V1ZG9FbGVtZW50cyhjb21tZW50VGV4dCk7XG4gIHBzZXVkb0VsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCl7XG4gICAgZWxlbWVudC5jb250ZW50SHJlZiA9IGhyZWY7XG4gICAgdGhpcy5lbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgIHRoaXMuZWxlbWVudHNCeVRhZ05hbWVbZWxlbWVudC5pc10gPSBlbGVtZW50O1xuICB9LmJpbmQodGhpcykpO1xuICBtZXRhZGF0YUxvYWRlZCA9IG1ldGFkYXRhTG9hZGVkLnRoZW4oZnVuY3Rpb24obWV0YWRhdGEpe1xuICAgIHZhciBtZXRhZGF0YUVudHJ5ID0ge1xuICAgICAgZWxlbWVudHM6IHBzZXVkb0VsZW1lbnRzLFxuICAgICAgZmVhdHVyZXM6IFtdLFxuICAgICAgYmVoYXZpb3JzOiBbXVxuICAgIH07XG4gICAgcmV0dXJuIFttZXRhZGF0YSwgbWV0YWRhdGFFbnRyeV0ucmVkdWNlKHJlZHVjZU1ldGFkYXRhKTtcbiAgfSk7XG4gIGRlcHNMb2FkZWQucHVzaChtZXRhZGF0YUxvYWRlZCk7XG5cblxuICBpZiAodGhpcy5sb2FkZXIpIHtcbiAgICB2YXIgYmFzZVVyaSA9IGhyZWY7XG4gICAgaWYgKHBhcnNlZC5iYXNlLmxlbmd0aCA+IDEpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJPbmx5IG9uZSBiYXNlIHRhZyBwZXIgZG9jdW1lbnQhXCIpO1xuICAgICAgdGhyb3cgXCJNdWx0aXBsZSBiYXNlIHRhZ3MgaW4gXCIgKyBocmVmO1xuICAgIH0gZWxzZSBpZiAocGFyc2VkLmJhc2UubGVuZ3RoID09IDEpIHtcbiAgICAgIHZhciBiYXNlSHJlZiA9IGRvbTUuZ2V0QXR0cmlidXRlKHBhcnNlZC5iYXNlWzBdLCBcImhyZWZcIik7XG4gICAgICBpZiAoYmFzZUhyZWYpIHtcbiAgICAgICAgYmFzZUhyZWYgPSBiYXNlSHJlZiArIFwiL1wiO1xuICAgICAgICBiYXNlVXJpID0gdXJsLnJlc29sdmUoYmFzZVVyaSwgYmFzZUhyZWYpO1xuICAgICAgfVxuICAgIH1cbiAgICBwYXJzZWQuaW1wb3J0LmZvckVhY2goZnVuY3Rpb24obGluaykge1xuICAgICAgdmFyIGxpbmt1cmwgPSBkb201LmdldEF0dHJpYnV0ZShsaW5rLCAnaHJlZicpO1xuICAgICAgaWYgKGxpbmt1cmwpIHtcbiAgICAgICAgdmFyIHJlc29sdmVkVXJsID0gdXJsLnJlc29sdmUoYmFzZVVyaSwgbGlua3VybCk7XG4gICAgICAgIGRlcEhyZWZzLnB1c2gocmVzb2x2ZWRVcmwpO1xuICAgICAgICBkZXBzTG9hZGVkLnB1c2godGhpcy5fZGVwZW5kZW5jaWVzTG9hZGVkRm9yKHJlc29sdmVkVXJsLCBocmVmKSk7XG4gICAgICB9XG4gICAgfS5iaW5kKHRoaXMpKTtcbiAgICBwYXJzZWQuc3R5bGUuZm9yRWFjaChmdW5jdGlvbihzdHlsZUVsZW1lbnQpIHtcbiAgICAgIGlmIChwb2x5bWVyRXh0ZXJuYWxTdHlsZShzdHlsZUVsZW1lbnQpKSB7XG4gICAgICAgIHZhciBzdHlsZUhyZWYgPSBkb201LmdldEF0dHJpYnV0ZShzdHlsZUVsZW1lbnQsICdocmVmJyk7XG4gICAgICAgIGlmIChocmVmKSB7XG4gICAgICAgICAgc3R5bGVIcmVmID0gdXJsLnJlc29sdmUoYmFzZVVyaSwgc3R5bGVIcmVmKTtcbiAgICAgICAgICBkZXBzTG9hZGVkLnB1c2godGhpcy5sb2FkZXIucmVxdWVzdChzdHlsZUhyZWYpLnRoZW4oZnVuY3Rpb24oY29udGVudCl7XG4gICAgICAgICAgICB0aGlzLl9jb250ZW50W3N0eWxlSHJlZl0gPSBjb250ZW50O1xuICAgICAgICAgIH0uYmluZCh0aGlzKSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfS5iaW5kKHRoaXMpKTtcbiAgfVxuICBkZXBzTG9hZGVkID0gUHJvbWlzZS5hbGwoZGVwc0xvYWRlZClcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24oKSB7cmV0dXJuIGRlcEhyZWZzO30pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbihlcnIpIHt0aHJvdyBlcnI7fSk7XG4gIHRoaXMucGFyc2VkRG9jdW1lbnRzW2hyZWZdID0gcGFyc2VkLmFzdDtcbiAgdGhpcy5odG1sW2hyZWZdID0ge1xuICAgICAgaHJlZjogaHJlZixcbiAgICAgIGh0bWxMb2FkZWQ6IGh0bWxMb2FkZWQsXG4gICAgICBtZXRhZGF0YUxvYWRlZDogbWV0YWRhdGFMb2FkZWQsXG4gICAgICBkZXBIcmVmczogZGVwSHJlZnMsXG4gICAgICBkZXBzTG9hZGVkOiBkZXBzTG9hZGVkXG4gIH07XG4gIHJldHVybiB0aGlzLmh0bWxbaHJlZl07XG59O1xuXG5BbmFseXplci5wcm90b3R5cGUuX3Byb2Nlc3NTY3JpcHRzID0gZnVuY3Rpb24gX3Byb2Nlc3NTY3JpcHRzKHNjcmlwdHMsIGhyZWYpIHtcbiAgdmFyIHNjcmlwdFByb21pc2VzID0gW107XG4gIHNjcmlwdHMuZm9yRWFjaChmdW5jdGlvbihzY3JpcHQpIHtcbiAgICBzY3JpcHRQcm9taXNlcy5wdXNoKHRoaXMuX3Byb2Nlc3NTY3JpcHQoc2NyaXB0LCBocmVmKSk7XG4gIH0uYmluZCh0aGlzKSk7XG4gIHJldHVybiBQcm9taXNlLmFsbChzY3JpcHRQcm9taXNlcykudGhlbihmdW5jdGlvbihtZXRhZGF0YUxpc3QpIHtcbiAgICByZXR1cm4gbWV0YWRhdGFMaXN0LnJlZHVjZShyZWR1Y2VNZXRhZGF0YSwgRU1QVFlfTUVUQURBVEEpO1xuICB9KTtcbn07XG5cbkFuYWx5emVyLnByb3RvdHlwZS5fcHJvY2Vzc1NjcmlwdCA9IGZ1bmN0aW9uIF9wcm9jZXNzU2NyaXB0KHNjcmlwdCwgaHJlZikge1xuICB2YXIgc3JjID0gZG9tNS5nZXRBdHRyaWJ1dGUoc2NyaXB0LCAnc3JjJyk7XG4gIHZhciBwYXJzZWRKcztcbiAgaWYgKCFzcmMpIHtcbiAgICB0cnkge1xuICAgICAgcGFyc2VkSnMgPSBqc1BhcnNlKChzY3JpcHQuY2hpbGROb2Rlcy5sZW5ndGgpID8gc2NyaXB0LmNoaWxkTm9kZXNbMF0udmFsdWUgOiAnJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBGaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGxpbmUgbnVtYmVyIGZvciB0aGUgZXJyb3IuXG4gICAgICB2YXIgbGluZSA9IDA7XG4gICAgICB2YXIgY29sID0gMDtcbiAgICAgIGlmIChzY3JpcHQuX19vd25lckRvY3VtZW50ICYmIHNjcmlwdC5fX293bmVyRG9jdW1lbnQgPT0gaHJlZikge1xuICAgICAgICBsaW5lID0gc2NyaXB0Ll9fbG9jYXRpb25EZXRhaWwubGluZSAtIDE7XG4gICAgICAgIGNvbCA9IHNjcmlwdC5fX2xvY2F0aW9uRGV0YWlsLmxpbmUgLSAxO1xuICAgICAgfVxuICAgICAgbGluZSArPSBlcnIubGluZU51bWJlcjtcbiAgICAgIGNvbCArPSBlcnIuY29sdW1uO1xuICAgICAgdmFyIG1lc3NhZ2UgPSBcIkVycm9yIHBhcnNpbmcgc2NyaXB0IGluIFwiICsgaHJlZiArIFwiIGF0IFwiICsgbGluZSArIFwiOlwiICsgY29sO1xuICAgICAgbWVzc2FnZSArPSBcIlxcblwiICsgZXJyLmRlc2NyaXB0aW9uO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihtZXNzYWdlKSk7XG4gICAgfVxuICAgIGlmIChwYXJzZWRKcy5lbGVtZW50cykge1xuICAgICAgcGFyc2VkSnMuZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIGVsZW1lbnQuc2NyaXB0RWxlbWVudCA9IHNjcmlwdDtcbiAgICAgICAgZWxlbWVudC5jb250ZW50SHJlZiA9IGhyZWY7XG4gICAgICAgIHRoaXMuZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgaWYgKGVsZW1lbnQuaXMgaW4gdGhpcy5lbGVtZW50c0J5VGFnTmFtZSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybignSWdub3JpbmcgZHVwbGljYXRlIGVsZW1lbnQgZGVmaW5pdGlvbjogJyArIGVsZW1lbnQuaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZWxlbWVudHNCeVRhZ05hbWVbZWxlbWVudC5pc10gPSBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9LmJpbmQodGhpcykpO1xuICAgIH1cbiAgICBpZiAocGFyc2VkSnMuZmVhdHVyZXMpIHtcbiAgICAgIHBhcnNlZEpzLmZlYXR1cmVzLmZvckVhY2goZnVuY3Rpb24oZmVhdHVyZSl7XG4gICAgICAgIGZlYXR1cmUuY29udGVudEhyZWYgPSBocmVmO1xuICAgICAgICBmZWF0dXJlLnNjcmlwdEVsZW1lbnQgPSBzY3JpcHQ7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZmVhdHVyZXMgPSB0aGlzLmZlYXR1cmVzLmNvbmNhdChwYXJzZWRKcy5mZWF0dXJlcyk7XG4gICAgfVxuICAgIGlmIChwYXJzZWRKcy5iZWhhdmlvcnMpIHtcbiAgICAgIHBhcnNlZEpzLmJlaGF2aW9ycy5mb3JFYWNoKGZ1bmN0aW9uKGJlaGF2aW9yKXtcbiAgICAgICAgYmVoYXZpb3IuY29udGVudEhyZWYgPSBocmVmO1xuICAgICAgICB0aGlzLmJlaGF2aW9yc0J5TmFtZVtiZWhhdmlvci5pc10gPSBiZWhhdmlvcjtcbiAgICAgICAgdGhpcy5iZWhhdmlvcnNCeU5hbWVbYmVoYXZpb3Iuc3ltYm9sXSA9IGJlaGF2aW9yO1xuICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgIHRoaXMuYmVoYXZpb3JzID0gdGhpcy5iZWhhdmlvcnMuY29uY2F0KHBhcnNlZEpzLmJlaGF2aW9ycyk7XG4gICAgfVxuICAgIGlmICghT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwodGhpcy5wYXJzZWRTY3JpcHRzLCBocmVmKSkge1xuICAgICAgdGhpcy5wYXJzZWRTY3JpcHRzW2hyZWZdID0gW107XG4gICAgfVxuICAgIHZhciBzY3JpcHRFbGVtZW50O1xuICAgIGlmIChzY3JpcHQuX19vd25lckRvY3VtZW50ICYmIHNjcmlwdC5fX293bmVyRG9jdW1lbnQgPT0gaHJlZikge1xuICAgICAgc2NyaXB0RWxlbWVudCA9IHNjcmlwdDtcbiAgICB9XG4gICAgdGhpcy5wYXJzZWRTY3JpcHRzW2hyZWZdLnB1c2goe1xuICAgICAgYXN0OiBwYXJzZWRKcy5wYXJzZWRTY3JpcHQsXG4gICAgICBzY3JpcHRFbGVtZW50OiBzY3JpcHRFbGVtZW50XG4gICAgfSk7XG4gICAgcmV0dXJuIHBhcnNlZEpzO1xuICB9XG4gIGlmICh0aGlzLmxvYWRlcikge1xuICAgIHZhciByZXNvbHZlZFNyYyA9IHVybC5yZXNvbHZlKGhyZWYsIHNyYyk7XG4gICAgcmV0dXJuIHRoaXMubG9hZGVyLnJlcXVlc3QocmVzb2x2ZWRTcmMpLnRoZW4oZnVuY3Rpb24oY29udGVudCkge1xuICAgICAgdGhpcy5fY29udGVudFtyZXNvbHZlZFNyY10gPSBjb250ZW50O1xuICAgICAgdmFyIHJlc29sdmVkU2NyaXB0ID0gT2JqZWN0LmNyZWF0ZShzY3JpcHQpO1xuICAgICAgcmVzb2x2ZWRTY3JpcHQuY2hpbGROb2RlcyA9IFt7dmFsdWU6IGNvbnRlbnR9XTtcbiAgICAgIHJlc29sdmVkU2NyaXB0LmF0dHJzID0gcmVzb2x2ZWRTY3JpcHQuYXR0cnMuc2xpY2UoKTtcbiAgICAgIGRvbTUucmVtb3ZlQXR0cmlidXRlKHJlc29sdmVkU2NyaXB0LCAnc3JjJyk7XG4gICAgICByZXR1cm4gdGhpcy5fcHJvY2Vzc1NjcmlwdChyZXNvbHZlZFNjcmlwdCwgcmVzb2x2ZWRTcmMpO1xuICAgIH0uYmluZCh0aGlzKSkuY2F0Y2goZnVuY3Rpb24oZXJyKSB7dGhyb3cgZXJyO30pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoRU1QVFlfTUVUQURBVEEpO1xuICB9XG59O1xuXG5BbmFseXplci5wcm90b3R5cGUuX2RlcGVuZGVuY2llc0xvYWRlZEZvciA9IGZ1bmN0aW9uIF9kZXBlbmRlbmNpZXNMb2FkZWRGb3IoaHJlZiwgcm9vdCkge1xuICB2YXIgZm91bmQgPSB7fTtcbiAgaWYgKHJvb3QgIT09IHVuZGVmaW5lZCkge1xuICAgIGZvdW5kW3Jvb3RdID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gdGhpcy5fZ2V0RGVwZW5kZW5jaWVzKGhyZWYsIGZvdW5kKS50aGVuKGZ1bmN0aW9uKGRlcHMpIHtcbiAgICB2YXIgZGVwTWV0YWRhdGFMb2FkZWQgPSBbXTtcbiAgICB2YXIgZGVwUHJvbWlzZXMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXBIcmVmKXtcbiAgICAgIHJldHVybiB0aGlzLmxvYWQoZGVwSHJlZikudGhlbihmdW5jdGlvbihodG1sTW9ub21lcikge1xuICAgICAgICByZXR1cm4gaHRtbE1vbm9tZXIubWV0YWRhdGFMb2FkZWQ7XG4gICAgICB9KTtcbiAgICB9LmJpbmQodGhpcykpO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChkZXBQcm9taXNlcyk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG4vKipcbiAqIExpc3QgYWxsIHRoZSBodG1sIGRlcGVuZGVuY2llcyBmb3IgdGhlIGRvY3VtZW50IGF0IGBocmVmYC5cbiAqIEBwYXJhbSAge3N0cmluZ30gICAgICAgICAgICAgICAgICAgaHJlZiAgICAgIFRoZSBocmVmIHRvIGdldCBkZXBlbmRlbmNpZXMgZm9yLlxuICogQHBhcmFtICB7T2JqZWN0LjxzdHJpbmcsYm9vbGVhbj49fSBmb3VuZCAgICAgQW4gb2JqZWN0IGtleWVkIGJ5IFVSTCBvZiB0aGVcbiAqICAgICBhbHJlYWR5IHJlc29sdmVkIGRlcGVuZGVuY2llcy5cbiAqIEBwYXJhbSAge2Jvb2xlYW49fSAgICAgICAgICAgICAgICB0cmFuc2l0aXZlIFdoZXRoZXIgdG8gbG9hZCB0cmFuc2l0aXZlXG4gKiAgICAgZGVwZW5kZW5jaWVzLiBEZWZhdWx0cyB0byB0cnVlLlxuICogQHJldHVybiB7QXJyYXkuPHN0cmluZz59ICBBIGxpc3Qgb2YgYWxsIHRoZSBodG1sIGRlcGVuZGVuY2llcy5cbiAqL1xuQW5hbHl6ZXIucHJvdG90eXBlLl9nZXREZXBlbmRlbmNpZXMgPSBmdW5jdGlvbiBfZ2V0RGVwZW5kZW5jaWVzKGhyZWYsIGZvdW5kLCB0cmFuc2l0aXZlKSB7XG4gIGlmIChmb3VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZm91bmQgPSB7fTtcbiAgICBmb3VuZFtocmVmXSA9IHRydWU7XG4gIH1cbiAgaWYgKHRyYW5zaXRpdmUgPT09IHVuZGVmaW5lZCkge1xuICAgIHRyYW5zaXRpdmUgPSB0cnVlO1xuICB9XG4gIHZhciBkZXBzID0gW107XG4gIHJldHVybiB0aGlzLmxvYWQoaHJlZikudGhlbihmdW5jdGlvbihodG1sTW9ub21lcikge1xuICAgIHZhciB0cmFuc2l0aXZlRGVwcyA9IFtdO1xuICAgIGh0bWxNb25vbWVyLmRlcEhyZWZzLmZvckVhY2goZnVuY3Rpb24oZGVwSHJlZil7XG4gICAgICBpZiAoZm91bmRbZGVwSHJlZl0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGVwcy5wdXNoKGRlcEhyZWYpO1xuICAgICAgZm91bmRbZGVwSHJlZl0gPSB0cnVlO1xuICAgICAgaWYgKHRyYW5zaXRpdmUpIHtcbiAgICAgICAgdHJhbnNpdGl2ZURlcHMucHVzaCh0aGlzLl9nZXREZXBlbmRlbmNpZXMoZGVwSHJlZiwgZm91bmQpKTtcbiAgICAgIH1cbiAgICB9LmJpbmQodGhpcykpO1xuICAgIHJldHVybiBQcm9taXNlLmFsbCh0cmFuc2l0aXZlRGVwcyk7XG4gIH0uYmluZCh0aGlzKSkudGhlbihmdW5jdGlvbih0cmFuc2l0aXZlRGVwcykge1xuICAgIHZhciBhbGxkZXBzID0gdHJhbnNpdGl2ZURlcHMucmVkdWNlKGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIHJldHVybiBhLmNvbmNhdChiKTtcbiAgICB9LCBbXSkuY29uY2F0KGRlcHMpO1xuICAgIHJldHVybiBhbGxkZXBzO1xuICB9KTtcbn07XG5cbmZ1bmN0aW9uIG1hdGNoZXNEb2N1bWVudEZvbGRlcihkZXNjcmlwdG9yLCBocmVmKSB7XG4gIGlmICghZGVzY3JpcHRvci5jb250ZW50SHJlZikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgZGVzY3JpcHRvckRvYyA9IHVybC5wYXJzZShkZXNjcmlwdG9yLmNvbnRlbnRIcmVmKTtcbiAgaWYgKCFkZXNjcmlwdG9yRG9jIHx8ICFkZXNjcmlwdG9yRG9jLnBhdGhuYW1lKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBzZWFyY2hEb2MgPSB1cmwucGFyc2UoaHJlZik7XG4gIGlmICghc2VhcmNoRG9jIHx8ICFzZWFyY2hEb2MucGF0aG5hbWUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHNlYXJjaFBhdGggPSBzZWFyY2hEb2MucGF0aG5hbWU7XG4gIHZhciBsYXN0U2xhc2ggPSBzZWFyY2hQYXRoLmxhc3RJbmRleE9mKFwiL1wiKTtcbiAgaWYgKGxhc3RTbGFzaCA+IDApIHtcbiAgICBzZWFyY2hQYXRoID0gc2VhcmNoUGF0aC5zbGljZSgwLCBsYXN0U2xhc2gpO1xuICB9XG4gIHJldHVybiBkZXNjcmlwdG9yRG9jLnBhdGhuYW1lLmluZGV4T2Yoc2VhcmNoUGF0aCkgPT09IDA7XG59XG5cbkFuYWx5emVyLnByb3RvdHlwZS5lbGVtZW50c0ZvckZvbGRlciA9IGZ1bmN0aW9uIGVsZW1lbnRzRm9yRm9sZGVyKGhyZWYpIHtcbiAgcmV0dXJuIHRoaXMuZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uKGVsZW1lbnQpe1xuICAgIHJldHVybiBtYXRjaGVzRG9jdW1lbnRGb2xkZXIoZWxlbWVudCwgaHJlZik7XG4gIH0pO1xufTtcblxuQW5hbHl6ZXIucHJvdG90eXBlLmJlaGF2aW9yc0ZvckZvbGRlciA9IGZ1bmN0aW9uIGJlaGF2aW9yc0ZvckZvbGRlcihocmVmKSB7XG4gIHJldHVybiB0aGlzLmJlaGF2aW9ycy5maWx0ZXIoZnVuY3Rpb24oYmVoYXZpb3Ipe1xuICAgIHJldHVybiBtYXRjaGVzRG9jdW1lbnRGb2xkZXIoYmVoYXZpb3IsIGhyZWYpO1xuICB9KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIFBPSk8gcmVwcmVzZW50YXRpb24gb2YgdGhlIGltcG9ydFxuICogdHJlZSwgaW4gYSBmb3JtYXQgdGhhdCBtYWludGFpbnMgdGhlIG9yZGVyaW5nIG9mIHRoZSBIVE1MIGltcG9ydHMgc3BlYy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIHRoZSBpbXBvcnQgdG8gZ2V0IG1ldGFkYXRhIGZvci5cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cbkFuYWx5emVyLnByb3RvdHlwZS5tZXRhZGF0YVRyZWUgPSBmdW5jdGlvbiBtZXRhZGF0YVRyZWUoaHJlZikge1xuICByZXR1cm4gdGhpcy5sb2FkKGhyZWYpLnRoZW4oZnVuY3Rpb24obW9ub21lcil7XG4gICAgdmFyIGxvYWRlZEhyZWZzID0ge307XG4gICAgbG9hZGVkSHJlZnNbaHJlZl0gPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVRyZWUobW9ub21lciwgbG9hZGVkSHJlZnMpO1xuICB9LmJpbmQodGhpcykpO1xufTtcblxuQW5hbHl6ZXIucHJvdG90eXBlLl9tZXRhZGF0YVRyZWUgPSBmdW5jdGlvbiBfbWV0YWRhdGFUcmVlKGh0bWxNb25vbWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZEhyZWZzKSB7XG4gIGlmIChsb2FkZWRIcmVmcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbG9hZGVkSHJlZnMgPSB7fTtcbiAgfVxuICByZXR1cm4gaHRtbE1vbm9tZXIubWV0YWRhdGFMb2FkZWQudGhlbihmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgIG1ldGFkYXRhID0ge1xuICAgICAgZWxlbWVudHM6IG1ldGFkYXRhLmVsZW1lbnRzLFxuICAgICAgZmVhdHVyZXM6IG1ldGFkYXRhLmZlYXR1cmVzLFxuICAgICAgaHJlZjogaHRtbE1vbm9tZXIuaHJlZlxuICAgIH07XG4gICAgcmV0dXJuIGh0bWxNb25vbWVyLmRlcHNMb2FkZWQudGhlbihmdW5jdGlvbihocmVmcykge1xuICAgICAgdmFyIGRlcE1ldGFkYXRhID0gW107XG4gICAgICBocmVmcy5mb3JFYWNoKGZ1bmN0aW9uKGhyZWYpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgaWYgKGRlcE1ldGFkYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBtZXRhZGF0YVByb21pc2UgPSBkZXBNZXRhZGF0YVtkZXBNZXRhZGF0YS5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBtZXRhZGF0YVByb21pc2UgPSBtZXRhZGF0YVByb21pc2UudGhlbihmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoIWxvYWRlZEhyZWZzW2hyZWZdKSB7XG4gICAgICAgICAgICBsb2FkZWRIcmVmc1tocmVmXSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFUcmVlKHRoaXMuaHRtbFtocmVmXSwgbG9hZGVkSHJlZnMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIGRlcE1ldGFkYXRhLnB1c2gobWV0YWRhdGFQcm9taXNlKTtcbiAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoZGVwTWV0YWRhdGEpLnRoZW4oZnVuY3Rpb24oaW1wb3J0TWV0YWRhdGEpIHtcbiAgICAgICAgbWV0YWRhdGEuaW1wb3J0cyA9IGltcG9ydE1ldGFkYXRhO1xuICAgICAgICByZXR1cm4gaHRtbE1vbm9tZXIuaHRtbExvYWRlZC50aGVuKGZ1bmN0aW9uKHBhcnNlZEh0bWwpIHtcbiAgICAgICAgICBtZXRhZGF0YS5odG1sID0gcGFyc2VkSHRtbDtcbiAgICAgICAgICBpZiAobWV0YWRhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgICAgIG1ldGFkYXRhLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgICAgICBhdHRhY2hEb21Nb2R1bGUocGFyc2VkSHRtbCwgZWxlbWVudCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG1ldGFkYXRhO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0uYmluZCh0aGlzKSk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG5mdW5jdGlvbiBtYXRjaGluZ0ltcG9ydChpbXBvcnRFbGVtZW50KSB7XG4gIHZhciBtYXRjaGVzVGFnID0gZG9tNS5wcmVkaWNhdGVzLmhhc1RhZ05hbWUoaW1wb3J0RWxlbWVudC50YWdOYW1lKTtcbiAgdmFyIG1hdGNoZXNIcmVmID0gZG9tNS5wcmVkaWNhdGVzLmhhc0F0dHJWYWx1ZSgnaHJlZicsIGRvbTUuZ2V0QXR0cmlidXRlKGltcG9ydEVsZW1lbnQsICdocmVmJykpO1xuICB2YXIgbWF0Y2hlc1JlbCA9IGRvbTUucHJlZGljYXRlcy5oYXNBdHRyVmFsdWUoJ3JlbCcsIGRvbTUuZ2V0QXR0cmlidXRlKGltcG9ydEVsZW1lbnQsICdyZWwnKSk7XG4gIHJldHVybiBkb201LnByZWRpY2F0ZXMuQU5EKG1hdGNoZXNUYWcsIG1hdGNoZXNIcmVmLCBtYXRjaGVzUmVsKTtcbn1cblxuLy8gVE9ETyhham8pOiBSZWZhY3RvciBvdXQgb2YgdnVsY2FuaXplIGludG8gZG9tNS5cbnZhciBwb2x5bWVyRXh0ZXJuYWxTdHlsZSA9IGRvbTUucHJlZGljYXRlcy5BTkQoXG4gIGRvbTUucHJlZGljYXRlcy5oYXNUYWdOYW1lKCdsaW5rJyksXG4gIGRvbTUucHJlZGljYXRlcy5oYXNBdHRyVmFsdWUoJ3JlbCcsICdpbXBvcnQnKSxcbiAgZG9tNS5wcmVkaWNhdGVzLmhhc0F0dHJWYWx1ZSgndHlwZScsICdjc3MnKVxuKTtcblxudmFyIGV4dGVybmFsU2NyaXB0ID0gZG9tNS5wcmVkaWNhdGVzLkFORChcbiAgZG9tNS5wcmVkaWNhdGVzLmhhc1RhZ05hbWUoJ3NjcmlwdCcpLFxuICBkb201LnByZWRpY2F0ZXMuaGFzQXR0cignc3JjJylcbik7XG5cbnZhciBpc0h0bWxJbXBvcnROb2RlID0gZG9tNS5wcmVkaWNhdGVzLkFORChcbiAgZG9tNS5wcmVkaWNhdGVzLmhhc1RhZ05hbWUoJ2xpbmsnKSxcbiAgZG9tNS5wcmVkaWNhdGVzLmhhc0F0dHJWYWx1ZSgncmVsJywgJ2ltcG9ydCcpLFxuICBkb201LnByZWRpY2F0ZXMuTk9UKFxuICAgIGRvbTUucHJlZGljYXRlcy5oYXNBdHRyVmFsdWUoJ3R5cGUnLCAnY3NzJylcbiAgKVxuKTtcblxuQW5hbHl6ZXIucHJvdG90eXBlLl9pbmxpbmVTdHlsZXMgPSBmdW5jdGlvbiBfaW5saW5lU3R5bGVzKGFzdCwgaHJlZikge1xuICB2YXIgY3NzTGlua3MgPSBkb201LnF1ZXJ5QWxsKGFzdCwgcG9seW1lckV4dGVybmFsU3R5bGUpO1xuICBjc3NMaW5rcy5mb3JFYWNoKGZ1bmN0aW9uKGxpbmspIHtcbiAgICB2YXIgbGlua0hyZWYgPSBkb201LmdldEF0dHJpYnV0ZShsaW5rLCAnaHJlZicpO1xuICAgIHZhciB1cmkgPSB1cmwucmVzb2x2ZShocmVmLCBsaW5rSHJlZik7XG4gICAgdmFyIGNvbnRlbnQgPSB0aGlzLl9jb250ZW50W3VyaV07XG4gICAgdmFyIHN0eWxlID0gZG9tNS5jb25zdHJ1Y3RvcnMuZWxlbWVudCgnc3R5bGUnKTtcbiAgICBkb201LnNldFRleHRDb250ZW50KHN0eWxlLCAnXFxuJyArIGNvbnRlbnQgKyAnXFxuJyk7XG4gICAgZG9tNS5yZXBsYWNlKGxpbmssIHN0eWxlKTtcbiAgfS5iaW5kKHRoaXMpKTtcbiAgcmV0dXJuIGNzc0xpbmtzLmxlbmd0aCA+IDA7XG59O1xuXG5BbmFseXplci5wcm90b3R5cGUuX2lubGluZVNjcmlwdHMgPSBmdW5jdGlvbiBfaW5saW5lU2NyaXB0cyhhc3QsIGhyZWYpIHtcbiAgdmFyIHNjcmlwdHMgPSBkb201LnF1ZXJ5QWxsKGFzdCwgZXh0ZXJuYWxTY3JpcHQpO1xuICBzY3JpcHRzLmZvckVhY2goZnVuY3Rpb24oc2NyaXB0KSB7XG4gICAgdmFyIHNjcmlwdEhyZWYgPSBkb201LmdldEF0dHJpYnV0ZShzY3JpcHQsICdzcmMnKTtcbiAgICB2YXIgdXJpID0gdXJsLnJlc29sdmUoaHJlZiwgc2NyaXB0SHJlZik7XG4gICAgdmFyIGNvbnRlbnQgPSB0aGlzLl9jb250ZW50W3VyaV07XG4gICAgdmFyIGlubGluZWQgPSBkb201LmNvbnN0cnVjdG9ycy5lbGVtZW50KCdzY3JpcHQnKTtcbiAgICBkb201LnNldFRleHRDb250ZW50KGlubGluZWQsICdcXG4nICsgY29udGVudCArICdcXG4nKTtcbiAgICBkb201LnJlcGxhY2Uoc2NyaXB0LCBpbmxpbmVkKTtcbiAgfS5iaW5kKHRoaXMpKTtcbiAgcmV0dXJuIHNjcmlwdHMubGVuZ3RoID4gMDtcbn07XG5cbkFuYWx5emVyLnByb3RvdHlwZS5faW5saW5lSW1wb3J0cyA9IGZ1bmN0aW9uIF9pbmxpbmVJbXBvcnRzKGFzdCwgaHJlZiwgbG9hZGVkKSB7XG4gIHZhciBpbXBvcnRzID0gZG9tNS5xdWVyeUFsbChhc3QsIGlzSHRtbEltcG9ydE5vZGUpO1xuICBpbXBvcnRzLmZvckVhY2goZnVuY3Rpb24oaHRtbEltcG9ydCkge1xuICAgIHZhciBpbXBvcnRIcmVmID0gZG9tNS5nZXRBdHRyaWJ1dGUoaHRtbEltcG9ydCwgJ2hyZWYnKTtcbiAgICB2YXIgdXJpID0gdXJsLnJlc29sdmUoaHJlZiwgaW1wb3J0SHJlZik7XG4gICAgaWYgKGxvYWRlZFt1cmldKSB7XG4gICAgICBkb201LnJlbW92ZShodG1sSW1wb3J0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGNvbnRlbnQgPSB0aGlzLmdldExvYWRlZEFzdCh1cmksIGxvYWRlZCk7XG4gICAgZG9tNS5yZXBsYWNlKGh0bWxJbXBvcnQsIGNvbnRlbnQpO1xuICB9LmJpbmQodGhpcykpO1xuICByZXR1cm4gaW1wb3J0cy5sZW5ndGggPiAwO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSByZXNvbHZpbmcgdG8gYSBmb3JtIG9mIHRoZSBBU1Qgd2l0aCBhbGwgbGlua3MgcmVwbGFjZWRcbiAqIHdpdGggdGhlIGRvY3VtZW50IHRoZXkgbGluayB0by4gLmNzcyBhbmQgLnNjcmlwdCBmaWxlcyBiZWNvbWUgJmx0O3N0eWxlJmd0OyBhbmRcbiAqICZsdDtzY3JpcHQmZ3Q7LCByZXNwZWN0aXZlbHkuXG4gKlxuICogVGhlIGVsZW1lbnRzIGluIHRoZSBsb2FkZWQgZG9jdW1lbnQgYXJlIHVubW9kaWZpZWQgZnJvbSB0aGVpciBvcmlnaW5hbFxuICogZG9jdW1lbnRzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIFRoZSBkb2N1bWVudCB0byBsb2FkLlxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZyxib29sZWFuPj19IGxvYWRlZCBBbiBvYmplY3Qga2V5ZWQgYnkgYWxyZWFkeSBsb2FkZWQgZG9jdW1lbnRzLlxuICogQHJldHVybiB7UHJvbWlzZS48RG9jdW1lbnRBU1Q+fVxuICovXG5BbmFseXplci5wcm90b3R5cGUuZ2V0TG9hZGVkQXN0ID0gZnVuY3Rpb24gZ2V0TG9hZGVkQXN0KGhyZWYsIGxvYWRlZCkge1xuICBpZiAoIWxvYWRlZCkge1xuICAgIGxvYWRlZCA9IHt9O1xuICB9XG4gIGxvYWRlZFtocmVmXSA9IHRydWU7XG4gIHZhciBwYXJzZWREb2N1bWVudCA9IHRoaXMucGFyc2VkRG9jdW1lbnRzW2hyZWZdO1xuICB2YXIgYW5hbHl6ZWREb2N1bWVudCA9IHRoaXMuaHRtbFtocmVmXTtcbiAgdmFyIGFzdENvcHkgPSBkb201LnBhcnNlKGRvbTUuc2VyaWFsaXplKHBhcnNlZERvY3VtZW50KSk7XG4gIC8vIFdoZW5ldmVyIHdlIGlubGluZSBzb21ldGhpbmcsIHJlc2V0IGlubGluZWQgdG8gdHJ1ZSB0byBrbm93IHRoYXQgYW5vYXRoZXJcbiAgLy8gaW5saW5pbmcgcGFzcyBpcyBuZWVkZWQ7XG4gIHRoaXMuX2lubGluZVN0eWxlcyhhc3RDb3B5LCBocmVmKTtcbiAgdGhpcy5faW5saW5lU2NyaXB0cyhhc3RDb3B5LCBocmVmKTtcbiAgdGhpcy5faW5saW5lSW1wb3J0cyhhc3RDb3B5LCBocmVmLCBsb2FkZWQpO1xuICByZXR1cm4gYXN0Q29weTtcbn07XG5cbi8qKlxuICogQ2FsbHMgYGRvbTUubm9kZVdhbGtBbGxgIG9uIGVhY2ggZG9jdW1lbnQgdGhhdCBgQW5heXpsZXJgIGhhcyBsYW9kZWQuXG4gKiBAcGFyYW0gIHtPYmplY3R9IHByZWRpY2F0ZSBBIGRvbTUgcHJlZGljYXRlLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5BbmFseXplci5wcm90b3R5cGUubm9kZVdhbGtEb2N1bWVudHMgPSBmdW5jdGlvbiBub2RlV2Fsa0RvY3VtZW50cyhwcmVkaWNhdGUpIHtcbiAgZm9yICh2YXIgaHJlZiBpbiB0aGlzLnBhcnNlZERvY3VtZW50cykge1xuICAgIHZhciBtYXRjaCA9IGRvbTUubm9kZVdhbGsodGhpcy5wYXJzZWREb2N1bWVudHNbaHJlZl0sIHByZWRpY2F0ZSk7XG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBDYWxscyBgZG9tNS5ub2RlV2Fsa0FsbGAgb24gZWFjaCBkb2N1bWVudCB0aGF0IGBBbmF5emxlcmAgaGFzIGxhb2RlZC5cbiAqIEBwYXJhbSAge09iamVjdH0gcHJlZGljYXRlIEEgZG9tNSBwcmVkaWNhdGUuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbkFuYWx5emVyLnByb3RvdHlwZS5ub2RlV2Fsa0FsbERvY3VtZW50cyA9IGZ1bmN0aW9uIG5vZGVXYWxrRG9jdW1lbnRzKHByZWRpY2F0ZSkge1xuICB2YXIgcmVzdWx0cyA9IFtdO1xuICBmb3IgKHZhciBocmVmIGluIHRoaXMucGFyc2VkRG9jdW1lbnRzKSB7XG4gICAgdmFyIG5ld05vZGVzID0gZG9tNS5ub2RlV2Fsa0FsbCh0aGlzLnBhcnNlZERvY3VtZW50c1tocmVmXSwgcHJlZGljYXRlKTtcbiAgICByZXN1bHRzID0gcmVzdWx0cy5jb25jYXQobmV3Tm9kZXMpO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLyoqIEFubm90YXRlcyBhbGwgbG9hZGVkIG1ldGFkYXRhIHdpdGggaXRzIGRvY3VtZW50YXRpb24uICovXG5BbmFseXplci5wcm90b3R5cGUuYW5ub3RhdGUgPSBmdW5jdGlvbiBhbm5vdGF0ZSgpIHtcbiAgaWYgKHRoaXMuZmVhdHVyZXMubGVuZ3RoID4gMCkge1xuICAgIHZhciBmZWF0dXJlRWwgPSBkb2NzLmZlYXR1cmVFbGVtZW50KHRoaXMuZmVhdHVyZXMpO1xuICAgIHRoaXMuZWxlbWVudHMudW5zaGlmdChmZWF0dXJlRWwpO1xuICAgIHRoaXMuZWxlbWVudHNCeVRhZ05hbWVbZmVhdHVyZUVsLmlzXSA9IGZlYXR1cmVFbDtcbiAgfVxuICB2YXIgYmVoYXZpb3JzQnlOYW1lID0gdGhpcy5iZWhhdmlvcnNCeU5hbWU7XG4gIHZhciBlbGVtZW50SGVscGVyID0gZnVuY3Rpb24oZGVzY3JpcHRvcil7XG4gICAgZG9jcy5hbm5vdGF0ZUVsZW1lbnQoZGVzY3JpcHRvciwgYmVoYXZpb3JzQnlOYW1lKTtcbiAgfTtcbiAgdGhpcy5lbGVtZW50cy5mb3JFYWNoKGVsZW1lbnRIZWxwZXIpO1xuICB0aGlzLmJlaGF2aW9ycy5mb3JFYWNoKGVsZW1lbnRIZWxwZXIpOyAvLyBTYW1lIHNoYXBlLlxuICB0aGlzLmJlaGF2aW9ycy5mb3JFYWNoKGZ1bmN0aW9uKGJlaGF2aW9yKXtcbiAgICBpZiAoYmVoYXZpb3IuaXMgIT09IGJlaGF2aW9yLnN5bWJvbCAmJiBiZWhhdmlvci5zeW1ib2wpIHtcbiAgICAgIHRoaXMuYmVoYXZpb3JzQnlOYW1lW2JlaGF2aW9yLnN5bWJvbF0gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9LmJpbmQodGhpcykpO1xufTtcblxuZnVuY3Rpb24gYXR0YWNoRG9tTW9kdWxlKHBhcnNlZEltcG9ydCwgZWxlbWVudCkge1xuICB2YXIgZG9tTW9kdWxlcyA9IHBhcnNlZEltcG9ydFsnZG9tLW1vZHVsZSddO1xuICBmb3IgKHZhciBpID0gMCwgZG9tTW9kdWxlOyBpIDwgZG9tTW9kdWxlcy5sZW5ndGg7IGkrKykge1xuICAgIGRvbU1vZHVsZSA9IGRvbU1vZHVsZXNbaV07XG4gICAgaWYgKGRvbTUuZ2V0QXR0cmlidXRlKGRvbU1vZHVsZSwgJ2lkJykgPT09IGVsZW1lbnQuaXMpIHtcbiAgICAgIGVsZW1lbnQuZG9tTW9kdWxlID0gZG9tTW9kdWxlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG4vKiogUmVtb3ZlcyByZWR1bmRhbnQgcHJvcGVydGllcyBmcm9tIHRoZSBjb2xsZWN0ZWQgZGVzY3JpcHRvcnMuICovXG5BbmFseXplci5wcm90b3R5cGUuY2xlYW4gPSBmdW5jdGlvbiBjbGVhbigpIHtcbiAgdGhpcy5lbGVtZW50cy5mb3JFYWNoKGRvY3MuY2xlYW5FbGVtZW50KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQW5hbHl6ZXI7XG4iXX0=
  737 +},{"./ast-utils/docs":5,"./ast-utils/import-parse":10,"./ast-utils/js-parse":11,"./loader/file-loader":13,"./loader/fs-resolver":14,"./loader/noop-resolver":15,"./loader/xhr-resolver":16,"dom5":38,"es6-promise":60,"url":26}],2:[function(require,module,exports){
636 738 /**
637 739 * @license
638 740 * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
... ... @@ -820,7 +922,7 @@ function arrayExpressionToValue(arry) {
820 922 for (var i=0; i<arry.elements.length; i++) {
821 923 var v = expressionToValue(arry.elements[i]);
822 924 if (v === undefined)
823   - v = CANT_CONVERT;
  925 + continue;
824 926 if (i !== 0)
825 927 value += ', ';
826 928 value += v;
... ... @@ -838,7 +940,7 @@ function objectExpressionToValue(obj) {
838 940 var k = expressionToValue(obj.properties[i].key);
839 941 var v = expressionToValue(obj.properties[i].value);
840 942 if (v === undefined)
841   - v = CANT_CONVERT;
  943 + continue;
842 944 if (i !== 0)
843 945 value += ', ';
844 946 value += '"' + k + '": ' + v;
... ... @@ -967,6 +1069,35 @@ module.exports = function behaviorFinder() {
967 1069 return newBehavior;
968 1070 }
969 1071  
  1072 + /**
  1073 + * gets the expression representing a behavior from a node.
  1074 + */
  1075 + function behaviorExpression(node) {
  1076 + switch(node.type) {
  1077 + case 'ExpressionStatement':
  1078 + return node.expression.right;
  1079 + case 'VariableDeclaration':
  1080 + return node.declarations.length > 0 ? node.declarations[0].init : null;
  1081 + }
  1082 + }
  1083 +
  1084 + /**
  1085 + * checks whether an expression is a simple array containing only member
  1086 + * expressions or identifiers.
  1087 + */
  1088 + function isSimpleBehaviorArray(expression) {
  1089 + if (!expression || expression.type !== 'ArrayExpression') return false;
  1090 + for (var i=0; i < expression.elements.length; i++) {
  1091 + if (expression.elements[i].type !== 'MemberExpression' &&
  1092 + expression.elements[i].type !== 'Identifier') {
  1093 + return false;
  1094 + }
  1095 + }
  1096 + return true;
  1097 + }
  1098 +
  1099 + var templatizer = "Polymer.Templatizer";
  1100 +
970 1101 var visitors = {
971 1102  
972 1103 /**
... ... @@ -993,20 +1124,14 @@ module.exports = function behaviorFinder() {
993 1124 // inside the array. Ex:
994 1125 // Polymer.IronMultiSelectableBehavior = [ {....}, Polymer.IronSelectableBehavior]
995 1126 // We add these to behaviors array
996   - var expression;
997   - switch(node.type) {
998   - case 'ExpressionStatement':
999   - expression = node.expression.right;
1000   - break;
1001   - case 'VariableDeclaration':
1002   - expression = node.declarations.length > 0 ? node.declarations[0].init : null;
1003   - break;
1004   - }
  1127 + var expression = behaviorExpression(node);
1005 1128 var chained = [];
1006 1129 if (expression && expression.type === 'ArrayExpression') {
1007 1130 for (var i=0; i < expression.elements.length; i++) {
1008   - if (expression.elements[i].type === 'MemberExpression')
  1131 + if (expression.elements[i].type === 'MemberExpression' ||
  1132 + expression.elements[i].type === 'Identifier') {
1009 1133 chained.push(astValue.expressionToValue(expression.elements[i]));
  1134 + }
1010 1135 }
1011 1136 if (chained.length > 0)
1012 1137 currentBehavior.behaviors = chained;
... ... @@ -1015,8 +1140,13 @@ module.exports = function behaviorFinder() {
1015 1140  
1016 1141 _initBehavior: function(node, getName) {
1017 1142 var comment = esutil.getAttachedComment(node);
  1143 + var symbol = getName();
1018 1144 // Quickly filter down to potential candidates.
1019   - if (!comment || comment.indexOf('@polymerBehavior') === -1) return;
  1145 + if (!comment || comment.indexOf('@polymerBehavior') === -1) {
  1146 + if (symbol !== templatizer) {
  1147 + return;
  1148 + }
  1149 + }
1020 1150  
1021 1151  
1022 1152 currentBehavior = {
... ... @@ -1029,14 +1159,16 @@ module.exports = function behaviorFinder() {
1029 1159  
1030 1160 docs.annotateBehavior(currentBehavior);
1031 1161 // Make sure that we actually parsed a behavior tag!
1032   - if (!jsdoc.hasTag(currentBehavior.jsdoc, 'polymerBehavior')) {
  1162 + if (!jsdoc.hasTag(currentBehavior.jsdoc, 'polymerBehavior') &&
  1163 + symbol !== templatizer) {
1033 1164 currentBehavior = null;
1034 1165 return;
1035 1166 }
1036 1167  
1037 1168 var name = jsdoc.getTag(currentBehavior.jsdoc, 'polymerBehavior', 'name');
  1169 + currentBehavior.symbol = symbol;
1038 1170 if (!name) {
1039   - name = getName();
  1171 + name = currentBehavior.symbol;
1040 1172 }
1041 1173 if (!name) {
1042 1174 console.warn('Unable to determine name for @polymerBehavior:', comment);
... ... @@ -1046,6 +1178,16 @@ module.exports = function behaviorFinder() {
1046 1178 this._parseChainedBehaviors(node);
1047 1179  
1048 1180 currentBehavior = mergeBehavior(currentBehavior);
  1181 +
  1182 + // Some behaviors are just lists of other behaviors. If this is one then
  1183 + // add it to behaviors right away.
  1184 + if (isSimpleBehaviorArray(behaviorExpression(node))) {
  1185 + // TODO(ajo): Add a test to confirm the presence of `properties`.
  1186 + if (!currentBehavior.properties) currentBehavior.properties = [];
  1187 + if (behaviors.indexOf(currentBehavior) === -1)
  1188 + behaviors.push(currentBehavior);
  1189 + currentBehavior = null;
  1190 + }
1049 1191 },
1050 1192  
1051 1193 /**
... ... @@ -1180,6 +1322,54 @@ function annotateElementHeader(descriptor) {
1180 1322 }
1181 1323 }
1182 1324  
  1325 +function matchByName(propa, propb) {
  1326 + return propa.name == propb.name;
  1327 +}
  1328 +
  1329 +function copyProperties(from, to, behaviorsByName) {
  1330 + if (from.properties) {
  1331 + from.properties.forEach(function(fromProp){
  1332 + for (var toProp, i = 0; i < to.properties.length; i++) {
  1333 + toProp = to.properties[i];
  1334 + if (fromProp.name === toProp.name) {
  1335 + return;
  1336 + }
  1337 + }
  1338 + var newProp = {__fromBehavior: from.is};
  1339 + if (fromProp.__fromBehavior) {
  1340 + return;
  1341 + }
  1342 + Object.keys(fromProp).forEach(function(propertyField){
  1343 + newProp[propertyField] = fromProp[propertyField];
  1344 + });
  1345 + to.properties.push(newProp);
  1346 + });
  1347 + }
  1348 + if (!from.behaviors) {
  1349 + return;
  1350 + }
  1351 + from.behaviors.forEach(function(behavior){
  1352 + var definedBehavior = behaviorsByName[behavior] || behaviorsByName[behavior.symbol];
  1353 + if (!definedBehavior) {
  1354 + return;
  1355 + }
  1356 + copyProperties(definedBehavior, to, behaviorsByName);
  1357 + });
  1358 +}
  1359 +
  1360 +function mixinBehaviors(descriptor, behaviorsByName) {
  1361 + if (descriptor.behaviors) {
  1362 + descriptor.behaviors.forEach(function(behavior){
  1363 + if (!behaviorsByName[behavior]) {
  1364 + console.warn("Behavior " + behavior + " not found!");
  1365 + return;
  1366 + }
  1367 + var definedBehavior = behaviorsByName[behavior];
  1368 + copyProperties(definedBehavior, descriptor, behaviorsByName);
  1369 + });
  1370 + }
  1371 +}
  1372 +
1183 1373 /**
1184 1374 * Annotates documentation found within a Hydrolysis element descriptor. Also
1185 1375 * supports behaviors.
... ... @@ -1190,7 +1380,7 @@ function annotateElementHeader(descriptor) {
1190 1380 * @param {Object} descriptor The element descriptor.
1191 1381 * @return {Object} The descriptor that was given.
1192 1382 */
1193   -function annotateElement(descriptor) {
  1383 +function annotateElement(descriptor, behaviorsByName) {
1194 1384 if (!descriptor.desc && descriptor.type === 'element') {
1195 1385 descriptor.desc = _findElementDocs(descriptor.is,
1196 1386 descriptor.domModule,
... ... @@ -1201,8 +1391,11 @@ function annotateElement(descriptor) {
1201 1391 // The `<dom-module>` is too low level for most needs, and it is _not_
1202 1392 // serializable. So we drop it now that we've extracted all the useful bits
1203 1393 // from it.
  1394 + // TODO: Don't worry about serializability here, provide an API to get JSON.
1204 1395 delete descriptor.domModule;
1205 1396  
  1397 + mixinBehaviors(descriptor, behaviorsByName);
  1398 +
1206 1399 // Descriptors that should have their `desc` properties parsed as JSDoc.
1207 1400 descriptor.properties.forEach(function(property) {
1208 1401 // Feature properties are special, configuration is really just a matter of
... ... @@ -1235,9 +1428,8 @@ function annotateElement(descriptor) {
1235 1428 * @param {Object} descriptor behavior descriptor
1236 1429 * @return {Object} descriptor passed in as param
1237 1430 */
1238   -function annotateBehavior(descriptor) {
  1431 +function annotateBehavior(descriptor, behaviorsByName) {
1239 1432 annotate(descriptor);
1240   -
1241 1433 annotateElementHeader(descriptor);
1242 1434  
1243 1435 return descriptor;
... ... @@ -1296,7 +1488,10 @@ function annotateProperty(descriptor, ignoreConfiguration) {
1296 1488 // @default JSDoc wins
1297 1489 var defaultTag = jsdoc.getTag(descriptor.jsdoc, 'default');
1298 1490 if (defaultTag !== null) {
1299   - descriptor.default = (defaultTag.name || '') + (defaultTag.description || '');
  1491 + var newDefault = (defaultTag.name || '') + (defaultTag.description || '');
  1492 + if (newDefault !== '') {
  1493 + descriptor.default = newDefault;
  1494 + }
1300 1495 }
1301 1496  
1302 1497 return descriptor;
... ... @@ -1408,6 +1603,30 @@ function cleanProperty(property) {
1408 1603 }
1409 1604  
1410 1605 /**
  1606 + * Parse elements defined only in comments.
  1607 + * @param {comments} Array<string> A list of comments to parse.
  1608 + * @return {ElementDescriptor} A list of pseudo-elements.
  1609 + */
  1610 +function parsePseudoElements(comments) {
  1611 + var elements = [];
  1612 + comments.forEach(function(comment) {
  1613 + var parsed = jsdoc.parseJsdoc(comment);
  1614 + var pseudoTag = jsdoc.getTag(parsed, 'pseudoElement', 'name');
  1615 + if (pseudoTag) {
  1616 + parsed.is = pseudoTag;
  1617 + parsed.jsdoc = {description: parsed.description, tags: parsed.tags};
  1618 + parsed.properties = [];
  1619 + parsed.desc = parsed.description;
  1620 + parsed.description = undefined;
  1621 + parsed.tags = undefined;
  1622 + annotateElementHeader(parsed);
  1623 + elements.push(parsed);
  1624 + }
  1625 + });
  1626 + return elements;
  1627 +}
  1628 +
  1629 +/**
1411 1630 * @param {string} elementId
1412 1631 * @param {DocumentAST} domModule
1413 1632 * @param {DocumentAST} scriptElement The script that the element was defined in.
... ... @@ -1470,6 +1689,7 @@ module.exports = {
1470 1689 clean: clean,
1471 1690 cleanElement: cleanElement,
1472 1691 featureElement: featureElement,
  1692 + parsePseudoElements: parsePseudoElements
1473 1693 };
1474 1694  
1475 1695 },{"./jsdoc":12,"dom5":38}],6:[function(require,module,exports){
... ... @@ -1525,7 +1745,6 @@ var elementFinder = function elementFinder() {
1525 1745 if (node.type != 'ArrayExpression') {
1526 1746 return;
1527 1747 }
1528   - element.behaviors = [];
1529 1748  
1530 1749 for (var i=0; i<node.elements.length; i++) {
1531 1750 var v = astValue.expressionToValue(node.elements[i]);
... ... @@ -1566,6 +1785,7 @@ var elementFinder = function elementFinder() {
1566 1785 enterObjectExpression: function enterObjectExpression(node, parent) {
1567 1786 if (element && !element.properties) {
1568 1787 element.properties = [];
  1788 + element.behaviors = [];
1569 1789 for (var i = 0; i < node.properties.length; i++) {
1570 1790 var prop = node.properties[i];
1571 1791 var name = esutil.objectKeyToString(prop.key);
... ... @@ -1883,13 +2103,30 @@ var isStyleNode = p.OR(
1883 2103 )
1884 2104 );
1885 2105  
  2106 +var isJSScriptNode = p.AND(
  2107 + p.hasTagName('script'),
  2108 + p.OR(
  2109 + p.NOT(p.hasAttr('type')),
  2110 + p.hasAttrValue('type', 'text/javascript'),
  2111 + p.hasAttrValue('type', 'application/javascript')
  2112 + )
  2113 +);
  2114 +
1886 2115 function addNode(node, registry) {
1887 2116 if (isHtmlImportNode(node)) {
1888 2117 registry.import.push(node);
1889 2118 } else if (isStyleNode(node)) {
1890 2119 registry.style.push(node);
1891   - } else if (registry.hasOwnProperty(node.tagName)) {
1892   - registry[node.tagName].push(node);
  2120 + } else if (isJSScriptNode(node)) {
  2121 + registry.script.push(node);
  2122 + } else if (node.tagName === 'base') {
  2123 + registry.base.push(node);
  2124 + } else if (node.tagName === 'template') {
  2125 + registry.template.push(node);
  2126 + } else if (node.tagName === 'dom-module') {
  2127 + registry['dom-module'].push(node);
  2128 + } else if (dom5.isCommentNode(node)) {
  2129 + registry.comment.push(node);
1893 2130 }
1894 2131 }
1895 2132  
... ... @@ -1951,13 +2188,14 @@ var importParse = function importParse(htmlString, href) {
1951 2188 script: [],
1952 2189 style: [],
1953 2190 import: [],
1954   - 'dom-module': []};
  2191 + 'dom-module': [],
  2192 + comment: []};
1955 2193  
1956 2194 var queue = [].concat(doc.childNodes);
1957 2195 var nextNode;
1958 2196 while (queue.length > 0) {
1959 2197 nextNode = queue.shift();
1960   - if (nextNode && nextNode.tagName) {
  2198 + if (nextNode) {
1961 2199 queue = queue.concat(nextNode.childNodes);
1962 2200 addNode(nextNode, registry);
1963 2201 }
... ... @@ -2058,6 +2296,7 @@ var jsParse = function jsParse(jsString) {
2058 2296 behaviors: behaviorInfo.behaviors,
2059 2297 elements: elementInfo.elements,
2060 2298 features: featureInfo.features,
  2299 + parsedScript: script
2061 2300 };
2062 2301 };
2063 2302  
... ... @@ -2376,7 +2615,7 @@ FileLoader.prototype = {
2376 2615 }
2377 2616  
2378 2617 if (!handled) {
2379   - deferred.reject('no resolver found');
  2618 + deferred.reject(new Error('no resolver found for ' + uri));
2380 2619 }
2381 2620  
2382 2621 promise = deferred.promise;
... ... @@ -2391,7 +2630,7 @@ FileLoader.prototype = {
2391 2630 module.exports = FileLoader;
2392 2631  
2393 2632 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2394   -
  2633 +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9sb2FkZXIvZmlsZS1sb2FkZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgVGhlIFBvbHltZXIgUHJvamVjdCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhpcyBjb2RlIG1heSBvbmx5IGJlIHVzZWQgdW5kZXIgdGhlIEJTRCBzdHlsZSBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9MSUNFTlNFLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBhdXRob3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQVVUSE9SUy50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgY29udHJpYnV0b3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQ09OVFJJQlVUT1JTLnR4dFxuICogQ29kZSBkaXN0cmlidXRlZCBieSBHb29nbGUgYXMgcGFydCBvZiB0aGUgcG9seW1lciBwcm9qZWN0IGlzIGFsc29cbiAqIHN1YmplY3QgdG8gYW4gYWRkaXRpb25hbCBJUCByaWdodHMgZ3JhbnQgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL1BBVEVOVFMudHh0XG4gKi9cblxuLy8ganNoaW50IG5vZGU6dHJ1ZVxuJ3VzZSBzdHJpY3QnO1xuXG4vLyBqc2hpbnQgLVcwNzlcbi8vIFByb21pc2UgcG9seWZpbGxcbnZhciBQcm9taXNlID0gZ2xvYmFsLlByb21pc2UgfHwgcmVxdWlyZSgnZXM2LXByb21pc2UnKS5Qcm9taXNlO1xuLy8ganNoaW50ICtXMDc5XG5cbmZ1bmN0aW9uIERlZmVycmVkKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMucHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHNlbGYucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgc2VsZi5yZWplY3QgPSByZWplY3Q7XG4gIH0pO1xufVxuXG4vKipcbiAqIEFuIG9iamVjdCB0aGF0IGtub3dzIGhvdyB0byByZXNvbHZlIHJlc291cmNlcy5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IFJlc29sdmVyXG4gKiBAbWVtYmVyb2YgaHlkcm9seXNpc1xuICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcsIERlZmVycmVkKTogYm9vbGVhbn0gYWNjZXB0IEF0dGVtcHQgdG8gcmVzb2x2ZVxuICogICAgIGBkZWZlcnJlZGAgd2l0aCB0aGUgY29udGVudHMgdGhlIHNwZWNpZmllZCBVUkwuIFJldHVybnMgZmFsc2UgaWYgdGhlXG4gKiAgICAgUmVzb2x2ZXIgaXMgdW5hYmxlIHRvIHJlc29sdmUgdGhlIFVSTC5cbiAqL1xuXG5cbi8qKlxuICogQSBGaWxlTG9hZGVyIGxldHMgeW91IHJlc29sdmUgVVJMcyB3aXRoIGEgc2V0IG9mIHBvdGVudGlhbCByZXNvbHZlcnMuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKi9cbmZ1bmN0aW9uIEZpbGVMb2FkZXIoKSB7XG4gIHRoaXMucmVzb2x2ZXJzID0gW107XG4gIC8vIG1hcCB1cmwgLT4gRGVmZXJyZWRcbiAgdGhpcy5yZXF1ZXN0cyA9IHt9O1xufVxuRmlsZUxvYWRlci5wcm90b3R5cGUgPSB7XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBpbnN0YW5jZSBvZiBhIFJlc29sdmVyIGNsYXNzIHRvIHRoZSBsaXN0IG9mIHVybCByZXNvbHZlcnNcbiAgICpcbiAgICogT3JkZXJpbmcgb2YgcmVzb2x2ZXJzIGlzIG1vc3QgdG8gbGVhc3QgcmVjZW50bHkgYWRkZWRcbiAgICogVGhlIGZpcnN0IHJlc29sdmVyIHRvIFwiYWNjZXB0XCIgdGhlIHVybCB3aW5zLlxuICAgKiBAcGFyYW0ge1Jlc29sdmVyfSByZXNvbHZlciBUaGUgcmVzb2x2ZXIgdG8gYWRkLlxuICAgKi9cbiAgYWRkUmVzb2x2ZXI6IGZ1bmN0aW9uKHJlc29sdmVyKSB7XG4gICAgdGhpcy5yZXNvbHZlcnMucHVzaChyZXNvbHZlcik7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHByb21pc2UgZm9yIGFuIGFic29sdXRlIHVybFxuICAgKlxuICAgKiBVcmwgcmVxdWVzdHMgYXJlIGRlZHVwbGljYXRlZCBieSB0aGUgbG9hZGVyLCByZXR1cm5pbmcgdGhlIHNhbWUgUHJvbWlzZSBmb3JcbiAgICogaWRlbnRpY2FsIHVybHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCAgICAgICAgVGhlIGFic29sdXRlIHVybCB0byByZXF1ZXN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlLjxzdHJpbmc+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgY29udGVudHMgb2YgdGhlIFVSTC5cbiAgICovXG4gIHJlcXVlc3Q6IGZ1bmN0aW9uKHVyaSkge1xuICAgIHZhciBwcm9taXNlO1xuXG4gICAgaWYgKCEodXJpIGluIHRoaXMucmVxdWVzdHMpKSB7XG4gICAgICB2YXIgaGFuZGxlZCA9IGZhbHNlO1xuICAgICAgdmFyIGRlZmVycmVkID0gbmV3IERlZmVycmVkKCk7XG4gICAgICB0aGlzLnJlcXVlc3RzW3VyaV0gPSBkZWZlcnJlZDtcblxuICAgICAgLy8gbG9vcCBiYWNrd2FyZHMgdGhyb3VnaCByZXNvbHZlcnMgdW50aWwgb25lIFwiYWNjZXB0c1wiIHRoZSByZXF1ZXN0XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy5yZXNvbHZlcnMubGVuZ3RoIC0gMSwgcjsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgciA9IHRoaXMucmVzb2x2ZXJzW2ldO1xuICAgICAgICBpZiAoci5hY2NlcHQodXJpLCBkZWZlcnJlZCkpIHtcbiAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWhhbmRsZWQpIHtcbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KG5ldyBFcnJvcignbm8gcmVzb2x2ZXIgZm91bmQgZm9yICcgKyB1cmkpKTtcbiAgICAgIH1cblxuICAgICAgcHJvbWlzZSA9IGRlZmVycmVkLnByb21pc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb21pc2UgPSB0aGlzLnJlcXVlc3RzW3VyaV0ucHJvbWlzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBGaWxlTG9hZGVyO1xuIl19
2395 2634 },{"es6-promise":60}],14:[function(require,module,exports){
2396 2635 /**
2397 2636 * @license
... ... @@ -3221,7 +3460,7 @@ var substr = &#39;ab&#39;.substr(-1) === &#39;b&#39;
3221 3460 ;
3222 3461  
3223 3462 }).call(this,require('_process'))
3224   -
  3463 +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYXRoLWJyb3dzZXJpZnkvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHJlc29sdmVzIC4gYW5kIC4uIGVsZW1lbnRzIGluIGEgcGF0aCBhcnJheSB3aXRoIGRpcmVjdG9yeSBuYW1lcyB0aGVyZVxuLy8gbXVzdCBiZSBubyBzbGFzaGVzLCBlbXB0eSBlbGVtZW50cywgb3IgZGV2aWNlIG5hbWVzIChjOlxcKSBpbiB0aGUgYXJyYXlcbi8vIChzbyBhbHNvIG5vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgLSBpdCBkb2VzIG5vdCBkaXN0aW5ndWlzaFxuLy8gcmVsYXRpdmUgYW5kIGFic29sdXRlIHBhdGhzKVxuZnVuY3Rpb24gbm9ybWFsaXplQXJyYXkocGFydHMsIGFsbG93QWJvdmVSb290KSB7XG4gIC8vIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gIHZhciB1cCA9IDA7XG4gIGZvciAodmFyIGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBsYXN0ID0gcGFydHNbaV07XG4gICAgaWYgKGxhc3QgPT09ICcuJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAobGFzdCA9PT0gJy4uJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKGFsbG93QWJvdmVSb290KSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBwYXJ0cy51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuLy8gU3BsaXQgYSBmaWxlbmFtZSBpbnRvIFtyb290LCBkaXIsIGJhc2VuYW1lLCBleHRdLCB1bml4IHZlcnNpb25cbi8vICdyb290JyBpcyBqdXN0IGEgc2xhc2gsIG9yIG5vdGhpbmcuXG52YXIgc3BsaXRQYXRoUmUgPVxuICAgIC9eKFxcLz98KShbXFxzXFxTXSo/KSgoPzpcXC57MSwyfXxbXlxcL10rP3wpKFxcLlteLlxcL10qfCkpKD86W1xcL10qKSQvO1xudmFyIHNwbGl0UGF0aCA9IGZ1bmN0aW9uKGZpbGVuYW1lKSB7XG4gIHJldHVybiBzcGxpdFBhdGhSZS5leGVjKGZpbGVuYW1lKS5zbGljZSgxKTtcbn07XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVzb2x2ZWRQYXRoID0gJycsXG4gICAgICByZXNvbHZlZEFic29sdXRlID0gZmFsc2U7XG5cbiAgZm9yICh2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGggLSAxOyBpID49IC0xICYmICFyZXNvbHZlZEFic29sdXRlOyBpLS0pIHtcbiAgICB2YXIgcGF0aCA9IChpID49IDApID8gYXJndW1lbnRzW2ldIDogcHJvY2Vzcy5jd2QoKTtcblxuICAgIC8vIFNraXAgZW1wdHkgYW5kIGludmFsaWQgZW50cmllc1xuICAgIGlmICh0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyB0byBwYXRoLnJlc29sdmUgbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfSBlbHNlIGlmICghcGF0aCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcmVzb2x2ZWRQYXRoID0gcGF0aCArICcvJyArIHJlc29sdmVkUGF0aDtcbiAgICByZXNvbHZlZEFic29sdXRlID0gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZUFycmF5KGZpbHRlcihyZXNvbHZlZFBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhcmVzb2x2ZWRBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIHJldHVybiAoKHJlc29sdmVkQWJzb2x1dGUgPyAnLycgOiAnJykgKyByZXNvbHZlZFBhdGgpIHx8ICcuJztcbn07XG5cbi8vIHBhdGgubm9ybWFsaXplKHBhdGgpXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIGlzQWJzb2x1dGUgPSBleHBvcnRzLmlzQWJzb2x1dGUocGF0aCksXG4gICAgICB0cmFpbGluZ1NsYXNoID0gc3Vic3RyKHBhdGgsIC0xKSA9PT0gJy8nO1xuXG4gIC8vIE5vcm1hbGl6ZSB0aGUgcGF0aFxuICBwYXRoID0gbm9ybWFsaXplQXJyYXkoZmlsdGVyKHBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhaXNBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIGlmICghcGF0aCAmJiAhaXNBYnNvbHV0ZSkge1xuICAgIHBhdGggPSAnLic7XG4gIH1cbiAgaWYgKHBhdGggJiYgdHJhaWxpbmdTbGFzaCkge1xuICAgIHBhdGggKz0gJy8nO1xuICB9XG5cbiAgcmV0dXJuIChpc0Fic29sdXRlID8gJy8nIDogJycpICsgcGF0aDtcbn07XG5cbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMuaXNBYnNvbHV0ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuIHBhdGguY2hhckF0KDApID09PSAnLyc7XG59O1xuXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLmpvaW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhdGhzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgcmV0dXJuIGV4cG9ydHMubm9ybWFsaXplKGZpbHRlcihwYXRocywgZnVuY3Rpb24ocCwgaW5kZXgpIHtcbiAgICBpZiAodHlwZW9mIHAgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgdG8gcGF0aC5qb2luIG11c3QgYmUgc3RyaW5ncycpO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbiAgfSkuam9pbignLycpKTtcbn07XG5cblxuLy8gcGF0aC5yZWxhdGl2ZShmcm9tLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVsYXRpdmUgPSBmdW5jdGlvbihmcm9tLCB0bykge1xuICBmcm9tID0gZXhwb3J0cy5yZXNvbHZlKGZyb20pLnN1YnN0cigxKTtcbiAgdG8gPSBleHBvcnRzLnJlc29sdmUodG8pLnN1YnN0cigxKTtcblxuICBmdW5jdGlvbiB0cmltKGFycikge1xuICAgIHZhciBzdGFydCA9IDA7XG4gICAgZm9yICg7IHN0YXJ0IDwgYXJyLmxlbmd0aDsgc3RhcnQrKykge1xuICAgICAgaWYgKGFycltzdGFydF0gIT09ICcnKSBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZW5kID0gYXJyLmxlbmd0aCAtIDE7XG4gICAgZm9yICg7IGVuZCA+PSAwOyBlbmQtLSkge1xuICAgICAgaWYgKGFycltlbmRdICE9PSAnJykgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ID4gZW5kKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGFyci5zbGljZShzdGFydCwgZW5kIC0gc3RhcnQgKyAxKTtcbiAgfVxuXG4gIHZhciBmcm9tUGFydHMgPSB0cmltKGZyb20uc3BsaXQoJy8nKSk7XG4gIHZhciB0b1BhcnRzID0gdHJpbSh0by5zcGxpdCgnLycpKTtcblxuICB2YXIgbGVuZ3RoID0gTWF0aC5taW4oZnJvbVBhcnRzLmxlbmd0aCwgdG9QYXJ0cy5sZW5ndGgpO1xuICB2YXIgc2FtZVBhcnRzTGVuZ3RoID0gbGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGZyb21QYXJ0c1tpXSAhPT0gdG9QYXJ0c1tpXSkge1xuICAgICAgc2FtZVBhcnRzTGVuZ3RoID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBvdXRwdXRQYXJ0cyA9IFtdO1xuICBmb3IgKHZhciBpID0gc2FtZVBhcnRzTGVuZ3RoOyBpIDwgZnJvbVBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0UGFydHMucHVzaCgnLi4nKTtcbiAgfVxuXG4gIG91dHB1dFBhcnRzID0gb3V0cHV0UGFydHMuY29uY2F0KHRvUGFydHMuc2xpY2Uoc2FtZVBhcnRzTGVuZ3RoKSk7XG5cbiAgcmV0dXJuIG91dHB1dFBhcnRzLmpvaW4oJy8nKTtcbn07XG5cbmV4cG9ydHMuc2VwID0gJy8nO1xuZXhwb3J0cy5kZWxpbWl0ZXIgPSAnOic7XG5cbmV4cG9ydHMuZGlybmFtZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKSxcbiAgICAgIHJvb3QgPSByZXN1bHRbMF0sXG4gICAgICBkaXIgPSByZXN1bHRbMV07XG5cbiAgaWYgKCFyb290ICYmICFkaXIpIHtcbiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXJcbiAgICByZXR1cm4gJy4nO1xuICB9XG5cbiAgaWYgKGRpcikge1xuICAgIC8vIEl0IGhhcyBhIGRpcm5hbWUsIHN0cmlwIHRyYWlsaW5nIHNsYXNoXG4gICAgZGlyID0gZGlyLnN1YnN0cigwLCBkaXIubGVuZ3RoIC0gMSk7XG4gIH1cblxuICByZXR1cm4gcm9vdCArIGRpcjtcbn07XG5cblxuZXhwb3J0cy5iYXNlbmFtZSA9IGZ1bmN0aW9uKHBhdGgsIGV4dCkge1xuICB2YXIgZiA9IHNwbGl0UGF0aChwYXRoKVsyXTtcbiAgLy8gVE9ETzogbWFrZSB0aGlzIGNvbXBhcmlzb24gY2FzZS1pbnNlbnNpdGl2ZSBvbiB3aW5kb3dzP1xuICBpZiAoZXh0ICYmIGYuc3Vic3RyKC0xICogZXh0Lmxlbmd0aCkgPT09IGV4dCkge1xuICAgIGYgPSBmLnN1YnN0cigwLCBmLmxlbmd0aCAtIGV4dC5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBmO1xufTtcblxuXG5leHBvcnRzLmV4dG5hbWUgPSBmdW5jdGlvbihwYXRoKSB7XG4gIHJldHVybiBzcGxpdFBhdGgocGF0aClbM107XG59O1xuXG5mdW5jdGlvbiBmaWx0ZXIgKHhzLCBmKSB7XG4gICAgaWYgKHhzLmZpbHRlcikgcmV0dXJuIHhzLmZpbHRlcihmKTtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZih4c1tpXSwgaSwgeHMpKSByZXMucHVzaCh4c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5cbi8vIFN0cmluZy5wcm90b3R5cGUuc3Vic3RyIC0gbmVnYXRpdmUgaW5kZXggZG9uJ3Qgd29yayBpbiBJRThcbnZhciBzdWJzdHIgPSAnYWInLnN1YnN0cigtMSkgPT09ICdiJ1xuICAgID8gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbikgeyByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKSB9XG4gICAgOiBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuKSB7XG4gICAgICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gc3RyLmxlbmd0aCArIHN0YXJ0O1xuICAgICAgICByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKTtcbiAgICB9XG47XG4iXX0=
3225 3464 },{"_process":21}],21:[function(require,module,exports){
3226 3465 // shim for using process in browser
3227 3466  
... ... @@ -3793,7 +4032,7 @@ process.umask = function() { return 0; };
3793 4032 }(this));
3794 4033  
3795 4034 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3796   -
  4035 +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdW55Y29kZS9wdW55Y29kZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qISBodHRwOi8vbXRocy5iZS9wdW55Y29kZSB2MS4yLjQgYnkgQG1hdGhpYXMgKi9cbjsoZnVuY3Rpb24ocm9vdCkge1xuXG5cdC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZXMgKi9cblx0dmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cztcblx0dmFyIGZyZWVNb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJlxuXHRcdG1vZHVsZS5leHBvcnRzID09IGZyZWVFeHBvcnRzICYmIG1vZHVsZTtcblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGBwdW55Y29kZWAgb2JqZWN0LlxuXHQgKiBAbmFtZSBwdW55Y29kZVxuXHQgKiBAdHlwZSBPYmplY3Rcblx0ICovXG5cdHZhciBwdW55Y29kZSxcblxuXHQvKiogSGlnaGVzdCBwb3NpdGl2ZSBzaWduZWQgMzItYml0IGZsb2F0IHZhbHVlICovXG5cdG1heEludCA9IDIxNDc0ODM2NDcsIC8vIGFrYS4gMHg3RkZGRkZGRiBvciAyXjMxLTFcblxuXHQvKiogQm9vdHN0cmluZyBwYXJhbWV0ZXJzICovXG5cdGJhc2UgPSAzNixcblx0dE1pbiA9IDEsXG5cdHRNYXggPSAyNixcblx0c2tldyA9IDM4LFxuXHRkYW1wID0gNzAwLFxuXHRpbml0aWFsQmlhcyA9IDcyLFxuXHRpbml0aWFsTiA9IDEyOCwgLy8gMHg4MFxuXHRkZWxpbWl0ZXIgPSAnLScsIC8vICdcXHgyRCdcblxuXHQvKiogUmVndWxhciBleHByZXNzaW9ucyAqL1xuXHRyZWdleFB1bnljb2RlID0gL154bi0tLyxcblx0cmVnZXhOb25BU0NJSSA9IC9bXiAtfl0vLCAvLyB1bnByaW50YWJsZSBBU0NJSSBjaGFycyArIG5vbi1BU0NJSSBjaGFyc1xuXHRyZWdleFNlcGFyYXRvcnMgPSAvXFx4MkV8XFx1MzAwMnxcXHVGRjBFfFxcdUZGNjEvZywgLy8gUkZDIDM0OTAgc2VwYXJhdG9yc1xuXG5cdC8qKiBFcnJvciBtZXNzYWdlcyAqL1xuXHRlcnJvcnMgPSB7XG5cdFx0J292ZXJmbG93JzogJ092ZXJmbG93OiBpbnB1dCBuZWVkcyB3aWRlciBpbnRlZ2VycyB0byBwcm9jZXNzJyxcblx0XHQnbm90LWJhc2ljJzogJ0lsbGVnYWwgaW5wdXQgPj0gMHg4MCAobm90IGEgYmFzaWMgY29kZSBwb2ludCknLFxuXHRcdCdpbnZhbGlkLWlucHV0JzogJ0ludmFsaWQgaW5wdXQnXG5cdH0sXG5cblx0LyoqIENvbnZlbmllbmNlIHNob3J0Y3V0cyAqL1xuXHRiYXNlTWludXNUTWluID0gYmFzZSAtIHRNaW4sXG5cdGZsb29yID0gTWF0aC5mbG9vcixcblx0c3RyaW5nRnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZSxcblxuXHQvKiogVGVtcG9yYXJ5IHZhcmlhYmxlICovXG5cdGtleTtcblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHQvKipcblx0ICogQSBnZW5lcmljIGVycm9yIHV0aWxpdHkgZnVuY3Rpb24uXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSBlcnJvciB0eXBlLlxuXHQgKiBAcmV0dXJucyB7RXJyb3J9IFRocm93cyBhIGBSYW5nZUVycm9yYCB3aXRoIHRoZSBhcHBsaWNhYmxlIGVycm9yIG1lc3NhZ2UuXG5cdCAqL1xuXHRmdW5jdGlvbiBlcnJvcih0eXBlKSB7XG5cdFx0dGhyb3cgUmFuZ2VFcnJvcihlcnJvcnNbdHlwZV0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEEgZ2VuZXJpYyBgQXJyYXkjbWFwYCB1dGlsaXR5IGZ1bmN0aW9uLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdGhhdCBnZXRzIGNhbGxlZCBmb3IgZXZlcnkgYXJyYXlcblx0ICogaXRlbS5cblx0ICogQHJldHVybnMge0FycmF5fSBBIG5ldyBhcnJheSBvZiB2YWx1ZXMgcmV0dXJuZWQgYnkgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLlxuXHQgKi9cblx0ZnVuY3Rpb24gbWFwKGFycmF5LCBmbikge1xuXHRcdHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cdFx0d2hpbGUgKGxlbmd0aC0tKSB7XG5cdFx0XHRhcnJheVtsZW5ndGhdID0gZm4oYXJyYXlbbGVuZ3RoXSk7XG5cdFx0fVxuXHRcdHJldHVybiBhcnJheTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBIHNpbXBsZSBgQXJyYXkjbWFwYC1saWtlIHdyYXBwZXIgdG8gd29yayB3aXRoIGRvbWFpbiBuYW1lIHN0cmluZ3MuXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gVGhlIGRvbWFpbiBuYW1lLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdGhhdCBnZXRzIGNhbGxlZCBmb3IgZXZlcnlcblx0ICogY2hhcmFjdGVyLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IEEgbmV3IHN0cmluZyBvZiBjaGFyYWN0ZXJzIHJldHVybmVkIGJ5IHRoZSBjYWxsYmFja1xuXHQgKiBmdW5jdGlvbi5cblx0ICovXG5cdGZ1bmN0aW9uIG1hcERvbWFpbihzdHJpbmcsIGZuKSB7XG5cdFx0cmV0dXJuIG1hcChzdHJpbmcuc3BsaXQocmVnZXhTZXBhcmF0b3JzKSwgZm4pLmpvaW4oJy4nKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIG51bWVyaWMgY29kZSBwb2ludHMgb2YgZWFjaCBVbmljb2RlXG5cdCAqIGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nLiBXaGlsZSBKYXZhU2NyaXB0IHVzZXMgVUNTLTIgaW50ZXJuYWxseSxcblx0ICogdGhpcyBmdW5jdGlvbiB3aWxsIGNvbnZlcnQgYSBwYWlyIG9mIHN1cnJvZ2F0ZSBoYWx2ZXMgKGVhY2ggb2Ygd2hpY2hcblx0ICogVUNTLTIgZXhwb3NlcyBhcyBzZXBhcmF0ZSBjaGFyYWN0ZXJzKSBpbnRvIGEgc2luZ2xlIGNvZGUgcG9pbnQsXG5cdCAqIG1hdGNoaW5nIFVURi0xNi5cblx0ICogQHNlZSBgcHVueWNvZGUudWNzMi5lbmNvZGVgXG5cdCAqIEBzZWUgPGh0dHA6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtZW5jb2Rpbmc+XG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZS51Y3MyXG5cdCAqIEBuYW1lIGRlY29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIFRoZSBVbmljb2RlIGlucHV0IHN0cmluZyAoVUNTLTIpLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBuZXcgYXJyYXkgb2YgY29kZSBwb2ludHMuXG5cdCAqL1xuXHRmdW5jdGlvbiB1Y3MyZGVjb2RlKHN0cmluZykge1xuXHRcdHZhciBvdXRwdXQgPSBbXSxcblx0XHQgICAgY291bnRlciA9IDAsXG5cdFx0ICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGgsXG5cdFx0ICAgIHZhbHVlLFxuXHRcdCAgICBleHRyYTtcblx0XHR3aGlsZSAoY291bnRlciA8IGxlbmd0aCkge1xuXHRcdFx0dmFsdWUgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuXHRcdFx0aWYgKHZhbHVlID49IDB4RDgwMCAmJiB2YWx1ZSA8PSAweERCRkYgJiYgY291bnRlciA8IGxlbmd0aCkge1xuXHRcdFx0XHQvLyBoaWdoIHN1cnJvZ2F0ZSwgYW5kIHRoZXJlIGlzIGEgbmV4dCBjaGFyYWN0ZXJcblx0XHRcdFx0ZXh0cmEgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuXHRcdFx0XHRpZiAoKGV4dHJhICYgMHhGQzAwKSA9PSAweERDMDApIHsgLy8gbG93IHN1cnJvZ2F0ZVxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKCgodmFsdWUgJiAweDNGRikgPDwgMTApICsgKGV4dHJhICYgMHgzRkYpICsgMHgxMDAwMCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gdW5tYXRjaGVkIHN1cnJvZ2F0ZTsgb25seSBhcHBlbmQgdGhpcyBjb2RlIHVuaXQsIGluIGNhc2UgdGhlIG5leHRcblx0XHRcdFx0XHQvLyBjb2RlIHVuaXQgaXMgdGhlIGhpZ2ggc3Vycm9nYXRlIG9mIGEgc3Vycm9nYXRlIHBhaXJcblx0XHRcdFx0XHRvdXRwdXQucHVzaCh2YWx1ZSk7XG5cdFx0XHRcdFx0Y291bnRlci0tO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvdXRwdXQucHVzaCh2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIHN0cmluZyBiYXNlZCBvbiBhbiBhcnJheSBvZiBudW1lcmljIGNvZGUgcG9pbnRzLlxuXHQgKiBAc2VlIGBwdW55Y29kZS51Y3MyLmRlY29kZWBcblx0ICogQG1lbWJlck9mIHB1bnljb2RlLnVjczJcblx0ICogQG5hbWUgZW5jb2RlXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGNvZGVQb2ludHMgVGhlIGFycmF5IG9mIG51bWVyaWMgY29kZSBwb2ludHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBuZXcgVW5pY29kZSBzdHJpbmcgKFVDUy0yKS5cblx0ICovXG5cdGZ1bmN0aW9uIHVjczJlbmNvZGUoYXJyYXkpIHtcblx0XHRyZXR1cm4gbWFwKGFycmF5LCBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdFx0aWYgKHZhbHVlID4gMHhGRkZGKSB7XG5cdFx0XHRcdHZhbHVlIC09IDB4MTAwMDA7XG5cdFx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApO1xuXHRcdFx0XHR2YWx1ZSA9IDB4REMwMCB8IHZhbHVlICYgMHgzRkY7XG5cdFx0XHR9XG5cdFx0XHRvdXRwdXQgKz0gc3RyaW5nRnJvbUNoYXJDb2RlKHZhbHVlKTtcblx0XHRcdHJldHVybiBvdXRwdXQ7XG5cdFx0fSkuam9pbignJyk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBiYXNpYyBjb2RlIHBvaW50IGludG8gYSBkaWdpdC9pbnRlZ2VyLlxuXHQgKiBAc2VlIGBkaWdpdFRvQmFzaWMoKWBcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGNvZGVQb2ludCBUaGUgYmFzaWMgbnVtZXJpYyBjb2RlIHBvaW50IHZhbHVlLlxuXHQgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgbnVtZXJpYyB2YWx1ZSBvZiBhIGJhc2ljIGNvZGUgcG9pbnQgKGZvciB1c2UgaW5cblx0ICogcmVwcmVzZW50aW5nIGludGVnZXJzKSBpbiB0aGUgcmFuZ2UgYDBgIHRvIGBiYXNlIC0gMWAsIG9yIGBiYXNlYCBpZlxuXHQgKiB0aGUgY29kZSBwb2ludCBkb2VzIG5vdCByZXByZXNlbnQgYSB2YWx1ZS5cblx0ICovXG5cdGZ1bmN0aW9uIGJhc2ljVG9EaWdpdChjb2RlUG9pbnQpIHtcblx0XHRpZiAoY29kZVBvaW50IC0gNDggPCAxMCkge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDIyO1xuXHRcdH1cblx0XHRpZiAoY29kZVBvaW50IC0gNjUgPCAyNikge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDY1O1xuXHRcdH1cblx0XHRpZiAoY29kZVBvaW50IC0gOTcgPCAyNikge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDk3O1xuXHRcdH1cblx0XHRyZXR1cm4gYmFzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIGRpZ2l0L2ludGVnZXIgaW50byBhIGJhc2ljIGNvZGUgcG9pbnQuXG5cdCAqIEBzZWUgYGJhc2ljVG9EaWdpdCgpYFxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0gZGlnaXQgVGhlIG51bWVyaWMgdmFsdWUgb2YgYSBiYXNpYyBjb2RlIHBvaW50LlxuXHQgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgYmFzaWMgY29kZSBwb2ludCB3aG9zZSB2YWx1ZSAod2hlbiB1c2VkIGZvclxuXHQgKiByZXByZXNlbnRpbmcgaW50ZWdlcnMpIGlzIGBkaWdpdGAsIHdoaWNoIG5lZWRzIHRvIGJlIGluIHRoZSByYW5nZVxuXHQgKiBgMGAgdG8gYGJhc2UgLSAxYC4gSWYgYGZsYWdgIGlzIG5vbi16ZXJvLCB0aGUgdXBwZXJjYXNlIGZvcm0gaXNcblx0ICogdXNlZDsgZWxzZSwgdGhlIGxvd2VyY2FzZSBmb3JtIGlzIHVzZWQuIFRoZSBiZWhhdmlvciBpcyB1bmRlZmluZWRcblx0ICogaWYgYGZsYWdgIGlzIG5vbi16ZXJvIGFuZCBgZGlnaXRgIGhhcyBubyB1cHBlcmNhc2UgZm9ybS5cblx0ICovXG5cdGZ1bmN0aW9uIGRpZ2l0VG9CYXNpYyhkaWdpdCwgZmxhZykge1xuXHRcdC8vICAwLi4yNSBtYXAgdG8gQVNDSUkgYS4ueiBvciBBLi5aXG5cdFx0Ly8gMjYuLjM1IG1hcCB0byBBU0NJSSAwLi45XG5cdFx0cmV0dXJuIGRpZ2l0ICsgMjIgKyA3NSAqIChkaWdpdCA8IDI2KSAtICgoZmxhZyAhPSAwKSA8PCA1KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBCaWFzIGFkYXB0YXRpb24gZnVuY3Rpb24gYXMgcGVyIHNlY3Rpb24gMy40IG9mIFJGQyAzNDkyLlxuXHQgKiBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNDkyI3NlY3Rpb24tMy40XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRmdW5jdGlvbiBhZGFwdChkZWx0YSwgbnVtUG9pbnRzLCBmaXJzdFRpbWUpIHtcblx0XHR2YXIgayA9IDA7XG5cdFx0ZGVsdGEgPSBmaXJzdFRpbWUgPyBmbG9vcihkZWx0YSAvIGRhbXApIDogZGVsdGEgPj4gMTtcblx0XHRkZWx0YSArPSBmbG9vcihkZWx0YSAvIG51bVBvaW50cyk7XG5cdFx0Zm9yICgvKiBubyBpbml0aWFsaXphdGlvbiAqLzsgZGVsdGEgPiBiYXNlTWludXNUTWluICogdE1heCA+PiAxOyBrICs9IGJhc2UpIHtcblx0XHRcdGRlbHRhID0gZmxvb3IoZGVsdGEgLyBiYXNlTWludXNUTWluKTtcblx0XHR9XG5cdFx0cmV0dXJuIGZsb29yKGsgKyAoYmFzZU1pbnVzVE1pbiArIDEpICogZGVsdGEgLyAoZGVsdGEgKyBza2V3KSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBQdW55Y29kZSBzdHJpbmcgb2YgQVNDSUktb25seSBzeW1ib2xzIHRvIGEgc3RyaW5nIG9mIFVuaWNvZGVcblx0ICogc3ltYm9scy5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBUaGUgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIHJlc3VsdGluZyBzdHJpbmcgb2YgVW5pY29kZSBzeW1ib2xzLlxuXHQgKi9cblx0ZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG5cdFx0Ly8gRG9uJ3QgdXNlIFVDUy0yXG5cdFx0dmFyIG91dHB1dCA9IFtdLFxuXHRcdCAgICBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aCxcblx0XHQgICAgb3V0LFxuXHRcdCAgICBpID0gMCxcblx0XHQgICAgbiA9IGluaXRpYWxOLFxuXHRcdCAgICBiaWFzID0gaW5pdGlhbEJpYXMsXG5cdFx0ICAgIGJhc2ljLFxuXHRcdCAgICBqLFxuXHRcdCAgICBpbmRleCxcblx0XHQgICAgb2xkaSxcblx0XHQgICAgdyxcblx0XHQgICAgayxcblx0XHQgICAgZGlnaXQsXG5cdFx0ICAgIHQsXG5cdFx0ICAgIC8qKiBDYWNoZWQgY2FsY3VsYXRpb24gcmVzdWx0cyAqL1xuXHRcdCAgICBiYXNlTWludXNUO1xuXG5cdFx0Ly8gSGFuZGxlIHRoZSBiYXNpYyBjb2RlIHBvaW50czogbGV0IGBiYXNpY2AgYmUgdGhlIG51bWJlciBvZiBpbnB1dCBjb2RlXG5cdFx0Ly8gcG9pbnRzIGJlZm9yZSB0aGUgbGFzdCBkZWxpbWl0ZXIsIG9yIGAwYCBpZiB0aGVyZSBpcyBub25lLCB0aGVuIGNvcHlcblx0XHQvLyB0aGUgZmlyc3QgYmFzaWMgY29kZSBwb2ludHMgdG8gdGhlIG91dHB1dC5cblxuXHRcdGJhc2ljID0gaW5wdXQubGFzdEluZGV4T2YoZGVsaW1pdGVyKTtcblx0XHRpZiAoYmFzaWMgPCAwKSB7XG5cdFx0XHRiYXNpYyA9IDA7XG5cdFx0fVxuXG5cdFx0Zm9yIChqID0gMDsgaiA8IGJhc2ljOyArK2opIHtcblx0XHRcdC8vIGlmIGl0J3Mgbm90IGEgYmFzaWMgY29kZSBwb2ludFxuXHRcdFx0aWYgKGlucHV0LmNoYXJDb2RlQXQoaikgPj0gMHg4MCkge1xuXHRcdFx0XHRlcnJvcignbm90LWJhc2ljJyk7XG5cdFx0XHR9XG5cdFx0XHRvdXRwdXQucHVzaChpbnB1dC5jaGFyQ29kZUF0KGopKTtcblx0XHR9XG5cblx0XHQvLyBNYWluIGRlY29kaW5nIGxvb3A6IHN0YXJ0IGp1c3QgYWZ0ZXIgdGhlIGxhc3QgZGVsaW1pdGVyIGlmIGFueSBiYXNpYyBjb2RlXG5cdFx0Ly8gcG9pbnRzIHdlcmUgY29waWVkOyBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG90aGVyd2lzZS5cblxuXHRcdGZvciAoaW5kZXggPSBiYXNpYyA+IDAgPyBiYXNpYyArIDEgOiAwOyBpbmRleCA8IGlucHV0TGVuZ3RoOyAvKiBubyBmaW5hbCBleHByZXNzaW9uICovKSB7XG5cblx0XHRcdC8vIGBpbmRleGAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGNoYXJhY3RlciB0byBiZSBjb25zdW1lZC5cblx0XHRcdC8vIERlY29kZSBhIGdlbmVyYWxpemVkIHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyIGludG8gYGRlbHRhYCxcblx0XHRcdC8vIHdoaWNoIGdldHMgYWRkZWQgdG8gYGlgLiBUaGUgb3ZlcmZsb3cgY2hlY2tpbmcgaXMgZWFzaWVyXG5cdFx0XHQvLyBpZiB3ZSBpbmNyZWFzZSBgaWAgYXMgd2UgZ28sIHRoZW4gc3VidHJhY3Qgb2ZmIGl0cyBzdGFydGluZ1xuXHRcdFx0Ly8gdmFsdWUgYXQgdGhlIGVuZCB0byBvYnRhaW4gYGRlbHRhYC5cblx0XHRcdGZvciAob2xkaSA9IGksIHcgPSAxLCBrID0gYmFzZTsgLyogbm8gY29uZGl0aW9uICovOyBrICs9IGJhc2UpIHtcblxuXHRcdFx0XHRpZiAoaW5kZXggPj0gaW5wdXRMZW5ndGgpIHtcblx0XHRcdFx0XHRlcnJvcignaW52YWxpZC1pbnB1dCcpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGlnaXQgPSBiYXNpY1RvRGlnaXQoaW5wdXQuY2hhckNvZGVBdChpbmRleCsrKSk7XG5cblx0XHRcdFx0aWYgKGRpZ2l0ID49IGJhc2UgfHwgZGlnaXQgPiBmbG9vcigobWF4SW50IC0gaSkgLyB3KSkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aSArPSBkaWdpdCAqIHc7XG5cdFx0XHRcdHQgPSBrIDw9IGJpYXMgPyB0TWluIDogKGsgPj0gYmlhcyArIHRNYXggPyB0TWF4IDogayAtIGJpYXMpO1xuXG5cdFx0XHRcdGlmIChkaWdpdCA8IHQpIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGJhc2VNaW51c1QgPSBiYXNlIC0gdDtcblx0XHRcdFx0aWYgKHcgPiBmbG9vcihtYXhJbnQgLyBiYXNlTWludXNUKSkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dyAqPSBiYXNlTWludXNUO1xuXG5cdFx0XHR9XG5cblx0XHRcdG91dCA9IG91dHB1dC5sZW5ndGggKyAxO1xuXHRcdFx0YmlhcyA9IGFkYXB0KGkgLSBvbGRpLCBvdXQsIG9sZGkgPT0gMCk7XG5cblx0XHRcdC8vIGBpYCB3YXMgc3VwcG9zZWQgdG8gd3JhcCBhcm91bmQgZnJvbSBgb3V0YCB0byBgMGAsXG5cdFx0XHQvLyBpbmNyZW1lbnRpbmcgYG5gIGVhY2ggdGltZSwgc28gd2UnbGwgZml4IHRoYXQgbm93OlxuXHRcdFx0aWYgKGZsb29yKGkgLyBvdXQpID4gbWF4SW50IC0gbikge1xuXHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdH1cblxuXHRcdFx0biArPSBmbG9vcihpIC8gb3V0KTtcblx0XHRcdGkgJT0gb3V0O1xuXG5cdFx0XHQvLyBJbnNlcnQgYG5gIGF0IHBvc2l0aW9uIGBpYCBvZiB0aGUgb3V0cHV0XG5cdFx0XHRvdXRwdXQuc3BsaWNlKGkrKywgMCwgbik7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdWNzMmVuY29kZShvdXRwdXQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgc3RyaW5nIG9mIFVuaWNvZGUgc3ltYm9scyB0byBhIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5XG5cdCAqIHN5bWJvbHMuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIHN0cmluZyBvZiBVbmljb2RlIHN5bWJvbHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSByZXN1bHRpbmcgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scy5cblx0ICovXG5cdGZ1bmN0aW9uIGVuY29kZShpbnB1dCkge1xuXHRcdHZhciBuLFxuXHRcdCAgICBkZWx0YSxcblx0XHQgICAgaGFuZGxlZENQQ291bnQsXG5cdFx0ICAgIGJhc2ljTGVuZ3RoLFxuXHRcdCAgICBiaWFzLFxuXHRcdCAgICBqLFxuXHRcdCAgICBtLFxuXHRcdCAgICBxLFxuXHRcdCAgICBrLFxuXHRcdCAgICB0LFxuXHRcdCAgICBjdXJyZW50VmFsdWUsXG5cdFx0ICAgIG91dHB1dCA9IFtdLFxuXHRcdCAgICAvKiogYGlucHV0TGVuZ3RoYCB3aWxsIGhvbGQgdGhlIG51bWJlciBvZiBjb2RlIHBvaW50cyBpbiBgaW5wdXRgLiAqL1xuXHRcdCAgICBpbnB1dExlbmd0aCxcblx0XHQgICAgLyoqIENhY2hlZCBjYWxjdWxhdGlvbiByZXN1bHRzICovXG5cdFx0ICAgIGhhbmRsZWRDUENvdW50UGx1c09uZSxcblx0XHQgICAgYmFzZU1pbnVzVCxcblx0XHQgICAgcU1pbnVzVDtcblxuXHRcdC8vIENvbnZlcnQgdGhlIGlucHV0IGluIFVDUy0yIHRvIFVuaWNvZGVcblx0XHRpbnB1dCA9IHVjczJkZWNvZGUoaW5wdXQpO1xuXG5cdFx0Ly8gQ2FjaGUgdGhlIGxlbmd0aFxuXHRcdGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSB0aGUgc3RhdGVcblx0XHRuID0gaW5pdGlhbE47XG5cdFx0ZGVsdGEgPSAwO1xuXHRcdGJpYXMgPSBpbml0aWFsQmlhcztcblxuXHRcdC8vIEhhbmRsZSB0aGUgYmFzaWMgY29kZSBwb2ludHNcblx0XHRmb3IgKGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRbal07XG5cdFx0XHRpZiAoY3VycmVudFZhbHVlIDwgMHg4MCkge1xuXHRcdFx0XHRvdXRwdXQucHVzaChzdHJpbmdGcm9tQ2hhckNvZGUoY3VycmVudFZhbHVlKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aGFuZGxlZENQQ291bnQgPSBiYXNpY0xlbmd0aCA9IG91dHB1dC5sZW5ndGg7XG5cblx0XHQvLyBgaGFuZGxlZENQQ291bnRgIGlzIHRoZSBudW1iZXIgb2YgY29kZSBwb2ludHMgdGhhdCBoYXZlIGJlZW4gaGFuZGxlZDtcblx0XHQvLyBgYmFzaWNMZW5ndGhgIGlzIHRoZSBudW1iZXIgb2YgYmFzaWMgY29kZSBwb2ludHMuXG5cblx0XHQvLyBGaW5pc2ggdGhlIGJhc2ljIHN0cmluZyAtIGlmIGl0IGlzIG5vdCBlbXB0eSAtIHdpdGggYSBkZWxpbWl0ZXJcblx0XHRpZiAoYmFzaWNMZW5ndGgpIHtcblx0XHRcdG91dHB1dC5wdXNoKGRlbGltaXRlcik7XG5cdFx0fVxuXG5cdFx0Ly8gTWFpbiBlbmNvZGluZyBsb29wOlxuXHRcdHdoaWxlIChoYW5kbGVkQ1BDb3VudCA8IGlucHV0TGVuZ3RoKSB7XG5cblx0XHRcdC8vIEFsbCBub24tYmFzaWMgY29kZSBwb2ludHMgPCBuIGhhdmUgYmVlbiBoYW5kbGVkIGFscmVhZHkuIEZpbmQgdGhlIG5leHRcblx0XHRcdC8vIGxhcmdlciBvbmU6XG5cdFx0XHRmb3IgKG0gPSBtYXhJbnQsIGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0XHRjdXJyZW50VmFsdWUgPSBpbnB1dFtqXTtcblx0XHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA+PSBuICYmIGN1cnJlbnRWYWx1ZSA8IG0pIHtcblx0XHRcdFx0XHRtID0gY3VycmVudFZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEluY3JlYXNlIGBkZWx0YWAgZW5vdWdoIHRvIGFkdmFuY2UgdGhlIGRlY29kZXIncyA8bixpPiBzdGF0ZSB0byA8bSwwPixcblx0XHRcdC8vIGJ1dCBndWFyZCBhZ2FpbnN0IG92ZXJmbG93XG5cdFx0XHRoYW5kbGVkQ1BDb3VudFBsdXNPbmUgPSBoYW5kbGVkQ1BDb3VudCArIDE7XG5cdFx0XHRpZiAobSAtIG4gPiBmbG9vcigobWF4SW50IC0gZGVsdGEpIC8gaGFuZGxlZENQQ291bnRQbHVzT25lKSkge1xuXHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVsdGEgKz0gKG0gLSBuKSAqIGhhbmRsZWRDUENvdW50UGx1c09uZTtcblx0XHRcdG4gPSBtO1xuXG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0XHRjdXJyZW50VmFsdWUgPSBpbnB1dFtqXTtcblxuXHRcdFx0XHRpZiAoY3VycmVudFZhbHVlIDwgbiAmJiArK2RlbHRhID4gbWF4SW50KSB7XG5cdFx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoY3VycmVudFZhbHVlID09IG4pIHtcblx0XHRcdFx0XHQvLyBSZXByZXNlbnQgZGVsdGEgYXMgYSBnZW5lcmFsaXplZCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlclxuXHRcdFx0XHRcdGZvciAocSA9IGRlbHRhLCBrID0gYmFzZTsgLyogbm8gY29uZGl0aW9uICovOyBrICs9IGJhc2UpIHtcblx0XHRcdFx0XHRcdHQgPSBrIDw9IGJpYXMgPyB0TWluIDogKGsgPj0gYmlhcyArIHRNYXggPyB0TWF4IDogayAtIGJpYXMpO1xuXHRcdFx0XHRcdFx0aWYgKHEgPCB0KSB7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0cU1pbnVzVCA9IHEgLSB0O1xuXHRcdFx0XHRcdFx0YmFzZU1pbnVzVCA9IGJhc2UgLSB0O1xuXHRcdFx0XHRcdFx0b3V0cHV0LnB1c2goXG5cdFx0XHRcdFx0XHRcdHN0cmluZ0Zyb21DaGFyQ29kZShkaWdpdFRvQmFzaWModCArIHFNaW51c1QgJSBiYXNlTWludXNULCAwKSlcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRxID0gZmxvb3IocU1pbnVzVCAvIGJhc2VNaW51c1QpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKHN0cmluZ0Zyb21DaGFyQ29kZShkaWdpdFRvQmFzaWMocSwgMCkpKTtcblx0XHRcdFx0XHRiaWFzID0gYWRhcHQoZGVsdGEsIGhhbmRsZWRDUENvdW50UGx1c09uZSwgaGFuZGxlZENQQ291bnQgPT0gYmFzaWNMZW5ndGgpO1xuXHRcdFx0XHRcdGRlbHRhID0gMDtcblx0XHRcdFx0XHQrK2hhbmRsZWRDUENvdW50O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdCsrZGVsdGE7XG5cdFx0XHQrK247XG5cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dC5qb2luKCcnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIFB1bnljb2RlIHN0cmluZyByZXByZXNlbnRpbmcgYSBkb21haW4gbmFtZSB0byBVbmljb2RlLiBPbmx5IHRoZVxuXHQgKiBQdW55Y29kZWQgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHdpbGwgYmUgY29udmVydGVkLCBpLmUuIGl0IGRvZXNuJ3Rcblx0ICogbWF0dGVyIGlmIHlvdSBjYWxsIGl0IG9uIGEgc3RyaW5nIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBjb252ZXJ0ZWQgdG9cblx0ICogVW5pY29kZS5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gVGhlIFB1bnljb2RlIGRvbWFpbiBuYW1lIHRvIGNvbnZlcnQgdG8gVW5pY29kZS5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIFVuaWNvZGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIFB1bnljb2RlXG5cdCAqIHN0cmluZy5cblx0ICovXG5cdGZ1bmN0aW9uIHRvVW5pY29kZShkb21haW4pIHtcblx0XHRyZXR1cm4gbWFwRG9tYWluKGRvbWFpbiwgZnVuY3Rpb24oc3RyaW5nKSB7XG5cdFx0XHRyZXR1cm4gcmVnZXhQdW55Y29kZS50ZXN0KHN0cmluZylcblx0XHRcdFx0PyBkZWNvZGUoc3RyaW5nLnNsaWNlKDQpLnRvTG93ZXJDYXNlKCkpXG5cdFx0XHRcdDogc3RyaW5nO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgVW5pY29kZSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgZG9tYWluIG5hbWUgdG8gUHVueWNvZGUuIE9ubHkgdGhlXG5cdCAqIG5vbi1BU0NJSSBwYXJ0cyBvZiB0aGUgZG9tYWluIG5hbWUgd2lsbCBiZSBjb252ZXJ0ZWQsIGkuZS4gaXQgZG9lc24ndFxuXHQgKiBtYXR0ZXIgaWYgeW91IGNhbGwgaXQgd2l0aCBhIGRvbWFpbiB0aGF0J3MgYWxyZWFkeSBpbiBBU0NJSS5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gVGhlIGRvbWFpbiBuYW1lIHRvIGNvbnZlcnQsIGFzIGEgVW5pY29kZSBzdHJpbmcuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBQdW55Y29kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gZG9tYWluIG5hbWUuXG5cdCAqL1xuXHRmdW5jdGlvbiB0b0FTQ0lJKGRvbWFpbikge1xuXHRcdHJldHVybiBtYXBEb21haW4oZG9tYWluLCBmdW5jdGlvbihzdHJpbmcpIHtcblx0XHRcdHJldHVybiByZWdleE5vbkFTQ0lJLnRlc3Qoc3RyaW5nKVxuXHRcdFx0XHQ/ICd4bi0tJyArIGVuY29kZShzdHJpbmcpXG5cdFx0XHRcdDogc3RyaW5nO1xuXHRcdH0pO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0LyoqIERlZmluZSB0aGUgcHVibGljIEFQSSAqL1xuXHRwdW55Y29kZSA9IHtcblx0XHQvKipcblx0XHQgKiBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgUHVueWNvZGUuanMgdmVyc2lvbiBudW1iZXIuXG5cdFx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdFx0ICogQHR5cGUgU3RyaW5nXG5cdFx0ICovXG5cdFx0J3ZlcnNpb24nOiAnMS4yLjQnLFxuXHRcdC8qKlxuXHRcdCAqIEFuIG9iamVjdCBvZiBtZXRob2RzIHRvIGNvbnZlcnQgZnJvbSBKYXZhU2NyaXB0J3MgaW50ZXJuYWwgY2hhcmFjdGVyXG5cdFx0ICogcmVwcmVzZW50YXRpb24gKFVDUy0yKSB0byBVbmljb2RlIGNvZGUgcG9pbnRzLCBhbmQgYmFjay5cblx0XHQgKiBAc2VlIDxodHRwOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LWVuY29kaW5nPlxuXHRcdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHRcdCAqIEB0eXBlIE9iamVjdFxuXHRcdCAqL1xuXHRcdCd1Y3MyJzoge1xuXHRcdFx0J2RlY29kZSc6IHVjczJkZWNvZGUsXG5cdFx0XHQnZW5jb2RlJzogdWNzMmVuY29kZVxuXHRcdH0sXG5cdFx0J2RlY29kZSc6IGRlY29kZSxcblx0XHQnZW5jb2RlJzogZW5jb2RlLFxuXHRcdCd0b0FTQ0lJJzogdG9BU0NJSSxcblx0XHQndG9Vbmljb2RlJzogdG9Vbmljb2RlXG5cdH07XG5cblx0LyoqIEV4cG9zZSBgcHVueWNvZGVgICovXG5cdC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIHNwZWNpZmljIGNvbmRpdGlvbiBwYXR0ZXJuc1xuXHQvLyBsaWtlIHRoZSBmb2xsb3dpbmc6XG5cdGlmIChcblx0XHR0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJlxuXHRcdGRlZmluZS5hbWRcblx0KSB7XG5cdFx0ZGVmaW5lKCdwdW55Y29kZScsIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHB1bnljb2RlO1xuXHRcdH0pO1xuXHR9IGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmICFmcmVlRXhwb3J0cy5ub2RlVHlwZSkge1xuXHRcdGlmIChmcmVlTW9kdWxlKSB7IC8vIGluIE5vZGUuanMgb3IgUmluZ29KUyB2MC44LjArXG5cdFx0XHRmcmVlTW9kdWxlLmV4cG9ydHMgPSBwdW55Y29kZTtcblx0XHR9IGVsc2UgeyAvLyBpbiBOYXJ3aGFsIG9yIFJpbmdvSlMgdjAuNy4wLVxuXHRcdFx0Zm9yIChrZXkgaW4gcHVueWNvZGUpIHtcblx0XHRcdFx0cHVueWNvZGUuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAoZnJlZUV4cG9ydHNba2V5XSA9IHB1bnljb2RlW2tleV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIHsgLy8gaW4gUmhpbm8gb3IgYSB3ZWIgYnJvd3NlclxuXHRcdHJvb3QucHVueWNvZGUgPSBwdW55Y29kZTtcblx0fVxuXG59KHRoaXMpKTtcbiJdfQ==
3797 4036 },{}],23:[function(require,module,exports){
3798 4037 // Copyright Joyent, Inc. and other Node contributors.
3799 4038 //
... ... @@ -5279,7 +5518,7 @@ function hasOwnProperty(obj, prop) {
5279 5518 }
5280 5519  
5281 5520 }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
5282   -
  5521 +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgZm9ybWF0UmVnRXhwID0gLyVbc2RqJV0vZztcbmV4cG9ydHMuZm9ybWF0ID0gZnVuY3Rpb24oZikge1xuICBpZiAoIWlzU3RyaW5nKGYpKSB7XG4gICAgdmFyIG9iamVjdHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgb2JqZWN0cy5wdXNoKGluc3BlY3QoYXJndW1lbnRzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHZhciBpID0gMTtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciBsZW4gPSBhcmdzLmxlbmd0aDtcbiAgdmFyIHN0ciA9IFN0cmluZyhmKS5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24oeCkge1xuICAgIGlmICh4ID09PSAnJSUnKSByZXR1cm4gJyUnO1xuICAgIGlmIChpID49IGxlbikgcmV0dXJuIHg7XG4gICAgc3dpdGNoICh4KSB7XG4gICAgICBjYXNlICclcyc6IHJldHVybiBTdHJpbmcoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVkJzogcmV0dXJuIE51bWJlcihhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWonOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmdzW2krK10pO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9KTtcbiAgZm9yICh2YXIgeCA9IGFyZ3NbaV07IGkgPCBsZW47IHggPSBhcmdzWysraV0pIHtcbiAgICBpZiAoaXNOdWxsKHgpIHx8ICFpc09iamVjdCh4KSkge1xuICAgICAgc3RyICs9ICcgJyArIHg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnICcgKyBpbnNwZWN0KHgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuXG4vLyBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuLy8gUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbi8vIElmIC0tbm8tZGVwcmVjYXRpb24gaXMgc2V0LCB0aGVuIGl0IGlzIGEgbm8tb3AuXG5leHBvcnRzLmRlcHJlY2F0ZSA9IGZ1bmN0aW9uKGZuLCBtc2cpIHtcbiAgLy8gQWxsb3cgZm9yIGRlcHJlY2F0aW5nIHRoaW5ncyBpbiB0aGUgcHJvY2VzcyBvZiBzdGFydGluZyB1cC5cbiAgaWYgKGlzVW5kZWZpbmVkKGdsb2JhbC5wcm9jZXNzKSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmRlcHJlY2F0ZShmbiwgbXNnKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cblxuICBpZiAocHJvY2Vzcy5ub0RlcHJlY2F0aW9uID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAocHJvY2Vzcy50aHJvd0RlcHJlY2F0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgfSBlbHNlIGlmIChwcm9jZXNzLnRyYWNlRGVwcmVjYXRpb24pIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn07XG5cblxudmFyIGRlYnVncyA9IHt9O1xudmFyIGRlYnVnRW52aXJvbjtcbmV4cG9ydHMuZGVidWdsb2cgPSBmdW5jdGlvbihzZXQpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKGRlYnVnRW52aXJvbikpXG4gICAgZGVidWdFbnZpcm9uID0gcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyB8fCAnJztcbiAgc2V0ID0gc2V0LnRvVXBwZXJDYXNlKCk7XG4gIGlmICghZGVidWdzW3NldF0pIHtcbiAgICBpZiAobmV3IFJlZ0V4cCgnXFxcXGInICsgc2V0ICsgJ1xcXFxiJywgJ2knKS50ZXN0KGRlYnVnRW52aXJvbikpIHtcbiAgICAgIHZhciBwaWQgPSBwcm9jZXNzLnBpZDtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBtc2cgPSBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCclcyAlZDogJXMnLCBzZXQsIHBpZCwgbXNnKTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7fTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRlYnVnc1tzZXRdO1xufTtcblxuXG4vKipcbiAqIEVjaG9zIHRoZSB2YWx1ZSBvZiBhIHZhbHVlLiBUcnlzIHRvIHByaW50IHRoZSB2YWx1ZSBvdXRcbiAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBwcmludCBvdXQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuICovXG4vKiBsZWdhY3k6IG9iaiwgc2hvd0hpZGRlbiwgZGVwdGgsIGNvbG9ycyovXG5mdW5jdGlvbiBpbnNwZWN0KG9iaiwgb3B0cykge1xuICAvLyBkZWZhdWx0IG9wdGlvbnNcbiAgdmFyIGN0eCA9IHtcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuICB9O1xuICAvLyBsZWdhY3kuLi5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG4gICAgLy8gbGVnYWN5Li4uXG4gICAgY3R4LnNob3dIaWRkZW4gPSBvcHRzO1xuICB9IGVsc2UgaWYgKG9wdHMpIHtcbiAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG4gICAgZXhwb3J0cy5fZXh0ZW5kKGN0eCwgb3B0cyk7XG4gIH1cbiAgLy8gc2V0IGRlZmF1bHQgb3B0aW9uc1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LnNob3dIaWRkZW4pKSBjdHguc2hvd0hpZGRlbiA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmRlcHRoKSkgY3R4LmRlcHRoID0gMjtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jb2xvcnMpKSBjdHguY29sb3JzID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY3VzdG9tSW5zcGVjdCkpIGN0eC5jdXN0b21JbnNwZWN0ID0gdHJ1ZTtcbiAgaWYgKGN0eC5jb2xvcnMpIGN0eC5zdHlsaXplID0gc3R5bGl6ZVdpdGhDb2xvcjtcbiAgcmV0dXJuIGZvcm1hdFZhbHVlKGN0eCwgb2JqLCBjdHguZGVwdGgpO1xufVxuZXhwb3J0cy5pbnNwZWN0ID0gaW5zcGVjdDtcblxuXG4vLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FOU0lfZXNjYXBlX2NvZGUjZ3JhcGhpY3Ncbmluc3BlY3QuY29sb3JzID0ge1xuICAnYm9sZCcgOiBbMSwgMjJdLFxuICAnaXRhbGljJyA6IFszLCAyM10sXG4gICd1bmRlcmxpbmUnIDogWzQsIDI0XSxcbiAgJ2ludmVyc2UnIDogWzcsIDI3XSxcbiAgJ3doaXRlJyA6IFszNywgMzldLFxuICAnZ3JleScgOiBbOTAsIDM5XSxcbiAgJ2JsYWNrJyA6IFszMCwgMzldLFxuICAnYmx1ZScgOiBbMzQsIDM5XSxcbiAgJ2N5YW4nIDogWzM2LCAzOV0sXG4gICdncmVlbicgOiBbMzIsIDM5XSxcbiAgJ21hZ2VudGEnIDogWzM1LCAzOV0sXG4gICdyZWQnIDogWzMxLCAzOV0sXG4gICd5ZWxsb3cnIDogWzMzLCAzOV1cbn07XG5cbi8vIERvbid0IHVzZSAnYmx1ZScgbm90IHZpc2libGUgb24gY21kLmV4ZVxuaW5zcGVjdC5zdHlsZXMgPSB7XG4gICdzcGVjaWFsJzogJ2N5YW4nLFxuICAnbnVtYmVyJzogJ3llbGxvdycsXG4gICdib29sZWFuJzogJ3llbGxvdycsXG4gICd1bmRlZmluZWQnOiAnZ3JleScsXG4gICdudWxsJzogJ2JvbGQnLFxuICAnc3RyaW5nJzogJ2dyZWVuJyxcbiAgJ2RhdGUnOiAnbWFnZW50YScsXG4gIC8vIFwibmFtZVwiOiBpbnRlbnRpb25hbGx5IG5vdCBzdHlsaW5nXG4gICdyZWdleHAnOiAncmVkJ1xufTtcblxuXG5mdW5jdGlvbiBzdHlsaXplV2l0aENvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHZhciBzdHlsZSA9IGluc3BlY3Quc3R5bGVzW3N0eWxlVHlwZV07XG5cbiAgaWYgKHN0eWxlKSB7XG4gICAgcmV0dXJuICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMF0gKyAnbScgKyBzdHIgK1xuICAgICAgICAgICAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzFdICsgJ20nO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzdHlsaXplTm9Db2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICByZXR1cm4gc3RyO1xufVxuXG5cbmZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG4gIHZhciBoYXNoID0ge307XG5cbiAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgIGhhc2hbdmFsXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBoYXNoO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuICAvLyBQcm92aWRlIGEgaG9vayBmb3IgdXNlci1zcGVjaWZpZWQgaW5zcGVjdCBmdW5jdGlvbnMuXG4gIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiZcbiAgICAgIHZhbHVlICYmXG4gICAgICBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGV4cG9ydHMuaW5zcGVjdCAmJlxuICAgICAgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG4gICAgICAhKHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gdmFsdWUpKSB7XG4gICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzLCBjdHgpO1xuICAgIGlmICghaXNTdHJpbmcocmV0KSkge1xuICAgICAgcmV0ID0gZm9ybWF0VmFsdWUoY3R4LCByZXQsIHJlY3Vyc2VUaW1lcyk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvLyBQcmltaXRpdmUgdHlwZXMgY2Fubm90IGhhdmUgcHJvcGVydGllc1xuICB2YXIgcHJpbWl0aXZlID0gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpO1xuICBpZiAocHJpbWl0aXZlKSB7XG4gICAgcmV0dXJuIHByaW1pdGl2ZTtcbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG4gIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG4gIGlmIChjdHguc2hvd0hpZGRlbikge1xuICAgIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG4gIH1cblxuICAvLyBJRSBkb2Vzbid0IG1ha2UgZXJyb3IgZmllbGRzIG5vbi1lbnVtZXJhYmxlXG4gIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9kd3c1MnNidCh2PXZzLjk0KS5hc3B4XG4gIGlmIChpc0Vycm9yKHZhbHVlKVxuICAgICAgJiYgKGtleXMuaW5kZXhPZignbWVzc2FnZScpID49IDAgfHwga2V5cy5pbmRleE9mKCdkZXNjcmlwdGlvbicpID49IDApKSB7XG4gICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICB2YXIgbmFtZSA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSkge1xuICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgndW5kZWZpbmVkJywgJ3VuZGVmaW5lZCcpO1xuICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIHNpbXBsZSA9ICdcXCcnICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpLnJlcGxhY2UoL15cInxcIiQvZywgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKHNpbXBsZSwgJ3N0cmluZycpO1xuICB9XG4gIGlmIChpc051bWJlcih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdudW1iZXInKTtcbiAgaWYgKGlzQm9vbGVhbih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdib29sZWFuJyk7XG4gIC8vIEZvciBzb21lIHJlYXNvbiB0eXBlb2YgbnVsbCBpcyBcIm9iamVjdFwiLCBzbyBzcGVjaWFsIGNhc2UgaGVyZS5cbiAgaWYgKGlzTnVsbCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCdudWxsJywgJ251bGwnKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eSh2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuICBrZXlzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuICBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KSB8fCB7IHZhbHVlOiB2YWx1ZVtrZXldIH07XG4gIGlmIChkZXNjLmdldCkge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoY3R4LnNlZW4uaW5kZXhPZihkZXNjLnZhbHVlKSA8IDApIHtcbiAgICAgIGlmIChpc051bGwocmVjdXJzZVRpbWVzKSkge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCByZWN1cnNlVGltZXMgLSAxKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBzdHIgPSBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBuYW1lID0gSlNPTi5zdHJpbmdpZnkoJycgKyBrZXkpO1xuICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyKDEsIG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJylcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ3N0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuYW1lICsgJzogJyArIHN0cjtcbn1cblxuXG5mdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuICB2YXIgbnVtTGluZXNFc3QgPSAwO1xuICB2YXIgbGVuZ3RoID0gb3V0cHV0LnJlZHVjZShmdW5jdGlvbihwcmV2LCBjdXIpIHtcbiAgICBudW1MaW5lc0VzdCsrO1xuICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgbnVtTGluZXNFc3QrKztcbiAgICByZXR1cm4gcHJldiArIGN1ci5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZywgJycpLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuXG4vLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcbi8vIGJlY2F1c2UgaXQgaXMgZnJhZ2lsZSBhbmQgY2FuIGJlIGVhc2lseSBmYWtlZCB3aXRoIGBPYmplY3QuY3JlYXRlKClgLlxuZnVuY3Rpb24gaXNBcnJheShhcikge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcik7XG59XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGwgPSBpc051bGw7XG5cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkID0gaXNOdWxsT3JVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG59XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5cbmZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCc7XG59XG5leHBvcnRzLmlzU3ltYm9sID0gaXNTeW1ib2w7XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiBpc09iamVjdChyZSkgJiYgb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBpc09iamVjdChkKSAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gaXNPYmplY3QoZSkgJiZcbiAgICAgIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IHJlcXVpcmUoJy4vc3VwcG9ydC9pc0J1ZmZlcicpO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cblxuZnVuY3Rpb24gcGFkKG4pIHtcbiAgcmV0dXJuIG4gPCAxMCA/ICcwJyArIG4udG9TdHJpbmcoMTApIDogbi50b1N0cmluZygxMCk7XG59XG5cblxudmFyIG1vbnRocyA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLFxuICAgICAgICAgICAgICAnT2N0JywgJ05vdicsICdEZWMnXTtcblxuLy8gMjYgRmViIDE2OjE5OjM0XG5mdW5jdGlvbiB0aW1lc3RhbXAoKSB7XG4gIHZhciBkID0gbmV3IERhdGUoKTtcbiAgdmFyIHRpbWUgPSBbcGFkKGQuZ2V0SG91cnMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldE1pbnV0ZXMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldFNlY29uZHMoKSldLmpvaW4oJzonKTtcbiAgcmV0dXJuIFtkLmdldERhdGUoKSwgbW9udGhzW2QuZ2V0TW9udGgoKV0sIHRpbWVdLmpvaW4oJyAnKTtcbn1cblxuXG4vLyBsb2cgaXMganVzdCBhIHRoaW4gd3JhcHBlciB0byBjb25zb2xlLmxvZyB0aGF0IHByZXBlbmRzIGEgdGltZXN0YW1wXG5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICBjb25zb2xlLmxvZygnJXMgLSAlcycsIHRpbWVzdGFtcCgpLCBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpKTtcbn07XG5cblxuLyoqXG4gKiBJbmhlcml0IHRoZSBwcm90b3R5cGUgbWV0aG9kcyBmcm9tIG9uZSBjb25zdHJ1Y3RvciBpbnRvIGFub3RoZXIuXG4gKlxuICogVGhlIEZ1bmN0aW9uLnByb3RvdHlwZS5pbmhlcml0cyBmcm9tIGxhbmcuanMgcmV3cml0dGVuIGFzIGEgc3RhbmRhbG9uZVxuICogZnVuY3Rpb24gKG5vdCBvbiBGdW5jdGlvbi5wcm90b3R5cGUpLiBOT1RFOiBJZiB0aGlzIGZpbGUgaXMgdG8gYmUgbG9hZGVkXG4gKiBkdXJpbmcgYm9vdHN0cmFwcGluZyB0aGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGJlIHJld3JpdHRlbiB1c2luZyBzb21lIG5hdGl2ZVxuICogZnVuY3Rpb25zIGFzIHByb3RvdHlwZSBzZXR1cCB1c2luZyBub3JtYWwgSmF2YVNjcmlwdCBkb2VzIG5vdCB3b3JrIGFzXG4gKiBleHBlY3RlZCBkdXJpbmcgYm9vdHN0cmFwcGluZyAoc2VlIG1pcnJvci5qcyBpbiByMTE0OTAzKS5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHdoaWNoIG5lZWRzIHRvIGluaGVyaXQgdGhlXG4gKiAgICAgcHJvdG90eXBlLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gc3VwZXJDdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHRvIGluaGVyaXQgcHJvdG90eXBlIGZyb20uXG4gKi9cbmV4cG9ydHMuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5leHBvcnRzLl9leHRlbmQgPSBmdW5jdGlvbihvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoYWRkKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gb3JpZ2luO1xufTtcblxuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cbiJdfQ==
5283 5522 },{"./support/isBuffer":27,"_process":21,"inherits":19}],29:[function(require,module,exports){
5284 5523 /*
5285 5524 Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
... ... @@ -5607,6 +5846,10 @@ function hasOwnProperty(obj, prop) {
5607 5846 name += scanIdentifier(last);
5608 5847  
5609 5848 }
  5849 + if(source.charCodeAt(index) === 0x5B /* '[' */ && source.charCodeAt(index + 1) === 0x5D /* ']' */){
  5850 + name += advance();
  5851 + name += advance();
  5852 + }
5610 5853 while (source.charCodeAt(index) === 0x2E /* '.' */ ||
5611 5854 source.charCodeAt(index) === 0x23 /* '#' */ ||
5612 5855 source.charCodeAt(index) === 0x7E /* '~' */) {
... ... @@ -5864,7 +6107,9 @@ function hasOwnProperty(obj, prop) {
5864 6107 // un-fix potentially sloppy declaration
5865 6108 if (isParamTitle(this._title) && !this._tag.type && description && description.charAt(0) === '[') {
5866 6109 this._tag.type = this._extra.name;
5867   - this._tag.name = undefined;
  6110 + if (!this._tag.name) {
  6111 + this._tag.name = undefined;
  6112 + }
5868 6113  
5869 6114 if (!sloppy) {
5870 6115 if (!this.addError('Missing or invalid tag name')) {
... ... @@ -7847,7 +8092,7 @@ module.exports={
7847 8092 "description": "JSDoc parser",
7848 8093 "homepage": "http://github.com/Constellation/doctrine.html",
7849 8094 "main": "lib/doctrine.js",
7850   - "version": "0.6.4",
  8095 + "version": "0.7.0",
7851 8096 "engines": {
7852 8097 "node": ">=0.10.0"
7853 8098 },
... ... @@ -7863,14 +8108,17 @@ module.exports={
7863 8108 ],
7864 8109 "maintainers": [
7865 8110 {
7866   - "name": "Yusuke Suzuki",
7867   - "email": "utatane.tea@gmail.com",
7868   - "url": "http://github.com/Constellation"
  8111 + "name": "constellation",
  8112 + "email": "utatane.tea@gmail.com"
  8113 + },
  8114 + {
  8115 + "name": "nzakas",
  8116 + "email": "nicholas@nczconsulting.com"
7869 8117 }
7870 8118 ],
7871 8119 "repository": {
7872 8120 "type": "git",
7873   - "url": "http://github.com/Constellation/doctrine.git"
  8121 + "url": "http://github.com/eslint/doctrine.git"
7874 8122 },
7875 8123 "devDependencies": {
7876 8124 "coveralls": "^2.11.2",
... ... @@ -7889,7 +8137,7 @@ module.exports={
7889 8137 "licenses": [
7890 8138 {
7891 8139 "type": "BSD",
7892   - "url": "http://github.com/Constellation/doctrine/raw/master/LICENSE.BSD"
  8140 + "url": "http://github.com/eslint/doctrine/raw/master/LICENSE.BSD"
7893 8141 }
7894 8142 ],
7895 8143 "scripts": {
... ... @@ -7902,17 +8150,23 @@ module.exports={
7902 8150 "esutils": "^1.1.6",
7903 8151 "isarray": "0.0.1"
7904 8152 },
7905   - "gitHead": "4f74c86ea5cd03fbd947c4df91a2192d13779fb5",
7906   - "readme": "doctrine ([doctrine](http://github.com/Constellation/doctrine)) is JSDoc parser.\n\n[![Build Status](https://travis-ci.org/Constellation/doctrine.svg?branch=master)](https://travis-ci.org/Constellation/doctrine)\n[![Coverage Status](https://img.shields.io/coveralls/Constellation/doctrine.svg)](https://coveralls.io/r/Constellation/doctrine?branch=master)\n[![Dependency Status](https://david-dm.org/Constellation/doctrine.svg)](https://david-dm.org/Constellation/doctrine)\n[![devDependency Status](https://david-dm.org/Constellation/doctrine/dev-status.svg)](https://david-dm.org/Constellation/doctrine#info=devDependencies)\n[![Gitter chat](https://badges.gitter.im/Constellation/doctrine.png)](https://gitter.im/Constellation/doctrine)\n\nIt is now used by content assist system of [Eclipse Orion](http://www.eclipse.org/orion/) ([detail](http://planetorion.org/news/2012/10/orion-1-0-release/)). And used as JSDoc validator in [ESLint](http://eslint.org/).\n\nDoctrine can be used in a web browser with using browserify.\nor in a Node.js application via the package manager:\n\n npm install doctrine\n\nsimple example:\n\n doctrine.parse(\n [\n \"/**\",\n \" * This function comment is parsed by doctrine\",\n \" * @param {{ok:String}} userName\",\n \"*/\"\n ].join('\\n'), { unwrap: true });\n\nand gets following information\n\n {\n \"description\": \"This function comment is parsed by doctrine\",\n \"tags\": [\n {\n \"title\": \"param\",\n \"description\": null,\n \"type\": {\n \"type\": \"RecordType\",\n \"fields\": [\n {\n \"type\": \"FieldType\",\n \"key\": \"ok\",\n \"value\": {\n \"type\": \"NameExpression\",\n \"name\": \"String\"\n }\n }\n ]\n },\n \"name\": \"userName\"\n }\n ]\n }\n\nsee [demo page](http://constellation.github.com/doctrine/demo/index.html) more detail.\n\n### Options\n\n#### doctrine.parse\nWe can pass options to `doctrine.parse(comment, options)`.\n```js\n{\n unwrap: boolean, // default: false\n tags: [ string ] | null, // default: null\n recoverable: boolean, // default: false\n sloppy: boolean, // default: false\n lineNumbers: boolean // default: false\n}\n```\n\n##### unwrap\n\nWhen `unwrap` is `true`, doctrine attempt to unwrap comment specific string from a provided comment text. (removes `/**`, `*/` and `*`)\nFor example, `unwrap` transforms\n```\n/**\n * @param use\n */\n```\nto\n```\n@param use\n```\nIf a provided comment has these comment specific strings, you need to specify this `unwrap` option to `true`.\n\n##### tags\n\nWhen `tags` array is specified, doctrine only produce tags that is specified in this array.\nFor example, if you specify `[ 'param' ]`, doctrine only produces `param` tags.\nIf null is specified, doctrine produces all tags that doctrine can recognize.\n\n##### recoverable\n\nWhen `recoverable` is `true`, doctrine becomes `recoverable` - When failing to parse jsdoc comment, doctrine recovers its state and attempt to continue parsing.\n\n##### sloppy\n\nWhen `sloppy` is `true`,\n```\n@param String [foo]\n```\n's `[foo]` is interpreted as a optional parameter, not interpreted as a name of this `@param`.\n\n##### lineNumbers\n\nWhen `lineNumbers` is `true`, parsed tags will include a `lineNumber` property indicating the line (relative to the start of the comment block) where each tag is located in the source. So, given the following comment:\n```\n/**\n * @param {String} foo\n * @return {number}\n */\n```\nThe `@param` tag will have `lineNumber: 1`, and the `@return` tag will have `lineNumber: 2`.\n\n\n### License\n\n#### doctrine\n\nCopyright (C) 2012 [Yusuke Suzuki](http://github.com/Constellation)\n (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#### esprima\n\nsome of functions is derived from esprima\n\nCopyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about)\n (twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)) and other contributors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n#### closure-compiler\n\nsome of extensions is derived from closure-compiler\n\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n",
7907   - "readmeFilename": "README.md",
  8153 + "gitHead": "0d059e422bdfd630eaa15d583567c8668923f7e6",
7908 8154 "bugs": {
7909   - "url": "https://github.com/Constellation/doctrine/issues"
  8155 + "url": "https://github.com/eslint/doctrine/issues"
  8156 + },
  8157 + "_id": "doctrine@0.7.0",
  8158 + "_shasum": "dcc9589850b043d6e58abe24b561ccd57176cfd3",
  8159 + "_from": "doctrine@*",
  8160 + "_npmVersion": "1.4.28",
  8161 + "_npmUser": {
  8162 + "name": "nzakas",
  8163 + "email": "nicholas@nczconsulting.com"
  8164 + },
  8165 + "dist": {
  8166 + "shasum": "dcc9589850b043d6e58abe24b561ccd57176cfd3",
  8167 + "tarball": "http://registry.npmjs.org/doctrine/-/doctrine-0.7.0.tgz"
7910 8168 },
7911   - "_id": "doctrine@0.6.4",
7912   - "_shasum": "5b8d534412b49b8177b52082cd95df380de390aa",
7913   - "_from": "git://github.com/PolymerLabs/doctrine.git#master",
7914   - "_resolved": "git://github.com/PolymerLabs/doctrine.git#4f74c86ea5cd03fbd947c4df91a2192d13779fb5",
7915   - "_fromGithub": true
  8169 + "_resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.0.tgz"
7916 8170 }
7917 8171  
7918 8172 },{}],38:[function(require,module,exports){
... ... @@ -8273,6 +8527,34 @@ function _reverseNodeWalkAll(node, predicate, matches) {
8273 8527 }
8274 8528  
8275 8529 /**
  8530 + * Equivalent to `nodeWalk`, but only returns nodes that are either
  8531 + * ancestors or earlier cousins/siblings in the document.
  8532 + *
  8533 + * Nodes are searched in reverse document order, starting from the sibling
  8534 + * prior to `node`.
  8535 + */
  8536 +function nodeWalkPrior(node, predicate) {
  8537 + // Search our earlier siblings and their descendents.
  8538 + var parent = node.parentNode;
  8539 + if (parent) {
  8540 + var idx = parent.childNodes.indexOf(node);
  8541 + var siblings = parent.childNodes.slice(0, idx);
  8542 + for (var i = siblings.length-1; i >= 0; i--) {
  8543 + var sibling = siblings[i];
  8544 + if (predicate(sibling)) {
  8545 + return sibling;
  8546 + }
  8547 + var found = nodeWalkPrior(sibling, predicate);
  8548 + }
  8549 + if (predicate(parent)) {
  8550 + return parent;
  8551 + }
  8552 + return nodeWalkPrior(parent, predicate);
  8553 + }
  8554 + return undefined;
  8555 +}
  8556 +
  8557 +/**
8276 8558 * Equivalent to `nodeWalkAll`, but only returns nodes that are either
8277 8559 * ancestors or earlier cousins/siblings in the document.
8278 8560 *
... ... @@ -8409,6 +8691,7 @@ module.exports = {
8409 8691 queryAll: queryAll,
8410 8692 nodeWalk: nodeWalk,