@tensorflow/tfjs-layers
Version:
TensorFlow layers API in JavaScript
196 lines • 18.3 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.
* =============================================================================
*/
// tslint:disable-next-line:max-line-length
import { Constant, GlorotNormal, GlorotUniform, HeNormal, HeUniform, Identity, LeCunNormal, LeCunUniform, Ones, Orthogonal, RandomNormal, RandomUniform, TruncatedNormal, VarianceScaling, Zeros } from './initializers';
/**
* Initializer that generates tensors initialized to 0.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function zeros() {
return new Zeros();
}
/**
* Initializer that generates tensors initialized to 1.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function ones() {
return new Ones();
}
/**
* Initializer that generates values initialized to some constant.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function constant(args) {
return new Constant(args);
}
/**
* Initializer that generates random values initialized to a uniform
* distribution.
*
* Values will be distributed uniformly between the configured minval and
* maxval.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function randomUniform(args) {
return new RandomUniform(args);
}
/**
* Initializer that generates random values initialized to a normal
* distribution.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function randomNormal(args) {
return new RandomNormal(args);
}
/**
* Initializer that generates random values initialized to a truncated normal
* distribution.
*
* These values are similar to values from a `RandomNormal` except that values
* more than two standard deviations from the mean are discarded and re-drawn.
* This is the recommended initializer for neural network weights and filters.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function truncatedNormal(args) {
return new TruncatedNormal(args);
}
/**
* Initializer that generates the identity matrix.
* Only use for square 2D matrices.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function identity(args) {
return new Identity(args);
}
/**
* Initializer capable of adapting its scale to the shape of weights.
* With distribution=NORMAL, samples are drawn from a truncated normal
* distribution centered on zero, with `stddev = sqrt(scale / n)` where n is:
* - number of input units in the weight tensor, if mode = FAN_IN.
* - number of output units, if mode = FAN_OUT.
* - average of the numbers of input and output units, if mode = FAN_AVG.
* With distribution=UNIFORM,
* samples are drawn from a uniform distribution
* within [-limit, limit], with `limit = sqrt(3 * scale / n)`.
*
* @doc {heading: 'Initializers',namespace: 'initializers'}
*/
export function varianceScaling(config) {
return new VarianceScaling(config);
}
/**
* Glorot uniform initializer, also called Xavier uniform initializer.
* It draws samples from a uniform distribution within [-limit, limit]
* where `limit` is `sqrt(6 / (fan_in + fan_out))`
* where `fan_in` is the number of input units in the weight tensor
* and `fan_out` is the number of output units in the weight tensor
*
* Reference:
* Glorot & Bengio, AISTATS 2010
* http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function glorotUniform(args) {
return new GlorotUniform(args);
}
/**
* Glorot normal initializer, also called Xavier normal initializer.
* It draws samples from a truncated normal distribution centered on 0
* with `stddev = sqrt(2 / (fan_in + fan_out))`
* where `fan_in` is the number of input units in the weight tensor
* and `fan_out` is the number of output units in the weight tensor.
*
* Reference:
* Glorot & Bengio, AISTATS 2010
* http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function glorotNormal(args) {
return new GlorotNormal(args);
}
/**
* He normal initializer.
*
* It draws samples from a truncated normal distribution centered on 0
* with `stddev = sqrt(2 / fanIn)`
* where `fanIn` is the number of input units in the weight tensor.
*
* Reference:
* He et al., http://arxiv.org/abs/1502.01852
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function heNormal(args) {
return new HeNormal(args);
}
/**
* He uniform initializer.
*
* It draws samples from a uniform distribution within [-limit, limit]
* where `limit` is `sqrt(6 / fan_in)`
* where `fanIn` is the number of input units in the weight tensor.
*
* Reference:
* He et al., http://arxiv.org/abs/1502.01852
*
* @doc {heading: 'Initializers',namespace: 'initializers'}
*/
export function heUniform(args) {
return new HeUniform(args);
}
/**
* LeCun normal initializer.
*
* It draws samples from a truncated normal distribution centered on 0
* with `stddev = sqrt(1 / fanIn)`
* where `fanIn` is the number of input units in the weight tensor.
*
* References:
* [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515)
* [Efficient Backprop](http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf)
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function leCunNormal(args) {
return new LeCunNormal(args);
}
/**
* LeCun uniform initializer.
*
* It draws samples from a uniform distribution in the interval
* `[-limit, limit]` with `limit = sqrt(3 / fanIn)`,
* where `fanIn` is the number of input units in the weight tensor.
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function leCunUniform(args) {
return new LeCunUniform(args);
}
/**
* Initializer that generates a random orthogonal matrix.
*
* Reference:
* [Saxe et al., http://arxiv.org/abs/1312.6120](http://arxiv.org/abs/1312.6120)
*
* @doc {heading: 'Initializers', namespace: 'initializers'}
*/
export function orthogonal(args) {
return new Orthogonal(args);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0c19pbml0aWFsaXplcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZmpzLWxheWVycy9zcmMvZXhwb3J0c19pbml0aWFsaXplcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0dBUUc7QUFDSCwyQ0FBMkM7QUFDM0MsT0FBTyxFQUFDLFFBQVEsRUFBZ0IsWUFBWSxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBNkIsV0FBVyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFrQixZQUFZLEVBQW9CLGFBQWEsRUFBOEMsZUFBZSxFQUF1QixlQUFlLEVBQXVCLEtBQUssRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBRXhYOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsS0FBSztJQUNuQixPQUFPLElBQUksS0FBSyxFQUFFLENBQUM7QUFDckIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsSUFBSTtJQUNsQixPQUFPLElBQUksSUFBSSxFQUFFLENBQUM7QUFDcEIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsUUFBUSxDQUFDLElBQWtCO0lBQ3pDLE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUF1QjtJQUNuRCxPQUFPLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBc0I7SUFDakQsT0FBTyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNoQyxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxJQUF5QjtJQUN2RCxPQUFPLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsSUFBa0I7SUFDekMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1QixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxNQUEyQjtJQUN6RCxPQUFPLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3JDLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLElBQTZCO0lBQ3pELE9BQU8sSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBNkI7SUFDeEQsT0FBTyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNoQyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUsUUFBUSxDQUFDLElBQTZCO0lBQ3BELE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxJQUE2QjtJQUNyRCxPQUFPLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUFDLElBQTZCO0lBQ3ZELE9BQU8sSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxJQUE2QjtJQUN4RCxPQUFPLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxJQUFvQjtJQUM3QyxPQUFPLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzlCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlXG4gKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXRcbiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuaW1wb3J0IHtDb25zdGFudCwgQ29uc3RhbnRBcmdzLCBHbG9yb3ROb3JtYWwsIEdsb3JvdFVuaWZvcm0sIEhlTm9ybWFsLCBIZVVuaWZvcm0sIElkZW50aXR5LCBJZGVudGl0eUFyZ3MsIEluaXRpYWxpemVyLCBMZUN1bk5vcm1hbCwgTGVDdW5Vbmlmb3JtLCBPbmVzLCBPcnRob2dvbmFsLCBPcnRob2dvbmFsQXJncywgUmFuZG9tTm9ybWFsLCBSYW5kb21Ob3JtYWxBcmdzLCBSYW5kb21Vbmlmb3JtLCBSYW5kb21Vbmlmb3JtQXJncywgU2VlZE9ubHlJbml0aWFsaXplckFyZ3MsIFRydW5jYXRlZE5vcm1hbCwgVHJ1bmNhdGVkTm9ybWFsQXJncywgVmFyaWFuY2VTY2FsaW5nLCBWYXJpYW5jZVNjYWxpbmdBcmdzLCBaZXJvc30gZnJvbSAnLi9pbml0aWFsaXplcnMnO1xuXG4vKipcbiAqIEluaXRpYWxpemVyIHRoYXQgZ2VuZXJhdGVzIHRlbnNvcnMgaW5pdGlhbGl6ZWQgdG8gMC5cbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJywgbmFtZXNwYWNlOiAnaW5pdGlhbGl6ZXJzJ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHplcm9zKCk6IFplcm9zIHtcbiAgcmV0dXJuIG5ldyBaZXJvcygpO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVyIHRoYXQgZ2VuZXJhdGVzIHRlbnNvcnMgaW5pdGlhbGl6ZWQgdG8gMS5cbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJywgbmFtZXNwYWNlOiAnaW5pdGlhbGl6ZXJzJ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uZXMoKTogSW5pdGlhbGl6ZXIge1xuICByZXR1cm4gbmV3IE9uZXMoKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplciB0aGF0IGdlbmVyYXRlcyB2YWx1ZXMgaW5pdGlhbGl6ZWQgdG8gc29tZSBjb25zdGFudC5cbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJywgbmFtZXNwYWNlOiAnaW5pdGlhbGl6ZXJzJ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnN0YW50KGFyZ3M6IENvbnN0YW50QXJncyk6IEluaXRpYWxpemVyIHtcbiAgcmV0dXJuIG5ldyBDb25zdGFudChhcmdzKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplciB0aGF0IGdlbmVyYXRlcyByYW5kb20gdmFsdWVzIGluaXRpYWxpemVkIHRvIGEgdW5pZm9ybVxuICogZGlzdHJpYnV0aW9uLlxuICpcbiAqIFZhbHVlcyB3aWxsIGJlIGRpc3RyaWJ1dGVkIHVuaWZvcm1seSBiZXR3ZWVuIHRoZSBjb25maWd1cmVkIG1pbnZhbCBhbmRcbiAqIG1heHZhbC5cbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJywgbmFtZXNwYWNlOiAnaW5pdGlhbGl6ZXJzJ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVVuaWZvcm0oYXJnczogUmFuZG9tVW5pZm9ybUFyZ3MpOiBJbml0aWFsaXplciB7XG4gIHJldHVybiBuZXcgUmFuZG9tVW5pZm9ybShhcmdzKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplciB0aGF0IGdlbmVyYXRlcyByYW5kb20gdmFsdWVzIGluaXRpYWxpemVkIHRvIGEgbm9ybWFsXG4gKiBkaXN0cmlidXRpb24uXG4gKlxuICogQGRvYyB7aGVhZGluZzogJ0luaXRpYWxpemVycycsIG5hbWVzcGFjZTogJ2luaXRpYWxpemVycyd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5kb21Ob3JtYWwoYXJnczogUmFuZG9tTm9ybWFsQXJncyk6IEluaXRpYWxpemVyIHtcbiAgcmV0dXJuIG5ldyBSYW5kb21Ob3JtYWwoYXJncyk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXIgdGhhdCBnZW5lcmF0ZXMgcmFuZG9tIHZhbHVlcyBpbml0aWFsaXplZCB0byBhIHRydW5jYXRlZCBub3JtYWxcbiAqIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiBUaGVzZSB2YWx1ZXMgYXJlIHNpbWlsYXIgdG8gdmFsdWVzIGZyb20gYSBgUmFuZG9tTm9ybWFsYCBleGNlcHQgdGhhdCB2YWx1ZXNcbiAqIG1vcmUgdGhhbiB0d28gc3RhbmRhcmQgZGV2aWF0aW9ucyBmcm9tIHRoZSBtZWFuIGFyZSBkaXNjYXJkZWQgYW5kIHJlLWRyYXduLlxuICogVGhpcyBpcyB0aGUgcmVjb21tZW5kZWQgaW5pdGlhbGl6ZXIgZm9yIG5ldXJhbCBuZXR3b3JrIHdlaWdodHMgYW5kIGZpbHRlcnMuXG4gKlxuICogQGRvYyB7aGVhZGluZzogJ0luaXRpYWxpemVycycsIG5hbWVzcGFjZTogJ2luaXRpYWxpemVycyd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cnVuY2F0ZWROb3JtYWwoYXJnczogVHJ1bmNhdGVkTm9ybWFsQXJncyk6IEluaXRpYWxpemVyIHtcbiAgcmV0dXJuIG5ldyBUcnVuY2F0ZWROb3JtYWwoYXJncyk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXIgdGhhdCBnZW5lcmF0ZXMgdGhlIGlkZW50aXR5IG1hdHJpeC5cbiAqIE9ubHkgdXNlIGZvciBzcXVhcmUgMkQgbWF0cmljZXMuXG4gKlxuICogQGRvYyB7aGVhZGluZzogJ0luaXRpYWxpemVycycsIG5hbWVzcGFjZTogJ2luaXRpYWxpemVycyd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpZGVudGl0eShhcmdzOiBJZGVudGl0eUFyZ3MpOiBJbml0aWFsaXplciB7XG4gIHJldHVybiBuZXcgSWRlbnRpdHkoYXJncyk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXIgY2FwYWJsZSBvZiBhZGFwdGluZyBpdHMgc2NhbGUgdG8gdGhlIHNoYXBlIG9mIHdlaWdodHMuXG4gKiBXaXRoIGRpc3RyaWJ1dGlvbj1OT1JNQUwsIHNhbXBsZXMgYXJlIGRyYXduIGZyb20gYSB0cnVuY2F0ZWQgbm9ybWFsXG4gKiBkaXN0cmlidXRpb24gY2VudGVyZWQgb24gemVybywgd2l0aCBgc3RkZGV2ID0gc3FydChzY2FsZSAvIG4pYCB3aGVyZSBuIGlzOlxuICogICAtIG51bWJlciBvZiBpbnB1dCB1bml0cyBpbiB0aGUgd2VpZ2h0IHRlbnNvciwgaWYgbW9kZSA9IEZBTl9JTi5cbiAqICAgLSBudW1iZXIgb2Ygb3V0cHV0IHVuaXRzLCBpZiBtb2RlID0gRkFOX09VVC5cbiAqICAgLSBhdmVyYWdlIG9mIHRoZSBudW1iZXJzIG9mIGlucHV0IGFuZCBvdXRwdXQgdW5pdHMsIGlmIG1vZGUgPSBGQU5fQVZHLlxuICogV2l0aCBkaXN0cmlidXRpb249VU5JRk9STSxcbiAqIHNhbXBsZXMgYXJlIGRyYXduIGZyb20gYSB1bmlmb3JtIGRpc3RyaWJ1dGlvblxuICogd2l0aGluIFstbGltaXQsIGxpbWl0XSwgd2l0aCBgbGltaXQgPSBzcXJ0KDMgKiBzY2FsZSAvIG4pYC5cbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJyxuYW1lc3BhY2U6ICdpbml0aWFsaXplcnMnfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFyaWFuY2VTY2FsaW5nKGNvbmZpZzogVmFyaWFuY2VTY2FsaW5nQXJncyk6IEluaXRpYWxpemVyIHtcbiAgcmV0dXJuIG5ldyBWYXJpYW5jZVNjYWxpbmcoY29uZmlnKTtcbn1cblxuLyoqXG4gKiBHbG9yb3QgdW5pZm9ybSBpbml0aWFsaXplciwgYWxzbyBjYWxsZWQgWGF2aWVyIHVuaWZvcm0gaW5pdGlhbGl6ZXIuXG4gKiBJdCBkcmF3cyBzYW1wbGVzIGZyb20gYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiB3aXRoaW4gWy1saW1pdCwgbGltaXRdXG4gKiB3aGVyZSBgbGltaXRgIGlzIGBzcXJ0KDYgLyAoZmFuX2luICsgZmFuX291dCkpYFxuICogd2hlcmUgYGZhbl9pbmAgaXMgdGhlIG51bWJlciBvZiBpbnB1dCB1bml0cyBpbiB0aGUgd2VpZ2h0IHRlbnNvclxuICogYW5kIGBmYW5fb3V0YCBpcyB0aGUgbnVtYmVyIG9mIG91dHB1dCB1bml0cyBpbiB0aGUgd2VpZ2h0IHRlbnNvclxuICpcbiAqIFJlZmVyZW5jZTpcbiAqICAgR2xvcm90ICYgQmVuZ2lvLCBBSVNUQVRTIDIwMTBcbiAqICAgICAgIGh0dHA6Ly9qbWxyLm9yZy9wcm9jZWVkaW5ncy9wYXBlcnMvdjkvZ2xvcm90MTBhL2dsb3JvdDEwYS5wZGYuXG4gKlxuICogQGRvYyB7aGVhZGluZzogJ0luaXRpYWxpemVycycsIG5hbWVzcGFjZTogJ2luaXRpYWxpemVycyd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnbG9yb3RVbmlmb3JtKGFyZ3M6IFNlZWRPbmx5SW5pdGlhbGl6ZXJBcmdzKTogSW5pdGlhbGl6ZXIge1xuICByZXR1cm4gbmV3IEdsb3JvdFVuaWZvcm0oYXJncyk7XG59XG5cbi8qKlxuICogR2xvcm90IG5vcm1hbCBpbml0aWFsaXplciwgYWxzbyBjYWxsZWQgWGF2aWVyIG5vcm1hbCBpbml0aWFsaXplci5cbiAqIEl0IGRyYXdzIHNhbXBsZXMgZnJvbSBhIHRydW5jYXRlZCBub3JtYWwgZGlzdHJpYnV0aW9uIGNlbnRlcmVkIG9uIDBcbiAqIHdpdGggYHN0ZGRldiA9IHNxcnQoMiAvIChmYW5faW4gKyBmYW5fb3V0KSlgXG4gKiB3aGVyZSBgZmFuX2luYCBpcyB0aGUgbnVtYmVyIG9mIGlucHV0IHVuaXRzIGluIHRoZSB3ZWlnaHQgdGVuc29yXG4gKiBhbmQgYGZhbl9vdXRgIGlzIHRoZSBudW1iZXIgb2Ygb3V0cHV0IHVuaXRzIGluIHRoZSB3ZWlnaHQgdGVuc29yLlxuICpcbiAqIFJlZmVyZW5jZTpcbiAqICAgR2xvcm90ICYgQmVuZ2lvLCBBSVNUQVRTIDIwMTBcbiAqICAgICAgIGh0dHA6Ly9qbWxyLm9yZy9wcm9jZWVkaW5ncy9wYXBlcnMvdjkvZ2xvcm90MTBhL2dsb3JvdDEwYS5wZGZcbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJywgbmFtZXNwYWNlOiAnaW5pdGlhbGl6ZXJzJ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdsb3JvdE5vcm1hbChhcmdzOiBTZWVkT25seUluaXRpYWxpemVyQXJncyk6IEluaXRpYWxpemVyIHtcbiAgcmV0dXJuIG5ldyBHbG9yb3ROb3JtYWwoYXJncyk7XG59XG5cbi8qKlxuICogSGUgbm9ybWFsIGluaXRpYWxpemVyLlxuICpcbiAqIEl0IGRyYXdzIHNhbXBsZXMgZnJvbSBhIHRydW5jYXRlZCBub3JtYWwgZGlzdHJpYnV0aW9uIGNlbnRlcmVkIG9uIDBcbiAqIHdpdGggYHN0ZGRldiA9IHNxcnQoMiAvIGZhbkluKWBcbiAqIHdoZXJlIGBmYW5JbmAgaXMgdGhlIG51bWJlciBvZiBpbnB1dCB1bml0cyBpbiB0aGUgd2VpZ2h0IHRlbnNvci5cbiAqXG4gKiBSZWZlcmVuY2U6XG4gKiAgICAgSGUgZXQgYWwuLCBodHRwOi8vYXJ4aXYub3JnL2Ficy8xNTAyLjAxODUyXG4gKlxuICogQGRvYyB7aGVhZGluZzogJ0luaXRpYWxpemVycycsIG5hbWVzcGFjZTogJ2luaXRpYWxpemVycyd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoZU5vcm1hbChhcmdzOiBTZWVkT25seUluaXRpYWxpemVyQXJncyk6IEluaXRpYWxpemVyIHtcbiAgcmV0dXJuIG5ldyBIZU5vcm1hbChhcmdzKTtcbn1cblxuLyoqXG4gKiBIZSB1bmlmb3JtIGluaXRpYWxpemVyLlxuICpcbiAqIEl0IGRyYXdzIHNhbXBsZXMgZnJvbSBhIHVuaWZvcm0gZGlzdHJpYnV0aW9uIHdpdGhpbiBbLWxpbWl0LCBsaW1pdF1cbiAqIHdoZXJlIGBsaW1pdGAgaXMgYHNxcnQoNiAvIGZhbl9pbilgXG4gKiB3aGVyZSBgZmFuSW5gIGlzIHRoZSBudW1iZXIgb2YgaW5wdXQgdW5pdHMgaW4gdGhlIHdlaWdodCB0ZW5zb3IuXG4gKlxuICogUmVmZXJlbmNlOlxuICogICAgIEhlIGV0IGFsLiwgaHR0cDovL2FyeGl2Lm9yZy9hYnMvMTUwMi4wMTg1MlxuICpcbiAqIEBkb2Mge2hlYWRpbmc6ICdJbml0aWFsaXplcnMnLG5hbWVzcGFjZTogJ2luaXRpYWxpemVycyd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoZVVuaWZvcm0oYXJnczogU2VlZE9ubHlJbml0aWFsaXplckFyZ3MpOiBJbml0aWFsaXplciB7XG4gIHJldHVybiBuZXcgSGVVbmlmb3JtKGFyZ3MpO1xufVxuXG4vKipcbiAqIExlQ3VuIG5vcm1hbCBpbml0aWFsaXplci5cbiAqXG4gKiBJdCBkcmF3cyBzYW1wbGVzIGZyb20gYSB0cnVuY2F0ZWQgbm9ybWFsIGRpc3RyaWJ1dGlvbiBjZW50ZXJlZCBvbiAwXG4gKiB3aXRoIGBzdGRkZXYgPSBzcXJ0KDEgLyBmYW5JbilgXG4gKiB3aGVyZSBgZmFuSW5gIGlzIHRoZSBudW1iZXIgb2YgaW5wdXQgdW5pdHMgaW4gdGhlIHdlaWdodCB0ZW5zb3IuXG4gKlxuICogUmVmZXJlbmNlczpcbiAqICAgW1NlbGYtTm9ybWFsaXppbmcgTmV1cmFsIE5ldHdvcmtzXShodHRwczovL2FyeGl2Lm9yZy9hYnMvMTcwNi4wMjUxNSlcbiAqICAgW0VmZmljaWVudCBCYWNrcHJvcF0oaHR0cDovL3lhbm4ubGVjdW4uY29tL2V4ZGIvcHVibGlzL3BkZi9sZWN1bi05OGIucGRmKVxuICpcbiAqIEBkb2Mge2hlYWRpbmc6ICdJbml0aWFsaXplcnMnLCBuYW1lc3BhY2U6ICdpbml0aWFsaXplcnMnfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbGVDdW5Ob3JtYWwoYXJnczogU2VlZE9ubHlJbml0aWFsaXplckFyZ3MpOiBJbml0aWFsaXplciB7XG4gIHJldHVybiBuZXcgTGVDdW5Ob3JtYWwoYXJncyk7XG59XG5cbi8qKlxuICogTGVDdW4gdW5pZm9ybSBpbml0aWFsaXplci5cbiAqXG4gKiBJdCBkcmF3cyBzYW1wbGVzIGZyb20gYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBpbiB0aGUgaW50ZXJ2YWxcbiAqIGBbLWxpbWl0LCBsaW1pdF1gIHdpdGggYGxpbWl0ID0gc3FydCgzIC8gZmFuSW4pYCxcbiAqIHdoZXJlIGBmYW5JbmAgaXMgdGhlIG51bWJlciBvZiBpbnB1dCB1bml0cyBpbiB0aGUgd2VpZ2h0IHRlbnNvci5cbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJywgbmFtZXNwYWNlOiAnaW5pdGlhbGl6ZXJzJ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlQ3VuVW5pZm9ybShhcmdzOiBTZWVkT25seUluaXRpYWxpemVyQXJncyk6IEluaXRpYWxpemVyIHtcbiAgcmV0dXJuIG5ldyBMZUN1blVuaWZvcm0oYXJncyk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXIgdGhhdCBnZW5lcmF0ZXMgYSByYW5kb20gb3J0aG9nb25hbCBtYXRyaXguXG4gKlxuICogUmVmZXJlbmNlOlxuICogW1NheGUgZXQgYWwuLCBodHRwOi8vYXJ4aXYub3JnL2Ficy8xMzEyLjYxMjBdKGh0dHA6Ly9hcnhpdi5vcmcvYWJzLzEzMTIuNjEyMClcbiAqXG4gKiBAZG9jIHtoZWFkaW5nOiAnSW5pdGlhbGl6ZXJzJywgbmFtZXNwYWNlOiAnaW5pdGlhbGl6ZXJzJ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9ydGhvZ29uYWwoYXJnczogT3J0aG9nb25hbEFyZ3MpOiBJbml0aWFsaXplciB7XG4gIHJldHVybiBuZXcgT3J0aG9nb25hbChhcmdzKTtcbn1cbiJdfQ==