@tensorflow/tfjs-layers
Version:
TensorFlow layers API in JavaScript
125 lines • 18.2 kB
JavaScript
/**
* @license
* Copyright 2018 Google LLC
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
* =============================================================================
*/
import { serialization } from '@tensorflow/tfjs-core';
import { getUid } from '../backend/state';
import { ValueError } from '../errors';
import { Layer, Node, SymbolicTensor } from './topology';
class InputLayer extends Layer {
constructor(args) {
super({
dtype: args.dtype,
name: args.name != null ? args.name : getUid('input').toString()
});
// Normalize config.batchSize and config.sparse
if (args.batchSize == null) {
args.batchSize = null;
}
if (args.sparse == null) {
args.sparse = false;
}
this.trainable = false;
this.built = true;
this.sparse = args.sparse;
if (args.inputShape != null && args.batchInputShape != null) {
throw new ValueError('Only provide the inputShape OR ' +
'batchInputShape argument to inputLayer, not both at the same time.');
}
let batchInputShape = args.batchInputShape;
if (batchInputShape == null) {
if (args.inputShape == null) {
throw new ValueError('An InputLayer should be passed either a ' +
'`batchInputShape` or an `inputShape`.');
}
else {
batchInputShape = [args.batchSize].concat(args.inputShape);
}
}
else {
// TODO(michaelterry): Backport to PyKeras
if (args.batchSize != null) {
throw new ValueError('Cannot specify batchSize if batchInputShape is ' +
'specified when creating an InputLayer.');
}
}
const dtype = args.dtype || 'float32';
this.batchInputShape = batchInputShape;
this.dtype = dtype;
// TODO(michaelterry): Backport this to PyKeras?
this.inputSpec = [{ shape: batchInputShape }];
const inputTensor = new SymbolicTensor(this.dtype, this.batchInputShape, this, [], {}, this.name);
inputTensor.nodeIndex = 0;
inputTensor.tensorIndex = 0;
// Create an input node to add to this.outboundNode.
// (This call has side effects.)
// tslint:disable-next-line:no-unused-expression
new Node({
outboundLayer: this,
inboundLayers: [],
nodeIndices: [],
tensorIndices: [],
inputTensors: [inputTensor],
outputTensors: [inputTensor],
inputMasks: [null],
outputMasks: [null],
inputShapes: [batchInputShape],
outputShapes: [batchInputShape]
});
}
apply(inputs, kwargs) {
throw new ValueError('Cannot pass any input to an ' +
`InputLayer's apply() method. InputLayer name: ${this.name}`);
}
dispose() {
// dispose() for InputLayer is overridden as no-op.
return { refCountAfterDispose: this._refCount, numDisposedVariables: 0 };
}
getConfig() {
return {
batchInputShape: this.batchInputShape,
dtype: this.dtype,
sparse: this.sparse,
name: this.name
};
}
}
/** @nocollapse */
InputLayer.className = 'InputLayer';
export { InputLayer };
serialization.registerClass(InputLayer);
export function Input(config) {
if (config.batchShape == null && config.shape == null) {
throw new Error('Please provide to Input either a `shape`' +
' or a `batchShape` argument. Note that ' +
'`shape` does not include the batch ' +
'dimension.');
}
if (config.batchShape != null && config.shape != null) {
// TODO(michaelterry): Backport to PyKeras.
throw new ValueError('Please provide either a `shape` or `batchShape` ' +
'argument to Input, but not both.');
}
let batchShape = config.batchShape;
if (config.shape != null && batchShape == null) {
batchShape = [null].concat(config.shape);
}
let dtype = config.dtype;
if (dtype == null) {
dtype = 'float32';
}
const inputLayer = new InputLayer({
batchInputShape: batchShape,
name: config.name,
dtype,
sparse: config.sparse
});
const outputs = inputLayer.inboundNodes[0].outputTensors;
return outputs[0];
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXRfbGF5ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWxheWVycy9zcmMvZW5naW5lL2lucHV0X2xheWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFXLGFBQWEsRUFBUyxNQUFNLHVCQUF1QixDQUFDO0FBRXRFLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUN4QyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBSXJDLE9BQU8sRUFBZ0IsS0FBSyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsTUFBTSxZQUFZLENBQUM7QUEyQnRFLE1BQWEsVUFBVyxTQUFRLEtBQUs7SUFJbkMsWUFBWSxJQUFvQjtRQUM5QixLQUFLLENBQUM7WUFDSixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7WUFDakIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFO1NBQ2pFLENBQUMsQ0FBQztRQUNILCtDQUErQztRQUMvQyxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxFQUFFO1lBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1NBQ3ZCO1FBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksRUFBRTtZQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztTQUNyQjtRQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUUxQixJQUFJLElBQUksQ0FBQyxVQUFVLElB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QUFNLENBQUMsVUFBVSxJQUFJLElBQUksSUFBSSxNQUFNLENBQUMsS0FBSyxJQUFJLElBQUksRUFBRTtRQUNyRCxNQUFNLElBQUksS0FBSyxDQUNYLDBDQUEwQztZQUMxQyx5Q0FBeUM7WUFDekMscUNBQXFDO1lBQ3JDLFlBQVksQ0FBQyxDQUFDO0tBQ25CO0lBQ0QsSUFBSSxNQUFNLENBQUMsVUFBVSxJQUFJLElBQUksSUFBSSxNQUFNLENBQUMsS0FBSyxJQUFJLElBQUksRUFBRTtRQUNyRCwyQ0FBMkM7UUFDM0MsTUFBTSxJQUFJLFVBQVUsQ0FDaEIsa0RBQWtEO1lBQ2xELGtDQUFrQyxDQUFDLENBQUM7S0FDekM7SUFDRCxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO0lBQ25DLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUksVUFBVSxJQUFJLElBQUksRUFBRTtRQUM5QyxVQUFVLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzFDO0lBRUQsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUN6QixJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7UUFDakIsS0FBSyxHQUFHLFNBQVMsQ0FBQztLQUNuQjtJQUVELE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDO1FBQ2hDLGVBQWUsRUFBRSxVQUFVO1FBQzNCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtRQUNqQixLQUFLO1FBQ0wsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO0tBQ3RCLENBQUMsQ0FBQztJQUVILE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO0lBQ3pELE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlXG4gKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXRcbiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQge0RhdGFUeXBlLCBzZXJpYWxpemF0aW9uLCBUZW5zb3J9IGZyb20gJ0B0ZW5zb3JmbG93L3RmanMtY29yZSc7XG5cbmltcG9ydCB7Z2V0VWlkfSBmcm9tICcuLi9iYWNrZW5kL3N0YXRlJztcbmltcG9ydCB7VmFsdWVFcnJvcn0gZnJvbSAnLi4vZXJyb3JzJztcbmltcG9ydCB7U2hhcGV9IGZyb20gJy4uL2tlcmFzX2Zvcm1hdC9jb21tb24nO1xuaW1wb3J0IHtLd2FyZ3N9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtEaXNwb3NlUmVzdWx0LCBMYXllciwgTm9kZSwgU3ltYm9saWNUZW5zb3J9IGZyb20gJy4vdG9wb2xvZ3knO1xuXG4vKipcbiAqIENvbnN0cnVjdG9yIGFyZ3VtZW50cyBmb3IgSW5wdXRMYXllci5cbiAqXG4gKiBOb3RlOiBZb3Ugc2hvdWxkIHByb3ZpZGUgb25seSBpbnB1dFNoYXBlIG9yIGJhdGNoSW5wdXRTaGFwZSAobm90IGJvdGgpLlxuICogSWYgb25seSBpbnB1dFNoYXBlIGlzIHByb3ZpZGVkLCB0aGVuIHRoZSBiYXRjaElucHV0U2hhcGUgaXMgZGV0ZXJtaW5lZCBieVxuICogdGhlIGJhdGNoU2l6ZSBhcmd1bWVudCBhbmQgdGhlIGlucHV0U2hhcGU6IFtiYXRjaFNpemVdLmNvbmNhdChpbnB1dFNoYXBlKS5cbiAqL1xuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIElucHV0TGF5ZXJBcmdzIHtcbiAgLyoqIElucHV0IHNoYXBlLCBub3QgaW5jbHVkaW5nIHRoZSBiYXRjaCBheGlzLiAqL1xuICBpbnB1dFNoYXBlPzogU2hhcGU7XG4gIC8qKiBPcHRpb25hbCBpbnB1dCBiYXRjaCBzaXplIChpbnRlZ2VyIG9yIG51bGwpLiAqL1xuICBiYXRjaFNpemU/OiBudW1iZXI7XG4gIC8qKiBCYXRjaCBpbnB1dCBzaGFwZSwgaW5jbHVkaW5nIHRoZSBiYXRjaCBheGlzLiAqL1xuICBiYXRjaElucHV0U2hhcGU/OiBTaGFwZTtcbiAgLyoqIERhdGF0eXBlIG9mIHRoZSBpbnB1dC4gICovXG4gIGR0eXBlPzogRGF0YVR5cGU7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBwbGFjZWhvbGRlciBjcmVhdGVkIGlzIG1lYW50IHRvIGJlIHNwYXJzZS5cbiAgICovXG4gIHNwYXJzZT86IGJvb2xlYW47ICAvLyBUT0RPKG1pY2hhZWx0ZXJyeSk6IE5vdCBjbGVhciB3aGV0aGVyIHdlJ2xsIG5lZWQgdGhpcy5cblxuICAvKiogTmFtZSBvZiB0aGUgbGF5ZXIuICovXG4gIG5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBJbnB1dExheWVyIGV4dGVuZHMgTGF5ZXIge1xuICAvKiogQG5vY29sbGFwc2UgKi9cbiAgc3RhdGljIHJlYWRvbmx5IGNsYXNzTmFtZSA9ICdJbnB1dExheWVyJztcbiAgc3BhcnNlOiBib29sZWFuO1xuICBjb25zdHJ1Y3RvcihhcmdzOiBJbnB1dExheWVyQXJncykge1xuICAgIHN1cGVyKHtcbiAgICAgIGR0eXBlOiBhcmdzLmR0eXBlLFxuICAgICAgbmFtZTogYXJncy5uYW1lICE9IG51bGwgPyBhcmdzLm5hbWUgOiBnZXRVaWQoJ2lucHV0JykudG9TdHJpbmcoKVxuICAgIH0pO1xuICAgIC8vIE5vcm1hbGl6ZSBjb25maWcuYmF0Y2hTaXplIGFuZCBjb25maWcuc3BhcnNlXG4gICAgaWYgKGFyZ3MuYmF0Y2hTaXplID09IG51bGwpIHtcbiAgICAgIGFyZ3MuYmF0Y2hTaXplID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKGFyZ3Muc3BhcnNlID09IG51bGwpIHtcbiAgICAgIGFyZ3Muc3BhcnNlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy50cmFpbmFibGUgPSBmYWxzZTtcbiAgICB0aGlzLmJ1aWx0ID0gdHJ1ZTtcbiAgICB0aGlzLnNwYXJzZSA9IGFyZ3Muc3BhcnNlO1xuXG4gICAgaWYgKGFyZ3MuaW5wdXRTaGFwZSAhPSBudWxsICYmIGFyZ3MuYmF0Y2hJbnB1dFNoYXBlICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBWYWx1ZUVycm9yKFxuICAgICAgICAgICdPbmx5IHByb3ZpZGUgdGhlIGlucHV0U2hhcGUgT1IgJyArXG4gICAgICAgICAgJ2JhdGNoSW5wdXRTaGFwZSBhcmd1bWVudCB0byBpbnB1dExheWVyLCBub3QgYm90aCBhdCB0aGUgc2FtZSB0aW1lLicpO1xuICAgIH1cbiAgICBsZXQgYmF0Y2hJbnB1dFNoYXBlID0gYXJncy5iYXRjaElucHV0U2hhcGU7XG4gICAgaWYgKGJhdGNoSW5wdXRTaGFwZSA9PSBudWxsKSB7XG4gICAgICBpZiAoYXJncy5pbnB1dFNoYXBlID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbHVlRXJyb3IoXG4gICAgICAgICAgICAnQW4gSW5wdXRMYXllciBzaG91bGQgYmUgcGFzc2VkIGVpdGhlciBhICcgK1xuICAgICAgICAgICAgJ2BiYXRjaElucHV0U2hhcGVgIG9yIGFuIGBpbnB1dFNoYXBlYC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhdGNoSW5wdXRTaGFwZSA9IFthcmdzLmJhdGNoU2l6ZV0uY29uY2F0KGFyZ3MuaW5wdXRTaGFwZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE8obWljaGFlbHRlcnJ5KTogQmFja3BvcnQgdG8gUHlLZXJhc1xuICAgICAgaWYgKGFyZ3MuYmF0Y2hTaXplICE9IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbHVlRXJyb3IoXG4gICAgICAgICAgICAnQ2Fubm90IHNwZWNpZnkgYmF0Y2hTaXplIGlmIGJhdGNoSW5wdXRTaGFwZSBpcyAnICtcbiAgICAgICAgICAgICdzcGVjaWZpZWQgd2hlbiBjcmVhdGluZyBhbiBJbnB1dExheWVyLicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGR0eXBlID0gYXJncy5kdHlwZSB8fCAnZmxvYXQzMic7XG5cbiAgICB0aGlzLmJhdGNoSW5wdXRTaGFwZSA9IGJhdGNoSW5wdXRTaGFwZTtcbiAgICB0aGlzLmR0eXBlID0gZHR5cGU7XG4gICAgLy8gVE9ETyhtaWNoYWVsdGVycnkpOiBCYWNrcG9ydCB0aGlzIHRvIFB5S2VyYXM/XG4gICAgdGhpcy5pbnB1dFNwZWMgPSBbe3NoYXBlOiBiYXRjaElucHV0U2hhcGV9XTtcblxuICAgIGNvbnN0IGlucHV0VGVuc29yID0gbmV3IFN5bWJvbGljVGVuc29yKFxuICAgICAgICB0aGlzLmR0eXBlLCB0aGlzLmJhdGNoSW5wdXRTaGFwZSwgdGhpcywgW10sIHt9LCB0aGlzLm5hbWUpO1xuICAgIGlucHV0VGVuc29yLm5vZGVJbmRleCA9IDA7XG4gICAgaW5wdXRUZW5zb3IudGVuc29ySW5kZXggPSAwO1xuXG4gICAgLy8gQ3JlYXRlIGFuIGlucHV0IG5vZGUgdG8gYWRkIHRvIHRoaXMub3V0Ym91bmROb2RlLlxuICAgIC8vIChUaGlzIGNhbGwgaGFzIHNpZGUgZWZmZWN0cy4pXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXVudXNlZC1leHByZXNzaW9uXG4gICAgbmV3IE5vZGUoe1xuICAgICAgb3V0Ym91bmRMYXllcjogdGhpcyxcbiAgICAgIGluYm91bmRMYXllcnM6IFtdLFxuICAgICAgbm9kZUluZGljZXM6IFtdLFxuICAgICAgdGVuc29ySW5kaWNlczogW10sXG4gICAgICBpbnB1dFRlbnNvcnM6IFtpbnB1dFRlbnNvcl0sXG4gICAgICBvdXRwdXRUZW5zb3JzOiBbaW5wdXRUZW5zb3JdLFxuICAgICAgaW5wdXRNYXNrczogW251bGxdLFxuICAgICAgb3V0cHV0TWFza3M6IFtudWxsXSxcbiAgICAgIGlucHV0U2hhcGVzOiBbYmF0Y2hJbnB1dFNoYXBlXSxcbiAgICAgIG91dHB1dFNoYXBlczogW2JhdGNoSW5wdXRTaGFwZV1cbiAgICB9KTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFwcGx5KFxuICAgICAgaW5wdXRzOiBUZW5zb3J8VGVuc29yW118U3ltYm9saWNUZW5zb3J8U3ltYm9saWNUZW5zb3JbXSxcbiAgICAgIGt3YXJncz86IEt3YXJncyk6IFRlbnNvcnxUZW5zb3JbXXxTeW1ib2xpY1RlbnNvciB7XG4gICAgdGhyb3cgbmV3IFZhbHVlRXJyb3IoXG4gICAgICAgICdDYW5ub3QgcGFzcyBhbnkgaW5wdXQgdG8gYW4gJyArXG4gICAgICAgIGBJbnB1dExheWVyJ3MgYXBwbHkoKSBtZXRob2QuIElucHV0TGF5ZXIgbmFtZTogJHt0aGlzLm5hbWV9YCk7XG4gIH1cblxuICBvdmVycmlkZSBkaXNwb3NlKCk6IERpc3Bvc2VSZXN1bHQge1xuICAgIC8vIGRpc3Bvc2UoKSBmb3IgSW5wdXRMYXllciBpcyBvdmVycmlkZGVuIGFzIG5vLW9wLlxuICAgIHJldHVybiB7cmVmQ291bnRBZnRlckRpc3Bvc2U6IHRoaXMuX3JlZkNvdW50LCBudW1EaXNwb3NlZFZhcmlhYmxlczogMH07XG4gIH1cblxuICBvdmVycmlkZSBnZXRDb25maWcoKTogc2VyaWFsaXphdGlvbi5Db25maWdEaWN0IHtcbiAgICByZXR1cm4ge1xuICAgICAgYmF0Y2hJbnB1dFNoYXBlOiB0aGlzLmJhdGNoSW5wdXRTaGFwZSxcbiAgICAgIGR0eXBlOiB0aGlzLmR0eXBlLFxuICAgICAgc3BhcnNlOiB0aGlzLnNwYXJzZSxcbiAgICAgIG5hbWU6IHRoaXMubmFtZVxuICAgIH07XG4gIH1cbn1cbnNlcmlhbGl6YXRpb24ucmVnaXN0ZXJDbGFzcyhJbnB1dExheWVyKTtcblxuLyoqXG4gKiBDb25maWcgZm9yIHRoZSBJbnB1dCBmdW5jdGlvbi5cbiAqXG4gKiBOb3RlOiBZb3Ugc2hvdWxkIHByb3ZpZGUgb25seSBzaGFwZSBvciBiYXRjaFNoYXBlIChub3QgYm90aCkuXG4gKiBJZiBvbmx5IHNoYXBlIGlzIHByb3ZpZGVkLCB0aGVuIHRoZSBiYXRjaFNoYXBlIGJlY29tZXNcbiAqIFtudWxsXS5jb25jYXQoaW5wdXRTaGFwZSkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXRDb25maWcge1xuICAvKipcbiAgICogQSBzaGFwZSwgbm90IGluY2x1ZGluZyB0aGUgYmF0Y2ggc2l6ZS4gRm9yIGluc3RhbmNlLCBgc2hhcGU9WzMyXWBcbiAgICogaW5kaWNhdGVzIHRoYXQgdGhlIGV4cGVjdGVkIGlucHV0IHdpbGwgYmUgYmF0Y2hlcyBvZiAzMi1kaW1lbnNpb25hbFxuICAgKiB2ZWN0b3JzLlxuICAgKi9cbiAgc2hhcGU/OiBTaGFwZTtcbiAgLyoqXG4gICAqIEEgc2hhcGUgdHVwbGUgKGludGVnZXIpLCBpbmNsdWRpbmcgdGhlIGJhdGNoIHNpemUuIEZvciBpbnN0YW5jZSxcbiAgICogYGJhdGNoU2hhcGU9WzEwLCAzMl1gIGluZGljYXRlcyB0aGF0IHRoZSBleHBlY3RlZCBpbnB1dCB3aWxsIGJlIGJhdGNoZXMgb2ZcbiAgICogMTAgMzItZGltZW5zaW9uYWwgdmVjdG9ycy4gYGJhdGNoU2hhcGU9W251bGwsIDMyXWAgaW5kaWNhdGVzIGJhdGNoZXMgb2YgYW5cbiAgICogYXJiaXRyYXJ5IG51bWJlciBvZiAzMi1kaW1lbnNpb25hbCB2ZWN0b3JzLlxuICAgKi9cbiAgYmF0Y2hTaGFwZT86IFNoYXBlO1xuICAvKipcbiAgICogQW4gb3B0aW9uYWwgbmFtZSBzdHJpbmcgZm9yIHRoZSBsYXllci4gU2hvdWxkIGJlIHVuaXF1ZSBpbiBhIG1vZGVsIChkbyBub3RcbiAgICogcmV1c2UgdGhlIHNhbWUgbmFtZSB0d2ljZSkuIEl0IHdpbGwgYmUgYXV0b2dlbmVyYXRlZCBpZiBpdCBpc24ndCBwcm92aWRlZC5cbiAgICovXG4gIG5hbWU/OiBzdHJpbmc7XG4gIGR0eXBlPzogRGF0YVR5cGU7XG4gIC8qKlxuICAgKiBBIGJvb2xlYW4gc3BlY2lmeWluZyB3aGV0aGVyIHRoZSBwbGFjZWhvbGRlciB0byBiZSBjcmVhdGVkIGlzIHNwYXJzZS5cbiAgICovXG4gIHNwYXJzZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBJbnB1dChjb25maWc6IElucHV0Q29uZmlnKTogU3ltYm9saWNUZW5zb3Ige1xuICBpZiAoY29uZmlnLmJhdGNoU2hhcGUgPT0gbnVsbCAmJiBjb25maWcuc2hhcGUgPT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1BsZWFzZSBwcm92aWRlIHRvIElucHV0IGVpdGhlciBhIGBzaGFwZWAnICtcbiAgICAgICAgJyBvciBhIGBiYXRjaFNoYXBlYCBhcmd1bWVudC4gTm90ZSB0aGF0ICcgK1xuICAgICAgICAnYHNoYXBlYCBkb2VzIG5vdCBpbmNsdWRlIHRoZSBiYXRjaCAnICtcbiAgICAgICAgJ2RpbWVuc2lvbi4nKTtcbiAgfVxuICBpZiAoY29uZmlnLmJhdGNoU2hhcGUgIT0gbnVsbCAmJiBjb25maWcuc2hhcGUgIT0gbnVsbCkge1xuICAgIC8vIFRPRE8obWljaGFlbHRlcnJ5KTogQmFja3BvcnQgdG8gUHlLZXJhcy5cbiAgICB0aHJvdyBuZXcgVmFsdWVFcnJvcihcbiAgICAgICAgJ1BsZWFzZSBwcm92aWRlIGVpdGhlciBhIGBzaGFwZWAgb3IgYGJhdGNoU2hhcGVgICcgK1xuICAgICAgICAnYXJndW1lbnQgdG8gSW5wdXQsIGJ1dCBub3QgYm90aC4nKTtcbiAgfVxuICBsZXQgYmF0Y2hTaGFwZSA9IGNvbmZpZy5iYXRjaFNoYXBlO1xuICBpZiAoY29uZmlnLnNoYXBlICE9IG51bGwgJiYgYmF0Y2hTaGFwZSA9PSBudWxsKSB7XG4gICAgYmF0Y2hTaGFwZSA9IFtudWxsXS5jb25jYXQoY29uZmlnLnNoYXBlKTtcbiAgfVxuXG4gIGxldCBkdHlwZSA9IGNvbmZpZy5kdHlwZTtcbiAgaWYgKGR0eXBlID09IG51bGwpIHtcbiAgICBkdHlwZSA9ICdmbG9hdDMyJztcbiAgfVxuXG4gIGNvbnN0IGlucHV0TGF5ZXIgPSBuZXcgSW5wdXRMYXllcih7XG4gICAgYmF0Y2hJbnB1dFNoYXBlOiBiYXRjaFNoYXBlLFxuICAgIG5hbWU6IGNvbmZpZy5uYW1lLFxuICAgIGR0eXBlLFxuICAgIHNwYXJzZTogY29uZmlnLnNwYXJzZVxuICB9KTtcblxuICBjb25zdCBvdXRwdXRzID0gaW5wdXRMYXllci5pbmJvdW5kTm9kZXNbMF0ub3V0cHV0VGVuc29ycztcbiAgcmV0dXJuIG91dHB1dHNbMF07XG59XG4iXX0=