UNPKG

tedious

Version:

A TDS driver, for connecting to MS SQLServer databases.

435 lines (381 loc) • 43.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _events = require("events"); var _dataType = require("./data-type"); var _errors = require("./errors"); var _types = require("./always-encrypted/types"); /** * The callback is called when the request has completed, either successfully or with an error. * If an error occurs during execution of the statement(s), then `err` will describe the error. * * As only one request at a time may be executed on a connection, another request should not * be initiated until this callback is called. * * This callback is called before `requestCompleted` is emitted. */ /** * ```js * const { Request } = require('tedious'); * const request = new Request("select 42, 'hello world'", (err, rowCount) => { * // Request completion callback... * }); * connection.execSql(request); * ``` */ class Request extends _events.EventEmitter { /** * @private */ /** * @private */ /** * @private */ /** * The parameters as resolved by the last call to `validateParameters`. * * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * This event, describing result set columns, will be emitted before row * events are emitted. This event may be emitted multiple times when more * than one recordset is produced by the statement. * * An array like object, where the columns can be accessed either by index * or name. Columns with a name that is an integer are not accessible by name, * as it would be interpreted as an array index. */ /** * The request has been prepared and can be used in subsequent calls to execute and unprepare. */ /** * The request encountered an error and has not been prepared. */ /** * A row resulting from execution of the SQL statement. */ /** * All rows from a result set have been provided (through `row` events). * * This token is used to indicate the completion of a SQL statement. * As multiple SQL statements can be sent to the server in a single SQL batch, multiple `done` can be generated. * An `done` event is emitted for each SQL statement in the SQL batch except variable declarations. * For execution of SQL statements within stored procedures, `doneProc` and `doneInProc` events are used in place of `done`. * * If you are using [[Connection.execSql]] then SQL server may treat the multiple calls with the same query as a stored procedure. * When this occurs, the `doneProc` and `doneInProc` events may be emitted instead. You must handle both events to ensure complete coverage. */ /** * `request.on('doneInProc', function (rowCount, more, rows) { });` * * Indicates the completion status of a SQL statement within a stored procedure. All rows from a statement * in a stored procedure have been provided (through `row` events). * * This event may also occur when executing multiple calls with the same query using [[execSql]]. */ /** * Indicates the completion status of a stored procedure. This is also generated for stored procedures * executed through SQL statements.\ * This event may also occur when executing multiple calls with the same query using [[execSql]]. */ /** * A value for an output parameter (that was added to the request with [[addOutputParameter]]). * See also `Using Parameters`. */ /** * This event gives the columns by which data is ordered, if `ORDER BY` clause is executed in SQL Server. */ /** * This event gives the names of the base tables of the result set, if the query was * executed in browse mode (e.g. with a `FOR BROWSE` clause or `SET NO_BROWSETABLE ON`). */ /** * This event describes how the columns of the result set map back to the base tables * given in the `tabName` event, if the query was executed in browse mode (e.g. with a * `FOR BROWSE` clause or `SET NO_BROWSETABLE ON`). */ on(event, listener) { return super.on(event, listener); } /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ /** * @private */ emit(event, ...args) { return super.emit(event, ...args); } /** * @param sqlTextOrProcedure * The SQL statement to be executed * * @param callback * The callback to execute once the request has been fully completed. */ constructor(sqlTextOrProcedure, callback, options) { super(); this.sqlTextOrProcedure = sqlTextOrProcedure; this.parameters = []; this.parametersByName = {}; this.preparing = false; this.handle = undefined; this.canceled = false; this.paused = false; this.error = undefined; this.connection = undefined; this.timeout = undefined; this.userCallback = callback; this.statementColumnEncryptionSetting = options && options.statementColumnEncryptionSetting || _types.SQLServerStatementColumnEncryptionSetting.UseConnectionSetting; this.cryptoMetadataLoaded = false; this.callback = function (err, rowCount, rows) { // A cancellation only applies to the execution it was made for, so it // must not fail later executions of the request - including ones that // are started from the callback or event listeners below. this.canceled = false; if (this.preparing) { this.preparing = false; if (err) { this.emit('error', err); } else { this.emit('prepared'); } } else { this.userCallback(err, rowCount, rows); this.emit('requestCompleted'); } }; } /** * @param name * The parameter name. This should correspond to a parameter in the SQL, * or a parameter that a called procedure expects. The name should not start with `@`. * * @param type * One of the supported data types. * * @param value * The value that the parameter is to be given. The Javascript type of the * argument should match that documented for data types. * * A `varchar(max)`, `nvarchar(max)` or `varbinary(max)` value, or the rows * of a table-valued parameter, can also be given as an async iterable * (e.g. a `Readable`) of chunks, or of rows. The source is read while the * request is being sent, so it does not have to fit in memory, and a * request that carries one can be executed only once. * * String chunks may split UTF-16 surrogate pairs; the pairs are preserved * across chunk boundaries, including empty chunks. An unpaired surrogate * is handled by the type's encoding as it is for an in-memory value. * A `Buffer` chunk of 8 KB or more is sent by * reference, as `socket.write` would send it, so a source must not reuse * or modify a buffer it has yielded until the request has completed. * * @param options * Additional type options. Optional. */ // TODO: `type` must be a valid TDS value type addParameter(name, type, value, options) { const { output = false, length, precision, scale } = options ?? {}; const parameter = { type: type, name: name, value: value, output: output, length: length, precision: precision, scale: scale }; this.parameters.push(parameter); this.parametersByName[name] = parameter; } /** * @param name * The parameter name. This should correspond to a parameter in the SQL, * or a parameter that a called procedure expects. * * @param type * One of the supported data types. * * @param value * The value that the parameter is to be given. The Javascript type of the * argument should match that documented for data types * * @param options * Additional type options. Optional. */ addOutputParameter(name, type, value, options) { this.addParameter(name, type, value, { ...options, output: true }); } /** * @private */ makeParamsParameter(parameters) { let paramsParameter = ''; for (let i = 0, len = parameters.length; i < len; i++) { const parameter = parameters[i]; if (paramsParameter.length > 0) { paramsParameter += ', '; } paramsParameter += '@' + parameter.name + ' '; paramsParameter += parameter.type.declaration(parameter); if (parameter.output) { paramsParameter += ' OUTPUT'; } } return paramsParameter; } /** * @private */ validateParameters(collation, options) { const resolvedParameters = []; for (let i = 0, len = this.parameters.length; i < len; i++) { const parameter = this.parameters[i]; let resolved; try { resolved = (0, _dataType.resolveParameter)(parameter, collation, options); } catch (error) { throw new _errors.RequestError('Validation failed for parameter \'' + parameter.name + '\'. ' + error.message, 'EPARAM', { cause: error }); } parameter.value = resolved.data.value; resolvedParameters.push(resolved); } this.resolvedParameters = resolvedParameters; } /** * Temporarily suspends the flow of data from the database. No more `row` events will be emitted until [[resume]] is called. * If this request is already in a paused state, calling [[pause]] has no effect. */ pause() { if (this.paused) { return; } this.emit('pause'); this.paused = true; } /** * Resumes the flow of data from the database. * If this request is not in a paused state, calling [[resume]] has no effect. */ resume() { if (!this.paused) { return; } this.paused = false; this.emit('resume'); } /** * Cancels a request while waiting for a server response. */ cancel() { if (this.canceled) { return; } this.canceled = true; this.emit('cancel'); } /** * Sets a timeout for this request. * * @param timeout * The number of milliseconds before the request is considered failed, * or `0` for no timeout. When no timeout is set for the request, * the [[ConnectionOptions.requestTimeout]] of the [[Connection]] is used. */ setTimeout(timeout) { this.timeout = timeout; } } var _default = exports.default = Request; module.exports = Request; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZXZlbnRzIiwicmVxdWlyZSIsIl9kYXRhVHlwZSIsIl9lcnJvcnMiLCJfdHlwZXMiLCJSZXF1ZXN0IiwiRXZlbnRFbWl0dGVyIiwib24iLCJldmVudCIsImxpc3RlbmVyIiwiZW1pdCIsImFyZ3MiLCJjb25zdHJ1Y3RvciIsInNxbFRleHRPclByb2NlZHVyZSIsImNhbGxiYWNrIiwib3B0aW9ucyIsInBhcmFtZXRlcnMiLCJwYXJhbWV0ZXJzQnlOYW1lIiwicHJlcGFyaW5nIiwiaGFuZGxlIiwidW5kZWZpbmVkIiwiY2FuY2VsZWQiLCJwYXVzZWQiLCJlcnJvciIsImNvbm5lY3Rpb24iLCJ0aW1lb3V0IiwidXNlckNhbGxiYWNrIiwic3RhdGVtZW50Q29sdW1uRW5jcnlwdGlvblNldHRpbmciLCJTUUxTZXJ2ZXJTdGF0ZW1lbnRDb2x1bW5FbmNyeXB0aW9uU2V0dGluZyIsIlVzZUNvbm5lY3Rpb25TZXR0aW5nIiwiY3J5cHRvTWV0YWRhdGFMb2FkZWQiLCJlcnIiLCJyb3dDb3VudCIsInJvd3MiLCJhZGRQYXJhbWV0ZXIiLCJuYW1lIiwidHlwZSIsInZhbHVlIiwib3V0cHV0IiwibGVuZ3RoIiwicHJlY2lzaW9uIiwic2NhbGUiLCJwYXJhbWV0ZXIiLCJwdXNoIiwiYWRkT3V0cHV0UGFyYW1ldGVyIiwibWFrZVBhcmFtc1BhcmFtZXRlciIsInBhcmFtc1BhcmFtZXRlciIsImkiLCJsZW4iLCJkZWNsYXJhdGlvbiIsInZhbGlkYXRlUGFyYW1ldGVycyIsImNvbGxhdGlvbiIsInJlc29sdmVkUGFyYW1ldGVycyIsInJlc29sdmVkIiwicmVzb2x2ZVBhcmFtZXRlciIsIlJlcXVlc3RFcnJvciIsIm1lc3NhZ2UiLCJjYXVzZSIsImRhdGEiLCJwYXVzZSIsInJlc3VtZSIsImNhbmNlbCIsInNldFRpbWVvdXQiLCJfZGVmYXVsdCIsImV4cG9ydHMiLCJkZWZhdWx0IiwibW9kdWxlIl0sInNvdXJjZXMiOlsiLi4vc3JjL3JlcXVlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCB7IHR5cGUgUGFyYW1ldGVyLCB0eXBlIERhdGFUeXBlLCB0eXBlIFJlc29sdmVkUGFyYW1ldGVyLCByZXNvbHZlUGFyYW1ldGVyIH0gZnJvbSAnLi9kYXRhLXR5cGUnO1xuaW1wb3J0IHsgUmVxdWVzdEVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuXG5pbXBvcnQgQ29ubmVjdGlvbiwgeyB0eXBlIEludGVybmFsQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuL2Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgdHlwZSBNZXRhZGF0YSB9IGZyb20gJy4vbWV0YWRhdGEtcGFyc2VyJztcbmltcG9ydCB7IFNRTFNlcnZlclN0YXRlbWVudENvbHVtbkVuY3J5cHRpb25TZXR0aW5nIH0gZnJvbSAnLi9hbHdheXMtZW5jcnlwdGVkL3R5cGVzJztcbmltcG9ydCB7IHR5cGUgQ29sdW1uTWV0YWRhdGEgfSBmcm9tICcuL3Rva2VuL2NvbG1ldGFkYXRhLXRva2VuLXBhcnNlcic7XG5pbXBvcnQgeyB0eXBlIENvbHVtbkluZm8gfSBmcm9tICcuL3Rva2VuL3Rva2VuJztcbmltcG9ydCB7IENvbGxhdGlvbiB9IGZyb20gJy4vY29sbGF0aW9uJztcblxuLyoqXG4gKiBUaGUgY2FsbGJhY2sgaXMgY2FsbGVkIHdoZW4gdGhlIHJlcXVlc3QgaGFzIGNvbXBsZXRlZCwgZWl0aGVyIHN1Y2Nlc3NmdWxseSBvciB3aXRoIGFuIGVycm9yLlxuICogSWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBleGVjdXRpb24gb2YgdGhlIHN0YXRlbWVudChzKSwgdGhlbiBgZXJyYCB3aWxsIGRlc2NyaWJlIHRoZSBlcnJvci5cbiAqXG4gKiBBcyBvbmx5IG9uZSByZXF1ZXN0IGF0IGEgdGltZSBtYXkgYmUgZXhlY3V0ZWQgb24gYSBjb25uZWN0aW9uLCBhbm90aGVyIHJlcXVlc3Qgc2hvdWxkIG5vdFxuICogYmUgaW5pdGlhdGVkIHVudGlsIHRoaXMgY2FsbGJhY2sgaXMgY2FsbGVkLlxuICpcbiAqIFRoaXMgY2FsbGJhY2sgaXMgY2FsbGVkIGJlZm9yZSBgcmVxdWVzdENvbXBsZXRlZGAgaXMgZW1pdHRlZC5cbiAqL1xudHlwZSBDb21wbGV0aW9uQ2FsbGJhY2sgPVxuICAvKipcbiAgICogQHBhcmFtIGVycm9yXG4gICAqICAgSWYgYW4gZXJyb3Igb2NjdXJyZWQsIGFuIGVycm9yIG9iamVjdC5cbiAgICpcbiAgICogQHBhcmFtIHJvd0NvdW50XG4gICAqICAgVGhlIG51bWJlciBvZiByb3dzIGVtaXR0ZWQgYXMgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGUgU1FMIHN0YXRlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHJvd3NcbiAgICogICBSb3dzIGFzIGEgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGUgU1FMIHN0YXRlbWVudC5cbiAgICogICBXaWxsIG9ubHkgYmUgYXZhaWxhYmxlIGlmIFtbQ29ubmVjdGlvbk9wdGlvbnMucm93Q29sbGVjdGlvbk9uUmVxdWVzdENvbXBsZXRpb25dXSBpcyBgdHJ1ZWAuXG4gICAqL1xuICAvLyBUT0RPOiBGaWd1cmUgb3V0IGhvdyB0byB0eXBlIHRoZSBgcm93c2AgcGFyYW1ldGVyIGhlcmUuXG4gIChlcnJvcjogRXJyb3IgfCBudWxsIHwgdW5kZWZpbmVkLCByb3dDb3VudD86IG51bWJlciwgcm93cz86IGFueSkgPT4gdm9pZDtcblxuZXhwb3J0IGludGVyZmFjZSBQYXJhbWV0ZXJPcHRpb25zIHtcbiAgb3V0cHV0PzogYm9vbGVhbjtcbiAgbGVuZ3RoPzogbnVtYmVyO1xuICBwcmVjaXNpb24/OiBudW1iZXI7XG4gIHNjYWxlPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUmVxdWVzdE9wdGlvbnMge1xuICBzdGF0ZW1lbnRDb2x1bW5FbmNyeXB0aW9uU2V0dGluZz86IFNRTFNlcnZlclN0YXRlbWVudENvbHVtbkVuY3J5cHRpb25TZXR0aW5nO1xufVxuXG4vKipcbiAqIGBgYGpzXG4gKiBjb25zdCB7IFJlcXVlc3QgfSA9IHJlcXVpcmUoJ3RlZGlvdXMnKTtcbiAqIGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdChcInNlbGVjdCA0MiwgJ2hlbGxvIHdvcmxkJ1wiLCAoZXJyLCByb3dDb3VudCkgPT4ge1xuICogICAvLyBSZXF1ZXN0IGNvbXBsZXRpb24gY2FsbGJhY2suLi5cbiAqIH0pO1xuICogY29ubmVjdGlvbi5leGVjU3FsKHJlcXVlc3QpO1xuICogYGBgXG4gKi9cbmNsYXNzIFJlcXVlc3QgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRlY2xhcmUgc3FsVGV4dE9yUHJvY2VkdXJlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBwYXJhbWV0ZXJzOiBQYXJhbWV0ZXJbXTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHBhcmFtZXRlcnNCeU5hbWU6IHsgW2tleTogc3RyaW5nXTogUGFyYW1ldGVyIH07XG4gIC8qKlxuICAgKiBUaGUgcGFyYW1ldGVycyBhcyByZXNvbHZlZCBieSB0aGUgbGFzdCBjYWxsIHRvIGB2YWxpZGF0ZVBhcmFtZXRlcnNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSByZXNvbHZlZFBhcmFtZXRlcnM6IFJlc29sdmVkUGFyYW1ldGVyW107XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBwcmVwYXJpbmc6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBjYW5jZWxlZDogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHBhdXNlZDogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHVzZXJDYWxsYmFjazogQ29tcGxldGlvbkNhbGxiYWNrO1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRlY2xhcmUgaGFuZGxlOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBjb25uZWN0aW9uOiBDb25uZWN0aW9uIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRlY2xhcmUgdGltZW91dDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSByb3dzPzogQXJyYXk8YW55PjtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHJzdD86IEFycmF5PGFueT47XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSByb3dDb3VudD86IG51bWJlcjtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRlY2xhcmUgY2FsbGJhY2s6IENvbXBsZXRpb25DYWxsYmFjaztcblxuXG4gIGRlY2xhcmUgc2hvdWxkSG9ub3JBRT86IGJvb2xlYW47XG4gIGRlY2xhcmUgc3RhdGVtZW50Q29sdW1uRW5jcnlwdGlvblNldHRpbmc6IFNRTFNlcnZlclN0YXRlbWVudENvbHVtbkVuY3J5cHRpb25TZXR0aW5nO1xuICBkZWNsYXJlIGNyeXB0b01ldGFkYXRhTG9hZGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGlzIGV2ZW50LCBkZXNjcmliaW5nIHJlc3VsdCBzZXQgY29sdW1ucywgd2lsbCBiZSBlbWl0dGVkIGJlZm9yZSByb3dcbiAgICogZXZlbnRzIGFyZSBlbWl0dGVkLiBUaGlzIGV2ZW50IG1heSBiZSBlbWl0dGVkIG11bHRpcGxlIHRpbWVzIHdoZW4gbW9yZVxuICAgKiB0aGFuIG9uZSByZWNvcmRzZXQgaXMgcHJvZHVjZWQgYnkgdGhlIHN0YXRlbWVudC5cbiAgICpcbiAgICogQW4gYXJyYXkgbGlrZSBvYmplY3QsIHdoZXJlIHRoZSBjb2x1bW5zIGNhbiBiZSBhY2Nlc3NlZCBlaXRoZXIgYnkgaW5kZXhcbiAgICogb3IgbmFtZS4gQ29sdW1ucyB3aXRoIGEgbmFtZSB0aGF0IGlzIGFuIGludGVnZXIgYXJlIG5vdCBhY2Nlc3NpYmxlIGJ5IG5hbWUsXG4gICAqIGFzIGl0IHdvdWxkIGJlIGludGVycHJldGVkIGFzIGFuIGFycmF5IGluZGV4LlxuICAgKi9cbiAgb24oXG4gICAgZXZlbnQ6ICdjb2x1bW5NZXRhZGF0YScsXG4gICAgbGlzdGVuZXI6XG4gICAgKGNvbHVtbnM6IENvbHVtbk1ldGFkYXRhW10gfCB7IFtrZXk6IHN0cmluZ106IENvbHVtbk1ldGFkYXRhIH0pID0+IHZvaWRcbiAgKTogdGhpc1xuXG4gIC8qKlxuICAgKiBUaGUgcmVxdWVzdCBoYXMgYmVlbiBwcmVwYXJlZCBhbmQgY2FuIGJlIHVzZWQgaW4gc3Vic2VxdWVudCBjYWxscyB0byBleGVjdXRlIGFuZCB1bnByZXBhcmUuXG4gICAqL1xuICBvbihldmVudDogJ3ByZXBhcmVkJywgbGlzdGVuZXI6ICgpID0+IHZvaWQpOiB0aGlzXG5cbiAgLyoqXG4gICAqIFRoZSByZXF1ZXN0IGVuY291bnRlcmVkIGFuIGVycm9yIGFuZCBoYXMgbm90IGJlZW4gcHJlcGFyZWQuXG4gICAqL1xuICBvbihldmVudDogJ2Vycm9yJywgbGlzdGVuZXI6IChlcnI6IEVycm9yKSA9PiB2b2lkKTogdGhpc1xuXG4gIC8qKlxuICAgKiBBIHJvdyByZXN1bHRpbmcgZnJvbSBleGVjdXRpb24gb2YgdGhlIFNRTCBzdGF0ZW1lbnQuXG4gICAqL1xuICBvbihcbiAgICBldmVudDogJ3JvdycsXG4gICAgbGlzdGVuZXI6XG4gICAgICAvKipcbiAgICAgICAqIEFuIGFycmF5IG9yIG9iamVjdCAoZGVwZW5kcyBvbiBbW0Nvbm5lY3Rpb25PcHRpb25zLnVzZUNvbHVtbk5hbWVzXV0pLCB3aGVyZSB0aGUgY29sdW1ucyBjYW4gYmUgYWNjZXNzZWQgYnkgaW5kZXgvbmFtZS5cbiAgICAgICAqIEVhY2ggY29sdW1uIGhhcyB0d28gcHJvcGVydGllcywgYG1ldGFkYXRhYCBhbmQgYHZhbHVlYDpcbiAgICAgICAqXG4gICAgICAgKiAqIGBtZXRhZGF0YWBcbiAgICAgICAqXG4gICAgICAgKiAgICBUaGUgc2FtZSBkYXRhIHRoYXQgaXMgZXhwb3NlZCBpbiB0aGUgYGNvbHVtbk1ldGFkYXRhYCBldmVudC5cbiAgICAgICAqXG4gICAgICAgKiAqIGB2YWx1ZWBcbiAgICAgICAqXG4gICAgICAgKiAgICBUaGUgY29sdW1uJ3MgdmFsdWUuIEl0IHdpbGwgYmUgYG51bGxgIGZvciBhIGBOVUxMYC5cbiAgICAgICAqICAgIElmIHRoZXJlIGFyZSBtdWx0aXBsZSBjb2x1bW5zIHdpdGggdGhlIHNhbWUgbmFtZSwgdGhlbiB0aGlzIHdpbGwgYmUgYW4gYXJyYXkgb2YgdGhlIHZhbHVlcy5cbiAgICAgICAqL1xuICAgICAgKGNvbHVtbnM6IGFueSkgPT4gdm9pZFxuICApOiB0aGlzXG5cbiAgLyoqXG4gICAqIEFsbCByb3dzIGZyb20gYSByZXN1bHQgc2V0IGhhdmUgYmVlbiBwcm92aWRlZCAodGhyb3VnaCBgcm93YCBldmVudHMpLlxuICAgKlxuICAgKiBUaGlzIHRva2VuIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIGNvbXBsZXRpb24gb2YgYSBTUUwgc3RhdGVtZW50LlxuICAgKiBBcyBtdWx0aXBsZSBTUUwgc3RhdGVtZW50cyBjYW4gYmUgc2VudCB0byB0aGUgc2VydmVyIGluIGEgc2luZ2xlIFNRTCBiYXRjaCwgbXVsdGlwbGUgYGRvbmVgIGNhbiBiZSBnZW5lcmF0ZWQuXG4gICAqIEFuIGBkb25lYCBldmVudCBpcyBlbWl0dGVkIGZvciBlYWNoIFNRTCBzdGF0ZW1lbnQgaW4gdGhlIFNRTCBiYXRjaCBleGNlcHQgdmFyaWFibGUgZGVjbGFyYXRpb25zLlxuICAgKiBGb3IgZXhlY3V0aW9uIG9mIFNRTCBzdGF0ZW1lbnRzIHdpdGhpbiBzdG9yZWQgcHJvY2VkdXJlcywgYGRvbmVQcm9jYCBhbmQgYGRvbmVJblByb2NgIGV2ZW50cyBhcmUgdXNlZCBpbiBwbGFjZSBvZiBgZG9uZWAuXG4gICAqXG4gICAqIElmIHlvdSBhcmUgdXNpbmcgW1tDb25uZWN0aW9uLmV4ZWNTcWxdXSB0aGVuIFNRTCBzZXJ2ZXIgbWF5IHRyZWF0IHRoZSBtdWx0aXBsZSBjYWxscyB3aXRoIHRoZSBzYW1lIHF1ZXJ5IGFzIGEgc3RvcmVkIHByb2NlZHVyZS5cbiAgICogV2hlbiB0aGlzIG9jY3VycywgdGhlIGBkb25lUHJvY2AgYW5kIGBkb25lSW5Qcm9jYCBldmVudHMgbWF5IGJlIGVtaXR0ZWQgaW5zdGVhZC4gWW91IG11c3QgaGFuZGxlIGJvdGggZXZlbnRzIHRvIGVuc3VyZSBjb21wbGV0ZSBjb3ZlcmFnZS5cbiAgICovXG4gIG9uKFxuICAgIGV2ZW50OiAnZG9uZScsXG4gICAgbGlzdGVuZXI6XG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSByb3dDb3VudFxuICAgICAgICogICBUaGUgbnVtYmVyIG9mIHJlc3VsdCByb3dzLiBNYXkgYmUgYHVuZGVmaW5lZGAgaWYgbm90IGF2YWlsYWJsZS5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gbW9yZVxuICAgICAgICogICBJZiB0aGVyZSBhcmUgbW9yZSByZXN1bHRzIHRvIGNvbWUgKHByb2JhYmx5IGJlY2F1c2UgbXVsdGlwbGUgc3RhdGVtZW50cyBhcmUgYmVpbmcgZXhlY3V0ZWQpLCB0aGVuIGB0cnVlYC5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gcnN0XG4gICAgICAgKiAgIFJvd3MgYXMgYSByZXN1bHQgb2YgZXhlY3V0aW5nIHRoZSBTUUwgc3RhdGVtZW50LlxuICAgICAgICogICBXaWxsIG9ubHkgYmUgYXZhaWxhYmxlIGlmIENvbm5lY3Rpb24ncyBbW0Nvbm5lY3Rpb25PcHRpb25zLnJvd0NvbGxlY3Rpb25PbkRvbmVdXSBpcyBgdHJ1ZWAuXG4gICAgICAgKi9cbiAgICAgIChyb3dDb3VudDogbnVtYmVyIHwgdW5kZWZpbmVkLCBtb3JlOiBib29sZWFuLCByc3Q/OiBhbnlbXSkgPT4gdm9pZFxuICApOiB0aGlzXG5cbiAgLyoqXG4gICAqIGByZXF1ZXN0Lm9uKCdkb25lSW5Qcm9jJywgZnVuY3Rpb24gKHJvd0NvdW50LCBtb3JlLCByb3dzKSB7IH0pO2BcbiAgICpcbiAgICogSW5kaWNhdGVzIHRoZSBjb21wbGV0aW9uIHN0YXR1cyBvZiBhIFNRTCBzdGF0ZW1lbnQgd2l0aGluIGEgc3RvcmVkIHByb2NlZHVyZS4gQWxsIHJvd3MgZnJvbSBhIHN0YXRlbWVudFxuICAgKiBpbiBhIHN0b3JlZCBwcm9jZWR1cmUgaGF2ZSBiZWVuIHByb3ZpZGVkICh0aHJvdWdoIGByb3dgIGV2ZW50cykuXG4gICAqXG4gICAqIFRoaXMgZXZlbnQgbWF5IGFsc28gb2NjdXIgd2hlbiBleGVjdXRpbmcgbXVsdGlwbGUgY2FsbHMgd2l0aCB0aGUgc2FtZSBxdWVyeSB1c2luZyBbW2V4ZWNTcWxdXS5cbiAgICovXG4gIG9uKFxuICAgIGV2ZW50OiAnZG9uZUluUHJvYycsXG4gICAgbGlzdGVuZXI6XG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSByb3dDb3VudFxuICAgICAgICogICBUaGUgbnVtYmVyIG9mIHJlc3VsdCByb3dzLiBNYXkgYmUgYHVuZGVmaW5lZGAgaWYgbm90IGF2YWlsYWJsZS5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gbW9yZVxuICAgICAgICogICBJZiB0aGVyZSBhcmUgbW9yZSByZXN1bHRzIHRvIGNvbWUgKHByb2JhYmx5IGJlY2F1c2UgbXVsdGlwbGUgc3RhdGVtZW50cyBhcmUgYmVpbmcgZXhlY3V0ZWQpLCB0aGVuIGB0cnVlYC5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gcnN0XG4gICAgICAgKiAgIFJvd3MgYXMgYSByZXN1bHQgb2YgZXhlY3V0aW5nIHRoZSBTUUwgc3RhdGVtZW50LlxuICAgICAgICogICBXaWxsIG9ubHkgYmUgYXZhaWxhYmxlIGlmIENvbm5lY3Rpb24ncyBbW0Nvbm5lY3Rpb25PcHRpb25zLnJvd0NvbGxlY3Rpb25PbkRvbmVdXSBpcyBgdHJ1ZWAuXG4gICAgICAgKi9cbiAgICAgIChyb3dDb3VudDogbnVtYmVyIHwgdW5kZWZpbmVkLCBtb3JlOiBib29sZWFuLCByc3Q/OiBhbnlbXSkgPT4gdm9pZFxuICApOiB0aGlzXG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGUgY29tcGxldGlvbiBzdGF0dXMgb2YgYSBzdG9yZWQgcHJvY2VkdXJlLiBUaGlzIGlzIGFsc28gZ2VuZXJhdGVkIGZvciBzdG9yZWQgcHJvY2VkdXJlc1xuICAgKiBleGVjdXRlZCB0aHJvdWdoIFNRTCBzdGF0ZW1lbnRzLlxcXG4gICAqIFRoaXMgZXZlbnQgbWF5IGFsc28gb2NjdXIgd2hlbiBleGVjdXRpbmcgbXVsdGlwbGUgY2FsbHMgd2l0aCB0aGUgc2FtZSBxdWVyeSB1c2luZyBbW2V4ZWNTcWxdXS5cbiAgICovXG4gIG9uKFxuICAgIGV2ZW50OiAnZG9uZVByb2MnLFxuICAgIGxpc3RlbmVyOlxuICAgICAgLyoqXG4gICAgICAgKiBAcGFyYW0gcm93Q291bnRcbiAgICAgICAqICAgVGhlIG51bWJlciBvZiByZXN1bHQgcm93cy4gTWF5IGJlIGB1bmRlZmluZWRgIGlmIG5vdCBhdmFpbGFibGUuXG4gICAgICAgKlxuICAgICAgICogQHBhcmFtIG1vcmVcbiAgICAgICAqICAgSWYgdGhlcmUgYXJlIG1vcmUgcmVzdWx0cyB0byBjb21lIChwcm9iYWJseSBiZWNhdXNlIG11bHRpcGxlIHN0YXRlbWVudHMgYXJlIGJlaW5nIGV4ZWN1dGVkKSwgdGhlbiBgdHJ1ZWAuXG4gICAgICAgKlxuICAgICAgICogQHBhcmFtIHJzdFxuICAgICAgICogICBSb3dzIGFzIGEgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGUgU1FMIHN0YXRlbWVudC5cbiAgICAgICAqICAgV2lsbCBvbmx5IGJlIGF2YWlsYWJsZSBpZiBDb25uZWN0aW9uJ3MgW1tDb25uZWN0aW9uT3B0aW9ucy5yb3dDb2xsZWN0aW9uT25Eb25lXV0gaXMgYHRydWVgLlxuICAgICAgICovXG4gICAgICAocm93Q291bnQ6IG51bWJlciB8IHVuZGVmaW5lZCwgbW9yZTogYm9vbGVhbiwgcHJvY1JldHVyblN0YXR1c1ZhbHVlOiBudW1iZXIsIHJzdD86IGFueVtdKSA9PiB2b2lkXG4gICk6IHRoaXNcblxuICAvKipcbiAgICogQSB2YWx1ZSBmb3IgYW4gb3V0cHV0IHBhcmFtZXRlciAodGhhdCB3YXMgYWRkZWQgdG8gdGhlIHJlcXVlc3Qgd2l0aCBbW2FkZE91dHB1dFBhcmFtZXRlcl1dKS5cbiAgICogU2VlIGFsc28gYFVzaW5nIFBhcmFtZXRlcnNgLlxuICAgKi9cbiAgb24oXG4gICAgZXZlbnQ6ICdyZXR1cm5WYWx1ZScsXG4gICAgbGlzdGVuZXI6XG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lXG4gICAgICAgKiAgIFRoZSBwYXJhbWV0ZXIgbmFtZS4gKERvZXMgbm90IHN0YXJ0IHdpdGggJ0AnLilcbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gdmFsdWVcbiAgICAgICAqICAgVGhlIHBhcmFtZXRlcidzIG91dHB1dCB2YWx1ZS5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gbWV0YWRhdGFcbiAgICAgICAqICAgVGhlIHNhbWUgZGF0YSB0aGF0IGlzIGV4cG9zZWQgaW4gdGhlIGBjb2x1bW5NZXRhZGF0YWAgZXZlbnQuXG4gICAgICAgKi9cbiAgICAgIChwYXJhbWV0ZXJOYW1lOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duLCBtZXRhZGF0YTogTWV0YWRhdGEpID0+IHZvaWRcbiAgKTogdGhpc1xuXG4gIC8qKlxuICAgKiBUaGlzIGV2ZW50IGdpdmVzIHRoZSBjb2x1bW5zIGJ5IHdoaWNoIGRhdGEgaXMgb3JkZXJlZCwgaWYgYE9SREVSIEJZYCBjbGF1c2UgaXMgZXhlY3V0ZWQgaW4gU1FMIFNlcnZlci5cbiAgICovXG4gIG9uKFxuICAgIGV2ZW50OiAnb3JkZXInLFxuICAgIGxpc3RlbmVyOlxuICAgICAgLyoqXG4gICAgICAgKiBAcGFyYW0gb3JkZXJDb2x1bW5zXG4gICAgICAgKiAgIEFuIGFycmF5IG9mIGNvbHVtbiBudW1iZXJzIGluIHRoZSByZXN1bHQgc2V0IGJ5IHdoaWNoIGRhdGEgaXMgb3JkZXJlZC5cbiAgICAgICAqL1xuICAgICAgKG9yZGVyQ29sdW1uczogbnVtYmVyW10pID0+IHZvaWRcbiAgKTogdGhpc1xuXG4gIC8qKlxuICAgKiBUaGlzIGV2ZW50IGdpdmVzIHRoZSBuYW1lcyBvZiB0aGUgYmFzZSB0YWJsZXMgb2YgdGhlIHJlc3VsdCBzZXQsIGlmIHRoZSBxdWVyeSB3YXNcbiAgICogZXhlY3V0ZWQgaW4gYnJvd3NlIG1vZGUgKGUuZy4gd2l0aCBhIGBGT1IgQlJPV1NFYCBjbGF1c2Ugb3IgYFNFVCBOT19CUk9XU0VUQUJMRSBPTmApLlxuICAgKi9cbiAgb24oXG4gICAgZXZlbnQ6ICd0YWJOYW1lJyxcbiAgICBsaXN0ZW5lcjpcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHRhYmxlTmFtZXNcbiAgICAgICAqICAgVGhlIG5hbWVzIG9mIHRoZSBiYXNlIHRhYmxlcyByZWZlcmVuY2VkIGluIHRoZSBxdWVyeSwgaW4gdGhlIG9yZGVyIHRoZVxuICAgICAgICogICBgY29sSW5mb2AgZXZlbnQncyBgdGFibGVOdW1gIHZhbHVlcyByZWZlciB0byB0aGVtLiBFYWNoIG5hbWUgaXMgZ2l2ZW5cbiAgICAgICAqICAgYXMgaXRzIGluZGl2aWR1YWwgcGFydHMgKGUuZy4gYFsnZGJvJywgJ2VtcGxveWVlcyddYCkuXG4gICAgICAgKi9cbiAgICAgICh0YWJsZU5hbWVzOiBzdHJpbmdbXVtdKSA9PiB2b2lkXG4gICk6IHRoaXNcblxuICAvKipcbiAgICogVGhpcyBldmVudCBkZXNjcmliZXMgaG93IHRoZSBjb2x1bW5zIG9mIHRoZSByZXN1bHQgc2V0IG1hcCBiYWNrIHRvIHRoZSBiYXNlIHRhYmxlc1xuICAgKiBnaXZlbiBpbiB0aGUgYHRhYk5hbWVgIGV2ZW50LCBpZiB0aGUgcXVlcnkgd2FzIGV4ZWN1dGVkIGluIGJyb3dzZSBtb2RlIChlLmcuIHdpdGggYVxuICAgKiBgRk9SIEJST1dTRWAgY2xhdXNlIG9yIGBTRVQgTk9fQlJPV1NFVEFCTEUgT05gKS5cbiAgICovXG4gIG9uKFxuICAgIGV2ZW50OiAnY29sSW5mbycsXG4gICAgbGlzdGVuZXI6XG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSBjb2x1bW5zXG4gICAgICAgKiAgIE9uZSBlbnRyeSBmb3IgZWFjaCBjb2x1bW4gaW4gdGhlIHJlc3VsdCBzZXQsIGRlc2NyaWJpbmcgdGhlIGJhc2UgdGFibGVcbiAgICAgICAqICAgdGhlIGNvbHVtbiB3YXMgZGVyaXZlZCBmcm9tLlxuICAgICAgICovXG4gICAgICAoY29sdW1uczogQ29sdW1uSW5mb1tdKSA9PiB2b2lkXG4gICk6IHRoaXNcblxuICBvbihldmVudDogJ3JlcXVlc3RDb21wbGV0ZWQnLCBsaXN0ZW5lcjogKCkgPT4gdm9pZCk6IHRoaXNcblxuICBvbihldmVudDogJ2NhbmNlbCcsIGxpc3RlbmVyOiAoKSA9PiB2b2lkKTogdGhpc1xuXG4gIG9uKGV2ZW50OiAncGF1c2UnLCBsaXN0ZW5lcjogKCkgPT4gdm9pZCk6IHRoaXNcblxuICBvbihldmVudDogJ3Jlc3VtZScsIGxpc3RlbmVyOiAoKSA9PiB2b2lkKTogdGhpc1xuXG4gIG9uKGV2ZW50OiBzdHJpbmcgfCBzeW1ib2wsIGxpc3RlbmVyOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQpIHtcbiAgICByZXR1cm4gc3VwZXIub24oZXZlbnQsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ2NvbHVtbk1ldGFkYXRhJywgY29sdW1uczogQ29sdW1uTWV0YWRhdGFbXSB8IHsgW2tleTogc3RyaW5nXTogQ29sdW1uTWV0YWRhdGEgfSk6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAncHJlcGFyZWQnKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdlcnJvcicsIGVycjogRXJyb3IpOiBib29sZWFuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ3JvdycsIGNvbHVtbnM6IGFueSk6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAnZG9uZScsIHJvd0NvdW50OiBudW1iZXIgfCB1bmRlZmluZWQsIG1vcmU6IGJvb2xlYW4sIHJzdD86IGFueVtdKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdkb25lSW5Qcm9jJywgcm93Q291bnQ6IG51bWJlciB8IHVuZGVmaW5lZCwgbW9yZTogYm9vbGVhbiwgcnN0PzogYW55W10pOiBib29sZWFuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ2RvbmVQcm9jJywgcm93Q291bnQ6IG51bWJlciB8IHVuZGVmaW5lZCwgbW9yZTogYm9vbGVhbiwgcHJvY1JldHVyblN0YXR1c1ZhbHVlOiBudW1iZXIsIHJzdD86IGFueVtdKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdyZXR1cm5WYWx1ZScsIHBhcmFtZXRlck5hbWU6IHN0cmluZywgdmFsdWU6IHVua25vd24sIG1ldGFkYXRhOiBNZXRhZGF0YSk6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAncmVxdWVzdENvbXBsZXRlZCcpOiBib29sZWFuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ2NhbmNlbCcpOiBib29sZWFuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ3BhdXNlJyk6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAncmVzdW1lJyk6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAnb3JkZXInLCBvcmRlckNvbHVtbnM6IG51bWJlcltdKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICd0YWJOYW1lJywgdGFibGVOYW1lczogc3RyaW5nW11bXSk6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAnY29sSW5mbycsIGNvbHVtbnM6IENvbHVtbkluZm9bXSk6IGJvb2xlYW5cbiAgZW1pdChldmVudDogc3RyaW5nIHwgc3ltYm9sLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIHJldHVybiBzdXBlci5lbWl0KGV2ZW50LCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gc3FsVGV4dE9yUHJvY2VkdXJlXG4gICAqICAgVGhlIFNRTCBzdGF0ZW1lbnQgdG8gYmUgZXhlY3V0ZWRcbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrXG4gICAqICAgVGhlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgb25jZSB0aGUgcmVxdWVzdCBoYXMgYmVlbiBmdWxseSBjb21wbGV0ZWQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzcWxUZXh0T3JQcm9jZWR1cmU6IHN0cmluZyB8IHVuZGVmaW5lZCwgY2FsbGJhY2s6IENvbXBsZXRpb25DYWxsYmFjaywgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuc3FsVGV4dE9yUHJvY2VkdXJlID0gc3FsVGV4dE9yUHJvY2VkdXJlO1xuICAgIHRoaXMucGFyYW1ldGVycyA9IFtdO1xuICAgIHRoaXMucGFyYW1ldGVyc0J5TmFtZSA9IHt9O1xuICAgIHRoaXMucHJlcGFyaW5nID0gZmFsc2U7XG4gICAgdGhpcy5oYW5kbGUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jYW5jZWxlZCA9IGZhbHNlO1xuICAgIHRoaXMucGF1c2VkID0gZmFsc2U7XG4gICAgdGhpcy5lcnJvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNvbm5lY3Rpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy50aW1lb3V0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudXNlckNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgdGhpcy5zdGF0ZW1lbnRDb2x1bW5FbmNyeXB0aW9uU2V0dGluZyA9IChvcHRpb25zICYmIG9wdGlvbnMuc3RhdGVtZW50Q29sdW1uRW5jcnlwdGlvblNldHRpbmcpIHx8IFNRTFNlcnZlclN0YXRlbWVudENvbHVtbkVuY3J5cHRpb25TZXR0aW5nLlVzZUNvbm5lY3Rpb25TZXR0aW5nO1xuICAgIHRoaXMuY3J5cHRvTWV0YWRhdGFMb2FkZWQgPSBmYWxzZTtcbiAgICB0aGlzLmNhbGxiYWNrID0gZnVuY3Rpb24oZXJyOiBFcnJvciB8IHVuZGVmaW5lZCB8IG51bGwsIHJvd0NvdW50PzogbnVtYmVyLCByb3dzPzogYW55KSB7XG4gICAgICAvLyBBIGNhbmNlbGxhdGlvbiBvbmx5IGFwcGxpZXMgdG8gdGhlIGV4ZWN1dGlvbiBpdCB3YXMgbWFkZSBmb3IsIHNvIGl0XG4gICAgICAvLyBtdXN0IG5vdCBmYWlsIGxhdGVyIGV4ZWN1dGlvbnMgb2YgdGhlIHJlcXVlc3QgLSBpbmNsdWRpbmcgb25lcyB0aGF0XG4gICAgICAvLyBhcmUgc3RhcnRlZCBmcm9tIHRoZSBjYWxsYmFjayBvciBldmVudCBsaXN0ZW5lcnMgYmVsb3cuXG4gICAgICB0aGlzLmNhbmNlbGVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLnByZXBhcmluZykge1xuICAgICAgICB0aGlzLnByZXBhcmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdwcmVwYXJlZCcpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnVzZXJDYWxsYmFjayhlcnIsIHJvd0NvdW50LCByb3dzKTtcbiAgICAgICAgdGhpcy5lbWl0KCdyZXF1ZXN0Q29tcGxldGVkJyk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gbmFtZVxuICAgKiAgIFRoZSBwYXJhbWV0ZXIgbmFtZS4gVGhpcyBzaG91bGQgY29ycmVzcG9uZCB0byBhIHBhcmFtZXRlciBpbiB0aGUgU1FMLFxuICAgKiAgIG9yIGEgcGFyYW1ldGVyIHRoYXQgYSBjYWxsZWQgcHJvY2VkdXJlIGV4cGVjdHMuIFRoZSBuYW1lIHNob3VsZCBub3Qgc3RhcnQgd2l0aCBgQGAuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlXG4gICAqICAgT25lIG9mIHRoZSBzdXBwb3J0ZWQgZGF0YSB0eXBlcy5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlXG4gICAqICAgVGhlIHZhbHVlIHRoYXQgdGhlIHBhcmFtZXRlciBpcyB0byBiZSBnaXZlbi4gVGhlIEphdmFzY3JpcHQgdHlwZSBvZiB0aGVcbiAgICogICBhcmd1bWVudCBzaG91bGQgbWF0Y2ggdGhhdCBkb2N1bWVudGVkIGZvciBkYXRhIHR5cGVzLlxuICAgKlxuICAgKiAgIEEgYHZhcmNoYXIobWF4KWAsIGBudmFyY2hhcihtYXgpYCBvciBgdmFyYmluYXJ5KG1heClgIHZhbHVlLCBvciB0aGUgcm93c1xuICAgKiAgIG9mIGEgdGFibGUtdmFsdWVkIHBhcmFtZXRlciwgY2FuIGFsc28gYmUgZ2l2ZW4gYXMgYW4gYXN5bmMgaXRlcmFibGVcbiAgICogICAoZS5nLiBhIGBSZWFkYWJsZWApIG9mIGNodW5rcywgb3Igb2Ygcm93cy4gVGhlIHNvdXJjZSBpcyByZWFkIHdoaWxlIHRoZVxuICAgKiAgIHJlcXVlc3QgaXMgYmVpbmcgc2VudCwgc28gaXQgZG9lcyBub3QgaGF2ZSB0byBmaXQgaW4gbWVtb3J5LCBhbmQgYVxuICAgKiAgIHJlcXVlc3QgdGhhdCBjYXJyaWVzIG9uZSBjYW4gYmUgZXhlY3V0ZWQgb25seSBvbmNlLlxuICAgKlxuICAgKiAgIFN0cmluZyBjaHVua3MgbWF5IHNwbGl0IFVURi0xNiBzdXJyb2dhdGUgcGFpcnM7IHRoZSBwYWlycyBhcmUgcHJlc2VydmVkXG4gICAqICAgYWNyb3NzIGNodW5rIGJvdW5kYXJpZXMsIGluY2x1ZGluZyBlbXB0eSBjaHVua3MuIEFuIHVucGFpcmVkIHN1cnJvZ2F0ZVxuICAgKiAgIGlzIGhhbmRsZWQgYnkgdGhlIHR5cGUncyBlbmNvZGluZyBhcyBpdCBpcyBmb3IgYW4gaW4tbWVtb3J5IHZhbHVlLlxuICAgKiAgIEEgYEJ1ZmZlcmAgY2h1bmsgb2YgOCBLQiBvciBtb3JlIGlzIHNlbnQgYnlcbiAgICogICByZWZlcmVuY2UsIGFzIGBzb2NrZXQud3JpdGVgIHdvdWxkIHNlbmQgaXQsIHNvIGEgc291cmNlIG11c3Qgbm90IHJldXNlXG4gICAqICAgb3IgbW9kaWZ5IGEgYnVmZmVyIGl0IGhhcyB5aWVsZGVkIHVudGlsIHRoZSByZXF1ZXN0IGhhcyBjb21wbGV0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zXG4gICAqICAgQWRkaXRpb25hbCB0eXBlIG9wdGlvbnMuIE9wdGlvbmFsLlxuICAgKi9cbiAgLy8gVE9ETzogYHR5cGVgIG11c3QgYmUgYSB2YWxpZCBURFMgdmFsdWUgdHlwZVxuICBhZGRQYXJhbWV0ZXIobmFtZTogc3RyaW5nLCB0eXBlOiBEYXRhVHlwZSwgdmFsdWU/OiB1bmtub3duLCBvcHRpb25zPzogUmVhZG9ubHk8UGFyYW1ldGVyT3B0aW9ucz4gfCBudWxsKSB7XG4gICAgY29uc3QgeyBvdXRwdXQgPSBmYWxzZSwgbGVuZ3RoLCBwcmVjaXNpb24sIHNjYWxlIH0gPSBvcHRpb25zID8/IHt9O1xuXG4gICAgY29uc3QgcGFyYW1ldGVyOiBQYXJhbWV0ZXIgPSB7XG4gICAgICB0eXBlOiB0eXBlLFxuICAgICAgbmFtZTogbmFtZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIG91dHB1dDogb3V0cHV0LFxuICAgICAgbGVuZ3RoOiBsZW5ndGgsXG4gICAgICBwcmVjaXNpb246IHByZWNpc2lvbixcbiAgICAgIHNjYWxlOiBzY2FsZVxuICAgIH07XG5cbiAgICB0aGlzLnBhcmFtZXRlcnMucHVzaChwYXJhbWV0ZXIpO1xuICAgIHRoaXMucGFyYW1ldGVyc0J5TmFtZVtuYW1lXSA9IHBhcmFtZXRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gbmFtZVxuICAgKiAgIFRoZSBwYXJhbWV0ZXIgbmFtZS4gVGhpcyBzaG91bGQgY29ycmVzcG9uZCB0byBhIHBhcmFtZXRlciBpbiB0aGUgU1FMLFxuICAgKiAgIG9yIGEgcGFyYW1ldGVyIHRoYXQgYSBjYWxsZWQgcHJvY2VkdXJlIGV4cGVjdHMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlXG4gICAqICAgT25lIG9mIHRoZSBzdXBwb3J0ZWQgZGF0YSB0eXBlcy5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlXG4gICAqICAgVGhlIHZhbHVlIHRoYXQgdGhlIHBhcmFtZXRlciBpcyB0byBiZSBnaXZlbi4gVGhlIEphdmFzY3JpcHQgdHlwZSBvZiB0aGVcbiAgICogICBhcmd1bWVudCBzaG91bGQgbWF0Y2ggdGhhdCBkb2N1bWVudGVkIGZvciBkYXRhIHR5cGVzXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zXG4gICAqICAgQWRkaXRpb25hbCB0eXBlIG9wdGlvbnMuIE9wdGlvbmFsLlxuICAgKi9cbiAgYWRkT3V0cHV0UGFyYW1ldGVyKG5hbWU6IHN0cmluZywgdHlwZTogRGF0YVR5cGUsIHZhbHVlPzogdW5rbm93biwgb3B0aW9ucz86IFJlYWRvbmx5PFBhcmFtZXRlck9wdGlvbnM+IHwgbnVsbCkge1xuICAgIHRoaXMuYWRkUGFyYW1ldGVyKG5hbWUsIHR5cGUsIHZhbHVlLCB7IC4uLm9wdGlvbnMsIG91dHB1dDogdHJ1ZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgbWFrZVBhcmFtc1BhcmFtZXRlcihwYXJhbWV0ZXJzOiBQYXJhbWV0ZXJbXSkge1xuICAgIGxldCBwYXJhbXNQYXJhbWV0ZXIgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcGFyYW1ldGVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgY29uc3QgcGFyYW1ldGVyID0gcGFyYW1ldGVyc1tpXTtcbiAgICAgIGlmIChwYXJhbXNQYXJhbWV0ZXIubGVuZ3RoID4gMCkge1xuICAgICAgICBwYXJhbXNQYXJhbWV0ZXIgKz0gJywgJztcbiAgICAgIH1cbiAgICAgIHBhcmFtc1BhcmFtZXRlciArPSAnQCcgKyBwYXJhbWV0ZXIubmFtZSArICcgJztcbiAgICAgIHBhcmFtc1BhcmFtZXRlciArPSBwYXJhbWV0ZXIudHlwZS5kZWNsYXJhdGlvbihwYXJhbWV0ZXIpO1xuICAgICAgaWYgKHBhcmFtZXRlci5vdXRwdXQpIHtcbiAgICAgICAgcGFyYW1zUGFyYW1ldGVyICs9ICcgT1VUUFVUJztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBhcmFtc1BhcmFtZXRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdmFsaWRhdGVQYXJhbWV0ZXJzKGNvbGxhdGlvbjogQ29sbGF0aW9uIHwgdW5kZWZpbmVkLCBvcHRpb25zOiBJbnRlcm5hbENvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRQYXJhbWV0ZXJzOiBSZXNvbHZlZFBhcmFtZXRlcltdID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjb25zdCBwYXJhbWV0ZXIgPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICAgIGxldCByZXNvbHZlZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc29sdmVkID0gcmVzb2x2ZVBhcmFtZXRlcihwYXJhbWV0ZXIsIGNvbGxhdGlvbiwgb3B0aW9ucyk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIHRocm93IG5ldyBSZXF1ZXN0RXJyb3IoJ1ZhbGlkYXRpb24gZmFpbGVkIGZvciBwYXJhbWV0ZXIgXFwnJyArIHBhcmFtZXRlci5uYW1lICsgJ1xcJy4gJyArIGVycm9yLm1lc3NhZ2UsICdFUEFSQU0nLCB7IGNhdXNlOiBlcnJvciB9KTtcbiAgICAgIH1cblxuICAgICAgcGFyYW1ldGVyLnZhbHVlID0gcmVzb2x2ZWQuZGF0YS52YWx1ZTtcbiAgICAgIHJlc29sdmVkUGFyYW1ldGVycy5wdXNoKHJlc29sdmVkKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc29sdmVkUGFyYW1ldGVycyA9IHJlc29sdmVkUGFyYW1ldGVycztcbiAgfVxuXG4gIC8qKlxuICAgKiBUZW1wb3JhcmlseSBzdXNwZW5kcyB0aGUgZmxvdyBvZiBkYXRhIGZyb20gdGhlIGRhdGFiYXNlLiBObyBtb3JlIGByb3dgIGV2ZW50cyB3aWxsIGJlIGVtaXR0ZWQgdW50aWwgW1tyZXN1bWVdXSBpcyBjYWxsZWQuXG4gICAqIElmIHRoaXMgcmVxdWVzdCBpcyBhbHJlYWR5IGluIGEgcGF1c2VkIHN0YXRlLCBjYWxsaW5nIFtbcGF1c2VdXSBoYXMgbm8gZWZmZWN0LlxuICAgKi9cbiAgcGF1c2UoKSB7XG4gICAgaWYgKHRoaXMucGF1c2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuZW1pdCgncGF1c2UnKTtcbiAgICB0aGlzLnBhdXNlZCA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogUmVzdW1lcyB0aGUgZmxvdyBvZiBkYXRhIGZyb20gdGhlIGRhdGFiYXNlLlxuICAgKiBJZiB0aGlzIHJlcXVlc3QgaXMgbm90IGluIGEgcGF1c2VkIHN0YXRlLCBjYWxsaW5nIFtbcmVzdW1lXV0gaGFzIG5vIGVmZmVjdC5cbiAgICovXG4gIHJlc3VtZSgpIHtcbiAgICBpZiAoIXRoaXMucGF1c2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucGF1c2VkID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdyZXN1bWUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5jZWxzIGEgcmVxdWVzdCB3aGlsZSB3YWl0aW5nIGZvciBhIHNlcnZlciByZXNwb25zZS5cbiAgICovXG4gIGNhbmNlbCgpIHtcbiAgICBpZiAodGhpcy5jYW5jZWxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY2FuY2VsZWQgPSB0cnVlO1xuICAgIHRoaXMuZW1pdCgnY2FuY2VsJyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIHRpbWVvdXQgZm9yIHRoaXMgcmVxdWVzdC5cbiAgICpcbiAgICogQHBhcmFtIHRpbWVvdXRcbiAgICogICBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIHJlcXVlc3QgaXMgY29uc2lkZXJlZCBmYWlsZWQsXG4gICAqICAgb3IgYDBgIGZvciBubyB0aW1lb3V0LiBXaGVuIG5vIHRpbWVvdXQgaXMgc2V0IGZvciB0aGUgcmVxdWVzdCxcbiAgICogICB0aGUgW1tDb25uZWN0aW9uT3B0aW9ucy5yZXF1ZXN0VGltZW91dF1dIG9mIHRoZSBbW0Nvbm5lY3Rpb25dXSBpcyB1c2VkLlxuICAgKi9cbiAgc2V0VGltZW91dCh0aW1lb3V0PzogbnVtYmVyKSB7XG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0O1xubW9kdWxlLmV4cG9ydHMgPSBSZXF1ZXN0O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxTQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFJQSxJQUFBRyxNQUFBLEdBQUFILE9BQUE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBMkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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