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,1054 +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.Bulk = 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
|
-
(function (process){
|
|
3
|
-
/*global process*/
|
|
4
|
-
/**
|
|
5
|
-
* @file Manages Salesforce Bulk API related operations
|
|
6
|
-
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
'use strict';
|
|
10
|
-
|
|
11
|
-
var inherits = window.jsforce.require('inherits'),
|
|
12
|
-
stream = window.jsforce.require('readable-stream'),
|
|
13
|
-
Duplex = stream.Duplex,
|
|
14
|
-
events = window.jsforce.require('events'),
|
|
15
|
-
_ = window.jsforce.require('lodash/core'),
|
|
16
|
-
joinStreams = window.jsforce.require('multistream'),
|
|
17
|
-
jsforce = window.jsforce.require('./core'),
|
|
18
|
-
RecordStream = window.jsforce.require('./record-stream'),
|
|
19
|
-
Promise = window.jsforce.require('./promise'),
|
|
20
|
-
HttpApi = window.jsforce.require('./http-api');
|
|
21
|
-
|
|
22
|
-
/*--------------------------------------------*/
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Class for Bulk API Job
|
|
26
|
-
*
|
|
27
|
-
* @protected
|
|
28
|
-
* @class Bulk~Job
|
|
29
|
-
* @extends events.EventEmitter
|
|
30
|
-
*
|
|
31
|
-
* @param {Bulk} bulk - Bulk API object
|
|
32
|
-
* @param {String} [type] - SObject type
|
|
33
|
-
* @param {String} [operation] - Bulk load operation ('insert', 'update', 'upsert', 'delete', or 'hardDelete')
|
|
34
|
-
* @param {Object} [options] - Options for bulk loading operation
|
|
35
|
-
* @param {String} [options.extIdField] - External ID field name (used when upsert operation).
|
|
36
|
-
* @param {String} [options.concurrencyMode] - 'Serial' or 'Parallel'. Defaults to Parallel.
|
|
37
|
-
* @param {String} [jobId] - Job ID (if already available)
|
|
38
|
-
*/
|
|
39
|
-
var Job = function(bulk, type, operation, options, jobId) {
|
|
40
|
-
this._bulk = bulk;
|
|
41
|
-
this.type = type;
|
|
42
|
-
this.operation = operation;
|
|
43
|
-
this.options = options || {};
|
|
44
|
-
this.id = jobId;
|
|
45
|
-
this.state = this.id ? 'Open' : 'Unknown';
|
|
46
|
-
this._batches = {};
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
inherits(Job, events.EventEmitter);
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @typedef {Object} Bulk~JobInfo
|
|
53
|
-
* @prop {String} id - Job ID
|
|
54
|
-
* @prop {String} object - Object type name
|
|
55
|
-
* @prop {String} operation - Operation type of the job
|
|
56
|
-
* @prop {String} state - Job status
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Return latest jobInfo from cache
|
|
61
|
-
*
|
|
62
|
-
* @method Bulk~Job#info
|
|
63
|
-
* @param {Callback.<Bulk~JobInfo>} [callback] - Callback function
|
|
64
|
-
* @returns {Promise.<Bulk~JobInfo>}
|
|
65
|
-
*/
|
|
66
|
-
Job.prototype.info = function(callback) {
|
|
67
|
-
var self = this;
|
|
68
|
-
// if cache is not available, check the latest
|
|
69
|
-
if (!this._jobInfo) {
|
|
70
|
-
this._jobInfo = this.check();
|
|
71
|
-
}
|
|
72
|
-
return this._jobInfo.thenCall(callback);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Open new job and get jobinfo
|
|
77
|
-
*
|
|
78
|
-
* @method Bulk~Job#open
|
|
79
|
-
* @param {Callback.<Bulk~JobInfo>} [callback] - Callback function
|
|
80
|
-
* @returns {Promise.<Bulk~JobInfo>}
|
|
81
|
-
*/
|
|
82
|
-
Job.prototype.open = function(callback) {
|
|
83
|
-
var self = this;
|
|
84
|
-
var bulk = this._bulk;
|
|
85
|
-
var logger = bulk._logger;
|
|
86
|
-
|
|
87
|
-
// if not requested opening job
|
|
88
|
-
if (!this._jobInfo) {
|
|
89
|
-
var operation = this.operation.toLowerCase();
|
|
90
|
-
if (operation === 'harddelete') { operation = 'hardDelete'; }
|
|
91
|
-
var body = [
|
|
92
|
-
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
93
|
-
'<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">',
|
|
94
|
-
'<operation>' + operation + '</operation>',
|
|
95
|
-
'<object>' + this.type + '</object>',
|
|
96
|
-
(this.options.extIdField ?
|
|
97
|
-
'<externalIdFieldName>'+this.options.extIdField+'</externalIdFieldName>' :
|
|
98
|
-
''),
|
|
99
|
-
(this.options.concurrencyMode ?
|
|
100
|
-
'<concurrencyMode>'+this.options.concurrencyMode+'</concurrencyMode>' :
|
|
101
|
-
''),
|
|
102
|
-
(this.options.assignmentRuleId ?
|
|
103
|
-
'<assignmentRuleId>' + this.options.assignmentRuleId + '</assignmentRuleId>' :
|
|
104
|
-
''),
|
|
105
|
-
'<contentType>CSV</contentType>',
|
|
106
|
-
'</jobInfo>'
|
|
107
|
-
].join('');
|
|
108
|
-
|
|
109
|
-
this._jobInfo = bulk._request({
|
|
110
|
-
method : 'POST',
|
|
111
|
-
path : "/job",
|
|
112
|
-
body : body,
|
|
113
|
-
headers : {
|
|
114
|
-
"Content-Type" : "application/xml; charset=utf-8"
|
|
115
|
-
},
|
|
116
|
-
responseType: "application/xml"
|
|
117
|
-
}).then(function(res) {
|
|
118
|
-
self.emit("open", res.jobInfo);
|
|
119
|
-
self.id = res.jobInfo.id;
|
|
120
|
-
self.state = res.jobInfo.state;
|
|
121
|
-
return res.jobInfo;
|
|
122
|
-
}, function(err) {
|
|
123
|
-
self.emit("error", err);
|
|
124
|
-
throw err;
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
return this._jobInfo.thenCall(callback);
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Create a new batch instance in the job
|
|
132
|
-
*
|
|
133
|
-
* @method Bulk~Job#createBatch
|
|
134
|
-
* @returns {Bulk~Batch}
|
|
135
|
-
*/
|
|
136
|
-
Job.prototype.createBatch = function() {
|
|
137
|
-
var batch = new Batch(this);
|
|
138
|
-
var self = this;
|
|
139
|
-
batch.on('queue', function() {
|
|
140
|
-
self._batches[batch.id] = batch;
|
|
141
|
-
});
|
|
142
|
-
return batch;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Get a batch instance specified by given batch ID
|
|
147
|
-
*
|
|
148
|
-
* @method Bulk~Job#batch
|
|
149
|
-
* @param {String} batchId - Batch ID
|
|
150
|
-
* @returns {Bulk~Batch}
|
|
151
|
-
*/
|
|
152
|
-
Job.prototype.batch = function(batchId) {
|
|
153
|
-
var batch = this._batches[batchId];
|
|
154
|
-
if (!batch) {
|
|
155
|
-
batch = new Batch(this, batchId);
|
|
156
|
-
this._batches[batchId] = batch;
|
|
157
|
-
}
|
|
158
|
-
return batch;
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Check the latest job status from server
|
|
163
|
-
*
|
|
164
|
-
* @method Bulk~Job#check
|
|
165
|
-
* @param {Callback.<Bulk~JobInfo>} [callback] - Callback function
|
|
166
|
-
* @returns {Promise.<Bulk~JobInfo>}
|
|
167
|
-
*/
|
|
168
|
-
Job.prototype.check = function(callback) {
|
|
169
|
-
var self = this;
|
|
170
|
-
var bulk = this._bulk;
|
|
171
|
-
var logger = bulk._logger;
|
|
172
|
-
|
|
173
|
-
this._jobInfo = this._waitAssign().then(function() {
|
|
174
|
-
return bulk._request({
|
|
175
|
-
method : 'GET',
|
|
176
|
-
path : "/job/" + self.id,
|
|
177
|
-
responseType: "application/xml"
|
|
178
|
-
});
|
|
179
|
-
}).then(function(res) {
|
|
180
|
-
logger.debug(res.jobInfo);
|
|
181
|
-
self.id = res.jobInfo.id;
|
|
182
|
-
self.type = res.jobInfo.object;
|
|
183
|
-
self.operation = res.jobInfo.operation;
|
|
184
|
-
self.state = res.jobInfo.state;
|
|
185
|
-
return res.jobInfo;
|
|
186
|
-
});
|
|
187
|
-
return this._jobInfo.thenCall(callback);
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Wait till the job is assigned to server
|
|
192
|
-
*
|
|
193
|
-
* @method Bulk~Job#info
|
|
194
|
-
* @param {Callback.<Bulk~JobInfo>} [callback] - Callback function
|
|
195
|
-
* @returns {Promise.<Bulk~JobInfo>}
|
|
196
|
-
*/
|
|
197
|
-
Job.prototype._waitAssign = function(callback) {
|
|
198
|
-
return (this.id ? Promise.resolve({ id: this.id }) : this.open()).thenCall(callback);
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* List all registered batch info in job
|
|
204
|
-
*
|
|
205
|
-
* @method Bulk~Job#list
|
|
206
|
-
* @param {Callback.<Array.<Bulk~BatchInfo>>} [callback] - Callback function
|
|
207
|
-
* @returns {Promise.<Array.<Bulk~BatchInfo>>}
|
|
208
|
-
*/
|
|
209
|
-
Job.prototype.list = function(callback) {
|
|
210
|
-
var self = this;
|
|
211
|
-
var bulk = this._bulk;
|
|
212
|
-
var logger = bulk._logger;
|
|
213
|
-
|
|
214
|
-
return this._waitAssign().then(function() {
|
|
215
|
-
return bulk._request({
|
|
216
|
-
method : 'GET',
|
|
217
|
-
path : "/job/" + self.id + "/batch",
|
|
218
|
-
responseType: "application/xml"
|
|
219
|
-
});
|
|
220
|
-
}).then(function(res) {
|
|
221
|
-
logger.debug(res.batchInfoList.batchInfo);
|
|
222
|
-
var batchInfoList = res.batchInfoList;
|
|
223
|
-
batchInfoList = _.isArray(batchInfoList.batchInfo) ? batchInfoList.batchInfo : [ batchInfoList.batchInfo ];
|
|
224
|
-
return batchInfoList;
|
|
225
|
-
}).thenCall(callback);
|
|
226
|
-
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Close opened job
|
|
231
|
-
*
|
|
232
|
-
* @method Bulk~Job#close
|
|
233
|
-
* @param {Callback.<Bulk~JobInfo>} [callback] - Callback function
|
|
234
|
-
* @returns {Promise.<Bulk~JobInfo>}
|
|
235
|
-
*/
|
|
236
|
-
Job.prototype.close = function() {
|
|
237
|
-
var self = this;
|
|
238
|
-
return this._changeState("Closed").then(function(jobInfo) {
|
|
239
|
-
self.id = null;
|
|
240
|
-
self.emit("close", jobInfo);
|
|
241
|
-
return jobInfo;
|
|
242
|
-
}, function(err) {
|
|
243
|
-
self.emit("error", err);
|
|
244
|
-
throw err;
|
|
245
|
-
});
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Set the status to abort
|
|
250
|
-
*
|
|
251
|
-
* @method Bulk~Job#abort
|
|
252
|
-
* @param {Callback.<Bulk~JobInfo>} [callback] - Callback function
|
|
253
|
-
* @returns {Promise.<Bulk~JobInfo>}
|
|
254
|
-
*/
|
|
255
|
-
Job.prototype.abort = function() {
|
|
256
|
-
var self = this;
|
|
257
|
-
return this._changeState("Aborted").then(function(jobInfo) {
|
|
258
|
-
self.id = null;
|
|
259
|
-
self.emit("abort", jobInfo);
|
|
260
|
-
return jobInfo;
|
|
261
|
-
}, function(err) {
|
|
262
|
-
self.emit("error", err);
|
|
263
|
-
throw err;
|
|
264
|
-
});
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* @private
|
|
269
|
-
*/
|
|
270
|
-
Job.prototype._changeState = function(state, callback) {
|
|
271
|
-
var self = this;
|
|
272
|
-
var bulk = this._bulk;
|
|
273
|
-
var logger = bulk._logger;
|
|
274
|
-
|
|
275
|
-
this._jobInfo = this._waitAssign().then(function() {
|
|
276
|
-
var body = [
|
|
277
|
-
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
278
|
-
'<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">',
|
|
279
|
-
'<state>' + state + '</state>',
|
|
280
|
-
'</jobInfo>'
|
|
281
|
-
].join('');
|
|
282
|
-
return bulk._request({
|
|
283
|
-
method : 'POST',
|
|
284
|
-
path : "/job/" + self.id,
|
|
285
|
-
body : body,
|
|
286
|
-
headers : {
|
|
287
|
-
"Content-Type" : "application/xml; charset=utf-8"
|
|
288
|
-
},
|
|
289
|
-
responseType: "application/xml"
|
|
290
|
-
});
|
|
291
|
-
}).then(function(res) {
|
|
292
|
-
logger.debug(res.jobInfo);
|
|
293
|
-
self.state = res.jobInfo.state;
|
|
294
|
-
return res.jobInfo;
|
|
295
|
-
});
|
|
296
|
-
return this._jobInfo.thenCall(callback);
|
|
297
|
-
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
/*--------------------------------------------*/
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Batch (extends RecordStream)
|
|
305
|
-
*
|
|
306
|
-
* @protected
|
|
307
|
-
* @class Bulk~Batch
|
|
308
|
-
* @extends {stream.Writable}
|
|
309
|
-
* @implements {Promise.<Array.<RecordResult>>}
|
|
310
|
-
* @param {Bulk~Job} job - Bulk job object
|
|
311
|
-
* @param {String} [batchId] - Batch ID (if already available)
|
|
312
|
-
*/
|
|
313
|
-
var Batch = function(job, batchId) {
|
|
314
|
-
Batch.super_.call(this, { objectMode: true });
|
|
315
|
-
this.job = job;
|
|
316
|
-
this.id = batchId;
|
|
317
|
-
this._bulk = job._bulk;
|
|
318
|
-
this._deferred = Promise.defer();
|
|
319
|
-
this._setupDataStreams();
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
inherits(Batch, stream.Writable);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* @private
|
|
327
|
-
*/
|
|
328
|
-
Batch.prototype._setupDataStreams = function() {
|
|
329
|
-
var batch = this;
|
|
330
|
-
var converterOptions = { nullValue : '#N/A' };
|
|
331
|
-
this._uploadStream = new RecordStream.Serializable();
|
|
332
|
-
this._uploadDataStream = this._uploadStream.stream('csv', converterOptions);
|
|
333
|
-
this._downloadStream = new RecordStream.Parsable();
|
|
334
|
-
this._downloadDataStream = this._downloadStream.stream('csv', converterOptions);
|
|
335
|
-
|
|
336
|
-
this.on('finish', function() {
|
|
337
|
-
batch._uploadStream.end();
|
|
338
|
-
});
|
|
339
|
-
this._uploadDataStream.once('readable', function() {
|
|
340
|
-
batch.job.open().then(function() {
|
|
341
|
-
// pipe upload data to batch API request stream
|
|
342
|
-
batch._uploadDataStream.pipe(batch._createRequestStream());
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
// duplex data stream, opened access to API programmers by Batch#stream()
|
|
347
|
-
var dataStream = this._dataStream = new Duplex();
|
|
348
|
-
dataStream._write = function(data, enc, cb) {
|
|
349
|
-
batch._uploadDataStream.write(data, enc, cb);
|
|
350
|
-
};
|
|
351
|
-
dataStream.on('finish', function() {
|
|
352
|
-
batch._uploadDataStream.end();
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
this._downloadDataStream.on('readable', function() {
|
|
356
|
-
dataStream.read(0);
|
|
357
|
-
});
|
|
358
|
-
this._downloadDataStream.on('end', function() {
|
|
359
|
-
dataStream.push(null);
|
|
360
|
-
});
|
|
361
|
-
dataStream._read = function(size) {
|
|
362
|
-
var chunk;
|
|
363
|
-
while ((chunk = batch._downloadDataStream.read()) !== null) {
|
|
364
|
-
dataStream.push(chunk);
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Connect batch API and create stream instance of request/response
|
|
371
|
-
*
|
|
372
|
-
* @private
|
|
373
|
-
* @returns {stream.Duplex}
|
|
374
|
-
*/
|
|
375
|
-
Batch.prototype._createRequestStream = function() {
|
|
376
|
-
var batch = this;
|
|
377
|
-
var bulk = batch._bulk;
|
|
378
|
-
var logger = bulk._logger;
|
|
379
|
-
|
|
380
|
-
return bulk._request({
|
|
381
|
-
method : 'POST',
|
|
382
|
-
path : "/job/" + batch.job.id + "/batch",
|
|
383
|
-
headers: {
|
|
384
|
-
"Content-Type": "text/csv"
|
|
385
|
-
},
|
|
386
|
-
responseType: "application/xml"
|
|
387
|
-
}, function(err, res) {
|
|
388
|
-
if (err) {
|
|
389
|
-
batch.emit('error', err);
|
|
390
|
-
} else {
|
|
391
|
-
logger.debug(res.batchInfo);
|
|
392
|
-
batch.id = res.batchInfo.id;
|
|
393
|
-
batch.emit('queue', res.batchInfo);
|
|
394
|
-
}
|
|
395
|
-
}).stream();
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Implementation of Writable
|
|
400
|
-
*
|
|
401
|
-
* @override
|
|
402
|
-
* @private
|
|
403
|
-
*/
|
|
404
|
-
Batch.prototype._write = function(record, enc, cb) {
|
|
405
|
-
record = _.clone(record);
|
|
406
|
-
if (this.job.operation === "insert") {
|
|
407
|
-
delete record.Id;
|
|
408
|
-
} else if (this.job.operation === "delete") {
|
|
409
|
-
record = { Id: record.Id };
|
|
410
|
-
}
|
|
411
|
-
delete record.type;
|
|
412
|
-
delete record.attributes;
|
|
413
|
-
this._uploadStream.write(record, enc, cb);
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Returns duplex stream which accepts CSV data input and batch result output
|
|
418
|
-
*
|
|
419
|
-
* @returns {stream.Duplex}
|
|
420
|
-
*/
|
|
421
|
-
Batch.prototype.stream = function() {
|
|
422
|
-
return this._dataStream;
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Execute batch operation
|
|
427
|
-
*
|
|
428
|
-
* @method Bulk~Batch#execute
|
|
429
|
-
* @param {Array.<Record>|stream.Stream|String} [input] - Input source for batch operation. Accepts array of records, CSV string, and CSV data input stream in insert/update/upsert/delete/hardDelete operation, SOQL string in query operation.
|
|
430
|
-
* @param {Callback.<Array.<RecordResult>|Array.<BatchResultInfo>>} [callback] - Callback function
|
|
431
|
-
* @returns {Bulk~Batch}
|
|
432
|
-
*/
|
|
433
|
-
Batch.prototype.run =
|
|
434
|
-
Batch.prototype.exec =
|
|
435
|
-
Batch.prototype.execute = function(input, callback) {
|
|
436
|
-
var self = this;
|
|
437
|
-
|
|
438
|
-
if (typeof input === 'function') { // if input argument is omitted
|
|
439
|
-
callback = input;
|
|
440
|
-
input = null;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// if batch is already executed
|
|
444
|
-
if (this._result) {
|
|
445
|
-
throw new Error("Batch already executed.");
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
var rdeferred = Promise.defer();
|
|
449
|
-
this._result = rdeferred.promise;
|
|
450
|
-
this._result.then(function(res) {
|
|
451
|
-
self._deferred.resolve(res);
|
|
452
|
-
}, function(err) {
|
|
453
|
-
self._deferred.reject(err);
|
|
454
|
-
});
|
|
455
|
-
this.once('response', function(res) {
|
|
456
|
-
rdeferred.resolve(res);
|
|
457
|
-
});
|
|
458
|
-
this.once('error', function(err) {
|
|
459
|
-
rdeferred.reject(err);
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
if (_.isObject(input) && _.isFunction(input.pipe)) { // if input has stream.Readable interface
|
|
463
|
-
input.pipe(this._dataStream);
|
|
464
|
-
} else {
|
|
465
|
-
var data;
|
|
466
|
-
if (_.isArray(input)) {
|
|
467
|
-
_.forEach(input, function(record) {
|
|
468
|
-
Object.keys(record).forEach(function(key) {
|
|
469
|
-
if (typeof record[key] === 'boolean') {
|
|
470
|
-
record[key] = String(record[key])
|
|
471
|
-
}
|
|
472
|
-
})
|
|
473
|
-
self.write(record);
|
|
474
|
-
});
|
|
475
|
-
self.end();
|
|
476
|
-
} else if (_.isString(input)){
|
|
477
|
-
data = input;
|
|
478
|
-
this._dataStream.write(data, 'utf8');
|
|
479
|
-
this._dataStream.end();
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// return Batch instance for chaining
|
|
484
|
-
return this.thenCall(callback);
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Promise/A+ interface
|
|
489
|
-
* http://promises-aplus.github.io/promises-spec/
|
|
490
|
-
*
|
|
491
|
-
* Delegate to deferred promise, return promise instance for batch result
|
|
492
|
-
*
|
|
493
|
-
* @method Bulk~Batch#then
|
|
494
|
-
*/
|
|
495
|
-
Batch.prototype.then = function(onResolved, onReject, onProgress) {
|
|
496
|
-
return this._deferred.promise.then(onResolved, onReject, onProgress);
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
/**
|
|
500
|
-
* Promise/A+ extension
|
|
501
|
-
* Call "then" using given node-style callback function
|
|
502
|
-
*
|
|
503
|
-
* @method Bulk~Batch#thenCall
|
|
504
|
-
*/
|
|
505
|
-
Batch.prototype.thenCall = function(callback) {
|
|
506
|
-
if (_.isFunction(callback)) {
|
|
507
|
-
this.then(function(res) {
|
|
508
|
-
process.nextTick(function() {
|
|
509
|
-
callback(null, res);
|
|
510
|
-
});
|
|
511
|
-
}, function(err) {
|
|
512
|
-
process.nextTick(function() {
|
|
513
|
-
callback(err);
|
|
514
|
-
});
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
return this;
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
/**
|
|
521
|
-
* @typedef {Object} Bulk~BatchInfo
|
|
522
|
-
* @prop {String} id - Batch ID
|
|
523
|
-
* @prop {String} jobId - Job ID
|
|
524
|
-
* @prop {String} state - Batch state
|
|
525
|
-
* @prop {String} stateMessage - Batch state message
|
|
526
|
-
*/
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* Check the latest batch status in server
|
|
530
|
-
*
|
|
531
|
-
* @method Bulk~Batch#check
|
|
532
|
-
* @param {Callback.<Bulk~BatchInfo>} [callback] - Callback function
|
|
533
|
-
* @returns {Promise.<Bulk~BatchInfo>}
|
|
534
|
-
*/
|
|
535
|
-
Batch.prototype.check = function(callback) {
|
|
536
|
-
var self = this;
|
|
537
|
-
var bulk = this._bulk;
|
|
538
|
-
var logger = bulk._logger;
|
|
539
|
-
var jobId = this.job.id;
|
|
540
|
-
var batchId = this.id;
|
|
541
|
-
|
|
542
|
-
if (!jobId || !batchId) {
|
|
543
|
-
throw new Error("Batch not started.");
|
|
544
|
-
}
|
|
545
|
-
return bulk._request({
|
|
546
|
-
method : 'GET',
|
|
547
|
-
path : "/job/" + jobId + "/batch/" + batchId,
|
|
548
|
-
responseType: "application/xml"
|
|
549
|
-
}).then(function(res) {
|
|
550
|
-
logger.debug(res.batchInfo);
|
|
551
|
-
return res.batchInfo;
|
|
552
|
-
}).thenCall(callback);
|
|
553
|
-
};
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
/**
|
|
557
|
-
* Polling the batch result and retrieve
|
|
558
|
-
*
|
|
559
|
-
* @method Bulk~Batch#poll
|
|
560
|
-
* @param {Number} interval - Polling interval in milliseconds
|
|
561
|
-
* @param {Number} timeout - Polling timeout in milliseconds
|
|
562
|
-
*/
|
|
563
|
-
Batch.prototype.poll = function(interval, timeout) {
|
|
564
|
-
var self = this;
|
|
565
|
-
var jobId = this.job.id;
|
|
566
|
-
var batchId = this.id;
|
|
567
|
-
|
|
568
|
-
if (!jobId || !batchId) {
|
|
569
|
-
throw new Error("Batch not started.");
|
|
570
|
-
}
|
|
571
|
-
var startTime = new Date().getTime();
|
|
572
|
-
var poll = function() {
|
|
573
|
-
var now = new Date().getTime();
|
|
574
|
-
if (startTime + timeout < now) {
|
|
575
|
-
var err = new Error("Polling time out. Job Id = " + jobId + " , batch Id = " + batchId);
|
|
576
|
-
err.name = 'PollingTimeout';
|
|
577
|
-
err.jobId = jobId;
|
|
578
|
-
err.batchId = batchId;
|
|
579
|
-
self.emit('error', err);
|
|
580
|
-
return;
|
|
581
|
-
}
|
|
582
|
-
self.check(function(err, res) {
|
|
583
|
-
if (err) {
|
|
584
|
-
self.emit('error', err);
|
|
585
|
-
} else {
|
|
586
|
-
if (res.state === "Failed") {
|
|
587
|
-
if (parseInt(res.numberRecordsProcessed, 10) > 0) {
|
|
588
|
-
self.retrieve();
|
|
589
|
-
} else {
|
|
590
|
-
self.emit('error', new Error(res.stateMessage));
|
|
591
|
-
}
|
|
592
|
-
} else if (res.state === "Completed") {
|
|
593
|
-
self.retrieve();
|
|
594
|
-
} else {
|
|
595
|
-
self.emit('progress', res);
|
|
596
|
-
setTimeout(poll, interval);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
});
|
|
600
|
-
};
|
|
601
|
-
setTimeout(poll, interval);
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* @typedef {Object} Bulk~BatchResultInfo
|
|
606
|
-
* @prop {String} id - Batch result ID
|
|
607
|
-
* @prop {String} batchId - Batch ID which includes this batch result.
|
|
608
|
-
* @prop {String} jobId - Job ID which includes this batch result.
|
|
609
|
-
*/
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Retrieve batch result
|
|
613
|
-
*
|
|
614
|
-
* @method Bulk~Batch#retrieve
|
|
615
|
-
* @param {Callback.<Array.<RecordResult>|Array.<Bulk~BatchResultInfo>>} [callback] - Callback function
|
|
616
|
-
* @returns {Promise.<Array.<RecordResult>|Array.<Bulk~BatchResultInfo>>}
|
|
617
|
-
*/
|
|
618
|
-
Batch.prototype.retrieve = function(callback) {
|
|
619
|
-
var self = this;
|
|
620
|
-
var bulk = this._bulk;
|
|
621
|
-
var jobId = this.job.id;
|
|
622
|
-
var job = this.job;
|
|
623
|
-
var batchId = this.id;
|
|
624
|
-
|
|
625
|
-
if (!jobId || !batchId) {
|
|
626
|
-
throw new Error("Batch not started.");
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
return job.info().then(function(jobInfo) {
|
|
630
|
-
return bulk._request({
|
|
631
|
-
method : 'GET',
|
|
632
|
-
path : "/job/" + jobId + "/batch/" + batchId + "/result"
|
|
633
|
-
});
|
|
634
|
-
}).then(function(res) {
|
|
635
|
-
var results;
|
|
636
|
-
if (job.operation === 'query') {
|
|
637
|
-
var conn = bulk._conn;
|
|
638
|
-
var resultIds = res['result-list'].result;
|
|
639
|
-
results = res['result-list'].result;
|
|
640
|
-
results = _.map(_.isArray(results) ? results : [ results ], function(id) {
|
|
641
|
-
return {
|
|
642
|
-
id: id,
|
|
643
|
-
batchId: batchId,
|
|
644
|
-
jobId: jobId
|
|
645
|
-
};
|
|
646
|
-
});
|
|
647
|
-
} else {
|
|
648
|
-
results = _.map(res, function(ret) {
|
|
649
|
-
return {
|
|
650
|
-
id: ret.Id || null,
|
|
651
|
-
success: ret.Success === "true",
|
|
652
|
-
errors: ret.Error ? [ ret.Error ] : []
|
|
653
|
-
};
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
self.emit('response', results);
|
|
657
|
-
return results;
|
|
658
|
-
}).fail(function(err) {
|
|
659
|
-
self.emit('error', err);
|
|
660
|
-
throw err;
|
|
661
|
-
}).thenCall(callback);
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
/**
|
|
665
|
-
* Fetch query result as a record stream
|
|
666
|
-
* @param {String} resultId - Result id
|
|
667
|
-
* @returns {RecordStream} - Record stream, convertible to CSV data stream
|
|
668
|
-
*/
|
|
669
|
-
Batch.prototype.result = function(resultId) {
|
|
670
|
-
var jobId = this.job.id;
|
|
671
|
-
var batchId = this.id;
|
|
672
|
-
if (!jobId || !batchId) {
|
|
673
|
-
throw new Error("Batch not started.");
|
|
674
|
-
}
|
|
675
|
-
var resultStream = new RecordStream.Parsable();
|
|
676
|
-
var resultDataStream = resultStream.stream('csv');
|
|
677
|
-
var reqStream = this._bulk._request({
|
|
678
|
-
method : 'GET',
|
|
679
|
-
path : "/job/" + jobId + "/batch/" + batchId + "/result/" + resultId,
|
|
680
|
-
responseType: "application/octet-stream"
|
|
681
|
-
}).stream().pipe(resultDataStream);
|
|
682
|
-
return resultStream;
|
|
683
|
-
};
|
|
684
|
-
|
|
685
|
-
/*--------------------------------------------*/
|
|
686
|
-
/**
|
|
687
|
-
* @private
|
|
688
|
-
*/
|
|
689
|
-
var BulkApi = function() {
|
|
690
|
-
BulkApi.super_.apply(this, arguments);
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
inherits(BulkApi, HttpApi);
|
|
694
|
-
|
|
695
|
-
BulkApi.prototype.beforeSend = function(request) {
|
|
696
|
-
request.headers = request.headers || {};
|
|
697
|
-
request.headers["X-SFDC-SESSION"] = this._conn.accessToken;
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
BulkApi.prototype.isSessionExpired = function(response) {
|
|
701
|
-
return response.statusCode === 400 &&
|
|
702
|
-
/<exceptionCode>InvalidSessionId<\/exceptionCode>/.test(response.body);
|
|
703
|
-
};
|
|
704
|
-
|
|
705
|
-
BulkApi.prototype.hasErrorInResponseBody = function(body) {
|
|
706
|
-
return !!body.error;
|
|
707
|
-
};
|
|
708
|
-
|
|
709
|
-
BulkApi.prototype.parseError = function(body) {
|
|
710
|
-
return {
|
|
711
|
-
errorCode: body.error.exceptionCode,
|
|
712
|
-
message: body.error.exceptionMessage
|
|
713
|
-
};
|
|
714
|
-
};
|
|
715
|
-
|
|
716
|
-
/*--------------------------------------------*/
|
|
717
|
-
|
|
718
|
-
/**
|
|
719
|
-
* Class for Bulk API
|
|
720
|
-
*
|
|
721
|
-
* @class
|
|
722
|
-
* @param {Connection} conn - Connection object
|
|
723
|
-
*/
|
|
724
|
-
var Bulk = function(conn) {
|
|
725
|
-
this._conn = conn;
|
|
726
|
-
this._logger = conn._logger;
|
|
727
|
-
};
|
|
728
|
-
|
|
729
|
-
/**
|
|
730
|
-
* Polling interval in milliseconds
|
|
731
|
-
* @type {Number}
|
|
732
|
-
*/
|
|
733
|
-
Bulk.prototype.pollInterval = 1000;
|
|
734
|
-
|
|
735
|
-
/**
|
|
736
|
-
* Polling timeout in milliseconds
|
|
737
|
-
* @type {Number}
|
|
738
|
-
*/
|
|
739
|
-
Bulk.prototype.pollTimeout = 10000;
|
|
740
|
-
|
|
741
|
-
/** @private **/
|
|
742
|
-
Bulk.prototype._request = function(request, callback) {
|
|
743
|
-
var conn = this._conn;
|
|
744
|
-
request = _.clone(request);
|
|
745
|
-
var baseUrl = [ conn.instanceUrl, "services/async", conn.version ].join('/');
|
|
746
|
-
request.url = baseUrl + request.path;
|
|
747
|
-
var options = { responseType: request.responseType };
|
|
748
|
-
delete request.path;
|
|
749
|
-
delete request.responseType;
|
|
750
|
-
return new BulkApi(this._conn, options).request(request).thenCall(callback);
|
|
751
|
-
};
|
|
752
|
-
|
|
753
|
-
/**
|
|
754
|
-
* Create and start bulkload job and batch
|
|
755
|
-
*
|
|
756
|
-
* @param {String} type - SObject type
|
|
757
|
-
* @param {String} operation - Bulk load operation ('insert', 'update', 'upsert', 'delete', or 'hardDelete')
|
|
758
|
-
* @param {Object} [options] - Options for bulk loading operation
|
|
759
|
-
* @param {String} [options.extIdField] - External ID field name (used when upsert operation).
|
|
760
|
-
* @param {String} [options.concurrencyMode] - 'Serial' or 'Parallel'. Defaults to Parallel.
|
|
761
|
-
* @param {Array.<Record>|stream.Stream|String} [input] - Input source for bulkload. Accepts array of records, CSV string, and CSV data input stream in insert/update/upsert/delete/hardDelete operation, SOQL string in query operation.
|
|
762
|
-
* @param {Callback.<Array.<RecordResult>|Array.<Bulk~BatchResultInfo>>} [callback] - Callback function
|
|
763
|
-
* @returns {Bulk~Batch}
|
|
764
|
-
*/
|
|
765
|
-
Bulk.prototype.load = function(type, operation, options, input, callback) {
|
|
766
|
-
var self = this;
|
|
767
|
-
if (!type || !operation) {
|
|
768
|
-
throw new Error("Insufficient arguments. At least, 'type' and 'operation' are required.");
|
|
769
|
-
}
|
|
770
|
-
if (!_.isObject(options) || options.constructor !== Object) { // when options is not plain hash object, it is omitted
|
|
771
|
-
callback = input;
|
|
772
|
-
input = options;
|
|
773
|
-
options = null;
|
|
774
|
-
}
|
|
775
|
-
var job = this.createJob(type, operation, options);
|
|
776
|
-
job.once('error', function (error) {
|
|
777
|
-
if (batch) {
|
|
778
|
-
batch.emit('error', error); // pass job error to batch
|
|
779
|
-
}
|
|
780
|
-
});
|
|
781
|
-
var batch = job.createBatch();
|
|
782
|
-
var cleanup = function() {
|
|
783
|
-
batch = null;
|
|
784
|
-
job.close();
|
|
785
|
-
};
|
|
786
|
-
var cleanupOnError = function(err) {
|
|
787
|
-
if (err.name !== 'PollingTimeout') {
|
|
788
|
-
cleanup();
|
|
789
|
-
}
|
|
790
|
-
};
|
|
791
|
-
batch.on('response', cleanup);
|
|
792
|
-
batch.on('error', cleanupOnError);
|
|
793
|
-
batch.on('queue', function() { batch.poll(self.pollInterval, self.pollTimeout); });
|
|
794
|
-
return batch.execute(input, callback);
|
|
795
|
-
};
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
* Execute bulk query and get record stream
|
|
799
|
-
*
|
|
800
|
-
* @param {String} soql - SOQL to execute in bulk job
|
|
801
|
-
* @returns {RecordStream.Parsable} - Record stream, convertible to CSV data stream
|
|
802
|
-
*/
|
|
803
|
-
Bulk.prototype.query = function(soql) {
|
|
804
|
-
var m = soql.replace(/\([\s\S]+\)/g, '').match(/FROM\s+(\w+)/i);
|
|
805
|
-
if (!m) {
|
|
806
|
-
throw new Error("No sobject type found in query, maybe caused by invalid SOQL.");
|
|
807
|
-
}
|
|
808
|
-
var type = m[1];
|
|
809
|
-
var self = this;
|
|
810
|
-
var recordStream = new RecordStream.Parsable();
|
|
811
|
-
var dataStream = recordStream.stream('csv');
|
|
812
|
-
this.load(type, "query", soql).then(function(results) {
|
|
813
|
-
var streams = results.map(function(result) {
|
|
814
|
-
return self
|
|
815
|
-
.job(result.jobId)
|
|
816
|
-
.batch(result.batchId)
|
|
817
|
-
.result(result.id)
|
|
818
|
-
.stream();
|
|
819
|
-
});
|
|
820
|
-
|
|
821
|
-
joinStreams(streams).pipe(dataStream);
|
|
822
|
-
}).fail(function(err) {
|
|
823
|
-
recordStream.emit('error', err);
|
|
824
|
-
});
|
|
825
|
-
return recordStream;
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
/**
|
|
830
|
-
* Create a new job instance
|
|
831
|
-
*
|
|
832
|
-
* @param {String} type - SObject type
|
|
833
|
-
* @param {String} operation - Bulk load operation ('insert', 'update', 'upsert', 'delete', 'hardDelete', or 'query')
|
|
834
|
-
* @param {Object} [options] - Options for bulk loading operation
|
|
835
|
-
* @returns {Bulk~Job}
|
|
836
|
-
*/
|
|
837
|
-
Bulk.prototype.createJob = function(type, operation, options) {
|
|
838
|
-
return new Job(this, type, operation, options);
|
|
839
|
-
};
|
|
840
|
-
|
|
841
|
-
/**
|
|
842
|
-
* Get a job instance specified by given job ID
|
|
843
|
-
*
|
|
844
|
-
* @param {String} jobId - Job ID
|
|
845
|
-
* @returns {Bulk~Job}
|
|
846
|
-
*/
|
|
847
|
-
Bulk.prototype.job = function(jobId) {
|
|
848
|
-
return new Job(this, null, null, null, jobId);
|
|
849
|
-
};
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
/*--------------------------------------------*/
|
|
853
|
-
/*
|
|
854
|
-
* Register hook in connection instantiation for dynamically adding this API module features
|
|
855
|
-
*/
|
|
856
|
-
jsforce.on('connection:new', function(conn) {
|
|
857
|
-
conn.bulk = new Bulk(conn);
|
|
858
|
-
});
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
module.exports = Bulk;
|
|
862
|
-
|
|
863
|
-
}).call(this,require('_process'))
|
|
864
|
-
|
|
865
|
-
},{"_process":2}],2:[function(require,module,exports){
|
|
866
|
-
// shim for using process in browser
|
|
867
|
-
var process = module.exports = {};
|
|
868
|
-
|
|
869
|
-
// cached from whatever global is present so that test runners that stub it
|
|
870
|
-
// don't break things. But we need to wrap it in a try catch in case it is
|
|
871
|
-
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
872
|
-
// function because try/catches deoptimize in certain engines.
|
|
873
|
-
|
|
874
|
-
var cachedSetTimeout;
|
|
875
|
-
var cachedClearTimeout;
|
|
876
|
-
|
|
877
|
-
function defaultSetTimout() {
|
|
878
|
-
throw new Error('setTimeout has not been defined');
|
|
879
|
-
}
|
|
880
|
-
function defaultClearTimeout () {
|
|
881
|
-
throw new Error('clearTimeout has not been defined');
|
|
882
|
-
}
|
|
883
|
-
(function () {
|
|
884
|
-
try {
|
|
885
|
-
if (typeof setTimeout === 'function') {
|
|
886
|
-
cachedSetTimeout = setTimeout;
|
|
887
|
-
} else {
|
|
888
|
-
cachedSetTimeout = defaultSetTimout;
|
|
889
|
-
}
|
|
890
|
-
} catch (e) {
|
|
891
|
-
cachedSetTimeout = defaultSetTimout;
|
|
892
|
-
}
|
|
893
|
-
try {
|
|
894
|
-
if (typeof clearTimeout === 'function') {
|
|
895
|
-
cachedClearTimeout = clearTimeout;
|
|
896
|
-
} else {
|
|
897
|
-
cachedClearTimeout = defaultClearTimeout;
|
|
898
|
-
}
|
|
899
|
-
} catch (e) {
|
|
900
|
-
cachedClearTimeout = defaultClearTimeout;
|
|
901
|
-
}
|
|
902
|
-
} ())
|
|
903
|
-
function runTimeout(fun) {
|
|
904
|
-
if (cachedSetTimeout === setTimeout) {
|
|
905
|
-
//normal enviroments in sane situations
|
|
906
|
-
return setTimeout(fun, 0);
|
|
907
|
-
}
|
|
908
|
-
// if setTimeout wasn't available but was latter defined
|
|
909
|
-
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|
910
|
-
cachedSetTimeout = setTimeout;
|
|
911
|
-
return setTimeout(fun, 0);
|
|
912
|
-
}
|
|
913
|
-
try {
|
|
914
|
-
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
915
|
-
return cachedSetTimeout(fun, 0);
|
|
916
|
-
} catch(e){
|
|
917
|
-
try {
|
|
918
|
-
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
919
|
-
return cachedSetTimeout.call(null, fun, 0);
|
|
920
|
-
} catch(e){
|
|
921
|
-
// 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
|
|
922
|
-
return cachedSetTimeout.call(this, fun, 0);
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
}
|
|
928
|
-
function runClearTimeout(marker) {
|
|
929
|
-
if (cachedClearTimeout === clearTimeout) {
|
|
930
|
-
//normal enviroments in sane situations
|
|
931
|
-
return clearTimeout(marker);
|
|
932
|
-
}
|
|
933
|
-
// if clearTimeout wasn't available but was latter defined
|
|
934
|
-
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|
935
|
-
cachedClearTimeout = clearTimeout;
|
|
936
|
-
return clearTimeout(marker);
|
|
937
|
-
}
|
|
938
|
-
try {
|
|
939
|
-
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
940
|
-
return cachedClearTimeout(marker);
|
|
941
|
-
} catch (e){
|
|
942
|
-
try {
|
|
943
|
-
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
944
|
-
return cachedClearTimeout.call(null, marker);
|
|
945
|
-
} catch (e){
|
|
946
|
-
// 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.
|
|
947
|
-
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
948
|
-
return cachedClearTimeout.call(this, marker);
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
955
|
-
var queue = [];
|
|
956
|
-
var draining = false;
|
|
957
|
-
var currentQueue;
|
|
958
|
-
var queueIndex = -1;
|
|
959
|
-
|
|
960
|
-
function cleanUpNextTick() {
|
|
961
|
-
if (!draining || !currentQueue) {
|
|
962
|
-
return;
|
|
963
|
-
}
|
|
964
|
-
draining = false;
|
|
965
|
-
if (currentQueue.length) {
|
|
966
|
-
queue = currentQueue.concat(queue);
|
|
967
|
-
} else {
|
|
968
|
-
queueIndex = -1;
|
|
969
|
-
}
|
|
970
|
-
if (queue.length) {
|
|
971
|
-
drainQueue();
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
function drainQueue() {
|
|
976
|
-
if (draining) {
|
|
977
|
-
return;
|
|
978
|
-
}
|
|
979
|
-
var timeout = runTimeout(cleanUpNextTick);
|
|
980
|
-
draining = true;
|
|
981
|
-
|
|
982
|
-
var len = queue.length;
|
|
983
|
-
while(len) {
|
|
984
|
-
currentQueue = queue;
|
|
985
|
-
queue = [];
|
|
986
|
-
while (++queueIndex < len) {
|
|
987
|
-
if (currentQueue) {
|
|
988
|
-
currentQueue[queueIndex].run();
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
queueIndex = -1;
|
|
992
|
-
len = queue.length;
|
|
993
|
-
}
|
|
994
|
-
currentQueue = null;
|
|
995
|
-
draining = false;
|
|
996
|
-
runClearTimeout(timeout);
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
process.nextTick = function (fun) {
|
|
1000
|
-
var args = new Array(arguments.length - 1);
|
|
1001
|
-
if (arguments.length > 1) {
|
|
1002
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
1003
|
-
args[i - 1] = arguments[i];
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
queue.push(new Item(fun, args));
|
|
1007
|
-
if (queue.length === 1 && !draining) {
|
|
1008
|
-
runTimeout(drainQueue);
|
|
1009
|
-
}
|
|
1010
|
-
};
|
|
1011
|
-
|
|
1012
|
-
// v8 likes predictible objects
|
|
1013
|
-
function Item(fun, array) {
|
|
1014
|
-
this.fun = fun;
|
|
1015
|
-
this.array = array;
|
|
1016
|
-
}
|
|
1017
|
-
Item.prototype.run = function () {
|
|
1018
|
-
this.fun.apply(null, this.array);
|
|
1019
|
-
};
|
|
1020
|
-
process.title = 'browser';
|
|
1021
|
-
process.browser = true;
|
|
1022
|
-
process.env = {};
|
|
1023
|
-
process.argv = [];
|
|
1024
|
-
process.version = ''; // empty string to avoid regexp issues
|
|
1025
|
-
process.versions = {};
|
|
1026
|
-
|
|
1027
|
-
function noop() {}
|
|
1028
|
-
|
|
1029
|
-
process.on = noop;
|
|
1030
|
-
process.addListener = noop;
|
|
1031
|
-
process.once = noop;
|
|
1032
|
-
process.off = noop;
|
|
1033
|
-
process.removeListener = noop;
|
|
1034
|
-
process.removeAllListeners = noop;
|
|
1035
|
-
process.emit = noop;
|
|
1036
|
-
process.prependListener = noop;
|
|
1037
|
-
process.prependOnceListener = noop;
|
|
1038
|
-
|
|
1039
|
-
process.listeners = function (name) { return [] }
|
|
1040
|
-
|
|
1041
|
-
process.binding = function (name) {
|
|
1042
|
-
throw new Error('process.binding is not supported');
|
|
1043
|
-
};
|
|
1044
|
-
|
|
1045
|
-
process.cwd = function () { return '/' };
|
|
1046
|
-
process.chdir = function (dir) {
|
|
1047
|
-
throw new Error('process.chdir is not supported');
|
|
1048
|
-
};
|
|
1049
|
-
process.umask = function() { return 0; };
|
|
1050
|
-
|
|
1051
|
-
},{}]},{},[1])(1)
|
|
1052
|
-
});
|
|
1053
|
-
|
|
1054
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvYXBpL2J1bGsuanMiLCJub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvKmdsb2JhbCBwcm9jZXNzKi9cbi8qKlxuICogQGZpbGUgTWFuYWdlcyBTYWxlc2ZvcmNlIEJ1bGsgQVBJIHJlbGF0ZWQgb3BlcmF0aW9uc1xuICogQGF1dGhvciBTaGluaWNoaSBUb21pdGEgPHNoaW5pY2hpLnRvbWl0YUBnbWFpbC5jb20+XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW5oZXJpdHMgICAgID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnaW5oZXJpdHMnKSxcbiAgICBzdHJlYW0gICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0nKSxcbiAgICBEdXBsZXggICAgICAgPSBzdHJlYW0uRHVwbGV4LFxuICAgIGV2ZW50cyAgICAgICA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2V2ZW50cycpLFxuICAgIF8gICAgICAgICAgICA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2xvZGFzaC9jb3JlJyksXG4gICAgam9pblN0cmVhbXMgID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnbXVsdGlzdHJlYW0nKSxcbiAgICBqc2ZvcmNlICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL2NvcmUnKSxcbiAgICBSZWNvcmRTdHJlYW0gPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL3JlY29yZC1zdHJlYW0nKSxcbiAgICBQcm9taXNlICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL3Byb21pc2UnKSxcbiAgICBIdHRwQXBpICAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL2h0dHAtYXBpJyk7XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vKipcbiAqIENsYXNzIGZvciBCdWxrIEFQSSBKb2JcbiAqXG4gKiBAcHJvdGVjdGVkXG4gKiBAY2xhc3MgQnVsa35Kb2JcbiAqIEBleHRlbmRzIGV2ZW50cy5FdmVudEVtaXR0ZXJcbiAqXG4gKiBAcGFyYW0ge0J1bGt9IGJ1bGsgLSBCdWxrIEFQSSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBbdHlwZV0gLSBTT2JqZWN0IHR5cGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3BlcmF0aW9uXSAtIEJ1bGsgbG9hZCBvcGVyYXRpb24gKCdpbnNlcnQnLCAndXBkYXRlJywgJ3Vwc2VydCcsICdkZWxldGUnLCBvciAnaGFyZERlbGV0ZScpXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gT3B0aW9ucyBmb3IgYnVsayBsb2FkaW5nIG9wZXJhdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmV4dElkRmllbGRdIC0gRXh0ZXJuYWwgSUQgZmllbGQgbmFtZSAodXNlZCB3aGVuIHVwc2VydCBvcGVyYXRpb24pLlxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmNvbmN1cnJlbmN5TW9kZV0gLSAnU2VyaWFsJyBvciAnUGFyYWxsZWwnLiBEZWZhdWx0cyB0byBQYXJhbGxlbC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBbam9iSWRdIC0gSm9iIElEIChpZiBhbHJlYWR5IGF2YWlsYWJsZSlcbiAqL1xudmFyIEpvYiA9IGZ1bmN0aW9uKGJ1bGssIHR5cGUsIG9wZXJhdGlvbiwgb3B0aW9ucywgam9iSWQpIHtcbiAgdGhpcy5fYnVsayA9IGJ1bGs7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uO1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLmlkID0gam9iSWQ7XG4gIHRoaXMuc3RhdGUgPSB0aGlzLmlkID8gJ09wZW4nIDogJ1Vua25vd24nO1xuICB0aGlzLl9iYXRjaGVzID0ge307XG59O1xuXG5pbmhlcml0cyhKb2IsIGV2ZW50cy5FdmVudEVtaXR0ZXIpO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEJ1bGt+Sm9iSW5mb1xuICogQHByb3Age1N0cmluZ30gaWQgLSBKb2IgSURcbiAqIEBwcm9wIHtTdHJpbmd9IG9iamVjdCAtIE9iamVjdCB0eXBlIG5hbWVcbiAqIEBwcm9wIHtTdHJpbmd9IG9wZXJhdGlvbiAtIE9wZXJhdGlvbiB0eXBlIG9mIHRoZSBqb2JcbiAqIEBwcm9wIHtTdHJpbmd9IHN0YXRlIC0gSm9iIHN0YXR1c1xuICovXG5cbi8qKlxuICogUmV0dXJuIGxhdGVzdCBqb2JJbmZvIGZyb20gY2FjaGVcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+Sm9iI2luZm9cbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuaW5mbyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgLy8gaWYgY2FjaGUgaXMgbm90IGF2YWlsYWJsZSwgY2hlY2sgdGhlIGxhdGVzdFxuICBpZiAoIXRoaXMuX2pvYkluZm8pIHtcbiAgICB0aGlzLl9qb2JJbmZvID0gdGhpcy5jaGVjaygpO1xuICB9XG4gIHJldHVybiB0aGlzLl9qb2JJbmZvLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogT3BlbiBuZXcgam9iIGFuZCBnZXQgam9iaW5mb1xuICpcbiAqIEBtZXRob2QgQnVsa35Kb2Ijb3BlblxuICogQHBhcmFtIHtDYWxsYmFjay48QnVsa35Kb2JJbmZvPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QnVsa35Kb2JJbmZvPn1cbiAqL1xuSm9iLnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgYnVsayA9IHRoaXMuX2J1bGs7XG4gIHZhciBsb2dnZXIgPSBidWxrLl9sb2dnZXI7XG5cbiAgLy8gaWYgbm90IHJlcXVlc3RlZCBvcGVuaW5nIGpvYlxuICBpZiAoIXRoaXMuX2pvYkluZm8pIHtcbiAgICB2YXIgb3BlcmF0aW9uID0gdGhpcy5vcGVyYXRpb24udG9Mb3dlckNhc2UoKTtcbiAgICBpZiAob3BlcmF0aW9uID09PSAnaGFyZGRlbGV0ZScpIHsgb3BlcmF0aW9uID0gJ2hhcmREZWxldGUnOyB9XG4gICAgdmFyIGJvZHkgPSBbXG4gICAgICAnPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+JyxcbiAgICAgICc8am9iSW5mbyAgeG1sbnM9XCJodHRwOi8vd3d3LmZvcmNlLmNvbS8yMDA5LzA2L2FzeW5jYXBpL2RhdGFsb2FkXCI+JyxcbiAgICAgICAgJzxvcGVyYXRpb24+JyArIG9wZXJhdGlvbiArICc8L29wZXJhdGlvbj4nLFxuICAgICAgICAnPG9iamVjdD4nICsgdGhpcy50eXBlICsgJzwvb2JqZWN0PicsXG4gICAgICAgICh0aGlzLm9wdGlvbnMuZXh0SWRGaWVsZCA/XG4gICAgICAgICAnPGV4dGVybmFsSWRGaWVsZE5hbWU+Jyt0aGlzLm9wdGlvbnMuZXh0SWRGaWVsZCsnPC9leHRlcm5hbElkRmllbGROYW1lPicgOlxuICAgICAgICAgJycpLFxuICAgICAgICAodGhpcy5vcHRpb25zLmNvbmN1cnJlbmN5TW9kZSA/XG4gICAgICAgICAnPGNvbmN1cnJlbmN5TW9kZT4nK3RoaXMub3B0aW9ucy5jb25jdXJyZW5jeU1vZGUrJzwvY29uY3VycmVuY3lNb2RlPicgOlxuICAgICAgICAgJycpLFxuICAgICAgICAodGhpcy5vcHRpb25zLmFzc2lnbm1lbnRSdWxlSWQgP1xuICAgICAgICAgICc8YXNzaWdubWVudFJ1bGVJZD4nICsgdGhpcy5vcHRpb25zLmFzc2lnbm1lbnRSdWxlSWQgKyAnPC9hc3NpZ25tZW50UnVsZUlkPicgOlxuICAgICAgICAgICcnKSxcbiAgICAgICAgJzxjb250ZW50VHlwZT5DU1Y8L2NvbnRlbnRUeXBlPicsXG4gICAgICAnPC9qb2JJbmZvPidcbiAgICBdLmpvaW4oJycpO1xuXG4gICAgdGhpcy5fam9iSW5mbyA9IGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ1BPU1QnLFxuICAgICAgcGF0aCA6IFwiL2pvYlwiLFxuICAgICAgYm9keSA6IGJvZHksXG4gICAgICBoZWFkZXJzIDoge1xuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiIDogXCJhcHBsaWNhdGlvbi94bWw7IGNoYXJzZXQ9dXRmLThcIlxuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlVHlwZTogXCJhcHBsaWNhdGlvbi94bWxcIlxuICAgIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgICBzZWxmLmVtaXQoXCJvcGVuXCIsIHJlcy5qb2JJbmZvKTtcbiAgICAgIHNlbGYuaWQgPSByZXMuam9iSW5mby5pZDtcbiAgICAgIHNlbGYuc3RhdGUgPSByZXMuam9iSW5mby5zdGF0ZTtcbiAgICAgIHJldHVybiByZXMuam9iSW5mbztcbiAgICB9LCBmdW5jdGlvbihlcnIpIHtcbiAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVycik7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2pvYkluZm8udGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgYmF0Y2ggaW5zdGFuY2UgaW4gdGhlIGpvYlxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjY3JlYXRlQmF0Y2hcbiAqIEByZXR1cm5zIHtCdWxrfkJhdGNofVxuICovXG5Kb2IucHJvdG90eXBlLmNyZWF0ZUJhdGNoID0gZnVuY3Rpb24oKSB7XG4gIHZhciBiYXRjaCA9IG5ldyBCYXRjaCh0aGlzKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBiYXRjaC5vbigncXVldWUnLCBmdW5jdGlvbigpIHtcbiAgICBzZWxmLl9iYXRjaGVzW2JhdGNoLmlkXSA9IGJhdGNoO1xuICB9KTtcbiAgcmV0dXJuIGJhdGNoO1xufTtcblxuLyoqXG4gKiBHZXQgYSBiYXRjaCBpbnN0YW5jZSBzcGVjaWZpZWQgYnkgZ2l2ZW4gYmF0Y2ggSURcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+Sm9iI2JhdGNoXG4gKiBAcGFyYW0ge1N0cmluZ30gYmF0Y2hJZCAtIEJhdGNoIElEXG4gKiBAcmV0dXJucyB7QnVsa35CYXRjaH1cbiAqL1xuSm9iLnByb3RvdHlwZS5iYXRjaCA9IGZ1bmN0aW9uKGJhdGNoSWQpIHtcbiAgdmFyIGJhdGNoID0gdGhpcy5fYmF0Y2hlc1tiYXRjaElkXTtcbiAgaWYgKCFiYXRjaCkge1xuICAgIGJhdGNoID0gbmV3IEJhdGNoKHRoaXMsIGJhdGNoSWQpO1xuICAgIHRoaXMuX2JhdGNoZXNbYmF0Y2hJZF0gPSBiYXRjaDtcbiAgfVxuICByZXR1cm4gYmF0Y2g7XG59O1xuXG4vKipcbiAqIENoZWNrIHRoZSBsYXRlc3Qgam9iIHN0YXR1cyBmcm9tIHNlcnZlclxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjY2hlY2tcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBidWxrID0gdGhpcy5fYnVsaztcbiAgdmFyIGxvZ2dlciA9IGJ1bGsuX2xvZ2dlcjtcblxuICB0aGlzLl9qb2JJbmZvID0gdGhpcy5fd2FpdEFzc2lnbigpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ0dFVCcsXG4gICAgICBwYXRoIDogXCIvam9iL1wiICsgc2VsZi5pZCxcbiAgICAgIHJlc3BvbnNlVHlwZTogXCJhcHBsaWNhdGlvbi94bWxcIlxuICAgIH0pO1xuICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgIGxvZ2dlci5kZWJ1ZyhyZXMuam9iSW5mbyk7XG4gICAgc2VsZi5pZCA9IHJlcy5qb2JJbmZvLmlkO1xuICAgIHNlbGYudHlwZSA9IHJlcy5qb2JJbmZvLm9iamVjdDtcbiAgICBzZWxmLm9wZXJhdGlvbiA9IHJlcy5qb2JJbmZvLm9wZXJhdGlvbjtcbiAgICBzZWxmLnN0YXRlID0gcmVzLmpvYkluZm8uc3RhdGU7XG4gICAgcmV0dXJuIHJlcy5qb2JJbmZvO1xuICB9KTtcbiAgcmV0dXJuIHRoaXMuX2pvYkluZm8udGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBXYWl0IHRpbGwgdGhlIGpvYiBpcyBhc3NpZ25lZCB0byBzZXJ2ZXJcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+Sm9iI2luZm9cbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuX3dhaXRBc3NpZ24gPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICByZXR1cm4gKHRoaXMuaWQgPyBQcm9taXNlLnJlc29sdmUoeyBpZDogdGhpcy5pZCB9KSA6IHRoaXMub3BlbigpKS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG5cbi8qKlxuICogTGlzdCBhbGwgcmVnaXN0ZXJlZCBiYXRjaCBpbmZvIGluIGpvYlxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjbGlzdFxuICogQHBhcmFtIHtDYWxsYmFjay48QXJyYXkuPEJ1bGt+QmF0Y2hJbmZvPj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEFycmF5LjxCdWxrfkJhdGNoSW5mbz4+fVxuICovXG5Kb2IucHJvdG90eXBlLmxpc3QgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBidWxrID0gdGhpcy5fYnVsaztcbiAgdmFyIGxvZ2dlciA9IGJ1bGsuX2xvZ2dlcjtcblxuICByZXR1cm4gdGhpcy5fd2FpdEFzc2lnbigpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ0dFVCcsXG4gICAgICBwYXRoIDogXCIvam9iL1wiICsgc2VsZi5pZCArIFwiL2JhdGNoXCIsXG4gICAgICByZXNwb25zZVR5cGU6IFwiYXBwbGljYXRpb24veG1sXCJcbiAgICB9KTtcbiAgfSkudGhlbihmdW5jdGlvbihyZXMpIHtcbiAgICBsb2dnZXIuZGVidWcocmVzLmJhdGNoSW5mb0xpc3QuYmF0Y2hJbmZvKTtcbiAgICB2YXIgYmF0Y2hJbmZvTGlzdCA9IHJlcy5iYXRjaEluZm9MaXN0O1xuICAgIGJhdGNoSW5mb0xpc3QgPSBfLmlzQXJyYXkoYmF0Y2hJbmZvTGlzdC5iYXRjaEluZm8pID8gYmF0Y2hJbmZvTGlzdC5iYXRjaEluZm8gOiBbIGJhdGNoSW5mb0xpc3QuYmF0Y2hJbmZvIF07XG4gICAgcmV0dXJuIGJhdGNoSW5mb0xpc3Q7XG4gIH0pLnRoZW5DYWxsKGNhbGxiYWNrKTtcblxufTtcblxuLyoqXG4gKiBDbG9zZSBvcGVuZWQgam9iXG4gKlxuICogQG1ldGhvZCBCdWxrfkpvYiNjbG9zZVxuICogQHBhcmFtIHtDYWxsYmFjay48QnVsa35Kb2JJbmZvPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QnVsa35Kb2JJbmZvPn1cbiAqL1xuSm9iLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHJldHVybiB0aGlzLl9jaGFuZ2VTdGF0ZShcIkNsb3NlZFwiKS50aGVuKGZ1bmN0aW9uKGpvYkluZm8pIHtcbiAgICBzZWxmLmlkID0gbnVsbDtcbiAgICBzZWxmLmVtaXQoXCJjbG9zZVwiLCBqb2JJbmZvKTtcbiAgICByZXR1cm4gam9iSW5mbztcbiAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyKTtcbiAgICB0aHJvdyBlcnI7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIHN0YXR1cyB0byBhYm9ydFxuICpcbiAqIEBtZXRob2QgQnVsa35Kb2IjYWJvcnRcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+Sm9iSW5mbz59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPEJ1bGt+Sm9iSW5mbz59XG4gKi9cbkpvYi5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICByZXR1cm4gdGhpcy5fY2hhbmdlU3RhdGUoXCJBYm9ydGVkXCIpLnRoZW4oZnVuY3Rpb24oam9iSW5mbykge1xuICAgIHNlbGYuaWQgPSBudWxsO1xuICAgIHNlbGYuZW1pdChcImFib3J0XCIsIGpvYkluZm8pO1xuICAgIHJldHVybiBqb2JJbmZvO1xuICB9LCBmdW5jdGlvbihlcnIpIHtcbiAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIpO1xuICAgIHRocm93IGVycjtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbkpvYi5wcm90b3R5cGUuX2NoYW5nZVN0YXRlID0gZnVuY3Rpb24oc3RhdGUsIGNhbGxiYWNrKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGJ1bGsgPSB0aGlzLl9idWxrO1xuICB2YXIgbG9nZ2VyID0gYnVsay5fbG9nZ2VyO1xuXG4gIHRoaXMuX2pvYkluZm8gPSB0aGlzLl93YWl0QXNzaWduKCkudGhlbihmdW5jdGlvbigpIHtcbiAgICB2YXIgYm9keSA9IFtcbiAgICAgICc8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiPz4nLFxuICAgICAgJzxqb2JJbmZvIHhtbG5zPVwiaHR0cDovL3d3dy5mb3JjZS5jb20vMjAwOS8wNi9hc3luY2FwaS9kYXRhbG9hZFwiPicsXG4gICAgICAgICc8c3RhdGU+JyArIHN0YXRlICsgJzwvc3RhdGU+JyxcbiAgICAgICc8L2pvYkluZm8+J1xuICAgIF0uam9pbignJyk7XG4gICAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ1BPU1QnLFxuICAgICAgcGF0aCA6IFwiL2pvYi9cIiArIHNlbGYuaWQsXG4gICAgICBib2R5IDogYm9keSxcbiAgICAgIGhlYWRlcnMgOiB7XG4gICAgICAgIFwiQ29udGVudC1UeXBlXCIgOiBcImFwcGxpY2F0aW9uL3htbDsgY2hhcnNldD11dGYtOFwiXG4gICAgICB9LFxuICAgICAgcmVzcG9uc2VUeXBlOiBcImFwcGxpY2F0aW9uL3htbFwiXG4gICAgfSk7XG4gIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgbG9nZ2VyLmRlYnVnKHJlcy5qb2JJbmZvKTtcbiAgICBzZWxmLnN0YXRlID0gcmVzLmpvYkluZm8uc3RhdGU7XG4gICAgcmV0dXJuIHJlcy5qb2JJbmZvO1xuICB9KTtcbiAgcmV0dXJuIHRoaXMuX2pvYkluZm8udGhlbkNhbGwoY2FsbGJhY2spO1xuXG59O1xuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vKipcbiAqIEJhdGNoIChleHRlbmRzIFJlY29yZFN0cmVhbSlcbiAqXG4gKiBAcHJvdGVjdGVkXG4gKiBAY2xhc3MgQnVsa35CYXRjaFxuICogQGV4dGVuZHMge3N0cmVhbS5Xcml0YWJsZX1cbiAqIEBpbXBsZW1lbnRzIHtQcm9taXNlLjxBcnJheS48UmVjb3JkUmVzdWx0Pj59XG4gKiBAcGFyYW0ge0J1bGt+Sm9ifSBqb2IgLSBCdWxrIGpvYiBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBbYmF0Y2hJZF0gLSBCYXRjaCBJRCAoaWYgYWxyZWFkeSBhdmFpbGFibGUpXG4gKi9cbnZhciBCYXRjaCA9IGZ1bmN0aW9uKGpvYiwgYmF0Y2hJZCkge1xuICBCYXRjaC5zdXBlcl8uY2FsbCh0aGlzLCB7IG9iamVjdE1vZGU6IHRydWUgfSk7XG4gIHRoaXMuam9iID0gam9iO1xuICB0aGlzLmlkID0gYmF0Y2hJZDtcbiAgdGhpcy5fYnVsayA9IGpvYi5fYnVsaztcbiAgdGhpcy5fZGVmZXJyZWQgPSBQcm9taXNlLmRlZmVyKCk7XG4gIHRoaXMuX3NldHVwRGF0YVN0cmVhbXMoKTtcbn07XG5cbmluaGVyaXRzKEJhdGNoLCBzdHJlYW0uV3JpdGFibGUpO1xuXG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuQmF0Y2gucHJvdG90eXBlLl9zZXR1cERhdGFTdHJlYW1zID0gZnVuY3Rpb24oKSB7XG4gIHZhciBiYXRjaCA9IHRoaXM7XG4gIHZhciBjb252ZXJ0ZXJPcHRpb25zID0geyBudWxsVmFsdWUgOiAnI04vQScgfTtcbiAgdGhpcy5fdXBsb2FkU3RyZWFtID0gbmV3IFJlY29yZFN0cmVhbS5TZXJpYWxpemFibGUoKTtcbiAgdGhpcy5fdXBsb2FkRGF0YVN0cmVhbSA9IHRoaXMuX3VwbG9hZFN0cmVhbS5zdHJlYW0oJ2NzdicsIGNvbnZlcnRlck9wdGlvbnMpO1xuICB0aGlzLl9kb3dubG9hZFN0cmVhbSA9IG5ldyBSZWNvcmRTdHJlYW0uUGFyc2FibGUoKTtcbiAgdGhpcy5fZG93bmxvYWREYXRhU3RyZWFtID0gdGhpcy5fZG93bmxvYWRTdHJlYW0uc3RyZWFtKCdjc3YnLCBjb252ZXJ0ZXJPcHRpb25zKTtcblxuICB0aGlzLm9uKCdmaW5pc2gnLCBmdW5jdGlvbigpIHtcbiAgICBiYXRjaC5fdXBsb2FkU3RyZWFtLmVuZCgpO1xuICB9KTtcbiAgdGhpcy5fdXBsb2FkRGF0YVN0cmVhbS5vbmNlKCdyZWFkYWJsZScsIGZ1bmN0aW9uKCkge1xuICAgIGJhdGNoLmpvYi5vcGVuKCkudGhlbihmdW5jdGlvbigpIHtcbiAgICAgIC8vIHBpcGUgdXBsb2FkIGRhdGEgdG8gYmF0Y2ggQVBJIHJlcXVlc3Qgc3RyZWFtXG4gICAgICBiYXRjaC5fdXBsb2FkRGF0YVN0cmVhbS5waXBlKGJhdGNoLl9jcmVhdGVSZXF1ZXN0U3RyZWFtKCkpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBkdXBsZXggZGF0YSBzdHJlYW0sIG9wZW5lZCBhY2Nlc3MgdG8gQVBJIHByb2dyYW1tZXJzIGJ5IEJhdGNoI3N0cmVhbSgpXG4gIHZhciBkYXRhU3RyZWFtID0gdGhpcy5fZGF0YVN0cmVhbSA9IG5ldyBEdXBsZXgoKTtcbiAgZGF0YVN0cmVhbS5fd3JpdGUgPSBmdW5jdGlvbihkYXRhLCBlbmMsIGNiKSB7XG4gICAgYmF0Y2guX3VwbG9hZERhdGFTdHJlYW0ud3JpdGUoZGF0YSwgZW5jLCBjYik7XG4gIH07XG4gIGRhdGFTdHJlYW0ub24oJ2ZpbmlzaCcsIGZ1bmN0aW9uKCkge1xuICAgIGJhdGNoLl91cGxvYWREYXRhU3RyZWFtLmVuZCgpO1xuICB9KTtcblxuICB0aGlzLl9kb3dubG9hZERhdGFTdHJlYW0ub24oJ3JlYWRhYmxlJywgZnVuY3Rpb24oKSB7XG4gICAgZGF0YVN0cmVhbS5yZWFkKDApO1xuICB9KTtcbiAgdGhpcy5fZG93bmxvYWREYXRhU3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbigpIHtcbiAgICBkYXRhU3RyZWFtLnB1c2gobnVsbCk7XG4gIH0pO1xuICBkYXRhU3RyZWFtLl9yZWFkID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgIHZhciBjaHVuaztcbiAgICB3aGlsZSAoKGNodW5rID0gYmF0Y2guX2Rvd25sb2FkRGF0YVN0cmVhbS5yZWFkKCkpICE9PSBudWxsKSB7XG4gICAgICBkYXRhU3RyZWFtLnB1c2goY2h1bmspO1xuICAgIH1cbiAgfTtcbn07XG5cbi8qKlxuICogQ29ubmVjdCBiYXRjaCBBUEkgYW5kIGNyZWF0ZSBzdHJlYW0gaW5zdGFuY2Ugb2YgcmVxdWVzdC9yZXNwb25zZVxuICpcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJucyB7c3RyZWFtLkR1cGxleH1cbiAqL1xuQmF0Y2gucHJvdG90eXBlLl9jcmVhdGVSZXF1ZXN0U3RyZWFtID0gZnVuY3Rpb24oKSB7XG4gIHZhciBiYXRjaCA9IHRoaXM7XG4gIHZhciBidWxrID0gYmF0Y2guX2J1bGs7XG4gIHZhciBsb2dnZXIgPSBidWxrLl9sb2dnZXI7XG5cbiAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICBwYXRoIDogXCIvam9iL1wiICsgYmF0Y2guam9iLmlkICsgXCIvYmF0Y2hcIixcbiAgICBoZWFkZXJzOiB7XG4gICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcInRleHQvY3N2XCJcbiAgICB9LFxuICAgIHJlc3BvbnNlVHlwZTogXCJhcHBsaWNhdGlvbi94bWxcIlxuICB9LCBmdW5jdGlvbihlcnIsIHJlcykge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGJhdGNoLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nZ2VyLmRlYnVnKHJlcy5iYXRjaEluZm8pO1xuICAgICAgYmF0Y2guaWQgPSByZXMuYmF0Y2hJbmZvLmlkO1xuICAgICAgYmF0Y2guZW1pdCgncXVldWUnLCByZXMuYmF0Y2hJbmZvKTtcbiAgICB9XG4gIH0pLnN0cmVhbSgpO1xufTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBXcml0YWJsZVxuICpcbiAqIEBvdmVycmlkZVxuICogQHByaXZhdGVcbiAqL1xuQmF0Y2gucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uKHJlY29yZCwgZW5jLCBjYikge1xuICByZWNvcmQgPSBfLmNsb25lKHJlY29yZCk7XG4gIGlmICh0aGlzLmpvYi5vcGVyYXRpb24gPT09IFwiaW5zZXJ0XCIpIHtcbiAgICBkZWxldGUgcmVjb3JkLklkO1xuICB9IGVsc2UgaWYgKHRoaXMuam9iLm9wZXJhdGlvbiA9PT0gXCJkZWxldGVcIikge1xuICAgIHJlY29yZCA9IHsgSWQ6IHJlY29yZC5JZCB9O1xuICB9XG4gIGRlbGV0ZSByZWNvcmQudHlwZTtcbiAgZGVsZXRlIHJlY29yZC5hdHRyaWJ1dGVzO1xuICB0aGlzLl91cGxvYWRTdHJlYW0ud3JpdGUocmVjb3JkLCBlbmMsIGNiKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBkdXBsZXggc3RyZWFtIHdoaWNoIGFjY2VwdHMgQ1NWIGRhdGEgaW5wdXQgYW5kIGJhdGNoIHJlc3VsdCBvdXRwdXRcbiAqXG4gKiBAcmV0dXJucyB7c3RyZWFtLkR1cGxleH1cbiAqL1xuQmF0Y2gucHJvdG90eXBlLnN0cmVhbSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fZGF0YVN0cmVhbTtcbn07XG5cbi8qKlxuICogRXhlY3V0ZSBiYXRjaCBvcGVyYXRpb25cbiAqXG4gKiBAbWV0aG9kIEJ1bGt+QmF0Y2gjZXhlY3V0ZVxuICogQHBhcmFtIHtBcnJheS48UmVjb3JkPnxzdHJlYW0uU3RyZWFtfFN0cmluZ30gW2lucHV0XSAtIElucHV0IHNvdXJjZSBmb3IgYmF0Y2ggb3BlcmF0aW9uLiBBY2NlcHRzIGFycmF5IG9mIHJlY29yZHMsIENTViBzdHJpbmcsIGFuZCBDU1YgZGF0YSBpbnB1dCBzdHJlYW0gaW4gaW5zZXJ0L3VwZGF0ZS91cHNlcnQvZGVsZXRlL2hhcmREZWxldGUgb3BlcmF0aW9uLCBTT1FMIHN0cmluZyBpbiBxdWVyeSBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxBcnJheS48UmVjb3JkUmVzdWx0PnxBcnJheS48QmF0Y2hSZXN1bHRJbmZvPj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge0J1bGt+QmF0Y2h9XG4gKi9cbkJhdGNoLnByb3RvdHlwZS5ydW4gPVxuQmF0Y2gucHJvdG90eXBlLmV4ZWMgPVxuQmF0Y2gucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihpbnB1dCwgY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmICh0eXBlb2YgaW5wdXQgPT09ICdmdW5jdGlvbicpIHsgLy8gaWYgaW5wdXQgYXJndW1lbnQgaXMgb21pdHRlZFxuICAgIGNhbGxiYWNrID0gaW5wdXQ7XG4gICAgaW5wdXQgPSBudWxsO1xuICB9XG5cbiAgLy8gaWYgYmF0Y2ggaXMgYWxyZWFkeSBleGVjdXRlZFxuICBpZiAodGhpcy5fcmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQmF0Y2ggYWxyZWFkeSBleGVjdXRlZC5cIik7XG4gIH1cblxuICB2YXIgcmRlZmVycmVkID0gUHJvbWlzZS5kZWZlcigpO1xuICB0aGlzLl9yZXN1bHQgPSByZGVmZXJyZWQucHJvbWlzZTtcbiAgdGhpcy5fcmVzdWx0LnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgc2VsZi5fZGVmZXJyZWQucmVzb2x2ZShyZXMpO1xuICB9LCBmdW5jdGlvbihlcnIpIHtcbiAgICBzZWxmLl9kZWZlcnJlZC5yZWplY3QoZXJyKTtcbiAgfSk7XG4gIHRoaXMub25jZSgncmVzcG9uc2UnLCBmdW5jdGlvbihyZXMpIHtcbiAgICByZGVmZXJyZWQucmVzb2x2ZShyZXMpO1xuICB9KTtcbiAgdGhpcy5vbmNlKCdlcnJvcicsIGZ1bmN0aW9uKGVycikge1xuICAgIHJkZWZlcnJlZC5yZWplY3QoZXJyKTtcbiAgfSk7XG5cbiAgaWYgKF8uaXNPYmplY3QoaW5wdXQpICYmIF8uaXNGdW5jdGlvbihpbnB1dC5waXBlKSkgeyAvLyBpZiBpbnB1dCBoYXMgc3RyZWFtLlJlYWRhYmxlIGludGVyZmFjZVxuICAgIGlucHV0LnBpcGUodGhpcy5fZGF0YVN0cmVhbSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGRhdGE7XG4gICAgaWYgKF8uaXNBcnJheShpbnB1dCkpIHtcbiAgICAgIF8uZm9yRWFjaChpbnB1dCwgZnVuY3Rpb24ocmVjb3JkKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHJlY29yZCkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHJlY29yZFtrZXldID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHJlY29yZFtrZXldID0gU3RyaW5nKHJlY29yZFtrZXldKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgc2VsZi53cml0ZShyZWNvcmQpO1xuICAgICAgfSk7XG4gICAgICBzZWxmLmVuZCgpO1xuICAgIH0gZWxzZSBpZiAoXy5pc1N0cmluZyhpbnB1dCkpe1xuICAgICAgZGF0YSA9IGlucHV0O1xuICAgICAgdGhpcy5fZGF0YVN0cmVhbS53cml0ZShkYXRhLCAndXRmOCcpO1xuICAgICAgdGhpcy5fZGF0YVN0cmVhbS5lbmQoKTtcbiAgICB9XG4gIH1cblxuICAvLyByZXR1cm4gQmF0Y2ggaW5zdGFuY2UgZm9yIGNoYWluaW5nXG4gIHJldHVybiB0aGlzLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogUHJvbWlzZS9BKyBpbnRlcmZhY2VcbiAqIGh0dHA6Ly9wcm9taXNlcy1hcGx1cy5naXRodWIuaW8vcHJvbWlzZXMtc3BlYy9cbiAqXG4gKiBEZWxlZ2F0ZSB0byBkZWZlcnJlZCBwcm9taXNlLCByZXR1cm4gcHJvbWlzZSBpbnN0YW5jZSBmb3IgYmF0Y2ggcmVzdWx0XG4gKlxuICogQG1ldGhvZCBCdWxrfkJhdGNoI3RoZW5cbiAqL1xuQmF0Y2gucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbihvblJlc29sdmVkLCBvblJlamVjdCwgb25Qcm9ncmVzcykge1xuICByZXR1cm4gdGhpcy5fZGVmZXJyZWQucHJvbWlzZS50aGVuKG9uUmVzb2x2ZWQsIG9uUmVqZWN0LCBvblByb2dyZXNzKTtcbn07XG5cbi8qKlxuICogUHJvbWlzZS9BKyBleHRlbnNpb25cbiAqIENhbGwgXCJ0aGVuXCIgdXNpbmcgZ2l2ZW4gbm9kZS1zdHlsZSBjYWxsYmFjayBmdW5jdGlvblxuICpcbiAqIEBtZXRob2QgQnVsa35CYXRjaCN0aGVuQ2FsbFxuICovXG5CYXRjaC5wcm90b3R5cGUudGhlbkNhbGwgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICBpZiAoXy5pc0Z1bmN0aW9uKGNhbGxiYWNrKSkge1xuICAgIHRoaXMudGhlbihmdW5jdGlvbihyZXMpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIHJlcyk7XG4gICAgICB9KTtcbiAgICB9LCBmdW5jdGlvbihlcnIpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gQnVsa35CYXRjaEluZm9cbiAqIEBwcm9wIHtTdHJpbmd9IGlkIC0gQmF0Y2ggSURcbiAqIEBwcm9wIHtTdHJpbmd9IGpvYklkIC0gSm9iIElEXG4gKiBAcHJvcCB7U3RyaW5nfSBzdGF0ZSAtIEJhdGNoIHN0YXRlXG4gKiBAcHJvcCB7U3RyaW5nfSBzdGF0ZU1lc3NhZ2UgLSBCYXRjaCBzdGF0ZSBtZXNzYWdlXG4gKi9cblxuLyoqXG4gKiBDaGVjayB0aGUgbGF0ZXN0IGJhdGNoIHN0YXR1cyBpbiBzZXJ2ZXJcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+QmF0Y2gjY2hlY2tcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEJ1bGt+QmF0Y2hJbmZvPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QnVsa35CYXRjaEluZm8+fVxuICovXG5CYXRjaC5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBidWxrID0gdGhpcy5fYnVsaztcbiAgdmFyIGxvZ2dlciA9IGJ1bGsuX2xvZ2dlcjtcbiAgdmFyIGpvYklkID0gdGhpcy5qb2IuaWQ7XG4gIHZhciBiYXRjaElkID0gdGhpcy5pZDtcblxuICBpZiAoIWpvYklkIHx8ICFiYXRjaElkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQmF0Y2ggbm90IHN0YXJ0ZWQuXCIpO1xuICB9XG4gIHJldHVybiBidWxrLl9yZXF1ZXN0KHtcbiAgICBtZXRob2QgOiAnR0VUJyxcbiAgICBwYXRoIDogXCIvam9iL1wiICsgam9iSWQgKyBcIi9iYXRjaC9cIiArIGJhdGNoSWQsXG4gICAgcmVzcG9uc2VUeXBlOiBcImFwcGxpY2F0aW9uL3htbFwiXG4gIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgbG9nZ2VyLmRlYnVnKHJlcy5iYXRjaEluZm8pO1xuICAgIHJldHVybiByZXMuYmF0Y2hJbmZvO1xuICB9KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG5cbi8qKlxuICogUG9sbGluZyB0aGUgYmF0Y2ggcmVzdWx0IGFuZCByZXRyaWV2ZVxuICpcbiAqIEBtZXRob2QgQnVsa35CYXRjaCNwb2xsXG4gKiBAcGFyYW0ge051bWJlcn0gaW50ZXJ2YWwgLSBQb2xsaW5nIGludGVydmFsIGluIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtOdW1iZXJ9IHRpbWVvdXQgLSBQb2xsaW5nIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKi9cbkJhdGNoLnByb3RvdHlwZS5wb2xsID0gZnVuY3Rpb24oaW50ZXJ2YWwsIHRpbWVvdXQpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgam9iSWQgPSB0aGlzLmpvYi5pZDtcbiAgdmFyIGJhdGNoSWQgPSB0aGlzLmlkO1xuXG4gIGlmICgham9iSWQgfHwgIWJhdGNoSWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJCYXRjaCBub3Qgc3RhcnRlZC5cIik7XG4gIH1cbiAgdmFyIHN0YXJ0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICB2YXIgcG9sbCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBpZiAoc3RhcnRUaW1lICsgdGltZW91dCA8IG5vdykge1xuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcihcIlBvbGxpbmcgdGltZSBvdXQuIEpvYiBJZCA9IFwiICsgam9iSWQgKyBcIiAsIGJhdGNoIElkID0gXCIgKyBiYXRjaElkKTtcbiAgICAgIGVyci5uYW1lID0gJ1BvbGxpbmdUaW1lb3V0JztcbiAgICAgIGVyci5qb2JJZCA9IGpvYklkO1xuICAgICAgZXJyLmJhdGNoSWQgPSBiYXRjaElkO1xuICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHNlbGYuY2hlY2soZnVuY3Rpb24oZXJyLCByZXMpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocmVzLnN0YXRlID09PSBcIkZhaWxlZFwiKSB7XG4gICAgICAgICAgaWYgKHBhcnNlSW50KHJlcy5udW1iZXJSZWNvcmRzUHJvY2Vzc2VkLCAxMCkgPiAwKSB7XG4gICAgICAgICAgICBzZWxmLnJldHJpZXZlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IocmVzLnN0YXRlTWVzc2FnZSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChyZXMuc3RhdGUgPT09IFwiQ29tcGxldGVkXCIpIHtcbiAgICAgICAgICBzZWxmLnJldHJpZXZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VsZi5lbWl0KCdwcm9ncmVzcycsIHJlcyk7XG4gICAgICAgICAgc2V0VGltZW91dChwb2xsLCBpbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbiAgc2V0VGltZW91dChwb2xsLCBpbnRlcnZhbCk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEJ1bGt+QmF0Y2hSZXN1bHRJbmZvXG4gKiBAcHJvcCB7U3RyaW5nfSBpZCAtIEJhdGNoIHJlc3VsdCBJRFxuICogQHByb3Age1N0cmluZ30gYmF0Y2hJZCAtIEJhdGNoIElEIHdoaWNoIGluY2x1ZGVzIHRoaXMgYmF0Y2ggcmVzdWx0LlxuICogQHByb3Age1N0cmluZ30gam9iSWQgLSBKb2IgSUQgd2hpY2ggaW5jbHVkZXMgdGhpcyBiYXRjaCByZXN1bHQuXG4gKi9cblxuLyoqXG4gKiBSZXRyaWV2ZSBiYXRjaCByZXN1bHRcbiAqXG4gKiBAbWV0aG9kIEJ1bGt+QmF0Y2gjcmV0cmlldmVcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEFycmF5LjxSZWNvcmRSZXN1bHQ+fEFycmF5LjxCdWxrfkJhdGNoUmVzdWx0SW5mbz4+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtQcm9taXNlLjxBcnJheS48UmVjb3JkUmVzdWx0PnxBcnJheS48QnVsa35CYXRjaFJlc3VsdEluZm8+Pn1cbiAqL1xuQmF0Y2gucHJvdG90eXBlLnJldHJpZXZlID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgYnVsayA9IHRoaXMuX2J1bGs7XG4gIHZhciBqb2JJZCA9IHRoaXMuam9iLmlkO1xuICB2YXIgam9iID0gdGhpcy5qb2I7XG4gIHZhciBiYXRjaElkID0gdGhpcy5pZDtcblxuICBpZiAoIWpvYklkIHx8ICFiYXRjaElkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQmF0Y2ggbm90IHN0YXJ0ZWQuXCIpO1xuICB9XG5cbiAgcmV0dXJuIGpvYi5pbmZvKCkudGhlbihmdW5jdGlvbihqb2JJbmZvKSB7XG4gICAgcmV0dXJuIGJ1bGsuX3JlcXVlc3Qoe1xuICAgICAgbWV0aG9kIDogJ0dFVCcsXG4gICAgICBwYXRoIDogXCIvam9iL1wiICsgam9iSWQgKyBcIi9iYXRjaC9cIiArIGJhdGNoSWQgKyBcIi9yZXN1bHRcIlxuICAgIH0pO1xuICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgIHZhciByZXN1bHRzO1xuICAgIGlmIChqb2Iub3BlcmF0aW9uID09PSAncXVlcnknKSB7XG4gICAgICB2YXIgY29ubiA9IGJ1bGsuX2Nvbm47XG4gICAgICB2YXIgcmVzdWx0SWRzID0gcmVzWydyZXN1bHQtbGlzdCddLnJlc3VsdDtcbiAgICAgIHJlc3VsdHMgPSByZXNbJ3Jlc3VsdC1saXN0J10ucmVzdWx0O1xuICAgICAgcmVzdWx0cyA9IF8ubWFwKF8uaXNBcnJheShyZXN1bHRzKSA/IHJlc3VsdHMgOiBbIHJlc3VsdHMgXSwgZnVuY3Rpb24oaWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgYmF0Y2hJZDogYmF0Y2hJZCxcbiAgICAgICAgICBqb2JJZDogam9iSWRcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHRzID0gXy5tYXAocmVzLCBmdW5jdGlvbihyZXQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpZDogcmV0LklkIHx8IG51bGwsXG4gICAgICAgICAgc3VjY2VzczogcmV0LlN1Y2Nlc3MgPT09IFwidHJ1ZVwiLFxuICAgICAgICAgIGVycm9yczogcmV0LkVycm9yID8gWyByZXQuRXJyb3IgXSA6IFtdXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG4gICAgc2VsZi5lbWl0KCdyZXNwb25zZScsIHJlc3VsdHMpO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9KS5mYWlsKGZ1bmN0aW9uKGVycikge1xuICAgIHNlbGYuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgIHRocm93IGVycjtcbiAgfSkudGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBGZXRjaCBxdWVyeSByZXN1bHQgYXMgYSByZWNvcmQgc3RyZWFtXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVzdWx0SWQgLSBSZXN1bHQgaWRcbiAqIEByZXR1cm5zIHtSZWNvcmRTdHJlYW19IC0gUmVjb3JkIHN0cmVhbSwgY29udmVydGlibGUgdG8gQ1NWIGRhdGEgc3RyZWFtXG4gKi9cbkJhdGNoLnByb3RvdHlwZS5yZXN1bHQgPSBmdW5jdGlvbihyZXN1bHRJZCkge1xuICB2YXIgam9iSWQgPSB0aGlzLmpvYi5pZDtcbiAgdmFyIGJhdGNoSWQgPSB0aGlzLmlkO1xuICBpZiAoIWpvYklkIHx8ICFiYXRjaElkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQmF0Y2ggbm90IHN0YXJ0ZWQuXCIpO1xuICB9XG4gIHZhciByZXN1bHRTdHJlYW0gPSBuZXcgUmVjb3JkU3RyZWFtLlBhcnNhYmxlKCk7XG4gIHZhciByZXN1bHREYXRhU3RyZWFtID0gcmVzdWx0U3RyZWFtLnN0cmVhbSgnY3N2Jyk7XG4gIHZhciByZXFTdHJlYW0gPSB0aGlzLl9idWxrLl9yZXF1ZXN0KHtcbiAgICBtZXRob2QgOiAnR0VUJyxcbiAgICBwYXRoIDogXCIvam9iL1wiICsgam9iSWQgKyBcIi9iYXRjaC9cIiArIGJhdGNoSWQgKyBcIi9yZXN1bHQvXCIgKyByZXN1bHRJZCxcbiAgICByZXNwb25zZVR5cGU6IFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCJcbiAgfSkuc3RyZWFtKCkucGlwZShyZXN1bHREYXRhU3RyZWFtKTtcbiAgcmV0dXJuIHJlc3VsdFN0cmVhbTtcbn07XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG52YXIgQnVsa0FwaSA9IGZ1bmN0aW9uKCkge1xuICBCdWxrQXBpLnN1cGVyXy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufTtcblxuaW5oZXJpdHMoQnVsa0FwaSwgSHR0cEFwaSk7XG5cbkJ1bGtBcGkucHJvdG90eXBlLmJlZm9yZVNlbmQgPSBmdW5jdGlvbihyZXF1ZXN0KSB7XG4gIHJlcXVlc3QuaGVhZGVycyA9IHJlcXVlc3QuaGVhZGVycyB8fCB7fTtcbiAgcmVxdWVzdC5oZWFkZXJzW1wiWC1TRkRDLVNFU1NJT05cIl0gPSB0aGlzLl9jb25uLmFjY2Vzc1Rva2VuO1xufTtcblxuQnVsa0FwaS5wcm90b3R5cGUuaXNTZXNzaW9uRXhwaXJlZCA9IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gIHJldHVybiByZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MDAgJiZcbiAgICAvPGV4Y2VwdGlvbkNvZGU+SW52YWxpZFNlc3Npb25JZDxcXC9leGNlcHRpb25Db2RlPi8udGVzdChyZXNwb25zZS5ib2R5KTtcbn07XG5cbkJ1bGtBcGkucHJvdG90eXBlLmhhc0Vycm9ySW5SZXNwb25zZUJvZHkgPSBmdW5jdGlvbihib2R5KSB7XG4gIHJldHVybiAhIWJvZHkuZXJyb3I7XG59O1xuXG5CdWxrQXBpLnByb3RvdHlwZS5wYXJzZUVycm9yID0gZnVuY3Rpb24oYm9keSkge1xuICByZXR1cm4ge1xuICAgIGVycm9yQ29kZTogYm9keS5lcnJvci5leGNlcHRpb25Db2RlLFxuICAgIG1lc3NhZ2U6IGJvZHkuZXJyb3IuZXhjZXB0aW9uTWVzc2FnZVxuICB9O1xufTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi8qKlxuICogQ2xhc3MgZm9yIEJ1bGsgQVBJXG4gKlxuICogQGNsYXNzXG4gKiBAcGFyYW0ge0Nvbm5lY3Rpb259IGNvbm4gLSBDb25uZWN0aW9uIG9iamVjdFxuICovXG52YXIgQnVsayA9IGZ1bmN0aW9uKGNvbm4pIHtcbiAgdGhpcy5fY29ubiA9IGNvbm47XG4gIHRoaXMuX2xvZ2dlciA9IGNvbm4uX2xvZ2dlcjtcbn07XG5cbi8qKlxuICogUG9sbGluZyBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHNcbiAqIEB0eXBlIHtOdW1iZXJ9XG4gKi9cbkJ1bGsucHJvdG90eXBlLnBvbGxJbnRlcnZhbCA9IDEwMDA7XG5cbi8qKlxuICogUG9sbGluZyB0aW1lb3V0IGluIG1pbGxpc2Vjb25kc1xuICogQHR5cGUge051bWJlcn1cbiAqL1xuQnVsay5wcm90b3R5cGUucG9sbFRpbWVvdXQgPSAxMDAwMDtcblxuLyoqIEBwcml2YXRlICoqL1xuQnVsay5wcm90b3R5cGUuX3JlcXVlc3QgPSBmdW5jdGlvbihyZXF1ZXN0LCBjYWxsYmFjaykge1xuICB2YXIgY29ubiA9IHRoaXMuX2Nvbm47XG4gIHJlcXVlc3QgPSBfLmNsb25lKHJlcXVlc3QpO1xuICB2YXIgYmFzZVVybCA9IFsgY29ubi5pbnN0YW5jZVVybCwgXCJzZXJ2aWNlcy9hc3luY1wiLCBjb25uLnZlcnNpb24gXS5qb2luKCcvJyk7XG4gIHJlcXVlc3QudXJsID0gYmFzZVVybCArIHJlcXVlc3QucGF0aDtcbiAgdmFyIG9wdGlvbnMgPSB7IHJlc3BvbnNlVHlwZTogcmVxdWVzdC5yZXNwb25zZVR5cGUgfTtcbiAgZGVsZXRlIHJlcXVlc3QucGF0aDtcbiAgZGVsZXRlIHJlcXVlc3QucmVzcG9uc2VUeXBlO1xuICByZXR1cm4gbmV3IEJ1bGtBcGkodGhpcy5fY29ubiwgb3B0aW9ucykucmVxdWVzdChyZXF1ZXN0KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhbmQgc3RhcnQgYnVsa2xvYWQgam9iIGFuZCBiYXRjaFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIC0gU09iamVjdCB0eXBlXG4gKiBAcGFyYW0ge1N0cmluZ30gb3BlcmF0aW9uIC0gQnVsayBsb2FkIG9wZXJhdGlvbiAoJ2luc2VydCcsICd1cGRhdGUnLCAndXBzZXJ0JywgJ2RlbGV0ZScsIG9yICdoYXJkRGVsZXRlJylcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSBPcHRpb25zIGZvciBidWxrIGxvYWRpbmcgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuZXh0SWRGaWVsZF0gLSBFeHRlcm5hbCBJRCBmaWVsZCBuYW1lICh1c2VkIHdoZW4gdXBzZXJ0IG9wZXJhdGlvbikuXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuY29uY3VycmVuY3lNb2RlXSAtICdTZXJpYWwnIG9yICdQYXJhbGxlbCcuIERlZmF1bHRzIHRvIFBhcmFsbGVsLlxuICogQHBhcmFtIHtBcnJheS48UmVjb3JkPnxzdHJlYW0uU3RyZWFtfFN0cmluZ30gW2lucHV0XSAtIElucHV0IHNvdXJjZSBmb3IgYnVsa2xvYWQuIEFjY2VwdHMgYXJyYXkgb2YgcmVjb3JkcywgQ1NWIHN0cmluZywgYW5kIENTViBkYXRhIGlucHV0IHN0cmVhbSBpbiBpbnNlcnQvdXBkYXRlL3Vwc2VydC9kZWxldGUvaGFyZERlbGV0ZSBvcGVyYXRpb24sIFNPUUwgc3RyaW5nIGluIHF1ZXJ5IG9wZXJhdGlvbi5cbiAqIEBwYXJhbSB7Q2FsbGJhY2suPEFycmF5LjxSZWNvcmRSZXN1bHQ+fEFycmF5LjxCdWxrfkJhdGNoUmVzdWx0SW5mbz4+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtCdWxrfkJhdGNofVxuICovXG5CdWxrLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24odHlwZSwgb3BlcmF0aW9uLCBvcHRpb25zLCBpbnB1dCwgY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAoIXR5cGUgfHwgIW9wZXJhdGlvbikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkluc3VmZmljaWVudCBhcmd1bWVudHMuIEF0IGxlYXN0LCAndHlwZScgYW5kICdvcGVyYXRpb24nIGFyZSByZXF1aXJlZC5cIik7XG4gIH1cbiAgaWYgKCFfLmlzT2JqZWN0KG9wdGlvbnMpIHx8IG9wdGlvbnMuY29uc3RydWN0b3IgIT09IE9iamVjdCkgeyAvLyB3aGVuIG9wdGlvbnMgaXMgbm90IHBsYWluIGhhc2ggb2JqZWN0LCBpdCBpcyBvbWl0dGVkXG4gICAgY2FsbGJhY2sgPSBpbnB1dDtcbiAgICBpbnB1dCA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cbiAgdmFyIGpvYiA9IHRoaXMuY3JlYXRlSm9iKHR5cGUsIG9wZXJhdGlvbiwgb3B0aW9ucyk7XG4gIGpvYi5vbmNlKCdlcnJvcicsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgIGlmIChiYXRjaCkge1xuICAgICAgYmF0Y2guZW1pdCgnZXJyb3InLCBlcnJvcik7IC8vIHBhc3Mgam9iIGVycm9yIHRvIGJhdGNoXG4gICAgfVxuICB9KTtcbiAgdmFyIGJhdGNoID0gam9iLmNyZWF0ZUJhdGNoKCk7XG4gIHZhciBjbGVhbnVwID0gZnVuY3Rpb24oKSB7XG4gICAgYmF0Y2ggPSBudWxsO1xuICAgIGpvYi5jbG9zZSgpO1xuICB9O1xuICB2YXIgY2xlYW51cE9uRXJyb3IgPSBmdW5jdGlvbihlcnIpIHtcbiAgICBpZiAoZXJyLm5hbWUgIT09ICdQb2xsaW5nVGltZW91dCcpIHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICB9XG4gIH07XG4gIGJhdGNoLm9uKCdyZXNwb25zZScsIGNsZWFudXApO1xuICBiYXRjaC5vbignZXJyb3InLCBjbGVhbnVwT25FcnJvcik7XG4gIGJhdGNoLm9uKCdxdWV1ZScsIGZ1bmN0aW9uKCkgeyBiYXRjaC5wb2xsKHNlbGYucG9sbEludGVydmFsLCBzZWxmLnBvbGxUaW1lb3V0KTsgfSk7XG4gIHJldHVybiBiYXRjaC5leGVjdXRlKGlucHV0LCBjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIEV4ZWN1dGUgYnVsayBxdWVyeSBhbmQgZ2V0IHJlY29yZCBzdHJlYW1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc29xbCAtIFNPUUwgdG8gZXhlY3V0ZSBpbiBidWxrIGpvYlxuICogQHJldHVybnMge1JlY29yZFN0cmVhbS5QYXJzYWJsZX0gLSBSZWNvcmQgc3RyZWFtLCBjb252ZXJ0aWJsZSB0byBDU1YgZGF0YSBzdHJlYW1cbiAqL1xuQnVsay5wcm90b3R5cGUucXVlcnkgPSBmdW5jdGlvbihzb3FsKSB7XG4gIHZhciBtID0gc29xbC5yZXBsYWNlKC9cXChbXFxzXFxTXStcXCkvZywgJycpLm1hdGNoKC9GUk9NXFxzKyhcXHcrKS9pKTtcbiAgaWYgKCFtKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gc29iamVjdCB0eXBlIGZvdW5kIGluIHF1ZXJ5LCBtYXliZSBjYXVzZWQgYnkgaW52YWxpZCBTT1FMLlwiKTtcbiAgfVxuICB2YXIgdHlwZSA9IG1bMV07XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHJlY29yZFN0cmVhbSA9IG5ldyBSZWNvcmRTdHJlYW0uUGFyc2FibGUoKTtcbiAgdmFyIGRhdGFTdHJlYW0gPSByZWNvcmRTdHJlYW0uc3RyZWFtKCdjc3YnKTtcbiAgdGhpcy5sb2FkKHR5cGUsIFwicXVlcnlcIiwgc29xbCkudGhlbihmdW5jdGlvbihyZXN1bHRzKSB7XG4gICAgdmFyIHN0cmVhbXMgPSByZXN1bHRzLm1hcChmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgIHJldHVybiBzZWxmXG4gICAgICAgIC5qb2IocmVzdWx0LmpvYklkKVxuICAgICAgICAuYmF0Y2gocmVzdWx0LmJhdGNoSWQpXG4gICAgICAgIC5yZXN1bHQocmVzdWx0LmlkKVxuICAgICAgICAuc3RyZWFtKCk7XG4gICAgfSk7XG5cbiAgICBqb2luU3RyZWFtcyhzdHJlYW1zKS5waXBlKGRhdGFTdHJlYW0pO1xuICB9KS5mYWlsKGZ1bmN0aW9uKGVycikge1xuICAgIHJlY29yZFN0cmVhbS5lbWl0KCdlcnJvcicsIGVycik7XG4gIH0pO1xuICByZXR1cm4gcmVjb3JkU3RyZWFtO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBqb2IgaW5zdGFuY2VcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFNPYmplY3QgdHlwZVxuICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdGlvbiAtIEJ1bGsgbG9hZCBvcGVyYXRpb24gKCdpbnNlcnQnLCAndXBkYXRlJywgJ3Vwc2VydCcsICdkZWxldGUnLCAnaGFyZERlbGV0ZScsIG9yICdxdWVyeScpXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gT3B0aW9ucyBmb3IgYnVsayBsb2FkaW5nIG9wZXJhdGlvblxuICogQHJldHVybnMge0J1bGt+Sm9ifVxuICovXG5CdWxrLnByb3RvdHlwZS5jcmVhdGVKb2IgPSBmdW5jdGlvbih0eXBlLCBvcGVyYXRpb24sIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBKb2IodGhpcywgdHlwZSwgb3BlcmF0aW9uLCBvcHRpb25zKTtcbn07XG5cbi8qKlxuICogR2V0IGEgam9iIGluc3RhbmNlIHNwZWNpZmllZCBieSBnaXZlbiBqb2IgSURcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gam9iSWQgLSBKb2IgSURcbiAqIEByZXR1cm5zIHtCdWxrfkpvYn1cbiAqL1xuQnVsay5wcm90b3R5cGUuam9iID0gZnVuY3Rpb24oam9iSWQpIHtcbiAgcmV0dXJuIG5ldyBKb2IodGhpcywgbnVsbCwgbnVsbCwgbnVsbCwgam9iSWQpO1xufTtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbi8qXG4gKiBSZWdpc3RlciBob29rIGluIGNvbm5lY3Rpb24gaW5zdGFudGlhdGlvbiBmb3IgZHluYW1pY2FsbHkgYWRkaW5nIHRoaXMgQVBJIG1vZHVsZSBmZWF0dXJlc1xuICovXG5qc2ZvcmNlLm9uKCdjb25uZWN0aW9uOm5ldycsIGZ1bmN0aW9uKGNvbm4pIHtcbiAgY29ubi5idWxrID0gbmV3IEJ1bGsoY29ubik7XG59KTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IEJ1bGs7XG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIl19
|