foop
Version:
interfaces that describe their intentions.
269 lines (254 loc) • 16.8 kB
JavaScript
/**
* @since 2.0.0
*/
var dot = require('../deps/dot')
var isDot = require('../deps/is/dot')
// const accessor = x => x.split('.')[0]
/**
* @desc checks if this.meta.dot != false & isDot(key) - scoped
*
* @private
* @since 3.0.1
*
* @param {string} key key in .get/.has/.delete/set
* @param {DotProp} thisArg Chain
* @return {boolean} shouldDot
*
* @see DotProp.dot
* @see deps/is/dot
* @see deps/meta
* @see https://lodash.com/docs/#get
* @see https://github.com/sindresorhus/dot-prop
*
* @example
*
* const chain = new DotProp()
* shouldDot('me.me', chain)
* //=> true
*
* const chain = new DotProp()
* shouldDot('me', chain)
* //=> false
*
* const chain = new DotProp()
* chain.dot(false)
* shouldDot('me.me', chain)
* //=> false
*
*/
var shouldDot = function (key, thisArg) { return thisArg.meta.dot !== false && isDot(key); }
/**
* @class DotProp
* @member Observe
* @extends {ChainedMap}
* @memberOf compose
* @category Chainable
*
* @param {Class | Composable} Target composable class
* @return {DotProp} class
*
* @tests DotProp
* @types DotProp
*
* @see deps/dot
*
* @example
*
* const {compose} = require('chain-able')
* const {DotProp} = compose
* new DotProp()
* //=> DotProp
*
* @example
*
* const chain = new Chain()
*
* chain.set('moose.simple', 1)
* //=> Chain
*
* chain.get('moose.simple')
* //=>1
*
* chain.get('moose')
* //=> {simple: 1}
*
* chain.set('moose.canada.eh', true).set('moose.canada.igloo', true)
* //=> Chain
*
* //set, has, get, delete :-)
* chain.delete('moose.canada.eh')
* //=> Chain
*
* //also works with an array (moose.canada.igloo)
* chain.get(['moose', 'canada', 'igloo'])
* //=> true
*
*/
module.exports = function (Target) {
// is this any better?
var entries = Target.prototype.entries
var set = Target.prototype.set
var has = Target.prototype.has
var get = Target.prototype.get
var del = Target.prototype.delete
/**
* @method dot
* @methodTarget DotProp
* @since 3.0.1
*
* @param {boolean} [useDot=undefined] use dot prop or not
* @return {DotProp} @chainable
*
* @see deps/meta
*
* @example
*
* const chain = new Target()
* chain.dot(false)
* chain.set('moose.simple', 1)
*
* toArr(chain.store.keys())
* //=> ['moose.simple']
*
*/
Target.prototype.dot = function enableDisableDot(useDot) {
this.meta.dot = useDot
return this
}
/**
* @desc since we have a map,
* we need to ensure the first property is available
* otherwise we have an empty map.entries obj
* which does nothing by reference
* @since 3.0.1
* @memberOf DotProp
*
* @override
* @inheritdoc
*
* @see TargetedMap.set
* @see .dot
*
* @example
* const chain = new Target()
*
* chain.set('moose.simple', 1)
* //=> Target store:Map: { moose: { simple: 1 } }
*/
Target.prototype.set = function dotSet(key, val) {
if (shouldDot(key, this)) {
// first accessor
// @example: `canada` in `canada.eh`
// @TODO could use `first`
// @NOTE was `.shift` but this is the only `.shift` anywhere
var prop = key.split('.')[0]
// we already know it is .dot, call super instead
// if (!super.has(prop)) super.set(prop, {})
// spread
var data = entries.call(this)
// set on the spread data
dot.set(data, key, val)
// is already by ref, but be extra safe, + observables
return set.call(this, prop, data[prop], key)
}
return set.call(this, key, val)
}
/**
* @desc dot-prop enabled get
* @method get
* @memberOf DotProp
*
* @since 3.0.1
* @override
* @inheritdoc
*
* @param {Primitive} key dot prop key, or any primitive key
* @param {any} [fallback=undefined] fallback value, if it cannot find value with key path
* @return {any} value for path, or fallback value if provided
*
* @see ChainedMap.get
* @see deps/dot
* @see deps/is/dot
*
* @TODO dot-prop on non-store instance.property when using nested chains...
*
* @example
*
* chain.set('moose.simple', 1)
* //=> Chain
*
* chain.get('moose.simple')
* //=>1
*
* chain.get('moose')
* //=> {simple: 1}
*
* @example
*
* //also works with an array (moose.simple)
* chain.get(['moose', 'simple'])
* //=> 1
*
*/
Target.prototype.get = function dotGet(key, fallback) {
return shouldDot(key, this)
? dot.get(entries.call(this), key, fallback)
: get.call(this, key)
}
/**
* @method has
* @methodOf DotProp
* @since 3.0.1
* @override
* @inheritdoc
*
* @see deps/dot
* @see deps/is/dot
*
* @example
*
* chain.set('one.two', 3)
* chain.has('one.two')
* //=> true
*
*/
Target.prototype.has = function dotHas(key) {
return shouldDot(key, this)
? dot.has(entries.call(this), key)
: has.call(this, key)
}
/**
* @method delete
* @methodOf DotProp
* @since 3.0.1
*
* @override
* @inheritdoc
* @see deps/dot
* @see deps/is/dot
*
* @example
*
* chain.set('moose.canada.eh', true)
* chain.set('moose.canada.igloo', true)
* //=> Chain
*
* chain.delete('moose.canada.eh')
* //=> Chain
*
* chain.has('moose.canada.eh')
* //=> true
*
* //still has moose.canada.igloo
* chain.has('moose.canada')
* //=> true
*
*/
Target.prototype.delete = function dotDelete(key) {
return shouldDot(key, this)
? dot.delete(entries.call(this), key)
: del.call(this, key)
}
return Target
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRG90UHJvcC5qcyIsInNvdXJjZXMiOlsiRG90UHJvcC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBzaW5jZSAyLjAuMFxuICovXG5jb25zdCBkb3QgPSByZXF1aXJlKCcuLi9kZXBzL2RvdCcpXG5jb25zdCBpc0RvdCA9IHJlcXVpcmUoJy4uL2RlcHMvaXMvZG90JylcblxuLy8gY29uc3QgYWNjZXNzb3IgPSB4ID0+IHguc3BsaXQoJy4nKVswXVxuXG4vKipcbiAqIEBkZXNjIGNoZWNrcyBpZiB0aGlzLm1ldGEuZG90ICE9IGZhbHNlICYgaXNEb3Qoa2V5KSAtIHNjb3BlZFxuICpcbiAqIEBwcml2YXRlXG4gKiBAc2luY2UgMy4wLjFcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGtleSBrZXkgaW4gLmdldC8uaGFzLy5kZWxldGUvc2V0XG4gKiBAcGFyYW0gIHtEb3RQcm9wfSB0aGlzQXJnIENoYWluXG4gKiBAcmV0dXJuIHtib29sZWFufSBzaG91bGREb3RcbiAqXG4gKiBAc2VlIERvdFByb3AuZG90XG4gKiBAc2VlIGRlcHMvaXMvZG90XG4gKiBAc2VlIGRlcHMvbWV0YVxuICogQHNlZSBodHRwczovL2xvZGFzaC5jb20vZG9jcy8jZ2V0XG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5kcmVzb3JodXMvZG90LXByb3BcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICBjb25zdCBjaGFpbiA9IG5ldyBEb3RQcm9wKClcbiAqICBzaG91bGREb3QoJ21lLm1lJywgY2hhaW4pXG4gKiAgLy89PiB0cnVlXG4gKlxuICogIGNvbnN0IGNoYWluID0gbmV3IERvdFByb3AoKVxuICogIHNob3VsZERvdCgnbWUnLCBjaGFpbilcbiAqICAvLz0+IGZhbHNlXG4gKlxuICogIGNvbnN0IGNoYWluID0gbmV3IERvdFByb3AoKVxuICogIGNoYWluLmRvdChmYWxzZSlcbiAqICBzaG91bGREb3QoJ21lLm1lJywgY2hhaW4pXG4gKiAgLy89PiBmYWxzZVxuICpcbiAqL1xuY29uc3Qgc2hvdWxkRG90ID0gKGtleSwgdGhpc0FyZykgPT4gdGhpc0FyZy5tZXRhLmRvdCAhPT0gZmFsc2UgJiYgaXNEb3Qoa2V5KVxuXG4vKipcbiAqIEBjbGFzcyBEb3RQcm9wXG4gKiBAbWVtYmVyIE9ic2VydmVcbiAqIEBleHRlbmRzIHtDaGFpbmVkTWFwfVxuICogQG1lbWJlck9mIGNvbXBvc2VcbiAqIEBjYXRlZ29yeSBDaGFpbmFibGVcbiAqXG4gKiBAcGFyYW0gIHtDbGFzcyB8IENvbXBvc2FibGV9IFRhcmdldCBjb21wb3NhYmxlIGNsYXNzXG4gKiBAcmV0dXJuIHtEb3RQcm9wfSBjbGFzc1xuICpcbiAqIEB0ZXN0cyBEb3RQcm9wXG4gKiBAdHlwZXMgRG90UHJvcFxuICpcbiAqIEBzZWUgZGVwcy9kb3RcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgIGNvbnN0IHtjb21wb3NlfSA9IHJlcXVpcmUoJ2NoYWluLWFibGUnKVxuICogICAgY29uc3Qge0RvdFByb3B9ID0gY29tcG9zZVxuICogICAgbmV3IERvdFByb3AoKVxuICogICAgLy89PiBEb3RQcm9wXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICBjb25zdCBjaGFpbiA9IG5ldyBDaGFpbigpXG4gKlxuICogICAgY2hhaW4uc2V0KCdtb29zZS5zaW1wbGUnLCAxKVxuICogICAgLy89PiBDaGFpblxuICpcbiAqICAgIGNoYWluLmdldCgnbW9vc2Uuc2ltcGxlJylcbiAqICAgIC8vPT4xXG4gKlxuICogICAgY2hhaW4uZ2V0KCdtb29zZScpXG4gKiAgICAvLz0+IHtzaW1wbGU6IDF9XG4gKlxuICogICAgY2hhaW4uc2V0KCdtb29zZS5jYW5hZGEuZWgnLCB0cnVlKS5zZXQoJ21vb3NlLmNhbmFkYS5pZ2xvbycsIHRydWUpXG4gKiAgICAvLz0+IENoYWluXG4gKlxuICogICAgLy9zZXQsIGhhcywgZ2V0LCBkZWxldGUgOi0pXG4gKiAgICBjaGFpbi5kZWxldGUoJ21vb3NlLmNhbmFkYS5laCcpXG4gKiAgICAvLz0+IENoYWluXG4gKlxuICogICAgLy9hbHNvIHdvcmtzIHdpdGggYW4gYXJyYXkgKG1vb3NlLmNhbmFkYS5pZ2xvbylcbiAqICAgIGNoYWluLmdldChbJ21vb3NlJywgJ2NhbmFkYScsICdpZ2xvbyddKVxuICogICAgLy89PiB0cnVlXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IFRhcmdldCA9PiB7XG4gIC8vIGlzIHRoaXMgYW55IGJldHRlcj9cbiAgY29uc3QgZW50cmllcyA9IFRhcmdldC5wcm90b3R5cGUuZW50cmllc1xuICBjb25zdCBzZXQgPSBUYXJnZXQucHJvdG90eXBlLnNldFxuICBjb25zdCBoYXMgPSBUYXJnZXQucHJvdG90eXBlLmhhc1xuICBjb25zdCBnZXQgPSBUYXJnZXQucHJvdG90eXBlLmdldFxuICBjb25zdCBkZWwgPSBUYXJnZXQucHJvdG90eXBlLmRlbGV0ZVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGRvdFxuICAgKiBAbWV0aG9kVGFyZ2V0IERvdFByb3BcbiAgICogQHNpbmNlIDMuMC4xXG4gICAqXG4gICAqIEBwYXJhbSAge2Jvb2xlYW59IFt1c2VEb3Q9dW5kZWZpbmVkXSB1c2UgZG90IHByb3Agb3Igbm90XG4gICAqIEByZXR1cm4ge0RvdFByb3B9IEBjaGFpbmFibGVcbiAgICpcbiAgICogQHNlZSBkZXBzL21ldGFcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgIGNvbnN0IGNoYWluID0gbmV3IFRhcmdldCgpXG4gICAqICAgICBjaGFpbi5kb3QoZmFsc2UpXG4gICAqICAgICBjaGFpbi5zZXQoJ21vb3NlLnNpbXBsZScsIDEpXG4gICAqXG4gICAqICAgICB0b0FycihjaGFpbi5zdG9yZS5rZXlzKCkpXG4gICAqICAgICAvLz0+IFsnbW9vc2Uuc2ltcGxlJ11cbiAgICpcbiAgICovXG4gIFRhcmdldC5wcm90b3R5cGUuZG90ID0gZnVuY3Rpb24gZW5hYmxlRGlzYWJsZURvdCh1c2VEb3QpIHtcbiAgICB0aGlzLm1ldGEuZG90ID0gdXNlRG90XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzYyBzaW5jZSB3ZSBoYXZlIGEgbWFwLFxuICAgKiAgICAgICB3ZSBuZWVkIHRvIGVuc3VyZSB0aGUgZmlyc3QgcHJvcGVydHkgaXMgYXZhaWxhYmxlXG4gICAqICAgICAgIG90aGVyd2lzZSB3ZSBoYXZlIGFuIGVtcHR5IG1hcC5lbnRyaWVzIG9ialxuICAgKiAgICAgICB3aGljaCBkb2VzIG5vdGhpbmcgYnkgcmVmZXJlbmNlXG4gICAqIEBzaW5jZSAzLjAuMVxuICAgKiBAbWVtYmVyT2YgRG90UHJvcFxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQGluaGVyaXRkb2NcbiAgICpcbiAgICogQHNlZSBUYXJnZXRlZE1hcC5zZXRcbiAgICogQHNlZSAuZG90XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqICAgIGNvbnN0IGNoYWluID0gbmV3IFRhcmdldCgpXG4gICAqXG4gICAqICAgIGNoYWluLnNldCgnbW9vc2Uuc2ltcGxlJywgMSlcbiAgICogICAgLy89PiBUYXJnZXQgc3RvcmU6TWFwOiAgeyBtb29zZTogeyBzaW1wbGU6IDEgfSB9XG4gICAqL1xuICBUYXJnZXQucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIGRvdFNldChrZXksIHZhbCkge1xuICAgIGlmIChzaG91bGREb3Qoa2V5LCB0aGlzKSkge1xuICAgICAgLy8gZmlyc3QgYWNjZXNzb3JcbiAgICAgIC8vIEBleGFtcGxlOiBgY2FuYWRhYCBpbiBgY2FuYWRhLmVoYFxuICAgICAgLy8gQFRPRE8gY291bGQgdXNlIGBmaXJzdGBcbiAgICAgIC8vIEBOT1RFIHdhcyBgLnNoaWZ0YCBidXQgdGhpcyBpcyB0aGUgb25seSBgLnNoaWZ0YCBhbnl3aGVyZVxuICAgICAgY29uc3QgcHJvcCA9IGtleS5zcGxpdCgnLicpWzBdXG5cbiAgICAgIC8vIHdlIGFscmVhZHkga25vdyBpdCBpcyAuZG90LCBjYWxsIHN1cGVyIGluc3RlYWRcbiAgICAgIC8vIGlmICghc3VwZXIuaGFzKHByb3ApKSBzdXBlci5zZXQocHJvcCwge30pXG5cbiAgICAgIC8vIHNwcmVhZFxuICAgICAgY29uc3QgZGF0YSA9IGVudHJpZXMuY2FsbCh0aGlzKVxuXG4gICAgICAvLyBzZXQgb24gdGhlIHNwcmVhZCBkYXRhXG4gICAgICBkb3Quc2V0KGRhdGEsIGtleSwgdmFsKVxuXG4gICAgICAvLyBpcyBhbHJlYWR5IGJ5IHJlZiwgYnV0IGJlIGV4dHJhIHNhZmUsICsgb2JzZXJ2YWJsZXNcbiAgICAgIHJldHVybiBzZXQuY2FsbCh0aGlzLCBwcm9wLCBkYXRhW3Byb3BdLCBrZXkpXG4gICAgfVxuXG4gICAgcmV0dXJuIHNldC5jYWxsKHRoaXMsIGtleSwgdmFsKVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjIGRvdC1wcm9wIGVuYWJsZWQgZ2V0XG4gICAqIEBtZXRob2QgZ2V0XG4gICAqIEBtZW1iZXJPZiBEb3RQcm9wXG4gICAqXG4gICAqIEBzaW5jZSAzLjAuMVxuICAgKiBAb3ZlcnJpZGVcbiAgICogQGluaGVyaXRkb2NcbiAgICpcbiAgICogQHBhcmFtIHtQcmltaXRpdmV9IGtleSBkb3QgcHJvcCBrZXksIG9yIGFueSBwcmltaXRpdmUga2V5XG4gICAqIEBwYXJhbSB7YW55fSBbZmFsbGJhY2s9dW5kZWZpbmVkXSBmYWxsYmFjayB2YWx1ZSwgaWYgaXQgY2Fubm90IGZpbmQgdmFsdWUgd2l0aCBrZXkgcGF0aFxuICAgKiBAcmV0dXJuIHthbnl9IHZhbHVlIGZvciBwYXRoLCBvciBmYWxsYmFjayB2YWx1ZSBpZiBwcm92aWRlZFxuICAgKlxuICAgKiBAc2VlIENoYWluZWRNYXAuZ2V0XG4gICAqIEBzZWUgZGVwcy9kb3RcbiAgICogQHNlZSBkZXBzL2lzL2RvdFxuICAgKlxuICAgKiBAVE9ETyBkb3QtcHJvcCBvbiBub24tc3RvcmUgaW5zdGFuY2UucHJvcGVydHkgd2hlbiB1c2luZyBuZXN0ZWQgY2hhaW5zLi4uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICAgIGNoYWluLnNldCgnbW9vc2Uuc2ltcGxlJywgMSlcbiAgICogICAgLy89PiBDaGFpblxuICAgKlxuICAgKiAgICBjaGFpbi5nZXQoJ21vb3NlLnNpbXBsZScpXG4gICAqICAgIC8vPT4xXG4gICAqXG4gICAqICAgIGNoYWluLmdldCgnbW9vc2UnKVxuICAgKiAgICAvLz0+IHtzaW1wbGU6IDF9XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICAgIC8vYWxzbyB3b3JrcyB3aXRoIGFuIGFycmF5IChtb29zZS5zaW1wbGUpXG4gICAqICAgIGNoYWluLmdldChbJ21vb3NlJywgJ3NpbXBsZSddKVxuICAgKiAgICAvLz0+IDFcbiAgICpcbiAgICovXG4gIFRhcmdldC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gZG90R2V0KGtleSwgZmFsbGJhY2spIHtcbiAgICByZXR1cm4gc2hvdWxkRG90KGtleSwgdGhpcylcbiAgICAgID8gZG90LmdldChlbnRyaWVzLmNhbGwodGhpcyksIGtleSwgZmFsbGJhY2spXG4gICAgICA6IGdldC5jYWxsKHRoaXMsIGtleSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGhhc1xuICAgKiBAbWV0aG9kT2YgRG90UHJvcFxuICAgKiBAc2luY2UgMy4wLjFcbiAgICogQG92ZXJyaWRlXG4gICAqIEBpbmhlcml0ZG9jXG4gICAqXG4gICAqIEBzZWUgZGVwcy9kb3RcbiAgICogQHNlZSBkZXBzL2lzL2RvdFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgY2hhaW4uc2V0KCdvbmUudHdvJywgMylcbiAgICogIGNoYWluLmhhcygnb25lLnR3bycpXG4gICAqICAvLz0+IHRydWVcbiAgICpcbiAgICovXG4gIFRhcmdldC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gZG90SGFzKGtleSkge1xuICAgIHJldHVybiBzaG91bGREb3Qoa2V5LCB0aGlzKVxuICAgICAgPyBkb3QuaGFzKGVudHJpZXMuY2FsbCh0aGlzKSwga2V5KVxuICAgICAgOiBoYXMuY2FsbCh0aGlzLCBrZXkpXG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBkZWxldGVcbiAgICogQG1ldGhvZE9mIERvdFByb3BcbiAgICogQHNpbmNlIDMuMC4xXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAaW5oZXJpdGRvY1xuICAgKiBAc2VlIGRlcHMvZG90XG4gICAqIEBzZWUgZGVwcy9pcy9kb3RcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgY2hhaW4uc2V0KCdtb29zZS5jYW5hZGEuZWgnLCB0cnVlKVxuICAgKiAgICBjaGFpbi5zZXQoJ21vb3NlLmNhbmFkYS5pZ2xvbycsIHRydWUpXG4gICAqICAgIC8vPT4gQ2hhaW5cbiAgICpcbiAgICogICAgY2hhaW4uZGVsZXRlKCdtb29zZS5jYW5hZGEuZWgnKVxuICAgKiAgICAvLz0+IENoYWluXG4gICAqXG4gICAqICAgIGNoYWluLmhhcygnbW9vc2UuY2FuYWRhLmVoJylcbiAgICogICAgLy89PiB0cnVlXG4gICAqXG4gICAqICAgIC8vc3RpbGwgaGFzIG1vb3NlLmNhbmFkYS5pZ2xvb1xuICAgKiAgICBjaGFpbi5oYXMoJ21vb3NlLmNhbmFkYScpXG4gICAqICAgIC8vPT4gdHJ1ZVxuICAgKlxuICAgKi9cbiAgVGFyZ2V0LnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiBkb3REZWxldGUoa2V5KSB7XG4gICAgcmV0dXJuIHNob3VsZERvdChrZXksIHRoaXMpXG4gICAgICA/IGRvdC5kZWxldGUoZW50cmllcy5jYWxsKHRoaXMpLCBrZXkpXG4gICAgICA6IGRlbC5jYWxsKHRoaXMsIGtleSlcbiAgfVxuXG4gIHJldHVybiBUYXJnZXRcbn1cbiJdLCJuYW1lcyI6WyJjb25zdCJdLCJtYXBwaW5ncyI6IkFBQUE7OztBQUdBQSxHQUFLLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7QUFDbENBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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