jsforce2 1.11.1 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jsforce2 might be problematic. Click here for more details.
- package/index.js +46 -1
- package/package.json +7 -105
- package/LICENSE +0 -22
- package/README.md +0 -74
- package/bin/jsforce +0 -3
- package/bower.json +0 -30
- package/build/jsforce-api-analytics.js +0 -393
- package/build/jsforce-api-analytics.min.js +0 -2
- package/build/jsforce-api-analytics.min.js.map +0 -1
- package/build/jsforce-api-apex.js +0 -183
- package/build/jsforce-api-apex.min.js +0 -2
- package/build/jsforce-api-apex.min.js.map +0 -1
- package/build/jsforce-api-bulk.js +0 -1054
- package/build/jsforce-api-bulk.min.js +0 -2
- package/build/jsforce-api-bulk.min.js.map +0 -1
- package/build/jsforce-api-chatter.js +0 -320
- package/build/jsforce-api-chatter.min.js +0 -2
- package/build/jsforce-api-chatter.min.js.map +0 -1
- package/build/jsforce-api-metadata.js +0 -3020
- package/build/jsforce-api-metadata.min.js +0 -2
- package/build/jsforce-api-metadata.min.js.map +0 -1
- package/build/jsforce-api-soap.js +0 -403
- package/build/jsforce-api-soap.min.js +0 -2
- package/build/jsforce-api-soap.min.js.map +0 -1
- package/build/jsforce-api-streaming.js +0 -3479
- package/build/jsforce-api-streaming.min.js +0 -2
- package/build/jsforce-api-streaming.min.js.map +0 -1
- package/build/jsforce-api-tooling.js +0 -319
- package/build/jsforce-api-tooling.min.js +0 -2
- package/build/jsforce-api-tooling.min.js.map +0 -1
- package/build/jsforce-core.js +0 -25250
- package/build/jsforce-core.min.js +0 -2
- package/build/jsforce-core.min.js.map +0 -1
- package/build/jsforce.js +0 -31637
- package/build/jsforce.min.js +0 -2
- package/build/jsforce.min.js.map +0 -1
- package/core.js +0 -1
- package/lib/VERSION.js +0 -2
- package/lib/_required.js +0 -29
- package/lib/api/analytics.js +0 -387
- package/lib/api/apex.js +0 -177
- package/lib/api/bulk.js +0 -862
- package/lib/api/chatter.js +0 -314
- package/lib/api/index.js +0 -8
- package/lib/api/metadata.js +0 -848
- package/lib/api/soap.js +0 -397
- package/lib/api/streaming-extension.js +0 -136
- package/lib/api/streaming.js +0 -270
- package/lib/api/tooling.js +0 -313
- package/lib/browser/canvas.js +0 -90
- package/lib/browser/client.js +0 -241
- package/lib/browser/core.js +0 -5
- package/lib/browser/jsforce.js +0 -6
- package/lib/browser/jsonp.js +0 -52
- package/lib/browser/request.js +0 -70
- package/lib/cache.js +0 -252
- package/lib/cli/cli.js +0 -431
- package/lib/cli/repl.js +0 -337
- package/lib/connection.js +0 -1881
- package/lib/core.js +0 -16
- package/lib/csv.js +0 -50
- package/lib/date.js +0 -163
- package/lib/http-api.js +0 -300
- package/lib/jsforce.js +0 -10
- package/lib/logger.js +0 -52
- package/lib/oauth2.js +0 -206
- package/lib/process.js +0 -275
- package/lib/promise.js +0 -164
- package/lib/query.js +0 -881
- package/lib/quick-action.js +0 -90
- package/lib/record-stream.js +0 -305
- package/lib/record.js +0 -107
- package/lib/registry/file-registry.js +0 -48
- package/lib/registry/index.js +0 -3
- package/lib/registry/registry.js +0 -111
- package/lib/require.js +0 -14
- package/lib/soap.js +0 -207
- package/lib/sobject.js +0 -558
- package/lib/soql-builder.js +0 -236
- package/lib/transport.js +0 -233
|
@@ -1,3479 +0,0 @@
|
|
|
1
|
-
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.jsforce||(g.jsforce = {}));g=(g.modules||(g.modules = {}));g=(g.api||(g.api = {}));g.Streaming = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
2
|
-
/**
|
|
3
|
-
* Faye Client extensions: https://faye.jcoglan.com/browser/extensions.html
|
|
4
|
-
*
|
|
5
|
-
* For use with Streaming.prototype.createClient()
|
|
6
|
-
**/
|
|
7
|
-
var StreamingExtension = {};
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Constructor for an auth failure detector extension
|
|
11
|
-
*
|
|
12
|
-
* Based on new feature released with Salesforce Spring '18:
|
|
13
|
-
* https://releasenotes.docs.salesforce.com/en-us/spring18/release-notes/rn_messaging_cometd_auth_validation.htm?edition=&impact=
|
|
14
|
-
*
|
|
15
|
-
* Example triggering error message:
|
|
16
|
-
*
|
|
17
|
-
* ```
|
|
18
|
-
* {
|
|
19
|
-
* "ext":{
|
|
20
|
-
* "sfdc":{"failureReason":"401::Authentication invalid"},
|
|
21
|
-
* "replay":true},
|
|
22
|
-
* "advice":{"reconnect":"none"},
|
|
23
|
-
* "channel":"/meta/handshake",
|
|
24
|
-
* "error":"403::Handshake denied",
|
|
25
|
-
* "successful":false
|
|
26
|
-
* }
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* Example usage:
|
|
30
|
-
*
|
|
31
|
-
* ```javascript
|
|
32
|
-
* const conn = new jsforce.Connection({ … });
|
|
33
|
-
*
|
|
34
|
-
* const channel = "/event/My_Event__e";
|
|
35
|
-
*
|
|
36
|
-
* // Exit the Node process when auth fails
|
|
37
|
-
* const exitCallback = () => process.exit(1);
|
|
38
|
-
* const authFailureExt = new jsforce.StreamingExtension.AuthFailure(exitCallback);
|
|
39
|
-
*
|
|
40
|
-
* const fayeClient = conn.streaming.createClient([ authFailureExt ]);
|
|
41
|
-
*
|
|
42
|
-
* const subscription = fayeClient.subscribe(channel, data => {
|
|
43
|
-
* console.log('topic received data', data);
|
|
44
|
-
* });
|
|
45
|
-
*
|
|
46
|
-
* subscription.cancel();
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
* @param {Function} failureCallback - Invoked when authentication becomes invalid
|
|
50
|
-
*/
|
|
51
|
-
StreamingExtension.AuthFailure = function(failureCallback) {
|
|
52
|
-
this.incoming = function(message, callback) {
|
|
53
|
-
if (
|
|
54
|
-
(message.channel === '/meta/connect' ||
|
|
55
|
-
message.channel === '/meta/handshake')
|
|
56
|
-
&& message.advice
|
|
57
|
-
&& message.advice.reconnect == 'none'
|
|
58
|
-
) {
|
|
59
|
-
failureCallback(message);
|
|
60
|
-
} else {
|
|
61
|
-
callback(message);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Constructor for a durable streaming replay extension
|
|
68
|
-
*
|
|
69
|
-
* Modified from original Salesforce demo source code:
|
|
70
|
-
* https://github.com/developerforce/SalesforceDurableStreamingDemo/blob/3d4a56eac956f744ad6c22e6a8141b6feb57abb9/staticresources/cometdReplayExtension.resource
|
|
71
|
-
*
|
|
72
|
-
* Example usage:
|
|
73
|
-
*
|
|
74
|
-
* ```javascript
|
|
75
|
-
* const conn = new jsforce.Connection({ … });
|
|
76
|
-
*
|
|
77
|
-
* const channel = "/event/My_Event__e";
|
|
78
|
-
* const replayId = -2; // -2 is all retained events
|
|
79
|
-
*
|
|
80
|
-
* const replayExt = new jsforce.StreamingExtension.Replay(channel, replayId);
|
|
81
|
-
*
|
|
82
|
-
* const fayeClient = conn.streaming.createClient([ replayExt ]);
|
|
83
|
-
*
|
|
84
|
-
* const subscription = fayeClient.subscribe(channel, data => {
|
|
85
|
-
* console.log('topic received data', data);
|
|
86
|
-
* });
|
|
87
|
-
*
|
|
88
|
-
* subscription.cancel();
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
StreamingExtension.Replay = function(channel, replayId) {
|
|
92
|
-
var REPLAY_FROM_KEY = "replay";
|
|
93
|
-
|
|
94
|
-
var _extensionEnabled = replayId != null ? true : false;
|
|
95
|
-
var _replay = replayId;
|
|
96
|
-
var _channel = channel;
|
|
97
|
-
|
|
98
|
-
this.setExtensionEnabled = function(extensionEnabled) {
|
|
99
|
-
_extensionEnabled = extensionEnabled;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
this.setReplay = function (replay) {
|
|
103
|
-
_replay = parseInt(replay, 10);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
this.setChannel = function(channel) {
|
|
107
|
-
_channel = channel;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
this.incoming = function(message, callback) {
|
|
111
|
-
if (message.channel === '/meta/handshake') {
|
|
112
|
-
if (message.ext && message.ext[REPLAY_FROM_KEY] == true) {
|
|
113
|
-
_extensionEnabled = true;
|
|
114
|
-
}
|
|
115
|
-
} else if (message.channel === _channel && message.data && message.data.event && message.data.event.replayId) {
|
|
116
|
-
_replay = message.data.event.replayId;
|
|
117
|
-
}
|
|
118
|
-
callback(message);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
this.outgoing = function(message, callback) {
|
|
122
|
-
if (message.channel === '/meta/subscribe' && message.subscription === _channel) {
|
|
123
|
-
if (_extensionEnabled) {
|
|
124
|
-
if (!message.ext) { message.ext = {}; }
|
|
125
|
-
|
|
126
|
-
var replayFromMap = {};
|
|
127
|
-
replayFromMap[_channel] = _replay;
|
|
128
|
-
|
|
129
|
-
// add "ext : { "replay" : { CHANNEL : REPLAY_VALUE }}" to subscribe message
|
|
130
|
-
message.ext[REPLAY_FROM_KEY] = replayFromMap;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
callback(message);
|
|
134
|
-
};
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
module.exports = StreamingExtension;
|
|
138
|
-
|
|
139
|
-
},{}],2:[function(require,module,exports){
|
|
140
|
-
/**
|
|
141
|
-
* @file Manages Streaming APIs
|
|
142
|
-
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
143
|
-
*/
|
|
144
|
-
|
|
145
|
-
'use strict';
|
|
146
|
-
|
|
147
|
-
var events = window.jsforce.require('events'),
|
|
148
|
-
inherits = window.jsforce.require('inherits'),
|
|
149
|
-
_ = window.jsforce.require('lodash/core'),
|
|
150
|
-
Faye = require('faye'),
|
|
151
|
-
StreamingExtension = require('./streaming-extension'),
|
|
152
|
-
jsforce = window.jsforce.require('./core');
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Streaming API topic class
|
|
156
|
-
*
|
|
157
|
-
* @class Streaming~Topic
|
|
158
|
-
* @param {Streaming} steaming - Streaming API object
|
|
159
|
-
* @param {String} name - Topic name
|
|
160
|
-
*/
|
|
161
|
-
var Topic = function(streaming, name) {
|
|
162
|
-
this._streaming = streaming;
|
|
163
|
-
this.name = name;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* @typedef {Object} Streaming~StreamingMessage
|
|
168
|
-
* @prop {Object} event
|
|
169
|
-
* @prop {Object} event.type - Event type
|
|
170
|
-
* @prop {Record} sobject - Record information
|
|
171
|
-
*/
|
|
172
|
-
/**
|
|
173
|
-
* Subscribe listener to topic
|
|
174
|
-
*
|
|
175
|
-
* @method Streaming~Topic#subscribe
|
|
176
|
-
* @param {Callback.<Streaming~StreamingMesasge>} listener - Streaming message listener
|
|
177
|
-
* @returns {Subscription} - Faye subscription object
|
|
178
|
-
*/
|
|
179
|
-
Topic.prototype.subscribe = function(listener) {
|
|
180
|
-
return this._streaming.subscribe(this.name, listener);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Unsubscribe listener from topic
|
|
185
|
-
*
|
|
186
|
-
* @method Streaming~Topic#unsubscribe
|
|
187
|
-
* @param {Callback.<Streaming~StreamingMesasge>} listener - Streaming message listener
|
|
188
|
-
* @returns {Streaming~Topic}
|
|
189
|
-
*/
|
|
190
|
-
Topic.prototype.unsubscribe = function(listener) {
|
|
191
|
-
this._streaming.unsubscribe(this.name, listener);
|
|
192
|
-
return this;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
/*--------------------------------------------*/
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Streaming API Generic Streaming Channel
|
|
199
|
-
*
|
|
200
|
-
* @class Streaming~Channel
|
|
201
|
-
* @param {Streaming} steaming - Streaming API object
|
|
202
|
-
* @param {String} name - Channel name (starts with "/u/")
|
|
203
|
-
*/
|
|
204
|
-
var Channel = function(streaming, name) {
|
|
205
|
-
this._streaming = streaming;
|
|
206
|
-
this._name = name;
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Subscribe to channel
|
|
211
|
-
*
|
|
212
|
-
* @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
|
|
213
|
-
* @returns {Subscription} - Faye subscription object
|
|
214
|
-
*/
|
|
215
|
-
Channel.prototype.subscribe = function(listener) {
|
|
216
|
-
return this._streaming.subscribe(this._name, listener);
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
Channel.prototype.unsubscribe = function(listener) {
|
|
220
|
-
this._streaming.unsubscribe(this._name, listener);
|
|
221
|
-
return this;
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
Channel.prototype.push = function(events, callback) {
|
|
225
|
-
var isArray = _.isArray(events);
|
|
226
|
-
events = isArray ? events : [ events ];
|
|
227
|
-
var conn = this._streaming._conn;
|
|
228
|
-
if (!this._id) {
|
|
229
|
-
this._id = conn.sobject('StreamingChannel').findOne({ Name: this._name }, 'Id')
|
|
230
|
-
.then(function(rec) { return rec.Id });
|
|
231
|
-
}
|
|
232
|
-
return this._id.then(function(id) {
|
|
233
|
-
var channelUrl = '/sobjects/StreamingChannel/' + id + '/push';
|
|
234
|
-
return conn.requestPost(channelUrl, { pushEvents: events });
|
|
235
|
-
}).then(function(rets) {
|
|
236
|
-
return isArray ? rets : rets[0];
|
|
237
|
-
}).thenCall(callback);
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
/*--------------------------------------------*/
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Streaming API class
|
|
244
|
-
*
|
|
245
|
-
* @class
|
|
246
|
-
* @extends events.EventEmitter
|
|
247
|
-
* @param {Connection} conn - Connection object
|
|
248
|
-
*/
|
|
249
|
-
var Streaming = function(conn) {
|
|
250
|
-
this._conn = conn;
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
inherits(Streaming, events.EventEmitter);
|
|
254
|
-
|
|
255
|
-
/** @private **/
|
|
256
|
-
Streaming.prototype._createClient = function(forChannelName, extensions) {
|
|
257
|
-
// forChannelName is advisory, for an API workaround. It does not restrict or select the channel.
|
|
258
|
-
var needsReplayFix = typeof forChannelName === 'string' && forChannelName.indexOf('/u/') === 0;
|
|
259
|
-
var endpointUrl = [
|
|
260
|
-
this._conn.instanceUrl,
|
|
261
|
-
// special endpoint "/cometd/replay/xx.x" is only available in 36.0.
|
|
262
|
-
// See https://releasenotes.docs.salesforce.com/en-us/summer16/release-notes/rn_api_streaming_classic_replay.htm
|
|
263
|
-
"cometd" + (needsReplayFix === true && this._conn.version === "36.0" ? "/replay" : ""),
|
|
264
|
-
this._conn.version
|
|
265
|
-
].join('/');
|
|
266
|
-
var fayeClient = new Faye.Client(endpointUrl, {});
|
|
267
|
-
fayeClient.setHeader('Authorization', 'OAuth '+this._conn.accessToken);
|
|
268
|
-
if (extensions instanceof Array) {
|
|
269
|
-
extensions.forEach(function(extension) {
|
|
270
|
-
fayeClient.addExtension(extension);
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
if (fayeClient._dispatcher.getConnectionTypes().indexOf('callback-polling') === -1) {
|
|
274
|
-
// prevent streaming API server error
|
|
275
|
-
fayeClient._dispatcher.selectTransport('long-polling');
|
|
276
|
-
fayeClient._dispatcher._transport.batching = false;
|
|
277
|
-
}
|
|
278
|
-
return fayeClient;
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
/** @private **/
|
|
282
|
-
Streaming.prototype._getFayeClient = function(channelName) {
|
|
283
|
-
var isGeneric = channelName.indexOf('/u/') === 0;
|
|
284
|
-
var clientType = isGeneric ? 'generic' : 'pushTopic';
|
|
285
|
-
if (!this._fayeClients || !this._fayeClients[clientType]) {
|
|
286
|
-
this._fayeClients = this._fayeClients || {};
|
|
287
|
-
this._fayeClients[clientType] = this._createClient(channelName);
|
|
288
|
-
}
|
|
289
|
-
return this._fayeClients[clientType];
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Get named topic
|
|
295
|
-
*
|
|
296
|
-
* @param {String} name - Topic name
|
|
297
|
-
* @returns {Streaming~Topic}
|
|
298
|
-
*/
|
|
299
|
-
Streaming.prototype.topic = function(name) {
|
|
300
|
-
this._topics = this._topics || {};
|
|
301
|
-
var topic = this._topics[name] =
|
|
302
|
-
this._topics[name] || new Topic(this, name);
|
|
303
|
-
return topic;
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Get Channel for Id
|
|
308
|
-
* @param {String} channelId - Id of StreamingChannel object
|
|
309
|
-
* @returns {Streaming~Channel}
|
|
310
|
-
*/
|
|
311
|
-
Streaming.prototype.channel = function(channelId) {
|
|
312
|
-
return new Channel(this, channelId);
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Subscribe topic/channel
|
|
317
|
-
*
|
|
318
|
-
* @param {String} name - Topic name
|
|
319
|
-
* @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
|
|
320
|
-
* @returns {Subscription} - Faye subscription object
|
|
321
|
-
*/
|
|
322
|
-
Streaming.prototype.subscribe = function(name, listener) {
|
|
323
|
-
var channelName = name.indexOf('/') === 0 ? name : '/topic/' + name;
|
|
324
|
-
var fayeClient = this._getFayeClient(channelName);
|
|
325
|
-
return fayeClient.subscribe(channelName, listener);
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Unsubscribe topic
|
|
330
|
-
*
|
|
331
|
-
* @param {String} name - Topic name
|
|
332
|
-
* @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
|
|
333
|
-
* @returns {Streaming}
|
|
334
|
-
*/
|
|
335
|
-
Streaming.prototype.unsubscribe = function(name, listener) {
|
|
336
|
-
var channelName = name.indexOf('/') === 0 ? name : '/topic/' + name;
|
|
337
|
-
var fayeClient = this._getFayeClient(channelName);
|
|
338
|
-
fayeClient.unsubscribe(channelName, listener);
|
|
339
|
-
return this;
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Create a Streaming client, optionally with extensions
|
|
345
|
-
*
|
|
346
|
-
* See Faye docs for implementation details: https://faye.jcoglan.com/browser/extensions.html
|
|
347
|
-
*
|
|
348
|
-
* Example usage:
|
|
349
|
-
*
|
|
350
|
-
* ```javascript
|
|
351
|
-
* // Establish a Salesforce connection. (Details elided)
|
|
352
|
-
* const conn = new jsforce.Connection({ … });
|
|
353
|
-
*
|
|
354
|
-
* const fayeClient = conn.streaming.createClient();
|
|
355
|
-
*
|
|
356
|
-
* const subscription = fayeClient.subscribe(channel, data => {
|
|
357
|
-
* console.log('topic received data', data);
|
|
358
|
-
* });
|
|
359
|
-
*
|
|
360
|
-
* subscription.cancel();
|
|
361
|
-
* ```
|
|
362
|
-
*
|
|
363
|
-
* Example with extensions, using Replay & Auth Failure extensions in a server-side Node.js app:
|
|
364
|
-
*
|
|
365
|
-
* ```javascript
|
|
366
|
-
* // Establish a Salesforce connection. (Details elided)
|
|
367
|
-
* const conn = new jsforce.Connection({ … });
|
|
368
|
-
*
|
|
369
|
-
* const channel = "/event/My_Event__e";
|
|
370
|
-
* const replayId = -2; // -2 is all retained events
|
|
371
|
-
*
|
|
372
|
-
* const exitCallback = () => process.exit(1);
|
|
373
|
-
* const authFailureExt = new jsforce.StreamingExtension.AuthFailure(exitCallback);
|
|
374
|
-
*
|
|
375
|
-
* const replayExt = new jsforce.StreamingExtension.Replay(channel, replayId);
|
|
376
|
-
*
|
|
377
|
-
* const fayeClient = conn.streaming.createClient([
|
|
378
|
-
* authFailureExt,
|
|
379
|
-
* replayExt
|
|
380
|
-
* ]);
|
|
381
|
-
*
|
|
382
|
-
* const subscription = fayeClient.subscribe(channel, data => {
|
|
383
|
-
* console.log('topic received data', data);
|
|
384
|
-
* });
|
|
385
|
-
*
|
|
386
|
-
* subscription.cancel();
|
|
387
|
-
* ```
|
|
388
|
-
*
|
|
389
|
-
* @param {Array} Extensions - Optional, extensions to apply to the Faye client
|
|
390
|
-
* @returns {FayeClient} - Faye client object
|
|
391
|
-
*/
|
|
392
|
-
Streaming.prototype.createClient = function(extensions) {
|
|
393
|
-
return this._createClient(null, extensions);
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
/*--------------------------------------------*/
|
|
397
|
-
/*
|
|
398
|
-
* Register hook in connection instantiation for dynamically adding this API module features
|
|
399
|
-
*/
|
|
400
|
-
jsforce.on('connection:new', function(conn) {
|
|
401
|
-
conn.streaming = new Streaming(conn);
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
/*
|
|
405
|
-
*
|
|
406
|
-
*/
|
|
407
|
-
jsforce.StreamingExtension = StreamingExtension;
|
|
408
|
-
|
|
409
|
-
module.exports = Streaming;
|
|
410
|
-
|
|
411
|
-
},{"./streaming-extension":1,"faye":5}],3:[function(require,module,exports){
|
|
412
|
-
"use strict";
|
|
413
|
-
|
|
414
|
-
// rawAsap provides everything we need except exception management.
|
|
415
|
-
var rawAsap = require("./raw");
|
|
416
|
-
// RawTasks are recycled to reduce GC churn.
|
|
417
|
-
var freeTasks = [];
|
|
418
|
-
// We queue errors to ensure they are thrown in right order (FIFO).
|
|
419
|
-
// Array-as-queue is good enough here, since we are just dealing with exceptions.
|
|
420
|
-
var pendingErrors = [];
|
|
421
|
-
var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);
|
|
422
|
-
|
|
423
|
-
function throwFirstError() {
|
|
424
|
-
if (pendingErrors.length) {
|
|
425
|
-
throw pendingErrors.shift();
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Calls a task as soon as possible after returning, in its own event, with priority
|
|
431
|
-
* over other events like animation, reflow, and repaint. An error thrown from an
|
|
432
|
-
* event will not interrupt, nor even substantially slow down the processing of
|
|
433
|
-
* other events, but will be rather postponed to a lower priority event.
|
|
434
|
-
* @param {{call}} task A callable object, typically a function that takes no
|
|
435
|
-
* arguments.
|
|
436
|
-
*/
|
|
437
|
-
module.exports = asap;
|
|
438
|
-
function asap(task) {
|
|
439
|
-
var rawTask;
|
|
440
|
-
if (freeTasks.length) {
|
|
441
|
-
rawTask = freeTasks.pop();
|
|
442
|
-
} else {
|
|
443
|
-
rawTask = new RawTask();
|
|
444
|
-
}
|
|
445
|
-
rawTask.task = task;
|
|
446
|
-
rawAsap(rawTask);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// We wrap tasks with recyclable task objects. A task object implements
|
|
450
|
-
// `call`, just like a function.
|
|
451
|
-
function RawTask() {
|
|
452
|
-
this.task = null;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// The sole purpose of wrapping the task is to catch the exception and recycle
|
|
456
|
-
// the task object after its single use.
|
|
457
|
-
RawTask.prototype.call = function () {
|
|
458
|
-
try {
|
|
459
|
-
this.task.call();
|
|
460
|
-
} catch (error) {
|
|
461
|
-
if (asap.onerror) {
|
|
462
|
-
// This hook exists purely for testing purposes.
|
|
463
|
-
// Its name will be periodically randomized to break any code that
|
|
464
|
-
// depends on its existence.
|
|
465
|
-
asap.onerror(error);
|
|
466
|
-
} else {
|
|
467
|
-
// In a web browser, exceptions are not fatal. However, to avoid
|
|
468
|
-
// slowing down the queue of pending tasks, we rethrow the error in a
|
|
469
|
-
// lower priority turn.
|
|
470
|
-
pendingErrors.push(error);
|
|
471
|
-
requestErrorThrow();
|
|
472
|
-
}
|
|
473
|
-
} finally {
|
|
474
|
-
this.task = null;
|
|
475
|
-
freeTasks[freeTasks.length] = this;
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
},{"./raw":4}],4:[function(require,module,exports){
|
|
480
|
-
(function (global){
|
|
481
|
-
"use strict";
|
|
482
|
-
|
|
483
|
-
// Use the fastest means possible to execute a task in its own turn, with
|
|
484
|
-
// priority over other events including IO, animation, reflow, and redraw
|
|
485
|
-
// events in browsers.
|
|
486
|
-
//
|
|
487
|
-
// An exception thrown by a task will permanently interrupt the processing of
|
|
488
|
-
// subsequent tasks. The higher level `asap` function ensures that if an
|
|
489
|
-
// exception is thrown by a task, that the task queue will continue flushing as
|
|
490
|
-
// soon as possible, but if you use `rawAsap` directly, you are responsible to
|
|
491
|
-
// either ensure that no exceptions are thrown from your task, or to manually
|
|
492
|
-
// call `rawAsap.requestFlush` if an exception is thrown.
|
|
493
|
-
module.exports = rawAsap;
|
|
494
|
-
function rawAsap(task) {
|
|
495
|
-
if (!queue.length) {
|
|
496
|
-
requestFlush();
|
|
497
|
-
flushing = true;
|
|
498
|
-
}
|
|
499
|
-
// Equivalent to push, but avoids a function call.
|
|
500
|
-
queue[queue.length] = task;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
var queue = [];
|
|
504
|
-
// Once a flush has been requested, no further calls to `requestFlush` are
|
|
505
|
-
// necessary until the next `flush` completes.
|
|
506
|
-
var flushing = false;
|
|
507
|
-
// `requestFlush` is an implementation-specific method that attempts to kick
|
|
508
|
-
// off a `flush` event as quickly as possible. `flush` will attempt to exhaust
|
|
509
|
-
// the event queue before yielding to the browser's own event loop.
|
|
510
|
-
var requestFlush;
|
|
511
|
-
// The position of the next task to execute in the task queue. This is
|
|
512
|
-
// preserved between calls to `flush` so that it can be resumed if
|
|
513
|
-
// a task throws an exception.
|
|
514
|
-
var index = 0;
|
|
515
|
-
// If a task schedules additional tasks recursively, the task queue can grow
|
|
516
|
-
// unbounded. To prevent memory exhaustion, the task queue will periodically
|
|
517
|
-
// truncate already-completed tasks.
|
|
518
|
-
var capacity = 1024;
|
|
519
|
-
|
|
520
|
-
// The flush function processes all tasks that have been scheduled with
|
|
521
|
-
// `rawAsap` unless and until one of those tasks throws an exception.
|
|
522
|
-
// If a task throws an exception, `flush` ensures that its state will remain
|
|
523
|
-
// consistent and will resume where it left off when called again.
|
|
524
|
-
// However, `flush` does not make any arrangements to be called again if an
|
|
525
|
-
// exception is thrown.
|
|
526
|
-
function flush() {
|
|
527
|
-
while (index < queue.length) {
|
|
528
|
-
var currentIndex = index;
|
|
529
|
-
// Advance the index before calling the task. This ensures that we will
|
|
530
|
-
// begin flushing on the next task the task throws an error.
|
|
531
|
-
index = index + 1;
|
|
532
|
-
queue[currentIndex].call();
|
|
533
|
-
// Prevent leaking memory for long chains of recursive calls to `asap`.
|
|
534
|
-
// If we call `asap` within tasks scheduled by `asap`, the queue will
|
|
535
|
-
// grow, but to avoid an O(n) walk for every task we execute, we don't
|
|
536
|
-
// shift tasks off the queue after they have been executed.
|
|
537
|
-
// Instead, we periodically shift 1024 tasks off the queue.
|
|
538
|
-
if (index > capacity) {
|
|
539
|
-
// Manually shift all values starting at the index back to the
|
|
540
|
-
// beginning of the queue.
|
|
541
|
-
for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
|
|
542
|
-
queue[scan] = queue[scan + index];
|
|
543
|
-
}
|
|
544
|
-
queue.length -= index;
|
|
545
|
-
index = 0;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
queue.length = 0;
|
|
549
|
-
index = 0;
|
|
550
|
-
flushing = false;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// `requestFlush` is implemented using a strategy based on data collected from
|
|
554
|
-
// every available SauceLabs Selenium web driver worker at time of writing.
|
|
555
|
-
// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593
|
|
556
|
-
|
|
557
|
-
// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
|
|
558
|
-
// have WebKitMutationObserver but not un-prefixed MutationObserver.
|
|
559
|
-
// Must use `global` or `self` instead of `window` to work in both frames and web
|
|
560
|
-
// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
|
|
561
|
-
|
|
562
|
-
/* globals self */
|
|
563
|
-
var scope = typeof global !== "undefined" ? global : self;
|
|
564
|
-
var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
|
|
565
|
-
|
|
566
|
-
// MutationObservers are desirable because they have high priority and work
|
|
567
|
-
// reliably everywhere they are implemented.
|
|
568
|
-
// They are implemented in all modern browsers.
|
|
569
|
-
//
|
|
570
|
-
// - Android 4-4.3
|
|
571
|
-
// - Chrome 26-34
|
|
572
|
-
// - Firefox 14-29
|
|
573
|
-
// - Internet Explorer 11
|
|
574
|
-
// - iPad Safari 6-7.1
|
|
575
|
-
// - iPhone Safari 7-7.1
|
|
576
|
-
// - Safari 6-7
|
|
577
|
-
if (typeof BrowserMutationObserver === "function") {
|
|
578
|
-
requestFlush = makeRequestCallFromMutationObserver(flush);
|
|
579
|
-
|
|
580
|
-
// MessageChannels are desirable because they give direct access to the HTML
|
|
581
|
-
// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
|
|
582
|
-
// 11-12, and in web workers in many engines.
|
|
583
|
-
// Although message channels yield to any queued rendering and IO tasks, they
|
|
584
|
-
// would be better than imposing the 4ms delay of timers.
|
|
585
|
-
// However, they do not work reliably in Internet Explorer or Safari.
|
|
586
|
-
|
|
587
|
-
// Internet Explorer 10 is the only browser that has setImmediate but does
|
|
588
|
-
// not have MutationObservers.
|
|
589
|
-
// Although setImmediate yields to the browser's renderer, it would be
|
|
590
|
-
// preferrable to falling back to setTimeout since it does not have
|
|
591
|
-
// the minimum 4ms penalty.
|
|
592
|
-
// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
|
|
593
|
-
// Desktop to a lesser extent) that renders both setImmediate and
|
|
594
|
-
// MessageChannel useless for the purposes of ASAP.
|
|
595
|
-
// https://github.com/kriskowal/q/issues/396
|
|
596
|
-
|
|
597
|
-
// Timers are implemented universally.
|
|
598
|
-
// We fall back to timers in workers in most engines, and in foreground
|
|
599
|
-
// contexts in the following browsers.
|
|
600
|
-
// However, note that even this simple case requires nuances to operate in a
|
|
601
|
-
// broad spectrum of browsers.
|
|
602
|
-
//
|
|
603
|
-
// - Firefox 3-13
|
|
604
|
-
// - Internet Explorer 6-9
|
|
605
|
-
// - iPad Safari 4.3
|
|
606
|
-
// - Lynx 2.8.7
|
|
607
|
-
} else {
|
|
608
|
-
requestFlush = makeRequestCallFromTimer(flush);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// `requestFlush` requests that the high priority event queue be flushed as
|
|
612
|
-
// soon as possible.
|
|
613
|
-
// This is useful to prevent an error thrown in a task from stalling the event
|
|
614
|
-
// queue if the exception handled by Node.js’s
|
|
615
|
-
// `process.on("uncaughtException")` or by a domain.
|
|
616
|
-
rawAsap.requestFlush = requestFlush;
|
|
617
|
-
|
|
618
|
-
// To request a high priority event, we induce a mutation observer by toggling
|
|
619
|
-
// the text of a text node between "1" and "-1".
|
|
620
|
-
function makeRequestCallFromMutationObserver(callback) {
|
|
621
|
-
var toggle = 1;
|
|
622
|
-
var observer = new BrowserMutationObserver(callback);
|
|
623
|
-
var node = document.createTextNode("");
|
|
624
|
-
observer.observe(node, {characterData: true});
|
|
625
|
-
return function requestCall() {
|
|
626
|
-
toggle = -toggle;
|
|
627
|
-
node.data = toggle;
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
// The message channel technique was discovered by Malte Ubl and was the
|
|
632
|
-
// original foundation for this library.
|
|
633
|
-
// http://www.nonblocking.io/2011/06/windownexttick.html
|
|
634
|
-
|
|
635
|
-
// Safari 6.0.5 (at least) intermittently fails to create message ports on a
|
|
636
|
-
// page's first load. Thankfully, this version of Safari supports
|
|
637
|
-
// MutationObservers, so we don't need to fall back in that case.
|
|
638
|
-
|
|
639
|
-
// function makeRequestCallFromMessageChannel(callback) {
|
|
640
|
-
// var channel = new MessageChannel();
|
|
641
|
-
// channel.port1.onmessage = callback;
|
|
642
|
-
// return function requestCall() {
|
|
643
|
-
// channel.port2.postMessage(0);
|
|
644
|
-
// };
|
|
645
|
-
// }
|
|
646
|
-
|
|
647
|
-
// For reasons explained above, we are also unable to use `setImmediate`
|
|
648
|
-
// under any circumstances.
|
|
649
|
-
// Even if we were, there is another bug in Internet Explorer 10.
|
|
650
|
-
// It is not sufficient to assign `setImmediate` to `requestFlush` because
|
|
651
|
-
// `setImmediate` must be called *by name* and therefore must be wrapped in a
|
|
652
|
-
// closure.
|
|
653
|
-
// Never forget.
|
|
654
|
-
|
|
655
|
-
// function makeRequestCallFromSetImmediate(callback) {
|
|
656
|
-
// return function requestCall() {
|
|
657
|
-
// setImmediate(callback);
|
|
658
|
-
// };
|
|
659
|
-
// }
|
|
660
|
-
|
|
661
|
-
// Safari 6.0 has a problem where timers will get lost while the user is
|
|
662
|
-
// scrolling. This problem does not impact ASAP because Safari 6.0 supports
|
|
663
|
-
// mutation observers, so that implementation is used instead.
|
|
664
|
-
// However, if we ever elect to use timers in Safari, the prevalent work-around
|
|
665
|
-
// is to add a scroll event listener that calls for a flush.
|
|
666
|
-
|
|
667
|
-
// `setTimeout` does not call the passed callback if the delay is less than
|
|
668
|
-
// approximately 7 in web workers in Firefox 8 through 18, and sometimes not
|
|
669
|
-
// even then.
|
|
670
|
-
|
|
671
|
-
function makeRequestCallFromTimer(callback) {
|
|
672
|
-
return function requestCall() {
|
|
673
|
-
// We dispatch a timeout with a specified delay of 0 for engines that
|
|
674
|
-
// can reliably accommodate that request. This will usually be snapped
|
|
675
|
-
// to a 4 milisecond delay, but once we're flushing, there's no delay
|
|
676
|
-
// between events.
|
|
677
|
-
var timeoutHandle = setTimeout(handleTimer, 0);
|
|
678
|
-
// However, since this timer gets frequently dropped in Firefox
|
|
679
|
-
// workers, we enlist an interval handle that will try to fire
|
|
680
|
-
// an event 20 times per second until it succeeds.
|
|
681
|
-
var intervalHandle = setInterval(handleTimer, 50);
|
|
682
|
-
|
|
683
|
-
function handleTimer() {
|
|
684
|
-
// Whichever timer succeeds will cancel both timers and
|
|
685
|
-
// execute the callback.
|
|
686
|
-
clearTimeout(timeoutHandle);
|
|
687
|
-
clearInterval(intervalHandle);
|
|
688
|
-
callback();
|
|
689
|
-
}
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
// This is for `asap.js` only.
|
|
694
|
-
// Its name will be periodically randomized to break any code that depends on
|
|
695
|
-
// its existence.
|
|
696
|
-
rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;
|
|
697
|
-
|
|
698
|
-
// ASAP was originally a nextTick shim included in Q. This was factored out
|
|
699
|
-
// into this ASAP package. It was later adapted to RSVP which made further
|
|
700
|
-
// amendments. These decisions, particularly to marginalize MessageChannel and
|
|
701
|
-
// to capture the MutationObserver implementation in a closure, were integrated
|
|
702
|
-
// back into ASAP proper.
|
|
703
|
-
// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
|
|
704
|
-
|
|
705
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
706
|
-
|
|
707
|
-
},{}],5:[function(require,module,exports){
|
|
708
|
-
'use strict';
|
|
709
|
-
|
|
710
|
-
var constants = require('./util/constants'),
|
|
711
|
-
Logging = require('./mixins/logging');
|
|
712
|
-
|
|
713
|
-
var Faye = {
|
|
714
|
-
VERSION: constants.VERSION,
|
|
715
|
-
|
|
716
|
-
Client: require('./protocol/client'),
|
|
717
|
-
Scheduler: require('./protocol/scheduler')
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
Logging.wrapper = Faye;
|
|
721
|
-
|
|
722
|
-
module.exports = Faye;
|
|
723
|
-
|
|
724
|
-
},{"./mixins/logging":7,"./protocol/client":11,"./protocol/scheduler":17,"./util/constants":29}],6:[function(require,module,exports){
|
|
725
|
-
(function (global){
|
|
726
|
-
'use strict';
|
|
727
|
-
|
|
728
|
-
var Promise = require('../util/promise');
|
|
729
|
-
|
|
730
|
-
module.exports = {
|
|
731
|
-
then: function(callback, errback) {
|
|
732
|
-
var self = this;
|
|
733
|
-
if (!this._promise)
|
|
734
|
-
this._promise = new Promise(function(resolve, reject) {
|
|
735
|
-
self._resolve = resolve;
|
|
736
|
-
self._reject = reject;
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
if (arguments.length === 0)
|
|
740
|
-
return this._promise;
|
|
741
|
-
else
|
|
742
|
-
return this._promise.then(callback, errback);
|
|
743
|
-
},
|
|
744
|
-
|
|
745
|
-
callback: function(callback, context) {
|
|
746
|
-
return this.then(function(value) { callback.call(context, value) });
|
|
747
|
-
},
|
|
748
|
-
|
|
749
|
-
errback: function(callback, context) {
|
|
750
|
-
return this.then(null, function(reason) { callback.call(context, reason) });
|
|
751
|
-
},
|
|
752
|
-
|
|
753
|
-
timeout: function(seconds, message) {
|
|
754
|
-
this.then();
|
|
755
|
-
var self = this;
|
|
756
|
-
this._timer = global.setTimeout(function() {
|
|
757
|
-
self._reject(message);
|
|
758
|
-
}, seconds * 1000);
|
|
759
|
-
},
|
|
760
|
-
|
|
761
|
-
setDeferredStatus: function(status, value) {
|
|
762
|
-
if (this._timer) global.clearTimeout(this._timer);
|
|
763
|
-
|
|
764
|
-
this.then();
|
|
765
|
-
|
|
766
|
-
if (status === 'succeeded')
|
|
767
|
-
this._resolve(value);
|
|
768
|
-
else if (status === 'failed')
|
|
769
|
-
this._reject(value);
|
|
770
|
-
else
|
|
771
|
-
delete this._promise;
|
|
772
|
-
}
|
|
773
|
-
};
|
|
774
|
-
|
|
775
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
776
|
-
|
|
777
|
-
},{"../util/promise":34}],7:[function(require,module,exports){
|
|
778
|
-
'use strict';
|
|
779
|
-
|
|
780
|
-
var toJSON = require('../util/to_json');
|
|
781
|
-
|
|
782
|
-
var Logging = {
|
|
783
|
-
LOG_LEVELS: {
|
|
784
|
-
fatal: 4,
|
|
785
|
-
error: 3,
|
|
786
|
-
warn: 2,
|
|
787
|
-
info: 1,
|
|
788
|
-
debug: 0
|
|
789
|
-
},
|
|
790
|
-
|
|
791
|
-
writeLog: function(messageArgs, level) {
|
|
792
|
-
var logger = Logging.logger || (Logging.wrapper || Logging).logger;
|
|
793
|
-
if (!logger) return;
|
|
794
|
-
|
|
795
|
-
var args = Array.prototype.slice.apply(messageArgs),
|
|
796
|
-
banner = '[Faye',
|
|
797
|
-
klass = this.className,
|
|
798
|
-
|
|
799
|
-
message = args.shift().replace(/\?/g, function() {
|
|
800
|
-
try {
|
|
801
|
-
return toJSON(args.shift());
|
|
802
|
-
} catch (error) {
|
|
803
|
-
return '[Object]';
|
|
804
|
-
}
|
|
805
|
-
});
|
|
806
|
-
|
|
807
|
-
if (klass) banner += '.' + klass;
|
|
808
|
-
banner += '] ';
|
|
809
|
-
|
|
810
|
-
if (typeof logger[level] === 'function')
|
|
811
|
-
logger[level](banner + message);
|
|
812
|
-
else if (typeof logger === 'function')
|
|
813
|
-
logger(banner + message);
|
|
814
|
-
}
|
|
815
|
-
};
|
|
816
|
-
|
|
817
|
-
for (var key in Logging.LOG_LEVELS)
|
|
818
|
-
(function(level) {
|
|
819
|
-
Logging[level] = function() {
|
|
820
|
-
this.writeLog(arguments, level);
|
|
821
|
-
};
|
|
822
|
-
})(key);
|
|
823
|
-
|
|
824
|
-
module.exports = Logging;
|
|
825
|
-
|
|
826
|
-
},{"../util/to_json":36}],8:[function(require,module,exports){
|
|
827
|
-
'use strict';
|
|
828
|
-
|
|
829
|
-
var extend = require('../util/extend'),
|
|
830
|
-
EventEmitter = require('../util/event_emitter');
|
|
831
|
-
|
|
832
|
-
var Publisher = {
|
|
833
|
-
countListeners: function(eventType) {
|
|
834
|
-
return this.listeners(eventType).length;
|
|
835
|
-
},
|
|
836
|
-
|
|
837
|
-
bind: function(eventType, listener, context) {
|
|
838
|
-
var slice = Array.prototype.slice,
|
|
839
|
-
handler = function() { listener.apply(context, slice.call(arguments)) };
|
|
840
|
-
|
|
841
|
-
this._listeners = this._listeners || [];
|
|
842
|
-
this._listeners.push([eventType, listener, context, handler]);
|
|
843
|
-
return this.on(eventType, handler);
|
|
844
|
-
},
|
|
845
|
-
|
|
846
|
-
unbind: function(eventType, listener, context) {
|
|
847
|
-
this._listeners = this._listeners || [];
|
|
848
|
-
var n = this._listeners.length, tuple;
|
|
849
|
-
|
|
850
|
-
while (n--) {
|
|
851
|
-
tuple = this._listeners[n];
|
|
852
|
-
if (tuple[0] !== eventType) continue;
|
|
853
|
-
if (listener && (tuple[1] !== listener || tuple[2] !== context)) continue;
|
|
854
|
-
this._listeners.splice(n, 1);
|
|
855
|
-
this.removeListener(eventType, tuple[3]);
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
};
|
|
859
|
-
|
|
860
|
-
extend(Publisher, EventEmitter.prototype);
|
|
861
|
-
Publisher.trigger = Publisher.emit;
|
|
862
|
-
|
|
863
|
-
module.exports = Publisher;
|
|
864
|
-
|
|
865
|
-
},{"../util/event_emitter":32,"../util/extend":33}],9:[function(require,module,exports){
|
|
866
|
-
(function (global){
|
|
867
|
-
'use strict';
|
|
868
|
-
|
|
869
|
-
module.exports = {
|
|
870
|
-
addTimeout: function(name, delay, callback, context) {
|
|
871
|
-
this._timeouts = this._timeouts || {};
|
|
872
|
-
if (this._timeouts.hasOwnProperty(name)) return;
|
|
873
|
-
var self = this;
|
|
874
|
-
this._timeouts[name] = global.setTimeout(function() {
|
|
875
|
-
delete self._timeouts[name];
|
|
876
|
-
callback.call(context);
|
|
877
|
-
}, 1000 * delay);
|
|
878
|
-
},
|
|
879
|
-
|
|
880
|
-
removeTimeout: function(name) {
|
|
881
|
-
this._timeouts = this._timeouts || {};
|
|
882
|
-
var timeout = this._timeouts[name];
|
|
883
|
-
if (!timeout) return;
|
|
884
|
-
global.clearTimeout(timeout);
|
|
885
|
-
delete this._timeouts[name];
|
|
886
|
-
},
|
|
887
|
-
|
|
888
|
-
removeAllTimeouts: function() {
|
|
889
|
-
this._timeouts = this._timeouts || {};
|
|
890
|
-
for (var name in this._timeouts) this.removeTimeout(name);
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
|
-
|
|
894
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
895
|
-
|
|
896
|
-
},{}],10:[function(require,module,exports){
|
|
897
|
-
'use strict';
|
|
898
|
-
|
|
899
|
-
var Class = require('../util/class'),
|
|
900
|
-
extend = require('../util/extend'),
|
|
901
|
-
Publisher = require('../mixins/publisher'),
|
|
902
|
-
Grammar = require('./grammar');
|
|
903
|
-
|
|
904
|
-
var Channel = Class({
|
|
905
|
-
initialize: function(name) {
|
|
906
|
-
this.id = this.name = name;
|
|
907
|
-
},
|
|
908
|
-
|
|
909
|
-
push: function(message) {
|
|
910
|
-
this.trigger('message', message);
|
|
911
|
-
},
|
|
912
|
-
|
|
913
|
-
isUnused: function() {
|
|
914
|
-
return this.countListeners('message') === 0;
|
|
915
|
-
}
|
|
916
|
-
});
|
|
917
|
-
|
|
918
|
-
extend(Channel.prototype, Publisher);
|
|
919
|
-
|
|
920
|
-
extend(Channel, {
|
|
921
|
-
HANDSHAKE: '/meta/handshake',
|
|
922
|
-
CONNECT: '/meta/connect',
|
|
923
|
-
SUBSCRIBE: '/meta/subscribe',
|
|
924
|
-
UNSUBSCRIBE: '/meta/unsubscribe',
|
|
925
|
-
DISCONNECT: '/meta/disconnect',
|
|
926
|
-
|
|
927
|
-
META: 'meta',
|
|
928
|
-
SERVICE: 'service',
|
|
929
|
-
|
|
930
|
-
expand: function(name) {
|
|
931
|
-
var segments = this.parse(name),
|
|
932
|
-
channels = ['/**', name];
|
|
933
|
-
|
|
934
|
-
var copy = segments.slice();
|
|
935
|
-
copy[copy.length - 1] = '*';
|
|
936
|
-
channels.push(this.unparse(copy));
|
|
937
|
-
|
|
938
|
-
for (var i = 1, n = segments.length; i < n; i++) {
|
|
939
|
-
copy = segments.slice(0, i);
|
|
940
|
-
copy.push('**');
|
|
941
|
-
channels.push(this.unparse(copy));
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
return channels;
|
|
945
|
-
},
|
|
946
|
-
|
|
947
|
-
isValid: function(name) {
|
|
948
|
-
return Grammar.CHANNEL_NAME.test(name) ||
|
|
949
|
-
Grammar.CHANNEL_PATTERN.test(name);
|
|
950
|
-
},
|
|
951
|
-
|
|
952
|
-
parse: function(name) {
|
|
953
|
-
if (!this.isValid(name)) return null;
|
|
954
|
-
return name.split('/').slice(1);
|
|
955
|
-
},
|
|
956
|
-
|
|
957
|
-
unparse: function(segments) {
|
|
958
|
-
return '/' + segments.join('/');
|
|
959
|
-
},
|
|
960
|
-
|
|
961
|
-
isMeta: function(name) {
|
|
962
|
-
var segments = this.parse(name);
|
|
963
|
-
return segments ? (segments[0] === this.META) : null;
|
|
964
|
-
},
|
|
965
|
-
|
|
966
|
-
isService: function(name) {
|
|
967
|
-
var segments = this.parse(name);
|
|
968
|
-
return segments ? (segments[0] === this.SERVICE) : null;
|
|
969
|
-
},
|
|
970
|
-
|
|
971
|
-
isSubscribable: function(name) {
|
|
972
|
-
if (!this.isValid(name)) return null;
|
|
973
|
-
return !this.isMeta(name) && !this.isService(name);
|
|
974
|
-
},
|
|
975
|
-
|
|
976
|
-
Set: Class({
|
|
977
|
-
initialize: function() {
|
|
978
|
-
this._channels = {};
|
|
979
|
-
},
|
|
980
|
-
|
|
981
|
-
getKeys: function() {
|
|
982
|
-
var keys = [];
|
|
983
|
-
for (var key in this._channels) keys.push(key);
|
|
984
|
-
return keys;
|
|
985
|
-
},
|
|
986
|
-
|
|
987
|
-
remove: function(name) {
|
|
988
|
-
delete this._channels[name];
|
|
989
|
-
},
|
|
990
|
-
|
|
991
|
-
hasSubscription: function(name) {
|
|
992
|
-
return this._channels.hasOwnProperty(name);
|
|
993
|
-
},
|
|
994
|
-
|
|
995
|
-
subscribe: function(names, subscription) {
|
|
996
|
-
var name;
|
|
997
|
-
for (var i = 0, n = names.length; i < n; i++) {
|
|
998
|
-
name = names[i];
|
|
999
|
-
var channel = this._channels[name] = this._channels[name] || new Channel(name);
|
|
1000
|
-
channel.bind('message', subscription);
|
|
1001
|
-
}
|
|
1002
|
-
},
|
|
1003
|
-
|
|
1004
|
-
unsubscribe: function(name, subscription) {
|
|
1005
|
-
var channel = this._channels[name];
|
|
1006
|
-
if (!channel) return false;
|
|
1007
|
-
channel.unbind('message', subscription);
|
|
1008
|
-
|
|
1009
|
-
if (channel.isUnused()) {
|
|
1010
|
-
this.remove(name);
|
|
1011
|
-
return true;
|
|
1012
|
-
} else {
|
|
1013
|
-
return false;
|
|
1014
|
-
}
|
|
1015
|
-
},
|
|
1016
|
-
|
|
1017
|
-
distributeMessage: function(message) {
|
|
1018
|
-
var channels = Channel.expand(message.channel);
|
|
1019
|
-
|
|
1020
|
-
for (var i = 0, n = channels.length; i < n; i++) {
|
|
1021
|
-
var channel = this._channels[channels[i]];
|
|
1022
|
-
if (channel) channel.trigger('message', message);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
})
|
|
1026
|
-
});
|
|
1027
|
-
|
|
1028
|
-
module.exports = Channel;
|
|
1029
|
-
|
|
1030
|
-
},{"../mixins/publisher":8,"../util/class":28,"../util/extend":33,"./grammar":15}],11:[function(require,module,exports){
|
|
1031
|
-
(function (global){
|
|
1032
|
-
'use strict';
|
|
1033
|
-
|
|
1034
|
-
var asap = require('asap'),
|
|
1035
|
-
Class = require('../util/class'),
|
|
1036
|
-
Promise = require('../util/promise'),
|
|
1037
|
-
URI = require('../util/uri'),
|
|
1038
|
-
array = require('../util/array'),
|
|
1039
|
-
browser = require('../util/browser'),
|
|
1040
|
-
constants = require('../util/constants'),
|
|
1041
|
-
extend = require('../util/extend'),
|
|
1042
|
-
validateOptions = require('../util/validate_options'),
|
|
1043
|
-
Deferrable = require('../mixins/deferrable'),
|
|
1044
|
-
Logging = require('../mixins/logging'),
|
|
1045
|
-
Publisher = require('../mixins/publisher'),
|
|
1046
|
-
Channel = require('./channel'),
|
|
1047
|
-
Dispatcher = require('./dispatcher'),
|
|
1048
|
-
Error = require('./error'),
|
|
1049
|
-
Extensible = require('./extensible'),
|
|
1050
|
-
Publication = require('./publication'),
|
|
1051
|
-
Subscription = require('./subscription');
|
|
1052
|
-
|
|
1053
|
-
var Client = Class({ className: 'Client',
|
|
1054
|
-
UNCONNECTED: 1,
|
|
1055
|
-
CONNECTING: 2,
|
|
1056
|
-
CONNECTED: 3,
|
|
1057
|
-
DISCONNECTED: 4,
|
|
1058
|
-
|
|
1059
|
-
HANDSHAKE: 'handshake',
|
|
1060
|
-
RETRY: 'retry',
|
|
1061
|
-
NONE: 'none',
|
|
1062
|
-
|
|
1063
|
-
CONNECTION_TIMEOUT: 60,
|
|
1064
|
-
|
|
1065
|
-
DEFAULT_ENDPOINT: '/bayeux',
|
|
1066
|
-
INTERVAL: 0,
|
|
1067
|
-
|
|
1068
|
-
initialize: function(endpoint, options) {
|
|
1069
|
-
this.info('New client created for ?', endpoint);
|
|
1070
|
-
options = options || {};
|
|
1071
|
-
|
|
1072
|
-
validateOptions(options, ['interval', 'timeout', 'endpoints', 'proxy', 'retry', 'scheduler', 'websocketExtensions', 'tls', 'ca']);
|
|
1073
|
-
|
|
1074
|
-
this._channels = new Channel.Set();
|
|
1075
|
-
this._dispatcher = Dispatcher.create(this, endpoint || this.DEFAULT_ENDPOINT, options);
|
|
1076
|
-
|
|
1077
|
-
this._messageId = 0;
|
|
1078
|
-
this._state = this.UNCONNECTED;
|
|
1079
|
-
|
|
1080
|
-
this._responseCallbacks = {};
|
|
1081
|
-
|
|
1082
|
-
this._advice = {
|
|
1083
|
-
reconnect: this.RETRY,
|
|
1084
|
-
interval: 1000 * (options.interval || this.INTERVAL),
|
|
1085
|
-
timeout: 1000 * (options.timeout || this.CONNECTION_TIMEOUT)
|
|
1086
|
-
};
|
|
1087
|
-
this._dispatcher.timeout = this._advice.timeout / 1000;
|
|
1088
|
-
|
|
1089
|
-
this._dispatcher.bind('message', this._receiveMessage, this);
|
|
1090
|
-
|
|
1091
|
-
if (browser.Event && global.onbeforeunload !== undefined)
|
|
1092
|
-
browser.Event.on(global, 'beforeunload', function() {
|
|
1093
|
-
if (array.indexOf(this._dispatcher._disabled, 'autodisconnect') < 0)
|
|
1094
|
-
this.disconnect();
|
|
1095
|
-
}, this);
|
|
1096
|
-
},
|
|
1097
|
-
|
|
1098
|
-
addWebsocketExtension: function(extension) {
|
|
1099
|
-
return this._dispatcher.addWebsocketExtension(extension);
|
|
1100
|
-
},
|
|
1101
|
-
|
|
1102
|
-
disable: function(feature) {
|
|
1103
|
-
return this._dispatcher.disable(feature);
|
|
1104
|
-
},
|
|
1105
|
-
|
|
1106
|
-
setHeader: function(name, value) {
|
|
1107
|
-
return this._dispatcher.setHeader(name, value);
|
|
1108
|
-
},
|
|
1109
|
-
|
|
1110
|
-
// Request
|
|
1111
|
-
// MUST include: * channel
|
|
1112
|
-
// * version
|
|
1113
|
-
// * supportedConnectionTypes
|
|
1114
|
-
// MAY include: * minimumVersion
|
|
1115
|
-
// * ext
|
|
1116
|
-
// * id
|
|
1117
|
-
//
|
|
1118
|
-
// Success Response Failed Response
|
|
1119
|
-
// MUST include: * channel MUST include: * channel
|
|
1120
|
-
// * version * successful
|
|
1121
|
-
// * supportedConnectionTypes * error
|
|
1122
|
-
// * clientId MAY include: * supportedConnectionTypes
|
|
1123
|
-
// * successful * advice
|
|
1124
|
-
// MAY include: * minimumVersion * version
|
|
1125
|
-
// * advice * minimumVersion
|
|
1126
|
-
// * ext * ext
|
|
1127
|
-
// * id * id
|
|
1128
|
-
// * authSuccessful
|
|
1129
|
-
handshake: function(callback, context) {
|
|
1130
|
-
if (this._advice.reconnect === this.NONE) return;
|
|
1131
|
-
if (this._state !== this.UNCONNECTED) return;
|
|
1132
|
-
|
|
1133
|
-
this._state = this.CONNECTING;
|
|
1134
|
-
var self = this;
|
|
1135
|
-
|
|
1136
|
-
this.info('Initiating handshake with ?', URI.stringify(this._dispatcher.endpoint));
|
|
1137
|
-
this._dispatcher.selectTransport(constants.MANDATORY_CONNECTION_TYPES);
|
|
1138
|
-
|
|
1139
|
-
this._sendMessage({
|
|
1140
|
-
channel: Channel.HANDSHAKE,
|
|
1141
|
-
version: constants.BAYEUX_VERSION,
|
|
1142
|
-
supportedConnectionTypes: this._dispatcher.getConnectionTypes()
|
|
1143
|
-
|
|
1144
|
-
}, {}, function(response) {
|
|
1145
|
-
|
|
1146
|
-
if (response.successful) {
|
|
1147
|
-
this._state = this.CONNECTED;
|
|
1148
|
-
this._dispatcher.clientId = response.clientId;
|
|
1149
|
-
|
|
1150
|
-
this._dispatcher.selectTransport(response.supportedConnectionTypes);
|
|
1151
|
-
|
|
1152
|
-
this.info('Handshake successful: ?', this._dispatcher.clientId);
|
|
1153
|
-
|
|
1154
|
-
this.subscribe(this._channels.getKeys(), true);
|
|
1155
|
-
if (callback) asap(function() { callback.call(context) });
|
|
1156
|
-
|
|
1157
|
-
} else {
|
|
1158
|
-
this.info('Handshake unsuccessful');
|
|
1159
|
-
global.setTimeout(function() { self.handshake(callback, context) }, this._dispatcher.retry * 1000);
|
|
1160
|
-
this._state = this.UNCONNECTED;
|
|
1161
|
-
}
|
|
1162
|
-
}, this);
|
|
1163
|
-
},
|
|
1164
|
-
|
|
1165
|
-
// Request Response
|
|
1166
|
-
// MUST include: * channel MUST include: * channel
|
|
1167
|
-
// * clientId * successful
|
|
1168
|
-
// * connectionType * clientId
|
|
1169
|
-
// MAY include: * ext MAY include: * error
|
|
1170
|
-
// * id * advice
|
|
1171
|
-
// * ext
|
|
1172
|
-
// * id
|
|
1173
|
-
// * timestamp
|
|
1174
|
-
connect: function(callback, context) {
|
|
1175
|
-
if (this._advice.reconnect === this.NONE) return;
|
|
1176
|
-
if (this._state === this.DISCONNECTED) return;
|
|
1177
|
-
|
|
1178
|
-
if (this._state === this.UNCONNECTED)
|
|
1179
|
-
return this.handshake(function() { this.connect(callback, context) }, this);
|
|
1180
|
-
|
|
1181
|
-
this.callback(callback, context);
|
|
1182
|
-
if (this._state !== this.CONNECTED) return;
|
|
1183
|
-
|
|
1184
|
-
this.info('Calling deferred actions for ?', this._dispatcher.clientId);
|
|
1185
|
-
this.setDeferredStatus('succeeded');
|
|
1186
|
-
this.setDeferredStatus('unknown');
|
|
1187
|
-
|
|
1188
|
-
if (this._connectRequest) return;
|
|
1189
|
-
this._connectRequest = true;
|
|
1190
|
-
|
|
1191
|
-
this.info('Initiating connection for ?', this._dispatcher.clientId);
|
|
1192
|
-
|
|
1193
|
-
this._sendMessage({
|
|
1194
|
-
channel: Channel.CONNECT,
|
|
1195
|
-
clientId: this._dispatcher.clientId,
|
|
1196
|
-
connectionType: this._dispatcher.connectionType
|
|
1197
|
-
|
|
1198
|
-
}, {}, this._cycleConnection, this);
|
|
1199
|
-
},
|
|
1200
|
-
|
|
1201
|
-
// Request Response
|
|
1202
|
-
// MUST include: * channel MUST include: * channel
|
|
1203
|
-
// * clientId * successful
|
|
1204
|
-
// MAY include: * ext * clientId
|
|
1205
|
-
// * id MAY include: * error
|
|
1206
|
-
// * ext
|
|
1207
|
-
// * id
|
|
1208
|
-
disconnect: function() {
|
|
1209
|
-
if (this._state !== this.CONNECTED) return;
|
|
1210
|
-
this._state = this.DISCONNECTED;
|
|
1211
|
-
|
|
1212
|
-
this.info('Disconnecting ?', this._dispatcher.clientId);
|
|
1213
|
-
var promise = new Publication();
|
|
1214
|
-
|
|
1215
|
-
this._sendMessage({
|
|
1216
|
-
channel: Channel.DISCONNECT,
|
|
1217
|
-
clientId: this._dispatcher.clientId
|
|
1218
|
-
|
|
1219
|
-
}, {}, function(response) {
|
|
1220
|
-
if (response.successful) {
|
|
1221
|
-
this._dispatcher.close();
|
|
1222
|
-
promise.setDeferredStatus('succeeded');
|
|
1223
|
-
} else {
|
|
1224
|
-
promise.setDeferredStatus('failed', Error.parse(response.error));
|
|
1225
|
-
}
|
|
1226
|
-
}, this);
|
|
1227
|
-
|
|
1228
|
-
this.info('Clearing channel listeners for ?', this._dispatcher.clientId);
|
|
1229
|
-
this._channels = new Channel.Set();
|
|
1230
|
-
|
|
1231
|
-
return promise;
|
|
1232
|
-
},
|
|
1233
|
-
|
|
1234
|
-
// Request Response
|
|
1235
|
-
// MUST include: * channel MUST include: * channel
|
|
1236
|
-
// * clientId * successful
|
|
1237
|
-
// * subscription * clientId
|
|
1238
|
-
// MAY include: * ext * subscription
|
|
1239
|
-
// * id MAY include: * error
|
|
1240
|
-
// * advice
|
|
1241
|
-
// * ext
|
|
1242
|
-
// * id
|
|
1243
|
-
// * timestamp
|
|
1244
|
-
subscribe: function(channel, callback, context) {
|
|
1245
|
-
if (channel instanceof Array)
|
|
1246
|
-
return array.map(channel, function(c) {
|
|
1247
|
-
return this.subscribe(c, callback, context);
|
|
1248
|
-
}, this);
|
|
1249
|
-
|
|
1250
|
-
var subscription = new Subscription(this, channel, callback, context),
|
|
1251
|
-
force = (callback === true),
|
|
1252
|
-
hasSubscribe = this._channels.hasSubscription(channel);
|
|
1253
|
-
|
|
1254
|
-
if (hasSubscribe && !force) {
|
|
1255
|
-
this._channels.subscribe([channel], subscription);
|
|
1256
|
-
subscription.setDeferredStatus('succeeded');
|
|
1257
|
-
return subscription;
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
this.connect(function() {
|
|
1261
|
-
this.info('Client ? attempting to subscribe to ?', this._dispatcher.clientId, channel);
|
|
1262
|
-
if (!force) this._channels.subscribe([channel], subscription);
|
|
1263
|
-
|
|
1264
|
-
this._sendMessage({
|
|
1265
|
-
channel: Channel.SUBSCRIBE,
|
|
1266
|
-
clientId: this._dispatcher.clientId,
|
|
1267
|
-
subscription: channel
|
|
1268
|
-
|
|
1269
|
-
}, {}, function(response) {
|
|
1270
|
-
if (!response.successful) {
|
|
1271
|
-
subscription.setDeferredStatus('failed', Error.parse(response.error));
|
|
1272
|
-
return this._channels.unsubscribe(channel, subscription);
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
var channels = [].concat(response.subscription);
|
|
1276
|
-
this.info('Subscription acknowledged for ? to ?', this._dispatcher.clientId, channels);
|
|
1277
|
-
subscription.setDeferredStatus('succeeded');
|
|
1278
|
-
}, this);
|
|
1279
|
-
}, this);
|
|
1280
|
-
|
|
1281
|
-
return subscription;
|
|
1282
|
-
},
|
|
1283
|
-
|
|
1284
|
-
// Request Response
|
|
1285
|
-
// MUST include: * channel MUST include: * channel
|
|
1286
|
-
// * clientId * successful
|
|
1287
|
-
// * subscription * clientId
|
|
1288
|
-
// MAY include: * ext * subscription
|
|
1289
|
-
// * id MAY include: * error
|
|
1290
|
-
// * advice
|
|
1291
|
-
// * ext
|
|
1292
|
-
// * id
|
|
1293
|
-
// * timestamp
|
|
1294
|
-
unsubscribe: function(channel, subscription) {
|
|
1295
|
-
if (channel instanceof Array)
|
|
1296
|
-
return array.map(channel, function(c) {
|
|
1297
|
-
return this.unsubscribe(c, subscription);
|
|
1298
|
-
}, this);
|
|
1299
|
-
|
|
1300
|
-
var dead = this._channels.unsubscribe(channel, subscription);
|
|
1301
|
-
if (!dead) return;
|
|
1302
|
-
|
|
1303
|
-
this.connect(function() {
|
|
1304
|
-
this.info('Client ? attempting to unsubscribe from ?', this._dispatcher.clientId, channel);
|
|
1305
|
-
|
|
1306
|
-
this._sendMessage({
|
|
1307
|
-
channel: Channel.UNSUBSCRIBE,
|
|
1308
|
-
clientId: this._dispatcher.clientId,
|
|
1309
|
-
subscription: channel
|
|
1310
|
-
|
|
1311
|
-
}, {}, function(response) {
|
|
1312
|
-
if (!response.successful) return;
|
|
1313
|
-
|
|
1314
|
-
var channels = [].concat(response.subscription);
|
|
1315
|
-
this.info('Unsubscription acknowledged for ? from ?', this._dispatcher.clientId, channels);
|
|
1316
|
-
}, this);
|
|
1317
|
-
}, this);
|
|
1318
|
-
},
|
|
1319
|
-
|
|
1320
|
-
// Request Response
|
|
1321
|
-
// MUST include: * channel MUST include: * channel
|
|
1322
|
-
// * data * successful
|
|
1323
|
-
// MAY include: * clientId MAY include: * id
|
|
1324
|
-
// * id * error
|
|
1325
|
-
// * ext * ext
|
|
1326
|
-
publish: function(channel, data, options) {
|
|
1327
|
-
validateOptions(options || {}, ['attempts', 'deadline']);
|
|
1328
|
-
var publication = new Publication();
|
|
1329
|
-
|
|
1330
|
-
this.connect(function() {
|
|
1331
|
-
this.info('Client ? queueing published message to ?: ?', this._dispatcher.clientId, channel, data);
|
|
1332
|
-
|
|
1333
|
-
this._sendMessage({
|
|
1334
|
-
channel: channel,
|
|
1335
|
-
data: data,
|
|
1336
|
-
clientId: this._dispatcher.clientId
|
|
1337
|
-
|
|
1338
|
-
}, options, function(response) {
|
|
1339
|
-
if (response.successful)
|
|
1340
|
-
publication.setDeferredStatus('succeeded');
|
|
1341
|
-
else
|
|
1342
|
-
publication.setDeferredStatus('failed', Error.parse(response.error));
|
|
1343
|
-
}, this);
|
|
1344
|
-
}, this);
|
|
1345
|
-
|
|
1346
|
-
return publication;
|
|
1347
|
-
},
|
|
1348
|
-
|
|
1349
|
-
_sendMessage: function(message, options, callback, context) {
|
|
1350
|
-
message.id = this._generateMessageId();
|
|
1351
|
-
|
|
1352
|
-
var timeout = this._advice.timeout
|
|
1353
|
-
? 1.2 * this._advice.timeout / 1000
|
|
1354
|
-
: 1.2 * this._dispatcher.retry;
|
|
1355
|
-
|
|
1356
|
-
this.pipeThroughExtensions('outgoing', message, null, function(message) {
|
|
1357
|
-
if (!message) return;
|
|
1358
|
-
if (callback) this._responseCallbacks[message.id] = [callback, context];
|
|
1359
|
-
this._dispatcher.sendMessage(message, timeout, options || {});
|
|
1360
|
-
}, this);
|
|
1361
|
-
},
|
|
1362
|
-
|
|
1363
|
-
_generateMessageId: function() {
|
|
1364
|
-
this._messageId += 1;
|
|
1365
|
-
if (this._messageId >= Math.pow(2,32)) this._messageId = 0;
|
|
1366
|
-
return this._messageId.toString(36);
|
|
1367
|
-
},
|
|
1368
|
-
|
|
1369
|
-
_receiveMessage: function(message) {
|
|
1370
|
-
var id = message.id, callback;
|
|
1371
|
-
|
|
1372
|
-
if (message.successful !== undefined) {
|
|
1373
|
-
callback = this._responseCallbacks[id];
|
|
1374
|
-
delete this._responseCallbacks[id];
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
this.pipeThroughExtensions('incoming', message, null, function(message) {
|
|
1378
|
-
if (!message) return;
|
|
1379
|
-
if (message.advice) this._handleAdvice(message.advice);
|
|
1380
|
-
this._deliverMessage(message);
|
|
1381
|
-
if (callback) callback[0].call(callback[1], message);
|
|
1382
|
-
}, this);
|
|
1383
|
-
},
|
|
1384
|
-
|
|
1385
|
-
_handleAdvice: function(advice) {
|
|
1386
|
-
extend(this._advice, advice);
|
|
1387
|
-
this._dispatcher.timeout = this._advice.timeout / 1000;
|
|
1388
|
-
|
|
1389
|
-
if (this._advice.reconnect === this.HANDSHAKE && this._state !== this.DISCONNECTED) {
|
|
1390
|
-
this._state = this.UNCONNECTED;
|
|
1391
|
-
this._dispatcher.clientId = null;
|
|
1392
|
-
this._cycleConnection();
|
|
1393
|
-
}
|
|
1394
|
-
},
|
|
1395
|
-
|
|
1396
|
-
_deliverMessage: function(message) {
|
|
1397
|
-
if (!message.channel || message.data === undefined) return;
|
|
1398
|
-
this.info('Client ? calling listeners for ? with ?', this._dispatcher.clientId, message.channel, message.data);
|
|
1399
|
-
this._channels.distributeMessage(message);
|
|
1400
|
-
},
|
|
1401
|
-
|
|
1402
|
-
_cycleConnection: function() {
|
|
1403
|
-
if (this._connectRequest) {
|
|
1404
|
-
this._connectRequest = null;
|
|
1405
|
-
this.info('Closed connection for ?', this._dispatcher.clientId);
|
|
1406
|
-
}
|
|
1407
|
-
var self = this;
|
|
1408
|
-
global.setTimeout(function() { self.connect() }, this._advice.interval);
|
|
1409
|
-
}
|
|
1410
|
-
});
|
|
1411
|
-
|
|
1412
|
-
extend(Client.prototype, Deferrable);
|
|
1413
|
-
extend(Client.prototype, Publisher);
|
|
1414
|
-
extend(Client.prototype, Logging);
|
|
1415
|
-
extend(Client.prototype, Extensible);
|
|
1416
|
-
|
|
1417
|
-
module.exports = Client;
|
|
1418
|
-
|
|
1419
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
1420
|
-
|
|
1421
|
-
},{"../mixins/deferrable":6,"../mixins/logging":7,"../mixins/publisher":8,"../util/array":26,"../util/browser":27,"../util/class":28,"../util/constants":29,"../util/extend":33,"../util/promise":34,"../util/uri":37,"../util/validate_options":38,"./channel":10,"./dispatcher":12,"./error":13,"./extensible":14,"./publication":16,"./subscription":18,"asap":3}],12:[function(require,module,exports){
|
|
1422
|
-
(function (global){
|
|
1423
|
-
'use strict';
|
|
1424
|
-
|
|
1425
|
-
var Class = require('../util/class'),
|
|
1426
|
-
URI = require('../util/uri'),
|
|
1427
|
-
cookies = require('../util/cookies'),
|
|
1428
|
-
extend = require('../util/extend'),
|
|
1429
|
-
Logging = require('../mixins/logging'),
|
|
1430
|
-
Publisher = require('../mixins/publisher'),
|
|
1431
|
-
Transport = require('../transport'),
|
|
1432
|
-
Scheduler = require('./scheduler');
|
|
1433
|
-
|
|
1434
|
-
var Dispatcher = Class({ className: 'Dispatcher',
|
|
1435
|
-
MAX_REQUEST_SIZE: 2048,
|
|
1436
|
-
DEFAULT_RETRY: 5,
|
|
1437
|
-
|
|
1438
|
-
UP: 1,
|
|
1439
|
-
DOWN: 2,
|
|
1440
|
-
|
|
1441
|
-
initialize: function(client, endpoint, options) {
|
|
1442
|
-
this._client = client;
|
|
1443
|
-
this.endpoint = URI.parse(endpoint);
|
|
1444
|
-
this._alternates = options.endpoints || {};
|
|
1445
|
-
|
|
1446
|
-
this.cookies = cookies.CookieJar && new cookies.CookieJar();
|
|
1447
|
-
this._disabled = [];
|
|
1448
|
-
this._envelopes = {};
|
|
1449
|
-
this.headers = {};
|
|
1450
|
-
this.retry = options.retry || this.DEFAULT_RETRY;
|
|
1451
|
-
this._scheduler = options.scheduler || Scheduler;
|
|
1452
|
-
this._state = 0;
|
|
1453
|
-
this.transports = {};
|
|
1454
|
-
this.wsExtensions = [];
|
|
1455
|
-
|
|
1456
|
-
this.proxy = options.proxy || {};
|
|
1457
|
-
if (typeof this._proxy === 'string') this._proxy = {origin: this._proxy};
|
|
1458
|
-
|
|
1459
|
-
var exts = options.websocketExtensions;
|
|
1460
|
-
if (exts) {
|
|
1461
|
-
exts = [].concat(exts);
|
|
1462
|
-
for (var i = 0, n = exts.length; i < n; i++)
|
|
1463
|
-
this.addWebsocketExtension(exts[i]);
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
this.tls = options.tls || {};
|
|
1467
|
-
this.tls.ca = this.tls.ca || options.ca;
|
|
1468
|
-
|
|
1469
|
-
for (var type in this._alternates)
|
|
1470
|
-
this._alternates[type] = URI.parse(this._alternates[type]);
|
|
1471
|
-
|
|
1472
|
-
this.maxRequestSize = this.MAX_REQUEST_SIZE;
|
|
1473
|
-
},
|
|
1474
|
-
|
|
1475
|
-
endpointFor: function(connectionType) {
|
|
1476
|
-
return this._alternates[connectionType] || this.endpoint;
|
|
1477
|
-
},
|
|
1478
|
-
|
|
1479
|
-
addWebsocketExtension: function(extension) {
|
|
1480
|
-
this.wsExtensions.push(extension);
|
|
1481
|
-
},
|
|
1482
|
-
|
|
1483
|
-
disable: function(feature) {
|
|
1484
|
-
this._disabled.push(feature);
|
|
1485
|
-
},
|
|
1486
|
-
|
|
1487
|
-
setHeader: function(name, value) {
|
|
1488
|
-
this.headers[name] = value;
|
|
1489
|
-
},
|
|
1490
|
-
|
|
1491
|
-
close: function() {
|
|
1492
|
-
var transport = this._transport;
|
|
1493
|
-
delete this._transport;
|
|
1494
|
-
if (transport) transport.close();
|
|
1495
|
-
},
|
|
1496
|
-
|
|
1497
|
-
getConnectionTypes: function() {
|
|
1498
|
-
return Transport.getConnectionTypes();
|
|
1499
|
-
},
|
|
1500
|
-
|
|
1501
|
-
selectTransport: function(transportTypes) {
|
|
1502
|
-
Transport.get(this, transportTypes, this._disabled, function(transport) {
|
|
1503
|
-
this.debug('Selected ? transport for ?', transport.connectionType, URI.stringify(transport.endpoint));
|
|
1504
|
-
|
|
1505
|
-
if (transport === this._transport) return;
|
|
1506
|
-
if (this._transport) this._transport.close();
|
|
1507
|
-
|
|
1508
|
-
this._transport = transport;
|
|
1509
|
-
this.connectionType = transport.connectionType;
|
|
1510
|
-
}, this);
|
|
1511
|
-
},
|
|
1512
|
-
|
|
1513
|
-
sendMessage: function(message, timeout, options) {
|
|
1514
|
-
options = options || {};
|
|
1515
|
-
|
|
1516
|
-
var id = message.id,
|
|
1517
|
-
attempts = options.attempts,
|
|
1518
|
-
deadline = options.deadline && new Date().getTime() + (options.deadline * 1000),
|
|
1519
|
-
envelope = this._envelopes[id],
|
|
1520
|
-
scheduler;
|
|
1521
|
-
|
|
1522
|
-
if (!envelope) {
|
|
1523
|
-
scheduler = new this._scheduler(message, {timeout: timeout, interval: this.retry, attempts: attempts, deadline: deadline});
|
|
1524
|
-
envelope = this._envelopes[id] = {message: message, scheduler: scheduler};
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
this._sendEnvelope(envelope);
|
|
1528
|
-
},
|
|
1529
|
-
|
|
1530
|
-
_sendEnvelope: function(envelope) {
|
|
1531
|
-
if (!this._transport) return;
|
|
1532
|
-
if (envelope.request || envelope.timer) return;
|
|
1533
|
-
|
|
1534
|
-
var message = envelope.message,
|
|
1535
|
-
scheduler = envelope.scheduler,
|
|
1536
|
-
self = this;
|
|
1537
|
-
|
|
1538
|
-
if (!scheduler.isDeliverable()) {
|
|
1539
|
-
scheduler.abort();
|
|
1540
|
-
delete this._envelopes[message.id];
|
|
1541
|
-
return;
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1544
|
-
envelope.timer = global.setTimeout(function() {
|
|
1545
|
-
self.handleError(message);
|
|
1546
|
-
}, scheduler.getTimeout() * 1000);
|
|
1547
|
-
|
|
1548
|
-
scheduler.send();
|
|
1549
|
-
envelope.request = this._transport.sendMessage(message);
|
|
1550
|
-
},
|
|
1551
|
-
|
|
1552
|
-
handleResponse: function(reply) {
|
|
1553
|
-
var envelope = this._envelopes[reply.id];
|
|
1554
|
-
|
|
1555
|
-
if (reply.successful !== undefined && envelope) {
|
|
1556
|
-
envelope.scheduler.succeed();
|
|
1557
|
-
delete this._envelopes[reply.id];
|
|
1558
|
-
global.clearTimeout(envelope.timer);
|
|
1559
|
-
}
|
|
1560
|
-
|
|
1561
|
-
this.trigger('message', reply);
|
|
1562
|
-
|
|
1563
|
-
if (this._state === this.UP) return;
|
|
1564
|
-
this._state = this.UP;
|
|
1565
|
-
this._client.trigger('transport:up');
|
|
1566
|
-
},
|
|
1567
|
-
|
|
1568
|
-
handleError: function(message, immediate) {
|
|
1569
|
-
var envelope = this._envelopes[message.id],
|
|
1570
|
-
request = envelope && envelope.request,
|
|
1571
|
-
self = this;
|
|
1572
|
-
|
|
1573
|
-
if (!request) return;
|
|
1574
|
-
|
|
1575
|
-
request.then(function(req) {
|
|
1576
|
-
if (req && req.abort) req.abort();
|
|
1577
|
-
});
|
|
1578
|
-
|
|
1579
|
-
var scheduler = envelope.scheduler;
|
|
1580
|
-
scheduler.fail();
|
|
1581
|
-
|
|
1582
|
-
global.clearTimeout(envelope.timer);
|
|
1583
|
-
envelope.request = envelope.timer = null;
|
|
1584
|
-
|
|
1585
|
-
if (immediate) {
|
|
1586
|
-
this._sendEnvelope(envelope);
|
|
1587
|
-
} else {
|
|
1588
|
-
envelope.timer = global.setTimeout(function() {
|
|
1589
|
-
envelope.timer = null;
|
|
1590
|
-
self._sendEnvelope(envelope);
|
|
1591
|
-
}, scheduler.getInterval() * 1000);
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
if (this._state === this.DOWN) return;
|
|
1595
|
-
this._state = this.DOWN;
|
|
1596
|
-
this._client.trigger('transport:down');
|
|
1597
|
-
}
|
|
1598
|
-
});
|
|
1599
|
-
|
|
1600
|
-
Dispatcher.create = function(client, endpoint, options) {
|
|
1601
|
-
return new Dispatcher(client, endpoint, options);
|
|
1602
|
-
};
|
|
1603
|
-
|
|
1604
|
-
extend(Dispatcher.prototype, Publisher);
|
|
1605
|
-
extend(Dispatcher.prototype, Logging);
|
|
1606
|
-
|
|
1607
|
-
module.exports = Dispatcher;
|
|
1608
|
-
|
|
1609
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
1610
|
-
|
|
1611
|
-
},{"../mixins/logging":7,"../mixins/publisher":8,"../transport":19,"../util/class":28,"../util/cookies":30,"../util/extend":33,"../util/uri":37,"./scheduler":17}],13:[function(require,module,exports){
|
|
1612
|
-
'use strict';
|
|
1613
|
-
|
|
1614
|
-
var Class = require('../util/class'),
|
|
1615
|
-
Grammar = require('./grammar');
|
|
1616
|
-
|
|
1617
|
-
var Error = Class({
|
|
1618
|
-
initialize: function(code, params, message) {
|
|
1619
|
-
this.code = code;
|
|
1620
|
-
this.params = Array.prototype.slice.call(params);
|
|
1621
|
-
this.message = message;
|
|
1622
|
-
},
|
|
1623
|
-
|
|
1624
|
-
toString: function() {
|
|
1625
|
-
return this.code + ':' +
|
|
1626
|
-
this.params.join(',') + ':' +
|
|
1627
|
-
this.message;
|
|
1628
|
-
}
|
|
1629
|
-
});
|
|
1630
|
-
|
|
1631
|
-
Error.parse = function(message) {
|
|
1632
|
-
message = message || '';
|
|
1633
|
-
if (!Grammar.ERROR.test(message)) return new Error(null, [], message);
|
|
1634
|
-
|
|
1635
|
-
var parts = message.split(':'),
|
|
1636
|
-
code = parseInt(parts[0]),
|
|
1637
|
-
params = parts[1].split(','),
|
|
1638
|
-
message = parts[2];
|
|
1639
|
-
|
|
1640
|
-
return new Error(code, params, message);
|
|
1641
|
-
};
|
|
1642
|
-
|
|
1643
|
-
// http://code.google.com/p/cometd/wiki/BayeuxCodes
|
|
1644
|
-
var errors = {
|
|
1645
|
-
versionMismatch: [300, 'Version mismatch'],
|
|
1646
|
-
conntypeMismatch: [301, 'Connection types not supported'],
|
|
1647
|
-
extMismatch: [302, 'Extension mismatch'],
|
|
1648
|
-
badRequest: [400, 'Bad request'],
|
|
1649
|
-
clientUnknown: [401, 'Unknown client'],
|
|
1650
|
-
parameterMissing: [402, 'Missing required parameter'],
|
|
1651
|
-
channelForbidden: [403, 'Forbidden channel'],
|
|
1652
|
-
channelUnknown: [404, 'Unknown channel'],
|
|
1653
|
-
channelInvalid: [405, 'Invalid channel'],
|
|
1654
|
-
extUnknown: [406, 'Unknown extension'],
|
|
1655
|
-
publishFailed: [407, 'Failed to publish'],
|
|
1656
|
-
serverError: [500, 'Internal server error']
|
|
1657
|
-
};
|
|
1658
|
-
|
|
1659
|
-
for (var name in errors)
|
|
1660
|
-
(function(name) {
|
|
1661
|
-
Error[name] = function() {
|
|
1662
|
-
return new Error(errors[name][0], arguments, errors[name][1]).toString();
|
|
1663
|
-
};
|
|
1664
|
-
})(name);
|
|
1665
|
-
|
|
1666
|
-
module.exports = Error;
|
|
1667
|
-
|
|
1668
|
-
},{"../util/class":28,"./grammar":15}],14:[function(require,module,exports){
|
|
1669
|
-
'use strict';
|
|
1670
|
-
|
|
1671
|
-
var extend = require('../util/extend'),
|
|
1672
|
-
Logging = require('../mixins/logging');
|
|
1673
|
-
|
|
1674
|
-
var Extensible = {
|
|
1675
|
-
addExtension: function(extension) {
|
|
1676
|
-
this._extensions = this._extensions || [];
|
|
1677
|
-
this._extensions.push(extension);
|
|
1678
|
-
if (extension.added) extension.added(this);
|
|
1679
|
-
},
|
|
1680
|
-
|
|
1681
|
-
removeExtension: function(extension) {
|
|
1682
|
-
if (!this._extensions) return;
|
|
1683
|
-
var i = this._extensions.length;
|
|
1684
|
-
while (i--) {
|
|
1685
|
-
if (this._extensions[i] !== extension) continue;
|
|
1686
|
-
this._extensions.splice(i,1);
|
|
1687
|
-
if (extension.removed) extension.removed(this);
|
|
1688
|
-
}
|
|
1689
|
-
},
|
|
1690
|
-
|
|
1691
|
-
pipeThroughExtensions: function(stage, message, request, callback, context) {
|
|
1692
|
-
this.debug('Passing through ? extensions: ?', stage, message);
|
|
1693
|
-
|
|
1694
|
-
if (!this._extensions) return callback.call(context, message);
|
|
1695
|
-
var extensions = this._extensions.slice();
|
|
1696
|
-
|
|
1697
|
-
var pipe = function(message) {
|
|
1698
|
-
if (!message) return callback.call(context, message);
|
|
1699
|
-
|
|
1700
|
-
var extension = extensions.shift();
|
|
1701
|
-
if (!extension) return callback.call(context, message);
|
|
1702
|
-
|
|
1703
|
-
var fn = extension[stage];
|
|
1704
|
-
if (!fn) return pipe(message);
|
|
1705
|
-
|
|
1706
|
-
if (fn.length >= 3) extension[stage](message, request, pipe);
|
|
1707
|
-
else extension[stage](message, pipe);
|
|
1708
|
-
};
|
|
1709
|
-
pipe(message);
|
|
1710
|
-
}
|
|
1711
|
-
};
|
|
1712
|
-
|
|
1713
|
-
extend(Extensible, Logging);
|
|
1714
|
-
|
|
1715
|
-
module.exports = Extensible;
|
|
1716
|
-
|
|
1717
|
-
},{"../mixins/logging":7,"../util/extend":33}],15:[function(require,module,exports){
|
|
1718
|
-
'use strict';
|
|
1719
|
-
|
|
1720
|
-
module.exports = {
|
|
1721
|
-
CHANNEL_NAME: /^\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$/,
|
|
1722
|
-
CHANNEL_PATTERN: /^(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*\/\*{1,2}$/,
|
|
1723
|
-
ERROR: /^([0-9][0-9][0-9]:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*(,(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)*:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*|[0-9][0-9][0-9]::(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)$/,
|
|
1724
|
-
VERSION: /^([0-9])+(\.(([a-z]|[A-Z])|[0-9])(((([a-z]|[A-Z])|[0-9])|\-|\_))*)*$/
|
|
1725
|
-
};
|
|
1726
|
-
|
|
1727
|
-
},{}],16:[function(require,module,exports){
|
|
1728
|
-
'use strict';
|
|
1729
|
-
|
|
1730
|
-
var Class = require('../util/class'),
|
|
1731
|
-
Deferrable = require('../mixins/deferrable');
|
|
1732
|
-
|
|
1733
|
-
module.exports = Class(Deferrable);
|
|
1734
|
-
|
|
1735
|
-
},{"../mixins/deferrable":6,"../util/class":28}],17:[function(require,module,exports){
|
|
1736
|
-
'use strict';
|
|
1737
|
-
|
|
1738
|
-
var extend = require('../util/extend');
|
|
1739
|
-
|
|
1740
|
-
var Scheduler = function(message, options) {
|
|
1741
|
-
this.message = message;
|
|
1742
|
-
this.options = options;
|
|
1743
|
-
this.attempts = 0;
|
|
1744
|
-
};
|
|
1745
|
-
|
|
1746
|
-
extend(Scheduler.prototype, {
|
|
1747
|
-
getTimeout: function() {
|
|
1748
|
-
return this.options.timeout;
|
|
1749
|
-
},
|
|
1750
|
-
|
|
1751
|
-
getInterval: function() {
|
|
1752
|
-
return this.options.interval;
|
|
1753
|
-
},
|
|
1754
|
-
|
|
1755
|
-
isDeliverable: function() {
|
|
1756
|
-
var attempts = this.options.attempts,
|
|
1757
|
-
made = this.attempts,
|
|
1758
|
-
deadline = this.options.deadline,
|
|
1759
|
-
now = new Date().getTime();
|
|
1760
|
-
|
|
1761
|
-
if (attempts !== undefined && made >= attempts)
|
|
1762
|
-
return false;
|
|
1763
|
-
|
|
1764
|
-
if (deadline !== undefined && now > deadline)
|
|
1765
|
-
return false;
|
|
1766
|
-
|
|
1767
|
-
return true;
|
|
1768
|
-
},
|
|
1769
|
-
|
|
1770
|
-
send: function() {
|
|
1771
|
-
this.attempts += 1;
|
|
1772
|
-
},
|
|
1773
|
-
|
|
1774
|
-
succeed: function() {},
|
|
1775
|
-
|
|
1776
|
-
fail: function() {},
|
|
1777
|
-
|
|
1778
|
-
abort: function() {}
|
|
1779
|
-
});
|
|
1780
|
-
|
|
1781
|
-
module.exports = Scheduler;
|
|
1782
|
-
|
|
1783
|
-
},{"../util/extend":33}],18:[function(require,module,exports){
|
|
1784
|
-
'use strict';
|
|
1785
|
-
|
|
1786
|
-
var Class = require('../util/class'),
|
|
1787
|
-
extend = require('../util/extend'),
|
|
1788
|
-
Deferrable = require('../mixins/deferrable');
|
|
1789
|
-
|
|
1790
|
-
var Subscription = Class({
|
|
1791
|
-
initialize: function(client, channels, callback, context) {
|
|
1792
|
-
this._client = client;
|
|
1793
|
-
this._channels = channels;
|
|
1794
|
-
this._callback = callback;
|
|
1795
|
-
this._context = context;
|
|
1796
|
-
this._cancelled = false;
|
|
1797
|
-
},
|
|
1798
|
-
|
|
1799
|
-
withChannel: function(callback, context) {
|
|
1800
|
-
this._withChannel = [callback, context];
|
|
1801
|
-
return this;
|
|
1802
|
-
},
|
|
1803
|
-
|
|
1804
|
-
apply: function(context, args) {
|
|
1805
|
-
var message = args[0];
|
|
1806
|
-
|
|
1807
|
-
if (this._callback)
|
|
1808
|
-
this._callback.call(this._context, message.data);
|
|
1809
|
-
|
|
1810
|
-
if (this._withChannel)
|
|
1811
|
-
this._withChannel[0].call(this._withChannel[1], message.channel, message.data);
|
|
1812
|
-
},
|
|
1813
|
-
|
|
1814
|
-
cancel: function() {
|
|
1815
|
-
if (this._cancelled) return;
|
|
1816
|
-
this._client.unsubscribe(this._channels, this);
|
|
1817
|
-
this._cancelled = true;
|
|
1818
|
-
},
|
|
1819
|
-
|
|
1820
|
-
unsubscribe: function() {
|
|
1821
|
-
this.cancel();
|
|
1822
|
-
}
|
|
1823
|
-
});
|
|
1824
|
-
|
|
1825
|
-
extend(Subscription.prototype, Deferrable);
|
|
1826
|
-
|
|
1827
|
-
module.exports = Subscription;
|
|
1828
|
-
|
|
1829
|
-
},{"../mixins/deferrable":6,"../util/class":28,"../util/extend":33}],19:[function(require,module,exports){
|
|
1830
|
-
'use strict';
|
|
1831
|
-
|
|
1832
|
-
var Transport = require('./transport');
|
|
1833
|
-
|
|
1834
|
-
Transport.register('websocket', require('./web_socket'));
|
|
1835
|
-
Transport.register('eventsource', require('./event_source'));
|
|
1836
|
-
Transport.register('long-polling', require('./xhr'));
|
|
1837
|
-
Transport.register('cross-origin-long-polling', require('./cors'));
|
|
1838
|
-
Transport.register('callback-polling', require('./jsonp'));
|
|
1839
|
-
|
|
1840
|
-
module.exports = Transport;
|
|
1841
|
-
|
|
1842
|
-
},{"./cors":20,"./event_source":21,"./jsonp":22,"./transport":23,"./web_socket":24,"./xhr":25}],20:[function(require,module,exports){
|
|
1843
|
-
(function (global){
|
|
1844
|
-
'use strict';
|
|
1845
|
-
|
|
1846
|
-
var Class = require('../util/class'),
|
|
1847
|
-
Set = require('../util/set'),
|
|
1848
|
-
URI = require('../util/uri'),
|
|
1849
|
-
extend = require('../util/extend'),
|
|
1850
|
-
toJSON = require('../util/to_json'),
|
|
1851
|
-
Transport = require('./transport');
|
|
1852
|
-
|
|
1853
|
-
var CORS = extend(Class(Transport, {
|
|
1854
|
-
encode: function(messages) {
|
|
1855
|
-
return 'message=' + encodeURIComponent(toJSON(messages));
|
|
1856
|
-
},
|
|
1857
|
-
|
|
1858
|
-
request: function(messages) {
|
|
1859
|
-
var xhrClass = global.XDomainRequest ? XDomainRequest : XMLHttpRequest,
|
|
1860
|
-
xhr = new xhrClass(),
|
|
1861
|
-
id = ++CORS._id,
|
|
1862
|
-
headers = this._dispatcher.headers,
|
|
1863
|
-
self = this,
|
|
1864
|
-
key;
|
|
1865
|
-
|
|
1866
|
-
xhr.open('POST', URI.stringify(this.endpoint), true);
|
|
1867
|
-
|
|
1868
|
-
if (xhr.setRequestHeader) {
|
|
1869
|
-
xhr.setRequestHeader('Pragma', 'no-cache');
|
|
1870
|
-
for (key in headers) {
|
|
1871
|
-
if (!headers.hasOwnProperty(key)) continue;
|
|
1872
|
-
xhr.setRequestHeader(key, headers[key]);
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
var cleanUp = function() {
|
|
1877
|
-
if (!xhr) return false;
|
|
1878
|
-
CORS._pending.remove(id);
|
|
1879
|
-
xhr.onload = xhr.onerror = xhr.ontimeout = xhr.onprogress = null;
|
|
1880
|
-
xhr = null;
|
|
1881
|
-
};
|
|
1882
|
-
|
|
1883
|
-
xhr.onload = function() {
|
|
1884
|
-
var replies;
|
|
1885
|
-
try { replies = JSON.parse(xhr.responseText) } catch (error) {}
|
|
1886
|
-
|
|
1887
|
-
cleanUp();
|
|
1888
|
-
|
|
1889
|
-
if (replies)
|
|
1890
|
-
self._receive(replies);
|
|
1891
|
-
else
|
|
1892
|
-
self._handleError(messages);
|
|
1893
|
-
};
|
|
1894
|
-
|
|
1895
|
-
xhr.onerror = xhr.ontimeout = function() {
|
|
1896
|
-
cleanUp();
|
|
1897
|
-
self._handleError(messages);
|
|
1898
|
-
};
|
|
1899
|
-
|
|
1900
|
-
xhr.onprogress = function() {};
|
|
1901
|
-
|
|
1902
|
-
if (xhrClass === global.XDomainRequest)
|
|
1903
|
-
CORS._pending.add({id: id, xhr: xhr});
|
|
1904
|
-
|
|
1905
|
-
xhr.send(this.encode(messages));
|
|
1906
|
-
return xhr;
|
|
1907
|
-
}
|
|
1908
|
-
}), {
|
|
1909
|
-
_id: 0,
|
|
1910
|
-
_pending: new Set(),
|
|
1911
|
-
|
|
1912
|
-
isUsable: function(dispatcher, endpoint, callback, context) {
|
|
1913
|
-
if (URI.isSameOrigin(endpoint))
|
|
1914
|
-
return callback.call(context, false);
|
|
1915
|
-
|
|
1916
|
-
if (global.XDomainRequest)
|
|
1917
|
-
return callback.call(context, endpoint.protocol === location.protocol);
|
|
1918
|
-
|
|
1919
|
-
if (global.XMLHttpRequest) {
|
|
1920
|
-
var xhr = new XMLHttpRequest();
|
|
1921
|
-
return callback.call(context, xhr.withCredentials !== undefined);
|
|
1922
|
-
}
|
|
1923
|
-
return callback.call(context, false);
|
|
1924
|
-
}
|
|
1925
|
-
});
|
|
1926
|
-
|
|
1927
|
-
module.exports = CORS;
|
|
1928
|
-
|
|
1929
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
1930
|
-
|
|
1931
|
-
},{"../util/class":28,"../util/extend":33,"../util/set":35,"../util/to_json":36,"../util/uri":37,"./transport":23}],21:[function(require,module,exports){
|
|
1932
|
-
(function (global){
|
|
1933
|
-
'use strict';
|
|
1934
|
-
|
|
1935
|
-
var Class = require('../util/class'),
|
|
1936
|
-
URI = require('../util/uri'),
|
|
1937
|
-
copyObject = require('../util/copy_object'),
|
|
1938
|
-
extend = require('../util/extend'),
|
|
1939
|
-
Deferrable = require('../mixins/deferrable'),
|
|
1940
|
-
Transport = require('./transport'),
|
|
1941
|
-
XHR = require('./xhr');
|
|
1942
|
-
|
|
1943
|
-
var EventSource = extend(Class(Transport, {
|
|
1944
|
-
initialize: function(dispatcher, endpoint) {
|
|
1945
|
-
Transport.prototype.initialize.call(this, dispatcher, endpoint);
|
|
1946
|
-
if (!global.EventSource) return this.setDeferredStatus('failed');
|
|
1947
|
-
|
|
1948
|
-
this._xhr = new XHR(dispatcher, endpoint);
|
|
1949
|
-
|
|
1950
|
-
endpoint = copyObject(endpoint);
|
|
1951
|
-
endpoint.pathname += '/' + dispatcher.clientId;
|
|
1952
|
-
|
|
1953
|
-
var socket = new global.EventSource(URI.stringify(endpoint)),
|
|
1954
|
-
self = this;
|
|
1955
|
-
|
|
1956
|
-
socket.onopen = function() {
|
|
1957
|
-
self._everConnected = true;
|
|
1958
|
-
self.setDeferredStatus('succeeded');
|
|
1959
|
-
};
|
|
1960
|
-
|
|
1961
|
-
socket.onerror = function() {
|
|
1962
|
-
if (self._everConnected) {
|
|
1963
|
-
self._handleError([]);
|
|
1964
|
-
} else {
|
|
1965
|
-
self.setDeferredStatus('failed');
|
|
1966
|
-
socket.close();
|
|
1967
|
-
}
|
|
1968
|
-
};
|
|
1969
|
-
|
|
1970
|
-
socket.onmessage = function(event) {
|
|
1971
|
-
var replies;
|
|
1972
|
-
try { replies = JSON.parse(event.data) } catch (error) {}
|
|
1973
|
-
|
|
1974
|
-
if (replies)
|
|
1975
|
-
self._receive(replies);
|
|
1976
|
-
else
|
|
1977
|
-
self._handleError([]);
|
|
1978
|
-
};
|
|
1979
|
-
|
|
1980
|
-
this._socket = socket;
|
|
1981
|
-
},
|
|
1982
|
-
|
|
1983
|
-
close: function() {
|
|
1984
|
-
if (!this._socket) return;
|
|
1985
|
-
this._socket.onopen = this._socket.onerror = this._socket.onmessage = null;
|
|
1986
|
-
this._socket.close();
|
|
1987
|
-
delete this._socket;
|
|
1988
|
-
},
|
|
1989
|
-
|
|
1990
|
-
isUsable: function(callback, context) {
|
|
1991
|
-
this.callback(function() { callback.call(context, true) });
|
|
1992
|
-
this.errback(function() { callback.call(context, false) });
|
|
1993
|
-
},
|
|
1994
|
-
|
|
1995
|
-
encode: function(messages) {
|
|
1996
|
-
return this._xhr.encode(messages);
|
|
1997
|
-
},
|
|
1998
|
-
|
|
1999
|
-
request: function(messages) {
|
|
2000
|
-
return this._xhr.request(messages);
|
|
2001
|
-
}
|
|
2002
|
-
|
|
2003
|
-
}), {
|
|
2004
|
-
isUsable: function(dispatcher, endpoint, callback, context) {
|
|
2005
|
-
var id = dispatcher.clientId;
|
|
2006
|
-
if (!id) return callback.call(context, false);
|
|
2007
|
-
|
|
2008
|
-
XHR.isUsable(dispatcher, endpoint, function(usable) {
|
|
2009
|
-
if (!usable) return callback.call(context, false);
|
|
2010
|
-
this.create(dispatcher, endpoint).isUsable(callback, context);
|
|
2011
|
-
}, this);
|
|
2012
|
-
},
|
|
2013
|
-
|
|
2014
|
-
create: function(dispatcher, endpoint) {
|
|
2015
|
-
var sockets = dispatcher.transports.eventsource = dispatcher.transports.eventsource || {},
|
|
2016
|
-
id = dispatcher.clientId;
|
|
2017
|
-
|
|
2018
|
-
var url = copyObject(endpoint);
|
|
2019
|
-
url.pathname += '/' + (id || '');
|
|
2020
|
-
url = URI.stringify(url);
|
|
2021
|
-
|
|
2022
|
-
sockets[url] = sockets[url] || new this(dispatcher, endpoint);
|
|
2023
|
-
return sockets[url];
|
|
2024
|
-
}
|
|
2025
|
-
});
|
|
2026
|
-
|
|
2027
|
-
extend(EventSource.prototype, Deferrable);
|
|
2028
|
-
|
|
2029
|
-
module.exports = EventSource;
|
|
2030
|
-
|
|
2031
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
2032
|
-
|
|
2033
|
-
},{"../mixins/deferrable":6,"../util/class":28,"../util/copy_object":31,"../util/extend":33,"../util/uri":37,"./transport":23,"./xhr":25}],22:[function(require,module,exports){
|
|
2034
|
-
(function (global){
|
|
2035
|
-
'use strict';
|
|
2036
|
-
|
|
2037
|
-
var Class = require('../util/class'),
|
|
2038
|
-
URI = require('../util/uri'),
|
|
2039
|
-
copyObject = require('../util/copy_object'),
|
|
2040
|
-
extend = require('../util/extend'),
|
|
2041
|
-
toJSON = require('../util/to_json'),
|
|
2042
|
-
Transport = require('./transport');
|
|
2043
|
-
|
|
2044
|
-
var JSONP = extend(Class(Transport, {
|
|
2045
|
-
encode: function(messages) {
|
|
2046
|
-
var url = copyObject(this.endpoint);
|
|
2047
|
-
url.query.message = toJSON(messages);
|
|
2048
|
-
url.query.jsonp = '__jsonp' + JSONP._cbCount + '__';
|
|
2049
|
-
return URI.stringify(url);
|
|
2050
|
-
},
|
|
2051
|
-
|
|
2052
|
-
request: function(messages) {
|
|
2053
|
-
var head = document.getElementsByTagName('head')[0],
|
|
2054
|
-
script = document.createElement('script'),
|
|
2055
|
-
callbackName = JSONP.getCallbackName(),
|
|
2056
|
-
endpoint = copyObject(this.endpoint),
|
|
2057
|
-
self = this;
|
|
2058
|
-
|
|
2059
|
-
endpoint.query.message = toJSON(messages);
|
|
2060
|
-
endpoint.query.jsonp = callbackName;
|
|
2061
|
-
|
|
2062
|
-
var cleanup = function() {
|
|
2063
|
-
if (!global[callbackName]) return false;
|
|
2064
|
-
global[callbackName] = undefined;
|
|
2065
|
-
try { delete global[callbackName] } catch (error) {}
|
|
2066
|
-
script.parentNode.removeChild(script);
|
|
2067
|
-
};
|
|
2068
|
-
|
|
2069
|
-
global[callbackName] = function(replies) {
|
|
2070
|
-
cleanup();
|
|
2071
|
-
self._receive(replies);
|
|
2072
|
-
};
|
|
2073
|
-
|
|
2074
|
-
script.type = 'text/javascript';
|
|
2075
|
-
script.src = URI.stringify(endpoint);
|
|
2076
|
-
head.appendChild(script);
|
|
2077
|
-
|
|
2078
|
-
script.onerror = function() {
|
|
2079
|
-
cleanup();
|
|
2080
|
-
self._handleError(messages);
|
|
2081
|
-
};
|
|
2082
|
-
|
|
2083
|
-
return {abort: cleanup};
|
|
2084
|
-
}
|
|
2085
|
-
}), {
|
|
2086
|
-
_cbCount: 0,
|
|
2087
|
-
|
|
2088
|
-
getCallbackName: function() {
|
|
2089
|
-
this._cbCount += 1;
|
|
2090
|
-
return '__jsonp' + this._cbCount + '__';
|
|
2091
|
-
},
|
|
2092
|
-
|
|
2093
|
-
isUsable: function(dispatcher, endpoint, callback, context) {
|
|
2094
|
-
callback.call(context, true);
|
|
2095
|
-
}
|
|
2096
|
-
});
|
|
2097
|
-
|
|
2098
|
-
module.exports = JSONP;
|
|
2099
|
-
|
|
2100
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
2101
|
-
|
|
2102
|
-
},{"../util/class":28,"../util/copy_object":31,"../util/extend":33,"../util/to_json":36,"../util/uri":37,"./transport":23}],23:[function(require,module,exports){
|
|
2103
|
-
(function (process){
|
|
2104
|
-
'use strict';
|
|
2105
|
-
|
|
2106
|
-
var Class = require('../util/class'),
|
|
2107
|
-
Cookie = require('../util/cookies').Cookie,
|
|
2108
|
-
Promise = require('../util/promise'),
|
|
2109
|
-
URI = require('../util/uri'),
|
|
2110
|
-
array = require('../util/array'),
|
|
2111
|
-
extend = require('../util/extend'),
|
|
2112
|
-
Logging = require('../mixins/logging'),
|
|
2113
|
-
Timeouts = require('../mixins/timeouts'),
|
|
2114
|
-
Channel = require('../protocol/channel');
|
|
2115
|
-
|
|
2116
|
-
var Transport = extend(Class({ className: 'Transport',
|
|
2117
|
-
DEFAULT_PORTS: {'http:': 80, 'https:': 443, 'ws:': 80, 'wss:': 443},
|
|
2118
|
-
MAX_DELAY: 0,
|
|
2119
|
-
|
|
2120
|
-
batching: true,
|
|
2121
|
-
|
|
2122
|
-
initialize: function(dispatcher, endpoint) {
|
|
2123
|
-
this._dispatcher = dispatcher;
|
|
2124
|
-
this.endpoint = endpoint;
|
|
2125
|
-
this._outbox = [];
|
|
2126
|
-
this._proxy = extend({}, this._dispatcher.proxy);
|
|
2127
|
-
|
|
2128
|
-
if (!this._proxy.origin)
|
|
2129
|
-
this._proxy.origin = this._findProxy();
|
|
2130
|
-
},
|
|
2131
|
-
|
|
2132
|
-
close: function() {},
|
|
2133
|
-
|
|
2134
|
-
encode: function(messages) {
|
|
2135
|
-
return '';
|
|
2136
|
-
},
|
|
2137
|
-
|
|
2138
|
-
sendMessage: function(message) {
|
|
2139
|
-
this.debug('Client ? sending message to ?: ?',
|
|
2140
|
-
this._dispatcher.clientId, URI.stringify(this.endpoint), message);
|
|
2141
|
-
|
|
2142
|
-
if (!this.batching) return Promise.resolve(this.request([message]));
|
|
2143
|
-
|
|
2144
|
-
this._outbox.push(message);
|
|
2145
|
-
this._flushLargeBatch();
|
|
2146
|
-
|
|
2147
|
-
if (message.channel === Channel.HANDSHAKE)
|
|
2148
|
-
return this._publish(0.01);
|
|
2149
|
-
|
|
2150
|
-
if (message.channel === Channel.CONNECT)
|
|
2151
|
-
this._connectMessage = message;
|
|
2152
|
-
|
|
2153
|
-
return this._publish(this.MAX_DELAY);
|
|
2154
|
-
},
|
|
2155
|
-
|
|
2156
|
-
_makePromise: function() {
|
|
2157
|
-
var self = this;
|
|
2158
|
-
|
|
2159
|
-
this._requestPromise = this._requestPromise || new Promise(function(resolve) {
|
|
2160
|
-
self._resolvePromise = resolve;
|
|
2161
|
-
});
|
|
2162
|
-
},
|
|
2163
|
-
|
|
2164
|
-
_publish: function(delay) {
|
|
2165
|
-
this._makePromise();
|
|
2166
|
-
|
|
2167
|
-
this.addTimeout('publish', delay, function() {
|
|
2168
|
-
this._flush();
|
|
2169
|
-
delete this._requestPromise;
|
|
2170
|
-
}, this);
|
|
2171
|
-
|
|
2172
|
-
return this._requestPromise;
|
|
2173
|
-
},
|
|
2174
|
-
|
|
2175
|
-
_flush: function() {
|
|
2176
|
-
this.removeTimeout('publish');
|
|
2177
|
-
|
|
2178
|
-
if (this._outbox.length > 1 && this._connectMessage)
|
|
2179
|
-
this._connectMessage.advice = {timeout: 0};
|
|
2180
|
-
|
|
2181
|
-
this._resolvePromise(this.request(this._outbox));
|
|
2182
|
-
|
|
2183
|
-
this._connectMessage = null;
|
|
2184
|
-
this._outbox = [];
|
|
2185
|
-
},
|
|
2186
|
-
|
|
2187
|
-
_flushLargeBatch: function() {
|
|
2188
|
-
var string = this.encode(this._outbox);
|
|
2189
|
-
if (string.length < this._dispatcher.maxRequestSize) return;
|
|
2190
|
-
var last = this._outbox.pop();
|
|
2191
|
-
|
|
2192
|
-
this._makePromise();
|
|
2193
|
-
this._flush();
|
|
2194
|
-
|
|
2195
|
-
if (last) this._outbox.push(last);
|
|
2196
|
-
},
|
|
2197
|
-
|
|
2198
|
-
_receive: function(replies) {
|
|
2199
|
-
if (!replies) return;
|
|
2200
|
-
replies = [].concat(replies);
|
|
2201
|
-
|
|
2202
|
-
this.debug('Client ? received from ? via ?: ?',
|
|
2203
|
-
this._dispatcher.clientId, URI.stringify(this.endpoint), this.connectionType, replies);
|
|
2204
|
-
|
|
2205
|
-
for (var i = 0, n = replies.length; i < n; i++)
|
|
2206
|
-
this._dispatcher.handleResponse(replies[i]);
|
|
2207
|
-
},
|
|
2208
|
-
|
|
2209
|
-
_handleError: function(messages, immediate) {
|
|
2210
|
-
messages = [].concat(messages);
|
|
2211
|
-
|
|
2212
|
-
this.debug('Client ? failed to send to ? via ?: ?',
|
|
2213
|
-
this._dispatcher.clientId, URI.stringify(this.endpoint), this.connectionType, messages);
|
|
2214
|
-
|
|
2215
|
-
for (var i = 0, n = messages.length; i < n; i++)
|
|
2216
|
-
this._dispatcher.handleError(messages[i]);
|
|
2217
|
-
},
|
|
2218
|
-
|
|
2219
|
-
_getCookies: function() {
|
|
2220
|
-
var cookies = this._dispatcher.cookies,
|
|
2221
|
-
url = URI.stringify(this.endpoint);
|
|
2222
|
-
|
|
2223
|
-
if (!cookies) return '';
|
|
2224
|
-
|
|
2225
|
-
return array.map(cookies.getCookiesSync(url), function(cookie) {
|
|
2226
|
-
return cookie.cookieString();
|
|
2227
|
-
}).join('; ');
|
|
2228
|
-
},
|
|
2229
|
-
|
|
2230
|
-
_storeCookies: function(setCookie) {
|
|
2231
|
-
var cookies = this._dispatcher.cookies,
|
|
2232
|
-
url = URI.stringify(this.endpoint),
|
|
2233
|
-
cookie;
|
|
2234
|
-
|
|
2235
|
-
if (!setCookie || !cookies) return;
|
|
2236
|
-
setCookie = [].concat(setCookie);
|
|
2237
|
-
|
|
2238
|
-
for (var i = 0, n = setCookie.length; i < n; i++) {
|
|
2239
|
-
cookie = Cookie.parse(setCookie[i]);
|
|
2240
|
-
cookies.setCookieSync(cookie, url);
|
|
2241
|
-
}
|
|
2242
|
-
},
|
|
2243
|
-
|
|
2244
|
-
_findProxy: function() {
|
|
2245
|
-
if (typeof process === 'undefined') return undefined;
|
|
2246
|
-
|
|
2247
|
-
var protocol = this.endpoint.protocol;
|
|
2248
|
-
if (!protocol) return undefined;
|
|
2249
|
-
|
|
2250
|
-
var name = protocol.replace(/:$/, '').toLowerCase() + '_proxy',
|
|
2251
|
-
upcase = name.toUpperCase(),
|
|
2252
|
-
env = process.env,
|
|
2253
|
-
keys, proxy;
|
|
2254
|
-
|
|
2255
|
-
if (name === 'http_proxy' && env.REQUEST_METHOD) {
|
|
2256
|
-
keys = Object.keys(env).filter(function(k) { return /^http_proxy$/i.test(k) });
|
|
2257
|
-
if (keys.length === 1) {
|
|
2258
|
-
if (keys[0] === name && env[upcase] === undefined)
|
|
2259
|
-
proxy = env[name];
|
|
2260
|
-
} else if (keys.length > 1) {
|
|
2261
|
-
proxy = env[name];
|
|
2262
|
-
}
|
|
2263
|
-
proxy = proxy || env['CGI_' + upcase];
|
|
2264
|
-
} else {
|
|
2265
|
-
proxy = env[name] || env[upcase];
|
|
2266
|
-
if (proxy && !env[name])
|
|
2267
|
-
console.warn('The environment variable ' + upcase +
|
|
2268
|
-
' is discouraged. Use ' + name + '.');
|
|
2269
|
-
}
|
|
2270
|
-
return proxy;
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
}), {
|
|
2274
|
-
get: function(dispatcher, allowed, disabled, callback, context) {
|
|
2275
|
-
var endpoint = dispatcher.endpoint;
|
|
2276
|
-
|
|
2277
|
-
array.asyncEach(this._transports, function(pair, resume) {
|
|
2278
|
-
var connType = pair[0], klass = pair[1],
|
|
2279
|
-
connEndpoint = dispatcher.endpointFor(connType);
|
|
2280
|
-
|
|
2281
|
-
if (array.indexOf(disabled, connType) >= 0)
|
|
2282
|
-
return resume();
|
|
2283
|
-
|
|
2284
|
-
if (array.indexOf(allowed, connType) < 0) {
|
|
2285
|
-
klass.isUsable(dispatcher, connEndpoint, function() {});
|
|
2286
|
-
return resume();
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
klass.isUsable(dispatcher, connEndpoint, function(isUsable) {
|
|
2290
|
-
if (!isUsable) return resume();
|
|
2291
|
-
var transport = klass.hasOwnProperty('create') ? klass.create(dispatcher, connEndpoint) : new klass(dispatcher, connEndpoint);
|
|
2292
|
-
callback.call(context, transport);
|
|
2293
|
-
});
|
|
2294
|
-
}, function() {
|
|
2295
|
-
throw new Error('Could not find a usable connection type for ' + URI.stringify(endpoint));
|
|
2296
|
-
});
|
|
2297
|
-
},
|
|
2298
|
-
|
|
2299
|
-
register: function(type, klass) {
|
|
2300
|
-
this._transports.push([type, klass]);
|
|
2301
|
-
klass.prototype.connectionType = type;
|
|
2302
|
-
},
|
|
2303
|
-
|
|
2304
|
-
getConnectionTypes: function() {
|
|
2305
|
-
return array.map(this._transports, function(t) { return t[0] });
|
|
2306
|
-
},
|
|
2307
|
-
|
|
2308
|
-
_transports: []
|
|
2309
|
-
});
|
|
2310
|
-
|
|
2311
|
-
extend(Transport.prototype, Logging);
|
|
2312
|
-
extend(Transport.prototype, Timeouts);
|
|
2313
|
-
|
|
2314
|
-
module.exports = Transport;
|
|
2315
|
-
|
|
2316
|
-
}).call(this,require('_process'))
|
|
2317
|
-
|
|
2318
|
-
},{"../mixins/logging":7,"../mixins/timeouts":9,"../protocol/channel":10,"../util/array":26,"../util/class":28,"../util/cookies":30,"../util/extend":33,"../util/promise":34,"../util/uri":37,"_process":40}],24:[function(require,module,exports){
|
|
2319
|
-
(function (global){
|
|
2320
|
-
'use strict';
|
|
2321
|
-
|
|
2322
|
-
var Class = require('../util/class'),
|
|
2323
|
-
Promise = require('../util/promise'),
|
|
2324
|
-
Set = require('../util/set'),
|
|
2325
|
-
URI = require('../util/uri'),
|
|
2326
|
-
browser = require('../util/browser'),
|
|
2327
|
-
copyObject = require('../util/copy_object'),
|
|
2328
|
-
extend = require('../util/extend'),
|
|
2329
|
-
toJSON = require('../util/to_json'),
|
|
2330
|
-
ws = require('../util/websocket'),
|
|
2331
|
-
Deferrable = require('../mixins/deferrable'),
|
|
2332
|
-
Transport = require('./transport');
|
|
2333
|
-
|
|
2334
|
-
var WebSocket = extend(Class(Transport, {
|
|
2335
|
-
UNCONNECTED: 1,
|
|
2336
|
-
CONNECTING: 2,
|
|
2337
|
-
CONNECTED: 3,
|
|
2338
|
-
|
|
2339
|
-
batching: false,
|
|
2340
|
-
|
|
2341
|
-
isUsable: function(callback, context) {
|
|
2342
|
-
this.callback(function() { callback.call(context, true) });
|
|
2343
|
-
this.errback(function() { callback.call(context, false) });
|
|
2344
|
-
this.connect();
|
|
2345
|
-
},
|
|
2346
|
-
|
|
2347
|
-
request: function(messages) {
|
|
2348
|
-
this._pending = this._pending || new Set();
|
|
2349
|
-
for (var i = 0, n = messages.length; i < n; i++) this._pending.add(messages[i]);
|
|
2350
|
-
|
|
2351
|
-
var self = this;
|
|
2352
|
-
|
|
2353
|
-
var promise = new Promise(function(resolve, reject) {
|
|
2354
|
-
self.callback(function(socket) {
|
|
2355
|
-
if (!socket || socket.readyState !== 1) return;
|
|
2356
|
-
socket.send(toJSON(messages));
|
|
2357
|
-
resolve(socket);
|
|
2358
|
-
});
|
|
2359
|
-
|
|
2360
|
-
self.connect();
|
|
2361
|
-
});
|
|
2362
|
-
|
|
2363
|
-
return {
|
|
2364
|
-
abort: function() { promise.then(function(ws) { ws.close() }) }
|
|
2365
|
-
};
|
|
2366
|
-
},
|
|
2367
|
-
|
|
2368
|
-
connect: function() {
|
|
2369
|
-
if (WebSocket._unloaded) return;
|
|
2370
|
-
|
|
2371
|
-
this._state = this._state || this.UNCONNECTED;
|
|
2372
|
-
if (this._state !== this.UNCONNECTED) return;
|
|
2373
|
-
this._state = this.CONNECTING;
|
|
2374
|
-
|
|
2375
|
-
var socket = this._createSocket();
|
|
2376
|
-
if (!socket) return this.setDeferredStatus('failed');
|
|
2377
|
-
|
|
2378
|
-
var self = this;
|
|
2379
|
-
|
|
2380
|
-
socket.onopen = function() {
|
|
2381
|
-
if (socket.headers) self._storeCookies(socket.headers['set-cookie']);
|
|
2382
|
-
self._socket = socket;
|
|
2383
|
-
self._state = self.CONNECTED;
|
|
2384
|
-
self._everConnected = true;
|
|
2385
|
-
self._ping();
|
|
2386
|
-
self.setDeferredStatus('succeeded', socket);
|
|
2387
|
-
};
|
|
2388
|
-
|
|
2389
|
-
var closed = false;
|
|
2390
|
-
socket.onclose = socket.onerror = function() {
|
|
2391
|
-
if (closed) return;
|
|
2392
|
-
closed = true;
|
|
2393
|
-
|
|
2394
|
-
var wasConnected = (self._state === self.CONNECTED);
|
|
2395
|
-
socket.onopen = socket.onclose = socket.onerror = socket.onmessage = null;
|
|
2396
|
-
|
|
2397
|
-
delete self._socket;
|
|
2398
|
-
self._state = self.UNCONNECTED;
|
|
2399
|
-
self.removeTimeout('ping');
|
|
2400
|
-
|
|
2401
|
-
var pending = self._pending ? self._pending.toArray() : [];
|
|
2402
|
-
delete self._pending;
|
|
2403
|
-
|
|
2404
|
-
if (wasConnected || self._everConnected) {
|
|
2405
|
-
self.setDeferredStatus('unknown');
|
|
2406
|
-
self._handleError(pending, wasConnected);
|
|
2407
|
-
} else {
|
|
2408
|
-
self.setDeferredStatus('failed');
|
|
2409
|
-
}
|
|
2410
|
-
};
|
|
2411
|
-
|
|
2412
|
-
socket.onmessage = function(event) {
|
|
2413
|
-
var replies;
|
|
2414
|
-
try { replies = JSON.parse(event.data) } catch (error) {}
|
|
2415
|
-
|
|
2416
|
-
if (!replies) return;
|
|
2417
|
-
|
|
2418
|
-
replies = [].concat(replies);
|
|
2419
|
-
|
|
2420
|
-
for (var i = 0, n = replies.length; i < n; i++) {
|
|
2421
|
-
if (replies[i].successful === undefined) continue;
|
|
2422
|
-
self._pending.remove(replies[i]);
|
|
2423
|
-
}
|
|
2424
|
-
self._receive(replies);
|
|
2425
|
-
};
|
|
2426
|
-
},
|
|
2427
|
-
|
|
2428
|
-
close: function() {
|
|
2429
|
-
if (!this._socket) return;
|
|
2430
|
-
this._socket.close();
|
|
2431
|
-
},
|
|
2432
|
-
|
|
2433
|
-
_createSocket: function() {
|
|
2434
|
-
var url = WebSocket.getSocketUrl(this.endpoint),
|
|
2435
|
-
headers = this._dispatcher.headers,
|
|
2436
|
-
extensions = this._dispatcher.wsExtensions,
|
|
2437
|
-
cookie = this._getCookies(),
|
|
2438
|
-
tls = this._dispatcher.tls,
|
|
2439
|
-
options = {extensions: extensions, headers: headers, proxy: this._proxy, tls: tls};
|
|
2440
|
-
|
|
2441
|
-
if (cookie !== '') options.headers['Cookie'] = cookie;
|
|
2442
|
-
|
|
2443
|
-
return ws.create(url, [], options);
|
|
2444
|
-
},
|
|
2445
|
-
|
|
2446
|
-
_ping: function() {
|
|
2447
|
-
if (!this._socket || this._socket.readyState !== 1) return;
|
|
2448
|
-
this._socket.send('[]');
|
|
2449
|
-
this.addTimeout('ping', this._dispatcher.timeout / 2, this._ping, this);
|
|
2450
|
-
}
|
|
2451
|
-
|
|
2452
|
-
}), {
|
|
2453
|
-
PROTOCOLS: {
|
|
2454
|
-
'http:': 'ws:',
|
|
2455
|
-
'https:': 'wss:'
|
|
2456
|
-
},
|
|
2457
|
-
|
|
2458
|
-
create: function(dispatcher, endpoint) {
|
|
2459
|
-
var sockets = dispatcher.transports.websocket = dispatcher.transports.websocket || {};
|
|
2460
|
-
sockets[endpoint.href] = sockets[endpoint.href] || new this(dispatcher, endpoint);
|
|
2461
|
-
return sockets[endpoint.href];
|
|
2462
|
-
},
|
|
2463
|
-
|
|
2464
|
-
getSocketUrl: function(endpoint) {
|
|
2465
|
-
endpoint = copyObject(endpoint);
|
|
2466
|
-
endpoint.protocol = this.PROTOCOLS[endpoint.protocol];
|
|
2467
|
-
return URI.stringify(endpoint);
|
|
2468
|
-
},
|
|
2469
|
-
|
|
2470
|
-
isUsable: function(dispatcher, endpoint, callback, context) {
|
|
2471
|
-
this.create(dispatcher, endpoint).isUsable(callback, context);
|
|
2472
|
-
}
|
|
2473
|
-
});
|
|
2474
|
-
|
|
2475
|
-
extend(WebSocket.prototype, Deferrable);
|
|
2476
|
-
|
|
2477
|
-
if (browser.Event && global.onbeforeunload !== undefined)
|
|
2478
|
-
browser.Event.on(global, 'beforeunload', function() { WebSocket._unloaded = true });
|
|
2479
|
-
|
|
2480
|
-
module.exports = WebSocket;
|
|
2481
|
-
|
|
2482
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
2483
|
-
|
|
2484
|
-
},{"../mixins/deferrable":6,"../util/browser":27,"../util/class":28,"../util/copy_object":31,"../util/extend":33,"../util/promise":34,"../util/set":35,"../util/to_json":36,"../util/uri":37,"../util/websocket":39,"./transport":23}],25:[function(require,module,exports){
|
|
2485
|
-
(function (global){
|
|
2486
|
-
'use strict';
|
|
2487
|
-
|
|
2488
|
-
var Class = require('../util/class'),
|
|
2489
|
-
URI = require('../util/uri'),
|
|
2490
|
-
browser = require('../util/browser'),
|
|
2491
|
-
extend = require('../util/extend'),
|
|
2492
|
-
toJSON = require('../util/to_json'),
|
|
2493
|
-
Transport = require('./transport');
|
|
2494
|
-
|
|
2495
|
-
var XHR = extend(Class(Transport, {
|
|
2496
|
-
encode: function(messages) {
|
|
2497
|
-
return toJSON(messages);
|
|
2498
|
-
},
|
|
2499
|
-
|
|
2500
|
-
request: function(messages) {
|
|
2501
|
-
var href = this.endpoint.href,
|
|
2502
|
-
self = this,
|
|
2503
|
-
xhr;
|
|
2504
|
-
|
|
2505
|
-
// Prefer XMLHttpRequest over ActiveXObject if they both exist
|
|
2506
|
-
if (global.XMLHttpRequest) {
|
|
2507
|
-
xhr = new XMLHttpRequest();
|
|
2508
|
-
} else if (global.ActiveXObject) {
|
|
2509
|
-
xhr = new ActiveXObject('Microsoft.XMLHTTP');
|
|
2510
|
-
} else {
|
|
2511
|
-
return this._handleError(messages);
|
|
2512
|
-
}
|
|
2513
|
-
|
|
2514
|
-
xhr.open('POST', href, true);
|
|
2515
|
-
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
2516
|
-
xhr.setRequestHeader('Pragma', 'no-cache');
|
|
2517
|
-
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
2518
|
-
|
|
2519
|
-
var headers = this._dispatcher.headers;
|
|
2520
|
-
for (var key in headers) {
|
|
2521
|
-
if (!headers.hasOwnProperty(key)) continue;
|
|
2522
|
-
xhr.setRequestHeader(key, headers[key]);
|
|
2523
|
-
}
|
|
2524
|
-
|
|
2525
|
-
var abort = function() { xhr.abort() };
|
|
2526
|
-
if (global.onbeforeunload !== undefined)
|
|
2527
|
-
browser.Event.on(global, 'beforeunload', abort);
|
|
2528
|
-
|
|
2529
|
-
xhr.onreadystatechange = function() {
|
|
2530
|
-
if (!xhr || xhr.readyState !== 4) return;
|
|
2531
|
-
|
|
2532
|
-
var replies = null,
|
|
2533
|
-
status = xhr.status,
|
|
2534
|
-
text = xhr.responseText,
|
|
2535
|
-
successful = (status >= 200 && status < 300) || status === 304 || status === 1223;
|
|
2536
|
-
|
|
2537
|
-
if (global.onbeforeunload !== undefined)
|
|
2538
|
-
browser.Event.detach(global, 'beforeunload', abort);
|
|
2539
|
-
|
|
2540
|
-
xhr.onreadystatechange = function() {};
|
|
2541
|
-
xhr = null;
|
|
2542
|
-
|
|
2543
|
-
if (!successful) return self._handleError(messages);
|
|
2544
|
-
|
|
2545
|
-
try {
|
|
2546
|
-
replies = JSON.parse(text);
|
|
2547
|
-
} catch (error) {}
|
|
2548
|
-
|
|
2549
|
-
if (replies)
|
|
2550
|
-
self._receive(replies);
|
|
2551
|
-
else
|
|
2552
|
-
self._handleError(messages);
|
|
2553
|
-
};
|
|
2554
|
-
|
|
2555
|
-
xhr.send(this.encode(messages));
|
|
2556
|
-
return xhr;
|
|
2557
|
-
}
|
|
2558
|
-
}), {
|
|
2559
|
-
isUsable: function(dispatcher, endpoint, callback, context) {
|
|
2560
|
-
var usable = (navigator.product === 'ReactNative')
|
|
2561
|
-
|| URI.isSameOrigin(endpoint);
|
|
2562
|
-
|
|
2563
|
-
callback.call(context, usable);
|
|
2564
|
-
}
|
|
2565
|
-
});
|
|
2566
|
-
|
|
2567
|
-
module.exports = XHR;
|
|
2568
|
-
|
|
2569
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
2570
|
-
|
|
2571
|
-
},{"../util/browser":27,"../util/class":28,"../util/extend":33,"../util/to_json":36,"../util/uri":37,"./transport":23}],26:[function(require,module,exports){
|
|
2572
|
-
'use strict';
|
|
2573
|
-
|
|
2574
|
-
module.exports = {
|
|
2575
|
-
commonElement: function(lista, listb) {
|
|
2576
|
-
for (var i = 0, n = lista.length; i < n; i++) {
|
|
2577
|
-
if (this.indexOf(listb, lista[i]) !== -1)
|
|
2578
|
-
return lista[i];
|
|
2579
|
-
}
|
|
2580
|
-
return null;
|
|
2581
|
-
},
|
|
2582
|
-
|
|
2583
|
-
indexOf: function(list, needle) {
|
|
2584
|
-
if (list.indexOf) return list.indexOf(needle);
|
|
2585
|
-
|
|
2586
|
-
for (var i = 0, n = list.length; i < n; i++) {
|
|
2587
|
-
if (list[i] === needle) return i;
|
|
2588
|
-
}
|
|
2589
|
-
return -1;
|
|
2590
|
-
},
|
|
2591
|
-
|
|
2592
|
-
map: function(object, callback, context) {
|
|
2593
|
-
if (object.map) return object.map(callback, context);
|
|
2594
|
-
var result = [];
|
|
2595
|
-
|
|
2596
|
-
if (object instanceof Array) {
|
|
2597
|
-
for (var i = 0, n = object.length; i < n; i++) {
|
|
2598
|
-
result.push(callback.call(context || null, object[i], i));
|
|
2599
|
-
}
|
|
2600
|
-
} else {
|
|
2601
|
-
for (var key in object) {
|
|
2602
|
-
if (!object.hasOwnProperty(key)) continue;
|
|
2603
|
-
result.push(callback.call(context || null, key, object[key]));
|
|
2604
|
-
}
|
|
2605
|
-
}
|
|
2606
|
-
return result;
|
|
2607
|
-
},
|
|
2608
|
-
|
|
2609
|
-
filter: function(array, callback, context) {
|
|
2610
|
-
if (array.filter) return array.filter(callback, context);
|
|
2611
|
-
var result = [];
|
|
2612
|
-
for (var i = 0, n = array.length; i < n; i++) {
|
|
2613
|
-
if (callback.call(context || null, array[i], i))
|
|
2614
|
-
result.push(array[i]);
|
|
2615
|
-
}
|
|
2616
|
-
return result;
|
|
2617
|
-
},
|
|
2618
|
-
|
|
2619
|
-
asyncEach: function(list, iterator, callback, context) {
|
|
2620
|
-
var n = list.length,
|
|
2621
|
-
i = -1,
|
|
2622
|
-
calls = 0,
|
|
2623
|
-
looping = false;
|
|
2624
|
-
|
|
2625
|
-
var iterate = function() {
|
|
2626
|
-
calls -= 1;
|
|
2627
|
-
i += 1;
|
|
2628
|
-
if (i === n) return callback && callback.call(context);
|
|
2629
|
-
iterator(list[i], resume);
|
|
2630
|
-
};
|
|
2631
|
-
|
|
2632
|
-
var loop = function() {
|
|
2633
|
-
if (looping) return;
|
|
2634
|
-
looping = true;
|
|
2635
|
-
while (calls > 0) iterate();
|
|
2636
|
-
looping = false;
|
|
2637
|
-
};
|
|
2638
|
-
|
|
2639
|
-
var resume = function() {
|
|
2640
|
-
calls += 1;
|
|
2641
|
-
loop();
|
|
2642
|
-
};
|
|
2643
|
-
resume();
|
|
2644
|
-
}
|
|
2645
|
-
};
|
|
2646
|
-
|
|
2647
|
-
},{}],27:[function(require,module,exports){
|
|
2648
|
-
(function (global){
|
|
2649
|
-
'use strict';
|
|
2650
|
-
|
|
2651
|
-
var Event = {
|
|
2652
|
-
_registry: [],
|
|
2653
|
-
|
|
2654
|
-
on: function(element, eventName, callback, context) {
|
|
2655
|
-
var wrapped = function() { callback.call(context) };
|
|
2656
|
-
|
|
2657
|
-
if (element.addEventListener)
|
|
2658
|
-
element.addEventListener(eventName, wrapped, false);
|
|
2659
|
-
else
|
|
2660
|
-
element.attachEvent('on' + eventName, wrapped);
|
|
2661
|
-
|
|
2662
|
-
this._registry.push({
|
|
2663
|
-
_element: element,
|
|
2664
|
-
_type: eventName,
|
|
2665
|
-
_callback: callback,
|
|
2666
|
-
_context: context,
|
|
2667
|
-
_handler: wrapped
|
|
2668
|
-
});
|
|
2669
|
-
},
|
|
2670
|
-
|
|
2671
|
-
detach: function(element, eventName, callback, context) {
|
|
2672
|
-
var i = this._registry.length, register;
|
|
2673
|
-
while (i--) {
|
|
2674
|
-
register = this._registry[i];
|
|
2675
|
-
|
|
2676
|
-
if ((element && element !== register._element) ||
|
|
2677
|
-
(eventName && eventName !== register._type) ||
|
|
2678
|
-
(callback && callback !== register._callback) ||
|
|
2679
|
-
(context && context !== register._context))
|
|
2680
|
-
continue;
|
|
2681
|
-
|
|
2682
|
-
if (register._element.removeEventListener)
|
|
2683
|
-
register._element.removeEventListener(register._type, register._handler, false);
|
|
2684
|
-
else
|
|
2685
|
-
register._element.detachEvent('on' + register._type, register._handler);
|
|
2686
|
-
|
|
2687
|
-
this._registry.splice(i,1);
|
|
2688
|
-
register = null;
|
|
2689
|
-
}
|
|
2690
|
-
}
|
|
2691
|
-
};
|
|
2692
|
-
|
|
2693
|
-
if (global.onunload !== undefined)
|
|
2694
|
-
Event.on(global, 'unload', Event.detach, Event);
|
|
2695
|
-
|
|
2696
|
-
module.exports = {
|
|
2697
|
-
Event: Event
|
|
2698
|
-
};
|
|
2699
|
-
|
|
2700
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
2701
|
-
|
|
2702
|
-
},{}],28:[function(require,module,exports){
|
|
2703
|
-
'use strict';
|
|
2704
|
-
|
|
2705
|
-
var extend = require('./extend');
|
|
2706
|
-
|
|
2707
|
-
module.exports = function(parent, methods) {
|
|
2708
|
-
if (typeof parent !== 'function') {
|
|
2709
|
-
methods = parent;
|
|
2710
|
-
parent = Object;
|
|
2711
|
-
}
|
|
2712
|
-
|
|
2713
|
-
var klass = function() {
|
|
2714
|
-
if (!this.initialize) return this;
|
|
2715
|
-
return this.initialize.apply(this, arguments) || this;
|
|
2716
|
-
};
|
|
2717
|
-
|
|
2718
|
-
var bridge = function() {};
|
|
2719
|
-
bridge.prototype = parent.prototype;
|
|
2720
|
-
|
|
2721
|
-
klass.prototype = new bridge();
|
|
2722
|
-
extend(klass.prototype, methods);
|
|
2723
|
-
|
|
2724
|
-
return klass;
|
|
2725
|
-
};
|
|
2726
|
-
|
|
2727
|
-
},{"./extend":33}],29:[function(require,module,exports){
|
|
2728
|
-
module.exports = {
|
|
2729
|
-
VERSION: '1.2.4',
|
|
2730
|
-
|
|
2731
|
-
BAYEUX_VERSION: '1.0',
|
|
2732
|
-
ID_LENGTH: 160,
|
|
2733
|
-
JSONP_CALLBACK: 'jsonpcallback',
|
|
2734
|
-
CONNECTION_TYPES: ['long-polling', 'cross-origin-long-polling', 'callback-polling', 'websocket', 'eventsource', 'in-process'],
|
|
2735
|
-
|
|
2736
|
-
MANDATORY_CONNECTION_TYPES: ['long-polling', 'callback-polling', 'in-process']
|
|
2737
|
-
};
|
|
2738
|
-
|
|
2739
|
-
},{}],30:[function(require,module,exports){
|
|
2740
|
-
'use strict';
|
|
2741
|
-
|
|
2742
|
-
module.exports = {};
|
|
2743
|
-
|
|
2744
|
-
},{}],31:[function(require,module,exports){
|
|
2745
|
-
'use strict';
|
|
2746
|
-
|
|
2747
|
-
var copyObject = function(object) {
|
|
2748
|
-
var clone, i, key;
|
|
2749
|
-
if (object instanceof Array) {
|
|
2750
|
-
clone = [];
|
|
2751
|
-
i = object.length;
|
|
2752
|
-
while (i--) clone[i] = copyObject(object[i]);
|
|
2753
|
-
return clone;
|
|
2754
|
-
} else if (typeof object === 'object') {
|
|
2755
|
-
clone = (object === null) ? null : {};
|
|
2756
|
-
for (key in object) clone[key] = copyObject(object[key]);
|
|
2757
|
-
return clone;
|
|
2758
|
-
} else {
|
|
2759
|
-
return object;
|
|
2760
|
-
}
|
|
2761
|
-
};
|
|
2762
|
-
|
|
2763
|
-
module.exports = copyObject;
|
|
2764
|
-
|
|
2765
|
-
},{}],32:[function(require,module,exports){
|
|
2766
|
-
/*
|
|
2767
|
-
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
2768
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
2769
|
-
this software and associated documentation files (the "Software"), to deal in
|
|
2770
|
-
the Software without restriction, including without limitation the rights to
|
|
2771
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
2772
|
-
of the Software, and to permit persons to whom the Software is furnished to do
|
|
2773
|
-
so, subject to the following conditions:
|
|
2774
|
-
|
|
2775
|
-
The above copyright notice and this permission notice shall be included in all
|
|
2776
|
-
copies or substantial portions of the Software.
|
|
2777
|
-
|
|
2778
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
2779
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
2780
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
2781
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
2782
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
2783
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
2784
|
-
SOFTWARE.
|
|
2785
|
-
*/
|
|
2786
|
-
|
|
2787
|
-
var isArray = typeof Array.isArray === 'function'
|
|
2788
|
-
? Array.isArray
|
|
2789
|
-
: function (xs) {
|
|
2790
|
-
return Object.prototype.toString.call(xs) === '[object Array]'
|
|
2791
|
-
}
|
|
2792
|
-
;
|
|
2793
|
-
function indexOf (xs, x) {
|
|
2794
|
-
if (xs.indexOf) return xs.indexOf(x);
|
|
2795
|
-
for (var i = 0; i < xs.length; i++) {
|
|
2796
|
-
if (x === xs[i]) return i;
|
|
2797
|
-
}
|
|
2798
|
-
return -1;
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2801
|
-
function EventEmitter() {}
|
|
2802
|
-
module.exports = EventEmitter;
|
|
2803
|
-
|
|
2804
|
-
EventEmitter.prototype.emit = function(type) {
|
|
2805
|
-
// If there is no 'error' event listener then throw.
|
|
2806
|
-
if (type === 'error') {
|
|
2807
|
-
if (!this._events || !this._events.error ||
|
|
2808
|
-
(isArray(this._events.error) && !this._events.error.length))
|
|
2809
|
-
{
|
|
2810
|
-
if (arguments[1] instanceof Error) {
|
|
2811
|
-
throw arguments[1]; // Unhandled 'error' event
|
|
2812
|
-
} else {
|
|
2813
|
-
throw new Error("Uncaught, unspecified 'error' event.");
|
|
2814
|
-
}
|
|
2815
|
-
return false;
|
|
2816
|
-
}
|
|
2817
|
-
}
|
|
2818
|
-
|
|
2819
|
-
if (!this._events) return false;
|
|
2820
|
-
var handler = this._events[type];
|
|
2821
|
-
if (!handler) return false;
|
|
2822
|
-
|
|
2823
|
-
if (typeof handler == 'function') {
|
|
2824
|
-
switch (arguments.length) {
|
|
2825
|
-
// fast cases
|
|
2826
|
-
case 1:
|
|
2827
|
-
handler.call(this);
|
|
2828
|
-
break;
|
|
2829
|
-
case 2:
|
|
2830
|
-
handler.call(this, arguments[1]);
|
|
2831
|
-
break;
|
|
2832
|
-
case 3:
|
|
2833
|
-
handler.call(this, arguments[1], arguments[2]);
|
|
2834
|
-
break;
|
|
2835
|
-
// slower
|
|
2836
|
-
default:
|
|
2837
|
-
var args = Array.prototype.slice.call(arguments, 1);
|
|
2838
|
-
handler.apply(this, args);
|
|
2839
|
-
}
|
|
2840
|
-
return true;
|
|
2841
|
-
|
|
2842
|
-
} else if (isArray(handler)) {
|
|
2843
|
-
var args = Array.prototype.slice.call(arguments, 1);
|
|
2844
|
-
|
|
2845
|
-
var listeners = handler.slice();
|
|
2846
|
-
for (var i = 0, l = listeners.length; i < l; i++) {
|
|
2847
|
-
listeners[i].apply(this, args);
|
|
2848
|
-
}
|
|
2849
|
-
return true;
|
|
2850
|
-
|
|
2851
|
-
} else {
|
|
2852
|
-
return false;
|
|
2853
|
-
}
|
|
2854
|
-
};
|
|
2855
|
-
|
|
2856
|
-
// EventEmitter is defined in src/node_events.cc
|
|
2857
|
-
// EventEmitter.prototype.emit() is also defined there.
|
|
2858
|
-
EventEmitter.prototype.addListener = function(type, listener) {
|
|
2859
|
-
if ('function' !== typeof listener) {
|
|
2860
|
-
throw new Error('addListener only takes instances of Function');
|
|
2861
|
-
}
|
|
2862
|
-
|
|
2863
|
-
if (!this._events) this._events = {};
|
|
2864
|
-
|
|
2865
|
-
// To avoid recursion in the case that type == "newListeners"! Before
|
|
2866
|
-
// adding it to the listeners, first emit "newListeners".
|
|
2867
|
-
this.emit('newListener', type, listener);
|
|
2868
|
-
|
|
2869
|
-
if (!this._events[type]) {
|
|
2870
|
-
// Optimize the case of one listener. Don't need the extra array object.
|
|
2871
|
-
this._events[type] = listener;
|
|
2872
|
-
} else if (isArray(this._events[type])) {
|
|
2873
|
-
// If we've already got an array, just append.
|
|
2874
|
-
this._events[type].push(listener);
|
|
2875
|
-
} else {
|
|
2876
|
-
// Adding the second element, need to change to array.
|
|
2877
|
-
this._events[type] = [this._events[type], listener];
|
|
2878
|
-
}
|
|
2879
|
-
|
|
2880
|
-
return this;
|
|
2881
|
-
};
|
|
2882
|
-
|
|
2883
|
-
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
2884
|
-
|
|
2885
|
-
EventEmitter.prototype.once = function(type, listener) {
|
|
2886
|
-
var self = this;
|
|
2887
|
-
self.on(type, function g() {
|
|
2888
|
-
self.removeListener(type, g);
|
|
2889
|
-
listener.apply(this, arguments);
|
|
2890
|
-
});
|
|
2891
|
-
|
|
2892
|
-
return this;
|
|
2893
|
-
};
|
|
2894
|
-
|
|
2895
|
-
EventEmitter.prototype.removeListener = function(type, listener) {
|
|
2896
|
-
if ('function' !== typeof listener) {
|
|
2897
|
-
throw new Error('removeListener only takes instances of Function');
|
|
2898
|
-
}
|
|
2899
|
-
|
|
2900
|
-
// does not use listeners(), so no side effect of creating _events[type]
|
|
2901
|
-
if (!this._events || !this._events[type]) return this;
|
|
2902
|
-
|
|
2903
|
-
var list = this._events[type];
|
|
2904
|
-
|
|
2905
|
-
if (isArray(list)) {
|
|
2906
|
-
var i = indexOf(list, listener);
|
|
2907
|
-
if (i < 0) return this;
|
|
2908
|
-
list.splice(i, 1);
|
|
2909
|
-
if (list.length == 0)
|
|
2910
|
-
delete this._events[type];
|
|
2911
|
-
} else if (this._events[type] === listener) {
|
|
2912
|
-
delete this._events[type];
|
|
2913
|
-
}
|
|
2914
|
-
|
|
2915
|
-
return this;
|
|
2916
|
-
};
|
|
2917
|
-
|
|
2918
|
-
EventEmitter.prototype.removeAllListeners = function(type) {
|
|
2919
|
-
if (arguments.length === 0) {
|
|
2920
|
-
this._events = {};
|
|
2921
|
-
return this;
|
|
2922
|
-
}
|
|
2923
|
-
|
|
2924
|
-
// does not use listeners(), so no side effect of creating _events[type]
|
|
2925
|
-
if (type && this._events && this._events[type]) this._events[type] = null;
|
|
2926
|
-
return this;
|
|
2927
|
-
};
|
|
2928
|
-
|
|
2929
|
-
EventEmitter.prototype.listeners = function(type) {
|
|
2930
|
-
if (!this._events) this._events = {};
|
|
2931
|
-
if (!this._events[type]) this._events[type] = [];
|
|
2932
|
-
if (!isArray(this._events[type])) {
|
|
2933
|
-
this._events[type] = [this._events[type]];
|
|
2934
|
-
}
|
|
2935
|
-
return this._events[type];
|
|
2936
|
-
};
|
|
2937
|
-
|
|
2938
|
-
},{}],33:[function(require,module,exports){
|
|
2939
|
-
'use strict';
|
|
2940
|
-
|
|
2941
|
-
module.exports = function(dest, source, overwrite) {
|
|
2942
|
-
if (!source) return dest;
|
|
2943
|
-
for (var key in source) {
|
|
2944
|
-
if (!source.hasOwnProperty(key)) continue;
|
|
2945
|
-
if (dest.hasOwnProperty(key) && overwrite === false) continue;
|
|
2946
|
-
if (dest[key] !== source[key])
|
|
2947
|
-
dest[key] = source[key];
|
|
2948
|
-
}
|
|
2949
|
-
return dest;
|
|
2950
|
-
};
|
|
2951
|
-
|
|
2952
|
-
},{}],34:[function(require,module,exports){
|
|
2953
|
-
'use strict';
|
|
2954
|
-
|
|
2955
|
-
var asap = require('asap');
|
|
2956
|
-
|
|
2957
|
-
var PENDING = 0,
|
|
2958
|
-
FULFILLED = 1,
|
|
2959
|
-
REJECTED = 2;
|
|
2960
|
-
|
|
2961
|
-
var RETURN = function(x) { return x },
|
|
2962
|
-
THROW = function(x) { throw x };
|
|
2963
|
-
|
|
2964
|
-
var Promise = function(task) {
|
|
2965
|
-
this._state = PENDING;
|
|
2966
|
-
this._onFulfilled = [];
|
|
2967
|
-
this._onRejected = [];
|
|
2968
|
-
|
|
2969
|
-
if (typeof task !== 'function') return;
|
|
2970
|
-
var self = this;
|
|
2971
|
-
|
|
2972
|
-
task(function(value) { resolve(self, value) },
|
|
2973
|
-
function(reason) { reject(self, reason) });
|
|
2974
|
-
};
|
|
2975
|
-
|
|
2976
|
-
Promise.prototype.then = function(onFulfilled, onRejected) {
|
|
2977
|
-
var next = new Promise();
|
|
2978
|
-
registerOnFulfilled(this, onFulfilled, next);
|
|
2979
|
-
registerOnRejected(this, onRejected, next);
|
|
2980
|
-
return next;
|
|
2981
|
-
};
|
|
2982
|
-
|
|
2983
|
-
Promise.prototype['catch'] = function(onRejected) {
|
|
2984
|
-
return this.then(null, onRejected);
|
|
2985
|
-
};
|
|
2986
|
-
|
|
2987
|
-
var registerOnFulfilled = function(promise, onFulfilled, next) {
|
|
2988
|
-
if (typeof onFulfilled !== 'function') onFulfilled = RETURN;
|
|
2989
|
-
var handler = function(value) { invoke(onFulfilled, value, next) };
|
|
2990
|
-
|
|
2991
|
-
if (promise._state === PENDING) {
|
|
2992
|
-
promise._onFulfilled.push(handler);
|
|
2993
|
-
} else if (promise._state === FULFILLED) {
|
|
2994
|
-
handler(promise._value);
|
|
2995
|
-
}
|
|
2996
|
-
};
|
|
2997
|
-
|
|
2998
|
-
var registerOnRejected = function(promise, onRejected, next) {
|
|
2999
|
-
if (typeof onRejected !== 'function') onRejected = THROW;
|
|
3000
|
-
var handler = function(reason) { invoke(onRejected, reason, next) };
|
|
3001
|
-
|
|
3002
|
-
if (promise._state === PENDING) {
|
|
3003
|
-
promise._onRejected.push(handler);
|
|
3004
|
-
} else if (promise._state === REJECTED) {
|
|
3005
|
-
handler(promise._reason);
|
|
3006
|
-
}
|
|
3007
|
-
};
|
|
3008
|
-
|
|
3009
|
-
var invoke = function(fn, value, next) {
|
|
3010
|
-
asap(function() { _invoke(fn, value, next) });
|
|
3011
|
-
};
|
|
3012
|
-
|
|
3013
|
-
var _invoke = function(fn, value, next) {
|
|
3014
|
-
var outcome;
|
|
3015
|
-
|
|
3016
|
-
try {
|
|
3017
|
-
outcome = fn(value);
|
|
3018
|
-
} catch (error) {
|
|
3019
|
-
return reject(next, error);
|
|
3020
|
-
}
|
|
3021
|
-
|
|
3022
|
-
if (outcome === next) {
|
|
3023
|
-
reject(next, new TypeError('Recursive promise chain detected'));
|
|
3024
|
-
} else {
|
|
3025
|
-
resolve(next, outcome);
|
|
3026
|
-
}
|
|
3027
|
-
};
|
|
3028
|
-
|
|
3029
|
-
var resolve = function(promise, value) {
|
|
3030
|
-
var called = false, type, then;
|
|
3031
|
-
|
|
3032
|
-
try {
|
|
3033
|
-
type = typeof value;
|
|
3034
|
-
then = value !== null && (type === 'function' || type === 'object') && value.then;
|
|
3035
|
-
|
|
3036
|
-
if (typeof then !== 'function') return fulfill(promise, value);
|
|
3037
|
-
|
|
3038
|
-
then.call(value, function(v) {
|
|
3039
|
-
if (!(called ^ (called = true))) return;
|
|
3040
|
-
resolve(promise, v);
|
|
3041
|
-
}, function(r) {
|
|
3042
|
-
if (!(called ^ (called = true))) return;
|
|
3043
|
-
reject(promise, r);
|
|
3044
|
-
});
|
|
3045
|
-
} catch (error) {
|
|
3046
|
-
if (!(called ^ (called = true))) return;
|
|
3047
|
-
reject(promise, error);
|
|
3048
|
-
}
|
|
3049
|
-
};
|
|
3050
|
-
|
|
3051
|
-
var fulfill = function(promise, value) {
|
|
3052
|
-
if (promise._state !== PENDING) return;
|
|
3053
|
-
|
|
3054
|
-
promise._state = FULFILLED;
|
|
3055
|
-
promise._value = value;
|
|
3056
|
-
promise._onRejected = [];
|
|
3057
|
-
|
|
3058
|
-
var onFulfilled = promise._onFulfilled, fn;
|
|
3059
|
-
while (fn = onFulfilled.shift()) fn(value);
|
|
3060
|
-
};
|
|
3061
|
-
|
|
3062
|
-
var reject = function(promise, reason) {
|
|
3063
|
-
if (promise._state !== PENDING) return;
|
|
3064
|
-
|
|
3065
|
-
promise._state = REJECTED;
|
|
3066
|
-
promise._reason = reason;
|
|
3067
|
-
promise._onFulfilled = [];
|
|
3068
|
-
|
|
3069
|
-
var onRejected = promise._onRejected, fn;
|
|
3070
|
-
while (fn = onRejected.shift()) fn(reason);
|
|
3071
|
-
};
|
|
3072
|
-
|
|
3073
|
-
Promise.resolve = function(value) {
|
|
3074
|
-
return new Promise(function(resolve, reject) { resolve(value) });
|
|
3075
|
-
};
|
|
3076
|
-
|
|
3077
|
-
Promise.reject = function(reason) {
|
|
3078
|
-
return new Promise(function(resolve, reject) { reject(reason) });
|
|
3079
|
-
};
|
|
3080
|
-
|
|
3081
|
-
Promise.all = function(promises) {
|
|
3082
|
-
return new Promise(function(resolve, reject) {
|
|
3083
|
-
var list = [], n = promises.length, i;
|
|
3084
|
-
|
|
3085
|
-
if (n === 0) return resolve(list);
|
|
3086
|
-
|
|
3087
|
-
for (i = 0; i < n; i++) (function(promise, i) {
|
|
3088
|
-
Promise.resolve(promise).then(function(value) {
|
|
3089
|
-
list[i] = value;
|
|
3090
|
-
if (--n === 0) resolve(list);
|
|
3091
|
-
}, reject);
|
|
3092
|
-
})(promises[i], i);
|
|
3093
|
-
});
|
|
3094
|
-
};
|
|
3095
|
-
|
|
3096
|
-
Promise.race = function(promises) {
|
|
3097
|
-
return new Promise(function(resolve, reject) {
|
|
3098
|
-
for (var i = 0, n = promises.length; i < n; i++)
|
|
3099
|
-
Promise.resolve(promises[i]).then(resolve, reject);
|
|
3100
|
-
});
|
|
3101
|
-
};
|
|
3102
|
-
|
|
3103
|
-
Promise.deferred = Promise.pending = function() {
|
|
3104
|
-
var tuple = {};
|
|
3105
|
-
|
|
3106
|
-
tuple.promise = new Promise(function(resolve, reject) {
|
|
3107
|
-
tuple.resolve = resolve;
|
|
3108
|
-
tuple.reject = reject;
|
|
3109
|
-
});
|
|
3110
|
-
return tuple;
|
|
3111
|
-
};
|
|
3112
|
-
|
|
3113
|
-
module.exports = Promise;
|
|
3114
|
-
|
|
3115
|
-
},{"asap":3}],35:[function(require,module,exports){
|
|
3116
|
-
'use strict';
|
|
3117
|
-
|
|
3118
|
-
var Class = require('./class');
|
|
3119
|
-
|
|
3120
|
-
module.exports = Class({
|
|
3121
|
-
initialize: function() {
|
|
3122
|
-
this._index = {};
|
|
3123
|
-
},
|
|
3124
|
-
|
|
3125
|
-
add: function(item) {
|
|
3126
|
-
var key = (item.id !== undefined) ? item.id : item;
|
|
3127
|
-
if (this._index.hasOwnProperty(key)) return false;
|
|
3128
|
-
this._index[key] = item;
|
|
3129
|
-
return true;
|
|
3130
|
-
},
|
|
3131
|
-
|
|
3132
|
-
forEach: function(block, context) {
|
|
3133
|
-
for (var key in this._index) {
|
|
3134
|
-
if (this._index.hasOwnProperty(key))
|
|
3135
|
-
block.call(context, this._index[key]);
|
|
3136
|
-
}
|
|
3137
|
-
},
|
|
3138
|
-
|
|
3139
|
-
isEmpty: function() {
|
|
3140
|
-
for (var key in this._index) {
|
|
3141
|
-
if (this._index.hasOwnProperty(key)) return false;
|
|
3142
|
-
}
|
|
3143
|
-
return true;
|
|
3144
|
-
},
|
|
3145
|
-
|
|
3146
|
-
member: function(item) {
|
|
3147
|
-
for (var key in this._index) {
|
|
3148
|
-
if (this._index[key] === item) return true;
|
|
3149
|
-
}
|
|
3150
|
-
return false;
|
|
3151
|
-
},
|
|
3152
|
-
|
|
3153
|
-
remove: function(item) {
|
|
3154
|
-
var key = (item.id !== undefined) ? item.id : item;
|
|
3155
|
-
var removed = this._index[key];
|
|
3156
|
-
delete this._index[key];
|
|
3157
|
-
return removed;
|
|
3158
|
-
},
|
|
3159
|
-
|
|
3160
|
-
toArray: function() {
|
|
3161
|
-
var array = [];
|
|
3162
|
-
this.forEach(function(item) { array.push(item) });
|
|
3163
|
-
return array;
|
|
3164
|
-
}
|
|
3165
|
-
});
|
|
3166
|
-
|
|
3167
|
-
},{"./class":28}],36:[function(require,module,exports){
|
|
3168
|
-
'use strict';
|
|
3169
|
-
|
|
3170
|
-
// http://assanka.net/content/tech/2009/09/02/json2-js-vs-prototype/
|
|
3171
|
-
|
|
3172
|
-
module.exports = function(object) {
|
|
3173
|
-
return JSON.stringify(object, function(key, value) {
|
|
3174
|
-
return (this[key] instanceof Array) ? this[key] : value;
|
|
3175
|
-
});
|
|
3176
|
-
};
|
|
3177
|
-
|
|
3178
|
-
},{}],37:[function(require,module,exports){
|
|
3179
|
-
'use strict';
|
|
3180
|
-
|
|
3181
|
-
module.exports = {
|
|
3182
|
-
isURI: function(uri) {
|
|
3183
|
-
return uri && uri.protocol && uri.host && uri.path;
|
|
3184
|
-
},
|
|
3185
|
-
|
|
3186
|
-
isSameOrigin: function(uri) {
|
|
3187
|
-
return uri.protocol === location.protocol &&
|
|
3188
|
-
uri.hostname === location.hostname &&
|
|
3189
|
-
uri.port === location.port;
|
|
3190
|
-
},
|
|
3191
|
-
|
|
3192
|
-
parse: function(url) {
|
|
3193
|
-
if (typeof url !== 'string') return url;
|
|
3194
|
-
var uri = {}, parts, query, pairs, i, n, data;
|
|
3195
|
-
|
|
3196
|
-
var consume = function(name, pattern) {
|
|
3197
|
-
url = url.replace(pattern, function(match) {
|
|
3198
|
-
uri[name] = match;
|
|
3199
|
-
return '';
|
|
3200
|
-
});
|
|
3201
|
-
uri[name] = uri[name] || '';
|
|
3202
|
-
};
|
|
3203
|
-
|
|
3204
|
-
consume('protocol', /^[a-z]+\:/i);
|
|
3205
|
-
consume('host', /^\/\/[^\/\?#]+/);
|
|
3206
|
-
|
|
3207
|
-
if (!/^\//.test(url) && !uri.host)
|
|
3208
|
-
url = location.pathname.replace(/[^\/]*$/, '') + url;
|
|
3209
|
-
|
|
3210
|
-
consume('pathname', /^[^\?#]*/);
|
|
3211
|
-
consume('search', /^\?[^#]*/);
|
|
3212
|
-
consume('hash', /^#.*/);
|
|
3213
|
-
|
|
3214
|
-
uri.protocol = uri.protocol || location.protocol;
|
|
3215
|
-
|
|
3216
|
-
if (uri.host) {
|
|
3217
|
-
uri.host = uri.host.substr(2);
|
|
3218
|
-
parts = uri.host.split(':');
|
|
3219
|
-
uri.hostname = parts[0];
|
|
3220
|
-
uri.port = parts[1] || '';
|
|
3221
|
-
} else {
|
|
3222
|
-
uri.host = location.host;
|
|
3223
|
-
uri.hostname = location.hostname;
|
|
3224
|
-
uri.port = location.port;
|
|
3225
|
-
}
|
|
3226
|
-
|
|
3227
|
-
uri.pathname = uri.pathname || '/';
|
|
3228
|
-
uri.path = uri.pathname + uri.search;
|
|
3229
|
-
|
|
3230
|
-
query = uri.search.replace(/^\?/, '');
|
|
3231
|
-
pairs = query ? query.split('&') : [];
|
|
3232
|
-
data = {};
|
|
3233
|
-
|
|
3234
|
-
for (i = 0, n = pairs.length; i < n; i++) {
|
|
3235
|
-
parts = pairs[i].split('=');
|
|
3236
|
-
data[decodeURIComponent(parts[0] || '')] = decodeURIComponent(parts[1] || '');
|
|
3237
|
-
}
|
|
3238
|
-
|
|
3239
|
-
uri.query = data;
|
|
3240
|
-
|
|
3241
|
-
uri.href = this.stringify(uri);
|
|
3242
|
-
return uri;
|
|
3243
|
-
},
|
|
3244
|
-
|
|
3245
|
-
stringify: function(uri) {
|
|
3246
|
-
var string = uri.protocol + '//' + uri.hostname;
|
|
3247
|
-
if (uri.port) string += ':' + uri.port;
|
|
3248
|
-
string += uri.pathname + this.queryString(uri.query) + (uri.hash || '');
|
|
3249
|
-
return string;
|
|
3250
|
-
},
|
|
3251
|
-
|
|
3252
|
-
queryString: function(query) {
|
|
3253
|
-
var pairs = [];
|
|
3254
|
-
for (var key in query) {
|
|
3255
|
-
if (!query.hasOwnProperty(key)) continue;
|
|
3256
|
-
pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(query[key]));
|
|
3257
|
-
}
|
|
3258
|
-
if (pairs.length === 0) return '';
|
|
3259
|
-
return '?' + pairs.join('&');
|
|
3260
|
-
}
|
|
3261
|
-
};
|
|
3262
|
-
|
|
3263
|
-
},{}],38:[function(require,module,exports){
|
|
3264
|
-
'use strict';
|
|
3265
|
-
|
|
3266
|
-
var array = require('./array');
|
|
3267
|
-
|
|
3268
|
-
module.exports = function(options, validKeys) {
|
|
3269
|
-
for (var key in options) {
|
|
3270
|
-
if (array.indexOf(validKeys, key) < 0)
|
|
3271
|
-
throw new Error('Unrecognized option: ' + key);
|
|
3272
|
-
}
|
|
3273
|
-
};
|
|
3274
|
-
|
|
3275
|
-
},{"./array":26}],39:[function(require,module,exports){
|
|
3276
|
-
(function (global){
|
|
3277
|
-
'use strict';
|
|
3278
|
-
|
|
3279
|
-
var WS = global.MozWebSocket || global.WebSocket;
|
|
3280
|
-
|
|
3281
|
-
module.exports = {
|
|
3282
|
-
create: function(url, protocols, options) {
|
|
3283
|
-
if (typeof WS !== 'function') return null;
|
|
3284
|
-
return new WS(url);
|
|
3285
|
-
}
|
|
3286
|
-
};
|
|
3287
|
-
|
|
3288
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
3289
|
-
|
|
3290
|
-
},{}],40:[function(require,module,exports){
|
|
3291
|
-
// shim for using process in browser
|
|
3292
|
-
var process = module.exports = {};
|
|
3293
|
-
|
|
3294
|
-
// cached from whatever global is present so that test runners that stub it
|
|
3295
|
-
// don't break things. But we need to wrap it in a try catch in case it is
|
|
3296
|
-
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
3297
|
-
// function because try/catches deoptimize in certain engines.
|
|
3298
|
-
|
|
3299
|
-
var cachedSetTimeout;
|
|
3300
|
-
var cachedClearTimeout;
|
|
3301
|
-
|
|
3302
|
-
function defaultSetTimout() {
|
|
3303
|
-
throw new Error('setTimeout has not been defined');
|
|
3304
|
-
}
|
|
3305
|
-
function defaultClearTimeout () {
|
|
3306
|
-
throw new Error('clearTimeout has not been defined');
|
|
3307
|
-
}
|
|
3308
|
-
(function () {
|
|
3309
|
-
try {
|
|
3310
|
-
if (typeof setTimeout === 'function') {
|
|
3311
|
-
cachedSetTimeout = setTimeout;
|
|
3312
|
-
} else {
|
|
3313
|
-
cachedSetTimeout = defaultSetTimout;
|
|
3314
|
-
}
|
|
3315
|
-
} catch (e) {
|
|
3316
|
-
cachedSetTimeout = defaultSetTimout;
|
|
3317
|
-
}
|
|
3318
|
-
try {
|
|
3319
|
-
if (typeof clearTimeout === 'function') {
|
|
3320
|
-
cachedClearTimeout = clearTimeout;
|
|
3321
|
-
} else {
|
|
3322
|
-
cachedClearTimeout = defaultClearTimeout;
|
|
3323
|
-
}
|
|
3324
|
-
} catch (e) {
|
|
3325
|
-
cachedClearTimeout = defaultClearTimeout;
|
|
3326
|
-
}
|
|
3327
|
-
} ())
|
|
3328
|
-
function runTimeout(fun) {
|
|
3329
|
-
if (cachedSetTimeout === setTimeout) {
|
|
3330
|
-
//normal enviroments in sane situations
|
|
3331
|
-
return setTimeout(fun, 0);
|
|
3332
|
-
}
|
|
3333
|
-
// if setTimeout wasn't available but was latter defined
|
|
3334
|
-
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|
3335
|
-
cachedSetTimeout = setTimeout;
|
|
3336
|
-
return setTimeout(fun, 0);
|
|
3337
|
-
}
|
|
3338
|
-
try {
|
|
3339
|
-
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
3340
|
-
return cachedSetTimeout(fun, 0);
|
|
3341
|
-
} catch(e){
|
|
3342
|
-
try {
|
|
3343
|
-
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
3344
|
-
return cachedSetTimeout.call(null, fun, 0);
|
|
3345
|
-
} catch(e){
|
|
3346
|
-
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|
3347
|
-
return cachedSetTimeout.call(this, fun, 0);
|
|
3348
|
-
}
|
|
3349
|
-
}
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
}
|
|
3353
|
-
function runClearTimeout(marker) {
|
|
3354
|
-
if (cachedClearTimeout === clearTimeout) {
|
|
3355
|
-
//normal enviroments in sane situations
|
|
3356
|
-
return clearTimeout(marker);
|
|
3357
|
-
}
|
|
3358
|
-
// if clearTimeout wasn't available but was latter defined
|
|
3359
|
-
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|
3360
|
-
cachedClearTimeout = clearTimeout;
|
|
3361
|
-
return clearTimeout(marker);
|
|
3362
|
-
}
|
|
3363
|
-
try {
|
|
3364
|
-
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
3365
|
-
return cachedClearTimeout(marker);
|
|
3366
|
-
} catch (e){
|
|
3367
|
-
try {
|
|
3368
|
-
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
3369
|
-
return cachedClearTimeout.call(null, marker);
|
|
3370
|
-
} catch (e){
|
|
3371
|
-
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|
3372
|
-
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
3373
|
-
return cachedClearTimeout.call(this, marker);
|
|
3374
|
-
}
|
|
3375
|
-
}
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
}
|
|
3380
|
-
var queue = [];
|
|
3381
|
-
var draining = false;
|
|
3382
|
-
var currentQueue;
|
|
3383
|
-
var queueIndex = -1;
|
|
3384
|
-
|
|
3385
|
-
function cleanUpNextTick() {
|
|
3386
|
-
if (!draining || !currentQueue) {
|
|
3387
|
-
return;
|
|
3388
|
-
}
|
|
3389
|
-
draining = false;
|
|
3390
|
-
if (currentQueue.length) {
|
|
3391
|
-
queue = currentQueue.concat(queue);
|
|
3392
|
-
} else {
|
|
3393
|
-
queueIndex = -1;
|
|
3394
|
-
}
|
|
3395
|
-
if (queue.length) {
|
|
3396
|
-
drainQueue();
|
|
3397
|
-
}
|
|
3398
|
-
}
|
|
3399
|
-
|
|
3400
|
-
function drainQueue() {
|
|
3401
|
-
if (draining) {
|
|
3402
|
-
return;
|
|
3403
|
-
}
|
|
3404
|
-
var timeout = runTimeout(cleanUpNextTick);
|
|
3405
|
-
draining = true;
|
|
3406
|
-
|
|
3407
|
-
var len = queue.length;
|
|
3408
|
-
while(len) {
|
|
3409
|
-
currentQueue = queue;
|
|
3410
|
-
queue = [];
|
|
3411
|
-
while (++queueIndex < len) {
|
|
3412
|
-
if (currentQueue) {
|
|
3413
|
-
currentQueue[queueIndex].run();
|
|
3414
|
-
}
|
|
3415
|
-
}
|
|
3416
|
-
queueIndex = -1;
|
|
3417
|
-
len = queue.length;
|
|
3418
|
-
}
|
|
3419
|
-
currentQueue = null;
|
|
3420
|
-
draining = false;
|
|
3421
|
-
runClearTimeout(timeout);
|
|
3422
|
-
}
|
|
3423
|
-
|
|
3424
|
-
process.nextTick = function (fun) {
|
|
3425
|
-
var args = new Array(arguments.length - 1);
|
|
3426
|
-
if (arguments.length > 1) {
|
|
3427
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
3428
|
-
args[i - 1] = arguments[i];
|
|
3429
|
-
}
|
|
3430
|
-
}
|
|
3431
|
-
queue.push(new Item(fun, args));
|
|
3432
|
-
if (queue.length === 1 && !draining) {
|
|
3433
|
-
runTimeout(drainQueue);
|
|
3434
|
-
}
|
|
3435
|
-
};
|
|
3436
|
-
|
|
3437
|
-
// v8 likes predictible objects
|
|
3438
|
-
function Item(fun, array) {
|
|
3439
|
-
this.fun = fun;
|
|
3440
|
-
this.array = array;
|
|
3441
|
-
}
|
|
3442
|
-
Item.prototype.run = function () {
|
|
3443
|
-
this.fun.apply(null, this.array);
|
|
3444
|
-
};
|
|
3445
|
-
process.title = 'browser';
|
|
3446
|
-
process.browser = true;
|
|
3447
|
-
process.env = {};
|
|
3448
|
-
process.argv = [];
|
|
3449
|
-
process.version = ''; // empty string to avoid regexp issues
|
|
3450
|
-
process.versions = {};
|
|
3451
|
-
|
|
3452
|
-
function noop() {}
|
|
3453
|
-
|
|
3454
|
-
process.on = noop;
|
|
3455
|
-
process.addListener = noop;
|
|
3456
|
-
process.once = noop;
|
|
3457
|
-
process.off = noop;
|
|
3458
|
-
process.removeListener = noop;
|
|
3459
|
-
process.removeAllListeners = noop;
|
|
3460
|
-
process.emit = noop;
|
|
3461
|
-
process.prependListener = noop;
|
|
3462
|
-
process.prependOnceListener = noop;
|
|
3463
|
-
|
|
3464
|
-
process.listeners = function (name) { return [] }
|
|
3465
|
-
|
|
3466
|
-
process.binding = function (name) {
|
|
3467
|
-
throw new Error('process.binding is not supported');
|
|
3468
|
-
};
|
|
3469
|
-
|
|
3470
|
-
process.cwd = function () { return '/' };
|
|
3471
|
-
process.chdir = function (dir) {
|
|
3472
|
-
throw new Error('process.chdir is not supported');
|
|
3473
|
-
};
|
|
3474
|
-
process.umask = function() { return 0; };
|
|
3475
|
-
|
|
3476
|
-
},{}]},{},[2])(2)
|
|
3477
|
-
});
|
|
3478
|
-
|
|
3479
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvYXBpL3N0cmVhbWluZy1leHRlbnNpb24uanMiLCJsaWIvYXBpL3N0cmVhbWluZy5qcyIsIm5vZGVfbW9kdWxlcy9hc2FwL2Jyb3dzZXItYXNhcC5qcyIsIm5vZGVfbW9kdWxlcy9hc2FwL2Jyb3dzZXItcmF3LmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL2ZheWVfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9taXhpbnMvZGVmZXJyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9taXhpbnMvbG9nZ2luZy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9taXhpbnMvcHVibGlzaGVyLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL21peGlucy90aW1lb3V0cy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9jaGFubmVsLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3Byb3RvY29sL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9kaXNwYXRjaGVyLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3Byb3RvY29sL2Vycm9yLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3Byb3RvY29sL2V4dGVuc2libGUuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvcHJvdG9jb2wvZ3JhbW1hci5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9wdWJsaWNhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9zY2hlZHVsZXIuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvcHJvdG9jb2wvc3Vic2NyaXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3RyYW5zcG9ydC9icm93c2VyX3RyYW5zcG9ydHMuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdHJhbnNwb3J0L2NvcnMuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdHJhbnNwb3J0L2V2ZW50X3NvdXJjZS5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy90cmFuc3BvcnQvanNvbnAuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdHJhbnNwb3J0L3RyYW5zcG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy90cmFuc3BvcnQvd2ViX3NvY2tldC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy90cmFuc3BvcnQveGhyLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvYXJyYXkuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9icm93c2VyL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvY2xhc3MuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9jb25zdGFudHMuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9jb29raWVzL2Jyb3dzZXJfY29va2llcy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL2NvcHlfb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvZXZlbnRfZW1pdHRlci5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL2V4dGVuZC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL3Byb21pc2UuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9zZXQuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC90b19qc29uLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvdXJpLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvdmFsaWRhdGVfb3B0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL3dlYnNvY2tldC9icm93c2VyX3dlYnNvY2tldC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3BJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbFlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbk5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNqS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8qKlxuICogRmF5ZSBDbGllbnQgZXh0ZW5zaW9uczogaHR0cHM6Ly9mYXllLmpjb2dsYW4uY29tL2Jyb3dzZXIvZXh0ZW5zaW9ucy5odG1sXG4gKlxuICogRm9yIHVzZSB3aXRoIFN0cmVhbWluZy5wcm90b3R5cGUuY3JlYXRlQ2xpZW50KClcbioqL1xudmFyIFN0cmVhbWluZ0V4dGVuc2lvbiA9IHt9O1xuXG4vKipcbiAqIENvbnN0cnVjdG9yIGZvciBhbiBhdXRoIGZhaWx1cmUgZGV0ZWN0b3IgZXh0ZW5zaW9uXG4gKlxuICogQmFzZWQgb24gbmV3IGZlYXR1cmUgcmVsZWFzZWQgd2l0aCBTYWxlc2ZvcmNlIFNwcmluZyAnMTg6XG4gKiBodHRwczovL3JlbGVhc2Vub3Rlcy5kb2NzLnNhbGVzZm9yY2UuY29tL2VuLXVzL3NwcmluZzE4L3JlbGVhc2Utbm90ZXMvcm5fbWVzc2FnaW5nX2NvbWV0ZF9hdXRoX3ZhbGlkYXRpb24uaHRtP2VkaXRpb249JmltcGFjdD1cbiAqXG4gKiBFeGFtcGxlIHRyaWdnZXJpbmcgZXJyb3IgbWVzc2FnZTpcbiAqXG4gKiBgYGBcbiAqIHtcbiAqICAgXCJleHRcIjp7XG4gKiAgICAgXCJzZmRjXCI6e1wiZmFpbHVyZVJlYXNvblwiOlwiNDAxOjpBdXRoZW50aWNhdGlvbiBpbnZhbGlkXCJ9LFxuICogICAgIFwicmVwbGF5XCI6dHJ1ZX0sXG4gKiAgIFwiYWR2aWNlXCI6e1wicmVjb25uZWN0XCI6XCJub25lXCJ9LFxuICogICBcImNoYW5uZWxcIjpcIi9tZXRhL2hhbmRzaGFrZVwiLFxuICogICBcImVycm9yXCI6XCI0MDM6OkhhbmRzaGFrZSBkZW5pZWRcIixcbiAqICAgXCJzdWNjZXNzZnVsXCI6ZmFsc2VcbiAqIH1cbiAqIGBgYFxuICpcbiAqIEV4YW1wbGUgdXNhZ2U6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3QgY29ubiA9IG5ldyBqc2ZvcmNlLkNvbm5lY3Rpb24oeyDigKYgfSk7XG4gKiBcbiAqIGNvbnN0IGNoYW5uZWwgPSBcIi9ldmVudC9NeV9FdmVudF9fZVwiO1xuICogXG4gKiAvLyBFeGl0IHRoZSBOb2RlIHByb2Nlc3Mgd2hlbiBhdXRoIGZhaWxzXG4gKiBjb25zdCBleGl0Q2FsbGJhY2sgPSAoKSA9PiBwcm9jZXNzLmV4aXQoMSk7XG4gKiBjb25zdCBhdXRoRmFpbHVyZUV4dCA9IG5ldyBqc2ZvcmNlLlN0cmVhbWluZ0V4dGVuc2lvbi5BdXRoRmFpbHVyZShleGl0Q2FsbGJhY2spO1xuICogXG4gKiBjb25zdCBmYXllQ2xpZW50ID0gY29ubi5zdHJlYW1pbmcuY3JlYXRlQ2xpZW50KFsgYXV0aEZhaWx1cmVFeHQgXSk7XG4gKiBcbiAqIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGZheWVDbGllbnQuc3Vic2NyaWJlKGNoYW5uZWwsIGRhdGEgPT4ge1xuICogICBjb25zb2xlLmxvZygndG9waWMgcmVjZWl2ZWQgZGF0YScsIGRhdGEpO1xuICogfSk7XG4gKiBcbiAqIHN1YnNjcmlwdGlvbi5jYW5jZWwoKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZhaWx1cmVDYWxsYmFjayAtIEludm9rZWQgd2hlbiBhdXRoZW50aWNhdGlvbiBiZWNvbWVzIGludmFsaWRcbiAqL1xuU3RyZWFtaW5nRXh0ZW5zaW9uLkF1dGhGYWlsdXJlID0gZnVuY3Rpb24oZmFpbHVyZUNhbGxiYWNrKSB7XG4gIHRoaXMuaW5jb21pbmcgPSBmdW5jdGlvbihtZXNzYWdlLCBjYWxsYmFjaykge1xuICAgIGlmIChcbiAgICAgIChtZXNzYWdlLmNoYW5uZWwgPT09ICcvbWV0YS9jb25uZWN0JyB8fFxuICAgICAgICBtZXNzYWdlLmNoYW5uZWwgPT09ICcvbWV0YS9oYW5kc2hha2UnKVxuICAgICAgJiYgbWVzc2FnZS5hZHZpY2VcbiAgICAgICYmIG1lc3NhZ2UuYWR2aWNlLnJlY29ubmVjdCA9PSAnbm9uZSdcbiAgICApIHtcbiAgICAgIGZhaWx1cmVDYWxsYmFjayhtZXNzYWdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbGJhY2sobWVzc2FnZSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIENvbnN0cnVjdG9yIGZvciBhIGR1cmFibGUgc3RyZWFtaW5nIHJlcGxheSBleHRlbnNpb25cbiAqXG4gKiBNb2RpZmllZCBmcm9tIG9yaWdpbmFsIFNhbGVzZm9yY2UgZGVtbyBzb3VyY2UgY29kZTpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9kZXZlbG9wZXJmb3JjZS9TYWxlc2ZvcmNlRHVyYWJsZVN0cmVhbWluZ0RlbW8vYmxvYi8zZDRhNTZlYWM5NTZmNzQ0YWQ2YzIyZTZhODE0MWI2ZmViNTdhYmI5L3N0YXRpY3Jlc291cmNlcy9jb21ldGRSZXBsYXlFeHRlbnNpb24ucmVzb3VyY2VcbiAqIFxuICogRXhhbXBsZSB1c2FnZTpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBjb25zdCBjb25uID0gbmV3IGpzZm9yY2UuQ29ubmVjdGlvbih7IOKApiB9KTtcbiAqIFxuICogY29uc3QgY2hhbm5lbCA9IFwiL2V2ZW50L015X0V2ZW50X19lXCI7XG4gKiBjb25zdCByZXBsYXlJZCA9IC0yOyAvLyAtMiBpcyBhbGwgcmV0YWluZWQgZXZlbnRzXG4gKiBcbiAqIGNvbnN0IHJlcGxheUV4dCA9IG5ldyBqc2ZvcmNlLlN0cmVhbWluZ0V4dGVuc2lvbi5SZXBsYXkoY2hhbm5lbCwgcmVwbGF5SWQpO1xuICogXG4gKiBjb25zdCBmYXllQ2xpZW50ID0gY29ubi5zdHJlYW1pbmcuY3JlYXRlQ2xpZW50KFsgcmVwbGF5RXh0IF0pO1xuICogXG4gKiBjb25zdCBzdWJzY3JpcHRpb24gPSBmYXllQ2xpZW50LnN1YnNjcmliZShjaGFubmVsLCBkYXRhID0+IHtcbiAqICAgY29uc29sZS5sb2coJ3RvcGljIHJlY2VpdmVkIGRhdGEnLCBkYXRhKTtcbiAqIH0pO1xuICogXG4gKiBzdWJzY3JpcHRpb24uY2FuY2VsKCk7XG4gKiBgYGBcbiAqL1xuU3RyZWFtaW5nRXh0ZW5zaW9uLlJlcGxheSA9IGZ1bmN0aW9uKGNoYW5uZWwsIHJlcGxheUlkKSB7XG4gIHZhciBSRVBMQVlfRlJPTV9LRVkgPSBcInJlcGxheVwiO1xuICBcbiAgdmFyIF9leHRlbnNpb25FbmFibGVkID0gcmVwbGF5SWQgIT0gbnVsbCA/IHRydWUgOiBmYWxzZTtcbiAgdmFyIF9yZXBsYXkgPSByZXBsYXlJZDtcbiAgdmFyIF9jaGFubmVsID0gY2hhbm5lbDtcblxuICB0aGlzLnNldEV4dGVuc2lvbkVuYWJsZWQgPSBmdW5jdGlvbihleHRlbnNpb25FbmFibGVkKSB7XG4gICAgX2V4dGVuc2lvbkVuYWJsZWQgPSBleHRlbnNpb25FbmFibGVkO1xuICB9XG5cbiAgdGhpcy5zZXRSZXBsYXkgPSBmdW5jdGlvbiAocmVwbGF5KSB7XG4gICAgX3JlcGxheSA9IHBhcnNlSW50KHJlcGxheSwgMTApO1xuICB9XG5cbiAgdGhpcy5zZXRDaGFubmVsID0gZnVuY3Rpb24oY2hhbm5lbCkge1xuICAgIF9jaGFubmVsID0gY2hhbm5lbDtcbiAgfVxuXG4gIHRoaXMuaW5jb21pbmcgPSBmdW5jdGlvbihtZXNzYWdlLCBjYWxsYmFjaykge1xuICAgIGlmIChtZXNzYWdlLmNoYW5uZWwgPT09ICcvbWV0YS9oYW5kc2hha2UnKSB7XG4gICAgICBpZiAobWVzc2FnZS5leHQgJiYgbWVzc2FnZS5leHRbUkVQTEFZX0ZST01fS0VZXSA9PSB0cnVlKSB7XG4gICAgICAgIF9leHRlbnNpb25FbmFibGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG1lc3NhZ2UuY2hhbm5lbCA9PT0gX2NoYW5uZWwgJiYgbWVzc2FnZS5kYXRhICYmIG1lc3NhZ2UuZGF0YS5ldmVudCAmJiBtZXNzYWdlLmRhdGEuZXZlbnQucmVwbGF5SWQpIHtcbiAgICAgIF9yZXBsYXkgPSBtZXNzYWdlLmRhdGEuZXZlbnQucmVwbGF5SWQ7XG4gICAgfVxuICAgIGNhbGxiYWNrKG1lc3NhZ2UpO1xuICB9XG4gIFxuICB0aGlzLm91dGdvaW5nID0gZnVuY3Rpb24obWVzc2FnZSwgY2FsbGJhY2spIHtcbiAgICBpZiAobWVzc2FnZS5jaGFubmVsID09PSAnL21ldGEvc3Vic2NyaWJlJyAmJiBtZXNzYWdlLnN1YnNjcmlwdGlvbiA9PT0gX2NoYW5uZWwpIHtcbiAgICAgIGlmIChfZXh0ZW5zaW9uRW5hYmxlZCkge1xuICAgICAgICBpZiAoIW1lc3NhZ2UuZXh0KSB7IG1lc3NhZ2UuZXh0ID0ge307IH1cblxuICAgICAgICB2YXIgcmVwbGF5RnJvbU1hcCA9IHt9O1xuICAgICAgICByZXBsYXlGcm9tTWFwW19jaGFubmVsXSA9IF9yZXBsYXk7XG5cbiAgICAgICAgLy8gYWRkIFwiZXh0IDogeyBcInJlcGxheVwiIDogeyBDSEFOTkVMIDogUkVQTEFZX1ZBTFVFIH19XCIgdG8gc3Vic2NyaWJlIG1lc3NhZ2VcbiAgICAgICAgbWVzc2FnZS5leHRbUkVQTEFZX0ZST01fS0VZXSA9IHJlcGxheUZyb21NYXA7XG4gICAgICB9XG4gICAgfVxuICAgIGNhbGxiYWNrKG1lc3NhZ2UpO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1pbmdFeHRlbnNpb247XG4iLCIvKipcbiAqIEBmaWxlIE1hbmFnZXMgU3RyZWFtaW5nIEFQSXNcbiAqIEBhdXRob3IgU2hpbmljaGkgVG9taXRhIDxzaGluaWNoaS50b21pdGFAZ21haWwuY29tPlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGV2ZW50cyA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2V2ZW50cycpLFxuICAgIGluaGVyaXRzID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnaW5oZXJpdHMnKSxcbiAgICBfID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnbG9kYXNoL2NvcmUnKSxcbiAgICBGYXllICAgPSByZXF1aXJlKCdmYXllJyksXG4gICAgU3RyZWFtaW5nRXh0ZW5zaW9uID0gcmVxdWlyZSgnLi9zdHJlYW1pbmctZXh0ZW5zaW9uJyksXG4gICAganNmb3JjZSA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJy4vY29yZScpO1xuXG4vKipcbiAqIFN0cmVhbWluZyBBUEkgdG9waWMgY2xhc3NcbiAqXG4gKiBAY2xhc3MgU3RyZWFtaW5nflRvcGljXG4gKiBAcGFyYW0ge1N0cmVhbWluZ30gc3RlYW1pbmcgLSBTdHJlYW1pbmcgQVBJIG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKi9cbnZhciBUb3BpYyA9IGZ1bmN0aW9uKHN0cmVhbWluZywgbmFtZSkge1xuICB0aGlzLl9zdHJlYW1pbmcgPSBzdHJlYW1pbmc7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFN0cmVhbWluZ35TdHJlYW1pbmdNZXNzYWdlXG4gKiBAcHJvcCB7T2JqZWN0fSBldmVudFxuICogQHByb3Age09iamVjdH0gZXZlbnQudHlwZSAtIEV2ZW50IHR5cGVcbiAqIEBwcm9wIHtSZWNvcmR9IHNvYmplY3QgLSBSZWNvcmQgaW5mb3JtYXRpb25cbiAqL1xuLyoqXG4gKiBTdWJzY3JpYmUgbGlzdGVuZXIgdG8gdG9waWNcbiAqXG4gKiBAbWV0aG9kIFN0cmVhbWluZ35Ub3BpYyNzdWJzY3JpYmVcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPFN0cmVhbWluZ35TdHJlYW1pbmdNZXNhc2dlPn0gbGlzdGVuZXIgLSBTdHJlYW1pbmcgbWVzc2FnZSBsaXN0ZW5lclxuICogQHJldHVybnMge1N1YnNjcmlwdGlvbn0gLSBGYXllIHN1YnNjcmlwdGlvbiBvYmplY3RcbiAqL1xuVG9waWMucHJvdG90eXBlLnN1YnNjcmliZSA9IGZ1bmN0aW9uKGxpc3RlbmVyKSB7XG4gIHJldHVybiB0aGlzLl9zdHJlYW1pbmcuc3Vic2NyaWJlKHRoaXMubmFtZSwgbGlzdGVuZXIpO1xufTtcblxuLyoqXG4gKiBVbnN1YnNjcmliZSBsaXN0ZW5lciBmcm9tIHRvcGljXG4gKlxuICogQG1ldGhvZCBTdHJlYW1pbmd+VG9waWMjdW5zdWJzY3JpYmVcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPFN0cmVhbWluZ35TdHJlYW1pbmdNZXNhc2dlPn0gbGlzdGVuZXIgLSBTdHJlYW1pbmcgbWVzc2FnZSBsaXN0ZW5lclxuICogQHJldHVybnMge1N0cmVhbWluZ35Ub3BpY31cbiAqL1xuVG9waWMucHJvdG90eXBlLnVuc3Vic2NyaWJlID0gZnVuY3Rpb24obGlzdGVuZXIpIHtcbiAgdGhpcy5fc3RyZWFtaW5nLnVuc3Vic2NyaWJlKHRoaXMubmFtZSwgbGlzdGVuZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vKipcbiAqIFN0cmVhbWluZyBBUEkgR2VuZXJpYyBTdHJlYW1pbmcgQ2hhbm5lbFxuICpcbiAqIEBjbGFzcyBTdHJlYW1pbmd+Q2hhbm5lbFxuICogQHBhcmFtIHtTdHJlYW1pbmd9IHN0ZWFtaW5nIC0gU3RyZWFtaW5nIEFQSSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gQ2hhbm5lbCBuYW1lIChzdGFydHMgd2l0aCBcIi91L1wiKVxuICovXG52YXIgQ2hhbm5lbCA9IGZ1bmN0aW9uKHN0cmVhbWluZywgbmFtZSkge1xuICB0aGlzLl9zdHJlYW1pbmcgPSBzdHJlYW1pbmc7XG4gIHRoaXMuX25hbWUgPSBuYW1lO1xufTtcblxuLyoqXG4gKiBTdWJzY3JpYmUgdG8gY2hhbm5lbFxuICpcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPFN0cmVhbWluZ35TdHJlYW1pbmdNZXNzYWdlPn0gbGlzdGVuZXIgLSBTdHJlYW1pbmcgbWVzc2FnZSBsaXN0ZW5lclxuICogQHJldHVybnMge1N1YnNjcmlwdGlvbn0gLSBGYXllIHN1YnNjcmlwdGlvbiBvYmplY3RcbiAqL1xuQ2hhbm5lbC5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24obGlzdGVuZXIpIHtcbiAgcmV0dXJuIHRoaXMuX3N0cmVhbWluZy5zdWJzY3JpYmUodGhpcy5fbmFtZSwgbGlzdGVuZXIpO1xufTtcblxuQ2hhbm5lbC5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbihsaXN0ZW5lcikge1xuICB0aGlzLl9zdHJlYW1pbmcudW5zdWJzY3JpYmUodGhpcy5fbmFtZSwgbGlzdGVuZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkNoYW5uZWwucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbihldmVudHMsIGNhbGxiYWNrKSB7XG4gIHZhciBpc0FycmF5ID0gXy5pc0FycmF5KGV2ZW50cyk7XG4gIGV2ZW50cyA9IGlzQXJyYXkgPyBldmVudHMgOiBbIGV2ZW50cyBdO1xuICB2YXIgY29ubiA9IHRoaXMuX3N0cmVhbWluZy5fY29ubjtcbiAgaWYgKCF0aGlzLl9pZCkge1xuICAgIHRoaXMuX2lkID0gY29ubi5zb2JqZWN0KCdTdHJlYW1pbmdDaGFubmVsJykuZmluZE9uZSh7IE5hbWU6IHRoaXMuX25hbWUgfSwgJ0lkJylcbiAgICAgIC50aGVuKGZ1bmN0aW9uKHJlYykgeyByZXR1cm4gcmVjLklkIH0pO1xuICB9XG4gIHJldHVybiB0aGlzLl9pZC50aGVuKGZ1bmN0aW9uKGlkKSB7XG4gICAgdmFyIGNoYW5uZWxVcmwgPSAnL3NvYmplY3RzL1N0cmVhbWluZ0NoYW5uZWwvJyArIGlkICsgJy9wdXNoJztcbiAgICByZXR1cm4gY29ubi5yZXF1ZXN0UG9zdChjaGFubmVsVXJsLCB7IHB1c2hFdmVudHM6IGV2ZW50cyB9KTtcbiAgfSkudGhlbihmdW5jdGlvbihyZXRzKSB7XG4gICAgcmV0dXJuIGlzQXJyYXkgPyByZXRzIDogcmV0c1swXTtcbiAgfSkudGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi8qKlxuICogU3RyZWFtaW5nIEFQSSBjbGFzc1xuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgZXZlbnRzLkV2ZW50RW1pdHRlclxuICogQHBhcmFtIHtDb25uZWN0aW9ufSBjb25uIC0gQ29ubmVjdGlvbiBvYmplY3RcbiAqL1xudmFyIFN0cmVhbWluZyA9IGZ1bmN0aW9uKGNvbm4pIHtcbiAgdGhpcy5fY29ubiA9IGNvbm47XG59O1xuXG5pbmhlcml0cyhTdHJlYW1pbmcsIGV2ZW50cy5FdmVudEVtaXR0ZXIpO1xuXG4vKiogQHByaXZhdGUgKiovXG5TdHJlYW1pbmcucHJvdG90eXBlLl9jcmVhdGVDbGllbnQgPSBmdW5jdGlvbihmb3JDaGFubmVsTmFtZSwgZXh0ZW5zaW9ucykge1xuICAvLyBmb3JDaGFubmVsTmFtZSBpcyBhZHZpc29yeSwgZm9yIGFuIEFQSSB3b3JrYXJvdW5kLiBJdCBkb2VzIG5vdCByZXN0cmljdCBvciBzZWxlY3QgdGhlIGNoYW5uZWwuXG4gIHZhciBuZWVkc1JlcGxheUZpeCA9IHR5cGVvZiBmb3JDaGFubmVsTmFtZSA9PT0gJ3N0cmluZycgJiYgZm9yQ2hhbm5lbE5hbWUuaW5kZXhPZignL3UvJykgPT09IDA7XG4gIHZhciBlbmRwb2ludFVybCA9IFtcbiAgICB0aGlzLl9jb25uLmluc3RhbmNlVXJsLFxuICAgIC8vIHNwZWNpYWwgZW5kcG9pbnQgXCIvY29tZXRkL3JlcGxheS94eC54XCIgaXMgb25seSBhdmFpbGFibGUgaW4gMzYuMC5cbiAgICAvLyBTZWUgaHR0cHM6Ly9yZWxlYXNlbm90ZXMuZG9jcy5zYWxlc2ZvcmNlLmNvbS9lbi11cy9zdW1tZXIxNi9yZWxlYXNlLW5vdGVzL3JuX2FwaV9zdHJlYW1pbmdfY2xhc3NpY19yZXBsYXkuaHRtXG4gICAgXCJjb21ldGRcIiArIChuZWVkc1JlcGxheUZpeCA9PT0gdHJ1ZSAmJiB0aGlzLl9jb25uLnZlcnNpb24gPT09IFwiMzYuMFwiID8gXCIvcmVwbGF5XCIgOiBcIlwiKSxcbiAgICB0aGlzLl9jb25uLnZlcnNpb25cbiAgXS5qb2luKCcvJyk7XG4gIHZhciBmYXllQ2xpZW50ID0gbmV3IEZheWUuQ2xpZW50KGVuZHBvaW50VXJsLCB7fSk7XG4gIGZheWVDbGllbnQuc2V0SGVhZGVyKCdBdXRob3JpemF0aW9uJywgJ09BdXRoICcrdGhpcy5fY29ubi5hY2Nlc3NUb2tlbik7XG4gIGlmIChleHRlbnNpb25zIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBleHRlbnNpb25zLmZvckVhY2goZnVuY3Rpb24oZXh0ZW5zaW9uKSB7XG4gICAgICBmYXllQ2xpZW50LmFkZEV4dGVuc2lvbihleHRlbnNpb24pO1xuICAgIH0pO1xuICB9XG4gIGlmIChmYXllQ2xpZW50Ll9kaXNwYXRjaGVyLmdldENvbm5lY3Rpb25UeXBlcygpLmluZGV4T2YoJ2NhbGxiYWNrLXBvbGxpbmcnKSA9PT0gLTEpIHtcbiAgICAvLyBwcmV2ZW50IHN0cmVhbWluZyBBUEkgc2VydmVyIGVycm9yXG4gICAgZmF5ZUNsaWVudC5fZGlzcGF0Y2hlci5zZWxlY3RUcmFuc3BvcnQoJ2xvbmctcG9sbGluZycpO1xuICAgIGZheWVDbGllbnQuX2Rpc3BhdGNoZXIuX3RyYW5zcG9ydC5iYXRjaGluZyA9IGZhbHNlO1xuICB9XG4gIHJldHVybiBmYXllQ2xpZW50O1xufTtcblxuLyoqIEBwcml2YXRlICoqL1xuU3RyZWFtaW5nLnByb3RvdHlwZS5fZ2V0RmF5ZUNsaWVudCA9IGZ1bmN0aW9uKGNoYW5uZWxOYW1lKSB7XG4gIHZhciBpc0dlbmVyaWMgPSBjaGFubmVsTmFtZS5pbmRleE9mKCcvdS8nKSA9PT0gMDtcbiAgdmFyIGNsaWVudFR5cGUgPSBpc0dlbmVyaWMgPyAnZ2VuZXJpYycgOiAncHVzaFRvcGljJztcbiAgaWYgKCF0aGlzLl9mYXllQ2xpZW50cyB8fCAhdGhpcy5fZmF5ZUNsaWVudHNbY2xpZW50VHlwZV0pIHtcbiAgICB0aGlzLl9mYXllQ2xpZW50cyA9IHRoaXMuX2ZheWVDbGllbnRzIHx8IHt9O1xuICAgIHRoaXMuX2ZheWVDbGllbnRzW2NsaWVudFR5cGVdID0gdGhpcy5fY3JlYXRlQ2xpZW50KGNoYW5uZWxOYW1lKTtcbiAgfVxuICByZXR1cm4gdGhpcy5fZmF5ZUNsaWVudHNbY2xpZW50VHlwZV07XG59O1xuXG5cbi8qKlxuICogR2V0IG5hbWVkIHRvcGljXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKiBAcmV0dXJucyB7U3RyZWFtaW5nflRvcGljfVxuICovXG5TdHJlYW1pbmcucHJvdG90eXBlLnRvcGljID0gZnVuY3Rpb24obmFtZSkge1xuICB0aGlzLl90b3BpY3MgPSB0aGlzLl90b3BpY3MgfHwge307XG4gIHZhciB0b3BpYyA9IHRoaXMuX3RvcGljc1tuYW1lXSA9XG4gICAgdGhpcy5fdG9waWNzW25hbWVdIHx8IG5ldyBUb3BpYyh0aGlzLCBuYW1lKTtcbiAgcmV0dXJuIHRvcGljO1xufTtcblxuLyoqXG4gKiBHZXQgQ2hhbm5lbCBmb3IgSWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsSWQgLSBJZCBvZiBTdHJlYW1pbmdDaGFubmVsIG9iamVjdFxuICogQHJldHVybnMge1N0cmVhbWluZ35DaGFubmVsfVxuICovXG5TdHJlYW1pbmcucHJvdG90eXBlLmNoYW5uZWwgPSBmdW5jdGlvbihjaGFubmVsSWQpIHtcbiAgcmV0dXJuIG5ldyBDaGFubmVsKHRoaXMsIGNoYW5uZWxJZCk7XG59O1xuXG4vKipcbiAqIFN1YnNjcmliZSB0b3BpYy9jaGFubmVsXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxTdHJlYW1pbmd+U3RyZWFtaW5nTWVzc2FnZT59IGxpc3RlbmVyIC0gU3RyZWFtaW5nIG1lc3NhZ2UgbGlzdGVuZXJcbiAqIEByZXR1cm5zIHtTdWJzY3JpcHRpb259IC0gRmF5ZSBzdWJzY3JpcHRpb24gb2JqZWN0XG4gKi9cblN0cmVhbWluZy5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24obmFtZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGNoYW5uZWxOYW1lID0gbmFtZS5pbmRleE9mKCcvJykgPT09IDAgPyBuYW1lIDogJy90b3BpYy8nICsgbmFtZTtcbiAgdmFyIGZheWVDbGllbnQgPSB0aGlzLl9nZXRGYXllQ2xpZW50KGNoYW5uZWxOYW1lKTtcbiAgcmV0dXJuIGZheWVDbGllbnQuc3Vic2NyaWJlKGNoYW5uZWxOYW1lLCBsaXN0ZW5lcik7XG59O1xuXG4vKipcbiAqIFVuc3Vic2NyaWJlIHRvcGljXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxTdHJlYW1pbmd+U3RyZWFtaW5nTWVzc2FnZT59IGxpc3RlbmVyIC0gU3RyZWFtaW5nIG1lc3NhZ2UgbGlzdGVuZXJcbiAqIEByZXR1cm5zIHtTdHJlYW1pbmd9XG4gKi9cblN0cmVhbWluZy5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbihuYW1lLCBsaXN0ZW5lcikge1xuICB2YXIgY2hhbm5lbE5hbWUgPSBuYW1lLmluZGV4T2YoJy8nKSA9PT0gMCA/IG5hbWUgOiAnL3RvcGljLycgKyBuYW1lO1xuICB2YXIgZmF5ZUNsaWVudCA9IHRoaXMuX2dldEZheWVDbGllbnQoY2hhbm5lbE5hbWUpO1xuICBmYXllQ2xpZW50LnVuc3Vic2NyaWJlKGNoYW5uZWxOYW1lLCBsaXN0ZW5lcik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZSBhIFN0cmVhbWluZyBjbGllbnQsIG9wdGlvbmFsbHkgd2l0aCBleHRlbnNpb25zXG4gKlxuICogU2VlIEZheWUgZG9jcyBmb3IgaW1wbGVtZW50YXRpb24gZGV0YWlsczogaHR0cHM6Ly9mYXllLmpjb2dsYW4uY29tL2Jyb3dzZXIvZXh0ZW5zaW9ucy5odG1sXG4gKlxuICogRXhhbXBsZSB1c2FnZTpcbiAqIFxuICogYGBgamF2YXNjcmlwdFxuICogLy8gRXN0YWJsaXNoIGEgU2FsZXNmb3JjZSBjb25uZWN0aW9uLiAoRGV0YWlscyBlbGlkZWQpXG4gKiBjb25zdCBjb25uID0gbmV3IGpzZm9yY2UuQ29ubmVjdGlvbih7IOKApiB9KTtcbiAqIFxuICogY29uc3QgZmF5ZUNsaWVudCA9IGNvbm4uc3RyZWFtaW5nLmNyZWF0ZUNsaWVudCgpO1xuICogXG4gKiBjb25zdCBzdWJzY3JpcHRpb24gPSBmYXllQ2xpZW50LnN1YnNjcmliZShjaGFubmVsLCBkYXRhID0+IHtcbiAqICAgY29uc29sZS5sb2coJ3RvcGljIHJlY2VpdmVkIGRhdGEnLCBkYXRhKTtcbiAqIH0pO1xuICogXG4gKiBzdWJzY3JpcHRpb24uY2FuY2VsKCk7XG4gKiBgYGBcbiAqIFxuICogRXhhbXBsZSB3aXRoIGV4dGVuc2lvbnMsIHVzaW5nIFJlcGxheSAmIEF1dGggRmFpbHVyZSBleHRlbnNpb25zIGluIGEgc2VydmVyLXNpZGUgTm9kZS5qcyBhcHA6XG4gKiBcbiAqIGBgYGphdmFzY3JpcHRcbiAqIC8vIEVzdGFibGlzaCBhIFNhbGVzZm9yY2UgY29ubmVjdGlvbi4gKERldGFpbHMgZWxpZGVkKVxuICogY29uc3QgY29ubiA9IG5ldyBqc2ZvcmNlLkNvbm5lY3Rpb24oeyDigKYgfSk7XG4gKiBcbiAqIGNvbnN0IGNoYW5uZWwgPSBcIi9ldmVudC9NeV9FdmVudF9fZVwiO1xuICogY29uc3QgcmVwbGF5SWQgPSAtMjsgLy8gLTIgaXMgYWxsIHJldGFpbmVkIGV2ZW50c1xuICogXG4gKiBjb25zdCBleGl0Q2FsbGJhY2sgPSAoKSA9PiBwcm9jZXNzLmV4aXQoMSk7XG4gKiBjb25zdCBhdXRoRmFpbHVyZUV4dCA9IG5ldyBqc2ZvcmNlLlN0cmVhbWluZ0V4dGVuc2lvbi5BdXRoRmFpbHVyZShleGl0Q2FsbGJhY2spO1xuICogXG4gKiBjb25zdCByZXBsYXlFeHQgPSBuZXcganNmb3JjZS5TdHJlYW1pbmdFeHRlbnNpb24uUmVwbGF5KGNoYW5uZWwsIHJlcGxheUlkKTtcbiAqIFxuICogY29uc3QgZmF5ZUNsaWVudCA9IGNvbm4uc3RyZWFtaW5nLmNyZWF0ZUNsaWVudChbXG4gKiAgIGF1dGhGYWlsdXJlRXh0LFxuICogICByZXBsYXlFeHRcbiAqIF0pO1xuICogXG4gKiBjb25zdCBzdWJzY3JpcHRpb24gPSBmYXllQ2xpZW50LnN1YnNjcmliZShjaGFubmVsLCBkYXRhID0+IHtcbiAqICAgY29uc29sZS5sb2coJ3RvcGljIHJlY2VpdmVkIGRhdGEnLCBkYXRhKTtcbiAqIH0pO1xuICogXG4gKiBzdWJzY3JpcHRpb24uY2FuY2VsKCk7XG4gKiBgYGBcbiAqIFxuICogQHBhcmFtIHtBcnJheX0gRXh0ZW5zaW9ucyAtIE9wdGlvbmFsLCBleHRlbnNpb25zIHRvIGFwcGx5IHRvIHRoZSBGYXllIGNsaWVudFxuICogQHJldHVybnMge0ZheWVDbGllbnR9IC0gRmF5ZSBjbGllbnQgb2JqZWN0XG4gKi9cblN0cmVhbWluZy5wcm90b3R5cGUuY3JlYXRlQ2xpZW50ID0gZnVuY3Rpb24oZXh0ZW5zaW9ucykge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlQ2xpZW50KG51bGwsIGV4dGVuc2lvbnMpO1xufTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKlxuICogUmVnaXN0ZXIgaG9vayBpbiBjb25uZWN0aW9uIGluc3RhbnRpYXRpb24gZm9yIGR5bmFtaWNhbGx5IGFkZGluZyB0aGlzIEFQSSBtb2R1bGUgZmVhdHVyZXNcbiAqL1xuanNmb3JjZS5vbignY29ubmVjdGlvbjpuZXcnLCBmdW5jdGlvbihjb25uKSB7XG4gIGNvbm4uc3RyZWFtaW5nID0gbmV3IFN0cmVhbWluZyhjb25uKTtcbn0pO1xuXG4vKlxuICogXG4gKi9cbmpzZm9yY2UuU3RyZWFtaW5nRXh0ZW5zaW9uID0gU3RyZWFtaW5nRXh0ZW5zaW9uO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmVhbWluZztcbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vLyByYXdBc2FwIHByb3ZpZGVzIGV2ZXJ5dGhpbmcgd2UgbmVlZCBleGNlcHQgZXhjZXB0aW9uIG1hbmFnZW1lbnQuXG52YXIgcmF3QXNhcCA9IHJlcXVpcmUoXCIuL3Jhd1wiKTtcbi8vIFJhd1Rhc2tzIGFyZSByZWN5Y2xlZCB0byByZWR1Y2UgR0MgY2h1cm4uXG52YXIgZnJlZVRhc2tzID0gW107XG4vLyBXZSBxdWV1ZSBlcnJvcnMgdG8gZW5zdXJlIHRoZXkgYXJlIHRocm93biBpbiByaWdodCBvcmRlciAoRklGTykuXG4vLyBBcnJheS1hcy1xdWV1ZSBpcyBnb29kIGVub3VnaCBoZXJlLCBzaW5jZSB3ZSBhcmUganVzdCBkZWFsaW5nIHdpdGggZXhjZXB0aW9ucy5cbnZhciBwZW5kaW5nRXJyb3JzID0gW107XG52YXIgcmVxdWVzdEVycm9yVGhyb3cgPSByYXdBc2FwLm1ha2VSZXF1ZXN0Q2FsbEZyb21UaW1lcih0aHJvd0ZpcnN0RXJyb3IpO1xuXG5mdW5jdGlvbiB0aHJvd0ZpcnN0RXJyb3IoKSB7XG4gICAgaWYgKHBlbmRpbmdFcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IHBlbmRpbmdFcnJvcnMuc2hpZnQoKTtcbiAgICB9XG59XG5cbi8qKlxuICogQ2FsbHMgYSB0YXNrIGFzIHNvb24gYXMgcG9zc2libGUgYWZ0ZXIgcmV0dXJuaW5nLCBpbiBpdHMgb3duIGV2ZW50LCB3aXRoIHByaW9yaXR5XG4gKiBvdmVyIG90aGVyIGV2ZW50cyBsaWtlIGFuaW1hdGlvbiwgcmVmbG93LCBhbmQgcmVwYWludC4gQW4gZXJyb3IgdGhyb3duIGZyb20gYW5cbiAqIGV2ZW50IHdpbGwgbm90IGludGVycnVwdCwgbm9yIGV2ZW4gc3Vic3RhbnRpYWxseSBzbG93IGRvd24gdGhlIHByb2Nlc3Npbmcgb2ZcbiAqIG90aGVyIGV2ZW50cywgYnV0IHdpbGwgYmUgcmF0aGVyIHBvc3Rwb25lZCB0byBhIGxvd2VyIHByaW9yaXR5IGV2ZW50LlxuICogQHBhcmFtIHt7Y2FsbH19IHRhc2sgQSBjYWxsYWJsZSBvYmplY3QsIHR5cGljYWxseSBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgbm9cbiAqIGFyZ3VtZW50cy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBhc2FwO1xuZnVuY3Rpb24gYXNhcCh0YXNrKSB7XG4gICAgdmFyIHJhd1Rhc2s7XG4gICAgaWYgKGZyZWVUYXNrcy5sZW5ndGgpIHtcbiAgICAgICAgcmF3VGFzayA9IGZyZWVUYXNrcy5wb3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByYXdUYXNrID0gbmV3IFJhd1Rhc2soKTtcbiAgICB9XG4gICAgcmF3VGFzay50YXNrID0gdGFzaztcbiAgICByYXdBc2FwKHJhd1Rhc2spO1xufVxuXG4vLyBXZSB3cmFwIHRhc2tzIHdpdGggcmVjeWNsYWJsZSB0YXNrIG9iamVjdHMuICBBIHRhc2sgb2JqZWN0IGltcGxlbWVudHNcbi8vIGBjYWxsYCwganVzdCBsaWtlIGEgZnVuY3Rpb24uXG5mdW5jdGlvbiBSYXdUYXNrKCkge1xuICAgIHRoaXMudGFzayA9IG51bGw7XG59XG5cbi8vIFRoZSBzb2xlIHB1cnBvc2Ugb2Ygd3JhcHBpbmcgdGhlIHRhc2sgaXMgdG8gY2F0Y2ggdGhlIGV4Y2VwdGlvbiBhbmQgcmVjeWNsZVxuLy8gdGhlIHRhc2sgb2JqZWN0IGFmdGVyIGl0cyBzaW5nbGUgdXNlLlxuUmF3VGFzay5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICB0aGlzLnRhc2suY2FsbCgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChhc2FwLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgaG9vayBleGlzdHMgcHVyZWx5IGZvciB0ZXN0aW5nIHB1cnBvc2VzLlxuICAgICAgICAgICAgLy8gSXRzIG5hbWUgd2lsbCBiZSBwZXJpb2RpY2FsbHkgcmFuZG9taXplZCB0byBicmVhayBhbnkgY29kZSB0aGF0XG4gICAgICAgICAgICAvLyBkZXBlbmRzIG9uIGl0cyBleGlzdGVuY2UuXG4gICAgICAgICAgICBhc2FwLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSW4gYSB3ZWIgYnJvd3NlciwgZXhjZXB0aW9ucyBhcmUgbm90IGZhdGFsLiBIb3dldmVyLCB0byBhdm9pZFxuICAgICAgICAgICAgLy8gc2xvd2luZyBkb3duIHRoZSBxdWV1ZSBvZiBwZW5kaW5nIHRhc2tzLCB3ZSByZXRocm93IHRoZSBlcnJvciBpbiBhXG4gICAgICAgICAgICAvLyBsb3dlciBwcmlvcml0eSB0dXJuLlxuICAgICAgICAgICAgcGVuZGluZ0Vycm9ycy5wdXNoKGVycm9yKTtcbiAgICAgICAgICAgIHJlcXVlc3RFcnJvclRocm93KCk7XG4gICAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLnRhc2sgPSBudWxsO1xuICAgICAgICBmcmVlVGFza3NbZnJlZVRhc2tzLmxlbmd0aF0gPSB0aGlzO1xuICAgIH1cbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuLy8gVXNlIHRoZSBmYXN0ZXN0IG1lYW5zIHBvc3NpYmxlIHRvIGV4ZWN1dGUgYSB0YXNrIGluIGl0cyBvd24gdHVybiwgd2l0aFxuLy8gcHJpb3JpdHkgb3ZlciBvdGhlciBldmVudHMgaW5jbHVkaW5nIElPLCBhbmltYXRpb24sIHJlZmxvdywgYW5kIHJlZHJhd1xuLy8gZXZlbnRzIGluIGJyb3dzZXJzLlxuLy9cbi8vIEFuIGV4Y2VwdGlvbiB0aHJvd24gYnkgYSB0YXNrIHdpbGwgcGVybWFuZW50bHkgaW50ZXJydXB0IHRoZSBwcm9jZXNzaW5nIG9mXG4vLyBzdWJzZXF1ZW50IHRhc2tzLiBUaGUgaGlnaGVyIGxldmVsIGBhc2FwYCBmdW5jdGlvbiBlbnN1cmVzIHRoYXQgaWYgYW5cbi8vIGV4Y2VwdGlvbiBpcyB0aHJvd24gYnkgYSB0YXNrLCB0aGF0IHRoZSB0YXNrIHF1ZXVlIHdpbGwgY29udGludWUgZmx1c2hpbmcgYXNcbi8vIHNvb24gYXMgcG9zc2libGUsIGJ1dCBpZiB5b3UgdXNlIGByYXdBc2FwYCBkaXJlY3RseSwgeW91IGFyZSByZXNwb25zaWJsZSB0b1xuLy8gZWl0aGVyIGVuc3VyZSB0aGF0IG5vIGV4Y2VwdGlvbnMgYXJlIHRocm93biBmcm9tIHlvdXIgdGFzaywgb3IgdG8gbWFudWFsbHlcbi8vIGNhbGwgYHJhd0FzYXAucmVxdWVzdEZsdXNoYCBpZiBhbiBleGNlcHRpb24gaXMgdGhyb3duLlxubW9kdWxlLmV4cG9ydHMgPSByYXdBc2FwO1xuZnVuY3Rpb24gcmF3QXNhcCh0YXNrKSB7XG4gICAgaWYgKCFxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcmVxdWVzdEZsdXNoKCk7XG4gICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICB9XG4gICAgLy8gRXF1aXZhbGVudCB0byBwdXNoLCBidXQgYXZvaWRzIGEgZnVuY3Rpb24gY2FsbC5cbiAgICBxdWV1ZVtxdWV1ZS5sZW5ndGhdID0gdGFzaztcbn1cblxudmFyIHF1ZXVlID0gW107XG4vLyBPbmNlIGEgZmx1c2ggaGFzIGJlZW4gcmVxdWVzdGVkLCBubyBmdXJ0aGVyIGNhbGxzIHRvIGByZXF1ZXN0Rmx1c2hgIGFyZVxuLy8gbmVjZXNzYXJ5IHVudGlsIHRoZSBuZXh0IGBmbHVzaGAgY29tcGxldGVzLlxudmFyIGZsdXNoaW5nID0gZmFsc2U7XG4vLyBgcmVxdWVzdEZsdXNoYCBpcyBhbiBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyBtZXRob2QgdGhhdCBhdHRlbXB0cyB0byBraWNrXG4vLyBvZmYgYSBgZmx1c2hgIGV2ZW50IGFzIHF1aWNrbHkgYXMgcG9zc2libGUuIGBmbHVzaGAgd2lsbCBhdHRlbXB0IHRvIGV4aGF1c3Rcbi8vIHRoZSBldmVudCBxdWV1ZSBiZWZvcmUgeWllbGRpbmcgdG8gdGhlIGJyb3dzZXIncyBvd24gZXZlbnQgbG9vcC5cbnZhciByZXF1ZXN0Rmx1c2g7XG4vLyBUaGUgcG9zaXRpb24gb2YgdGhlIG5leHQgdGFzayB0byBleGVjdXRlIGluIHRoZSB0YXNrIHF1ZXVlLiBUaGlzIGlzXG4vLyBwcmVzZXJ2ZWQgYmV0d2VlbiBjYWxscyB0byBgZmx1c2hgIHNvIHRoYXQgaXQgY2FuIGJlIHJlc3VtZWQgaWZcbi8vIGEgdGFzayB0aHJvd3MgYW4gZXhjZXB0aW9uLlxudmFyIGluZGV4ID0gMDtcbi8vIElmIGEgdGFzayBzY2hlZHVsZXMgYWRkaXRpb25hbCB0YXNrcyByZWN1cnNpdmVseSwgdGhlIHRhc2sgcXVldWUgY2FuIGdyb3dcbi8vIHVuYm91bmRlZC4gVG8gcHJldmVudCBtZW1vcnkgZXhoYXVzdGlvbiwgdGhlIHRhc2sgcXVldWUgd2lsbCBwZXJpb2RpY2FsbHlcbi8vIHRydW5jYXRlIGFscmVhZHktY29tcGxldGVkIHRhc2tzLlxudmFyIGNhcGFjaXR5ID0gMTAyNDtcblxuLy8gVGhlIGZsdXNoIGZ1bmN0aW9uIHByb2Nlc3NlcyBhbGwgdGFza3MgdGhhdCBoYXZlIGJlZW4gc2NoZWR1bGVkIHdpdGhcbi8vIGByYXdBc2FwYCB1bmxlc3MgYW5kIHVudGlsIG9uZSBvZiB0aG9zZSB0YXNrcyB0aHJvd3MgYW4gZXhjZXB0aW9uLlxuLy8gSWYgYSB0YXNrIHRocm93cyBhbiBleGNlcHRpb24sIGBmbHVzaGAgZW5zdXJlcyB0aGF0IGl0cyBzdGF0ZSB3aWxsIHJlbWFpblxuLy8gY29uc2lzdGVudCBhbmQgd2lsbCByZXN1bWUgd2hlcmUgaXQgbGVmdCBvZmYgd2hlbiBjYWxsZWQgYWdhaW4uXG4vLyBIb3dldmVyLCBgZmx1c2hgIGRvZXMgbm90IG1ha2UgYW55IGFycmFuZ2VtZW50cyB0byBiZSBjYWxsZWQgYWdhaW4gaWYgYW5cbi8vIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG5mdW5jdGlvbiBmbHVzaCgpIHtcbiAgICB3aGlsZSAoaW5kZXggPCBxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRJbmRleCA9IGluZGV4O1xuICAgICAgICAvLyBBZHZhbmNlIHRoZSBpbmRleCBiZWZvcmUgY2FsbGluZyB0aGUgdGFzay4gVGhpcyBlbnN1cmVzIHRoYXQgd2Ugd2lsbFxuICAgICAgICAvLyBiZWdpbiBmbHVzaGluZyBvbiB0aGUgbmV4dCB0YXNrIHRoZSB0YXNrIHRocm93cyBhbiBlcnJvci5cbiAgICAgICAgaW5kZXggPSBpbmRleCArIDE7XG4gICAgICAgIHF1ZXVlW2N1cnJlbnRJbmRleF0uY2FsbCgpO1xuICAgICAgICAvLyBQcmV2ZW50IGxlYWtpbmcgbWVtb3J5IGZvciBsb25nIGNoYWlucyBvZiByZWN1cnNpdmUgY2FsbHMgdG8gYGFzYXBgLlxuICAgICAgICAvLyBJZiB3ZSBjYWxsIGBhc2FwYCB3aXRoaW4gdGFza3Mgc2NoZWR1bGVkIGJ5IGBhc2FwYCwgdGhlIHF1ZXVlIHdpbGxcbiAgICAgICAgLy8gZ3JvdywgYnV0IHRvIGF2b2lkIGFuIE8obikgd2FsayBmb3IgZXZlcnkgdGFzayB3ZSBleGVjdXRlLCB3ZSBkb24ndFxuICAgICAgICAvLyBzaGlmdCB0YXNrcyBvZmYgdGhlIHF1ZXVlIGFmdGVyIHRoZXkgaGF2ZSBiZWVuIGV4ZWN1dGVkLlxuICAgICAgICAvLyBJbnN0ZWFkLCB3ZSBwZXJpb2RpY2FsbHkgc2hpZnQgMTAyNCB0YXNrcyBvZmYgdGhlIHF1ZXVlLlxuICAgICAgICBpZiAoaW5kZXggPiBjYXBhY2l0eSkge1xuICAgICAgICAgICAgLy8gTWFudWFsbHkgc2hpZnQgYWxsIHZhbHVlcyBzdGFydGluZyBhdCB0aGUgaW5kZXggYmFjayB0byB0aGVcbiAgICAgICAgICAgIC8vIGJlZ2lubmluZyBvZiB0aGUgcXVldWUuXG4gICAgICAgICAgICBmb3IgKHZhciBzY2FuID0gMCwgbmV3TGVuZ3RoID0gcXVldWUubGVuZ3RoIC0gaW5kZXg7IHNjYW4gPCBuZXdMZW5ndGg7IHNjYW4rKykge1xuICAgICAgICAgICAgICAgIHF1ZXVlW3NjYW5dID0gcXVldWVbc2NhbiArIGluZGV4XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHF1ZXVlLmxlbmd0aCAtPSBpbmRleDtcbiAgICAgICAgICAgIGluZGV4ID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5sZW5ndGggPSAwO1xuICAgIGluZGV4ID0gMDtcbiAgICBmbHVzaGluZyA9IGZhbHNlO1xufVxuXG4vLyBgcmVxdWVzdEZsdXNoYCBpcyBpbXBsZW1lbnRlZCB1c2luZyBhIHN0cmF0ZWd5IGJhc2VkIG9uIGRhdGEgY29sbGVjdGVkIGZyb21cbi8vIGV2ZXJ5IGF2YWlsYWJsZSBTYXVjZUxhYnMgU2VsZW5pdW0gd2ViIGRyaXZlciB3b3JrZXIgYXQgdGltZSBvZiB3cml0aW5nLlxuLy8gaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMW1HLTVVWUd1cDVxeEdkRU1Xa2hQNkJXQ3owNTNOVWIyRTFRb1VUVTE2dUEvZWRpdCNnaWQ9NzgzNzI0NTkzXG5cbi8vIFNhZmFyaSA2IGFuZCA2LjEgZm9yIGRlc2t0b3AsIGlQYWQsIGFuZCBpUGhvbmUgYXJlIHRoZSBvbmx5IGJyb3dzZXJzIHRoYXRcbi8vIGhhdmUgV2ViS2l0TXV0YXRpb25PYnNlcnZlciBidXQgbm90IHVuLXByZWZpeGVkIE11dGF0aW9uT2JzZXJ2ZXIuXG4vLyBNdXN0IHVzZSBgZ2xvYmFsYCBvciBgc2VsZmAgaW5zdGVhZCBvZiBgd2luZG93YCB0byB3b3JrIGluIGJvdGggZnJhbWVzIGFuZCB3ZWJcbi8vIHdvcmtlcnMuIGBnbG9iYWxgIGlzIGEgcHJvdmlzaW9uIG9mIEJyb3dzZXJpZnksIE1yLCBNcnMsIG9yIE1vcC5cblxuLyogZ2xvYmFscyBzZWxmICovXG52YXIgc2NvcGUgPSB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogc2VsZjtcbnZhciBCcm93c2VyTXV0YXRpb25PYnNlcnZlciA9IHNjb3BlLk11dGF0aW9uT2JzZXJ2ZXIgfHwgc2NvcGUuV2ViS2l0TXV0YXRpb25PYnNlcnZlcjtcblxuLy8gTXV0YXRpb25PYnNlcnZlcnMgYXJlIGRlc2lyYWJsZSBiZWNhdXNlIHRoZXkgaGF2ZSBoaWdoIHByaW9yaXR5IGFuZCB3b3JrXG4vLyByZWxpYWJseSBldmVyeXdoZXJlIHRoZXkgYXJlIGltcGxlbWVudGVkLlxuLy8gVGhleSBhcmUgaW1wbGVtZW50ZWQgaW4gYWxsIG1vZGVybiBicm93c2Vycy5cbi8vXG4vLyAtIEFuZHJvaWQgNC00LjNcbi8vIC0gQ2hyb21lIDI2LTM0XG4vLyAtIEZpcmVmb3ggMTQtMjlcbi8vIC0gSW50ZXJuZXQgRXhwbG9yZXIgMTFcbi8vIC0gaVBhZCBTYWZhcmkgNi03LjFcbi8vIC0gaVBob25lIFNhZmFyaSA3LTcuMVxuLy8gLSBTYWZhcmkgNi03XG5pZiAodHlwZW9mIEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICByZXF1ZXN0Rmx1c2ggPSBtYWtlUmVxdWVzdENhbGxGcm9tTXV0YXRpb25PYnNlcnZlcihmbHVzaCk7XG5cbi8vIE1lc3NhZ2VDaGFubmVscyBhcmUgZGVzaXJhYmxlIGJlY2F1c2UgdGhleSBnaXZlIGRpcmVjdCBhY2Nlc3MgdG8gdGhlIEhUTUxcbi8vIHRhc2sgcXVldWUsIGFyZSBpbXBsZW1lbnRlZCBpbiBJbnRlcm5ldCBFeHBsb3JlciAxMCwgU2FmYXJpIDUuMC0xLCBhbmQgT3BlcmFcbi8vIDExLTEyLCBhbmQgaW4gd2ViIHdvcmtlcnMgaW4gbWFueSBlbmdpbmVzLlxuLy8gQWx0aG91Z2ggbWVzc2FnZSBjaGFubmVscyB5aWVsZCB0byBhbnkgcXVldWVkIHJlbmRlcmluZyBhbmQgSU8gdGFza3MsIHRoZXlcbi8vIHdvdWxkIGJlIGJldHRlciB0aGFuIGltcG9zaW5nIHRoZSA0bXMgZGVsYXkgb2YgdGltZXJzLlxuLy8gSG93ZXZlciwgdGhleSBkbyBub3Qgd29yayByZWxpYWJseSBpbiBJbnRlcm5ldCBFeHBsb3JlciBvciBTYWZhcmkuXG5cbi8vIEludGVybmV0IEV4cGxvcmVyIDEwIGlzIHRoZSBvbmx5IGJyb3dzZXIgdGhhdCBoYXMgc2V0SW1tZWRpYXRlIGJ1dCBkb2VzXG4vLyBub3QgaGF2ZSBNdXRhdGlvbk9ic2VydmVycy5cbi8vIEFsdGhvdWdoIHNldEltbWVkaWF0ZSB5aWVsZHMgdG8gdGhlIGJyb3dzZXIncyByZW5kZXJlciwgaXQgd291bGQgYmVcbi8vIHByZWZlcnJhYmxlIHRvIGZhbGxpbmcgYmFjayB0byBzZXRUaW1lb3V0IHNpbmNlIGl0IGRvZXMgbm90IGhhdmVcbi8vIHRoZSBtaW5pbXVtIDRtcyBwZW5hbHR5LlxuLy8gVW5mb3J0dW5hdGVseSB0aGVyZSBhcHBlYXJzIHRvIGJlIGEgYnVnIGluIEludGVybmV0IEV4cGxvcmVyIDEwIE1vYmlsZSAoYW5kXG4vLyBEZXNrdG9wIHRvIGEgbGVzc2VyIGV4dGVudCkgdGhhdCByZW5kZXJzIGJvdGggc2V0SW1tZWRpYXRlIGFuZFxuLy8gTWVzc2FnZUNoYW5uZWwgdXNlbGVzcyBmb3IgdGhlIHB1cnBvc2VzIG9mIEFTQVAuXG4vLyBodHRwczovL2dpdGh1Yi5jb20va3Jpc2tvd2FsL3EvaXNzdWVzLzM5NlxuXG4vLyBUaW1lcnMgYXJlIGltcGxlbWVudGVkIHVuaXZlcnNhbGx5LlxuLy8gV2UgZmFsbCBiYWNrIHRvIHRpbWVycyBpbiB3b3JrZXJzIGluIG1vc3QgZW5naW5lcywgYW5kIGluIGZvcmVncm91bmRcbi8vIGNvbnRleHRzIGluIHRoZSBmb2xsb3dpbmcgYnJvd3NlcnMuXG4vLyBIb3dldmVyLCBub3RlIHRoYXQgZXZlbiB0aGlzIHNpbXBsZSBjYXNlIHJlcXVpcmVzIG51YW5jZXMgdG8gb3BlcmF0ZSBpbiBhXG4vLyBicm9hZCBzcGVjdHJ1bSBvZiBicm93c2Vycy5cbi8vXG4vLyAtIEZpcmVmb3ggMy0xM1xuLy8gLSBJbnRlcm5ldCBFeHBsb3JlciA2LTlcbi8vIC0gaVBhZCBTYWZhcmkgNC4zXG4vLyAtIEx5bnggMi44Ljdcbn0gZWxzZSB7XG4gICAgcmVxdWVzdEZsdXNoID0gbWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyKGZsdXNoKTtcbn1cblxuLy8gYHJlcXVlc3RGbHVzaGAgcmVxdWVzdHMgdGhhdCB0aGUgaGlnaCBwcmlvcml0eSBldmVudCBxdWV1ZSBiZSBmbHVzaGVkIGFzXG4vLyBzb29uIGFzIHBvc3NpYmxlLlxuLy8gVGhpcyBpcyB1c2VmdWwgdG8gcHJldmVudCBhbiBlcnJvciB0aHJvd24gaW4gYSB0YXNrIGZyb20gc3RhbGxpbmcgdGhlIGV2ZW50XG4vLyBxdWV1ZSBpZiB0aGUgZXhjZXB0aW9uIGhhbmRsZWQgYnkgTm9kZS5qc+KAmXNcbi8vIGBwcm9jZXNzLm9uKFwidW5jYXVnaHRFeGNlcHRpb25cIilgIG9yIGJ5IGEgZG9tYWluLlxucmF3QXNhcC5yZXF1ZXN0Rmx1c2ggPSByZXF1ZXN0Rmx1c2g7XG5cbi8vIFRvIHJlcXVlc3QgYSBoaWdoIHByaW9yaXR5IGV2ZW50LCB3ZSBpbmR1Y2UgYSBtdXRhdGlvbiBvYnNlcnZlciBieSB0b2dnbGluZ1xuLy8gdGhlIHRleHQgb2YgYSB0ZXh0IG5vZGUgYmV0d2VlbiBcIjFcIiBhbmQgXCItMVwiLlxuZnVuY3Rpb24gbWFrZVJlcXVlc3RDYWxsRnJvbU11dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spIHtcbiAgICB2YXIgdG9nZ2xlID0gMTtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spO1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCJcIik7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShub2RlLCB7Y2hhcmFjdGVyRGF0YTogdHJ1ZX0pO1xuICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbiAgICAgICAgdG9nZ2xlID0gLXRvZ2dsZTtcbiAgICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlO1xuICAgIH07XG59XG5cbi8vIFRoZSBtZXNzYWdlIGNoYW5uZWwgdGVjaG5pcXVlIHdhcyBkaXNjb3ZlcmVkIGJ5IE1hbHRlIFVibCBhbmQgd2FzIHRoZVxuLy8gb3JpZ2luYWwgZm91bmRhdGlvbiBmb3IgdGhpcyBsaWJyYXJ5LlxuLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcblxuLy8gU2FmYXJpIDYuMC41IChhdCBsZWFzdCkgaW50ZXJtaXR0ZW50bHkgZmFpbHMgdG8gY3JlYXRlIG1lc3NhZ2UgcG9ydHMgb24gYVxuLy8gcGFnZSdzIGZpcnN0IGxvYWQuIFRoYW5rZnVsbHksIHRoaXMgdmVyc2lvbiBvZiBTYWZhcmkgc3VwcG9ydHNcbi8vIE11dGF0aW9uT2JzZXJ2ZXJzLCBzbyB3ZSBkb24ndCBuZWVkIHRvIGZhbGwgYmFjayBpbiB0aGF0IGNhc2UuXG5cbi8vIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21NZXNzYWdlQ2hhbm5lbChjYWxsYmFjaykge1xuLy8gICAgIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4vLyAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBjYWxsYmFjaztcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gcmVxdWVzdENhbGwoKSB7XG4vLyAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4vLyAgICAgfTtcbi8vIH1cblxuLy8gRm9yIHJlYXNvbnMgZXhwbGFpbmVkIGFib3ZlLCB3ZSBhcmUgYWxzbyB1bmFibGUgdG8gdXNlIGBzZXRJbW1lZGlhdGVgXG4vLyB1bmRlciBhbnkgY2lyY3Vtc3RhbmNlcy5cbi8vIEV2ZW4gaWYgd2Ugd2VyZSwgdGhlcmUgaXMgYW5vdGhlciBidWcgaW4gSW50ZXJuZXQgRXhwbG9yZXIgMTAuXG4vLyBJdCBpcyBub3Qgc3VmZmljaWVudCB0byBhc3NpZ24gYHNldEltbWVkaWF0ZWAgdG8gYHJlcXVlc3RGbHVzaGAgYmVjYXVzZVxuLy8gYHNldEltbWVkaWF0ZWAgbXVzdCBiZSBjYWxsZWQgKmJ5IG5hbWUqIGFuZCB0aGVyZWZvcmUgbXVzdCBiZSB3cmFwcGVkIGluIGFcbi8vIGNsb3N1cmUuXG4vLyBOZXZlciBmb3JnZXQuXG5cbi8vIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21TZXRJbW1lZGlhdGUoY2FsbGJhY2spIHtcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gcmVxdWVzdENhbGwoKSB7XG4vLyAgICAgICAgIHNldEltbWVkaWF0ZShjYWxsYmFjayk7XG4vLyAgICAgfTtcbi8vIH1cblxuLy8gU2FmYXJpIDYuMCBoYXMgYSBwcm9ibGVtIHdoZXJlIHRpbWVycyB3aWxsIGdldCBsb3N0IHdoaWxlIHRoZSB1c2VyIGlzXG4vLyBzY3JvbGxpbmcuIFRoaXMgcHJvYmxlbSBkb2VzIG5vdCBpbXBhY3QgQVNBUCBiZWNhdXNlIFNhZmFyaSA2LjAgc3VwcG9ydHNcbi8vIG11dGF0aW9uIG9ic2VydmVycywgc28gdGhhdCBpbXBsZW1lbnRhdGlvbiBpcyB1c2VkIGluc3RlYWQuXG4vLyBIb3dldmVyLCBpZiB3ZSBldmVyIGVsZWN0IHRvIHVzZSB0aW1lcnMgaW4gU2FmYXJpLCB0aGUgcHJldmFsZW50IHdvcmstYXJvdW5kXG4vLyBpcyB0byBhZGQgYSBzY3JvbGwgZXZlbnQgbGlzdGVuZXIgdGhhdCBjYWxscyBmb3IgYSBmbHVzaC5cblxuLy8gYHNldFRpbWVvdXRgIGRvZXMgbm90IGNhbGwgdGhlIHBhc3NlZCBjYWxsYmFjayBpZiB0aGUgZGVsYXkgaXMgbGVzcyB0aGFuXG4vLyBhcHByb3hpbWF0ZWx5IDcgaW4gd2ViIHdvcmtlcnMgaW4gRmlyZWZveCA4IHRocm91Z2ggMTgsIGFuZCBzb21ldGltZXMgbm90XG4vLyBldmVuIHRoZW4uXG5cbmZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21UaW1lcihjYWxsYmFjaykge1xuICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbiAgICAgICAgLy8gV2UgZGlzcGF0Y2ggYSB0aW1lb3V0IHdpdGggYSBzcGVjaWZpZWQgZGVsYXkgb2YgMCBmb3IgZW5naW5lcyB0aGF0XG4gICAgICAgIC8vIGNhbiByZWxpYWJseSBhY2NvbW1vZGF0ZSB0aGF0IHJlcXVlc3QuIFRoaXMgd2lsbCB1c3VhbGx5IGJlIHNuYXBwZWRcbiAgICAgICAgLy8gdG8gYSA0IG1pbGlzZWNvbmQgZGVsYXksIGJ1dCBvbmNlIHdlJ3JlIGZsdXNoaW5nLCB0aGVyZSdzIG5vIGRlbGF5XG4gICAgICAgIC8vIGJldHdlZW4gZXZlbnRzLlxuICAgICAgICB2YXIgdGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoaGFuZGxlVGltZXIsIDApO1xuICAgICAgICAvLyBIb3dldmVyLCBzaW5jZSB0aGlzIHRpbWVyIGdldHMgZnJlcXVlbnRseSBkcm9wcGVkIGluIEZpcmVmb3hcbiAgICAgICAgLy8gd29ya2Vycywgd2UgZW5saXN0IGFuIGludGVydmFsIGhhbmRsZSB0aGF0IHdpbGwgdHJ5IHRvIGZpcmVcbiAgICAgICAgLy8gYW4gZXZlbnQgMjAgdGltZXMgcGVyIHNlY29uZCB1bnRpbCBpdCBzdWNjZWVkcy5cbiAgICAgICAgdmFyIGludGVydmFsSGFuZGxlID0gc2V0SW50ZXJ2YWwoaGFuZGxlVGltZXIsIDUwKTtcblxuICAgICAgICBmdW5jdGlvbiBoYW5kbGVUaW1lcigpIHtcbiAgICAgICAgICAgIC8vIFdoaWNoZXZlciB0aW1lciBzdWNjZWVkcyB3aWxsIGNhbmNlbCBib3RoIHRpbWVycyBhbmRcbiAgICAgICAgICAgIC8vIGV4ZWN1dGUgdGhlIGNhbGxiYWNrLlxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRIYW5kbGUpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbEhhbmRsZSk7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfTtcbn1cblxuLy8gVGhpcyBpcyBmb3IgYGFzYXAuanNgIG9ubHkuXG4vLyBJdHMgbmFtZSB3aWxsIGJlIHBlcmlvZGljYWxseSByYW5kb21pemVkIHRvIGJyZWFrIGFueSBjb2RlIHRoYXQgZGVwZW5kcyBvblxuLy8gaXRzIGV4aXN0ZW5jZS5cbnJhd0FzYXAubWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyID0gbWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyO1xuXG4vLyBBU0FQIHdhcyBvcmlnaW5hbGx5IGEgbmV4dFRpY2sgc2hpbSBpbmNsdWRlZCBpbiBRLiBUaGlzIHdhcyBmYWN0b3JlZCBvdXRcbi8vIGludG8gdGhpcyBBU0FQIHBhY2thZ2UuIEl0IHdhcyBsYXRlciBhZGFwdGVkIHRvIFJTVlAgd2hpY2ggbWFkZSBmdXJ0aGVyXG4vLyBhbWVuZG1lbnRzLiBUaGVzZSBkZWNpc2lvbnMsIHBhcnRpY3VsYXJseSB0byBtYXJnaW5hbGl6ZSBNZXNzYWdlQ2hhbm5lbCBhbmRcbi8vIHRvIGNhcHR1cmUgdGhlIE11dGF0aW9uT2JzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaW4gYSBjbG9zdXJlLCB3ZXJlIGludGVncmF0ZWRcbi8vIGJhY2sgaW50byBBU0FQIHByb3Blci5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90aWxkZWlvL3JzdnAuanMvYmxvYi9jZGRmNzIzMjU0NmE5Y2Y4NTg1MjRiNzVjZGU2ZjllZGY3MjYyMGE3L2xpYi9yc3ZwL2FzYXAuanNcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbnN0YW50cyA9IHJlcXVpcmUoJy4vdXRpbC9jb25zdGFudHMnKSxcbiAgICBMb2dnaW5nICAgPSByZXF1aXJlKCcuL21peGlucy9sb2dnaW5nJyk7XG5cbnZhciBGYXllID0ge1xuICBWRVJTSU9OOiAgICBjb25zdGFudHMuVkVSU0lPTixcblxuICBDbGllbnQ6ICAgICByZXF1aXJlKCcuL3Byb3RvY29sL2NsaWVudCcpLFxuICBTY2hlZHVsZXI6ICByZXF1aXJlKCcuL3Byb3RvY29sL3NjaGVkdWxlcicpXG59O1xuXG5Mb2dnaW5nLndyYXBwZXIgPSBGYXllO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZheWU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBQcm9taXNlICAgPSByZXF1aXJlKCcuLi91dGlsL3Byb21pc2UnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHRoZW46IGZ1bmN0aW9uKGNhbGxiYWNrLCBlcnJiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICghdGhpcy5fcHJvbWlzZSlcbiAgICAgIHRoaXMuX3Byb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5fcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIHNlbGYuX3JlamVjdCAgPSByZWplY3Q7XG4gICAgICB9KTtcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2UudGhlbihjYWxsYmFjaywgZXJyYmFjayk7XG4gIH0sXG5cbiAgY2FsbGJhY2s6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbih2YWx1ZSkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQsIHZhbHVlKSB9KTtcbiAgfSxcblxuICBlcnJiYWNrOiBmdW5jdGlvbihjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4obnVsbCwgZnVuY3Rpb24ocmVhc29uKSB7IGNhbGxiYWNrLmNhbGwoY29udGV4dCwgcmVhc29uKSB9KTtcbiAgfSxcblxuICB0aW1lb3V0OiBmdW5jdGlvbihzZWNvbmRzLCBtZXNzYWdlKSB7XG4gICAgdGhpcy50aGVuKCk7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuX3RpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLl9yZWplY3QobWVzc2FnZSk7XG4gICAgfSwgc2Vjb25kcyAqIDEwMDApO1xuICB9LFxuXG4gIHNldERlZmVycmVkU3RhdHVzOiBmdW5jdGlvbihzdGF0dXMsIHZhbHVlKSB7XG4gICAgaWYgKHRoaXMuX3RpbWVyKSBnbG9iYWwuY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcblxuICAgIHRoaXMudGhlbigpO1xuXG4gICAgaWYgKHN0YXR1cyA9PT0gJ3N1Y2NlZWRlZCcpXG4gICAgICB0aGlzLl9yZXNvbHZlKHZhbHVlKTtcbiAgICBlbHNlIGlmIChzdGF0dXMgPT09ICdmYWlsZWQnKVxuICAgICAgdGhpcy5fcmVqZWN0KHZhbHVlKTtcbiAgICBlbHNlXG4gICAgICBkZWxldGUgdGhpcy5fcHJvbWlzZTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHRvSlNPTiA9IHJlcXVpcmUoJy4uL3V0aWwvdG9fanNvbicpO1xuXG52YXIgTG9nZ2luZyA9IHtcbiAgTE9HX0xFVkVMUzoge1xuICAgIGZhdGFsOiAgNCxcbiAgICBlcnJvcjogIDMsXG4gICAgd2FybjogICAyLFxuICAgIGluZm86ICAgMSxcbiAgICBkZWJ1ZzogIDBcbiAgfSxcblxuICB3cml0ZUxvZzogZnVuY3Rpb24obWVzc2FnZUFyZ3MsIGxldmVsKSB7XG4gICAgdmFyIGxvZ2dlciA9IExvZ2dpbmcubG9nZ2VyIHx8IChMb2dnaW5nLndyYXBwZXIgfHwgTG9nZ2luZykubG9nZ2VyO1xuICAgIGlmICghbG9nZ2VyKSByZXR1cm47XG5cbiAgICB2YXIgYXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KG1lc3NhZ2VBcmdzKSxcbiAgICAgICAgYmFubmVyID0gJ1tGYXllJyxcbiAgICAgICAga2xhc3MgID0gdGhpcy5jbGFzc05hbWUsXG5cbiAgICAgICAgbWVzc2FnZSA9IGFyZ3Muc2hpZnQoKS5yZXBsYWNlKC9cXD8vZywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiB0b0pTT04oYXJncy5zaGlmdCgpKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuICdbT2JqZWN0XSc7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIGlmIChrbGFzcykgYmFubmVyICs9ICcuJyArIGtsYXNzO1xuICAgIGJhbm5lciArPSAnXSAnO1xuXG4gICAgaWYgKHR5cGVvZiBsb2dnZXJbbGV2ZWxdID09PSAnZnVuY3Rpb24nKVxuICAgICAgbG9nZ2VyW2xldmVsXShiYW5uZXIgKyBtZXNzYWdlKTtcbiAgICBlbHNlIGlmICh0eXBlb2YgbG9nZ2VyID09PSAnZnVuY3Rpb24nKVxuICAgICAgbG9nZ2VyKGJhbm5lciArIG1lc3NhZ2UpO1xuICB9XG59O1xuXG5mb3IgKHZhciBrZXkgaW4gTG9nZ2luZy5MT0dfTEVWRUxTKVxuICAoZnVuY3Rpb24obGV2ZWwpIHtcbiAgICBMb2dnaW5nW2xldmVsXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy53cml0ZUxvZyhhcmd1bWVudHMsIGxldmVsKTtcbiAgICB9O1xuICB9KShrZXkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExvZ2dpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL3V0aWwvZXZlbnRfZW1pdHRlcicpO1xuXG52YXIgUHVibGlzaGVyID0ge1xuICBjb3VudExpc3RlbmVyczogZnVuY3Rpb24oZXZlbnRUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzKGV2ZW50VHlwZSkubGVuZ3RoO1xuICB9LFxuXG4gIGJpbmQ6IGZ1bmN0aW9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIGNvbnRleHQpIHtcbiAgICB2YXIgc2xpY2UgICA9IEFycmF5LnByb3RvdHlwZS5zbGljZSxcbiAgICAgICAgaGFuZGxlciA9IGZ1bmN0aW9uKCkgeyBsaXN0ZW5lci5hcHBseShjb250ZXh0LCBzbGljZS5jYWxsKGFyZ3VtZW50cykpIH07XG5cbiAgICB0aGlzLl9saXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnMgfHwgW107XG4gICAgdGhpcy5fbGlzdGVuZXJzLnB1c2goW2V2ZW50VHlwZSwgbGlzdGVuZXIsIGNvbnRleHQsIGhhbmRsZXJdKTtcbiAgICByZXR1cm4gdGhpcy5vbihldmVudFR5cGUsIGhhbmRsZXIpO1xuICB9LFxuXG4gIHVuYmluZDogZnVuY3Rpb24oZXZlbnRUeXBlLCBsaXN0ZW5lciwgY29udGV4dCkge1xuICAgIHRoaXMuX2xpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycyB8fCBbXTtcbiAgICB2YXIgbiA9IHRoaXMuX2xpc3RlbmVycy5sZW5ndGgsIHR1cGxlO1xuXG4gICAgd2hpbGUgKG4tLSkge1xuICAgICAgdHVwbGUgPSB0aGlzLl9saXN0ZW5lcnNbbl07XG4gICAgICBpZiAodHVwbGVbMF0gIT09IGV2ZW50VHlwZSkgY29udGludWU7XG4gICAgICBpZiAobGlzdGVuZXIgJiYgKHR1cGxlWzFdICE9PSBsaXN0ZW5lciB8fCB0dXBsZVsyXSAhPT0gY29udGV4dCkpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5fbGlzdGVuZXJzLnNwbGljZShuLCAxKTtcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCB0dXBsZVszXSk7XG4gICAgfVxuICB9XG59O1xuXG5leHRlbmQoUHVibGlzaGVyLCBFdmVudEVtaXR0ZXIucHJvdG90eXBlKTtcblB1Ymxpc2hlci50cmlnZ2VyID0gUHVibGlzaGVyLmVtaXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gUHVibGlzaGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYWRkVGltZW91dDogZnVuY3Rpb24obmFtZSwgZGVsYXksIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fdGltZW91dHMgPSB0aGlzLl90aW1lb3V0cyB8fCB7fTtcbiAgICBpZiAodGhpcy5fdGltZW91dHMuaGFzT3duUHJvcGVydHkobmFtZSkpIHJldHVybjtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5fdGltZW91dHNbbmFtZV0gPSBnbG9iYWwuc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIGRlbGV0ZSBzZWxmLl90aW1lb3V0c1tuYW1lXTtcbiAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCk7XG4gICAgfSwgMTAwMCAqIGRlbGF5KTtcbiAgfSxcblxuICByZW1vdmVUaW1lb3V0OiBmdW5jdGlvbihuYW1lKSB7XG4gICAgdGhpcy5fdGltZW91dHMgPSB0aGlzLl90aW1lb3V0cyB8fCB7fTtcbiAgICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXRzW25hbWVdO1xuICAgIGlmICghdGltZW91dCkgcmV0dXJuO1xuICAgIGdsb2JhbC5jbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgZGVsZXRlIHRoaXMuX3RpbWVvdXRzW25hbWVdO1xuICB9LFxuXG4gIHJlbW92ZUFsbFRpbWVvdXRzOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl90aW1lb3V0cyA9IHRoaXMuX3RpbWVvdXRzIHx8IHt9O1xuICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcy5fdGltZW91dHMpIHRoaXMucmVtb3ZlVGltZW91dChuYW1lKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBleHRlbmQgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIFB1Ymxpc2hlciA9IHJlcXVpcmUoJy4uL21peGlucy9wdWJsaXNoZXInKSxcbiAgICBHcmFtbWFyICAgPSByZXF1aXJlKCcuL2dyYW1tYXInKTtcblxudmFyIENoYW5uZWwgPSBDbGFzcyh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB0aGlzLmlkID0gdGhpcy5uYW1lID0gbmFtZTtcbiAgfSxcblxuICBwdXNoOiBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgdGhpcy50cmlnZ2VyKCdtZXNzYWdlJywgbWVzc2FnZSk7XG4gIH0sXG5cbiAgaXNVbnVzZWQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNvdW50TGlzdGVuZXJzKCdtZXNzYWdlJykgPT09IDA7XG4gIH1cbn0pO1xuXG5leHRlbmQoQ2hhbm5lbC5wcm90b3R5cGUsIFB1Ymxpc2hlcik7XG5cbmV4dGVuZChDaGFubmVsLCB7XG4gIEhBTkRTSEFLRTogICAgJy9tZXRhL2hhbmRzaGFrZScsXG4gIENPTk5FQ1Q6ICAgICAgJy9tZXRhL2Nvbm5lY3QnLFxuICBTVUJTQ1JJQkU6ICAgICcvbWV0YS9zdWJzY3JpYmUnLFxuICBVTlNVQlNDUklCRTogICcvbWV0YS91bnN1YnNjcmliZScsXG4gIERJU0NPTk5FQ1Q6ICAgJy9tZXRhL2Rpc2Nvbm5lY3QnLFxuXG4gIE1FVEE6ICAgICAgICAgJ21ldGEnLFxuICBTRVJWSUNFOiAgICAgICdzZXJ2aWNlJyxcblxuICBleHBhbmQ6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgc2VnbWVudHMgPSB0aGlzLnBhcnNlKG5hbWUpLFxuICAgICAgICBjaGFubmVscyA9IFsnLyoqJywgbmFtZV07XG5cbiAgICB2YXIgY29weSA9IHNlZ21lbnRzLnNsaWNlKCk7XG4gICAgY29weVtjb3B5Lmxlbmd0aCAtIDFdID0gJyonO1xuICAgIGNoYW5uZWxzLnB1c2godGhpcy51bnBhcnNlKGNvcHkpKTtcblxuICAgIGZvciAodmFyIGkgPSAxLCBuID0gc2VnbWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICBjb3B5ID0gc2VnbWVudHMuc2xpY2UoMCwgaSk7XG4gICAgICBjb3B5LnB1c2goJyoqJyk7XG4gICAgICBjaGFubmVscy5wdXNoKHRoaXMudW5wYXJzZShjb3B5KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNoYW5uZWxzO1xuICB9LFxuXG4gIGlzVmFsaWQ6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gR3JhbW1hci5DSEFOTkVMX05BTUUudGVzdChuYW1lKSB8fFxuICAgICAgICAgICBHcmFtbWFyLkNIQU5ORUxfUEFUVEVSTi50ZXN0KG5hbWUpO1xuICB9LFxuXG4gIHBhcnNlOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQobmFtZSkpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBuYW1lLnNwbGl0KCcvJykuc2xpY2UoMSk7XG4gIH0sXG5cbiAgdW5wYXJzZTogZnVuY3Rpb24oc2VnbWVudHMpIHtcbiAgICByZXR1cm4gJy8nICsgc2VnbWVudHMuam9pbignLycpO1xuICB9LFxuXG4gIGlzTWV0YTogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBzZWdtZW50cyA9IHRoaXMucGFyc2UobmFtZSk7XG4gICAgcmV0dXJuIHNlZ21lbnRzID8gKHNlZ21lbnRzWzBdID09PSB0aGlzLk1FVEEpIDogbnVsbDtcbiAgfSxcblxuICBpc1NlcnZpY2U6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgc2VnbWVudHMgPSB0aGlzLnBhcnNlKG5hbWUpO1xuICAgIHJldHVybiBzZWdtZW50cyA/IChzZWdtZW50c1swXSA9PT0gdGhpcy5TRVJWSUNFKSA6IG51bGw7XG4gIH0sXG5cbiAgaXNTdWJzY3JpYmFibGU6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZChuYW1lKSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuICF0aGlzLmlzTWV0YShuYW1lKSAmJiAhdGhpcy5pc1NlcnZpY2UobmFtZSk7XG4gIH0sXG5cbiAgU2V0OiBDbGFzcyh7XG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLl9jaGFubmVscyA9IHt9O1xuICAgIH0sXG5cbiAgICBnZXRLZXlzOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrZXlzID0gW107XG4gICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5fY2hhbm5lbHMpIGtleXMucHVzaChrZXkpO1xuICAgICAgcmV0dXJuIGtleXM7XG4gICAgfSxcblxuICAgIHJlbW92ZTogZnVuY3Rpb24obmFtZSkge1xuICAgICAgZGVsZXRlIHRoaXMuX2NoYW5uZWxzW25hbWVdO1xuICAgIH0sXG5cbiAgICBoYXNTdWJzY3JpcHRpb246IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jaGFubmVscy5oYXNPd25Qcm9wZXJ0eShuYW1lKTtcbiAgICB9LFxuXG4gICAgc3Vic2NyaWJlOiBmdW5jdGlvbihuYW1lcywgc3Vic2NyaXB0aW9uKSB7XG4gICAgICB2YXIgbmFtZTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBuID0gbmFtZXMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lc1tpXTtcbiAgICAgICAgdmFyIGNoYW5uZWwgPSB0aGlzLl9jaGFubmVsc1tuYW1lXSA9IHRoaXMuX2NoYW5uZWxzW25hbWVdIHx8IG5ldyBDaGFubmVsKG5hbWUpO1xuICAgICAgICBjaGFubmVsLmJpbmQoJ21lc3NhZ2UnLCBzdWJzY3JpcHRpb24pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICB1bnN1YnNjcmliZTogZnVuY3Rpb24obmFtZSwgc3Vic2NyaXB0aW9uKSB7XG4gICAgICB2YXIgY2hhbm5lbCA9IHRoaXMuX2NoYW5uZWxzW25hbWVdO1xuICAgICAgaWYgKCFjaGFubmVsKSByZXR1cm4gZmFsc2U7XG4gICAgICBjaGFubmVsLnVuYmluZCgnbWVzc2FnZScsIHN1YnNjcmlwdGlvbik7XG5cbiAgICAgIGlmIChjaGFubmVsLmlzVW51c2VkKCkpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUobmFtZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBkaXN0cmlidXRlTWVzc2FnZTogZnVuY3Rpb24obWVzc2FnZSkge1xuICAgICAgdmFyIGNoYW5uZWxzID0gQ2hhbm5lbC5leHBhbmQobWVzc2FnZS5jaGFubmVsKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBjaGFubmVscy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgdmFyIGNoYW5uZWwgPSB0aGlzLl9jaGFubmVsc1tjaGFubmVsc1tpXV07XG4gICAgICAgIGlmIChjaGFubmVsKSBjaGFubmVsLnRyaWdnZXIoJ21lc3NhZ2UnLCBtZXNzYWdlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBDaGFubmVsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNhcCAgICAgICAgICAgID0gcmVxdWlyZSgnYXNhcCcpLFxuICAgIENsYXNzICAgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBQcm9taXNlICAgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3Byb21pc2UnKSxcbiAgICBVUkkgICAgICAgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3VyaScpLFxuICAgIGFycmF5ICAgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvYXJyYXknKSxcbiAgICBicm93c2VyICAgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2Jyb3dzZXInKSxcbiAgICBjb25zdGFudHMgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2NvbnN0YW50cycpLFxuICAgIGV4dGVuZCAgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgdmFsaWRhdGVPcHRpb25zID0gcmVxdWlyZSgnLi4vdXRpbC92YWxpZGF0ZV9vcHRpb25zJyksXG4gICAgRGVmZXJyYWJsZSAgICAgID0gcmVxdWlyZSgnLi4vbWl4aW5zL2RlZmVycmFibGUnKSxcbiAgICBMb2dnaW5nICAgICAgICAgPSByZXF1aXJlKCcuLi9taXhpbnMvbG9nZ2luZycpLFxuICAgIFB1Ymxpc2hlciAgICAgICA9IHJlcXVpcmUoJy4uL21peGlucy9wdWJsaXNoZXInKSxcbiAgICBDaGFubmVsICAgICAgICAgPSByZXF1aXJlKCcuL2NoYW5uZWwnKSxcbiAgICBEaXNwYXRjaGVyICAgICAgPSByZXF1aXJlKCcuL2Rpc3BhdGNoZXInKSxcbiAgICBFcnJvciAgICAgICAgICAgPSByZXF1aXJlKCcuL2Vycm9yJyksXG4gICAgRXh0ZW5zaWJsZSAgICAgID0gcmVxdWlyZSgnLi9leHRlbnNpYmxlJyksXG4gICAgUHVibGljYXRpb24gICAgID0gcmVxdWlyZSgnLi9wdWJsaWNhdGlvbicpLFxuICAgIFN1YnNjcmlwdGlvbiAgICA9IHJlcXVpcmUoJy4vc3Vic2NyaXB0aW9uJyk7XG5cbnZhciBDbGllbnQgPSBDbGFzcyh7IGNsYXNzTmFtZTogJ0NsaWVudCcsXG4gIFVOQ09OTkVDVEVEOiAgICAgICAgMSxcbiAgQ09OTkVDVElORzogICAgICAgICAyLFxuICBDT05ORUNURUQ6ICAgICAgICAgIDMsXG4gIERJU0NPTk5FQ1RFRDogICAgICAgNCxcblxuICBIQU5EU0hBS0U6ICAgICAgICAgICdoYW5kc2hha2UnLFxuICBSRVRSWTogICAgICAgICAgICAgICdyZXRyeScsXG4gIE5PTkU6ICAgICAgICAgICAgICAgJ25vbmUnLFxuXG4gIENPTk5FQ1RJT05fVElNRU9VVDogNjAsXG5cbiAgREVGQVVMVF9FTkRQT0lOVDogICAnL2JheWV1eCcsXG4gIElOVEVSVkFMOiAgICAgICAgICAgMCxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihlbmRwb2ludCwgb3B0aW9ucykge1xuICAgIHRoaXMuaW5mbygnTmV3IGNsaWVudCBjcmVhdGVkIGZvciA/JywgZW5kcG9pbnQpO1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgdmFsaWRhdGVPcHRpb25zKG9wdGlvbnMsIFsnaW50ZXJ2YWwnLCAndGltZW91dCcsICdlbmRwb2ludHMnLCAncHJveHknLCAncmV0cnknLCAnc2NoZWR1bGVyJywgJ3dlYnNvY2tldEV4dGVuc2lvbnMnLCAndGxzJywgJ2NhJ10pO1xuXG4gICAgdGhpcy5fY2hhbm5lbHMgICA9IG5ldyBDaGFubmVsLlNldCgpO1xuICAgIHRoaXMuX2Rpc3BhdGNoZXIgPSBEaXNwYXRjaGVyLmNyZWF0ZSh0aGlzLCBlbmRwb2ludCB8fCB0aGlzLkRFRkFVTFRfRU5EUE9JTlQsIG9wdGlvbnMpO1xuXG4gICAgdGhpcy5fbWVzc2FnZUlkID0gMDtcbiAgICB0aGlzLl9zdGF0ZSAgICAgPSB0aGlzLlVOQ09OTkVDVEVEO1xuXG4gICAgdGhpcy5fcmVzcG9uc2VDYWxsYmFja3MgPSB7fTtcblxuICAgIHRoaXMuX2FkdmljZSA9IHtcbiAgICAgIHJlY29ubmVjdDogdGhpcy5SRVRSWSxcbiAgICAgIGludGVydmFsOiAgMTAwMCAqIChvcHRpb25zLmludGVydmFsIHx8IHRoaXMuSU5URVJWQUwpLFxuICAgICAgdGltZW91dDogICAxMDAwICogKG9wdGlvbnMudGltZW91dCAgfHwgdGhpcy5DT05ORUNUSU9OX1RJTUVPVVQpXG4gICAgfTtcbiAgICB0aGlzLl9kaXNwYXRjaGVyLnRpbWVvdXQgPSB0aGlzLl9hZHZpY2UudGltZW91dCAvIDEwMDA7XG5cbiAgICB0aGlzLl9kaXNwYXRjaGVyLmJpbmQoJ21lc3NhZ2UnLCB0aGlzLl9yZWNlaXZlTWVzc2FnZSwgdGhpcyk7XG5cbiAgICBpZiAoYnJvd3Nlci5FdmVudCAmJiBnbG9iYWwub25iZWZvcmV1bmxvYWQgIT09IHVuZGVmaW5lZClcbiAgICAgIGJyb3dzZXIuRXZlbnQub24oZ2xvYmFsLCAnYmVmb3JldW5sb2FkJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmIChhcnJheS5pbmRleE9mKHRoaXMuX2Rpc3BhdGNoZXIuX2Rpc2FibGVkLCAnYXV0b2Rpc2Nvbm5lY3QnKSA8IDApXG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgICB9LCB0aGlzKTtcbiAgfSxcblxuICBhZGRXZWJzb2NrZXRFeHRlbnNpb246IGZ1bmN0aW9uKGV4dGVuc2lvbikge1xuICAgIHJldHVybiB0aGlzLl9kaXNwYXRjaGVyLmFkZFdlYnNvY2tldEV4dGVuc2lvbihleHRlbnNpb24pO1xuICB9LFxuXG4gIGRpc2FibGU6IGZ1bmN0aW9uKGZlYXR1cmUpIHtcbiAgICByZXR1cm4gdGhpcy5fZGlzcGF0Y2hlci5kaXNhYmxlKGZlYXR1cmUpO1xuICB9LFxuXG4gIHNldEhlYWRlcjogZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fZGlzcGF0Y2hlci5zZXRIZWFkZXIobmFtZSwgdmFsdWUpO1xuICB9LFxuXG4gIC8vIFJlcXVlc3RcbiAgLy8gTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsXG4gIC8vICAgICAgICAgICAgICAgICogdmVyc2lvblxuICAvLyAgICAgICAgICAgICAgICAqIHN1cHBvcnRlZENvbm5lY3Rpb25UeXBlc1xuICAvLyBNQVkgaW5jbHVkZTogICAqIG1pbmltdW1WZXJzaW9uXG4gIC8vICAgICAgICAgICAgICAgICogZXh0XG4gIC8vICAgICAgICAgICAgICAgICogaWRcbiAgLy9cbiAgLy8gU3VjY2VzcyBSZXNwb25zZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFpbGVkIFJlc3BvbnNlXG4gIC8vIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbCAgICAgICAgICAgICAgICAgICAgIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbFxuICAvLyAgICAgICAgICAgICAgICAqIHZlcnNpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHN1Y2Nlc3NmdWxcbiAgLy8gICAgICAgICAgICAgICAgKiBzdXBwb3J0ZWRDb25uZWN0aW9uVHlwZXMgICAgICAgICAgICAgICAgICAgKiBlcnJvclxuICAvLyAgICAgICAgICAgICAgICAqIGNsaWVudElkICAgICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIHN1cHBvcnRlZENvbm5lY3Rpb25UeXBlc1xuICAvLyAgICAgICAgICAgICAgICAqIHN1Y2Nlc3NmdWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGFkdmljZVxuICAvLyBNQVkgaW5jbHVkZTogICAqIG1pbmltdW1WZXJzaW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHZlcnNpb25cbiAgLy8gICAgICAgICAgICAgICAgKiBhZHZpY2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBtaW5pbXVtVmVyc2lvblxuICAvLyAgICAgICAgICAgICAgICAqIGV4dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGV4dFxuICAvLyAgICAgICAgICAgICAgICAqIGlkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGlkXG4gIC8vICAgICAgICAgICAgICAgICogYXV0aFN1Y2Nlc3NmdWxcbiAgaGFuZHNoYWtlOiBmdW5jdGlvbihjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmICh0aGlzLl9hZHZpY2UucmVjb25uZWN0ID09PSB0aGlzLk5PTkUpIHJldHVybjtcbiAgICBpZiAodGhpcy5fc3RhdGUgIT09IHRoaXMuVU5DT05ORUNURUQpIHJldHVybjtcblxuICAgIHRoaXMuX3N0YXRlID0gdGhpcy5DT05ORUNUSU5HO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHRoaXMuaW5mbygnSW5pdGlhdGluZyBoYW5kc2hha2Ugd2l0aCA/JywgVVJJLnN0cmluZ2lmeSh0aGlzLl9kaXNwYXRjaGVyLmVuZHBvaW50KSk7XG4gICAgdGhpcy5fZGlzcGF0Y2hlci5zZWxlY3RUcmFuc3BvcnQoY29uc3RhbnRzLk1BTkRBVE9SWV9DT05ORUNUSU9OX1RZUEVTKTtcblxuICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWw6ICAgICAgICAgICAgICAgICAgQ2hhbm5lbC5IQU5EU0hBS0UsXG4gICAgICB2ZXJzaW9uOiAgICAgICAgICAgICAgICAgIGNvbnN0YW50cy5CQVlFVVhfVkVSU0lPTixcbiAgICAgIHN1cHBvcnRlZENvbm5lY3Rpb25UeXBlczogdGhpcy5fZGlzcGF0Y2hlci5nZXRDb25uZWN0aW9uVHlwZXMoKVxuXG4gICAgfSwge30sIGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG5cbiAgICAgIGlmIChyZXNwb25zZS5zdWNjZXNzZnVsKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gdGhpcy5DT05ORUNURUQ7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQgID0gcmVzcG9uc2UuY2xpZW50SWQ7XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hlci5zZWxlY3RUcmFuc3BvcnQocmVzcG9uc2Uuc3VwcG9ydGVkQ29ubmVjdGlvblR5cGVzKTtcblxuICAgICAgICB0aGlzLmluZm8oJ0hhbmRzaGFrZSBzdWNjZXNzZnVsOiA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCk7XG5cbiAgICAgICAgdGhpcy5zdWJzY3JpYmUodGhpcy5fY2hhbm5lbHMuZ2V0S2V5cygpLCB0cnVlKTtcbiAgICAgICAgaWYgKGNhbGxiYWNrKSBhc2FwKGZ1bmN0aW9uKCkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQpIH0pO1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluZm8oJ0hhbmRzaGFrZSB1bnN1Y2Nlc3NmdWwnKTtcbiAgICAgICAgZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHNlbGYuaGFuZHNoYWtlKGNhbGxiYWNrLCBjb250ZXh0KSB9LCB0aGlzLl9kaXNwYXRjaGVyLnJldHJ5ICogMTAwMCk7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gdGhpcy5VTkNPTk5FQ1RFRDtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcbiAgfSxcblxuICAvLyBSZXF1ZXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzcG9uc2VcbiAgLy8gTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsICAgICAgICAgICAgIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbFxuICAvLyAgICAgICAgICAgICAgICAqIGNsaWVudElkICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzdWNjZXNzZnVsXG4gIC8vICAgICAgICAgICAgICAgICogY29ubmVjdGlvblR5cGUgICAgICAgICAgICAgICAgICAgICAqIGNsaWVudElkXG4gIC8vIE1BWSBpbmNsdWRlOiAgICogZXh0ICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIGVycm9yXG4gIC8vICAgICAgICAgICAgICAgICogaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGFkdmljZVxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBleHRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogaWRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdGltZXN0YW1wXG4gIGNvbm5lY3Q6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgaWYgKHRoaXMuX2FkdmljZS5yZWNvbm5lY3QgPT09IHRoaXMuTk9ORSkgcmV0dXJuO1xuICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gdGhpcy5ESVNDT05ORUNURUQpIHJldHVybjtcblxuICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gdGhpcy5VTkNPTk5FQ1RFRClcbiAgICAgIHJldHVybiB0aGlzLmhhbmRzaGFrZShmdW5jdGlvbigpIHsgdGhpcy5jb25uZWN0KGNhbGxiYWNrLCBjb250ZXh0KSB9LCB0aGlzKTtcblxuICAgIHRoaXMuY2FsbGJhY2soY2FsbGJhY2ssIGNvbnRleHQpO1xuICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gdGhpcy5DT05ORUNURUQpIHJldHVybjtcblxuICAgIHRoaXMuaW5mbygnQ2FsbGluZyBkZWZlcnJlZCBhY3Rpb25zIGZvciA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCk7XG4gICAgdGhpcy5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgdGhpcy5zZXREZWZlcnJlZFN0YXR1cygndW5rbm93bicpO1xuXG4gICAgaWYgKHRoaXMuX2Nvbm5lY3RSZXF1ZXN0KSByZXR1cm47XG4gICAgdGhpcy5fY29ubmVjdFJlcXVlc3QgPSB0cnVlO1xuXG4gICAgdGhpcy5pbmZvKCdJbml0aWF0aW5nIGNvbm5lY3Rpb24gZm9yID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkKTtcblxuICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWw6ICAgICAgICBDaGFubmVsLkNPTk5FQ1QsXG4gICAgICBjbGllbnRJZDogICAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCxcbiAgICAgIGNvbm5lY3Rpb25UeXBlOiB0aGlzLl9kaXNwYXRjaGVyLmNvbm5lY3Rpb25UeXBlXG5cbiAgICB9LCB7fSwgdGhpcy5fY3ljbGVDb25uZWN0aW9uLCB0aGlzKTtcbiAgfSxcblxuICAvLyBSZXF1ZXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzcG9uc2VcbiAgLy8gTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsICAgICAgICAgICAgIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbFxuICAvLyAgICAgICAgICAgICAgICAqIGNsaWVudElkICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzdWNjZXNzZnVsXG4gIC8vIE1BWSBpbmNsdWRlOiAgICogZXh0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGNsaWVudElkXG4gIC8vICAgICAgICAgICAgICAgICogaWQgICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIGVycm9yXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGV4dFxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpZFxuICBkaXNjb25uZWN0OiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fc3RhdGUgIT09IHRoaXMuQ09OTkVDVEVEKSByZXR1cm47XG4gICAgdGhpcy5fc3RhdGUgPSB0aGlzLkRJU0NPTk5FQ1RFRDtcblxuICAgIHRoaXMuaW5mbygnRGlzY29ubmVjdGluZyA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCk7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHVibGljYXRpb24oKTtcblxuICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWw6ICBDaGFubmVsLkRJU0NPTk5FQ1QsXG4gICAgICBjbGllbnRJZDogdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZFxuXG4gICAgfSwge30sIGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICBpZiAocmVzcG9uc2Uuc3VjY2Vzc2Z1bCkge1xuICAgICAgICB0aGlzLl9kaXNwYXRjaGVyLmNsb3NlKCk7XG4gICAgICAgIHByb21pc2Uuc2V0RGVmZXJyZWRTdGF0dXMoJ3N1Y2NlZWRlZCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcHJvbWlzZS5zZXREZWZlcnJlZFN0YXR1cygnZmFpbGVkJywgRXJyb3IucGFyc2UocmVzcG9uc2UuZXJyb3IpKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcblxuICAgIHRoaXMuaW5mbygnQ2xlYXJpbmcgY2hhbm5lbCBsaXN0ZW5lcnMgZm9yID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkKTtcbiAgICB0aGlzLl9jaGFubmVscyA9IG5ldyBDaGFubmVsLlNldCgpO1xuXG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH0sXG5cbiAgLy8gUmVxdWVzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3BvbnNlXG4gIC8vIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbCAgICAgICAgICAgICBNVVNUIGluY2x1ZGU6ICAqIGNoYW5uZWxcbiAgLy8gICAgICAgICAgICAgICAgKiBjbGllbnRJZCAgICAgICAgICAgICAgICAgICAgICAgICAgICogc3VjY2Vzc2Z1bFxuICAvLyAgICAgICAgICAgICAgICAqIHN1YnNjcmlwdGlvbiAgICAgICAgICAgICAgICAgICAgICAgKiBjbGllbnRJZFxuICAvLyBNQVkgaW5jbHVkZTogICAqIGV4dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzdWJzY3JpcHRpb25cbiAgLy8gICAgICAgICAgICAgICAgKiBpZCAgICAgICAgICAgICAgICAgIE1BWSBpbmNsdWRlOiAgICogZXJyb3JcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogYWR2aWNlXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGV4dFxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpZFxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB0aW1lc3RhbXBcbiAgc3Vic2NyaWJlOiBmdW5jdGlvbihjaGFubmVsLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmIChjaGFubmVsIGluc3RhbmNlb2YgQXJyYXkpXG4gICAgICByZXR1cm4gYXJyYXkubWFwKGNoYW5uZWwsIGZ1bmN0aW9uKGMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3Vic2NyaWJlKGMsIGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgICAgIH0sIHRoaXMpO1xuXG4gICAgdmFyIHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24odGhpcywgY2hhbm5lbCwgY2FsbGJhY2ssIGNvbnRleHQpLFxuICAgICAgICBmb3JjZSAgICAgICAgPSAoY2FsbGJhY2sgPT09IHRydWUpLFxuICAgICAgICBoYXNTdWJzY3JpYmUgPSB0aGlzLl9jaGFubmVscy5oYXNTdWJzY3JpcHRpb24oY2hhbm5lbCk7XG5cbiAgICBpZiAoaGFzU3Vic2NyaWJlICYmICFmb3JjZSkge1xuICAgICAgdGhpcy5fY2hhbm5lbHMuc3Vic2NyaWJlKFtjaGFubmVsXSwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIHN1YnNjcmlwdGlvbi5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgICByZXR1cm4gc3Vic2NyaXB0aW9uO1xuICAgIH1cblxuICAgIHRoaXMuY29ubmVjdChmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuaW5mbygnQ2xpZW50ID8gYXR0ZW1wdGluZyB0byBzdWJzY3JpYmUgdG8gPycsIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQsIGNoYW5uZWwpO1xuICAgICAgaWYgKCFmb3JjZSkgdGhpcy5fY2hhbm5lbHMuc3Vic2NyaWJlKFtjaGFubmVsXSwgc3Vic2NyaXB0aW9uKTtcblxuICAgICAgdGhpcy5fc2VuZE1lc3NhZ2Uoe1xuICAgICAgICBjaGFubmVsOiAgICAgIENoYW5uZWwuU1VCU0NSSUJFLFxuICAgICAgICBjbGllbnRJZDogICAgIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQsXG4gICAgICAgIHN1YnNjcmlwdGlvbjogY2hhbm5lbFxuXG4gICAgICB9LCB7fSwgZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdWNjZXNzZnVsKSB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uLnNldERlZmVycmVkU3RhdHVzKCdmYWlsZWQnLCBFcnJvci5wYXJzZShyZXNwb25zZS5lcnJvcikpO1xuICAgICAgICAgIHJldHVybiB0aGlzLl9jaGFubmVscy51bnN1YnNjcmliZShjaGFubmVsLCBzdWJzY3JpcHRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNoYW5uZWxzID0gW10uY29uY2F0KHJlc3BvbnNlLnN1YnNjcmlwdGlvbik7XG4gICAgICAgIHRoaXMuaW5mbygnU3Vic2NyaXB0aW9uIGFja25vd2xlZGdlZCBmb3IgPyB0byA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgY2hhbm5lbHMpO1xuICAgICAgICBzdWJzY3JpcHRpb24uc2V0RGVmZXJyZWRTdGF0dXMoJ3N1Y2NlZWRlZCcpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSwgdGhpcyk7XG5cbiAgICByZXR1cm4gc3Vic2NyaXB0aW9uO1xuICB9LFxuXG4gIC8vIFJlcXVlc3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNwb25zZVxuICAvLyBNVVNUIGluY2x1ZGU6ICAqIGNoYW5uZWwgICAgICAgICAgICAgTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsXG4gIC8vICAgICAgICAgICAgICAgICogY2xpZW50SWQgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHN1Y2Nlc3NmdWxcbiAgLy8gICAgICAgICAgICAgICAgKiBzdWJzY3JpcHRpb24gICAgICAgICAgICAgICAgICAgICAgICogY2xpZW50SWRcbiAgLy8gTUFZIGluY2x1ZGU6ICAgKiBleHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogc3Vic2NyaXB0aW9uXG4gIC8vICAgICAgICAgICAgICAgICogaWQgICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIGVycm9yXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGFkdmljZVxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBleHRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogaWRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdGltZXN0YW1wXG4gIHVuc3Vic2NyaWJlOiBmdW5jdGlvbihjaGFubmVsLCBzdWJzY3JpcHRpb24pIHtcbiAgICBpZiAoY2hhbm5lbCBpbnN0YW5jZW9mIEFycmF5KVxuICAgICAgcmV0dXJuIGFycmF5Lm1hcChjaGFubmVsLCBmdW5jdGlvbihjKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVuc3Vic2NyaWJlKGMsIHN1YnNjcmlwdGlvbik7XG4gICAgICB9LCB0aGlzKTtcblxuICAgIHZhciBkZWFkID0gdGhpcy5fY2hhbm5lbHMudW5zdWJzY3JpYmUoY2hhbm5lbCwgc3Vic2NyaXB0aW9uKTtcbiAgICBpZiAoIWRlYWQpIHJldHVybjtcblxuICAgIHRoaXMuY29ubmVjdChmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuaW5mbygnQ2xpZW50ID8gYXR0ZW1wdGluZyB0byB1bnN1YnNjcmliZSBmcm9tID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkLCBjaGFubmVsKTtcblxuICAgICAgdGhpcy5fc2VuZE1lc3NhZ2Uoe1xuICAgICAgICBjaGFubmVsOiAgICAgIENoYW5uZWwuVU5TVUJTQ1JJQkUsXG4gICAgICAgIGNsaWVudElkOiAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCxcbiAgICAgICAgc3Vic2NyaXB0aW9uOiBjaGFubmVsXG5cbiAgICAgIH0sIHt9LCBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnN1Y2Nlc3NmdWwpIHJldHVybjtcblxuICAgICAgICB2YXIgY2hhbm5lbHMgPSBbXS5jb25jYXQocmVzcG9uc2Uuc3Vic2NyaXB0aW9uKTtcbiAgICAgICAgdGhpcy5pbmZvKCdVbnN1YnNjcmlwdGlvbiBhY2tub3dsZWRnZWQgZm9yID8gZnJvbSA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgY2hhbm5lbHMpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSwgdGhpcyk7XG4gIH0sXG5cbiAgLy8gUmVxdWVzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3BvbnNlXG4gIC8vIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbCAgICAgICAgICAgICBNVVNUIGluY2x1ZGU6ICAqIGNoYW5uZWxcbiAgLy8gICAgICAgICAgICAgICAgKiBkYXRhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogc3VjY2Vzc2Z1bFxuICAvLyBNQVkgaW5jbHVkZTogICAqIGNsaWVudElkICAgICAgICAgICAgTUFZIGluY2x1ZGU6ICAgKiBpZFxuICAvLyAgICAgICAgICAgICAgICAqIGlkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBlcnJvclxuICAvLyAgICAgICAgICAgICAgICAqIGV4dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBleHRcbiAgcHVibGlzaDogZnVuY3Rpb24oY2hhbm5lbCwgZGF0YSwgb3B0aW9ucykge1xuICAgIHZhbGlkYXRlT3B0aW9ucyhvcHRpb25zIHx8IHt9LCBbJ2F0dGVtcHRzJywgJ2RlYWRsaW5lJ10pO1xuICAgIHZhciBwdWJsaWNhdGlvbiA9IG5ldyBQdWJsaWNhdGlvbigpO1xuXG4gICAgdGhpcy5jb25uZWN0KGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5pbmZvKCdDbGllbnQgPyBxdWV1ZWluZyBwdWJsaXNoZWQgbWVzc2FnZSB0byA/OiA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgY2hhbm5lbCwgZGF0YSk7XG5cbiAgICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgICAgY2hhbm5lbDogIGNoYW5uZWwsXG4gICAgICAgIGRhdGE6ICAgICBkYXRhLFxuICAgICAgICBjbGllbnRJZDogdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZFxuXG4gICAgICB9LCBvcHRpb25zLCBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgICAgICBpZiAocmVzcG9uc2Uuc3VjY2Vzc2Z1bClcbiAgICAgICAgICBwdWJsaWNhdGlvbi5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBwdWJsaWNhdGlvbi5zZXREZWZlcnJlZFN0YXR1cygnZmFpbGVkJywgRXJyb3IucGFyc2UocmVzcG9uc2UuZXJyb3IpKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0sIHRoaXMpO1xuXG4gICAgcmV0dXJuIHB1YmxpY2F0aW9uO1xuICB9LFxuXG4gIF9zZW5kTWVzc2FnZTogZnVuY3Rpb24obWVzc2FnZSwgb3B0aW9ucywgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICBtZXNzYWdlLmlkID0gdGhpcy5fZ2VuZXJhdGVNZXNzYWdlSWQoKTtcblxuICAgIHZhciB0aW1lb3V0ID0gdGhpcy5fYWR2aWNlLnRpbWVvdXRcbiAgICAgICAgICAgICAgICA/IDEuMiAqIHRoaXMuX2FkdmljZS50aW1lb3V0IC8gMTAwMFxuICAgICAgICAgICAgICAgIDogMS4yICogdGhpcy5fZGlzcGF0Y2hlci5yZXRyeTtcblxuICAgIHRoaXMucGlwZVRocm91Z2hFeHRlbnNpb25zKCdvdXRnb2luZycsIG1lc3NhZ2UsIG51bGwsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGlmICghbWVzc2FnZSkgcmV0dXJuO1xuICAgICAgaWYgKGNhbGxiYWNrKSB0aGlzLl9yZXNwb25zZUNhbGxiYWNrc1ttZXNzYWdlLmlkXSA9IFtjYWxsYmFjaywgY29udGV4dF07XG4gICAgICB0aGlzLl9kaXNwYXRjaGVyLnNlbmRNZXNzYWdlKG1lc3NhZ2UsIHRpbWVvdXQsIG9wdGlvbnMgfHwge30pO1xuICAgIH0sIHRoaXMpO1xuICB9LFxuXG4gIF9nZW5lcmF0ZU1lc3NhZ2VJZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbWVzc2FnZUlkICs9IDE7XG4gICAgaWYgKHRoaXMuX21lc3NhZ2VJZCA+PSBNYXRoLnBvdygyLDMyKSkgdGhpcy5fbWVzc2FnZUlkID0gMDtcbiAgICByZXR1cm4gdGhpcy5fbWVzc2FnZUlkLnRvU3RyaW5nKDM2KTtcbiAgfSxcblxuICBfcmVjZWl2ZU1lc3NhZ2U6IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICB2YXIgaWQgPSBtZXNzYWdlLmlkLCBjYWxsYmFjaztcblxuICAgIGlmIChtZXNzYWdlLnN1Y2Nlc3NmdWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FsbGJhY2sgPSB0aGlzLl9yZXNwb25zZUNhbGxiYWNrc1tpZF07XG4gICAgICBkZWxldGUgdGhpcy5fcmVzcG9uc2VDYWxsYmFja3NbaWRdO1xuICAgIH1cblxuICAgIHRoaXMucGlwZVRocm91Z2hFeHRlbnNpb25zKCdpbmNvbWluZycsIG1lc3NhZ2UsIG51bGwsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGlmICghbWVzc2FnZSkgcmV0dXJuO1xuICAgICAgaWYgKG1lc3NhZ2UuYWR2aWNlKSB0aGlzLl9oYW5kbGVBZHZpY2UobWVzc2FnZS5hZHZpY2UpO1xuICAgICAgdGhpcy5fZGVsaXZlck1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrWzBdLmNhbGwoY2FsbGJhY2tbMV0sIG1lc3NhZ2UpO1xuICAgIH0sIHRoaXMpO1xuICB9LFxuXG4gIF9oYW5kbGVBZHZpY2U6IGZ1bmN0aW9uKGFkdmljZSkge1xuICAgIGV4dGVuZCh0aGlzLl9hZHZpY2UsIGFkdmljZSk7XG4gICAgdGhpcy5fZGlzcGF0Y2hlci50aW1lb3V0ID0gdGhpcy5fYWR2aWNlLnRpbWVvdXQgLyAxMDAwO1xuXG4gICAgaWYgKHRoaXMuX2FkdmljZS5yZWNvbm5lY3QgPT09IHRoaXMuSEFORFNIQUtFICYmIHRoaXMuX3N0YXRlICE9PSB0aGlzLkRJU0NPTk5FQ1RFRCkge1xuICAgICAgdGhpcy5fc3RhdGUgPSB0aGlzLlVOQ09OTkVDVEVEO1xuICAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCA9IG51bGw7XG4gICAgICB0aGlzLl9jeWNsZUNvbm5lY3Rpb24oKTtcbiAgICB9XG4gIH0sXG5cbiAgX2RlbGl2ZXJNZXNzYWdlOiBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlLmNoYW5uZWwgfHwgbWVzc2FnZS5kYXRhID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICB0aGlzLmluZm8oJ0NsaWVudCA/IGNhbGxpbmcgbGlzdGVuZXJzIGZvciA/IHdpdGggPycsIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQsIG1lc3NhZ2UuY2hhbm5lbCwgbWVzc2FnZS5kYXRhKTtcbiAgICB0aGlzLl9jaGFubmVscy5kaXN0cmlidXRlTWVzc2FnZShtZXNzYWdlKTtcbiAgfSxcblxuICBfY3ljbGVDb25uZWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fY29ubmVjdFJlcXVlc3QpIHtcbiAgICAgIHRoaXMuX2Nvbm5lY3RSZXF1ZXN0ID0gbnVsbDtcbiAgICAgIHRoaXMuaW5mbygnQ2xvc2VkIGNvbm5lY3Rpb24gZm9yID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkKTtcbiAgICB9XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGdsb2JhbC5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBzZWxmLmNvbm5lY3QoKSB9LCB0aGlzLl9hZHZpY2UuaW50ZXJ2YWwpO1xuICB9XG59KTtcblxuZXh0ZW5kKENsaWVudC5wcm90b3R5cGUsIERlZmVycmFibGUpO1xuZXh0ZW5kKENsaWVudC5wcm90b3R5cGUsIFB1Ymxpc2hlcik7XG5leHRlbmQoQ2xpZW50LnByb3RvdHlwZSwgTG9nZ2luZyk7XG5leHRlbmQoQ2xpZW50LnByb3RvdHlwZSwgRXh0ZW5zaWJsZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2xpZW50O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3MgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9jbGFzcycpLFxuICAgIFVSSSAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvdXJpJyksXG4gICAgY29va2llcyAgID0gcmVxdWlyZSgnLi4vdXRpbC9jb29raWVzJyksXG4gICAgZXh0ZW5kICAgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICBMb2dnaW5nICAgPSByZXF1aXJlKCcuLi9taXhpbnMvbG9nZ2luZycpLFxuICAgIFB1Ymxpc2hlciA9IHJlcXVpcmUoJy4uL21peGlucy9wdWJsaXNoZXInKSxcbiAgICBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKSxcbiAgICBTY2hlZHVsZXIgPSByZXF1aXJlKCcuL3NjaGVkdWxlcicpO1xuXG52YXIgRGlzcGF0Y2hlciA9IENsYXNzKHsgY2xhc3NOYW1lOiAnRGlzcGF0Y2hlcicsXG4gIE1BWF9SRVFVRVNUX1NJWkU6IDIwNDgsXG4gIERFRkFVTFRfUkVUUlk6ICAgIDUsXG5cbiAgVVA6ICAgMSxcbiAgRE9XTjogMixcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihjbGllbnQsIGVuZHBvaW50LCBvcHRpb25zKSB7XG4gICAgdGhpcy5fY2xpZW50ICAgICA9IGNsaWVudDtcbiAgICB0aGlzLmVuZHBvaW50ICAgID0gVVJJLnBhcnNlKGVuZHBvaW50KTtcbiAgICB0aGlzLl9hbHRlcm5hdGVzID0gb3B0aW9ucy5lbmRwb2ludHMgfHwge307XG5cbiAgICB0aGlzLmNvb2tpZXMgICAgICA9IGNvb2tpZXMuQ29va2llSmFyICYmIG5ldyBjb29raWVzLkNvb2tpZUphcigpO1xuICAgIHRoaXMuX2Rpc2FibGVkICAgID0gW107XG4gICAgdGhpcy5fZW52ZWxvcGVzICAgPSB7fTtcbiAgICB0aGlzLmhlYWRlcnMgICAgICA9IHt9O1xuICAgIHRoaXMucmV0cnkgICAgICAgID0gb3B0aW9ucy5yZXRyeSB8fCB0aGlzLkRFRkFVTFRfUkVUUlk7XG4gICAgdGhpcy5fc2NoZWR1bGVyICAgPSBvcHRpb25zLnNjaGVkdWxlciB8fCBTY2hlZHVsZXI7XG4gICAgdGhpcy5fc3RhdGUgICAgICAgPSAwO1xuICAgIHRoaXMudHJhbnNwb3J0cyAgID0ge307XG4gICAgdGhpcy53c0V4dGVuc2lvbnMgPSBbXTtcblxuICAgIHRoaXMucHJveHkgPSBvcHRpb25zLnByb3h5IHx8IHt9O1xuICAgIGlmICh0eXBlb2YgdGhpcy5fcHJveHkgPT09ICdzdHJpbmcnKSB0aGlzLl9wcm94eSA9IHtvcmlnaW46IHRoaXMuX3Byb3h5fTtcblxuICAgIHZhciBleHRzID0gb3B0aW9ucy53ZWJzb2NrZXRFeHRlbnNpb25zO1xuICAgIGlmIChleHRzKSB7XG4gICAgICBleHRzID0gW10uY29uY2F0KGV4dHMpO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBleHRzLmxlbmd0aDsgaSA8IG47IGkrKylcbiAgICAgICAgdGhpcy5hZGRXZWJzb2NrZXRFeHRlbnNpb24oZXh0c1tpXSk7XG4gICAgfVxuXG4gICAgdGhpcy50bHMgPSBvcHRpb25zLnRscyB8fCB7fTtcbiAgICB0aGlzLnRscy5jYSA9IHRoaXMudGxzLmNhIHx8IG9wdGlvbnMuY2E7XG5cbiAgICBmb3IgKHZhciB0eXBlIGluIHRoaXMuX2FsdGVybmF0ZXMpXG4gICAgICB0aGlzLl9hbHRlcm5hdGVzW3R5cGVdID0gVVJJLnBhcnNlKHRoaXMuX2FsdGVybmF0ZXNbdHlwZV0pO1xuXG4gICAgdGhpcy5tYXhSZXF1ZXN0U2l6ZSA9IHRoaXMuTUFYX1JFUVVFU1RfU0laRTtcbiAgfSxcblxuICBlbmRwb2ludEZvcjogZnVuY3Rpb24oY29ubmVjdGlvblR5cGUpIHtcbiAgICByZXR1cm4gdGhpcy5fYWx0ZXJuYXRlc1tjb25uZWN0aW9uVHlwZV0gfHwgdGhpcy5lbmRwb2ludDtcbiAgfSxcblxuICBhZGRXZWJzb2NrZXRFeHRlbnNpb246IGZ1bmN0aW9uKGV4dGVuc2lvbikge1xuICAgIHRoaXMud3NFeHRlbnNpb25zLnB1c2goZXh0ZW5zaW9uKTtcbiAgfSxcblxuICBkaXNhYmxlOiBmdW5jdGlvbihmZWF0dXJlKSB7XG4gICAgdGhpcy5fZGlzYWJsZWQucHVzaChmZWF0dXJlKTtcbiAgfSxcblxuICBzZXRIZWFkZXI6IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgdGhpcy5oZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gIH0sXG5cbiAgY2xvc2U6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLl90cmFuc3BvcnQ7XG4gICAgZGVsZXRlIHRoaXMuX3RyYW5zcG9ydDtcbiAgICBpZiAodHJhbnNwb3J0KSB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgfSxcblxuICBnZXRDb25uZWN0aW9uVHlwZXM6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBUcmFuc3BvcnQuZ2V0Q29ubmVjdGlvblR5cGVzKCk7XG4gIH0sXG5cbiAgc2VsZWN0VHJhbnNwb3J0OiBmdW5jdGlvbih0cmFuc3BvcnRUeXBlcykge1xuICAgIFRyYW5zcG9ydC5nZXQodGhpcywgdHJhbnNwb3J0VHlwZXMsIHRoaXMuX2Rpc2FibGVkLCBmdW5jdGlvbih0cmFuc3BvcnQpIHtcbiAgICAgIHRoaXMuZGVidWcoJ1NlbGVjdGVkID8gdHJhbnNwb3J0IGZvciA/JywgdHJhbnNwb3J0LmNvbm5lY3Rpb25UeXBlLCBVUkkuc3RyaW5naWZ5KHRyYW5zcG9ydC5lbmRwb2ludCkpO1xuXG4gICAgICBpZiAodHJhbnNwb3J0ID09PSB0aGlzLl90cmFuc3BvcnQpIHJldHVybjtcbiAgICAgIGlmICh0aGlzLl90cmFuc3BvcnQpIHRoaXMuX3RyYW5zcG9ydC5jbG9zZSgpO1xuXG4gICAgICB0aGlzLl90cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25UeXBlID0gdHJhbnNwb3J0LmNvbm5lY3Rpb25UeXBlO1xuICAgIH0sIHRoaXMpO1xuICB9LFxuXG4gIHNlbmRNZXNzYWdlOiBmdW5jdGlvbihtZXNzYWdlLCB0aW1lb3V0LCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICB2YXIgaWQgICAgICAgPSBtZXNzYWdlLmlkLFxuICAgICAgICBhdHRlbXB0cyA9IG9wdGlvbnMuYXR0ZW1wdHMsXG4gICAgICAgIGRlYWRsaW5lID0gb3B0aW9ucy5kZWFkbGluZSAmJiBuZXcgRGF0ZSgpLmdldFRpbWUoKSArIChvcHRpb25zLmRlYWRsaW5lICogMTAwMCksXG4gICAgICAgIGVudmVsb3BlID0gdGhpcy5fZW52ZWxvcGVzW2lkXSxcbiAgICAgICAgc2NoZWR1bGVyO1xuXG4gICAgaWYgKCFlbnZlbG9wZSkge1xuICAgICAgc2NoZWR1bGVyID0gbmV3IHRoaXMuX3NjaGVkdWxlcihtZXNzYWdlLCB7dGltZW91dDogdGltZW91dCwgaW50ZXJ2YWw6IHRoaXMucmV0cnksIGF0dGVtcHRzOiBhdHRlbXB0cywgZGVhZGxpbmU6IGRlYWRsaW5lfSk7XG4gICAgICBlbnZlbG9wZSAgPSB0aGlzLl9lbnZlbG9wZXNbaWRdID0ge21lc3NhZ2U6IG1lc3NhZ2UsIHNjaGVkdWxlcjogc2NoZWR1bGVyfTtcbiAgICB9XG5cbiAgICB0aGlzLl9zZW5kRW52ZWxvcGUoZW52ZWxvcGUpO1xuICB9LFxuXG4gIF9zZW5kRW52ZWxvcGU6IGZ1bmN0aW9uKGVudmVsb3BlKSB7XG4gICAgaWYgKCF0aGlzLl90cmFuc3BvcnQpIHJldHVybjtcbiAgICBpZiAoZW52ZWxvcGUucmVxdWVzdCB8fCBlbnZlbG9wZS50aW1lcikgcmV0dXJuO1xuXG4gICAgdmFyIG1lc3NhZ2UgICA9IGVudmVsb3BlLm1lc3NhZ2UsXG4gICAgICAgIHNjaGVkdWxlciA9IGVudmVsb3BlLnNjaGVkdWxlcixcbiAgICAgICAgc2VsZiAgICAgID0gdGhpcztcblxuICAgIGlmICghc2NoZWR1bGVyLmlzRGVsaXZlcmFibGUoKSkge1xuICAgICAgc2NoZWR1bGVyLmFib3J0KCk7XG4gICAgICBkZWxldGUgdGhpcy5fZW52ZWxvcGVzW21lc3NhZ2UuaWRdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVudmVsb3BlLnRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLmhhbmRsZUVycm9yKG1lc3NhZ2UpO1xuICAgIH0sIHNjaGVkdWxlci5nZXRUaW1lb3V0KCkgKiAxMDAwKTtcblxuICAgIHNjaGVkdWxlci5zZW5kKCk7XG4gICAgZW52ZWxvcGUucmVxdWVzdCA9IHRoaXMuX3RyYW5zcG9ydC5zZW5kTWVzc2FnZShtZXNzYWdlKTtcbiAgfSxcblxuICBoYW5kbGVSZXNwb25zZTogZnVuY3Rpb24ocmVwbHkpIHtcbiAgICB2YXIgZW52ZWxvcGUgPSB0aGlzLl9lbnZlbG9wZXNbcmVwbHkuaWRdO1xuXG4gICAgaWYgKHJlcGx5LnN1Y2Nlc3NmdWwgIT09IHVuZGVmaW5lZCAmJiBlbnZlbG9wZSkge1xuICAgICAgZW52ZWxvcGUuc2NoZWR1bGVyLnN1Y2NlZWQoKTtcbiAgICAgIGRlbGV0ZSB0aGlzLl9lbnZlbG9wZXNbcmVwbHkuaWRdO1xuICAgICAgZ2xvYmFsLmNsZWFyVGltZW91dChlbnZlbG9wZS50aW1lcik7XG4gICAgfVxuXG4gICAgdGhpcy50cmlnZ2VyKCdtZXNzYWdlJywgcmVwbHkpO1xuXG4gICAgaWYgKHRoaXMuX3N0YXRlID09PSB0aGlzLlVQKSByZXR1cm47XG4gICAgdGhpcy5fc3RhdGUgPSB0aGlzLlVQO1xuICAgIHRoaXMuX2NsaWVudC50cmlnZ2VyKCd0cmFuc3BvcnQ6dXAnKTtcbiAgfSxcblxuICBoYW5kbGVFcnJvcjogZnVuY3Rpb24obWVzc2FnZSwgaW1tZWRpYXRlKSB7XG4gICAgdmFyIGVudmVsb3BlID0gdGhpcy5fZW52ZWxvcGVzW21lc3NhZ2UuaWRdLFxuICAgICAgICByZXF1ZXN0ICA9IGVudmVsb3BlICYmIGVudmVsb3BlLnJlcXVlc3QsXG4gICAgICAgIHNlbGYgICAgID0gdGhpcztcblxuICAgIGlmICghcmVxdWVzdCkgcmV0dXJuO1xuXG4gICAgcmVxdWVzdC50aGVuKGZ1bmN0aW9uKHJlcSkge1xuICAgICAgaWYgKHJlcSAmJiByZXEuYWJvcnQpIHJlcS5hYm9ydCgpO1xuICAgIH0pO1xuXG4gICAgdmFyIHNjaGVkdWxlciA9IGVudmVsb3BlLnNjaGVkdWxlcjtcbiAgICBzY2hlZHVsZXIuZmFpbCgpO1xuXG4gICAgZ2xvYmFsLmNsZWFyVGltZW91dChlbnZlbG9wZS50aW1lcik7XG4gICAgZW52ZWxvcGUucmVxdWVzdCA9IGVudmVsb3BlLnRpbWVyID0gbnVsbDtcblxuICAgIGlmIChpbW1lZGlhdGUpIHtcbiAgICAgIHRoaXMuX3NlbmRFbnZlbG9wZShlbnZlbG9wZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudmVsb3BlLnRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIGVudmVsb3BlLnRpbWVyID0gbnVsbDtcbiAgICAgICAgc2VsZi5fc2VuZEVudmVsb3BlKGVudmVsb3BlKTtcbiAgICAgIH0sIHNjaGVkdWxlci5nZXRJbnRlcnZhbCgpICogMTAwMCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3N0YXRlID09PSB0aGlzLkRPV04pIHJldHVybjtcbiAgICB0aGlzLl9zdGF0ZSA9IHRoaXMuRE9XTjtcbiAgICB0aGlzLl9jbGllbnQudHJpZ2dlcigndHJhbnNwb3J0OmRvd24nKTtcbiAgfVxufSk7XG5cbkRpc3BhdGNoZXIuY3JlYXRlID0gZnVuY3Rpb24oY2xpZW50LCBlbmRwb2ludCwgb3B0aW9ucykge1xuICByZXR1cm4gbmV3IERpc3BhdGNoZXIoY2xpZW50LCBlbmRwb2ludCwgb3B0aW9ucyk7XG59O1xuXG5leHRlbmQoRGlzcGF0Y2hlci5wcm90b3R5cGUsIFB1Ymxpc2hlcik7XG5leHRlbmQoRGlzcGF0Y2hlci5wcm90b3R5cGUsIExvZ2dpbmcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IERpc3BhdGNoZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyAgID0gcmVxdWlyZSgnLi4vdXRpbC9jbGFzcycpLFxuICAgIEdyYW1tYXIgPSByZXF1aXJlKCcuL2dyYW1tYXInKTtcblxudmFyIEVycm9yID0gQ2xhc3Moe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbihjb2RlLCBwYXJhbXMsIG1lc3NhZ2UpIHtcbiAgICB0aGlzLmNvZGUgICAgPSBjb2RlO1xuICAgIHRoaXMucGFyYW1zICA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHBhcmFtcyk7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgfSxcblxuICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuY29kZSArICc6JyArXG4gICAgICAgICAgIHRoaXMucGFyYW1zLmpvaW4oJywnKSArICc6JyArXG4gICAgICAgICAgIHRoaXMubWVzc2FnZTtcbiAgfVxufSk7XG5cbkVycm9yLnBhcnNlID0gZnVuY3Rpb24obWVzc2FnZSkge1xuICBtZXNzYWdlID0gbWVzc2FnZSB8fCAnJztcbiAgaWYgKCFHcmFtbWFyLkVSUk9SLnRlc3QobWVzc2FnZSkpIHJldHVybiBuZXcgRXJyb3IobnVsbCwgW10sIG1lc3NhZ2UpO1xuXG4gIHZhciBwYXJ0cyAgID0gbWVzc2FnZS5zcGxpdCgnOicpLFxuICAgICAgY29kZSAgICA9IHBhcnNlSW50KHBhcnRzWzBdKSxcbiAgICAgIHBhcmFtcyAgPSBwYXJ0c1sxXS5zcGxpdCgnLCcpLFxuICAgICAgbWVzc2FnZSA9IHBhcnRzWzJdO1xuXG4gIHJldHVybiBuZXcgRXJyb3IoY29kZSwgcGFyYW1zLCBtZXNzYWdlKTtcbn07XG5cbi8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9jb21ldGQvd2lraS9CYXlldXhDb2Rlc1xudmFyIGVycm9ycyA9IHtcbiAgdmVyc2lvbk1pc21hdGNoOiAgWzMwMCwgJ1ZlcnNpb24gbWlzbWF0Y2gnXSxcbiAgY29ubnR5cGVNaXNtYXRjaDogWzMwMSwgJ0Nvbm5lY3Rpb24gdHlwZXMgbm90IHN1cHBvcnRlZCddLFxuICBleHRNaXNtYXRjaDogICAgICBbMzAyLCAnRXh0ZW5zaW9uIG1pc21hdGNoJ10sXG4gIGJhZFJlcXVlc3Q6ICAgICAgIFs0MDAsICdCYWQgcmVxdWVzdCddLFxuICBjbGllbnRVbmtub3duOiAgICBbNDAxLCAnVW5rbm93biBjbGllbnQnXSxcbiAgcGFyYW1ldGVyTWlzc2luZzogWzQwMiwgJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyJ10sXG4gIGNoYW5uZWxGb3JiaWRkZW46IFs0MDMsICdGb3JiaWRkZW4gY2hhbm5lbCddLFxuICBjaGFubmVsVW5rbm93bjogICBbNDA0LCAnVW5rbm93biBjaGFubmVsJ10sXG4gIGNoYW5uZWxJbnZhbGlkOiAgIFs0MDUsICdJbnZhbGlkIGNoYW5uZWwnXSxcbiAgZXh0VW5rbm93bjogICAgICAgWzQwNiwgJ1Vua25vd24gZXh0ZW5zaW9uJ10sXG4gIHB1Ymxpc2hGYWlsZWQ6ICAgIFs0MDcsICdGYWlsZWQgdG8gcHVibGlzaCddLFxuICBzZXJ2ZXJFcnJvcjogICAgICBbNTAwLCAnSW50ZXJuYWwgc2VydmVyIGVycm9yJ11cbn07XG5cbmZvciAodmFyIG5hbWUgaW4gZXJyb3JzKVxuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIEVycm9yW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKGVycm9yc1tuYW1lXVswXSwgYXJndW1lbnRzLCBlcnJvcnNbbmFtZV1bMV0pLnRvU3RyaW5nKCk7XG4gICAgfTtcbiAgfSkobmFtZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICBMb2dnaW5nID0gcmVxdWlyZSgnLi4vbWl4aW5zL2xvZ2dpbmcnKTtcblxudmFyIEV4dGVuc2libGUgPSB7XG4gIGFkZEV4dGVuc2lvbjogZnVuY3Rpb24oZXh0ZW5zaW9uKSB7XG4gICAgdGhpcy5fZXh0ZW5zaW9ucyA9IHRoaXMuX2V4dGVuc2lvbnMgfHwgW107XG4gICAgdGhpcy5fZXh0ZW5zaW9ucy5wdXNoKGV4dGVuc2lvbik7XG4gICAgaWYgKGV4dGVuc2lvbi5hZGRlZCkgZXh0ZW5zaW9uLmFkZGVkKHRoaXMpO1xuICB9LFxuXG4gIHJlbW92ZUV4dGVuc2lvbjogZnVuY3Rpb24oZXh0ZW5zaW9uKSB7XG4gICAgaWYgKCF0aGlzLl9leHRlbnNpb25zKSByZXR1cm47XG4gICAgdmFyIGkgPSB0aGlzLl9leHRlbnNpb25zLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBpZiAodGhpcy5fZXh0ZW5zaW9uc1tpXSAhPT0gZXh0ZW5zaW9uKSBjb250aW51ZTtcbiAgICAgIHRoaXMuX2V4dGVuc2lvbnMuc3BsaWNlKGksMSk7XG4gICAgICBpZiAoZXh0ZW5zaW9uLnJlbW92ZWQpIGV4dGVuc2lvbi5yZW1vdmVkKHRoaXMpO1xuICAgIH1cbiAgfSxcblxuICBwaXBlVGhyb3VnaEV4dGVuc2lvbnM6IGZ1bmN0aW9uKHN0YWdlLCBtZXNzYWdlLCByZXF1ZXN0LCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHRoaXMuZGVidWcoJ1Bhc3NpbmcgdGhyb3VnaCA/IGV4dGVuc2lvbnM6ID8nLCBzdGFnZSwgbWVzc2FnZSk7XG5cbiAgICBpZiAoIXRoaXMuX2V4dGVuc2lvbnMpIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1lc3NhZ2UpO1xuICAgIHZhciBleHRlbnNpb25zID0gdGhpcy5fZXh0ZW5zaW9ucy5zbGljZSgpO1xuXG4gICAgdmFyIHBpcGUgPSBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICBpZiAoIW1lc3NhZ2UpIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1lc3NhZ2UpO1xuXG4gICAgICB2YXIgZXh0ZW5zaW9uID0gZXh0ZW5zaW9ucy5zaGlmdCgpO1xuICAgICAgaWYgKCFleHRlbnNpb24pIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1lc3NhZ2UpO1xuXG4gICAgICB2YXIgZm4gPSBleHRlbnNpb25bc3RhZ2VdO1xuICAgICAgaWYgKCFmbikgcmV0dXJuIHBpcGUobWVzc2FnZSk7XG5cbiAgICAgIGlmIChmbi5sZW5ndGggPj0gMykgZXh0ZW5zaW9uW3N0YWdlXShtZXNzYWdlLCByZXF1ZXN0LCBwaXBlKTtcbiAgICAgIGVsc2UgICAgICAgICAgICAgICAgZXh0ZW5zaW9uW3N0YWdlXShtZXNzYWdlLCBwaXBlKTtcbiAgICB9O1xuICAgIHBpcGUobWVzc2FnZSk7XG4gIH1cbn07XG5cbmV4dGVuZChFeHRlbnNpYmxlLCBMb2dnaW5nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBFeHRlbnNpYmxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQ0hBTk5FTF9OQU1FOiAgICAgL15cXC8oKCgoW2Etel18W0EtWl0pfFswLTldKXwoXFwtfFxcX3xcXCF8XFx+fFxcKHxcXCl8XFwkfFxcQCkpKSsoXFwvKCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApKSkrKSokLyxcbiAgQ0hBTk5FTF9QQVRURVJOOiAgL14oXFwvKCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApKSkrKSpcXC9cXCp7MSwyfSQvLFxuICBFUlJPUjogICAgICAgICAgICAvXihbMC05XVswLTldWzAtOV06KCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApfCB8XFwvfFxcKnxcXC4pKSooLCgoKChbYS16XXxbQS1aXSl8WzAtOV0pfChcXC18XFxffFxcIXxcXH58XFwofFxcKXxcXCR8XFxAKXwgfFxcL3xcXCp8XFwuKSkqKSo6KCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApfCB8XFwvfFxcKnxcXC4pKSp8WzAtOV1bMC05XVswLTldOjooKCgoW2Etel18W0EtWl0pfFswLTldKXwoXFwtfFxcX3xcXCF8XFx+fFxcKHxcXCl8XFwkfFxcQCl8IHxcXC98XFwqfFxcLikpKikkLyxcbiAgVkVSU0lPTjogICAgICAgICAgL14oWzAtOV0pKyhcXC4oKFthLXpdfFtBLVpdKXxbMC05XSkoKCgoW2Etel18W0EtWl0pfFswLTldKXxcXC18XFxfKSkqKSokL1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2NsYXNzJyksXG4gICAgRGVmZXJyYWJsZSA9IHJlcXVpcmUoJy4uL21peGlucy9kZWZlcnJhYmxlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2xhc3MoRGVmZXJyYWJsZSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpO1xuXG52YXIgU2NoZWR1bGVyID0gZnVuY3Rpb24obWVzc2FnZSwgb3B0aW9ucykge1xuICB0aGlzLm1lc3NhZ2UgID0gbWVzc2FnZTtcbiAgdGhpcy5vcHRpb25zICA9IG9wdGlvbnM7XG4gIHRoaXMuYXR0ZW1wdHMgPSAwO1xufTtcblxuZXh0ZW5kKFNjaGVkdWxlci5wcm90b3R5cGUsIHtcbiAgZ2V0VGltZW91dDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy50aW1lb3V0O1xuICB9LFxuXG4gIGdldEludGVydmFsOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmludGVydmFsO1xuICB9LFxuXG4gIGlzRGVsaXZlcmFibGU6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhdHRlbXB0cyA9IHRoaXMub3B0aW9ucy5hdHRlbXB0cyxcbiAgICAgICAgbWFkZSAgICAgPSB0aGlzLmF0dGVtcHRzLFxuICAgICAgICBkZWFkbGluZSA9IHRoaXMub3B0aW9ucy5kZWFkbGluZSxcbiAgICAgICAgbm93ICAgICAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgIGlmIChhdHRlbXB0cyAhPT0gdW5kZWZpbmVkICYmIG1hZGUgPj0gYXR0ZW1wdHMpXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAoZGVhZGxpbmUgIT09IHVuZGVmaW5lZCAmJiBub3cgPiBkZWFkbGluZSlcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9LFxuXG4gIHNlbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuYXR0ZW1wdHMgKz0gMTtcbiAgfSxcblxuICBzdWNjZWVkOiBmdW5jdGlvbigpIHt9LFxuXG4gIGZhaWw6IGZ1bmN0aW9uKCkge30sXG5cbiAgYWJvcnQ6IGZ1bmN0aW9uKCkge31cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVkdWxlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2NsYXNzJyksXG4gICAgZXh0ZW5kICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgRGVmZXJyYWJsZSA9IHJlcXVpcmUoJy4uL21peGlucy9kZWZlcnJhYmxlJyk7XG5cbnZhciBTdWJzY3JpcHRpb24gPSBDbGFzcyh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNsaWVudCwgY2hhbm5lbHMsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fY2xpZW50ICAgID0gY2xpZW50O1xuICAgIHRoaXMuX2NoYW5uZWxzICA9IGNoYW5uZWxzO1xuICAgIHRoaXMuX2NhbGxiYWNrICA9IGNhbGxiYWNrO1xuICAgIHRoaXMuX2NvbnRleHQgICA9IGNvbnRleHQ7XG4gICAgdGhpcy5fY2FuY2VsbGVkID0gZmFsc2U7XG4gIH0sXG5cbiAgd2l0aENoYW5uZWw6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fd2l0aENoYW5uZWwgPSBbY2FsbGJhY2ssIGNvbnRleHRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGFwcGx5OiBmdW5jdGlvbihjb250ZXh0LCBhcmdzKSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBhcmdzWzBdO1xuXG4gICAgaWYgKHRoaXMuX2NhbGxiYWNrKVxuICAgICAgdGhpcy5fY2FsbGJhY2suY2FsbCh0aGlzLl9jb250ZXh0LCBtZXNzYWdlLmRhdGEpO1xuXG4gICAgaWYgKHRoaXMuX3dpdGhDaGFubmVsKVxuICAgICAgdGhpcy5fd2l0aENoYW5uZWxbMF0uY2FsbCh0aGlzLl93aXRoQ2hhbm5lbFsxXSwgbWVzc2FnZS5jaGFubmVsLCBtZXNzYWdlLmRhdGEpO1xuICB9LFxuXG4gIGNhbmNlbDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2NhbmNlbGxlZCkgcmV0dXJuO1xuICAgIHRoaXMuX2NsaWVudC51bnN1YnNjcmliZSh0aGlzLl9jaGFubmVscywgdGhpcyk7XG4gICAgdGhpcy5fY2FuY2VsbGVkID0gdHJ1ZTtcbiAgfSxcblxuICB1bnN1YnNjcmliZTogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5jYW5jZWwoKTtcbiAgfVxufSk7XG5cbmV4dGVuZChTdWJzY3JpcHRpb24ucHJvdG90eXBlLCBEZWZlcnJhYmxlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTdWJzY3JpcHRpb247XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuXG5UcmFuc3BvcnQucmVnaXN0ZXIoJ3dlYnNvY2tldCcsIHJlcXVpcmUoJy4vd2ViX3NvY2tldCcpKTtcblRyYW5zcG9ydC5yZWdpc3RlcignZXZlbnRzb3VyY2UnLCByZXF1aXJlKCcuL2V2ZW50X3NvdXJjZScpKTtcblRyYW5zcG9ydC5yZWdpc3RlcignbG9uZy1wb2xsaW5nJywgcmVxdWlyZSgnLi94aHInKSk7XG5UcmFuc3BvcnQucmVnaXN0ZXIoJ2Nyb3NzLW9yaWdpbi1sb25nLXBvbGxpbmcnLCByZXF1aXJlKCcuL2NvcnMnKSk7XG5UcmFuc3BvcnQucmVnaXN0ZXIoJ2NhbGxiYWNrLXBvbGxpbmcnLCByZXF1aXJlKCcuL2pzb25wJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zcG9ydDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBTZXQgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3NldCcpLFxuICAgIFVSSSAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvdXJpJyksXG4gICAgZXh0ZW5kICAgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICB0b0pTT04gICAgPSByZXF1aXJlKCcuLi91dGlsL3RvX2pzb24nKSxcbiAgICBUcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuXG52YXIgQ09SUyA9IGV4dGVuZChDbGFzcyhUcmFuc3BvcnQsIHtcbiAgZW5jb2RlOiBmdW5jdGlvbihtZXNzYWdlcykge1xuICAgIHJldHVybiAnbWVzc2FnZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHRvSlNPTihtZXNzYWdlcykpO1xuICB9LFxuXG4gIHJlcXVlc3Q6IGZ1bmN0aW9uKG1lc3NhZ2VzKSB7XG4gICAgdmFyIHhockNsYXNzID0gZ2xvYmFsLlhEb21haW5SZXF1ZXN0ID8gWERvbWFpblJlcXVlc3QgOiBYTUxIdHRwUmVxdWVzdCxcbiAgICAgICAgeGhyICAgICAgPSBuZXcgeGhyQ2xhc3MoKSxcbiAgICAgICAgaWQgICAgICAgPSArK0NPUlMuX2lkLFxuICAgICAgICBoZWFkZXJzICA9IHRoaXMuX2Rpc3BhdGNoZXIuaGVhZGVycyxcbiAgICAgICAgc2VsZiAgICAgPSB0aGlzLFxuICAgICAgICBrZXk7XG5cbiAgICB4aHIub3BlbignUE9TVCcsIFVSSS5zdHJpbmdpZnkodGhpcy5lbmRwb2ludCksIHRydWUpO1xuXG4gICAgaWYgKHhoci5zZXRSZXF1ZXN0SGVhZGVyKSB7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignUHJhZ21hJywgJ25vLWNhY2hlJyk7XG4gICAgICBmb3IgKGtleSBpbiBoZWFkZXJzKSB7XG4gICAgICAgIGlmICghaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCBoZWFkZXJzW2tleV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjbGVhblVwID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXhocikgcmV0dXJuIGZhbHNlO1xuICAgICAgQ09SUy5fcGVuZGluZy5yZW1vdmUoaWQpO1xuICAgICAgeGhyLm9ubG9hZCA9IHhoci5vbmVycm9yID0geGhyLm9udGltZW91dCA9IHhoci5vbnByb2dyZXNzID0gbnVsbDtcbiAgICAgIHhociA9IG51bGw7XG4gICAgfTtcblxuICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZXBsaWVzO1xuICAgICAgdHJ5IHsgcmVwbGllcyA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCkgfSBjYXRjaCAoZXJyb3IpIHt9XG5cbiAgICAgIGNsZWFuVXAoKTtcblxuICAgICAgaWYgKHJlcGxpZXMpXG4gICAgICAgIHNlbGYuX3JlY2VpdmUocmVwbGllcyk7XG4gICAgICBlbHNlXG4gICAgICAgIHNlbGYuX2hhbmRsZUVycm9yKG1lc3NhZ2VzKTtcbiAgICB9O1xuXG4gICAgeGhyLm9uZXJyb3IgPSB4aHIub250aW1lb3V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICBjbGVhblVwKCk7XG4gICAgICBzZWxmLl9oYW5kbGVFcnJvcihtZXNzYWdlcyk7XG4gICAgfTtcblxuICAgIHhoci5vbnByb2dyZXNzID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIGlmICh4aHJDbGFzcyA9PT0gZ2xvYmFsLlhEb21haW5SZXF1ZXN0KVxuICAgICAgQ09SUy5fcGVuZGluZy5hZGQoe2lkOiBpZCwgeGhyOiB4aHJ9KTtcblxuICAgIHhoci5zZW5kKHRoaXMuZW5jb2RlKG1lc3NhZ2VzKSk7XG4gICAgcmV0dXJuIHhocjtcbiAgfVxufSksIHtcbiAgX2lkOiAgICAgIDAsXG4gIF9wZW5kaW5nOiBuZXcgU2V0KCksXG5cbiAgaXNVc2FibGU6IGZ1bmN0aW9uKGRpc3BhdGNoZXIsIGVuZHBvaW50LCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmIChVUkkuaXNTYW1lT3JpZ2luKGVuZHBvaW50KSlcbiAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIGZhbHNlKTtcblxuICAgIGlmIChnbG9iYWwuWERvbWFpblJlcXVlc3QpXG4gICAgICByZXR1cm4gY2FsbGJhY2suY2FsbChjb250ZXh0LCBlbmRwb2ludC5wcm90b2NvbCA9PT0gbG9jYXRpb24ucHJvdG9jb2wpO1xuXG4gICAgaWYgKGdsb2JhbC5YTUxIdHRwUmVxdWVzdCkge1xuICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgeGhyLndpdGhDcmVkZW50aWFscyAhPT0gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgZmFsc2UpO1xuICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBDT1JTO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3MgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBVUkkgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBjb3B5T2JqZWN0ID0gcmVxdWlyZSgnLi4vdXRpbC9jb3B5X29iamVjdCcpLFxuICAgIGV4dGVuZCAgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIERlZmVycmFibGUgPSByZXF1aXJlKCcuLi9taXhpbnMvZGVmZXJyYWJsZScpLFxuICAgIFRyYW5zcG9ydCAgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpLFxuICAgIFhIUiAgICAgICAgPSByZXF1aXJlKCcuL3hocicpO1xuXG52YXIgRXZlbnRTb3VyY2UgPSBleHRlbmQoQ2xhc3MoVHJhbnNwb3J0LCB7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKGRpc3BhdGNoZXIsIGVuZHBvaW50KSB7XG4gICAgVHJhbnNwb3J0LnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcywgZGlzcGF0Y2hlciwgZW5kcG9pbnQpO1xuICAgIGlmICghZ2xvYmFsLkV2ZW50U291cmNlKSByZXR1cm4gdGhpcy5zZXREZWZlcnJlZFN0YXR1cygnZmFpbGVkJyk7XG5cbiAgICB0aGlzLl94aHIgPSBuZXcgWEhSKGRpc3BhdGNoZXIsIGVuZHBvaW50KTtcblxuICAgIGVuZHBvaW50ID0gY29weU9iamVjdChlbmRwb2ludCk7XG4gICAgZW5kcG9pbnQucGF0aG5hbWUgKz0gJy8nICsgZGlzcGF0Y2hlci5jbGllbnRJZDtcblxuICAgIHZhciBzb2NrZXQgPSBuZXcgZ2xvYmFsLkV2ZW50U291cmNlKFVSSS5zdHJpbmdpZnkoZW5kcG9pbnQpKSxcbiAgICAgICAgc2VsZiAgID0gdGhpcztcblxuICAgIHNvY2tldC5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuX2V2ZXJDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgc2VsZi5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgfTtcblxuICAgIHNvY2tldC5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoc2VsZi5fZXZlckNvbm5lY3RlZCkge1xuICAgICAgICBzZWxmLl9oYW5kbGVFcnJvcihbXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCdmYWlsZWQnKTtcbiAgICAgICAgc29ja2V0LmNsb3NlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHNvY2tldC5vbm1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIHJlcGxpZXM7XG4gICAgICB0cnkgeyByZXBsaWVzID0gSlNPTi5wYXJzZShldmVudC5kYXRhKSB9IGNhdGNoIChlcnJvcikge31cblxuICAgICAgaWYgKHJlcGxpZXMpXG4gICAgICAgIHNlbGYuX3JlY2VpdmUocmVwbGllcyk7XG4gICAgICBlbHNlXG4gICAgICAgIHNlbGYuX2hhbmRsZUVycm9yKFtdKTtcbiAgICB9O1xuXG4gICAgdGhpcy5fc29ja2V0ID0gc29ja2V0O1xuICB9LFxuXG4gIGNsb3NlOiBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuX3NvY2tldCkgcmV0dXJuO1xuICAgIHRoaXMuX3NvY2tldC5vbm9wZW4gPSB0aGlzLl9zb2NrZXQub25lcnJvciA9IHRoaXMuX3NvY2tldC5vbm1lc3NhZ2UgPSBudWxsO1xuICAgIHRoaXMuX3NvY2tldC5jbG9zZSgpO1xuICAgIGRlbGV0ZSB0aGlzLl9zb2NrZXQ7XG4gIH0sXG5cbiAgaXNVc2FibGU6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5jYWxsYmFjayhmdW5jdGlvbigpIHsgY2FsbGJhY2suY2FsbChjb250ZXh0LCB0cnVlKSB9KTtcbiAgICB0aGlzLmVycmJhY2soZnVuY3Rpb24oKSB7IGNhbGxiYWNrLmNhbGwoY29udGV4dCwgZmFsc2UpIH0pO1xuICB9LFxuXG4gIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICByZXR1cm4gdGhpcy5feGhyLmVuY29kZShtZXNzYWdlcyk7XG4gIH0sXG5cbiAgcmVxdWVzdDogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICByZXR1cm4gdGhpcy5feGhyLnJlcXVlc3QobWVzc2FnZXMpO1xuICB9XG5cbn0pLCB7XG4gIGlzVXNhYmxlOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgaWQgPSBkaXNwYXRjaGVyLmNsaWVudElkO1xuICAgIGlmICghaWQpIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIGZhbHNlKTtcblxuICAgIFhIUi5pc1VzYWJsZShkaXNwYXRjaGVyLCBlbmRwb2ludCwgZnVuY3Rpb24odXNhYmxlKSB7XG4gICAgICBpZiAoIXVzYWJsZSkgcmV0dXJuIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgZmFsc2UpO1xuICAgICAgdGhpcy5jcmVhdGUoZGlzcGF0Y2hlciwgZW5kcG9pbnQpLmlzVXNhYmxlKGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgICB9LCB0aGlzKTtcbiAgfSxcblxuICBjcmVhdGU6IGZ1bmN0aW9uKGRpc3BhdGNoZXIsIGVuZHBvaW50KSB7XG4gICAgdmFyIHNvY2tldHMgPSBkaXNwYXRjaGVyLnRyYW5zcG9ydHMuZXZlbnRzb3VyY2UgPSBkaXNwYXRjaGVyLnRyYW5zcG9ydHMuZXZlbnRzb3VyY2UgfHwge30sXG4gICAgICAgIGlkICAgICAgPSBkaXNwYXRjaGVyLmNsaWVudElkO1xuXG4gICAgdmFyIHVybCA9IGNvcHlPYmplY3QoZW5kcG9pbnQpO1xuICAgIHVybC5wYXRobmFtZSArPSAnLycgKyAoaWQgfHwgJycpO1xuICAgIHVybCA9IFVSSS5zdHJpbmdpZnkodXJsKTtcblxuICAgIHNvY2tldHNbdXJsXSA9IHNvY2tldHNbdXJsXSB8fCBuZXcgdGhpcyhkaXNwYXRjaGVyLCBlbmRwb2ludCk7XG4gICAgcmV0dXJuIHNvY2tldHNbdXJsXTtcbiAgfVxufSk7XG5cbmV4dGVuZChFdmVudFNvdXJjZS5wcm90b3R5cGUsIERlZmVycmFibGUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50U291cmNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3MgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBVUkkgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBjb3B5T2JqZWN0ID0gcmVxdWlyZSgnLi4vdXRpbC9jb3B5X29iamVjdCcpLFxuICAgIGV4dGVuZCAgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIHRvSlNPTiAgICAgPSByZXF1aXJlKCcuLi91dGlsL3RvX2pzb24nKSxcbiAgICBUcmFuc3BvcnQgID0gcmVxdWlyZSgnLi90cmFuc3BvcnQnKTtcblxudmFyIEpTT05QID0gZXh0ZW5kKENsYXNzKFRyYW5zcG9ydCwge1xuIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICB2YXIgdXJsID0gY29weU9iamVjdCh0aGlzLmVuZHBvaW50KTtcbiAgICB1cmwucXVlcnkubWVzc2FnZSA9IHRvSlNPTihtZXNzYWdlcyk7XG4gICAgdXJsLnF1ZXJ5Lmpzb25wICAgPSAnX19qc29ucCcgKyBKU09OUC5fY2JDb3VudCArICdfXyc7XG4gICAgcmV0dXJuIFVSSS5zdHJpbmdpZnkodXJsKTtcbiAgfSxcblxuICByZXF1ZXN0OiBmdW5jdGlvbihtZXNzYWdlcykge1xuICAgIHZhciBoZWFkICAgICAgICAgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLFxuICAgICAgICBzY3JpcHQgICAgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSxcbiAgICAgICAgY2FsbGJhY2tOYW1lID0gSlNPTlAuZ2V0Q2FsbGJhY2tOYW1lKCksXG4gICAgICAgIGVuZHBvaW50ICAgICA9IGNvcHlPYmplY3QodGhpcy5lbmRwb2ludCksXG4gICAgICAgIHNlbGYgICAgICAgICA9IHRoaXM7XG5cbiAgICBlbmRwb2ludC5xdWVyeS5tZXNzYWdlID0gdG9KU09OKG1lc3NhZ2VzKTtcbiAgICBlbmRwb2ludC5xdWVyeS5qc29ucCAgID0gY2FsbGJhY2tOYW1lO1xuXG4gICAgdmFyIGNsZWFudXAgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghZ2xvYmFsW2NhbGxiYWNrTmFtZV0pIHJldHVybiBmYWxzZTtcbiAgICAgIGdsb2JhbFtjYWxsYmFja05hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgdHJ5IHsgZGVsZXRlIGdsb2JhbFtjYWxsYmFja05hbWVdIH0gY2F0Y2ggKGVycm9yKSB7fVxuICAgICAgc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICB9O1xuXG4gICAgZ2xvYmFsW2NhbGxiYWNrTmFtZV0gPSBmdW5jdGlvbihyZXBsaWVzKSB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICBzZWxmLl9yZWNlaXZlKHJlcGxpZXMpO1xuICAgIH07XG5cbiAgICBzY3JpcHQudHlwZSA9ICd0ZXh0L2phdmFzY3JpcHQnO1xuICAgIHNjcmlwdC5zcmMgID0gVVJJLnN0cmluZ2lmeShlbmRwb2ludCk7XG4gICAgaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXG4gICAgc2NyaXB0Lm9uZXJyb3IgPSBmdW5jdGlvbigpIHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICAgIHNlbGYuX2hhbmRsZUVycm9yKG1lc3NhZ2VzKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHthYm9ydDogY2xlYW51cH07XG4gIH1cbn0pLCB7XG4gIF9jYkNvdW50OiAwLFxuXG4gIGdldENhbGxiYWNrTmFtZTogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fY2JDb3VudCArPSAxO1xuICAgIHJldHVybiAnX19qc29ucCcgKyB0aGlzLl9jYkNvdW50ICsgJ19fJztcbiAgfSxcblxuICBpc1VzYWJsZTogZnVuY3Rpb24oZGlzcGF0Y2hlciwgZW5kcG9pbnQsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgY2FsbGJhY2suY2FsbChjb250ZXh0LCB0cnVlKTtcbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gSlNPTlA7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBDb29raWUgICA9IHJlcXVpcmUoJy4uL3V0aWwvY29va2llcycpLkNvb2tpZSxcbiAgICBQcm9taXNlICA9IHJlcXVpcmUoJy4uL3V0aWwvcHJvbWlzZScpLFxuICAgIFVSSSAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBhcnJheSAgICA9IHJlcXVpcmUoJy4uL3V0aWwvYXJyYXknKSxcbiAgICBleHRlbmQgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgTG9nZ2luZyAgPSByZXF1aXJlKCcuLi9taXhpbnMvbG9nZ2luZycpLFxuICAgIFRpbWVvdXRzID0gcmVxdWlyZSgnLi4vbWl4aW5zL3RpbWVvdXRzJyksXG4gICAgQ2hhbm5lbCAgPSByZXF1aXJlKCcuLi9wcm90b2NvbC9jaGFubmVsJyk7XG5cbnZhciBUcmFuc3BvcnQgPSBleHRlbmQoQ2xhc3MoeyBjbGFzc05hbWU6ICdUcmFuc3BvcnQnLFxuICBERUZBVUxUX1BPUlRTOiB7J2h0dHA6JzogODAsICdodHRwczonOiA0NDMsICd3czonOiA4MCwgJ3dzczonOiA0NDN9LFxuICBNQVhfREVMQVk6ICAgICAwLFxuXG4gIGJhdGNoaW5nOiAgdHJ1ZSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCkge1xuICAgIHRoaXMuX2Rpc3BhdGNoZXIgPSBkaXNwYXRjaGVyO1xuICAgIHRoaXMuZW5kcG9pbnQgICAgPSBlbmRwb2ludDtcbiAgICB0aGlzLl9vdXRib3ggICAgID0gW107XG4gICAgdGhpcy5fcHJveHkgICAgICA9IGV4dGVuZCh7fSwgdGhpcy5fZGlzcGF0Y2hlci5wcm94eSk7XG5cbiAgICBpZiAoIXRoaXMuX3Byb3h5Lm9yaWdpbilcbiAgICAgIHRoaXMuX3Byb3h5Lm9yaWdpbiA9IHRoaXMuX2ZpbmRQcm94eSgpO1xuICB9LFxuXG4gIGNsb3NlOiBmdW5jdGlvbigpIHt9LFxuXG4gIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICByZXR1cm4gJyc7XG4gIH0sXG5cbiAgc2VuZE1lc3NhZ2U6IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICB0aGlzLmRlYnVnKCdDbGllbnQgPyBzZW5kaW5nIG1lc3NhZ2UgdG8gPzogPycsXG4gICAgICAgICAgICAgICB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkLCBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpLCBtZXNzYWdlKTtcblxuICAgIGlmICghdGhpcy5iYXRjaGluZykgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLnJlcXVlc3QoW21lc3NhZ2VdKSk7XG5cbiAgICB0aGlzLl9vdXRib3gucHVzaChtZXNzYWdlKTtcbiAgICB0aGlzLl9mbHVzaExhcmdlQmF0Y2goKTtcblxuICAgIGlmIChtZXNzYWdlLmNoYW5uZWwgPT09IENoYW5uZWwuSEFORFNIQUtFKVxuICAgICAgcmV0dXJuIHRoaXMuX3B1Ymxpc2goMC4wMSk7XG5cbiAgICBpZiAobWVzc2FnZS5jaGFubmVsID09PSBDaGFubmVsLkNPTk5FQ1QpXG4gICAgICB0aGlzLl9jb25uZWN0TWVzc2FnZSA9IG1lc3NhZ2U7XG5cbiAgICByZXR1cm4gdGhpcy5fcHVibGlzaCh0aGlzLk1BWF9ERUxBWSk7XG4gIH0sXG5cbiAgX21ha2VQcm9taXNlOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB0aGlzLl9yZXF1ZXN0UHJvbWlzZSA9IHRoaXMuX3JlcXVlc3RQcm9taXNlIHx8IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcbiAgICAgIHNlbGYuX3Jlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICB9KTtcbiAgfSxcblxuICBfcHVibGlzaDogZnVuY3Rpb24oZGVsYXkpIHtcbiAgICB0aGlzLl9tYWtlUHJvbWlzZSgpO1xuXG4gICAgdGhpcy5hZGRUaW1lb3V0KCdwdWJsaXNoJywgZGVsYXksIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5fZmx1c2goKTtcbiAgICAgIGRlbGV0ZSB0aGlzLl9yZXF1ZXN0UHJvbWlzZTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiB0aGlzLl9yZXF1ZXN0UHJvbWlzZTtcbiAgfSxcblxuICBfZmx1c2g6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMucmVtb3ZlVGltZW91dCgncHVibGlzaCcpO1xuXG4gICAgaWYgKHRoaXMuX291dGJveC5sZW5ndGggPiAxICYmIHRoaXMuX2Nvbm5lY3RNZXNzYWdlKVxuICAgICAgdGhpcy5fY29ubmVjdE1lc3NhZ2UuYWR2aWNlID0ge3RpbWVvdXQ6IDB9O1xuXG4gICAgdGhpcy5fcmVzb2x2ZVByb21pc2UodGhpcy5yZXF1ZXN0KHRoaXMuX291dGJveCkpO1xuXG4gICAgdGhpcy5fY29ubmVjdE1lc3NhZ2UgPSBudWxsO1xuICAgIHRoaXMuX291dGJveCA9IFtdO1xuICB9LFxuXG4gIF9mbHVzaExhcmdlQmF0Y2g6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzdHJpbmcgPSB0aGlzLmVuY29kZSh0aGlzLl9vdXRib3gpO1xuICAgIGlmIChzdHJpbmcubGVuZ3RoIDwgdGhpcy5fZGlzcGF0Y2hlci5tYXhSZXF1ZXN0U2l6ZSkgcmV0dXJuO1xuICAgIHZhciBsYXN0ID0gdGhpcy5fb3V0Ym94LnBvcCgpO1xuXG4gICAgdGhpcy5fbWFrZVByb21pc2UoKTtcbiAgICB0aGlzLl9mbHVzaCgpO1xuXG4gICAgaWYgKGxhc3QpIHRoaXMuX291dGJveC5wdXNoKGxhc3QpO1xuICB9LFxuXG4gIF9yZWNlaXZlOiBmdW5jdGlvbihyZXBsaWVzKSB7XG4gICAgaWYgKCFyZXBsaWVzKSByZXR1cm47XG4gICAgcmVwbGllcyA9IFtdLmNvbmNhdChyZXBsaWVzKTtcblxuICAgIHRoaXMuZGVidWcoJ0NsaWVudCA/IHJlY2VpdmVkIGZyb20gPyB2aWEgPzogPycsXG4gICAgICAgICAgICAgICB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkLCBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpLCB0aGlzLmNvbm5lY3Rpb25UeXBlLCByZXBsaWVzKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBuID0gcmVwbGllcy5sZW5ndGg7IGkgPCBuOyBpKyspXG4gICAgICB0aGlzLl9kaXNwYXRjaGVyLmhhbmRsZVJlc3BvbnNlKHJlcGxpZXNbaV0pO1xuICB9LFxuXG4gIF9oYW5kbGVFcnJvcjogZnVuY3Rpb24obWVzc2FnZXMsIGltbWVkaWF0ZSkge1xuICAgIG1lc3NhZ2VzID0gW10uY29uY2F0KG1lc3NhZ2VzKTtcblxuICAgIHRoaXMuZGVidWcoJ0NsaWVudCA/IGZhaWxlZCB0byBzZW5kIHRvID8gdmlhID86ID8nLFxuICAgICAgICAgICAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgVVJJLnN0cmluZ2lmeSh0aGlzLmVuZHBvaW50KSwgdGhpcy5jb25uZWN0aW9uVHlwZSwgbWVzc2FnZXMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBtZXNzYWdlcy5sZW5ndGg7IGkgPCBuOyBpKyspXG4gICAgICB0aGlzLl9kaXNwYXRjaGVyLmhhbmRsZUVycm9yKG1lc3NhZ2VzW2ldKTtcbiAgfSxcblxuICBfZ2V0Q29va2llczogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvb2tpZXMgPSB0aGlzLl9kaXNwYXRjaGVyLmNvb2tpZXMsXG4gICAgICAgIHVybCAgICAgPSBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpO1xuXG4gICAgaWYgKCFjb29raWVzKSByZXR1cm4gJyc7XG5cbiAgICByZXR1cm4gYXJyYXkubWFwKGNvb2tpZXMuZ2V0Q29va2llc1N5bmModXJsKSwgZnVuY3Rpb24oY29va2llKSB7XG4gICAgICByZXR1cm4gY29va2llLmNvb2tpZVN0cmluZygpO1xuICAgIH0pLmpvaW4oJzsgJyk7XG4gIH0sXG5cbiAgX3N0b3JlQ29va2llczogZnVuY3Rpb24oc2V0Q29va2llKSB7XG4gICAgdmFyIGNvb2tpZXMgPSB0aGlzLl9kaXNwYXRjaGVyLmNvb2tpZXMsXG4gICAgICAgIHVybCAgICAgPSBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpLFxuICAgICAgICBjb29raWU7XG5cbiAgICBpZiAoIXNldENvb2tpZSB8fCAhY29va2llcykgcmV0dXJuO1xuICAgIHNldENvb2tpZSA9IFtdLmNvbmNhdChzZXRDb29raWUpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBzZXRDb29raWUubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICBjb29raWUgPSBDb29raWUucGFyc2Uoc2V0Q29va2llW2ldKTtcbiAgICAgIGNvb2tpZXMuc2V0Q29va2llU3luYyhjb29raWUsIHVybCk7XG4gICAgfVxuICB9LFxuXG4gIF9maW5kUHJveHk6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgcHJvdG9jb2wgPSB0aGlzLmVuZHBvaW50LnByb3RvY29sO1xuICAgIGlmICghcHJvdG9jb2wpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgbmFtZSAgID0gcHJvdG9jb2wucmVwbGFjZSgvOiQvLCAnJykudG9Mb3dlckNhc2UoKSArICdfcHJveHknLFxuICAgICAgICB1cGNhc2UgPSBuYW1lLnRvVXBwZXJDYXNlKCksXG4gICAgICAgIGVudiAgICA9IHByb2Nlc3MuZW52LFxuICAgICAgICBrZXlzLCBwcm94eTtcblxuICAgIGlmIChuYW1lID09PSAnaHR0cF9wcm94eScgJiYgZW52LlJFUVVFU1RfTUVUSE9EKSB7XG4gICAgICBrZXlzID0gT2JqZWN0LmtleXMoZW52KS5maWx0ZXIoZnVuY3Rpb24oaykgeyByZXR1cm4gL15odHRwX3Byb3h5JC9pLnRlc3QoaykgfSk7XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgaWYgKGtleXNbMF0gPT09IG5hbWUgJiYgZW52W3VwY2FzZV0gPT09IHVuZGVmaW5lZClcbiAgICAgICAgICBwcm94eSA9IGVudltuYW1lXTtcbiAgICAgIH0gZWxzZSBpZiAoa2V5cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHByb3h5ID0gZW52W25hbWVdO1xuICAgICAgfVxuICAgICAgcHJveHkgPSBwcm94eSB8fCBlbnZbJ0NHSV8nICsgdXBjYXNlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJveHkgPSBlbnZbbmFtZV0gfHwgZW52W3VwY2FzZV07XG4gICAgICBpZiAocHJveHkgJiYgIWVudltuYW1lXSlcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGUgZW52aXJvbm1lbnQgdmFyaWFibGUgJyArIHVwY2FzZSArXG4gICAgICAgICAgICAgICAgICAgICAnIGlzIGRpc2NvdXJhZ2VkLiBVc2UgJyArIG5hbWUgKyAnLicpO1xuICAgIH1cbiAgICByZXR1cm4gcHJveHk7XG4gIH1cblxufSksIHtcbiAgZ2V0OiBmdW5jdGlvbihkaXNwYXRjaGVyLCBhbGxvd2VkLCBkaXNhYmxlZCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgZW5kcG9pbnQgPSBkaXNwYXRjaGVyLmVuZHBvaW50O1xuXG4gICAgYXJyYXkuYXN5bmNFYWNoKHRoaXMuX3RyYW5zcG9ydHMsIGZ1bmN0aW9uKHBhaXIsIHJlc3VtZSkge1xuICAgICAgdmFyIGNvbm5UeXBlICAgICA9IHBhaXJbMF0sIGtsYXNzID0gcGFpclsxXSxcbiAgICAgICAgICBjb25uRW5kcG9pbnQgPSBkaXNwYXRjaGVyLmVuZHBvaW50Rm9yKGNvbm5UeXBlKTtcblxuICAgICAgaWYgKGFycmF5LmluZGV4T2YoZGlzYWJsZWQsIGNvbm5UeXBlKSA+PSAwKVxuICAgICAgICByZXR1cm4gcmVzdW1lKCk7XG5cbiAgICAgIGlmIChhcnJheS5pbmRleE9mKGFsbG93ZWQsIGNvbm5UeXBlKSA8IDApIHtcbiAgICAgICAga2xhc3MuaXNVc2FibGUoZGlzcGF0Y2hlciwgY29ubkVuZHBvaW50LCBmdW5jdGlvbigpIHt9KTtcbiAgICAgICAgcmV0dXJuIHJlc3VtZSgpO1xuICAgICAgfVxuXG4gICAgICBrbGFzcy5pc1VzYWJsZShkaXNwYXRjaGVyLCBjb25uRW5kcG9pbnQsIGZ1bmN0aW9uKGlzVXNhYmxlKSB7XG4gICAgICAgIGlmICghaXNVc2FibGUpIHJldHVybiByZXN1bWUoKTtcbiAgICAgICAgdmFyIHRyYW5zcG9ydCA9IGtsYXNzLmhhc093blByb3BlcnR5KCdjcmVhdGUnKSA/IGtsYXNzLmNyZWF0ZShkaXNwYXRjaGVyLCBjb25uRW5kcG9pbnQpIDogbmV3IGtsYXNzKGRpc3BhdGNoZXIsIGNvbm5FbmRwb2ludCk7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgdHJhbnNwb3J0KTtcbiAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBhIHVzYWJsZSBjb25uZWN0aW9uIHR5cGUgZm9yICcgKyBVUkkuc3RyaW5naWZ5KGVuZHBvaW50KSk7XG4gICAgfSk7XG4gIH0sXG5cbiAgcmVnaXN0ZXI6IGZ1bmN0aW9uKHR5cGUsIGtsYXNzKSB7XG4gICAgdGhpcy5fdHJhbnNwb3J0cy5wdXNoKFt0eXBlLCBrbGFzc10pO1xuICAgIGtsYXNzLnByb3RvdHlwZS5jb25uZWN0aW9uVHlwZSA9IHR5cGU7XG4gIH0sXG5cbiAgZ2V0Q29ubmVjdGlvblR5cGVzOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXJyYXkubWFwKHRoaXMuX3RyYW5zcG9ydHMsIGZ1bmN0aW9uKHQpIHsgcmV0dXJuIHRbMF0gfSk7XG4gIH0sXG5cbiAgX3RyYW5zcG9ydHM6IFtdXG59KTtcblxuZXh0ZW5kKFRyYW5zcG9ydC5wcm90b3R5cGUsIExvZ2dpbmcpO1xuZXh0ZW5kKFRyYW5zcG9ydC5wcm90b3R5cGUsIFRpbWVvdXRzKTtcblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9jbGFzcycpLFxuICAgIFByb21pc2UgICAgPSByZXF1aXJlKCcuLi91dGlsL3Byb21pc2UnKSxcbiAgICBTZXQgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9zZXQnKSxcbiAgICBVUkkgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBicm93c2VyICAgID0gcmVxdWlyZSgnLi4vdXRpbC9icm93c2VyJyksXG4gICAgY29weU9iamVjdCA9IHJlcXVpcmUoJy4uL3V0aWwvY29weV9vYmplY3QnKSxcbiAgICBleHRlbmQgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICB0b0pTT04gICAgID0gcmVxdWlyZSgnLi4vdXRpbC90b19qc29uJyksXG4gICAgd3MgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvd2Vic29ja2V0JyksXG4gICAgRGVmZXJyYWJsZSA9IHJlcXVpcmUoJy4uL21peGlucy9kZWZlcnJhYmxlJyksXG4gICAgVHJhbnNwb3J0ICA9IHJlcXVpcmUoJy4vdHJhbnNwb3J0Jyk7XG5cbnZhciBXZWJTb2NrZXQgPSBleHRlbmQoQ2xhc3MoVHJhbnNwb3J0LCB7XG4gIFVOQ09OTkVDVEVEOiAgMSxcbiAgQ09OTkVDVElORzogICAyLFxuICBDT05ORUNURUQ6ICAgIDMsXG5cbiAgYmF0Y2hpbmc6ICAgICBmYWxzZSxcblxuICBpc1VzYWJsZTogZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB0aGlzLmNhbGxiYWNrKGZ1bmN0aW9uKCkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQsIHRydWUpIH0pO1xuICAgIHRoaXMuZXJyYmFjayhmdW5jdGlvbigpIHsgY2FsbGJhY2suY2FsbChjb250ZXh0LCBmYWxzZSkgfSk7XG4gICAgdGhpcy5jb25uZWN0KCk7XG4gIH0sXG5cbiAgcmVxdWVzdDogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICB0aGlzLl9wZW5kaW5nID0gdGhpcy5fcGVuZGluZyB8fCBuZXcgU2V0KCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBtZXNzYWdlcy5sZW5ndGg7IGkgPCBuOyBpKyspIHRoaXMuX3BlbmRpbmcuYWRkKG1lc3NhZ2VzW2ldKTtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBzZWxmLmNhbGxiYWNrKGZ1bmN0aW9uKHNvY2tldCkge1xuICAgICAgICBpZiAoIXNvY2tldCB8fCBzb2NrZXQucmVhZHlTdGF0ZSAhPT0gMSkgcmV0dXJuO1xuICAgICAgICBzb2NrZXQuc2VuZCh0b0pTT04obWVzc2FnZXMpKTtcbiAgICAgICAgcmVzb2x2ZShzb2NrZXQpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlbGYuY29ubmVjdCgpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFib3J0OiBmdW5jdGlvbigpIHsgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHdzKSB7IHdzLmNsb3NlKCkgfSkgfVxuICAgIH07XG4gIH0sXG5cbiAgY29ubmVjdDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKFdlYlNvY2tldC5fdW5sb2FkZWQpIHJldHVybjtcblxuICAgIHRoaXMuX3N0YXRlID0gdGhpcy5fc3RhdGUgfHwgdGhpcy5VTkNPTk5FQ1RFRDtcbiAgICBpZiAodGhpcy5fc3RhdGUgIT09IHRoaXMuVU5DT05ORUNURUQpIHJldHVybjtcbiAgICB0aGlzLl9zdGF0ZSA9IHRoaXMuQ09OTkVDVElORztcblxuICAgIHZhciBzb2NrZXQgPSB0aGlzLl9jcmVhdGVTb2NrZXQoKTtcbiAgICBpZiAoIXNvY2tldCkgcmV0dXJuIHRoaXMuc2V0RGVmZXJyZWRTdGF0dXMoJ2ZhaWxlZCcpO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgc29ja2V0Lm9ub3BlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHNvY2tldC5oZWFkZXJzKSBzZWxmLl9zdG9yZUNvb2tpZXMoc29ja2V0LmhlYWRlcnNbJ3NldC1jb29raWUnXSk7XG4gICAgICBzZWxmLl9zb2NrZXQgPSBzb2NrZXQ7XG4gICAgICBzZWxmLl9zdGF0ZSA9IHNlbGYuQ09OTkVDVEVEO1xuICAgICAgc2VsZi5fZXZlckNvbm5lY3RlZCA9IHRydWU7XG4gICAgICBzZWxmLl9waW5nKCk7XG4gICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCdzdWNjZWVkZWQnLCBzb2NrZXQpO1xuICAgIH07XG5cbiAgICB2YXIgY2xvc2VkID0gZmFsc2U7XG4gICAgc29ja2V0Lm9uY2xvc2UgPSBzb2NrZXQub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGNsb3NlZCkgcmV0dXJuO1xuICAgICAgY2xvc2VkID0gdHJ1ZTtcblxuICAgICAgdmFyIHdhc0Nvbm5lY3RlZCA9IChzZWxmLl9zdGF0ZSA9PT0gc2VsZi5DT05ORUNURUQpO1xuICAgICAgc29ja2V0Lm9ub3BlbiA9IHNvY2tldC5vbmNsb3NlID0gc29ja2V0Lm9uZXJyb3IgPSBzb2NrZXQub25tZXNzYWdlID0gbnVsbDtcblxuICAgICAgZGVsZXRlIHNlbGYuX3NvY2tldDtcbiAgICAgIHNlbGYuX3N0YXRlID0gc2VsZi5VTkNPTk5FQ1RFRDtcbiAgICAgIHNlbGYucmVtb3ZlVGltZW91dCgncGluZycpO1xuXG4gICAgICB2YXIgcGVuZGluZyA9IHNlbGYuX3BlbmRpbmcgPyBzZWxmLl9wZW5kaW5nLnRvQXJyYXkoKSA6IFtdO1xuICAgICAgZGVsZXRlIHNlbGYuX3BlbmRpbmc7XG5cbiAgICAgIGlmICh3YXNDb25uZWN0ZWQgfHwgc2VsZi5fZXZlckNvbm5lY3RlZCkge1xuICAgICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCd1bmtub3duJyk7XG4gICAgICAgIHNlbGYuX2hhbmRsZUVycm9yKHBlbmRpbmcsIHdhc0Nvbm5lY3RlZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCdmYWlsZWQnKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc29ja2V0Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICB2YXIgcmVwbGllcztcbiAgICAgIHRyeSB7IHJlcGxpZXMgPSBKU09OLnBhcnNlKGV2ZW50LmRhdGEpIH0gY2F0Y2ggKGVycm9yKSB7fVxuXG4gICAgICBpZiAoIXJlcGxpZXMpIHJldHVybjtcblxuICAgICAgcmVwbGllcyA9IFtdLmNvbmNhdChyZXBsaWVzKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSByZXBsaWVzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgICBpZiAocmVwbGllc1tpXS5zdWNjZXNzZnVsID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICBzZWxmLl9wZW5kaW5nLnJlbW92ZShyZXBsaWVzW2ldKTtcbiAgICAgIH1cbiAgICAgIHNlbGYuX3JlY2VpdmUocmVwbGllcyk7XG4gICAgfTtcbiAgfSxcblxuICBjbG9zZTogZnVuY3Rpb24oKSB7XG4gICAgaWYgKCF0aGlzLl9zb2NrZXQpIHJldHVybjtcbiAgICB0aGlzLl9zb2NrZXQuY2xvc2UoKTtcbiAgfSxcblxuICBfY3JlYXRlU29ja2V0OiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdXJsICAgICAgICA9IFdlYlNvY2tldC5nZXRTb2NrZXRVcmwodGhpcy5lbmRwb2ludCksXG4gICAgICAgIGhlYWRlcnMgICAgPSB0aGlzLl9kaXNwYXRjaGVyLmhlYWRlcnMsXG4gICAgICAgIGV4dGVuc2lvbnMgPSB0aGlzLl9kaXNwYXRjaGVyLndzRXh0ZW5zaW9ucyxcbiAgICAgICAgY29va2llICAgICA9IHRoaXMuX2dldENvb2tpZXMoKSxcbiAgICAgICAgdGxzICAgICAgICA9IHRoaXMuX2Rpc3BhdGNoZXIudGxzLFxuICAgICAgICBvcHRpb25zICAgID0ge2V4dGVuc2lvbnM6IGV4dGVuc2lvbnMsIGhlYWRlcnM6IGhlYWRlcnMsIHByb3h5OiB0aGlzLl9wcm94eSwgdGxzOiB0bHN9O1xuXG4gICAgaWYgKGNvb2tpZSAhPT0gJycpIG9wdGlvbnMuaGVhZGVyc1snQ29va2llJ10gPSBjb29raWU7XG5cbiAgICByZXR1cm4gd3MuY3JlYXRlKHVybCwgW10sIG9wdGlvbnMpO1xuICB9LFxuXG4gIF9waW5nOiBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuX3NvY2tldCB8fCB0aGlzLl9zb2NrZXQucmVhZHlTdGF0ZSAhPT0gMSkgcmV0dXJuO1xuICAgIHRoaXMuX3NvY2tldC5zZW5kKCdbXScpO1xuICAgIHRoaXMuYWRkVGltZW91dCgncGluZycsIHRoaXMuX2Rpc3BhdGNoZXIudGltZW91dCAvIDIsIHRoaXMuX3BpbmcsIHRoaXMpO1xuICB9XG5cbn0pLCB7XG4gIFBST1RPQ09MUzoge1xuICAgICdodHRwOic6ICAnd3M6JyxcbiAgICAnaHR0cHM6JzogJ3dzczonXG4gIH0sXG5cbiAgY3JlYXRlOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCkge1xuICAgIHZhciBzb2NrZXRzID0gZGlzcGF0Y2hlci50cmFuc3BvcnRzLndlYnNvY2tldCA9IGRpc3BhdGNoZXIudHJhbnNwb3J0cy53ZWJzb2NrZXQgfHwge307XG4gICAgc29ja2V0c1tlbmRwb2ludC5ocmVmXSA9IHNvY2tldHNbZW5kcG9pbnQuaHJlZl0gfHwgbmV3IHRoaXMoZGlzcGF0Y2hlciwgZW5kcG9pbnQpO1xuICAgIHJldHVybiBzb2NrZXRzW2VuZHBvaW50LmhyZWZdO1xuICB9LFxuXG4gIGdldFNvY2tldFVybDogZnVuY3Rpb24oZW5kcG9pbnQpIHtcbiAgICBlbmRwb2ludCA9IGNvcHlPYmplY3QoZW5kcG9pbnQpO1xuICAgIGVuZHBvaW50LnByb3RvY29sID0gdGhpcy5QUk9UT0NPTFNbZW5kcG9pbnQucHJvdG9jb2xdO1xuICAgIHJldHVybiBVUkkuc3RyaW5naWZ5KGVuZHBvaW50KTtcbiAgfSxcblxuICBpc1VzYWJsZTogZnVuY3Rpb24oZGlzcGF0Y2hlciwgZW5kcG9pbnQsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5jcmVhdGUoZGlzcGF0Y2hlciwgZW5kcG9pbnQpLmlzVXNhYmxlKGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgfVxufSk7XG5cbmV4dGVuZChXZWJTb2NrZXQucHJvdG90eXBlLCBEZWZlcnJhYmxlKTtcblxuaWYgKGJyb3dzZXIuRXZlbnQgJiYgZ2xvYmFsLm9uYmVmb3JldW5sb2FkICE9PSB1bmRlZmluZWQpXG4gIGJyb3dzZXIuRXZlbnQub24oZ2xvYmFsLCAnYmVmb3JldW5sb2FkJywgZnVuY3Rpb24oKSB7IFdlYlNvY2tldC5fdW5sb2FkZWQgPSB0cnVlIH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBVUkkgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3VyaScpLFxuICAgIGJyb3dzZXIgICA9IHJlcXVpcmUoJy4uL3V0aWwvYnJvd3NlcicpLFxuICAgIGV4dGVuZCAgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgdG9KU09OICAgID0gcmVxdWlyZSgnLi4vdXRpbC90b19qc29uJyksXG4gICAgVHJhbnNwb3J0ID0gcmVxdWlyZSgnLi90cmFuc3BvcnQnKTtcblxudmFyIFhIUiA9IGV4dGVuZChDbGFzcyhUcmFuc3BvcnQsIHtcbiAgZW5jb2RlOiBmdW5jdGlvbihtZXNzYWdlcykge1xuICAgIHJldHVybiB0b0pTT04obWVzc2FnZXMpO1xuICB9LFxuXG4gIHJlcXVlc3Q6IGZ1bmN0aW9uKG1lc3NhZ2VzKSB7XG4gICAgdmFyIGhyZWYgPSB0aGlzLmVuZHBvaW50LmhyZWYsXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICB4aHI7XG5cbiAgICAvLyBQcmVmZXIgWE1MSHR0cFJlcXVlc3Qgb3ZlciBBY3RpdmVYT2JqZWN0IGlmIHRoZXkgYm90aCBleGlzdFxuICAgIGlmIChnbG9iYWwuWE1MSHR0cFJlcXVlc3QpIHtcbiAgICAgIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIH0gZWxzZSBpZiAoZ2xvYmFsLkFjdGl2ZVhPYmplY3QpIHtcbiAgICAgIHhociA9IG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5faGFuZGxlRXJyb3IobWVzc2FnZXMpO1xuICAgIH1cblxuICAgIHhoci5vcGVuKCdQT1NUJywgaHJlZiwgdHJ1ZSk7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1ByYWdtYScsICduby1jYWNoZScpO1xuICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0Jyk7XG5cbiAgICB2YXIgaGVhZGVycyA9IHRoaXMuX2Rpc3BhdGNoZXIuaGVhZGVycztcbiAgICBmb3IgKHZhciBrZXkgaW4gaGVhZGVycykge1xuICAgICAgaWYgKCFoZWFkZXJzLmhhc093blByb3BlcnR5KGtleSkpIGNvbnRpbnVlO1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCBoZWFkZXJzW2tleV0pO1xuICAgIH1cblxuICAgIHZhciBhYm9ydCA9IGZ1bmN0aW9uKCkgeyB4aHIuYWJvcnQoKSB9O1xuICAgIGlmIChnbG9iYWwub25iZWZvcmV1bmxvYWQgIT09IHVuZGVmaW5lZClcbiAgICAgIGJyb3dzZXIuRXZlbnQub24oZ2xvYmFsLCAnYmVmb3JldW5sb2FkJywgYWJvcnQpO1xuXG4gICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF4aHIgfHwgeGhyLnJlYWR5U3RhdGUgIT09IDQpIHJldHVybjtcblxuICAgICAgdmFyIHJlcGxpZXMgICAgPSBudWxsLFxuICAgICAgICAgIHN0YXR1cyAgICAgPSB4aHIuc3RhdHVzLFxuICAgICAgICAgIHRleHQgICAgICAgPSB4aHIucmVzcG9uc2VUZXh0LFxuICAgICAgICAgIHN1Y2Nlc3NmdWwgPSAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDApIHx8IHN0YXR1cyA9PT0gMzA0IHx8IHN0YXR1cyA9PT0gMTIyMztcblxuICAgICAgaWYgKGdsb2JhbC5vbmJlZm9yZXVubG9hZCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICBicm93c2VyLkV2ZW50LmRldGFjaChnbG9iYWwsICdiZWZvcmV1bmxvYWQnLCBhYm9ydCk7XG5cbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHt9O1xuICAgICAgeGhyID0gbnVsbDtcblxuICAgICAgaWYgKCFzdWNjZXNzZnVsKSByZXR1cm4gc2VsZi5faGFuZGxlRXJyb3IobWVzc2FnZXMpO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXBsaWVzID0gSlNPTi5wYXJzZSh0ZXh0KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7fVxuXG4gICAgICBpZiAocmVwbGllcylcbiAgICAgICAgc2VsZi5fcmVjZWl2ZShyZXBsaWVzKTtcbiAgICAgIGVsc2VcbiAgICAgICAgc2VsZi5faGFuZGxlRXJyb3IobWVzc2FnZXMpO1xuICAgIH07XG5cbiAgICB4aHIuc2VuZCh0aGlzLmVuY29kZShtZXNzYWdlcykpO1xuICAgIHJldHVybiB4aHI7XG4gIH1cbn0pLCB7XG4gIGlzVXNhYmxlOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgdXNhYmxlID0gKG5hdmlnYXRvci5wcm9kdWN0ID09PSAnUmVhY3ROYXRpdmUnKVxuICAgICAgICAgICAgICB8fCBVUkkuaXNTYW1lT3JpZ2luKGVuZHBvaW50KTtcblxuICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgdXNhYmxlKTtcbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gWEhSO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29tbW9uRWxlbWVudDogZnVuY3Rpb24obGlzdGEsIGxpc3RiKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBsaXN0YS5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgIGlmICh0aGlzLmluZGV4T2YobGlzdGIsIGxpc3RhW2ldKSAhPT0gLTEpXG4gICAgICAgIHJldHVybiBsaXN0YVtpXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG5cbiAgaW5kZXhPZjogZnVuY3Rpb24obGlzdCwgbmVlZGxlKSB7XG4gICAgaWYgKGxpc3QuaW5kZXhPZikgcmV0dXJuIGxpc3QuaW5kZXhPZihuZWVkbGUpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBsaXN0Lmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IG5lZWRsZSkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfSxcblxuICBtYXA6IGZ1bmN0aW9uKG9iamVjdCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICBpZiAob2JqZWN0Lm1hcCkgcmV0dXJuIG9iamVjdC5tYXAoY2FsbGJhY2ssIGNvbnRleHQpO1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGNhbGxiYWNrLmNhbGwoY29udGV4dCB8fCBudWxsLCBvYmplY3RbaV0sIGkpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAoIW9iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcbiAgICAgICAgcmVzdWx0LnB1c2goY2FsbGJhY2suY2FsbChjb250ZXh0IHx8IG51bGwsIGtleSwgb2JqZWN0W2tleV0pKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICBmaWx0ZXI6IGZ1bmN0aW9uKGFycmF5LCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmIChhcnJheS5maWx0ZXIpIHJldHVybiBhcnJheS5maWx0ZXIoY2FsbGJhY2ssIGNvbnRleHQpO1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IGFycmF5Lmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgaWYgKGNhbGxiYWNrLmNhbGwoY29udGV4dCB8fCBudWxsLCBhcnJheVtpXSwgaSkpXG4gICAgICAgIHJlc3VsdC5wdXNoKGFycmF5W2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICBhc3luY0VhY2g6IGZ1bmN0aW9uKGxpc3QsIGl0ZXJhdG9yLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHZhciBuICAgICAgID0gbGlzdC5sZW5ndGgsXG4gICAgICAgIGkgICAgICAgPSAtMSxcbiAgICAgICAgY2FsbHMgICA9IDAsXG4gICAgICAgIGxvb3BpbmcgPSBmYWxzZTtcblxuICAgIHZhciBpdGVyYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgICBjYWxscyAtPSAxO1xuICAgICAgaSArPSAxO1xuICAgICAgaWYgKGkgPT09IG4pIHJldHVybiBjYWxsYmFjayAmJiBjYWxsYmFjay5jYWxsKGNvbnRleHQpO1xuICAgICAgaXRlcmF0b3IobGlzdFtpXSwgcmVzdW1lKTtcbiAgICB9O1xuXG4gICAgdmFyIGxvb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChsb29waW5nKSByZXR1cm47XG4gICAgICBsb29waW5nID0gdHJ1ZTtcbiAgICAgIHdoaWxlIChjYWxscyA+IDApIGl0ZXJhdGUoKTtcbiAgICAgIGxvb3BpbmcgPSBmYWxzZTtcbiAgICB9O1xuXG4gICAgdmFyIHJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgY2FsbHMgKz0gMTtcbiAgICAgIGxvb3AoKTtcbiAgICB9O1xuICAgIHJlc3VtZSgpO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnQgPSB7XG4gIF9yZWdpc3RyeTogW10sXG5cbiAgb246IGZ1bmN0aW9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uKCkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQpIH07XG5cbiAgICBpZiAoZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKVxuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgd3JhcHBlZCwgZmFsc2UpO1xuICAgIGVsc2VcbiAgICAgIGVsZW1lbnQuYXR0YWNoRXZlbnQoJ29uJyArIGV2ZW50TmFtZSwgd3JhcHBlZCk7XG5cbiAgICB0aGlzLl9yZWdpc3RyeS5wdXNoKHtcbiAgICAgIF9lbGVtZW50OiAgIGVsZW1lbnQsXG4gICAgICBfdHlwZTogICAgICBldmVudE5hbWUsXG4gICAgICBfY2FsbGJhY2s6ICBjYWxsYmFjayxcbiAgICAgIF9jb250ZXh0OiAgICAgY29udGV4dCxcbiAgICAgIF9oYW5kbGVyOiAgIHdyYXBwZWRcbiAgICB9KTtcbiAgfSxcblxuICBkZXRhY2g6IGZ1bmN0aW9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgaSA9IHRoaXMuX3JlZ2lzdHJ5Lmxlbmd0aCwgcmVnaXN0ZXI7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgcmVnaXN0ZXIgPSB0aGlzLl9yZWdpc3RyeVtpXTtcblxuICAgICAgaWYgKChlbGVtZW50ICAgICYmIGVsZW1lbnQgICAgIT09IHJlZ2lzdGVyLl9lbGVtZW50KSAgfHxcbiAgICAgICAgICAoZXZlbnROYW1lICAmJiBldmVudE5hbWUgICE9PSByZWdpc3Rlci5fdHlwZSkgICAgIHx8XG4gICAgICAgICAgKGNhbGxiYWNrICAgJiYgY2FsbGJhY2sgICAhPT0gcmVnaXN0ZXIuX2NhbGxiYWNrKSB8fFxuICAgICAgICAgIChjb250ZXh0ICAgICYmIGNvbnRleHQgICAgIT09IHJlZ2lzdGVyLl9jb250ZXh0KSlcbiAgICAgICAgY29udGludWU7XG5cbiAgICAgIGlmIChyZWdpc3Rlci5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICByZWdpc3Rlci5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHJlZ2lzdGVyLl90eXBlLCByZWdpc3Rlci5faGFuZGxlciwgZmFsc2UpO1xuICAgICAgZWxzZVxuICAgICAgICByZWdpc3Rlci5fZWxlbWVudC5kZXRhY2hFdmVudCgnb24nICsgcmVnaXN0ZXIuX3R5cGUsIHJlZ2lzdGVyLl9oYW5kbGVyKTtcblxuICAgICAgdGhpcy5fcmVnaXN0cnkuc3BsaWNlKGksMSk7XG4gICAgICByZWdpc3RlciA9IG51bGw7XG4gICAgfVxuICB9XG59O1xuXG5pZiAoZ2xvYmFsLm9udW5sb2FkICE9PSB1bmRlZmluZWQpXG4gIEV2ZW50Lm9uKGdsb2JhbCwgJ3VubG9hZCcsIEV2ZW50LmRldGFjaCwgRXZlbnQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgRXZlbnQ6IEV2ZW50XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi9leHRlbmQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihwYXJlbnQsIG1ldGhvZHMpIHtcbiAgaWYgKHR5cGVvZiBwYXJlbnQgIT09ICdmdW5jdGlvbicpIHtcbiAgICBtZXRob2RzID0gcGFyZW50O1xuICAgIHBhcmVudCAgPSBPYmplY3Q7XG4gIH1cblxuICB2YXIga2xhc3MgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuaW5pdGlhbGl6ZSkgcmV0dXJuIHRoaXM7XG4gICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gIH07XG5cbiAgdmFyIGJyaWRnZSA9IGZ1bmN0aW9uKCkge307XG4gIGJyaWRnZS5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlO1xuXG4gIGtsYXNzLnByb3RvdHlwZSA9IG5ldyBicmlkZ2UoKTtcbiAgZXh0ZW5kKGtsYXNzLnByb3RvdHlwZSwgbWV0aG9kcyk7XG5cbiAgcmV0dXJuIGtsYXNzO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBWRVJTSU9OOiAgICAgICAgICAnMS4yLjQnLFxuXG4gIEJBWUVVWF9WRVJTSU9OOiAgICcxLjAnLFxuICBJRF9MRU5HVEg6ICAgICAgICAxNjAsXG4gIEpTT05QX0NBTExCQUNLOiAgICdqc29ucGNhbGxiYWNrJyxcbiAgQ09OTkVDVElPTl9UWVBFUzogWydsb25nLXBvbGxpbmcnLCAnY3Jvc3Mtb3JpZ2luLWxvbmctcG9sbGluZycsICdjYWxsYmFjay1wb2xsaW5nJywgJ3dlYnNvY2tldCcsICdldmVudHNvdXJjZScsICdpbi1wcm9jZXNzJ10sXG5cbiAgTUFOREFUT1JZX0NPTk5FQ1RJT05fVFlQRVM6IFsnbG9uZy1wb2xsaW5nJywgJ2NhbGxiYWNrLXBvbGxpbmcnLCAnaW4tcHJvY2VzcyddXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29weU9iamVjdCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgY2xvbmUsIGksIGtleTtcbiAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgY2xvbmUgPSBbXTtcbiAgICBpID0gb2JqZWN0Lmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSBjbG9uZVtpXSA9IGNvcHlPYmplY3Qob2JqZWN0W2ldKTtcbiAgICByZXR1cm4gY2xvbmU7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpIHtcbiAgICBjbG9uZSA9IChvYmplY3QgPT09IG51bGwpID8gbnVsbCA6IHt9O1xuICAgIGZvciAoa2V5IGluIG9iamVjdCkgY2xvbmVba2V5XSA9IGNvcHlPYmplY3Qob2JqZWN0W2tleV0pO1xuICAgIHJldHVybiBjbG9uZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNvcHlPYmplY3Q7XG4iLCIvKlxuQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5IG9mXG50aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluXG50aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvXG51c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllc1xub2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvXG5zbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuU09GVFdBUkUuXG4qL1xuXG52YXIgaXNBcnJheSA9IHR5cGVvZiBBcnJheS5pc0FycmF5ID09PSAnZnVuY3Rpb24nXG4gICAgPyBBcnJheS5pc0FycmF5XG4gICAgOiBmdW5jdGlvbiAoeHMpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4cykgPT09ICdbb2JqZWN0IEFycmF5XSdcbiAgICB9XG47XG5mdW5jdGlvbiBpbmRleE9mICh4cywgeCkge1xuICAgIGlmICh4cy5pbmRleE9mKSByZXR1cm4geHMuaW5kZXhPZih4KTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh4ID09PSB4c1tpXSkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge31cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc0FycmF5KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKVxuICAgIHtcbiAgICAgIGlmIChhcmd1bWVudHNbMV0gaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBhcmd1bWVudHNbMV07IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmNhdWdodCwgdW5zcGVjaWZpZWQgJ2Vycm9yJyBldmVudC5cIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpIHJldHVybiBmYWxzZTtcbiAgdmFyIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGlmICghaGFuZGxlcikgcmV0dXJuIGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PSAnZnVuY3Rpb24nKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfSBlbHNlIGlmIChpc0FycmF5KGhhbmRsZXIpKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8vIEV2ZW50RW1pdHRlciBpcyBkZWZpbmVkIGluIHNyYy9ub2RlX2V2ZW50cy5jY1xuLy8gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0KCkgaXMgYWxzbyBkZWZpbmVkIHRoZXJlLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICgnZnVuY3Rpb24nICE9PSB0eXBlb2YgbGlzdGVuZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2FkZExpc3RlbmVyIG9ubHkgdGFrZXMgaW5zdGFuY2VzIG9mIEZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAoIXRoaXMuX2V2ZW50cykgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PSBcIm5ld0xpc3RlbmVyc1wiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lcnNcIi5cbiAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSkge1xuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICB9IGVsc2UgaWYgKGlzQXJyYXkodGhpcy5fZXZlbnRzW3R5cGVdKSkge1xuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIH0gZWxzZSB7XG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzZWxmLm9uKHR5cGUsIGZ1bmN0aW9uIGcoKSB7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcbiAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9KTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoJ2Z1bmN0aW9uJyAhPT0gdHlwZW9mIGxpc3RlbmVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyZW1vdmVMaXN0ZW5lciBvbmx5IHRha2VzIGluc3RhbmNlcyBvZiBGdW5jdGlvbicpO1xuICB9XG5cbiAgLy8gZG9lcyBub3QgdXNlIGxpc3RlbmVycygpLCBzbyBubyBzaWRlIGVmZmVjdCBvZiBjcmVhdGluZyBfZXZlbnRzW3R5cGVdXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pIHJldHVybiB0aGlzO1xuXG4gIHZhciBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0FycmF5KGxpc3QpKSB7XG4gICAgdmFyIGkgPSBpbmRleE9mKGxpc3QsIGxpc3RlbmVyKTtcbiAgICBpZiAoaSA8IDApIHJldHVybiB0aGlzO1xuICAgIGxpc3Quc3BsaWNlKGksIDEpO1xuICAgIGlmIChsaXN0Lmxlbmd0aCA9PSAwKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgfSBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0gPT09IGxpc3RlbmVyKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBkb2VzIG5vdCB1c2UgbGlzdGVuZXJzKCksIHNvIG5vIHNpZGUgZWZmZWN0IG9mIGNyZWF0aW5nIF9ldmVudHNbdHlwZV1cbiAgaWYgKHR5cGUgJiYgdGhpcy5fZXZlbnRzICYmIHRoaXMuX2V2ZW50c1t0eXBlXSkgdGhpcy5fZXZlbnRzW3R5cGVdID0gbnVsbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMpIHRoaXMuX2V2ZW50cyA9IHt9O1xuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSkgdGhpcy5fZXZlbnRzW3R5cGVdID0gW107XG4gIGlmICghaXNBcnJheSh0aGlzLl9ldmVudHNbdHlwZV0pKSB7XG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2V2ZW50c1t0eXBlXTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZGVzdCwgc291cmNlLCBvdmVyd3JpdGUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiBkZXN0O1xuICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgaWYgKCFzb3VyY2UuaGFzT3duUHJvcGVydHkoa2V5KSkgY29udGludWU7XG4gICAgaWYgKGRlc3QuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBvdmVyd3JpdGUgPT09IGZhbHNlKSBjb250aW51ZTtcbiAgICBpZiAoZGVzdFtrZXldICE9PSBzb3VyY2Vba2V5XSlcbiAgICAgIGRlc3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBkZXN0O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzYXAgPSByZXF1aXJlKCdhc2FwJyk7XG5cbnZhciBQRU5ESU5HICAgPSAwLFxuICAgIEZVTEZJTExFRCA9IDEsXG4gICAgUkVKRUNURUQgID0gMjtcblxudmFyIFJFVFVSTiA9IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggfSxcbiAgICBUSFJPVyAgPSBmdW5jdGlvbih4KSB7IHRocm93ICB4IH07XG5cbnZhciBQcm9taXNlID0gZnVuY3Rpb24odGFzaykge1xuICB0aGlzLl9zdGF0ZSAgICAgICA9IFBFTkRJTkc7XG4gIHRoaXMuX29uRnVsZmlsbGVkID0gW107XG4gIHRoaXMuX29uUmVqZWN0ZWQgID0gW107XG5cbiAgaWYgKHR5cGVvZiB0YXNrICE9PSAnZnVuY3Rpb24nKSByZXR1cm47XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0YXNrKGZ1bmN0aW9uKHZhbHVlKSAgeyByZXNvbHZlKHNlbGYsIHZhbHVlKSB9LFxuICAgICAgIGZ1bmN0aW9uKHJlYXNvbikgeyByZWplY3Qoc2VsZiwgcmVhc29uKSB9KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICB2YXIgbmV4dCA9IG5ldyBQcm9taXNlKCk7XG4gIHJlZ2lzdGVyT25GdWxmaWxsZWQodGhpcywgb25GdWxmaWxsZWQsIG5leHQpO1xuICByZWdpc3Rlck9uUmVqZWN0ZWQodGhpcywgb25SZWplY3RlZCwgbmV4dCk7XG4gIHJldHVybiBuZXh0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGVbJ2NhdGNoJ10gPSBmdW5jdGlvbihvblJlamVjdGVkKSB7XG4gIHJldHVybiB0aGlzLnRoZW4obnVsbCwgb25SZWplY3RlZCk7XG59O1xuXG52YXIgcmVnaXN0ZXJPbkZ1bGZpbGxlZCA9IGZ1bmN0aW9uKHByb21pc2UsIG9uRnVsZmlsbGVkLCBuZXh0KSB7XG4gIGlmICh0eXBlb2Ygb25GdWxmaWxsZWQgIT09ICdmdW5jdGlvbicpIG9uRnVsZmlsbGVkID0gUkVUVVJOO1xuICB2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKHZhbHVlKSB7IGludm9rZShvbkZ1bGZpbGxlZCwgdmFsdWUsIG5leHQpIH07XG5cbiAgaWYgKHByb21pc2UuX3N0YXRlID09PSBQRU5ESU5HKSB7XG4gICAgcHJvbWlzZS5fb25GdWxmaWxsZWQucHVzaChoYW5kbGVyKTtcbiAgfSBlbHNlIGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gRlVMRklMTEVEKSB7XG4gICAgaGFuZGxlcihwcm9taXNlLl92YWx1ZSk7XG4gIH1cbn07XG5cbnZhciByZWdpc3Rlck9uUmVqZWN0ZWQgPSBmdW5jdGlvbihwcm9taXNlLCBvblJlamVjdGVkLCBuZXh0KSB7XG4gIGlmICh0eXBlb2Ygb25SZWplY3RlZCAhPT0gJ2Z1bmN0aW9uJykgb25SZWplY3RlZCA9IFRIUk9XO1xuICB2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKHJlYXNvbikgeyBpbnZva2Uob25SZWplY3RlZCwgcmVhc29uLCBuZXh0KSB9O1xuXG4gIGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gUEVORElORykge1xuICAgIHByb21pc2UuX29uUmVqZWN0ZWQucHVzaChoYW5kbGVyKTtcbiAgfSBlbHNlIGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICBoYW5kbGVyKHByb21pc2UuX3JlYXNvbik7XG4gIH1cbn07XG5cbnZhciBpbnZva2UgPSBmdW5jdGlvbihmbiwgdmFsdWUsIG5leHQpIHtcbiAgYXNhcChmdW5jdGlvbigpIHsgX2ludm9rZShmbiwgdmFsdWUsIG5leHQpIH0pO1xufTtcblxudmFyIF9pbnZva2UgPSBmdW5jdGlvbihmbiwgdmFsdWUsIG5leHQpIHtcbiAgdmFyIG91dGNvbWU7XG5cbiAgdHJ5IHtcbiAgICBvdXRjb21lID0gZm4odmFsdWUpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiByZWplY3QobmV4dCwgZXJyb3IpO1xuICB9XG5cbiAgaWYgKG91dGNvbWUgPT09IG5leHQpIHtcbiAgICByZWplY3QobmV4dCwgbmV3IFR5cGVFcnJvcignUmVjdXJzaXZlIHByb21pc2UgY2hhaW4gZGV0ZWN0ZWQnKSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzb2x2ZShuZXh0LCBvdXRjb21lKTtcbiAgfVxufTtcblxudmFyIHJlc29sdmUgPSBmdW5jdGlvbihwcm9taXNlLCB2YWx1ZSkge1xuICB2YXIgY2FsbGVkID0gZmFsc2UsIHR5cGUsIHRoZW47XG5cbiAgdHJ5IHtcbiAgICB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgIHRoZW4gPSB2YWx1ZSAhPT0gbnVsbCAmJiAodHlwZSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlID09PSAnb2JqZWN0JykgJiYgdmFsdWUudGhlbjtcblxuICAgIGlmICh0eXBlb2YgdGhlbiAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuXG4gICAgdGhlbi5jYWxsKHZhbHVlLCBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIShjYWxsZWQgXiAoY2FsbGVkID0gdHJ1ZSkpKSByZXR1cm47XG4gICAgICByZXNvbHZlKHByb21pc2UsIHYpO1xuICAgIH0sIGZ1bmN0aW9uKHIpIHtcbiAgICAgIGlmICghKGNhbGxlZCBeIChjYWxsZWQgPSB0cnVlKSkpIHJldHVybjtcbiAgICAgIHJlamVjdChwcm9taXNlLCByKTtcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoIShjYWxsZWQgXiAoY2FsbGVkID0gdHJ1ZSkpKSByZXR1cm47XG4gICAgcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgfVxufTtcblxudmFyIGZ1bGZpbGwgPSBmdW5jdGlvbihwcm9taXNlLCB2YWx1ZSkge1xuICBpZiAocHJvbWlzZS5fc3RhdGUgIT09IFBFTkRJTkcpIHJldHVybjtcblxuICBwcm9taXNlLl9zdGF0ZSAgICAgID0gRlVMRklMTEVEO1xuICBwcm9taXNlLl92YWx1ZSAgICAgID0gdmFsdWU7XG4gIHByb21pc2UuX29uUmVqZWN0ZWQgPSBbXTtcblxuICB2YXIgb25GdWxmaWxsZWQgPSBwcm9taXNlLl9vbkZ1bGZpbGxlZCwgZm47XG4gIHdoaWxlIChmbiA9IG9uRnVsZmlsbGVkLnNoaWZ0KCkpIGZuKHZhbHVlKTtcbn07XG5cbnZhciByZWplY3QgPSBmdW5jdGlvbihwcm9taXNlLCByZWFzb24pIHtcbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSByZXR1cm47XG5cbiAgcHJvbWlzZS5fc3RhdGUgICAgICAgPSBSRUpFQ1RFRDtcbiAgcHJvbWlzZS5fcmVhc29uICAgICAgPSByZWFzb247XG4gIHByb21pc2UuX29uRnVsZmlsbGVkID0gW107XG5cbiAgdmFyIG9uUmVqZWN0ZWQgPSBwcm9taXNlLl9vblJlamVjdGVkLCBmbjtcbiAgd2hpbGUgKGZuID0gb25SZWplY3RlZC5zaGlmdCgpKSBmbihyZWFzb24pO1xufTtcblxuUHJvbWlzZS5yZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkgeyByZXNvbHZlKHZhbHVlKSB9KTtcbn07XG5cblByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsgcmVqZWN0KHJlYXNvbikgfSk7XG59O1xuXG5Qcm9taXNlLmFsbCA9IGZ1bmN0aW9uKHByb21pc2VzKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgbGlzdCA9IFtdLCBuID0gcHJvbWlzZXMubGVuZ3RoLCBpO1xuXG4gICAgaWYgKG4gPT09IDApIHJldHVybiByZXNvbHZlKGxpc3QpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgKGZ1bmN0aW9uKHByb21pc2UsIGkpIHtcbiAgICAgIFByb21pc2UucmVzb2x2ZShwcm9taXNlKS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIGxpc3RbaV0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKC0tbiA9PT0gMCkgcmVzb2x2ZShsaXN0KTtcbiAgICAgIH0sIHJlamVjdCk7XG4gICAgfSkocHJvbWlzZXNbaV0sIGkpO1xuICB9KTtcbn07XG5cblByb21pc2UucmFjZSA9IGZ1bmN0aW9uKHByb21pc2VzKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IHByb21pc2VzLmxlbmd0aDsgaSA8IG47IGkrKylcbiAgICAgIFByb21pc2UucmVzb2x2ZShwcm9taXNlc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICB9KTtcbn07XG5cblByb21pc2UuZGVmZXJyZWQgPSBQcm9taXNlLnBlbmRpbmcgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHR1cGxlID0ge307XG5cbiAgdHVwbGUucHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHR1cGxlLnJlc29sdmUgPSByZXNvbHZlO1xuICAgIHR1cGxlLnJlamVjdCAgPSByZWplY3Q7XG4gIH0pO1xuICByZXR1cm4gdHVwbGU7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyA9IHJlcXVpcmUoJy4vY2xhc3MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBDbGFzcyh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2luZGV4ID0ge307XG4gIH0sXG5cbiAgYWRkOiBmdW5jdGlvbihpdGVtKSB7XG4gICAgdmFyIGtleSA9IChpdGVtLmlkICE9PSB1bmRlZmluZWQpID8gaXRlbS5pZCA6IGl0ZW07XG4gICAgaWYgKHRoaXMuX2luZGV4Lmhhc093blByb3BlcnR5KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICB0aGlzLl9pbmRleFtrZXldID0gaXRlbTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcblxuICBmb3JFYWNoOiBmdW5jdGlvbihibG9jaywgY29udGV4dCkge1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLl9pbmRleCkge1xuICAgICAgaWYgKHRoaXMuX2luZGV4Lmhhc093blByb3BlcnR5KGtleSkpXG4gICAgICAgIGJsb2NrLmNhbGwoY29udGV4dCwgdGhpcy5faW5kZXhba2V5XSk7XG4gICAgfVxuICB9LFxuXG4gIGlzRW1wdHk6IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLl9pbmRleCkge1xuICAgICAgaWYgKHRoaXMuX2luZGV4Lmhhc093blByb3BlcnR5KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG5cbiAgbWVtYmVyOiBmdW5jdGlvbihpdGVtKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuX2luZGV4KSB7XG4gICAgICBpZiAodGhpcy5faW5kZXhba2V5XSA9PT0gaXRlbSkgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICB2YXIga2V5ID0gKGl0ZW0uaWQgIT09IHVuZGVmaW5lZCkgPyBpdGVtLmlkIDogaXRlbTtcbiAgICB2YXIgcmVtb3ZlZCA9IHRoaXMuX2luZGV4W2tleV07XG4gICAgZGVsZXRlIHRoaXMuX2luZGV4W2tleV07XG4gICAgcmV0dXJuIHJlbW92ZWQ7XG4gIH0sXG5cbiAgdG9BcnJheTogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFycmF5ID0gW107XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pIHsgYXJyYXkucHVzaChpdGVtKSB9KTtcbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vYXNzYW5rYS5uZXQvY29udGVudC90ZWNoLzIwMDkvMDkvMDIvanNvbjItanMtdnMtcHJvdG90eXBlL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqZWN0LCBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuICh0aGlzW2tleV0gaW5zdGFuY2VvZiBBcnJheSkgPyB0aGlzW2tleV0gOiB2YWx1ZTtcbiAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaXNVUkk6IGZ1bmN0aW9uKHVyaSkge1xuICAgIHJldHVybiB1cmkgJiYgdXJpLnByb3RvY29sICYmIHVyaS5ob3N0ICYmIHVyaS5wYXRoO1xuICB9LFxuXG4gIGlzU2FtZU9yaWdpbjogZnVuY3Rpb24odXJpKSB7XG4gICAgcmV0dXJuIHVyaS5wcm90b2NvbCA9PT0gbG9jYXRpb24ucHJvdG9jb2wgJiZcbiAgICAgICAgICAgdXJpLmhvc3RuYW1lID09PSBsb2NhdGlvbi5ob3N0bmFtZSAmJlxuICAgICAgICAgICB1cmkucG9ydCAgICAgPT09IGxvY2F0aW9uLnBvcnQ7XG4gIH0sXG5cbiAgcGFyc2U6IGZ1bmN0aW9uKHVybCkge1xuICAgIGlmICh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgcmV0dXJuIHVybDtcbiAgICB2YXIgdXJpID0ge30sIHBhcnRzLCBxdWVyeSwgcGFpcnMsIGksIG4sIGRhdGE7XG5cbiAgICB2YXIgY29uc3VtZSA9IGZ1bmN0aW9uKG5hbWUsIHBhdHRlcm4pIHtcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlKHBhdHRlcm4sIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICAgIHVyaVtuYW1lXSA9IG1hdGNoO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9KTtcbiAgICAgIHVyaVtuYW1lXSA9IHVyaVtuYW1lXSB8fCAnJztcbiAgICB9O1xuXG4gICAgY29uc3VtZSgncHJvdG9jb2wnLCAvXlthLXpdK1xcOi9pKTtcbiAgICBjb25zdW1lKCdob3N0JywgICAgIC9eXFwvXFwvW15cXC9cXD8jXSsvKTtcblxuICAgIGlmICghL15cXC8vLnRlc3QodXJsKSAmJiAhdXJpLmhvc3QpXG4gICAgICB1cmwgPSBsb2NhdGlvbi5wYXRobmFtZS5yZXBsYWNlKC9bXlxcL10qJC8sICcnKSArIHVybDtcblxuICAgIGNvbnN1bWUoJ3BhdGhuYW1lJywgL15bXlxcPyNdKi8pO1xuICAgIGNvbnN1bWUoJ3NlYXJjaCcsICAgL15cXD9bXiNdKi8pO1xuICAgIGNvbnN1bWUoJ2hhc2gnLCAgICAgL14jLiovKTtcblxuICAgIHVyaS5wcm90b2NvbCA9IHVyaS5wcm90b2NvbCB8fCBsb2NhdGlvbi5wcm90b2NvbDtcblxuICAgIGlmICh1cmkuaG9zdCkge1xuICAgICAgdXJpLmhvc3QgICAgID0gdXJpLmhvc3Quc3Vic3RyKDIpO1xuICAgICAgcGFydHMgICAgICAgID0gdXJpLmhvc3Quc3BsaXQoJzonKTtcbiAgICAgIHVyaS5ob3N0bmFtZSA9IHBhcnRzWzBdO1xuICAgICAgdXJpLnBvcnQgICAgID0gcGFydHNbMV0gfHwgJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVyaS5ob3N0ICAgICA9IGxvY2F0aW9uLmhvc3Q7XG4gICAgICB1cmkuaG9zdG5hbWUgPSBsb2NhdGlvbi5ob3N0bmFtZTtcbiAgICAgIHVyaS5wb3J0ICAgICA9IGxvY2F0aW9uLnBvcnQ7XG4gICAgfVxuXG4gICAgdXJpLnBhdGhuYW1lID0gdXJpLnBhdGhuYW1lIHx8ICcvJztcbiAgICB1cmkucGF0aCA9IHVyaS5wYXRobmFtZSArIHVyaS5zZWFyY2g7XG5cbiAgICBxdWVyeSA9IHVyaS5zZWFyY2gucmVwbGFjZSgvXlxcPy8sICcnKTtcbiAgICBwYWlycyA9IHF1ZXJ5ID8gcXVlcnkuc3BsaXQoJyYnKSA6IFtdO1xuICAgIGRhdGEgID0ge307XG5cbiAgICBmb3IgKGkgPSAwLCBuID0gcGFpcnMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICBwYXJ0cyA9IHBhaXJzW2ldLnNwbGl0KCc9Jyk7XG4gICAgICBkYXRhW2RlY29kZVVSSUNvbXBvbmVudChwYXJ0c1swXSB8fCAnJyldID0gZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzFdIHx8ICcnKTtcbiAgICB9XG5cbiAgICB1cmkucXVlcnkgPSBkYXRhO1xuXG4gICAgdXJpLmhyZWYgPSB0aGlzLnN0cmluZ2lmeSh1cmkpO1xuICAgIHJldHVybiB1cmk7XG4gIH0sXG5cbiAgc3RyaW5naWZ5OiBmdW5jdGlvbih1cmkpIHtcbiAgICB2YXIgc3RyaW5nID0gdXJpLnByb3RvY29sICsgJy8vJyArIHVyaS5ob3N0bmFtZTtcbiAgICBpZiAodXJpLnBvcnQpIHN0cmluZyArPSAnOicgKyB1cmkucG9ydDtcbiAgICBzdHJpbmcgKz0gdXJpLnBhdGhuYW1lICsgdGhpcy5xdWVyeVN0cmluZyh1cmkucXVlcnkpICsgKHVyaS5oYXNoIHx8ICcnKTtcbiAgICByZXR1cm4gc3RyaW5nO1xuICB9LFxuXG4gIHF1ZXJ5U3RyaW5nOiBmdW5jdGlvbihxdWVyeSkge1xuICAgIHZhciBwYWlycyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBxdWVyeSkge1xuICAgICAgaWYgKCFxdWVyeS5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcbiAgICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQocXVlcnlba2V5XSkpO1xuICAgIH1cbiAgICBpZiAocGFpcnMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuICc/JyArIHBhaXJzLmpvaW4oJyYnKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFycmF5ID0gcmVxdWlyZSgnLi9hcnJheScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9wdGlvbnMsIHZhbGlkS2V5cykge1xuICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucykge1xuICAgIGlmIChhcnJheS5pbmRleE9mKHZhbGlkS2V5cywga2V5KSA8IDApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VucmVjb2duaXplZCBvcHRpb246ICcgKyBrZXkpO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgV1MgPSBnbG9iYWwuTW96V2ViU29ja2V0IHx8IGdsb2JhbC5XZWJTb2NrZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGU6IGZ1bmN0aW9uKHVybCwgcHJvdG9jb2xzLCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBXUyAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIG5ldyBXUyh1cmwpO1xuICB9XG59O1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiJdfQ==
|