UNPKG

saij

Version:
245 lines (205 loc) 19.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.getChangeEventType = exports.ObjectEvent = void 0; var _ObjectEventType = _interopRequireDefault(require("./ObjectEventType.js")); var _Observable = _interopRequireDefault(require("./Observable.js")); var _Event = _interopRequireDefault(require("./Event.js")); var _object = require("./utils/object.js"); var _uid = require("./utils/uid.js"); /** * @module saij/core/Object */ /** * @classdesc * Events emitted by {@link module:saij/core/Object~BaseObject} instances are * instances of this type. */ class ObjectEvent extends _Event.default { /** * @param {string} type The event type. * @param {string} key The property name. * @param {*} oldValue The old value for `key`. */ constructor(type, key, oldValue) { super(type); /** * The name of the property whose value is changing. * @type {string} * @api */ this.key = key; /** * The old value. To get the new value use `e.target.get(e.key)` where * `e` is the event object. * @type {*} * @api */ this.oldValue = oldValue; } } /** * @type {Object<string, string>} */ exports.ObjectEvent = ObjectEvent; const changeEventTypeCache = {}; /** * @param {string} key Key name. * @return {string} Change name. */ // eslint-disable-next-line no-return-assign const getChangeEventType = key => changeEventTypeCache.hasOwnProperty(key) ? changeEventTypeCache[key] : changeEventTypeCache[key] = `change:${key}`; /** * @classdesc * Abstract base class; normally only used for creating subclasses and not * instantiated in apps. * Most non-trivial classes inherit from this. * * This extends {@link module:saij/core/Observable} with observable * properties, where each property is observable as well as the object as a * whole. * * Classes that inherit from this have pre-defined properties, to which you can * add your owns. The pre-defined properties are listed in this documentation as * 'Observable Properties', and have their own accessors; for example, * {@link module:saij/Engine~Engine} has a `target` property, accessed with * `getTarget()` and changed with `setTarget()`. Not all properties are however * settable. There are also general-purpose accessors `get()` and `set()`. For * example, `get('target')` is equivalent to `getTarget()`. * * The `set` accessors trigger a change event, and you can monitor this by * registering a listener. For example, {@link module:saij/Reactor~Reactor} has * an `input` property, so `reactor.on('change:input', function(evt) {...});` * would call the function whenever the value of the input property changes. * Within the function, `evt.target` would be the Reactor, so * `evt.target.getInput()` would return the new input. * * You can add your own observable properties with * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`. * You can listen for changes on that property value with * `object.on('change:prop', listener)`. You can get a list of all * properties with {@link module:saij/Object~BaseObject#getProperties}. * * Note that the observable properties are separate from standard JS properties. * You can, for example, give your map object a title with * `Engine.name='New name'` and with `Engine.set('title', 'Another title')`. The * first will be a `hasOwnProperty`; the second will appear in * `getProperties()`. Only the second is observable. * * Properties can be deleted by using the unset method. E.g. * object.unset('foo'). * * @fires module:saij/core/Object~ObjectEvent * @api */ exports.getChangeEventType = getChangeEventType; class BaseObject extends _Observable.default { /** * @param {Object<string, *>=} opt_values An object with key-value pairs. */ constructor(opt_values) { super(); // Call {@link module:ol/util~getUid} to ensure that the order of objects' // ids is the same as the order in which they were created. This also helps // to ensure that object properties are always added in the same order, // which helps many JavaScript engines generate faster code. (0, _uid.getUid)(this); /** * @private * @type {!Object<string, *>} */ this.values_ = {}; if (opt_values !== undefined) { this.setProperties(opt_values); } } /** * Gets a value. * @param {string} key Key name. * @return {*} Value. * @api */ get(key) { if (this.values_.hasOwnProperty(key)) { return this.values_[key]; } return; } /** * Get a list of object property names. * @return {Array<string>} List of property names. * @api */ getKeys() { return Object.keys(this.values_); } /** * Get an object of all property names and values. * @return {Object<string, *>} Object. * @api */ getProperties() { return (0, _object.assign)({}, this.values_); } /** * @param {string} key Key name. * @param {*} oldValue Old value. */ notify(key, oldValue) { let eventType = null; eventType = getChangeEventType(key); this.dispatchEvent(new ObjectEvent(eventType, key, oldValue)); eventType = _ObjectEventType.default.PROPERTYCHANGE; this.dispatchEvent(new ObjectEvent(eventType, key, oldValue)); } /** * Sets a value. * @param {string} key Key name. * @param {*} value Value. * @param {boolean=} opt_silent Update without triggering an event. * @api */ set(key, value, opt_silent) { if (opt_silent) { this.values_[key] = value; } else { const oldValue = this.values_[key]; this.values_[key] = value; if (oldValue !== value) { this.notify(key, oldValue); } } } /** * Sets a collection of key-value pairs. Note that this changes any existing * properties and adds new ones (it does not remove any existing properties). * @param {Object<string, *>} values Values. * @param {boolean=} opt_silent Update without triggering an event. * @api */ setProperties(values, opt_silent) { // eslint-disable-next-line guard-for-in for (const key in values) { this.set(key, values[key], opt_silent); } } /** * Unsets a property. * @param {string} key Key name. * @param {boolean=} opt_silent Unset without triggering an event. * @api */ unset(key, opt_silent) { if (key in this.values_) { const oldValue = this.values_[key]; Reflect.deleteProperty(this.values_, key); if (!opt_silent) { this.notify(key, oldValue); } } } } var _default = BaseObject; exports.default = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zYWlqL2NvcmUvT2JqZWN0LmpzIl0sIm5hbWVzIjpbIk9iamVjdEV2ZW50IiwiRXZlbnQiLCJjb25zdHJ1Y3RvciIsInR5cGUiLCJrZXkiLCJvbGRWYWx1ZSIsImNoYW5nZUV2ZW50VHlwZUNhY2hlIiwiZ2V0Q2hhbmdlRXZlbnRUeXBlIiwiaGFzT3duUHJvcGVydHkiLCJCYXNlT2JqZWN0IiwiT2JzZXJ2YWJsZSIsIm9wdF92YWx1ZXMiLCJ2YWx1ZXNfIiwidW5kZWZpbmVkIiwic2V0UHJvcGVydGllcyIsImdldCIsImdldEtleXMiLCJPYmplY3QiLCJrZXlzIiwiZ2V0UHJvcGVydGllcyIsIm5vdGlmeSIsImV2ZW50VHlwZSIsImRpc3BhdGNoRXZlbnQiLCJPYmplY3RFdmVudFR5cGUiLCJQUk9QRVJUWUNIQU5HRSIsInNldCIsInZhbHVlIiwib3B0X3NpbGVudCIsInZhbHVlcyIsInVuc2V0IiwiUmVmbGVjdCIsImRlbGV0ZVByb3BlcnR5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFHQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFQQTs7OztBQVVBOzs7OztBQUtPLE1BQU1BLFdBQU4sU0FBMEJDLGNBQTFCLENBQWdDO0FBRXJDOzs7OztBQUtBQyxFQUFBQSxXQUFXLENBQUNDLElBQUQsRUFBT0MsR0FBUCxFQUFZQyxRQUFaLEVBQXNCO0FBQy9CLFVBQU1GLElBQU47QUFFQTs7Ozs7O0FBS0EsU0FBS0MsR0FBTCxHQUFXQSxHQUFYO0FBRUE7Ozs7Ozs7QUFNQSxTQUFLQyxRQUFMLEdBQWdCQSxRQUFoQjtBQUNEOztBQXhCb0M7QUE0QnZDOzs7Ozs7QUFHQSxNQUFNQyxvQkFBb0IsR0FBRyxFQUE3QjtBQUdBOzs7O0FBSUE7O0FBQ08sTUFBTUMsa0JBQWtCLEdBQUlILEdBQUQsSUFDaENFLG9CQUFvQixDQUFDRSxjQUFyQixDQUFvQ0osR0FBcEMsSUFDRUUsb0JBQW9CLENBQUNGLEdBQUQsQ0FEdEIsR0FFR0Usb0JBQW9CLENBQUNGLEdBQUQsQ0FBcEIsR0FBNkIsVUFBU0EsR0FBSSxFQUh4QztBQU9QOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJDQSxNQUFNSyxVQUFOLFNBQXlCQyxtQkFBekIsQ0FBb0M7QUFFbEM7OztBQUdBUixFQUFBQSxXQUFXLENBQUNTLFVBQUQsRUFBYTtBQUN0QixZQURzQixDQUd0QjtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxxQkFBTyxJQUFQO0FBRUE7Ozs7O0FBSUEsU0FBS0MsT0FBTCxHQUFlLEVBQWY7O0FBRUEsUUFBSUQsVUFBVSxLQUFLRSxTQUFuQixFQUE4QjtBQUM1QixXQUFLQyxhQUFMLENBQW1CSCxVQUFuQjtBQUNEO0FBQ0Y7QUFFRDs7Ozs7Ozs7QUFNQUksRUFBQUEsR0FBRyxDQUFDWCxHQUFELEVBQU07QUFDUCxRQUFJLEtBQUtRLE9BQUwsQ0FBYUosY0FBYixDQUE0QkosR0FBNUIsQ0FBSixFQUFzQztBQUNwQyxhQUFPLEtBQUtRLE9BQUwsQ0FBYVIsR0FBYixDQUFQO0FBQ0Q7O0FBQ0Q7QUFDRDtBQUVEOzs7Ozs7O0FBS0FZLEVBQUFBLE9BQU8sR0FBRztBQUNSLFdBQU9DLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZLEtBQUtOLE9BQWpCLENBQVA7QUFDRDtBQUVEOzs7Ozs7O0FBS0FPLEVBQUFBLGFBQWEsR0FBRztBQUNkLFdBQU8sb0JBQU8sRUFBUCxFQUFXLEtBQUtQLE9BQWhCLENBQVA7QUFDRDtBQUVEOzs7Ozs7QUFJQVEsRUFBQUEsTUFBTSxDQUFDaEIsR0FBRCxFQUFNQyxRQUFOLEVBQWdCO0FBQ3BCLFFBQUlnQixTQUFTLEdBQUcsSUFBaEI7QUFDQUEsSUFBQUEsU0FBUyxHQUFHZCxrQkFBa0IsQ0FBQ0gsR0FBRCxDQUE5QjtBQUNBLFNBQUtrQixhQUFMLENBQW1CLElBQUl0QixXQUFKLENBQWdCcUIsU0FBaEIsRUFBMkJqQixHQUEzQixFQUFnQ0MsUUFBaEMsQ0FBbkI7QUFDQWdCLElBQUFBLFNBQVMsR0FBR0UseUJBQWdCQyxjQUE1QjtBQUNBLFNBQUtGLGFBQUwsQ0FBbUIsSUFBSXRCLFdBQUosQ0FBZ0JxQixTQUFoQixFQUEyQmpCLEdBQTNCLEVBQWdDQyxRQUFoQyxDQUFuQjtBQUNEO0FBRUQ7Ozs7Ozs7OztBQU9Bb0IsRUFBQUEsR0FBRyxDQUFDckIsR0FBRCxFQUFNc0IsS0FBTixFQUFhQyxVQUFiLEVBQXlCO0FBQzFCLFFBQUlBLFVBQUosRUFBZ0I7QUFDZCxXQUFLZixPQUFMLENBQWFSLEdBQWIsSUFBb0JzQixLQUFwQjtBQUNELEtBRkQsTUFFTztBQUNMLFlBQU1yQixRQUFRLEdBQUcsS0FBS08sT0FBTCxDQUFhUixHQUFiLENBQWpCO0FBQ0EsV0FBS1EsT0FBTCxDQUFhUixHQUFiLElBQW9Cc0IsS0FBcEI7O0FBQ0EsVUFBSXJCLFFBQVEsS0FBS3FCLEtBQWpCLEVBQXdCO0FBQ3RCLGFBQUtOLE1BQUwsQ0FBWWhCLEdBQVosRUFBaUJDLFFBQWpCO0FBQ0Q7QUFDRjtBQUNGO0FBRUQ7Ozs7Ozs7OztBQU9BUyxFQUFBQSxhQUFhLENBQUNjLE1BQUQsRUFBU0QsVUFBVCxFQUFxQjtBQUNoQztBQUNBLFNBQUssTUFBTXZCLEdBQVgsSUFBa0J3QixNQUFsQixFQUEwQjtBQUN4QixXQUFLSCxHQUFMLENBQVNyQixHQUFULEVBQWN3QixNQUFNLENBQUN4QixHQUFELENBQXBCLEVBQTJCdUIsVUFBM0I7QUFDRDtBQUNGO0FBRUQ7Ozs7Ozs7O0FBTUFFLEVBQUFBLEtBQUssQ0FBQ3pCLEdBQUQsRUFBTXVCLFVBQU4sRUFBa0I7QUFDckIsUUFBSXZCLEdBQUcsSUFBSSxLQUFLUSxPQUFoQixFQUF5QjtBQUN2QixZQUFNUCxRQUFRLEdBQUcsS0FBS08sT0FBTCxDQUFhUixHQUFiLENBQWpCO0FBQ0EwQixNQUFBQSxPQUFPLENBQUNDLGNBQVIsQ0FBdUIsS0FBS25CLE9BQTVCLEVBQXFDUixHQUFyQzs7QUFDQSxVQUFJLENBQUN1QixVQUFMLEVBQWlCO0FBQ2YsYUFBS1AsTUFBTCxDQUFZaEIsR0FBWixFQUFpQkMsUUFBakI7QUFDRDtBQUNGO0FBQ0Y7O0FBbkhpQzs7ZUF1SHJCSSxVIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIHNhaWovY29yZS9PYmplY3RcbiAqL1xuaW1wb3J0IE9iamVjdEV2ZW50VHlwZSBmcm9tICcuL09iamVjdEV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgT2JzZXJ2YWJsZSBmcm9tICcuL09ic2VydmFibGUuanMnO1xuaW1wb3J0IEV2ZW50IGZyb20gJy4vRXZlbnQuanMnO1xuaW1wb3J0IHthc3NpZ259IGZyb20gJy4vdXRpbHMvb2JqZWN0LmpzJztcbmltcG9ydCB7Z2V0VWlkfSBmcm9tICcuL3V0aWxzL3VpZC5qcyc7XG5cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBieSB7QGxpbmsgbW9kdWxlOnNhaWovY29yZS9PYmplY3R+QmFzZU9iamVjdH0gaW5zdGFuY2VzIGFyZVxuICogaW5zdGFuY2VzIG9mIHRoaXMgdHlwZS5cbiAgKi9cbmV4cG9ydCBjbGFzcyBPYmplY3RFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHByb3BlcnR5IG5hbWUuXG4gICAqIEBwYXJhbSB7Kn0gb2xkVmFsdWUgVGhlIG9sZCB2YWx1ZSBmb3IgYGtleWAuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih0eXBlLCBrZXksIG9sZFZhbHVlKSB7XG4gICAgc3VwZXIodHlwZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgd2hvc2UgdmFsdWUgaXMgY2hhbmdpbmcuXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAYXBpXG4gICAgICovXG4gICAgdGhpcy5rZXkgPSBrZXk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2xkIHZhbHVlLiBUbyBnZXQgdGhlIG5ldyB2YWx1ZSB1c2UgYGUudGFyZ2V0LmdldChlLmtleSlgIHdoZXJlXG4gICAgICogYGVgIGlzIHRoZSBldmVudCBvYmplY3QuXG4gICAgICogQHR5cGUgeyp9XG4gICAgICogQGFwaVxuICAgICAqL1xuICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgfVxufVxuXG5cbi8qKlxuICogQHR5cGUge09iamVjdDxzdHJpbmcsIHN0cmluZz59XG4gKi9cbmNvbnN0IGNoYW5nZUV2ZW50VHlwZUNhY2hlID0ge307XG5cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleSBuYW1lLlxuICogQHJldHVybiB7c3RyaW5nfSBDaGFuZ2UgbmFtZS5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJldHVybi1hc3NpZ25cbmV4cG9ydCBjb25zdCBnZXRDaGFuZ2VFdmVudFR5cGUgPSAoa2V5KT0+IChcbiAgY2hhbmdlRXZlbnRUeXBlQ2FjaGUuaGFzT3duUHJvcGVydHkoa2V5KSA/XG4gICAgY2hhbmdlRXZlbnRUeXBlQ2FjaGVba2V5XSA6XG4gICAgKGNoYW5nZUV2ZW50VHlwZUNhY2hlW2tleV0gPSBgY2hhbmdlOiR7a2V5fWApXG4pO1xuXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogTW9zdCBub24tdHJpdmlhbCBjbGFzc2VzIGluaGVyaXQgZnJvbSB0aGlzLlxuICpcbiAqIFRoaXMgZXh0ZW5kcyB7QGxpbmsgbW9kdWxlOnNhaWovY29yZS9PYnNlcnZhYmxlfSB3aXRoIG9ic2VydmFibGVcbiAqIHByb3BlcnRpZXMsIHdoZXJlIGVhY2ggcHJvcGVydHkgaXMgb2JzZXJ2YWJsZSBhcyB3ZWxsIGFzIHRoZSBvYmplY3QgYXMgYVxuICogd2hvbGUuXG4gKlxuICogQ2xhc3NlcyB0aGF0IGluaGVyaXQgZnJvbSB0aGlzIGhhdmUgcHJlLWRlZmluZWQgcHJvcGVydGllcywgdG8gd2hpY2ggeW91IGNhblxuICogYWRkIHlvdXIgb3ducy4gVGhlIHByZS1kZWZpbmVkIHByb3BlcnRpZXMgYXJlIGxpc3RlZCBpbiB0aGlzIGRvY3VtZW50YXRpb24gYXNcbiAqICdPYnNlcnZhYmxlIFByb3BlcnRpZXMnLCBhbmQgaGF2ZSB0aGVpciBvd24gYWNjZXNzb3JzOyBmb3IgZXhhbXBsZSxcbiAqIHtAbGluayBtb2R1bGU6c2Fpai9FbmdpbmV+RW5naW5lfSBoYXMgYSBgdGFyZ2V0YCBwcm9wZXJ0eSwgYWNjZXNzZWQgd2l0aFxuICogYGdldFRhcmdldCgpYCBhbmQgY2hhbmdlZCB3aXRoIGBzZXRUYXJnZXQoKWAuIE5vdCBhbGwgcHJvcGVydGllcyBhcmUgaG93ZXZlclxuICogc2V0dGFibGUuIFRoZXJlIGFyZSBhbHNvIGdlbmVyYWwtcHVycG9zZSBhY2Nlc3NvcnMgYGdldCgpYCBhbmQgYHNldCgpYC4gRm9yXG4gKiBleGFtcGxlLCBgZ2V0KCd0YXJnZXQnKWAgaXMgZXF1aXZhbGVudCB0byBgZ2V0VGFyZ2V0KClgLlxuICpcbiAqIFRoZSBgc2V0YCBhY2Nlc3NvcnMgdHJpZ2dlciBhIGNoYW5nZSBldmVudCwgYW5kIHlvdSBjYW4gbW9uaXRvciB0aGlzIGJ5XG4gKiByZWdpc3RlcmluZyBhIGxpc3RlbmVyLiBGb3IgZXhhbXBsZSwge0BsaW5rIG1vZHVsZTpzYWlqL1JlYWN0b3J+UmVhY3Rvcn0gaGFzXG4gKiBhbiBgaW5wdXRgIHByb3BlcnR5LCBzbyBgcmVhY3Rvci5vbignY2hhbmdlOmlucHV0JywgZnVuY3Rpb24oZXZ0KSB7Li4ufSk7YFxuICogd291bGQgY2FsbCB0aGUgZnVuY3Rpb24gd2hlbmV2ZXIgdGhlIHZhbHVlIG9mIHRoZSBpbnB1dCBwcm9wZXJ0eSBjaGFuZ2VzLlxuICogV2l0aGluIHRoZSBmdW5jdGlvbiwgYGV2dC50YXJnZXRgIHdvdWxkIGJlIHRoZSBSZWFjdG9yLCBzb1xuICogYGV2dC50YXJnZXQuZ2V0SW5wdXQoKWAgd291bGQgcmV0dXJuIHRoZSBuZXcgaW5wdXQuXG4gKlxuICogWW91IGNhbiBhZGQgeW91ciBvd24gb2JzZXJ2YWJsZSBwcm9wZXJ0aWVzIHdpdGhcbiAqIGBvYmplY3Quc2V0KCdwcm9wJywgJ3ZhbHVlJylgLCBhbmQgcmV0cmlldmUgdGhhdCB3aXRoIGBvYmplY3QuZ2V0KCdwcm9wJylgLlxuICogWW91IGNhbiBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhhdCBwcm9wZXJ0eSB2YWx1ZSB3aXRoXG4gKiBgb2JqZWN0Lm9uKCdjaGFuZ2U6cHJvcCcsIGxpc3RlbmVyKWAuIFlvdSBjYW4gZ2V0IGEgbGlzdCBvZiBhbGxcbiAqIHByb3BlcnRpZXMgd2l0aCB7QGxpbmsgbW9kdWxlOnNhaWovT2JqZWN0fkJhc2VPYmplY3QjZ2V0UHJvcGVydGllc30uXG4gKlxuICogTm90ZSB0aGF0IHRoZSBvYnNlcnZhYmxlIHByb3BlcnRpZXMgYXJlIHNlcGFyYXRlIGZyb20gc3RhbmRhcmQgSlMgcHJvcGVydGllcy5cbiAqIFlvdSBjYW4sIGZvciBleGFtcGxlLCBnaXZlIHlvdXIgbWFwIG9iamVjdCBhIHRpdGxlIHdpdGhcbiAqIGBFbmdpbmUubmFtZT0nTmV3IG5hbWUnYCBhbmQgd2l0aCBgRW5naW5lLnNldCgndGl0bGUnLCAnQW5vdGhlciB0aXRsZScpYC4gVGhlXG4gKiBmaXJzdCB3aWxsIGJlIGEgYGhhc093blByb3BlcnR5YDsgdGhlIHNlY29uZCB3aWxsIGFwcGVhciBpblxuICogYGdldFByb3BlcnRpZXMoKWAuIE9ubHkgdGhlIHNlY29uZCBpcyBvYnNlcnZhYmxlLlxuICpcbiAqIFByb3BlcnRpZXMgY2FuIGJlIGRlbGV0ZWQgYnkgdXNpbmcgdGhlIHVuc2V0IG1ldGhvZC4gRS5nLlxuICogb2JqZWN0LnVuc2V0KCdmb28nKS5cbiAqXG4gKiBAZmlyZXMgbW9kdWxlOnNhaWovY29yZS9PYmplY3R+T2JqZWN0RXZlbnRcbiAqIEBhcGlcbiAqL1xuY2xhc3MgQmFzZU9iamVjdCBleHRlbmRzIE9ic2VydmFibGUge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsICo+PX0gb3B0X3ZhbHVlcyBBbiBvYmplY3Qgd2l0aCBrZXktdmFsdWUgcGFpcnMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRfdmFsdWVzKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIC8vIENhbGwge0BsaW5rIG1vZHVsZTpvbC91dGlsfmdldFVpZH0gdG8gZW5zdXJlIHRoYXQgdGhlIG9yZGVyIG9mIG9iamVjdHMnXG4gICAgLy8gaWRzIGlzIHRoZSBzYW1lIGFzIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IHdlcmUgY3JlYXRlZC4gIFRoaXMgYWxzbyBoZWxwc1xuICAgIC8vIHRvIGVuc3VyZSB0aGF0IG9iamVjdCBwcm9wZXJ0aWVzIGFyZSBhbHdheXMgYWRkZWQgaW4gdGhlIHNhbWUgb3JkZXIsXG4gICAgLy8gd2hpY2ggaGVscHMgbWFueSBKYXZhU2NyaXB0IGVuZ2luZXMgZ2VuZXJhdGUgZmFzdGVyIGNvZGUuXG4gICAgZ2V0VWlkKHRoaXMpO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsICo+fVxuICAgICAqL1xuICAgIHRoaXMudmFsdWVzXyA9IHt9O1xuXG4gICAgaWYgKG9wdF92YWx1ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXRQcm9wZXJ0aWVzKG9wdF92YWx1ZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgdmFsdWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5IG5hbWUuXG4gICAqIEByZXR1cm4geyp9IFZhbHVlLlxuICAgKiBAYXBpXG4gICAqL1xuICBnZXQoa2V5KSB7XG4gICAgaWYgKHRoaXMudmFsdWVzXy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNfW2tleV07XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBsaXN0IG9mIG9iamVjdCBwcm9wZXJ0eSBuYW1lcy5cbiAgICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gTGlzdCBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICogQGFwaVxuICAgKi9cbiAgZ2V0S2V5cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy52YWx1ZXNfKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYW4gb2JqZWN0IG9mIGFsbCBwcm9wZXJ0eSBuYW1lcyBhbmQgdmFsdWVzLlxuICAgKiBAcmV0dXJuIHtPYmplY3Q8c3RyaW5nLCAqPn0gT2JqZWN0LlxuICAgKiBAYXBpXG4gICAqL1xuICBnZXRQcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiBhc3NpZ24oe30sIHRoaXMudmFsdWVzXyk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgbmFtZS5cbiAgICogQHBhcmFtIHsqfSBvbGRWYWx1ZSBPbGQgdmFsdWUuXG4gICAqL1xuICBub3RpZnkoa2V5LCBvbGRWYWx1ZSkge1xuICAgIGxldCBldmVudFR5cGUgPSBudWxsO1xuICAgIGV2ZW50VHlwZSA9IGdldENoYW5nZUV2ZW50VHlwZShrZXkpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgT2JqZWN0RXZlbnQoZXZlbnRUeXBlLCBrZXksIG9sZFZhbHVlKSk7XG4gICAgZXZlbnRUeXBlID0gT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgT2JqZWN0RXZlbnQoZXZlbnRUeXBlLCBrZXksIG9sZFZhbHVlKSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIHZhbHVlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleSBuYW1lLlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc2lsZW50IFVwZGF0ZSB3aXRob3V0IHRyaWdnZXJpbmcgYW4gZXZlbnQuXG4gICAqIEBhcGlcbiAgICovXG4gIHNldChrZXksIHZhbHVlLCBvcHRfc2lsZW50KSB7XG4gICAgaWYgKG9wdF9zaWxlbnQpIHtcbiAgICAgIHRoaXMudmFsdWVzX1trZXldID0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy52YWx1ZXNfW2tleV07XG4gICAgICB0aGlzLnZhbHVlc19ba2V5XSA9IHZhbHVlO1xuICAgICAgaWYgKG9sZFZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgICB0aGlzLm5vdGlmeShrZXksIG9sZFZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIGNvbGxlY3Rpb24gb2Yga2V5LXZhbHVlIHBhaXJzLiAgTm90ZSB0aGF0IHRoaXMgY2hhbmdlcyBhbnkgZXhpc3RpbmdcbiAgICogcHJvcGVydGllcyBhbmQgYWRkcyBuZXcgb25lcyAoaXQgZG9lcyBub3QgcmVtb3ZlIGFueSBleGlzdGluZyBwcm9wZXJ0aWVzKS5cbiAgICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCAqPn0gdmFsdWVzIFZhbHVlcy5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3NpbGVudCBVcGRhdGUgd2l0aG91dCB0cmlnZ2VyaW5nIGFuIGV2ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuICBzZXRQcm9wZXJ0aWVzKHZhbHVlcywgb3B0X3NpbGVudCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBndWFyZC1mb3ItaW5cbiAgICBmb3IgKGNvbnN0IGtleSBpbiB2YWx1ZXMpIHtcbiAgICAgIHRoaXMuc2V0KGtleSwgdmFsdWVzW2tleV0sIG9wdF9zaWxlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbnNldHMgYSBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgbmFtZS5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3NpbGVudCBVbnNldCB3aXRob3V0IHRyaWdnZXJpbmcgYW4gZXZlbnQuXG4gICAqIEBhcGlcbiAgICovXG4gIHVuc2V0KGtleSwgb3B0X3NpbGVudCkge1xuICAgIGlmIChrZXkgaW4gdGhpcy52YWx1ZXNfKSB7XG4gICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMudmFsdWVzX1trZXldO1xuICAgICAgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0aGlzLnZhbHVlc18sIGtleSk7XG4gICAgICBpZiAoIW9wdF9zaWxlbnQpIHtcbiAgICAgICAgdGhpcy5ub3RpZnkoa2V5LCBvbGRWYWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cblxuZXhwb3J0IGRlZmF1bHQgQmFzZU9iamVjdDtcbiJdfQ==