Skip to content

Instantly share code, notes, and snippets.

@youngzhao-xyz
Last active August 18, 2017 23:51
Show Gist options
  • Save youngzhao-xyz/9e7a7bc2ab47f82dd97ecf478c2e67ed to your computer and use it in GitHub Desktop.
Save youngzhao-xyz/9e7a7bc2ab47f82dd97ecf478c2e67ed to your computer and use it in GitHub Desktop.
requirebin sketch
const { normalize, schema } = require('normalizr');
const data = [
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
},
{
"id": "124",
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
},
{
"id": "125",
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
},
{
"id": "126",
"comments": null
},
{
"id": "127",
"title": "My awesome blog post",
"comments": []
}
];
// Define a users schema
const user = new schema.Entity('users');
// Define your comments schema
const comment = new schema.Entity('comments', {
commenter: user
});
// Define your article
const article = new schema.Entity('articles', {
author: user,
comments: [ comment ]
});
const normalizedData = normalize(data, [article]);
console.log(normalizedData);
setTimeout(function(){
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.denormalize = exports.normalize = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _Polymorphic = require('./Polymorphic');
var _Polymorphic2 = _interopRequireDefault(_Polymorphic);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var validateSchema = function validateSchema(definition) {
var isArray = Array.isArray(definition);
if (isArray && definition.length > 1) {
throw new Error('Expected schema definition to be a single schema, but found ' + definition.length + '.');
}
return definition[0];
};
var getValues = function getValues(input) {
return Array.isArray(input) ? input : Object.keys(input).map(function (key) {
return input[key];
});
};
var normalize = exports.normalize = function normalize(schema, input, parent, key, visit, addEntity) {
schema = validateSchema(schema);
var values = getValues(input);
// Special case: Arrays pass *their* parent on to their children, since there
// is not any special information that can be gathered from themselves directly
return values.map(function (value, index) {
return visit(value, parent, key, schema, addEntity);
});
};
var denormalize = exports.denormalize = function denormalize(schema, input, unvisit, getDenormalizedEntity) {
schema = validateSchema(schema);
return Array.isArray(input) ? input.map(function (entityOrId) {
return unvisit(entityOrId, schema, getDenormalizedEntity);
}) : input;
};
var ArraySchema = function (_PolymorphicSchema) {
_inherits(ArraySchema, _PolymorphicSchema);
function ArraySchema() {
_classCallCheck(this, ArraySchema);
return _possibleConstructorReturn(this, (ArraySchema.__proto__ || Object.getPrototypeOf(ArraySchema)).apply(this, arguments));
}
_createClass(ArraySchema, [{
key: 'normalize',
value: function normalize(input, parent, key, visit, addEntity) {
var _this2 = this;
var values = getValues(input);
return values.map(function (value, index) {
return _this2.normalizeValue(value, parent, key, visit, addEntity);
}).filter(function (value) {
return value !== undefined && value !== null;
});
}
}, {
key: 'denormalize',
value: function denormalize(input, unvisit, getDenormalizedEntity) {
var _this3 = this;
return Array.isArray(input) ? input.map(function (value) {
return _this3.denormalizeValue(value, unvisit, getDenormalizedEntity);
}) : input;
}
}]);
return ArraySchema;
}(_Polymorphic2.default);
exports.default = ArraySchema;
},{"./Polymorphic":5}],2:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _ImmutableUtils = require('./ImmutableUtils');
var ImmutableUtils = _interopRequireWildcard(_ImmutableUtils);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var getDefaultGetId = function getDefaultGetId(idAttribute) {
return function (input) {
return ImmutableUtils.isImmutable(input) ? input.get(idAttribute) : input[idAttribute];
};
};
var EntitySchema = function () {
function EntitySchema(key) {
var definition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
_classCallCheck(this, EntitySchema);
if (!key || typeof key !== 'string') {
throw new Error('Expected a string key for Entity, but found ' + key + '.');
}
var _options$idAttribute = options.idAttribute,
idAttribute = _options$idAttribute === undefined ? 'id' : _options$idAttribute,
_options$mergeStrateg = options.mergeStrategy,
mergeStrategy = _options$mergeStrateg === undefined ? function (entityA, entityB) {
return _extends({}, entityA, entityB);
} : _options$mergeStrateg,
_options$processStrat = options.processStrategy,
processStrategy = _options$processStrat === undefined ? function (input) {
return _extends({}, input);
} : _options$processStrat;
this._key = key;
this._getId = typeof idAttribute === 'function' ? idAttribute : getDefaultGetId(idAttribute);
this._idAttribute = idAttribute;
this._mergeStrategy = mergeStrategy;
this._processStrategy = processStrategy;
this.define(definition);
}
_createClass(EntitySchema, [{
key: 'define',
value: function define(definition) {
this.schema = Object.keys(definition).reduce(function (entitySchema, key) {
var schema = definition[key];
return _extends({}, entitySchema, _defineProperty({}, key, schema));
}, this.schema || {});
}
}, {
key: 'getId',
value: function getId(input, parent, key) {
return this._getId(input, parent, key);
}
}, {
key: 'merge',
value: function merge(entityA, entityB) {
return this._mergeStrategy(entityA, entityB);
}
}, {
key: 'normalize',
value: function normalize(input, parent, key, visit, addEntity) {
var _this = this;
var processedEntity = this._processStrategy(input, parent, key);
Object.keys(this.schema).forEach(function (key) {
if (processedEntity.hasOwnProperty(key) && _typeof(processedEntity[key]) === 'object') {
var schema = _this.schema[key];
processedEntity[key] = visit(processedEntity[key], processedEntity, key, schema, addEntity);
}
});
addEntity(this, processedEntity, input, parent, key);
return this.getId(input, parent, key);
}
}, {
key: 'denormalize',
value: function denormalize(entityOrId, unvisit, getDenormalizedEntity) {
var _this2 = this;
var entity = getDenormalizedEntity(this, entityOrId);
if ((typeof entity === 'undefined' ? 'undefined' : _typeof(entity)) !== 'object' || entity === null) {
return entity;
}
if (ImmutableUtils.isImmutable(entity)) {
return ImmutableUtils.denormalizeImmutable(this.schema, entity, unvisit, getDenormalizedEntity);
}
var processedEntity = _extends({}, entity);
Object.keys(this.schema).forEach(function (key) {
if (processedEntity.hasOwnProperty(key)) {
var schema = _this2.schema[key];
processedEntity[key] = unvisit(processedEntity[key], schema, getDenormalizedEntity);
}
});
return processedEntity;
}
}, {
key: 'key',
get: function get() {
return this._key;
}
}, {
key: 'idAttribute',
get: function get() {
return this._idAttribute;
}
}]);
return EntitySchema;
}();
exports.default = EntitySchema;
},{"./ImmutableUtils":3}],3:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isImmutable = isImmutable;
exports.denormalizeImmutable = denormalizeImmutable;
/**
* Helpers to enable Immutable compatibility *without* bringing in
* the 'immutable' package as a dependency.
*/
/**
* Check if an object is immutable by checking if it has a key specific
* to the immutable library.
*
* @param {any} object
* @return {bool}
*/
function isImmutable(object) {
return !!(object && (object.hasOwnProperty('__ownerID') || // Immutable.Map
object._map && object._map.hasOwnProperty('__ownerID') // Immutable.Record
));
}
/**
* Denormalize an immutable entity.
*
* @param {Schema} schema
* @param {Immutable.Map|Immutable.Record} input
* @param {function} unvisit
* @param {function} getDenormalizedEntity
* @return {Immutable.Map|Immutable.Record}
*/
function denormalizeImmutable(schema, input, unvisit, getDenormalizedEntity) {
return Object.keys(schema).reduce(function (object, key) {
// Immutable maps cast keys to strings on write so we need to ensure
// we're accessing them using string keys.
var stringKey = '' + key;
if (object.has(stringKey)) {
return object.set(stringKey, unvisit(object.get(stringKey), schema[stringKey], getDenormalizedEntity));
} else {
return object;
}
}, input);
}
},{}],4:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.denormalize = exports.normalize = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _ImmutableUtils = require('./ImmutableUtils');
var ImmutableUtils = _interopRequireWildcard(_ImmutableUtils);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _normalize = function _normalize(schema, input, parent, key, visit, addEntity) {
var object = _extends({}, input);
Object.keys(schema).forEach(function (key) {
var localSchema = schema[key];
var value = visit(input[key], input, key, localSchema, addEntity);
if (value === undefined || value === null) {
delete object[key];
} else {
object[key] = value;
}
});
return object;
};
exports.normalize = _normalize;
var _denormalize = function _denormalize(schema, input, unvisit, getDenormalizedEntity) {
if (ImmutableUtils.isImmutable(input)) {
return ImmutableUtils.denormalizeImmutable(schema, input, unvisit, getDenormalizedEntity);
}
var object = _extends({}, input);
Object.keys(schema).forEach(function (key) {
if (object[key]) {
object[key] = unvisit(object[key], schema[key], getDenormalizedEntity);
}
});
return object;
};
exports.denormalize = _denormalize;
var ObjectSchema = function () {
function ObjectSchema(definition) {
_classCallCheck(this, ObjectSchema);
this.define(definition);
}
_createClass(ObjectSchema, [{
key: 'define',
value: function define(definition) {
this.schema = Object.keys(definition).reduce(function (entitySchema, key) {
var schema = definition[key];
return _extends({}, entitySchema, _defineProperty({}, key, schema));
}, this.schema || {});
}
}, {
key: 'normalize',
value: function normalize() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _normalize.apply(undefined, [this.schema].concat(args));
}
}, {
key: 'denormalize',
value: function denormalize() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return _denormalize.apply(undefined, [this.schema].concat(args));
}
}]);
return ObjectSchema;
}();
exports.default = ObjectSchema;
},{"./ImmutableUtils":3}],5:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var PolymorphicSchema = function () {
function PolymorphicSchema(definition, schemaAttribute) {
_classCallCheck(this, PolymorphicSchema);
if (schemaAttribute) {
this._schemaAttribute = typeof schemaAttribute === 'string' ? function (input) {
return input[schemaAttribute];
} : schemaAttribute;
}
this.define(definition);
}
_createClass(PolymorphicSchema, [{
key: 'define',
value: function define(definition) {
this.schema = definition;
}
}, {
key: 'getSchemaAttribute',
value: function getSchemaAttribute(input, parent, key) {
return !this.isSingleSchema && this._schemaAttribute(input, parent, key);
}
}, {
key: 'inferSchema',
value: function inferSchema(input, parent, key) {
if (this.isSingleSchema) {
return this.schema;
}
var attr = this.getSchemaAttribute(input, parent, key);
return this.schema[attr];
}
}, {
key: 'normalizeValue',
value: function normalizeValue(value, parent, key, visit, addEntity) {
var schema = this.inferSchema(value, parent, key);
if (!schema) {
return value;
}
var normalizedValue = visit(value, parent, key, schema, addEntity);
return this.isSingleSchema || normalizedValue === undefined || normalizedValue === null ? normalizedValue : { id: normalizedValue, schema: this.getSchemaAttribute(value, parent, key) };
}
}, {
key: 'denormalizeValue',
value: function denormalizeValue(value, unvisit, getDenormalizedEntity) {
if (!this.isSingleSchema && !value.schema) {
return value;
}
var schema = this.isSingleSchema ? this.schema : this.schema[value.schema];
return unvisit(value.id || value, schema, getDenormalizedEntity);
}
}, {
key: 'isSingleSchema',
get: function get() {
return !this._schemaAttribute;
}
}]);
return PolymorphicSchema;
}();
exports.default = PolymorphicSchema;
},{}],6:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _Polymorphic = require('./Polymorphic');
var _Polymorphic2 = _interopRequireDefault(_Polymorphic);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var UnionSchema = function (_PolymorphicSchema) {
_inherits(UnionSchema, _PolymorphicSchema);
function UnionSchema(definition, schemaAttribute) {
_classCallCheck(this, UnionSchema);
if (!schemaAttribute) {
throw new Error('Expected option "schemaAttribute" not found on UnionSchema.');
}
return _possibleConstructorReturn(this, (UnionSchema.__proto__ || Object.getPrototypeOf(UnionSchema)).call(this, definition, schemaAttribute));
}
_createClass(UnionSchema, [{
key: 'normalize',
value: function normalize(input, parent, key, visit, addEntity) {
return this.normalizeValue(input, parent, key, visit, addEntity);
}
}, {
key: 'denormalize',
value: function denormalize(input, unvisit, getDenormalizedEntity) {
return this.denormalizeValue(input, unvisit, getDenormalizedEntity);
}
}]);
return UnionSchema;
}(_Polymorphic2.default);
exports.default = UnionSchema;
},{"./Polymorphic":5}],7:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _Polymorphic = require('./Polymorphic');
var _Polymorphic2 = _interopRequireDefault(_Polymorphic);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ValuesSchema = function (_PolymorphicSchema) {
_inherits(ValuesSchema, _PolymorphicSchema);
function ValuesSchema() {
_classCallCheck(this, ValuesSchema);
return _possibleConstructorReturn(this, (ValuesSchema.__proto__ || Object.getPrototypeOf(ValuesSchema)).apply(this, arguments));
}
_createClass(ValuesSchema, [{
key: 'normalize',
value: function normalize(input, parent, key, visit, addEntity) {
var _this2 = this;
return Object.keys(input).reduce(function (output, key, index) {
var value = input[key];
return value !== undefined && value !== null ? _extends({}, output, _defineProperty({}, key, _this2.normalizeValue(value, input, key, visit, addEntity))) : output;
}, {});
}
}, {
key: 'denormalize',
value: function denormalize(input, unvisit, getDenormalizedEntity) {
var _this3 = this;
return Object.keys(input).reduce(function (output, key) {
var entityOrId = input[key];
return _extends({}, output, _defineProperty({}, key, _this3.denormalizeValue(entityOrId, unvisit, getDenormalizedEntity)));
}, {});
}
}]);
return ValuesSchema;
}(_Polymorphic2.default);
exports.default = ValuesSchema;
},{"./Polymorphic":5}],"normalizr":[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.denormalize = exports.normalize = exports.schema = undefined;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _Entity = require('./schemas/Entity');
var _Entity2 = _interopRequireDefault(_Entity);
var _Union = require('./schemas/Union');
var _Union2 = _interopRequireDefault(_Union);
var _Values = require('./schemas/Values');
var _Values2 = _interopRequireDefault(_Values);
var _Array = require('./schemas/Array');
var ArrayUtils = _interopRequireWildcard(_Array);
var _Object = require('./schemas/Object');
var ObjectUtils = _interopRequireWildcard(_Object);
var _ImmutableUtils = require('./schemas/ImmutableUtils');
var ImmutableUtils = _interopRequireWildcard(_ImmutableUtils);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var visit = function visit(value, parent, key, schema, addEntity) {
if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== 'object' || !value) {
return value;
}
if ((typeof schema === 'undefined' ? 'undefined' : _typeof(schema)) === 'object' && (!schema.normalize || typeof schema.normalize !== 'function')) {
var method = Array.isArray(schema) ? ArrayUtils.normalize : ObjectUtils.normalize;
return method(schema, value, parent, key, visit, addEntity);
}
return schema.normalize(value, parent, key, visit, addEntity);
};
var addEntities = function addEntities(entities) {
return function (schema, processedEntity, value, parent, key) {
var schemaKey = schema.key;
var id = schema.getId(value, parent, key);
if (!(schemaKey in entities)) {
entities[schemaKey] = {};
}
var existingEntity = entities[schemaKey][id];
if (existingEntity) {
entities[schemaKey][id] = schema.merge(existingEntity, processedEntity);
} else {
entities[schemaKey][id] = processedEntity;
}
};
};
var schema = exports.schema = {
Array: ArrayUtils.default,
Entity: _Entity2.default,
Object: ObjectUtils.default,
Union: _Union2.default,
Values: _Values2.default
};
var normalize = exports.normalize = function normalize(input, schema) {
if (!input || (typeof input === 'undefined' ? 'undefined' : _typeof(input)) !== 'object') {
throw new Error('Unexpected input given to normalize. Expected type to be "object", found "' + (typeof input === 'undefined' ? 'undefined' : _typeof(input)) + '".');
}
var entities = {};
var addEntity = addEntities(entities);
var result = visit(input, input, null, schema, addEntity);
return { entities: entities, result: result };
};
var unvisit = function unvisit(input, schema, getDenormalizedEntity) {
if ((typeof schema === 'undefined' ? 'undefined' : _typeof(schema)) === 'object' && (!schema.denormalize || typeof schema.denormalize !== 'function')) {
var method = Array.isArray(schema) ? ArrayUtils.denormalize : ObjectUtils.denormalize;
return method(schema, input, unvisit, getDenormalizedEntity);
}
if (input === undefined || input === null) {
return input;
}
return schema.denormalize(input, unvisit, getDenormalizedEntity);
};
var getEntity = function getEntity(entityOrId, schemaKey, entities, isImmutable) {
if ((typeof entityOrId === 'undefined' ? 'undefined' : _typeof(entityOrId)) === 'object') {
return entityOrId;
}
return isImmutable ? entities.getIn([schemaKey, entityOrId.toString()]) : entities[schemaKey][entityOrId];
};
var getEntities = function getEntities(entities, isImmutable) {
return function (schema, entityOrId) {
var schemaKey = schema.key;
return getEntity(entityOrId, schemaKey, entities, isImmutable);
};
};
var denormalize = exports.denormalize = function denormalize(input, schema, entities) {
if (!input) {
return input;
}
var isImmutable = ImmutableUtils.isImmutable(entities);
var getDenormalizedEntity = getEntities(entities, isImmutable);
return unvisit(input, schema, getDenormalizedEntity);
};
},{"./schemas/Array":1,"./schemas/Entity":2,"./schemas/ImmutableUtils":3,"./schemas/Object":4,"./schemas/Union":6,"./schemas/Values":7}]},{},[])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImRpc3Qvc3JjL3NjaGVtYXMvQXJyYXkuanMiLCJkaXN0L3NyYy9zY2hlbWFzL0VudGl0eS5qcyIsImRpc3Qvc3JjL3NjaGVtYXMvSW1tdXRhYmxlVXRpbHMuanMiLCJkaXN0L3NyYy9zY2hlbWFzL09iamVjdC5qcyIsImRpc3Qvc3JjL3NjaGVtYXMvUG9seW1vcnBoaWMuanMiLCJkaXN0L3NyYy9zY2hlbWFzL1VuaW9uLmpzIiwiZGlzdC9zcmMvc2NoZW1hcy9WYWx1ZXMuanMiLCJub3JtYWxpenIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlbm9ybWFsaXplID0gZXhwb3J0cy5ub3JtYWxpemUgPSB1bmRlZmluZWQ7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbnZhciBfUG9seW1vcnBoaWMgPSByZXF1aXJlKCcuL1BvbHltb3JwaGljJyk7XG5cbnZhciBfUG9seW1vcnBoaWMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUG9seW1vcnBoaWMpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5mdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmICghc2VsZikgeyB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWRcIik7IH0gcmV0dXJuIGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBjYWxsID09PSBcImZ1bmN0aW9uXCIpID8gY2FsbCA6IHNlbGY7IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciB2YWxpZGF0ZVNjaGVtYSA9IGZ1bmN0aW9uIHZhbGlkYXRlU2NoZW1hKGRlZmluaXRpb24pIHtcbiAgdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5KGRlZmluaXRpb24pO1xuICBpZiAoaXNBcnJheSAmJiBkZWZpbml0aW9uLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHNjaGVtYSBkZWZpbml0aW9uIHRvIGJlIGEgc2luZ2xlIHNjaGVtYSwgYnV0IGZvdW5kICcgKyBkZWZpbml0aW9uLmxlbmd0aCArICcuJyk7XG4gIH1cblxuICByZXR1cm4gZGVmaW5pdGlvblswXTtcbn07XG5cbnZhciBnZXRWYWx1ZXMgPSBmdW5jdGlvbiBnZXRWYWx1ZXMoaW5wdXQpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoaW5wdXQpID8gaW5wdXQgOiBPYmplY3Qua2V5cyhpbnB1dCkubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gaW5wdXRba2V5XTtcbiAgfSk7XG59O1xuXG52YXIgbm9ybWFsaXplID0gZXhwb3J0cy5ub3JtYWxpemUgPSBmdW5jdGlvbiBub3JtYWxpemUoc2NoZW1hLCBpbnB1dCwgcGFyZW50LCBrZXksIHZpc2l0LCBhZGRFbnRpdHkpIHtcbiAgc2NoZW1hID0gdmFsaWRhdGVTY2hlbWEoc2NoZW1hKTtcblxuICB2YXIgdmFsdWVzID0gZ2V0VmFsdWVzKGlucHV0KTtcblxuICAvLyBTcGVjaWFsIGNhc2U6IEFycmF5cyBwYXNzICp0aGVpciogcGFyZW50IG9uIHRvIHRoZWlyIGNoaWxkcmVuLCBzaW5jZSB0aGVyZVxuICAvLyBpcyBub3QgYW55IHNwZWNpYWwgaW5mb3JtYXRpb24gdGhhdCBjYW4gYmUgZ2F0aGVyZWQgZnJvbSB0aGVtc2VsdmVzIGRpcmVjdGx5XG4gIHJldHVybiB2YWx1ZXMubWFwKGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcbiAgICByZXR1cm4gdmlzaXQodmFsdWUsIHBhcmVudCwga2V5LCBzY2hlbWEsIGFkZEVudGl0eSk7XG4gIH0pO1xufTtcblxudmFyIGRlbm9ybWFsaXplID0gZXhwb3J0cy5kZW5vcm1hbGl6ZSA9IGZ1bmN0aW9uIGRlbm9ybWFsaXplKHNjaGVtYSwgaW5wdXQsIHVudmlzaXQsIGdldERlbm9ybWFsaXplZEVudGl0eSkge1xuICBzY2hlbWEgPSB2YWxpZGF0ZVNjaGVtYShzY2hlbWEpO1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShpbnB1dCkgPyBpbnB1dC5tYXAoZnVuY3Rpb24gKGVudGl0eU9ySWQpIHtcbiAgICByZXR1cm4gdW52aXNpdChlbnRpdHlPcklkLCBzY2hlbWEsIGdldERlbm9ybWFsaXplZEVudGl0eSk7XG4gIH0pIDogaW5wdXQ7XG59O1xuXG52YXIgQXJyYXlTY2hlbWEgPSBmdW5jdGlvbiAoX1BvbHltb3JwaGljU2NoZW1hKSB7XG4gIF9pbmhlcml0cyhBcnJheVNjaGVtYSwgX1BvbHltb3JwaGljU2NoZW1hKTtcblxuICBmdW5jdGlvbiBBcnJheVNjaGVtYSgpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQXJyYXlTY2hlbWEpO1xuXG4gICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChBcnJheVNjaGVtYS5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKEFycmF5U2NoZW1hKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoQXJyYXlTY2hlbWEsIFt7XG4gICAga2V5OiAnbm9ybWFsaXplJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gbm9ybWFsaXplKGlucHV0LCBwYXJlbnQsIGtleSwgdmlzaXQsIGFkZEVudGl0eSkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIHZhciB2YWx1ZXMgPSBnZXRWYWx1ZXMoaW5wdXQpO1xuXG4gICAgICByZXR1cm4gdmFsdWVzLm1hcChmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBfdGhpczIubm9ybWFsaXplVmFsdWUodmFsdWUsIHBhcmVudCwga2V5LCB2aXNpdCwgYWRkRW50aXR5KTtcbiAgICAgIH0pLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGw7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdkZW5vcm1hbGl6ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRlbm9ybWFsaXplKGlucHV0LCB1bnZpc2l0LCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpIHtcbiAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gQXJyYXkuaXNBcnJheShpbnB1dCkgPyBpbnB1dC5tYXAoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBfdGhpczMuZGVub3JtYWxpemVWYWx1ZSh2YWx1ZSwgdW52aXNpdCwgZ2V0RGVub3JtYWxpemVkRW50aXR5KTtcbiAgICAgIH0pIDogaW5wdXQ7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEFycmF5U2NoZW1hO1xufShfUG9seW1vcnBoaWMyLmRlZmF1bHQpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBBcnJheVNjaGVtYTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTtcblxudmFyIF9JbW11dGFibGVVdGlscyA9IHJlcXVpcmUoJy4vSW1tdXRhYmxlVXRpbHMnKTtcblxudmFyIEltbXV0YWJsZVV0aWxzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX0ltbXV0YWJsZVV0aWxzKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09iai5kZWZhdWx0ID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblxuZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkgeyBpZiAoa2V5IGluIG9iaikgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHsgdmFsdWU6IHZhbHVlLCBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0pOyB9IGVsc2UgeyBvYmpba2V5XSA9IHZhbHVlOyB9IHJldHVybiBvYmo7IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIGdldERlZmF1bHRHZXRJZCA9IGZ1bmN0aW9uIGdldERlZmF1bHRHZXRJZChpZEF0dHJpYnV0ZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgcmV0dXJuIEltbXV0YWJsZVV0aWxzLmlzSW1tdXRhYmxlKGlucHV0KSA/IGlucHV0LmdldChpZEF0dHJpYnV0ZSkgOiBpbnB1dFtpZEF0dHJpYnV0ZV07XG4gIH07XG59O1xuXG52YXIgRW50aXR5U2NoZW1hID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBFbnRpdHlTY2hlbWEoa2V5KSB7XG4gICAgdmFyIGRlZmluaXRpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbnRpdHlTY2hlbWEpO1xuXG4gICAgaWYgKCFrZXkgfHwgdHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgYSBzdHJpbmcga2V5IGZvciBFbnRpdHksIGJ1dCBmb3VuZCAnICsga2V5ICsgJy4nKTtcbiAgICB9XG5cbiAgICB2YXIgX29wdGlvbnMkaWRBdHRyaWJ1dGUgPSBvcHRpb25zLmlkQXR0cmlidXRlLFxuICAgICAgICBpZEF0dHJpYnV0ZSA9IF9vcHRpb25zJGlkQXR0cmlidXRlID09PSB1bmRlZmluZWQgPyAnaWQnIDogX29wdGlvbnMkaWRBdHRyaWJ1dGUsXG4gICAgICAgIF9vcHRpb25zJG1lcmdlU3RyYXRlZyA9IG9wdGlvbnMubWVyZ2VTdHJhdGVneSxcbiAgICAgICAgbWVyZ2VTdHJhdGVneSA9IF9vcHRpb25zJG1lcmdlU3RyYXRlZyA9PT0gdW5kZWZpbmVkID8gZnVuY3Rpb24gKGVudGl0eUEsIGVudGl0eUIpIHtcbiAgICAgIHJldHVybiBfZXh0ZW5kcyh7fSwgZW50aXR5QSwgZW50aXR5Qik7XG4gICAgfSA6IF9vcHRpb25zJG1lcmdlU3RyYXRlZyxcbiAgICAgICAgX29wdGlvbnMkcHJvY2Vzc1N0cmF0ID0gb3B0aW9ucy5wcm9jZXNzU3RyYXRlZ3ksXG4gICAgICAgIHByb2Nlc3NTdHJhdGVneSA9IF9vcHRpb25zJHByb2Nlc3NTdHJhdCA9PT0gdW5kZWZpbmVkID8gZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICByZXR1cm4gX2V4dGVuZHMoe30sIGlucHV0KTtcbiAgICB9IDogX29wdGlvbnMkcHJvY2Vzc1N0cmF0O1xuXG5cbiAgICB0aGlzLl9rZXkgPSBrZXk7XG4gICAgdGhpcy5fZ2V0SWQgPSB0eXBlb2YgaWRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbicgPyBpZEF0dHJpYnV0ZSA6IGdldERlZmF1bHRHZXRJZChpZEF0dHJpYnV0ZSk7XG4gICAgdGhpcy5faWRBdHRyaWJ1dGUgPSBpZEF0dHJpYnV0ZTtcbiAgICB0aGlzLl9tZXJnZVN0cmF0ZWd5ID0gbWVyZ2VTdHJhdGVneTtcbiAgICB0aGlzLl9wcm9jZXNzU3RyYXRlZ3kgPSBwcm9jZXNzU3RyYXRlZ3k7XG4gICAgdGhpcy5kZWZpbmUoZGVmaW5pdGlvbik7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoRW50aXR5U2NoZW1hLCBbe1xuICAgIGtleTogJ2RlZmluZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRlZmluZShkZWZpbml0aW9uKSB7XG4gICAgICB0aGlzLnNjaGVtYSA9IE9iamVjdC5rZXlzKGRlZmluaXRpb24pLnJlZHVjZShmdW5jdGlvbiAoZW50aXR5U2NoZW1hLCBrZXkpIHtcbiAgICAgICAgdmFyIHNjaGVtYSA9IGRlZmluaXRpb25ba2V5XTtcbiAgICAgICAgcmV0dXJuIF9leHRlbmRzKHt9LCBlbnRpdHlTY2hlbWEsIF9kZWZpbmVQcm9wZXJ0eSh7fSwga2V5LCBzY2hlbWEpKTtcbiAgICAgIH0sIHRoaXMuc2NoZW1hIHx8IHt9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdnZXRJZCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldElkKGlucHV0LCBwYXJlbnQsIGtleSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldElkKGlucHV0LCBwYXJlbnQsIGtleSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnbWVyZ2UnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBtZXJnZShlbnRpdHlBLCBlbnRpdHlCKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWVyZ2VTdHJhdGVneShlbnRpdHlBLCBlbnRpdHlCKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdub3JtYWxpemUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBub3JtYWxpemUoaW5wdXQsIHBhcmVudCwga2V5LCB2aXNpdCwgYWRkRW50aXR5KSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICB2YXIgcHJvY2Vzc2VkRW50aXR5ID0gdGhpcy5fcHJvY2Vzc1N0cmF0ZWd5KGlucHV0LCBwYXJlbnQsIGtleSk7XG4gICAgICBPYmplY3Qua2V5cyh0aGlzLnNjaGVtYSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGlmIChwcm9jZXNzZWRFbnRpdHkuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBfdHlwZW9mKHByb2Nlc3NlZEVudGl0eVtrZXldKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICB2YXIgc2NoZW1hID0gX3RoaXMuc2NoZW1hW2tleV07XG4gICAgICAgICAgcHJvY2Vzc2VkRW50aXR5W2tleV0gPSB2aXNpdChwcm9jZXNzZWRFbnRpdHlba2V5XSwgcHJvY2Vzc2VkRW50aXR5LCBrZXksIHNjaGVtYSwgYWRkRW50aXR5KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGFkZEVudGl0eSh0aGlzLCBwcm9jZXNzZWRFbnRpdHksIGlucHV0LCBwYXJlbnQsIGtleSk7XG4gICAgICByZXR1cm4gdGhpcy5nZXRJZChpbnB1dCwgcGFyZW50LCBrZXkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ2Rlbm9ybWFsaXplJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gZGVub3JtYWxpemUoZW50aXR5T3JJZCwgdW52aXNpdCwgZ2V0RGVub3JtYWxpemVkRW50aXR5KSB7XG4gICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgdmFyIGVudGl0eSA9IGdldERlbm9ybWFsaXplZEVudGl0eSh0aGlzLCBlbnRpdHlPcklkKTtcbiAgICAgIGlmICgodHlwZW9mIGVudGl0eSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YoZW50aXR5KSkgIT09ICdvYmplY3QnIHx8IGVudGl0eSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZW50aXR5O1xuICAgICAgfVxuXG4gICAgICBpZiAoSW1tdXRhYmxlVXRpbHMuaXNJbW11dGFibGUoZW50aXR5KSkge1xuICAgICAgICByZXR1cm4gSW1tdXRhYmxlVXRpbHMuZGVub3JtYWxpemVJbW11dGFibGUodGhpcy5zY2hlbWEsIGVudGl0eSwgdW52aXNpdCwgZ2V0RGVub3JtYWxpemVkRW50aXR5KTtcbiAgICAgIH1cblxuICAgICAgdmFyIHByb2Nlc3NlZEVudGl0eSA9IF9leHRlbmRzKHt9LCBlbnRpdHkpO1xuICAgICAgT2JqZWN0LmtleXModGhpcy5zY2hlbWEpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAocHJvY2Vzc2VkRW50aXR5Lmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICB2YXIgc2NoZW1hID0gX3RoaXMyLnNjaGVtYVtrZXldO1xuICAgICAgICAgIHByb2Nlc3NlZEVudGl0eVtrZXldID0gdW52aXNpdChwcm9jZXNzZWRFbnRpdHlba2V5XSwgc2NoZW1hLCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwcm9jZXNzZWRFbnRpdHk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAna2V5JyxcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl9rZXk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnaWRBdHRyaWJ1dGUnLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2lkQXR0cmlidXRlO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBFbnRpdHlTY2hlbWE7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEVudGl0eVNjaGVtYTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmlzSW1tdXRhYmxlID0gaXNJbW11dGFibGU7XG5leHBvcnRzLmRlbm9ybWFsaXplSW1tdXRhYmxlID0gZGVub3JtYWxpemVJbW11dGFibGU7XG4vKipcbiAqIEhlbHBlcnMgdG8gZW5hYmxlIEltbXV0YWJsZSBjb21wYXRpYmlsaXR5ICp3aXRob3V0KiBicmluZ2luZyBpblxuICogdGhlICdpbW11dGFibGUnIHBhY2thZ2UgYXMgYSBkZXBlbmRlbmN5LlxuICovXG5cbi8qKlxuICogQ2hlY2sgaWYgYW4gb2JqZWN0IGlzIGltbXV0YWJsZSBieSBjaGVja2luZyBpZiBpdCBoYXMgYSBrZXkgc3BlY2lmaWNcbiAqIHRvIHRoZSBpbW11dGFibGUgbGlicmFyeS5cbiAqXG4gKiBAcGFyYW0gIHthbnl9IG9iamVjdFxuICogQHJldHVybiB7Ym9vbH1cbiAqL1xuZnVuY3Rpb24gaXNJbW11dGFibGUob2JqZWN0KSB7XG4gIHJldHVybiAhIShvYmplY3QgJiYgKG9iamVjdC5oYXNPd25Qcm9wZXJ0eSgnX19vd25lcklEJykgfHwgLy8gSW1tdXRhYmxlLk1hcFxuICBvYmplY3QuX21hcCAmJiBvYmplY3QuX21hcC5oYXNPd25Qcm9wZXJ0eSgnX19vd25lcklEJykgLy8gSW1tdXRhYmxlLlJlY29yZFxuICApKTtcbn1cblxuLyoqXG4gKiBEZW5vcm1hbGl6ZSBhbiBpbW11dGFibGUgZW50aXR5LlxuICpcbiAqIEBwYXJhbSAge1NjaGVtYX0gc2NoZW1hXG4gKiBAcGFyYW0gIHtJbW11dGFibGUuTWFwfEltbXV0YWJsZS5SZWNvcmR9IGlucHV0XG4gKiBAcGFyYW0gIHtmdW5jdGlvbn0gdW52aXNpdFxuICogQHBhcmFtICB7ZnVuY3Rpb259IGdldERlbm9ybWFsaXplZEVudGl0eVxuICogQHJldHVybiB7SW1tdXRhYmxlLk1hcHxJbW11dGFibGUuUmVjb3JkfVxuICovXG5mdW5jdGlvbiBkZW5vcm1hbGl6ZUltbXV0YWJsZShzY2hlbWEsIGlucHV0LCB1bnZpc2l0LCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHNjaGVtYSkucmVkdWNlKGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIC8vIEltbXV0YWJsZSBtYXBzIGNhc3Qga2V5cyB0byBzdHJpbmdzIG9uIHdyaXRlIHNvIHdlIG5lZWQgdG8gZW5zdXJlXG4gICAgLy8gd2UncmUgYWNjZXNzaW5nIHRoZW0gdXNpbmcgc3RyaW5nIGtleXMuXG4gICAgdmFyIHN0cmluZ0tleSA9ICcnICsga2V5O1xuXG4gICAgaWYgKG9iamVjdC5oYXMoc3RyaW5nS2V5KSkge1xuICAgICAgcmV0dXJuIG9iamVjdC5zZXQoc3RyaW5nS2V5LCB1bnZpc2l0KG9iamVjdC5nZXQoc3RyaW5nS2V5KSwgc2NoZW1hW3N0cmluZ0tleV0sIGdldERlbm9ybWFsaXplZEVudGl0eSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cbiAgfSwgaW5wdXQpO1xufSIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVub3JtYWxpemUgPSBleHBvcnRzLm5vcm1hbGl6ZSA9IHVuZGVmaW5lZDtcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxudmFyIF9JbW11dGFibGVVdGlscyA9IHJlcXVpcmUoJy4vSW1tdXRhYmxlVXRpbHMnKTtcblxudmFyIEltbXV0YWJsZVV0aWxzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX0ltbXV0YWJsZVV0aWxzKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09iai5kZWZhdWx0ID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblxuZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkgeyBpZiAoa2V5IGluIG9iaikgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHsgdmFsdWU6IHZhbHVlLCBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0pOyB9IGVsc2UgeyBvYmpba2V5XSA9IHZhbHVlOyB9IHJldHVybiBvYmo7IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIF9ub3JtYWxpemUgPSBmdW5jdGlvbiBfbm9ybWFsaXplKHNjaGVtYSwgaW5wdXQsIHBhcmVudCwga2V5LCB2aXNpdCwgYWRkRW50aXR5KSB7XG4gIHZhciBvYmplY3QgPSBfZXh0ZW5kcyh7fSwgaW5wdXQpO1xuICBPYmplY3Qua2V5cyhzY2hlbWEpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBsb2NhbFNjaGVtYSA9IHNjaGVtYVtrZXldO1xuICAgIHZhciB2YWx1ZSA9IHZpc2l0KGlucHV0W2tleV0sIGlucHV0LCBrZXksIGxvY2FsU2NoZW1hLCBhZGRFbnRpdHkpO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsKSB7XG4gICAgICBkZWxldGUgb2JqZWN0W2tleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iamVjdFtrZXldID0gdmFsdWU7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG5cbmV4cG9ydHMubm9ybWFsaXplID0gX25vcm1hbGl6ZTtcbnZhciBfZGVub3JtYWxpemUgPSBmdW5jdGlvbiBfZGVub3JtYWxpemUoc2NoZW1hLCBpbnB1dCwgdW52aXNpdCwgZ2V0RGVub3JtYWxpemVkRW50aXR5KSB7XG4gIGlmIChJbW11dGFibGVVdGlscy5pc0ltbXV0YWJsZShpbnB1dCkpIHtcbiAgICByZXR1cm4gSW1tdXRhYmxlVXRpbHMuZGVub3JtYWxpemVJbW11dGFibGUoc2NoZW1hLCBpbnB1dCwgdW52aXNpdCwgZ2V0RGVub3JtYWxpemVkRW50aXR5KTtcbiAgfVxuXG4gIHZhciBvYmplY3QgPSBfZXh0ZW5kcyh7fSwgaW5wdXQpO1xuICBPYmplY3Qua2V5cyhzY2hlbWEpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIGlmIChvYmplY3Rba2V5XSkge1xuICAgICAgb2JqZWN0W2tleV0gPSB1bnZpc2l0KG9iamVjdFtrZXldLCBzY2hlbWFba2V5XSwgZ2V0RGVub3JtYWxpemVkRW50aXR5KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb2JqZWN0O1xufTtcblxuZXhwb3J0cy5kZW5vcm1hbGl6ZSA9IF9kZW5vcm1hbGl6ZTtcblxudmFyIE9iamVjdFNjaGVtYSA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gT2JqZWN0U2NoZW1hKGRlZmluaXRpb24pIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgT2JqZWN0U2NoZW1hKTtcblxuICAgIHRoaXMuZGVmaW5lKGRlZmluaXRpb24pO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKE9iamVjdFNjaGVtYSwgW3tcbiAgICBrZXk6ICdkZWZpbmUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBkZWZpbmUoZGVmaW5pdGlvbikge1xuICAgICAgdGhpcy5zY2hlbWEgPSBPYmplY3Qua2V5cyhkZWZpbml0aW9uKS5yZWR1Y2UoZnVuY3Rpb24gKGVudGl0eVNjaGVtYSwga2V5KSB7XG4gICAgICAgIHZhciBzY2hlbWEgPSBkZWZpbml0aW9uW2tleV07XG4gICAgICAgIHJldHVybiBfZXh0ZW5kcyh7fSwgZW50aXR5U2NoZW1hLCBfZGVmaW5lUHJvcGVydHkoe30sIGtleSwgc2NoZW1hKSk7XG4gICAgICB9LCB0aGlzLnNjaGVtYSB8fCB7fSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnbm9ybWFsaXplJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gbm9ybWFsaXplKCkge1xuICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIF9ub3JtYWxpemUuYXBwbHkodW5kZWZpbmVkLCBbdGhpcy5zY2hlbWFdLmNvbmNhdChhcmdzKSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnZGVub3JtYWxpemUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBkZW5vcm1hbGl6ZSgpIHtcbiAgICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgIGFyZ3NbX2tleTJdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIF9kZW5vcm1hbGl6ZS5hcHBseSh1bmRlZmluZWQsIFt0aGlzLnNjaGVtYV0uY29uY2F0KGFyZ3MpKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gT2JqZWN0U2NoZW1hO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBPYmplY3RTY2hlbWE7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgUG9seW1vcnBoaWNTY2hlbWEgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFBvbHltb3JwaGljU2NoZW1hKGRlZmluaXRpb24sIHNjaGVtYUF0dHJpYnV0ZSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQb2x5bW9ycGhpY1NjaGVtYSk7XG5cbiAgICBpZiAoc2NoZW1hQXR0cmlidXRlKSB7XG4gICAgICB0aGlzLl9zY2hlbWFBdHRyaWJ1dGUgPSB0eXBlb2Ygc2NoZW1hQXR0cmlidXRlID09PSAnc3RyaW5nJyA/IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXRbc2NoZW1hQXR0cmlidXRlXTtcbiAgICAgIH0gOiBzY2hlbWFBdHRyaWJ1dGU7XG4gICAgfVxuICAgIHRoaXMuZGVmaW5lKGRlZmluaXRpb24pO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFBvbHltb3JwaGljU2NoZW1hLCBbe1xuICAgIGtleTogJ2RlZmluZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRlZmluZShkZWZpbml0aW9uKSB7XG4gICAgICB0aGlzLnNjaGVtYSA9IGRlZmluaXRpb247XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnZ2V0U2NoZW1hQXR0cmlidXRlJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0U2NoZW1hQXR0cmlidXRlKGlucHV0LCBwYXJlbnQsIGtleSkge1xuICAgICAgcmV0dXJuICF0aGlzLmlzU2luZ2xlU2NoZW1hICYmIHRoaXMuX3NjaGVtYUF0dHJpYnV0ZShpbnB1dCwgcGFyZW50LCBrZXkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ2luZmVyU2NoZW1hJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gaW5mZXJTY2hlbWEoaW5wdXQsIHBhcmVudCwga2V5KSB7XG4gICAgICBpZiAodGhpcy5pc1NpbmdsZVNjaGVtYSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zY2hlbWE7XG4gICAgICB9XG5cbiAgICAgIHZhciBhdHRyID0gdGhpcy5nZXRTY2hlbWFBdHRyaWJ1dGUoaW5wdXQsIHBhcmVudCwga2V5KTtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYVthdHRyXTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdub3JtYWxpemVWYWx1ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlKHZhbHVlLCBwYXJlbnQsIGtleSwgdmlzaXQsIGFkZEVudGl0eSkge1xuICAgICAgdmFyIHNjaGVtYSA9IHRoaXMuaW5mZXJTY2hlbWEodmFsdWUsIHBhcmVudCwga2V5KTtcbiAgICAgIGlmICghc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBub3JtYWxpemVkVmFsdWUgPSB2aXNpdCh2YWx1ZSwgcGFyZW50LCBrZXksIHNjaGVtYSwgYWRkRW50aXR5KTtcbiAgICAgIHJldHVybiB0aGlzLmlzU2luZ2xlU2NoZW1hIHx8IG5vcm1hbGl6ZWRWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IG5vcm1hbGl6ZWRWYWx1ZSA9PT0gbnVsbCA/IG5vcm1hbGl6ZWRWYWx1ZSA6IHsgaWQ6IG5vcm1hbGl6ZWRWYWx1ZSwgc2NoZW1hOiB0aGlzLmdldFNjaGVtYUF0dHJpYnV0ZSh2YWx1ZSwgcGFyZW50LCBrZXkpIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnZGVub3JtYWxpemVWYWx1ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRlbm9ybWFsaXplVmFsdWUodmFsdWUsIHVudmlzaXQsIGdldERlbm9ybWFsaXplZEVudGl0eSkge1xuICAgICAgaWYgKCF0aGlzLmlzU2luZ2xlU2NoZW1hICYmICF2YWx1ZS5zY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgdmFyIHNjaGVtYSA9IHRoaXMuaXNTaW5nbGVTY2hlbWEgPyB0aGlzLnNjaGVtYSA6IHRoaXMuc2NoZW1hW3ZhbHVlLnNjaGVtYV07XG4gICAgICByZXR1cm4gdW52aXNpdCh2YWx1ZS5pZCB8fCB2YWx1ZSwgc2NoZW1hLCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ2lzU2luZ2xlU2NoZW1hJyxcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiAhdGhpcy5fc2NoZW1hQXR0cmlidXRlO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBQb2x5bW9ycGhpY1NjaGVtYTtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gUG9seW1vcnBoaWNTY2hlbWE7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpO1xuXG52YXIgX1BvbHltb3JwaGljID0gcmVxdWlyZSgnLi9Qb2x5bW9ycGhpYycpO1xuXG52YXIgX1BvbHltb3JwaGljMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1BvbHltb3JwaGljKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSA/IGNhbGwgOiBzZWxmOyB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgVW5pb25TY2hlbWEgPSBmdW5jdGlvbiAoX1BvbHltb3JwaGljU2NoZW1hKSB7XG4gIF9pbmhlcml0cyhVbmlvblNjaGVtYSwgX1BvbHltb3JwaGljU2NoZW1hKTtcblxuICBmdW5jdGlvbiBVbmlvblNjaGVtYShkZWZpbml0aW9uLCBzY2hlbWFBdHRyaWJ1dGUpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVW5pb25TY2hlbWEpO1xuXG4gICAgaWYgKCFzY2hlbWFBdHRyaWJ1dGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgb3B0aW9uIFwic2NoZW1hQXR0cmlidXRlXCIgbm90IGZvdW5kIG9uIFVuaW9uU2NoZW1hLicpO1xuICAgIH1cbiAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKFVuaW9uU2NoZW1hLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVW5pb25TY2hlbWEpKS5jYWxsKHRoaXMsIGRlZmluaXRpb24sIHNjaGVtYUF0dHJpYnV0ZSkpO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFVuaW9uU2NoZW1hLCBbe1xuICAgIGtleTogJ25vcm1hbGl6ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG5vcm1hbGl6ZShpbnB1dCwgcGFyZW50LCBrZXksIHZpc2l0LCBhZGRFbnRpdHkpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZVZhbHVlKGlucHV0LCBwYXJlbnQsIGtleSwgdmlzaXQsIGFkZEVudGl0eSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnZGVub3JtYWxpemUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBkZW5vcm1hbGl6ZShpbnB1dCwgdW52aXNpdCwgZ2V0RGVub3JtYWxpemVkRW50aXR5KSB7XG4gICAgICByZXR1cm4gdGhpcy5kZW5vcm1hbGl6ZVZhbHVlKGlucHV0LCB1bnZpc2l0LCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBVbmlvblNjaGVtYTtcbn0oX1BvbHltb3JwaGljMi5kZWZhdWx0KTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gVW5pb25TY2hlbWE7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpO1xuXG52YXIgX1BvbHltb3JwaGljID0gcmVxdWlyZSgnLi9Qb2x5bW9ycGhpYycpO1xuXG52YXIgX1BvbHltb3JwaGljMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1BvbHltb3JwaGljKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkgeyBpZiAoa2V5IGluIG9iaikgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHsgdmFsdWU6IHZhbHVlLCBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0pOyB9IGVsc2UgeyBvYmpba2V5XSA9IHZhbHVlOyB9IHJldHVybiBvYmo7IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSA/IGNhbGwgOiBzZWxmOyB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgVmFsdWVzU2NoZW1hID0gZnVuY3Rpb24gKF9Qb2x5bW9ycGhpY1NjaGVtYSkge1xuICBfaW5oZXJpdHMoVmFsdWVzU2NoZW1hLCBfUG9seW1vcnBoaWNTY2hlbWEpO1xuXG4gIGZ1bmN0aW9uIFZhbHVlc1NjaGVtYSgpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVmFsdWVzU2NoZW1hKTtcblxuICAgIHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCAoVmFsdWVzU2NoZW1hLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVmFsdWVzU2NoZW1hKSkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoVmFsdWVzU2NoZW1hLCBbe1xuICAgIGtleTogJ25vcm1hbGl6ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG5vcm1hbGl6ZShpbnB1dCwgcGFyZW50LCBrZXksIHZpc2l0LCBhZGRFbnRpdHkpIHtcbiAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gT2JqZWN0LmtleXMoaW5wdXQpLnJlZHVjZShmdW5jdGlvbiAob3V0cHV0LCBrZXksIGluZGV4KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGlucHV0W2tleV07XG4gICAgICAgIHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsID8gX2V4dGVuZHMoe30sIG91dHB1dCwgX2RlZmluZVByb3BlcnR5KHt9LCBrZXksIF90aGlzMi5ub3JtYWxpemVWYWx1ZSh2YWx1ZSwgaW5wdXQsIGtleSwgdmlzaXQsIGFkZEVudGl0eSkpKSA6IG91dHB1dDtcbiAgICAgIH0sIHt9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdkZW5vcm1hbGl6ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRlbm9ybWFsaXplKGlucHV0LCB1bnZpc2l0LCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpIHtcbiAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gT2JqZWN0LmtleXMoaW5wdXQpLnJlZHVjZShmdW5jdGlvbiAob3V0cHV0LCBrZXkpIHtcbiAgICAgICAgdmFyIGVudGl0eU9ySWQgPSBpbnB1dFtrZXldO1xuICAgICAgICByZXR1cm4gX2V4dGVuZHMoe30sIG91dHB1dCwgX2RlZmluZVByb3BlcnR5KHt9LCBrZXksIF90aGlzMy5kZW5vcm1hbGl6ZVZhbHVlKGVudGl0eU9ySWQsIHVudmlzaXQsIGdldERlbm9ybWFsaXplZEVudGl0eSkpKTtcbiAgICAgIH0sIHt9KTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gVmFsdWVzU2NoZW1hO1xufShfUG9seW1vcnBoaWMyLmRlZmF1bHQpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBWYWx1ZXNTY2hlbWE7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZW5vcm1hbGl6ZSA9IGV4cG9ydHMubm9ybWFsaXplID0gZXhwb3J0cy5zY2hlbWEgPSB1bmRlZmluZWQ7XG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblxudmFyIF9FbnRpdHkgPSByZXF1aXJlKCcuL3NjaGVtYXMvRW50aXR5Jyk7XG5cbnZhciBfRW50aXR5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0VudGl0eSk7XG5cbnZhciBfVW5pb24gPSByZXF1aXJlKCcuL3NjaGVtYXMvVW5pb24nKTtcblxudmFyIF9VbmlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Vbmlvbik7XG5cbnZhciBfVmFsdWVzID0gcmVxdWlyZSgnLi9zY2hlbWFzL1ZhbHVlcycpO1xuXG52YXIgX1ZhbHVlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9WYWx1ZXMpO1xuXG52YXIgX0FycmF5ID0gcmVxdWlyZSgnLi9zY2hlbWFzL0FycmF5Jyk7XG5cbnZhciBBcnJheVV0aWxzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX0FycmF5KTtcblxudmFyIF9PYmplY3QgPSByZXF1aXJlKCcuL3NjaGVtYXMvT2JqZWN0Jyk7XG5cbnZhciBPYmplY3RVdGlscyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9PYmplY3QpO1xuXG52YXIgX0ltbXV0YWJsZVV0aWxzID0gcmVxdWlyZSgnLi9zY2hlbWFzL0ltbXV0YWJsZVV0aWxzJyk7XG5cbnZhciBJbW11dGFibGVVdGlscyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9JbW11dGFibGVVdGlscyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gZWxzZSB7IHZhciBuZXdPYmogPSB7fTsgaWYgKG9iaiAhPSBudWxsKSB7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSBuZXdPYmouZGVmYXVsdCA9IG9iajsgcmV0dXJuIG5ld09iajsgfSB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciB2aXNpdCA9IGZ1bmN0aW9uIHZpc2l0KHZhbHVlLCBwYXJlbnQsIGtleSwgc2NoZW1hLCBhZGRFbnRpdHkpIHtcbiAgaWYgKCh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHZhbHVlKSkgIT09ICdvYmplY3QnIHx8ICF2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGlmICgodHlwZW9mIHNjaGVtYSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2Yoc2NoZW1hKSkgPT09ICdvYmplY3QnICYmICghc2NoZW1hLm5vcm1hbGl6ZSB8fCB0eXBlb2Ygc2NoZW1hLm5vcm1hbGl6ZSAhPT0gJ2Z1bmN0aW9uJykpIHtcbiAgICB2YXIgbWV0aG9kID0gQXJyYXkuaXNBcnJheShzY2hlbWEpID8gQXJyYXlVdGlscy5ub3JtYWxpemUgOiBPYmplY3RVdGlscy5ub3JtYWxpemU7XG4gICAgcmV0dXJuIG1ldGhvZChzY2hlbWEsIHZhbHVlLCBwYXJlbnQsIGtleSwgdmlzaXQsIGFkZEVudGl0eSk7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hLm5vcm1hbGl6ZSh2YWx1ZSwgcGFyZW50LCBrZXksIHZpc2l0LCBhZGRFbnRpdHkpO1xufTtcblxudmFyIGFkZEVudGl0aWVzID0gZnVuY3Rpb24gYWRkRW50aXRpZXMoZW50aXRpZXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChzY2hlbWEsIHByb2Nlc3NlZEVudGl0eSwgdmFsdWUsIHBhcmVudCwga2V5KSB7XG4gICAgdmFyIHNjaGVtYUtleSA9IHNjaGVtYS5rZXk7XG4gICAgdmFyIGlkID0gc2NoZW1hLmdldElkKHZhbHVlLCBwYXJlbnQsIGtleSk7XG4gICAgaWYgKCEoc2NoZW1hS2V5IGluIGVudGl0aWVzKSkge1xuICAgICAgZW50aXRpZXNbc2NoZW1hS2V5XSA9IHt9O1xuICAgIH1cblxuICAgIHZhciBleGlzdGluZ0VudGl0eSA9IGVudGl0aWVzW3NjaGVtYUtleV1baWRdO1xuICAgIGlmIChleGlzdGluZ0VudGl0eSkge1xuICAgICAgZW50aXRpZXNbc2NoZW1hS2V5XVtpZF0gPSBzY2hlbWEubWVyZ2UoZXhpc3RpbmdFbnRpdHksIHByb2Nlc3NlZEVudGl0eSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudGl0aWVzW3NjaGVtYUtleV1baWRdID0gcHJvY2Vzc2VkRW50aXR5O1xuICAgIH1cbiAgfTtcbn07XG5cbnZhciBzY2hlbWEgPSBleHBvcnRzLnNjaGVtYSA9IHtcbiAgQXJyYXk6IEFycmF5VXRpbHMuZGVmYXVsdCxcbiAgRW50aXR5OiBfRW50aXR5Mi5kZWZhdWx0LFxuICBPYmplY3Q6IE9iamVjdFV0aWxzLmRlZmF1bHQsXG4gIFVuaW9uOiBfVW5pb24yLmRlZmF1bHQsXG4gIFZhbHVlczogX1ZhbHVlczIuZGVmYXVsdFxufTtcblxudmFyIG5vcm1hbGl6ZSA9IGV4cG9ydHMubm9ybWFsaXplID0gZnVuY3Rpb24gbm9ybWFsaXplKGlucHV0LCBzY2hlbWEpIHtcbiAgaWYgKCFpbnB1dCB8fCAodHlwZW9mIGlucHV0ID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihpbnB1dCkpICE9PSAnb2JqZWN0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBpbnB1dCBnaXZlbiB0byBub3JtYWxpemUuIEV4cGVjdGVkIHR5cGUgdG8gYmUgXCJvYmplY3RcIiwgZm91bmQgXCInICsgKHR5cGVvZiBpbnB1dCA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YoaW5wdXQpKSArICdcIi4nKTtcbiAgfVxuXG4gIHZhciBlbnRpdGllcyA9IHt9O1xuICB2YXIgYWRkRW50aXR5ID0gYWRkRW50aXRpZXMoZW50aXRpZXMpO1xuXG4gIHZhciByZXN1bHQgPSB2aXNpdChpbnB1dCwgaW5wdXQsIG51bGwsIHNjaGVtYSwgYWRkRW50aXR5KTtcbiAgcmV0dXJuIHsgZW50aXRpZXM6IGVudGl0aWVzLCByZXN1bHQ6IHJlc3VsdCB9O1xufTtcblxudmFyIHVudmlzaXQgPSBmdW5jdGlvbiB1bnZpc2l0KGlucHV0LCBzY2hlbWEsIGdldERlbm9ybWFsaXplZEVudGl0eSkge1xuICBpZiAoKHR5cGVvZiBzY2hlbWEgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHNjaGVtYSkpID09PSAnb2JqZWN0JyAmJiAoIXNjaGVtYS5kZW5vcm1hbGl6ZSB8fCB0eXBlb2Ygc2NoZW1hLmRlbm9ybWFsaXplICE9PSAnZnVuY3Rpb24nKSkge1xuICAgIHZhciBtZXRob2QgPSBBcnJheS5pc0FycmF5KHNjaGVtYSkgPyBBcnJheVV0aWxzLmRlbm9ybWFsaXplIDogT2JqZWN0VXRpbHMuZGVub3JtYWxpemU7XG4gICAgcmV0dXJuIG1ldGhvZChzY2hlbWEsIGlucHV0LCB1bnZpc2l0LCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpO1xuICB9XG5cbiAgaWYgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgaW5wdXQgPT09IG51bGwpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hLmRlbm9ybWFsaXplKGlucHV0LCB1bnZpc2l0LCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpO1xufTtcblxudmFyIGdldEVudGl0eSA9IGZ1bmN0aW9uIGdldEVudGl0eShlbnRpdHlPcklkLCBzY2hlbWFLZXksIGVudGl0aWVzLCBpc0ltbXV0YWJsZSkge1xuICBpZiAoKHR5cGVvZiBlbnRpdHlPcklkID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihlbnRpdHlPcklkKSkgPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGVudGl0eU9ySWQ7XG4gIH1cblxuICByZXR1cm4gaXNJbW11dGFibGUgPyBlbnRpdGllcy5nZXRJbihbc2NoZW1hS2V5LCBlbnRpdHlPcklkLnRvU3RyaW5nKCldKSA6IGVudGl0aWVzW3NjaGVtYUtleV1bZW50aXR5T3JJZF07XG59O1xuXG52YXIgZ2V0RW50aXRpZXMgPSBmdW5jdGlvbiBnZXRFbnRpdGllcyhlbnRpdGllcywgaXNJbW11dGFibGUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChzY2hlbWEsIGVudGl0eU9ySWQpIHtcbiAgICB2YXIgc2NoZW1hS2V5ID0gc2NoZW1hLmtleTtcblxuICAgIHJldHVybiBnZXRFbnRpdHkoZW50aXR5T3JJZCwgc2NoZW1hS2V5LCBlbnRpdGllcywgaXNJbW11dGFibGUpO1xuICB9O1xufTtcblxudmFyIGRlbm9ybWFsaXplID0gZXhwb3J0cy5kZW5vcm1hbGl6ZSA9IGZ1bmN0aW9uIGRlbm9ybWFsaXplKGlucHV0LCBzY2hlbWEsIGVudGl0aWVzKSB7XG4gIGlmICghaW5wdXQpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICB2YXIgaXNJbW11dGFibGUgPSBJbW11dGFibGVVdGlscy5pc0ltbXV0YWJsZShlbnRpdGllcyk7XG4gIHZhciBnZXREZW5vcm1hbGl6ZWRFbnRpdHkgPSBnZXRFbnRpdGllcyhlbnRpdGllcywgaXNJbW11dGFibGUpO1xuICByZXR1cm4gdW52aXNpdChpbnB1dCwgc2NoZW1hLCBnZXREZW5vcm1hbGl6ZWRFbnRpdHkpO1xufTsiXX0=
const { normalize, schema } = require('normalizr');
const data = [
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
},
{
"id": "124",
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
},
{
"id": "125",
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
},
{
"id": "126",
"comments": null
},
{
"id": "127",
"title": "My awesome blog post",
"comments": []
}
];
// Define a users schema
const user = new schema.Entity('users');
// Define your comments schema
const comment = new schema.Entity('comments', {
commenter: user
});
// Define your article
const article = new schema.Entity('articles', {
author: user,
comments: [ comment ]
});
const normalizedData = normalize(data, [article]);
console.log(normalizedData);
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"normalizr": "3.2.1"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment