(() => {
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
function $parcel$interopDefault(a) {
return a && a.__esModule ? a.default : a;
}
var $parcel$global = globalThis;
var parcelRequire = $parcel$global["parcelRequire2d1f"];
var parcelRegister = parcelRequire.register;
parcelRegister("KfUSb", function(module, exports) {
$parcel$export(module.exports, "ErrorBox", () => $6f57cf00b9107dc2$export$f04a3ea04edc0e04);
var $lAN3N = parcelRequire("lAN3N");
var $6YscK = parcelRequire("6YscK");
var $4WfNn = parcelRequire("4WfNn");
var $eoQBx = parcelRequire("eoQBx");
const $6f57cf00b9107dc2$export$f04a3ea04edc0e04 = (0, $6YscK.withErrorBoundary)(({ children: children, meta: meta, id: id })=>{
const local = (0, $4WfNn.useLocal)({
retrying: false
});
const [error, resetError] = (0, $6YscK.useErrorBoundary)((error, errorInfo)=>{
console.warn(error);
});
let _meta = meta;
if (id) {
const p = (0, $4WfNn.useGlobal)((0, $eoQBx.EditorGlobal), "EDITOR");
_meta = p.treeMeta[id];
}
if (error) return /*#__PURE__*/ (0, $lAN3N.jsxs)("div", {
className: "bg-red-100 border border-red-300 rounded-sm text-xs flex flex-col items-center",
children: [
/*#__PURE__*/ (0, $lAN3N.jsxs)("div", {
className: "text-[10px] font-bold text-red-900 self-stretch px-1",
children: [
"ERROR ",
_meta?.item.name ? "[" + _meta.item.name + "]:" : ""
]
}),
/*#__PURE__*/ (0, $lAN3N.jsx)("p", {
className: "border-b border-red-300 px-1 pb-1 min-w-[100px]",
children: !local.retrying ? /*#__PURE__*/ (0, $lAN3N.jsx)((0, $lAN3N.Fragment), {
children: error.message
}) : /*#__PURE__*/ (0, $lAN3N.jsx)((0, $lAN3N.Fragment), {
children: "Retrying..."
})
}),
/*#__PURE__*/ (0, $lAN3N.jsx)("div", {
className: "p-1",
children: /*#__PURE__*/ (0, $lAN3N.jsx)("button", {
onClick: ()=>{
local.retrying = true;
local.render();
setTimeout(()=>{
local.retrying = false;
local.render();
resetError();
}, 100);
},
className: "bg-white border border-white hover:border-red-400 hover:bg-red-50 rounded px-2",
children: "Try again"
})
})
]
});
return children;
});
});
parcelRegister("6YscK", function(module, exports) {
$parcel$export(module.exports, "withErrorBoundary", () => $513e398b8d7c384a$export$f0c7a449e0cfaec7);
$parcel$export(module.exports, "useErrorBoundary", () => $513e398b8d7c384a$export$c052f6604b7d51fe);
var $63SH6 = parcelRequire("63SH6");
class $513e398b8d7c384a$var$ErrorBoundary extends (0, $63SH6.Component) {
displayName = "ReactUseErrorBoundary";
componentDidCatch(...args) {
this.setState({});
this.props.onError(...args);
}
render() {
return this.props.children;
}
}
const $513e398b8d7c384a$var$noop = ()=>false;
const $513e398b8d7c384a$var$errorBoundaryContext = (0, $63SH6.createContext)({
componentDidCatch: {
current: undefined
},
error: undefined,
setError: $513e398b8d7c384a$var$noop
});
function $513e398b8d7c384a$export$b16d9fb1a22de840({ children: children }) {
const [error, setError] = (0, $63SH6.useState)();
const componentDidCatch = (0, $63SH6.useRef)();
const ctx = (0, $63SH6.useMemo)(()=>({
componentDidCatch: componentDidCatch,
error: error,
setError: setError
}), [
error
]);
return (0, (/*@__PURE__*/$parcel$interopDefault($63SH6))).createElement($513e398b8d7c384a$var$errorBoundaryContext.Provider, {
value: ctx
}, (0, (/*@__PURE__*/$parcel$interopDefault($63SH6))).createElement($513e398b8d7c384a$var$ErrorBoundary, {
error: error,
onError: (error, errorInfo)=>{
setError(error);
componentDidCatch.current?.(error, errorInfo);
}
}, children));
}
$513e398b8d7c384a$export$b16d9fb1a22de840.displayName = "ReactUseErrorBoundaryContext";
function $513e398b8d7c384a$export$f0c7a449e0cfaec7(WrappedComponent) {
function WithErrorBoundary(props) {
return (0, (/*@__PURE__*/$parcel$interopDefault($63SH6))).createElement($513e398b8d7c384a$export$b16d9fb1a22de840, null, (0, (/*@__PURE__*/$parcel$interopDefault($63SH6))).createElement(WrappedComponent, {
key: "WrappedComponent",
...props
}));
}
WithErrorBoundary.displayName = `WithErrorBoundary(${WrappedComponent.displayName ?? WrappedComponent.name ?? "Component"})`;
return WithErrorBoundary;
}
function $513e398b8d7c384a$export$c052f6604b7d51fe(componentDidCatch) {
const ctx = (0, $63SH6.useContext)($513e398b8d7c384a$var$errorBoundaryContext);
ctx.componentDidCatch.current = componentDidCatch;
const resetError = (0, $63SH6.useCallback)(()=>{
ctx.setError(undefined);
}, []);
return [
ctx.error,
resetError
];
}
});
parcelRegister("cc0Z8", function(module, exports) {
$parcel$export(module.exports, "produceCSS", () => $a5136eecc56dd26b$export$9aa016b1e696fa5);
var $97sHp = parcelRequire("97sHp");
var $6h4bB = parcelRequire("6h4bB");
var $4DQaz = parcelRequire("4DQaz");
var $5OYrM = parcelRequire("5OYrM");
var $hP8yR = parcelRequire("hP8yR");
var $7aIlQ = parcelRequire("7aIlQ");
var $8DV5m = parcelRequire("8DV5m");
var $kXTha = parcelRequire("kXTha");
const $a5136eecc56dd26b$export$9aa016b1e696fa5 = (item, arg)=>{
try {
return cx([
css`
display: flex;
position: relative;
user-select: none;
${(0, $8DV5m.cssLayout)(item, arg.mode)}
${(0, $kXTha.cssPadding)(item, arg.mode)}
${(0, $5OYrM.cssDimension)(item, arg.mode, arg?.editor)}
${(0, $4DQaz.cssBorder)(item, arg.mode)}
${(0, $6h4bB.cssBackground)(item, arg.mode)}
${(0, $7aIlQ.cssFont)(item, arg.mode)}
`,
(arg?.hover || arg?.active) && (0, $hP8yR.cssEditor)({
item: item,
hover: arg?.hover,
active: arg?.active
}),
(0, $97sHp.cssAdv)(item, arg.mode)
]);
} catch (e) {
console.log(e);
}
return cx([]);
};
});
parcelRegister("97sHp", function(module, exports) {
$parcel$export(module.exports, "cssAdv", () => $3be87ae1f3b1a139$export$e31c5a57cedf6cc4);
var $bjM6F = parcelRequire("bjM6F");
const $3be87ae1f3b1a139$export$e31c5a57cedf6cc4 = (cur, mode)=>{
const adv = (0, $bjM6F.responsiveVal)(cur, "adv", mode, {});
if (typeof adv.css === "string") {
const hasCSS = adv.css.trim();
if (hasCSS) return cx(css`
${adv.css}
`, "cel", mode);
}
return "";
};
});
parcelRegister("bjM6F", function(module, exports) {
$parcel$export(module.exports, "responsiveVal", () => $6e7c56e8133f20c8$export$95f6a25db452441e);
const $6e7c56e8133f20c8$export$95f6a25db452441e = (item, key, mode, defaultVal)=>{
let value = item[key];
if (mode === "desktop" || !mode) {
if (!value && item.mobile && item.mobile[key]) value = item.mobile[key];
} else if (item.mobile && item.mobile[key]) value = item.mobile[key];
if (!value) value = defaultVal;
return value;
};
});
parcelRegister("6h4bB", function(module, exports) {
$parcel$export(module.exports, "cssBackground", () => $d7ca42aaee6dc748$export$84db22eb9d90f957);
var $bjM6F = parcelRequire("bjM6F");
const $d7ca42aaee6dc748$export$84db22eb9d90f957 = (cur, mode)=>{
const bg = (0, $bjM6F.responsiveVal)(cur, "bg", mode, {
size: "contain",
pos: "center"
});
let bgurl = `${serverurl}${bg.url}`;
if (bg && bg.url && bg.url.startsWith("http")) bgurl = bg.url;
return cx(`
background-repeat: no-repeat;
`, bg.color && `
background-color: ${bg.color};
`, bg.url && typeof siteApiUrl === "string" && `
background-image: url("${bgurl}");
`, bg.size && `
background-size: ${bg.size};
`, bg.pos && `
background-position: ${bg.pos};
`);
};
});
parcelRegister("4DQaz", function(module, exports) {
$parcel$export(module.exports, "cssBorder", () => $08be68fb51c3d33e$export$ff51516858af6918);
var $cfpVL = parcelRequire("cfpVL");
var $bjM6F = parcelRequire("bjM6F");
const $08be68fb51c3d33e$export$ff51516858af6918 = (cur, mode)=>{
const border = (0, $bjM6F.responsiveVal)(cur, "border", mode, {
style: "solid",
stroke: {},
rounded: {
tr: 0,
tl: 0,
bl: 0,
br: 0
},
color: "transparent"
});
return cx($08be68fb51c3d33e$var$pick(border, "stroke.l", "border-left-width"), $08be68fb51c3d33e$var$pick(border, "stroke.r", "border-right-width"), $08be68fb51c3d33e$var$pick(border, "stroke.b", "border-bottom-width"), $08be68fb51c3d33e$var$pick(border, "stroke.t", "border-top-width"), $08be68fb51c3d33e$var$pick(border, "color", "border-color", "transparent"), $08be68fb51c3d33e$var$pick(border, "style", "border-style", "dashed"), $08be68fb51c3d33e$var$pick(border, "rounded.tl", "border-top-left-radius"), $08be68fb51c3d33e$var$pick(border, "rounded.tr", "border-top-right-radius"), $08be68fb51c3d33e$var$pick(border, "rounded.bl", "border-bottom-left-radius"), $08be68fb51c3d33e$var$pick(border, "rounded.br", "border-bottom-right-radius"));
};
const $08be68fb51c3d33e$var$pick = (obj, key, attr, notpx)=>{
const val = (0, (/*@__PURE__*/$parcel$interopDefault($cfpVL)))(obj, key);
if (notpx) {
if (val) return `${attr}: ${val};`;
else return `${attr}: ${notpx};`;
} else if (val) return `${attr}: ${val}px;`;
};
});
parcelRegister("cfpVL", function(module, exports) {
/**
* lodash (Custom Build)
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors
* Released under MIT license
* Based on Underscore.js 1.8.3
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/ /** Used as the `TypeError` message for "Functions" methods. */ var $024d14a53d6ce9fd$var$FUNC_ERROR_TEXT = "Expected a function";
/** Used to stand-in for `undefined` hash values. */ var $024d14a53d6ce9fd$var$HASH_UNDEFINED = "__lodash_hash_undefined__";
/** Used as references for various `Number` constants. */ var $024d14a53d6ce9fd$var$INFINITY = 1 / 0;
/** `Object#toString` result references. */ var $024d14a53d6ce9fd$var$funcTag = "[object Function]", $024d14a53d6ce9fd$var$genTag = "[object GeneratorFunction]", $024d14a53d6ce9fd$var$symbolTag = "[object Symbol]";
/** Used to match property names within property paths. */ var $024d14a53d6ce9fd$var$reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, $024d14a53d6ce9fd$var$reIsPlainProp = /^\w*$/, $024d14a53d6ce9fd$var$reLeadingDot = /^\./, $024d14a53d6ce9fd$var$rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/ var $024d14a53d6ce9fd$var$reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
/** Used to match backslashes in property paths. */ var $024d14a53d6ce9fd$var$reEscapeChar = /\\(\\)?/g;
/** Used to detect host constructors (Safari). */ var $024d14a53d6ce9fd$var$reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Detect free variable `global` from Node.js. */ var $024d14a53d6ce9fd$var$freeGlobal = typeof $parcel$global == "object" && $parcel$global && $parcel$global.Object === Object && $parcel$global;
/** Detect free variable `self`. */ var $024d14a53d6ce9fd$var$freeSelf = typeof self == "object" && self && self.Object === Object && self;
/** Used as a reference to the global object. */ var $024d14a53d6ce9fd$var$root = $024d14a53d6ce9fd$var$freeGlobal || $024d14a53d6ce9fd$var$freeSelf || Function("return this")();
/**
* Gets the value at `key` of `object`.
*
* @private
* @param {Object} [object] The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/ function $024d14a53d6ce9fd$var$getValue(object, key) {
return object == null ? undefined : object[key];
}
/**
* Checks if `value` is a host object in IE < 9.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
*/ function $024d14a53d6ce9fd$var$isHostObject(value) {
// Many host objects are `Object` objects that can coerce to strings
// despite having improperly defined `toString` methods.
var result = false;
if (value != null && typeof value.toString != "function") try {
result = !!(value + "");
} catch (e) {}
return result;
}
/** Used for built-in method references. */ var $024d14a53d6ce9fd$var$arrayProto = Array.prototype, $024d14a53d6ce9fd$var$funcProto = Function.prototype, $024d14a53d6ce9fd$var$objectProto = Object.prototype;
/** Used to detect overreaching core-js shims. */ var $024d14a53d6ce9fd$var$coreJsData = $024d14a53d6ce9fd$var$root["__core-js_shared__"];
/** Used to detect methods masquerading as native. */ var $024d14a53d6ce9fd$var$maskSrcKey = function() {
var uid = /[^.]+$/.exec($024d14a53d6ce9fd$var$coreJsData && $024d14a53d6ce9fd$var$coreJsData.keys && $024d14a53d6ce9fd$var$coreJsData.keys.IE_PROTO || "");
return uid ? "Symbol(src)_1." + uid : "";
}();
/** Used to resolve the decompiled source of functions. */ var $024d14a53d6ce9fd$var$funcToString = $024d14a53d6ce9fd$var$funcProto.toString;
/** Used to check objects for own properties. */ var $024d14a53d6ce9fd$var$hasOwnProperty = $024d14a53d6ce9fd$var$objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/ var $024d14a53d6ce9fd$var$objectToString = $024d14a53d6ce9fd$var$objectProto.toString;
/** Used to detect if a method is native. */ var $024d14a53d6ce9fd$var$reIsNative = RegExp("^" + $024d14a53d6ce9fd$var$funcToString.call($024d14a53d6ce9fd$var$hasOwnProperty).replace($024d14a53d6ce9fd$var$reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$");
/** Built-in value references. */ var $024d14a53d6ce9fd$var$Symbol = $024d14a53d6ce9fd$var$root.Symbol, $024d14a53d6ce9fd$var$splice = $024d14a53d6ce9fd$var$arrayProto.splice;
/* Built-in method references that are verified to be native. */ var $024d14a53d6ce9fd$var$Map = $024d14a53d6ce9fd$var$getNative($024d14a53d6ce9fd$var$root, "Map"), $024d14a53d6ce9fd$var$nativeCreate = $024d14a53d6ce9fd$var$getNative(Object, "create");
/** Used to convert symbols to primitives and strings. */ var $024d14a53d6ce9fd$var$symbolProto = $024d14a53d6ce9fd$var$Symbol ? $024d14a53d6ce9fd$var$Symbol.prototype : undefined, $024d14a53d6ce9fd$var$symbolToString = $024d14a53d6ce9fd$var$symbolProto ? $024d14a53d6ce9fd$var$symbolProto.toString : undefined;
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/ function $024d14a53d6ce9fd$var$Hash(entries) {
var index = -1, length = entries ? entries.length : 0;
this.clear();
while(++index < length){
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the hash.
*
* @private
* @name clear
* @memberOf Hash
*/ function $024d14a53d6ce9fd$var$hashClear() {
this.__data__ = $024d14a53d6ce9fd$var$nativeCreate ? $024d14a53d6ce9fd$var$nativeCreate(null) : {};
}
/**
* Removes `key` and its value from the hash.
*
* @private
* @name delete
* @memberOf Hash
* @param {Object} hash The hash to modify.
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/ function $024d14a53d6ce9fd$var$hashDelete(key) {
return this.has(key) && delete this.__data__[key];
}
/**
* Gets the hash value for `key`.
*
* @private
* @name get
* @memberOf Hash
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/ function $024d14a53d6ce9fd$var$hashGet(key) {
var data = this.__data__;
if ($024d14a53d6ce9fd$var$nativeCreate) {
var result = data[key];
return result === $024d14a53d6ce9fd$var$HASH_UNDEFINED ? undefined : result;
}
return $024d14a53d6ce9fd$var$hasOwnProperty.call(data, key) ? data[key] : undefined;
}
/**
* Checks if a hash value for `key` exists.
*
* @private
* @name has
* @memberOf Hash
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/ function $024d14a53d6ce9fd$var$hashHas(key) {
var data = this.__data__;
return $024d14a53d6ce9fd$var$nativeCreate ? data[key] !== undefined : $024d14a53d6ce9fd$var$hasOwnProperty.call(data, key);
}
/**
* Sets the hash `key` to `value`.
*
* @private
* @name set
* @memberOf Hash
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the hash instance.
*/ function $024d14a53d6ce9fd$var$hashSet(key, value) {
var data = this.__data__;
data[key] = $024d14a53d6ce9fd$var$nativeCreate && value === undefined ? $024d14a53d6ce9fd$var$HASH_UNDEFINED : value;
return this;
}
// Add methods to `Hash`.
$024d14a53d6ce9fd$var$Hash.prototype.clear = $024d14a53d6ce9fd$var$hashClear;
$024d14a53d6ce9fd$var$Hash.prototype["delete"] = $024d14a53d6ce9fd$var$hashDelete;
$024d14a53d6ce9fd$var$Hash.prototype.get = $024d14a53d6ce9fd$var$hashGet;
$024d14a53d6ce9fd$var$Hash.prototype.has = $024d14a53d6ce9fd$var$hashHas;
$024d14a53d6ce9fd$var$Hash.prototype.set = $024d14a53d6ce9fd$var$hashSet;
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/ function $024d14a53d6ce9fd$var$ListCache(entries) {
var index = -1, length = entries ? entries.length : 0;
this.clear();
while(++index < length){
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the list cache.
*
* @private
* @name clear
* @memberOf ListCache
*/ function $024d14a53d6ce9fd$var$listCacheClear() {
this.__data__ = [];
}
/**
* Removes `key` and its value from the list cache.
*
* @private
* @name delete
* @memberOf ListCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/ function $024d14a53d6ce9fd$var$listCacheDelete(key) {
var data = this.__data__, index = $024d14a53d6ce9fd$var$assocIndexOf(data, key);
if (index < 0) return false;
var lastIndex = data.length - 1;
if (index == lastIndex) data.pop();
else $024d14a53d6ce9fd$var$splice.call(data, index, 1);
return true;
}
/**
* Gets the list cache value for `key`.
*
* @private
* @name get
* @memberOf ListCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/ function $024d14a53d6ce9fd$var$listCacheGet(key) {
var data = this.__data__, index = $024d14a53d6ce9fd$var$assocIndexOf(data, key);
return index < 0 ? undefined : data[index][1];
}
/**
* Checks if a list cache value for `key` exists.
*
* @private
* @name has
* @memberOf ListCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/ function $024d14a53d6ce9fd$var$listCacheHas(key) {
return $024d14a53d6ce9fd$var$assocIndexOf(this.__data__, key) > -1;
}
/**
* Sets the list cache `key` to `value`.
*
* @private
* @name set
* @memberOf ListCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the list cache instance.
*/ function $024d14a53d6ce9fd$var$listCacheSet(key, value) {
var data = this.__data__, index = $024d14a53d6ce9fd$var$assocIndexOf(data, key);
if (index < 0) data.push([
key,
value
]);
else data[index][1] = value;
return this;
}
// Add methods to `ListCache`.
$024d14a53d6ce9fd$var$ListCache.prototype.clear = $024d14a53d6ce9fd$var$listCacheClear;
$024d14a53d6ce9fd$var$ListCache.prototype["delete"] = $024d14a53d6ce9fd$var$listCacheDelete;
$024d14a53d6ce9fd$var$ListCache.prototype.get = $024d14a53d6ce9fd$var$listCacheGet;
$024d14a53d6ce9fd$var$ListCache.prototype.has = $024d14a53d6ce9fd$var$listCacheHas;
$024d14a53d6ce9fd$var$ListCache.prototype.set = $024d14a53d6ce9fd$var$listCacheSet;
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/ function $024d14a53d6ce9fd$var$MapCache(entries) {
var index = -1, length = entries ? entries.length : 0;
this.clear();
while(++index < length){
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the map.
*
* @private
* @name clear
* @memberOf MapCache
*/ function $024d14a53d6ce9fd$var$mapCacheClear() {
this.__data__ = {
"hash": new $024d14a53d6ce9fd$var$Hash,
"map": new ($024d14a53d6ce9fd$var$Map || $024d14a53d6ce9fd$var$ListCache),
"string": new $024d14a53d6ce9fd$var$Hash
};
}
/**
* Removes `key` and its value from the map.
*
* @private
* @name delete
* @memberOf MapCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/ function $024d14a53d6ce9fd$var$mapCacheDelete(key) {
return $024d14a53d6ce9fd$var$getMapData(this, key)["delete"](key);
}
/**
* Gets the map value for `key`.
*
* @private
* @name get
* @memberOf MapCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/ function $024d14a53d6ce9fd$var$mapCacheGet(key) {
return $024d14a53d6ce9fd$var$getMapData(this, key).get(key);
}
/**
* Checks if a map value for `key` exists.
*
* @private
* @name has
* @memberOf MapCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/ function $024d14a53d6ce9fd$var$mapCacheHas(key) {
return $024d14a53d6ce9fd$var$getMapData(this, key).has(key);
}
/**
* Sets the map `key` to `value`.
*
* @private
* @name set
* @memberOf MapCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the map cache instance.
*/ function $024d14a53d6ce9fd$var$mapCacheSet(key, value) {
$024d14a53d6ce9fd$var$getMapData(this, key).set(key, value);
return this;
}
// Add methods to `MapCache`.
$024d14a53d6ce9fd$var$MapCache.prototype.clear = $024d14a53d6ce9fd$var$mapCacheClear;
$024d14a53d6ce9fd$var$MapCache.prototype["delete"] = $024d14a53d6ce9fd$var$mapCacheDelete;
$024d14a53d6ce9fd$var$MapCache.prototype.get = $024d14a53d6ce9fd$var$mapCacheGet;
$024d14a53d6ce9fd$var$MapCache.prototype.has = $024d14a53d6ce9fd$var$mapCacheHas;
$024d14a53d6ce9fd$var$MapCache.prototype.set = $024d14a53d6ce9fd$var$mapCacheSet;
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/ function $024d14a53d6ce9fd$var$assocIndexOf(array, key) {
var length = array.length;
while(length--){
if ($024d14a53d6ce9fd$var$eq(array[length][0], key)) return length;
}
return -1;
}
/**
* The base implementation of `_.get` without support for default values.
*
* @private
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @returns {*} Returns the resolved value.
*/ function $024d14a53d6ce9fd$var$baseGet(object, path) {
path = $024d14a53d6ce9fd$var$isKey(path, object) ? [
path
] : $024d14a53d6ce9fd$var$castPath(path);
var index = 0, length = path.length;
while(object != null && index < length)object = object[$024d14a53d6ce9fd$var$toKey(path[index++])];
return index && index == length ? object : undefined;
}
/**
* The base implementation of `_.isNative` without bad shim checks.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function,
* else `false`.
*/ function $024d14a53d6ce9fd$var$baseIsNative(value) {
if (!$024d14a53d6ce9fd$var$isObject(value) || $024d14a53d6ce9fd$var$isMasked(value)) return false;
var pattern = $024d14a53d6ce9fd$var$isFunction(value) || $024d14a53d6ce9fd$var$isHostObject(value) ? $024d14a53d6ce9fd$var$reIsNative : $024d14a53d6ce9fd$var$reIsHostCtor;
return pattern.test($024d14a53d6ce9fd$var$toSource(value));
}
/**
* The base implementation of `_.toString` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/ function $024d14a53d6ce9fd$var$baseToString(value) {
// Exit early for strings to avoid a performance hit in some environments.
if (typeof value == "string") return value;
if ($024d14a53d6ce9fd$var$isSymbol(value)) return $024d14a53d6ce9fd$var$symbolToString ? $024d14a53d6ce9fd$var$symbolToString.call(value) : "";
var result = value + "";
return result == "0" && 1 / value == -$024d14a53d6ce9fd$var$INFINITY ? "-0" : result;
}
/**
* Casts `value` to a path array if it's not one.
*
* @private
* @param {*} value The value to inspect.
* @returns {Array} Returns the cast property path array.
*/ function $024d14a53d6ce9fd$var$castPath(value) {
return $024d14a53d6ce9fd$var$isArray(value) ? value : $024d14a53d6ce9fd$var$stringToPath(value);
}
/**
* Gets the data for `map`.
*
* @private
* @param {Object} map The map to query.
* @param {string} key The reference key.
* @returns {*} Returns the map data.
*/ function $024d14a53d6ce9fd$var$getMapData(map, key) {
var data = map.__data__;
return $024d14a53d6ce9fd$var$isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
}
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/ function $024d14a53d6ce9fd$var$getNative(object, key) {
var value = $024d14a53d6ce9fd$var$getValue(object, key);
return $024d14a53d6ce9fd$var$baseIsNative(value) ? value : undefined;
}
/**
* Checks if `value` is a property name and not a property path.
*
* @private
* @param {*} value The value to check.
* @param {Object} [object] The object to query keys on.
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
*/ function $024d14a53d6ce9fd$var$isKey(value, object) {
if ($024d14a53d6ce9fd$var$isArray(value)) return false;
var type = typeof value;
if (type == "number" || type == "symbol" || type == "boolean" || value == null || $024d14a53d6ce9fd$var$isSymbol(value)) return true;
return $024d14a53d6ce9fd$var$reIsPlainProp.test(value) || !$024d14a53d6ce9fd$var$reIsDeepProp.test(value) || object != null && value in Object(object);
}
/**
* Checks if `value` is suitable for use as unique object key.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
*/ function $024d14a53d6ce9fd$var$isKeyable(value) {
var type = typeof value;
return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null;
}
/**
* Checks if `func` has its source masked.
*
* @private
* @param {Function} func The function to check.
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
*/ function $024d14a53d6ce9fd$var$isMasked(func) {
return !!$024d14a53d6ce9fd$var$maskSrcKey && $024d14a53d6ce9fd$var$maskSrcKey in func;
}
/**
* Converts `string` to a property path array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the property path array.
*/ var $024d14a53d6ce9fd$var$stringToPath = $024d14a53d6ce9fd$var$memoize(function(string) {
string = $024d14a53d6ce9fd$var$toString(string);
var result = [];
if ($024d14a53d6ce9fd$var$reLeadingDot.test(string)) result.push("");
string.replace($024d14a53d6ce9fd$var$rePropName, function(match, number, quote, string) {
result.push(quote ? string.replace($024d14a53d6ce9fd$var$reEscapeChar, "$1") : number || match);
});
return result;
});
/**
* Converts `value` to a string key if it's not a string or symbol.
*
* @private
* @param {*} value The value to inspect.
* @returns {string|symbol} Returns the key.
*/ function $024d14a53d6ce9fd$var$toKey(value) {
if (typeof value == "string" || $024d14a53d6ce9fd$var$isSymbol(value)) return value;
var result = value + "";
return result == "0" && 1 / value == -$024d14a53d6ce9fd$var$INFINITY ? "-0" : result;
}
/**
* Converts `func` to its source code.
*
* @private
* @param {Function} func The function to process.
* @returns {string} Returns the source code.
*/ function $024d14a53d6ce9fd$var$toSource(func) {
if (func != null) {
try {
return $024d14a53d6ce9fd$var$funcToString.call(func);
} catch (e) {}
try {
return func + "";
} catch (e) {}
}
return "";
}
/**
* Creates a function that memoizes the result of `func`. If `resolver` is
* provided, it determines the cache key for storing the result based on the
* arguments provided to the memoized function. By default, the first argument
* provided to the memoized function is used as the map cache key. The `func`
* is invoked with the `this` binding of the memoized function.
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
* constructor with one whose instances implement the
* [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
* method interface of `delete`, `get`, `has`, and `set`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to have its output memoized.
* @param {Function} [resolver] The function to resolve the cache key.
* @returns {Function} Returns the new memoized function.
* @example
*
* var object = { 'a': 1, 'b': 2 };
* var other = { 'c': 3, 'd': 4 };
*
* var values = _.memoize(_.values);
* values(object);
* // => [1, 2]
*
* values(other);
* // => [3, 4]
*
* object.a = 2;
* values(object);
* // => [1, 2]
*
* // Modify the result cache.
* values.cache.set(object, ['a', 'b']);
* values(object);
* // => ['a', 'b']
*
* // Replace `_.memoize.Cache`.
* _.memoize.Cache = WeakMap;
*/ function $024d14a53d6ce9fd$var$memoize(func, resolver) {
if (typeof func != "function" || resolver && typeof resolver != "function") throw new TypeError($024d14a53d6ce9fd$var$FUNC_ERROR_TEXT);
var memoized = function() {
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache = memoized.cache;
if (cache.has(key)) return cache.get(key);
var result = func.apply(this, args);
memoized.cache = cache.set(key, result);
return result;
};
memoized.cache = new ($024d14a53d6ce9fd$var$memoize.Cache || $024d14a53d6ce9fd$var$MapCache);
return memoized;
}
// Assign cache to `_.memoize`.
$024d14a53d6ce9fd$var$memoize.Cache = $024d14a53d6ce9fd$var$MapCache;
/**
* Performs a
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.eq(object, object);
* // => true
*
* _.eq(object, other);
* // => false
*
* _.eq('a', 'a');
* // => true
*
* _.eq('a', Object('a'));
* // => false
*
* _.eq(NaN, NaN);
* // => true
*/ function $024d14a53d6ce9fd$var$eq(value, other) {
return value === other || value !== value && other !== other;
}
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/ var $024d14a53d6ce9fd$var$isArray = Array.isArray;
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/ function $024d14a53d6ce9fd$var$isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8-9 which returns 'object' for typed array and other constructors.
var tag = $024d14a53d6ce9fd$var$isObject(value) ? $024d14a53d6ce9fd$var$objectToString.call(value) : "";
return tag == $024d14a53d6ce9fd$var$funcTag || tag == $024d14a53d6ce9fd$var$genTag;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/ function $024d14a53d6ce9fd$var$isObject(value) {
var type = typeof value;
return !!value && (type == "object" || type == "function");
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/ function $024d14a53d6ce9fd$var$isObjectLike(value) {
return !!value && typeof value == "object";
}
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/ function $024d14a53d6ce9fd$var$isSymbol(value) {
return typeof value == "symbol" || $024d14a53d6ce9fd$var$isObjectLike(value) && $024d14a53d6ce9fd$var$objectToString.call(value) == $024d14a53d6ce9fd$var$symbolTag;
}
/**
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {string} Returns the string.
* @example
*
* _.toString(null);
* // => ''
*
* _.toString(-0);
* // => '-0'
*
* _.toString([1, 2, 3]);
* // => '1,2,3'
*/ function $024d14a53d6ce9fd$var$toString(value) {
return value == null ? "" : $024d14a53d6ce9fd$var$baseToString(value);
}
/**
* Gets the value at `path` of `object`. If the resolved value is
* `undefined`, the `defaultValue` is returned in its place.
*
* @static
* @memberOf _
* @since 3.7.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
* @returns {*} Returns the resolved value.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
*
* _.get(object, 'a[0].b.c');
* // => 3
*
* _.get(object, ['a', '0', 'b', 'c']);
* // => 3
*
* _.get(object, 'a.b.c', 'default');
* // => 'default'
*/ function $024d14a53d6ce9fd$var$get(object, path, defaultValue) {
var result = object == null ? undefined : $024d14a53d6ce9fd$var$baseGet(object, path);
return result === undefined ? defaultValue : result;
}
module.exports = $024d14a53d6ce9fd$var$get;
});
parcelRegister("5OYrM", function(module, exports) {
$parcel$export(module.exports, "cssDimension", () => $e97d39c9eeea8f30$export$8332787d62a8b259);
var $bjM6F = parcelRequire("bjM6F");
const $e97d39c9eeea8f30$export$8332787d62a8b259 = (cur, mode, editor)=>{
const dim = (0, $bjM6F.responsiveVal)(cur, "dim", mode, {
h: "fit",
w: "fit"
});
if (dim.w === "full" && dim.h === "full") return `
width:100%;
height:100%;
flex:1;
`;
return cx(dim.w === "fit" && `
& > .txt-box > * {
white-space: nowrap !important;
}
`, dim.w === "full" && `
width: 100%;
`, dim.w && typeof dim.w === "number" && dim.w >= 0 && `
width: ${dim.w}${dim.wUnit || "px"};
overflow-x: clip;
`, dim.h === "full" && `
height: ${editor ? "100%" : "100" + (cur.type === "section" ? mode === "mobile" ? "vh" : "vh" : "%")};
margin-bottom: auto;
`, dim.h && typeof dim.h === "number" && dim.h >= 0 && `
height: ${dim.h}${dim.hUnit || "px"};
overflow-y: clip;
`);
};
});
parcelRegister("hP8yR", function(module, exports) {
$parcel$export(module.exports, "cssEditor", () => $030198a0121d3861$export$e95d45482966d82e);
const $030198a0121d3861$export$e95d45482966d82e = ({ item: item, hover: hover, active: active })=>{
return cx(hover && css`
& {
box-shadow: inset 0 0 0px 3px #bae3fd;
> img {
opacity: 0.6;
}
}
`, active && css`
box-shadow: inset 0 0 0px 2px #009cff !important;
> img {
opacity: 0.6;
}
`);
};
});
parcelRegister("7aIlQ", function(module, exports) {
$parcel$export(module.exports, "cssFont", () => $fcd82c898ee5312d$export$d123feaf05ec1c83);
var $bjM6F = parcelRequire("bjM6F");
const $fcd82c898ee5312d$export$47010e6cb2852826 = window;
const $fcd82c898ee5312d$export$d123feaf05ec1c83 = (cur, mode)=>{
const font = (0, $bjM6F.responsiveVal)(cur, "font", mode, {});
if (font.family) {
if (!$fcd82c898ee5312d$export$47010e6cb2852826.loadedFonts) $fcd82c898ee5312d$export$47010e6cb2852826.loadedFonts = [];
const weight = `:wght@${[
300,
400,
500,
600
].join(";")}`;
const fontName = font.family.replace(/ /g, "+");
if ($fcd82c898ee5312d$export$47010e6cb2852826.loadedFonts.indexOf(font.family) < 0) {
$fcd82c898ee5312d$export$47010e6cb2852826.loadedFonts.push(font.family);
const doc = document;
const _href = `https://fonts.googleapis.com/css2?family=${fontName}${weight}&display=block`;
if (!doc.querySelector(`link[href="${_href}]`)) {
const link = doc.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = _href;
doc.head.appendChild(link);
}
}
}
if (!font.family && $fcd82c898ee5312d$export$47010e6cb2852826.defaultFont) font.family = $fcd82c898ee5312d$export$47010e6cb2852826.defaultFont;
return cx(font.color && `
color: ${font.color};
`, `
word-break: ${font.whitespace === "whitespace-normal" ? "break-word" : "normal"};
`, font.color && `
color: ${font.color};
`, `
text-align: ${font.align ? font.align : "left"};
`, font.size && `
font-size: ${font.size || 15}px;
`, font.height && `
line-height: ${font.height === "auto" ? "normal" : `${font.height}%`};
`, font.family && `
font-family: ${font.family};
`);
};
});
parcelRegister("8DV5m", function(module, exports) {
$parcel$export(module.exports, "cssLayout", () => $d5c91ba13c38aefc$export$5c677b0cb632cad);
var $bjM6F = parcelRequire("bjM6F");
const $d5c91ba13c38aefc$export$5c677b0cb632cad = (cur, mode)=>{
const result = [];
let layout = (0, $bjM6F.responsiveVal)(cur, "layout", mode, {
dir: "col",
align: "top-left",
gap: 0,
wrap: undefined
});
if (layout) {
if (layout.wrap) result.push(layout.wrap === "flex-wrap" ? "flex-wrap: wrap;" : "flex-wrap: nowrap;");
if (layout.dir.startsWith("col")) {
if (layout.dir === "col") result.push("flex-direction: column;");
else if (layout.dir === "col-reverse") result.push("flex-direction: column-reverse;");
if (layout.gap === "auto") {
if (layout.align === "left") result.push("align-items:start; justify-content: space-between;");
if (layout.align === "center") result.push("align-items:center; justify-content: space-between;");
if (layout.align === "right") result.push("align-items:end; justify-content: space-between;");
} else {
result.push(`gap: ${layout.gap}px;`);
if (layout.align === "top-left") result.push("align-items:start; justify-content: start;");
if (layout.align === "top-center") result.push("align-items:center; justify-content: start;");
if (layout.align === "top-right") result.push("align-items:end; justify-content: start;");
if (layout.align === "left") result.push("align-items:start; justify-content: center;");
if (layout.align === "center") result.push("align-items:center; justify-content: center;");
if (layout.align === "right") result.push("align-items:end; justify-content: center;");
if (layout.align === "bottom-left") result.push("align-items:start; justify-content: end;");
if (layout.align === "bottom-center") result.push("align-items:center; justify-content: end;");
if (layout.align === "bottom-right") result.push("align-items:end; justify-content: end;");
}
} else {
if (layout.dir === "row") result.push("flex-direction: row;");
else if (layout.dir === "row-reverse") result.push("flex-direction: row-reverse;");
if (layout.gap === "auto") {
if (layout.align === "top") result.push("align-items:start; justify-content: space-between;");
if (layout.align === "center") result.push("align-items:center; justify-content: space-between;");
if (layout.align === "bottom") result.push("align-items:end; justify-content: space-between;");
} else {
result.push(`
gap: ${layout.gap}px;
`);
if (layout.align === "top-left") result.push("align-items:start; justify-content: start;");
if (layout.align === "top-center") result.push("align-items:start; justify-content: center;");
if (layout.align === "top-right") result.push("align-items:start; justify-content: end;");
if (layout.align === "left") result.push("align-items:center; justify-content: start;");
if (layout.align === "center") result.push("align-items:center; justify-content: center;");
if (layout.align === "right") result.push("align-items:center; justify-content: end;");
if (layout.align === "bottom-left") result.push("align-items:end; justify-content: start;");
if (layout.align === "bottom-center") result.push("align-items:end; justify-content: center;");
if (layout.align === "bottom-right") result.push("align-items:end; justify-content: end;");
}
}
} else return "flex-direction:column; align-items:start; justify-content: start;";
return result.join("\n ").trim();
};
});
parcelRegister("kXTha", function(module, exports) {
$parcel$export(module.exports, "cssPadding", () => $ed2a90866c5a1750$export$e9df5348ba4716b1);
var $bjM6F = parcelRequire("bjM6F");
const $ed2a90866c5a1750$export$e9df5348ba4716b1 = (cur, mode)=>{
const padding = (0, $bjM6F.responsiveVal)(cur, "padding", mode, {
l: 0,
b: 0,
t: 0,
r: 0
});
return cx(padding.l !== undefined && `
padding-left: ${padding.l}px;
`, padding.r !== undefined && `
padding-right: ${padding.r}px;
`, padding.b !== undefined && `
padding-bottom: ${padding.b}px;
`, padding.t !== undefined && `
padding-top: ${padding.t}px;
`);
};
});
parcelRegister("aVHaH", function(module, exports) {
$parcel$export(module.exports, "Doc", () => $52a83e33f2b9e935$export$bceacc74c2212615);
$parcel$export(module.exports, "Array", () => $52a83e33f2b9e935$export$c4be6576ca6fe4aa);
$parcel$export(module.exports, "Text", () => $52a83e33f2b9e935$export$5f1af8db9871e1d6);
$parcel$export(module.exports, "Map", () => $52a83e33f2b9e935$export$a5c7b93649eaf8f8);
$parcel$export(module.exports, "applyUpdate", () => $52a83e33f2b9e935$export$c271737a9c02e925);
$parcel$export(module.exports, "encodeStateAsUpdate", () => $52a83e33f2b9e935$export$e5848df80e65bd53);
$parcel$export(module.exports, "encodeStateVector", () => $52a83e33f2b9e935$export$3e2f5393f32e71f);
var $9XqiC = parcelRequire("9XqiC");
var $7sfdv = parcelRequire("7sfdv");
var $kuitL = parcelRequire("kuitL");
var $e6DQe = parcelRequire("e6DQe");
var $1p1sv = parcelRequire("1p1sv");
var $f5RS8 = parcelRequire("f5RS8");
var $TGOcE = parcelRequire("TGOcE");
var $jKNqA = parcelRequire("jKNqA");
var $lB8LX = parcelRequire("lB8LX");
var $akmFO = parcelRequire("akmFO");
var $1GdQd = parcelRequire("1GdQd");
var $kXTKb = parcelRequire("kXTKb");
var $gB6ZU = parcelRequire("gB6ZU");
var $dcfNU = parcelRequire("dcfNU");
var $7i7Pw = parcelRequire("7i7Pw");
var $1oyOX = parcelRequire("1oyOX");
var $6rcMi = parcelRequire("6rcMi");
var $aP2RX = parcelRequire("aP2RX");
var $97qUn = parcelRequire("97qUn");
/**
* This is an abstract interface that all Connectors should implement to keep them interchangeable.
*
* @note This interface is experimental and it is not advised to actually inherit this class.
* It just serves as typing information.
*
* @extends {Observable}
*/ class $52a83e33f2b9e935$export$c3faceeb92aa39dd extends (0, $9XqiC.Observable) {
/**
* @param {Doc} ydoc
* @param {any} awareness
*/ constructor(ydoc, awareness){
super();
this.doc = ydoc;
this.awareness = awareness;
}
}
class $52a83e33f2b9e935$var$DeleteItem {
/**
* @param {number} clock
* @param {number} len
*/ constructor(clock, len){
/**
* @type {number}
*/ this.clock = clock;
/**
* @type {number}
*/ this.len = len;
}
}
/**
* We no longer maintain a DeleteStore. DeleteSet is a temporary object that is created when needed.
* - When created in a transaction, it must only be accessed after sorting, and merging
* - This DeleteSet is send to other clients
* - We do not create a DeleteSet when we send a sync message. The DeleteSet message is created directly from StructStore
* - We read a DeleteSet as part of a sync/update message. In this case the DeleteSet is already sorted and merged.
*/ class $52a83e33f2b9e935$var$DeleteSet {
constructor(){
/**
* @type {Map>}
*/ this.clients = new Map();
}
}
/**
* Iterate over all structs that the DeleteSet gc's.
*
* @param {Transaction} transaction
* @param {DeleteSet} ds
* @param {function(GC|Item):void} f
*
* @function
*/ const $52a83e33f2b9e935$export$8afefebbaf4e4c78 = (transaction, ds, f)=>ds.clients.forEach((deletes, clientid)=>{
const structs = /** @type {Array} */ transaction.doc.store.clients.get(clientid);
for(let i = 0; i < deletes.length; i++){
const del = deletes[i];
$52a83e33f2b9e935$var$iterateStructs(transaction, structs, del.clock, del.len, f);
}
});
/**
* @param {Array} dis
* @param {number} clock
* @return {number|null}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$findIndexDS = (dis, clock)=>{
let left = 0;
let right = dis.length - 1;
while(left <= right){
const midindex = $kuitL.floor((left + right) / 2);
const mid = dis[midindex];
const midclock = mid.clock;
if (midclock <= clock) {
if (clock < midclock + mid.len) return midindex;
left = midindex + 1;
} else right = midindex - 1;
}
return null;
};
/**
* @param {DeleteSet} ds
* @param {ID} id
* @return {boolean}
*
* @private
* @function
*/ const $52a83e33f2b9e935$export$dcb04af092e44fde = (ds, id)=>{
const dis = ds.clients.get(id.client);
return dis !== undefined && $52a83e33f2b9e935$var$findIndexDS(dis, id.clock) !== null;
};
/**
* @param {DeleteSet} ds
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$sortAndMergeDeleteSet = (ds)=>{
ds.clients.forEach((dels)=>{
dels.sort((a, b)=>a.clock - b.clock);
// merge items without filtering or splicing the array
// i is the current pointer
// j refers to the current insert position for the pointed item
// try to merge dels[i] into dels[j-1] or set dels[j]=dels[i]
let i, j;
for(i = 1, j = 1; i < dels.length; i++){
const left = dels[j - 1];
const right = dels[i];
if (left.clock + left.len >= right.clock) left.len = $kuitL.max(left.len, right.clock + right.len - left.clock);
else {
if (j < i) dels[j] = right;
j++;
}
}
dels.length = j;
});
};
/**
* @param {Array} dss
* @return {DeleteSet} A fresh DeleteSet
*/ const $52a83e33f2b9e935$var$mergeDeleteSets = (dss)=>{
const merged = new $52a83e33f2b9e935$var$DeleteSet();
for(let dssI = 0; dssI < dss.length; dssI++)dss[dssI].clients.forEach((delsLeft, client)=>{
if (!merged.clients.has(client)) {
// Write all missing keys from current ds and all following.
// If merged already contains `client` current ds has already been added.
/**
* @type {Array}
*/ const dels = delsLeft.slice();
for(let i = dssI + 1; i < dss.length; i++)$7sfdv.appendTo(dels, dss[i].clients.get(client) || []);
merged.clients.set(client, dels);
}
});
$52a83e33f2b9e935$var$sortAndMergeDeleteSet(merged);
return merged;
};
/**
* @param {DeleteSet} ds
* @param {number} client
* @param {number} clock
* @param {number} length
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$addToDeleteSet = (ds, client, clock, length)=>{
$e6DQe.setIfUndefined(ds.clients, client, ()=>/** @type {Array} */ []).push(new $52a83e33f2b9e935$var$DeleteItem(clock, length));
};
const $52a83e33f2b9e935$export$8cbac0d946238699 = ()=>new $52a83e33f2b9e935$var$DeleteSet();
/**
* @param {StructStore} ss
* @return {DeleteSet} Merged and sorted DeleteSet
*
* @private
* @function
*/ const $52a83e33f2b9e935$export$8450d668bec558e2 = (ss)=>{
const ds = $52a83e33f2b9e935$export$8cbac0d946238699();
ss.clients.forEach((structs, client)=>{
/**
* @type {Array}
*/ const dsitems = [];
for(let i = 0; i < structs.length; i++){
const struct = structs[i];
if (struct.deleted) {
const clock = struct.id.clock;
let len = struct.length;
if (i + 1 < structs.length) for(let next = structs[i + 1]; i + 1 < structs.length && next.deleted; next = structs[++i + 1])len += next.length;
dsitems.push(new $52a83e33f2b9e935$var$DeleteItem(clock, len));
}
}
if (dsitems.length > 0) ds.clients.set(client, dsitems);
});
return ds;
};
/**
* @param {DSEncoderV1 | DSEncoderV2} encoder
* @param {DeleteSet} ds
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$writeDeleteSet = (encoder, ds)=>{
$1p1sv.writeVarUint(encoder.restEncoder, ds.clients.size);
// Ensure that the delete set is written in a deterministic order
$7sfdv.from(ds.clients.entries()).sort((a, b)=>b[0] - a[0]).forEach(([client, dsitems])=>{
encoder.resetDsCurVal();
$1p1sv.writeVarUint(encoder.restEncoder, client);
const len = dsitems.length;
$1p1sv.writeVarUint(encoder.restEncoder, len);
for(let i = 0; i < len; i++){
const item = dsitems[i];
encoder.writeDsClock(item.clock);
encoder.writeDsLen(item.len);
}
});
};
/**
* @param {DSDecoderV1 | DSDecoderV2} decoder
* @return {DeleteSet}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$readDeleteSet = (decoder)=>{
const ds = new $52a83e33f2b9e935$var$DeleteSet();
const numClients = $f5RS8.readVarUint(decoder.restDecoder);
for(let i = 0; i < numClients; i++){
decoder.resetDsCurVal();
const client = $f5RS8.readVarUint(decoder.restDecoder);
const numberOfDeletes = $f5RS8.readVarUint(decoder.restDecoder);
if (numberOfDeletes > 0) {
const dsField = $e6DQe.setIfUndefined(ds.clients, client, ()=>/** @type {Array} */ []);
for(let i = 0; i < numberOfDeletes; i++)dsField.push(new $52a83e33f2b9e935$var$DeleteItem(decoder.readDsClock(), decoder.readDsLen()));
}
}
return ds;
};
/**
* @todo YDecoder also contains references to String and other Decoders. Would make sense to exchange YDecoder.toUint8Array for YDecoder.DsToUint8Array()..
*/ /**
* @param {DSDecoderV1 | DSDecoderV2} decoder
* @param {Transaction} transaction
* @param {StructStore} store
* @return {Uint8Array|null} Returns a v2 update containing all deletes that couldn't be applied yet; or null if all deletes were applied successfully.
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$readAndApplyDeleteSet = (decoder, transaction, store)=>{
const unappliedDS = new $52a83e33f2b9e935$var$DeleteSet();
const numClients = $f5RS8.readVarUint(decoder.restDecoder);
for(let i = 0; i < numClients; i++){
decoder.resetDsCurVal();
const client = $f5RS8.readVarUint(decoder.restDecoder);
const numberOfDeletes = $f5RS8.readVarUint(decoder.restDecoder);
const structs = store.clients.get(client) || [];
const state = $52a83e33f2b9e935$export$50fdfeece43146fd(store, client);
for(let i = 0; i < numberOfDeletes; i++){
const clock = decoder.readDsClock();
const clockEnd = clock + decoder.readDsLen();
if (clock < state) {
if (state < clockEnd) $52a83e33f2b9e935$var$addToDeleteSet(unappliedDS, client, state, clockEnd - state);
let index = $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, clock);
/**
* We can ignore the case of GC and Delete structs, because we are going to skip them
* @type {Item}
*/ // @ts-ignore
let struct = structs[index];
// split the first item if necessary
if (!struct.deleted && struct.id.clock < clock) {
structs.splice(index + 1, 0, $52a83e33f2b9e935$var$splitItem(transaction, struct, clock - struct.id.clock));
index++; // increase we now want to use the next struct
}
while(index < structs.length){
// @ts-ignore
struct = structs[index++];
if (struct.id.clock < clockEnd) {
if (!struct.deleted) {
if (clockEnd < struct.id.clock + struct.length) structs.splice(index, 0, $52a83e33f2b9e935$var$splitItem(transaction, struct, clockEnd - struct.id.clock));
struct.delete(transaction);
}
} else break;
}
} else $52a83e33f2b9e935$var$addToDeleteSet(unappliedDS, client, clock, clockEnd - clock);
}
}
if (unappliedDS.clients.size > 0) {
const ds = new $52a83e33f2b9e935$var$UpdateEncoderV2();
$1p1sv.writeVarUint(ds.restEncoder, 0); // encode 0 structs
$52a83e33f2b9e935$var$writeDeleteSet(ds, unappliedDS);
return ds.toUint8Array();
}
return null;
};
/**
* @param {DeleteSet} ds1
* @param {DeleteSet} ds2
*/ const $52a83e33f2b9e935$export$9697b72c46fd3a5d = (ds1, ds2)=>{
if (ds1.clients.size !== ds2.clients.size) return false;
for (const [client, deleteItems1] of ds1.clients.entries()){
const deleteItems2 = /** @type {Array} */ ds2.clients.get(client);
if (deleteItems2 === undefined || deleteItems1.length !== deleteItems2.length) return false;
for(let i = 0; i < deleteItems1.length; i++){
const di1 = deleteItems1[i];
const di2 = deleteItems2[i];
if (di1.clock !== di2.clock || di1.len !== di2.len) return false;
}
}
return true;
};
/**
* @module Y
*/ const $52a83e33f2b9e935$var$generateNewClientId = $TGOcE.uint32;
/**
* @typedef {Object} DocOpts
* @property {boolean} [DocOpts.gc=true] Disable garbage collection (default: gc=true)
* @property {function(Item):boolean} [DocOpts.gcFilter] Will be called before an Item is garbage collected. Return false to keep the Item.
* @property {string} [DocOpts.guid] Define a globally unique identifier for this document
* @property {string | null} [DocOpts.collectionid] Associate this document with a collection. This only plays a role if your provider has a concept of collection.
* @property {any} [DocOpts.meta] Any kind of meta information you want to associate with this document. If this is a subdocument, remote peers will store the meta information as well.
* @property {boolean} [DocOpts.autoLoad] If a subdocument, automatically load document. If this is a subdocument, remote peers will load the document as well automatically.
* @property {boolean} [DocOpts.shouldLoad] Whether the document should be synced by the provider now. This is toggled to true when you call ydoc.load()
*/ /**
* A Yjs instance handles the state of shared data.
* @extends Observable
*/ class $52a83e33f2b9e935$export$bceacc74c2212615 extends (0, $9XqiC.Observable) {
/**
* @param {DocOpts} opts configuration
*/ constructor({ guid: guid = $TGOcE.uuidv4(), collectionid: collectionid = null, gc: gc = true, gcFilter: gcFilter = ()=>true, meta: meta = null, autoLoad: autoLoad = false, shouldLoad: shouldLoad = true } = {}){
super();
this.gc = gc;
this.gcFilter = gcFilter;
this.clientID = $52a83e33f2b9e935$var$generateNewClientId();
this.guid = guid;
this.collectionid = collectionid;
/**
* @type {Map>>}
*/ this.share = new Map();
this.store = new $52a83e33f2b9e935$var$StructStore();
/**
* @type {Transaction | null}
*/ this._transaction = null;
/**
* @type {Array}
*/ this._transactionCleanups = [];
/**
* @type {Set}
*/ this.subdocs = new Set();
/**
* If this document is a subdocument - a document integrated into another document - then _item is defined.
* @type {Item?}
*/ this._item = null;
this.shouldLoad = shouldLoad;
this.autoLoad = autoLoad;
this.meta = meta;
/**
* This is set to true when the persistence provider loaded the document from the database or when the `sync` event fires.
* Note that not all providers implement this feature. Provider authors are encouraged to fire the `load` event when the doc content is loaded from the database.
*
* @type {boolean}
*/ this.isLoaded = false;
/**
* This is set to true when the connection provider has successfully synced with a backend.
* Note that when using peer-to-peer providers this event may not provide very useful.
* Also note that not all providers implement this feature. Provider authors are encouraged to fire
* the `sync` event when the doc has been synced (with `true` as a parameter) or if connection is
* lost (with false as a parameter).
*/ this.isSynced = false;
/**
* Promise that resolves once the document has been loaded from a presistence provider.
*/ this.whenLoaded = $jKNqA.create((resolve)=>{
this.on("load", ()=>{
this.isLoaded = true;
resolve(this);
});
});
const provideSyncedPromise = ()=>$jKNqA.create((resolve)=>{
/**
* @param {boolean} isSynced
*/ const eventHandler = (isSynced)=>{
if (isSynced === undefined || isSynced === true) {
this.off("sync", eventHandler);
resolve();
}
};
this.on("sync", eventHandler);
});
this.on("sync", (isSynced)=>{
if (isSynced === false && this.isSynced) this.whenSynced = provideSyncedPromise();
this.isSynced = isSynced === undefined || isSynced === true;
if (!this.isLoaded) this.emit("load", []);
});
/**
* Promise that resolves once the document has been synced with a backend.
* This promise is recreated when the connection is lost.
* Note the documentation about the `isSynced` property.
*/ this.whenSynced = provideSyncedPromise();
}
/**
* Notify the parent document that you request to load data into this subdocument (if it is a subdocument).
*
* `load()` might be used in the future to request any provider to load the most current data.
*
* It is safe to call `load()` multiple times.
*/ load() {
const item = this._item;
if (item !== null && !this.shouldLoad) $52a83e33f2b9e935$export$dac1bad6146b2469(/** @type {any} */ item.parent.doc, (transaction)=>{
transaction.subdocsLoaded.add(this);
}, null, true);
this.shouldLoad = true;
}
getSubdocs() {
return this.subdocs;
}
getSubdocGuids() {
return new Set($7sfdv.from(this.subdocs).map((doc)=>doc.guid));
}
/**
* Changes that happen inside of a transaction are bundled. This means that
* the observer fires _after_ the transaction is finished and that all changes
* that happened inside of the transaction are sent as one message to the
* other peers.
*
* @template T
* @param {function(Transaction):T} f The function that should be executed as a transaction
* @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin
* @return T
*
* @public
*/ transact(f, origin = null) {
return $52a83e33f2b9e935$export$dac1bad6146b2469(this, f, origin);
}
/**
* Define a shared data type.
*
* Multiple calls of `y.get(name, TypeConstructor)` yield the same result
* and do not overwrite each other. I.e.
* `y.define(name, Y.Array) === y.define(name, Y.Array)`
*
* After this method is called, the type is also available on `y.share.get(name)`.
*
* *Best Practices:*
* Define all types right after the Yjs instance is created and store them in a separate object.
* Also use the typed methods `getText(name)`, `getArray(name)`, ..
*
* @example
* const y = new Y(..)
* const appState = {
* document: y.getText('document')
* comments: y.getArray('comments')
* }
*
* @param {string} name
* @param {Function} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ...
* @return {AbstractType} The created type. Constructed with TypeConstructor
*
* @public
*/ get(name, TypeConstructor = $52a83e33f2b9e935$export$c265dc8338484497) {
const type = $e6DQe.setIfUndefined(this.share, name, ()=>{
// @ts-ignore
const t = new TypeConstructor();
t._integrate(this, null);
return t;
});
const Constr = type.constructor;
if (TypeConstructor !== $52a83e33f2b9e935$export$c265dc8338484497 && Constr !== TypeConstructor) {
if (Constr === $52a83e33f2b9e935$export$c265dc8338484497) {
// @ts-ignore
const t = new TypeConstructor();
t._map = type._map;
type._map.forEach(/** @param {Item?} n */ (n)=>{
for(; n !== null; n = n.left)// @ts-ignore
n.parent = t;
});
t._start = type._start;
for(let n = t._start; n !== null; n = n.right)n.parent = t;
t._length = type._length;
this.share.set(name, t);
t._integrate(this, null);
return t;
} else throw new Error(`Type with the name ${name} has already been defined with a different constructor`);
}
return type;
}
/**
* @template T
* @param {string} [name]
* @return {YArray}
*
* @public
*/ getArray(name = "") {
// @ts-ignore
return this.get(name, $52a83e33f2b9e935$export$c4be6576ca6fe4aa);
}
/**
* @param {string} [name]
* @return {YText}
*
* @public
*/ getText(name = "") {
// @ts-ignore
return this.get(name, $52a83e33f2b9e935$export$5f1af8db9871e1d6);
}
/**
* @template T
* @param {string} [name]
* @return {YMap}
*
* @public
*/ getMap(name = "") {
// @ts-ignore
return this.get(name, $52a83e33f2b9e935$export$a5c7b93649eaf8f8);
}
/**
* @param {string} [name]
* @return {YXmlFragment}
*
* @public
*/ getXmlFragment(name = "") {
// @ts-ignore
return this.get(name, $52a83e33f2b9e935$export$d5ce8c3e1731f1a7);
}
/**
* Converts the entire document into a js object, recursively traversing each yjs type
* Doesn't log types that have not been defined (using ydoc.getType(..)).
*
* @deprecated Do not use this method and rather call toJSON directly on the shared types.
*
* @return {Object}
*/ toJSON() {
/**
* @type {Object}
*/ const doc = {};
this.share.forEach((value, key)=>{
doc[key] = value.toJSON();
});
return doc;
}
/**
* Emit `destroy` event and unregister all event handlers.
*/ destroy() {
$7sfdv.from(this.subdocs).forEach((subdoc)=>subdoc.destroy());
const item = this._item;
if (item !== null) {
this._item = null;
const content = /** @type {ContentDoc} */ item.content;
content.doc = new $52a83e33f2b9e935$export$bceacc74c2212615({
guid: this.guid,
...content.opts,
shouldLoad: false
});
content.doc._item = item;
$52a83e33f2b9e935$export$dac1bad6146b2469(/** @type {any} */ item.parent.doc, (transaction)=>{
const doc = content.doc;
if (!item.deleted) transaction.subdocsAdded.add(doc);
transaction.subdocsRemoved.add(this);
}, null, true);
}
this.emit("destroyed", [
true
]);
this.emit("destroy", [
this
]);
super.destroy();
}
/**
* @param {string} eventName
* @param {function(...any):any} f
*/ on(eventName, f) {
super.on(eventName, f);
}
/**
* @param {string} eventName
* @param {function} f
*/ off(eventName, f) {
super.off(eventName, f);
}
}
class $52a83e33f2b9e935$var$DSDecoderV1 {
/**
* @param {decoding.Decoder} decoder
*/ constructor(decoder){
this.restDecoder = decoder;
}
resetDsCurVal() {
// nop
}
/**
* @return {number}
*/ readDsClock() {
return $f5RS8.readVarUint(this.restDecoder);
}
/**
* @return {number}
*/ readDsLen() {
return $f5RS8.readVarUint(this.restDecoder);
}
}
class $52a83e33f2b9e935$var$UpdateDecoderV1 extends $52a83e33f2b9e935$var$DSDecoderV1 {
/**
* @return {ID}
*/ readLeftID() {
return $52a83e33f2b9e935$export$6c7d4e6171d008d0($f5RS8.readVarUint(this.restDecoder), $f5RS8.readVarUint(this.restDecoder));
}
/**
* @return {ID}
*/ readRightID() {
return $52a83e33f2b9e935$export$6c7d4e6171d008d0($f5RS8.readVarUint(this.restDecoder), $f5RS8.readVarUint(this.restDecoder));
}
/**
* Read the next client id.
* Use this in favor of readID whenever possible to reduce the number of objects created.
*/ readClient() {
return $f5RS8.readVarUint(this.restDecoder);
}
/**
* @return {number} info An unsigned 8-bit integer
*/ readInfo() {
return $f5RS8.readUint8(this.restDecoder);
}
/**
* @return {string}
*/ readString() {
return $f5RS8.readVarString(this.restDecoder);
}
/**
* @return {boolean} isKey
*/ readParentInfo() {
return $f5RS8.readVarUint(this.restDecoder) === 1;
}
/**
* @return {number} info An unsigned 8-bit integer
*/ readTypeRef() {
return $f5RS8.readVarUint(this.restDecoder);
}
/**
* Write len of a struct - well suited for Opt RLE encoder.
*
* @return {number} len
*/ readLen() {
return $f5RS8.readVarUint(this.restDecoder);
}
/**
* @return {any}
*/ readAny() {
return $f5RS8.readAny(this.restDecoder);
}
/**
* @return {Uint8Array}
*/ readBuf() {
return $lB8LX.copyUint8Array($f5RS8.readVarUint8Array(this.restDecoder));
}
/**
* Legacy implementation uses JSON parse. We use any-decoding in v2.
*
* @return {any}
*/ readJSON() {
return JSON.parse($f5RS8.readVarString(this.restDecoder));
}
/**
* @return {string}
*/ readKey() {
return $f5RS8.readVarString(this.restDecoder);
}
}
class $52a83e33f2b9e935$var$DSDecoderV2 {
/**
* @param {decoding.Decoder} decoder
*/ constructor(decoder){
/**
* @private
*/ this.dsCurrVal = 0;
this.restDecoder = decoder;
}
resetDsCurVal() {
this.dsCurrVal = 0;
}
/**
* @return {number}
*/ readDsClock() {
this.dsCurrVal += $f5RS8.readVarUint(this.restDecoder);
return this.dsCurrVal;
}
/**
* @return {number}
*/ readDsLen() {
const diff = $f5RS8.readVarUint(this.restDecoder) + 1;
this.dsCurrVal += diff;
return diff;
}
}
class $52a83e33f2b9e935$var$UpdateDecoderV2 extends $52a83e33f2b9e935$var$DSDecoderV2 {
/**
* @param {decoding.Decoder} decoder
*/ constructor(decoder){
super(decoder);
/**
* List of cached keys. If the keys[id] does not exist, we read a new key
* from stringEncoder and push it to keys.
*
* @type {Array}
*/ this.keys = [];
$f5RS8.readVarUint(decoder); // read feature flag - currently unused
this.keyClockDecoder = new $f5RS8.IntDiffOptRleDecoder($f5RS8.readVarUint8Array(decoder));
this.clientDecoder = new $f5RS8.UintOptRleDecoder($f5RS8.readVarUint8Array(decoder));
this.leftClockDecoder = new $f5RS8.IntDiffOptRleDecoder($f5RS8.readVarUint8Array(decoder));
this.rightClockDecoder = new $f5RS8.IntDiffOptRleDecoder($f5RS8.readVarUint8Array(decoder));
this.infoDecoder = new $f5RS8.RleDecoder($f5RS8.readVarUint8Array(decoder), $f5RS8.readUint8);
this.stringDecoder = new $f5RS8.StringDecoder($f5RS8.readVarUint8Array(decoder));
this.parentInfoDecoder = new $f5RS8.RleDecoder($f5RS8.readVarUint8Array(decoder), $f5RS8.readUint8);
this.typeRefDecoder = new $f5RS8.UintOptRleDecoder($f5RS8.readVarUint8Array(decoder));
this.lenDecoder = new $f5RS8.UintOptRleDecoder($f5RS8.readVarUint8Array(decoder));
}
/**
* @return {ID}
*/ readLeftID() {
return new $52a83e33f2b9e935$export$8be180ec26319f9f(this.clientDecoder.read(), this.leftClockDecoder.read());
}
/**
* @return {ID}
*/ readRightID() {
return new $52a83e33f2b9e935$export$8be180ec26319f9f(this.clientDecoder.read(), this.rightClockDecoder.read());
}
/**
* Read the next client id.
* Use this in favor of readID whenever possible to reduce the number of objects created.
*/ readClient() {
return this.clientDecoder.read();
}
/**
* @return {number} info An unsigned 8-bit integer
*/ readInfo() {
return /** @type {number} */ this.infoDecoder.read();
}
/**
* @return {string}
*/ readString() {
return this.stringDecoder.read();
}
/**
* @return {boolean}
*/ readParentInfo() {
return this.parentInfoDecoder.read() === 1;
}
/**
* @return {number} An unsigned 8-bit integer
*/ readTypeRef() {
return this.typeRefDecoder.read();
}
/**
* Write len of a struct - well suited for Opt RLE encoder.
*
* @return {number}
*/ readLen() {
return this.lenDecoder.read();
}
/**
* @return {any}
*/ readAny() {
return $f5RS8.readAny(this.restDecoder);
}
/**
* @return {Uint8Array}
*/ readBuf() {
return $f5RS8.readVarUint8Array(this.restDecoder);
}
/**
* This is mainly here for legacy purposes.
*
* Initial we incoded objects using JSON. Now we use the much faster lib0/any-encoder. This method mainly exists for legacy purposes for the v1 encoder.
*
* @return {any}
*/ readJSON() {
return $f5RS8.readAny(this.restDecoder);
}
/**
* @return {string}
*/ readKey() {
const keyClock = this.keyClockDecoder.read();
if (keyClock < this.keys.length) return this.keys[keyClock];
else {
const key = this.stringDecoder.read();
this.keys.push(key);
return key;
}
}
}
class $52a83e33f2b9e935$var$DSEncoderV1 {
constructor(){
this.restEncoder = $1p1sv.createEncoder();
}
toUint8Array() {
return $1p1sv.toUint8Array(this.restEncoder);
}
resetDsCurVal() {
// nop
}
/**
* @param {number} clock
*/ writeDsClock(clock) {
$1p1sv.writeVarUint(this.restEncoder, clock);
}
/**
* @param {number} len
*/ writeDsLen(len) {
$1p1sv.writeVarUint(this.restEncoder, len);
}
}
class $52a83e33f2b9e935$export$99171b804d9c5b54 extends $52a83e33f2b9e935$var$DSEncoderV1 {
/**
* @param {ID} id
*/ writeLeftID(id) {
$1p1sv.writeVarUint(this.restEncoder, id.client);
$1p1sv.writeVarUint(this.restEncoder, id.clock);
}
/**
* @param {ID} id
*/ writeRightID(id) {
$1p1sv.writeVarUint(this.restEncoder, id.client);
$1p1sv.writeVarUint(this.restEncoder, id.clock);
}
/**
* Use writeClient and writeClock instead of writeID if possible.
* @param {number} client
*/ writeClient(client) {
$1p1sv.writeVarUint(this.restEncoder, client);
}
/**
* @param {number} info An unsigned 8-bit integer
*/ writeInfo(info) {
$1p1sv.writeUint8(this.restEncoder, info);
}
/**
* @param {string} s
*/ writeString(s) {
$1p1sv.writeVarString(this.restEncoder, s);
}
/**
* @param {boolean} isYKey
*/ writeParentInfo(isYKey) {
$1p1sv.writeVarUint(this.restEncoder, isYKey ? 1 : 0);
}
/**
* @param {number} info An unsigned 8-bit integer
*/ writeTypeRef(info) {
$1p1sv.writeVarUint(this.restEncoder, info);
}
/**
* Write len of a struct - well suited for Opt RLE encoder.
*
* @param {number} len
*/ writeLen(len) {
$1p1sv.writeVarUint(this.restEncoder, len);
}
/**
* @param {any} any
*/ writeAny(any) {
$1p1sv.writeAny(this.restEncoder, any);
}
/**
* @param {Uint8Array} buf
*/ writeBuf(buf) {
$1p1sv.writeVarUint8Array(this.restEncoder, buf);
}
/**
* @param {any} embed
*/ writeJSON(embed) {
$1p1sv.writeVarString(this.restEncoder, JSON.stringify(embed));
}
/**
* @param {string} key
*/ writeKey(key) {
$1p1sv.writeVarString(this.restEncoder, key);
}
}
class $52a83e33f2b9e935$var$DSEncoderV2 {
constructor(){
this.restEncoder = $1p1sv.createEncoder(); // encodes all the rest / non-optimized
this.dsCurrVal = 0;
}
toUint8Array() {
return $1p1sv.toUint8Array(this.restEncoder);
}
resetDsCurVal() {
this.dsCurrVal = 0;
}
/**
* @param {number} clock
*/ writeDsClock(clock) {
const diff = clock - this.dsCurrVal;
this.dsCurrVal = clock;
$1p1sv.writeVarUint(this.restEncoder, diff);
}
/**
* @param {number} len
*/ writeDsLen(len) {
if (len === 0) $akmFO.unexpectedCase();
$1p1sv.writeVarUint(this.restEncoder, len - 1);
this.dsCurrVal += len;
}
}
class $52a83e33f2b9e935$var$UpdateEncoderV2 extends $52a83e33f2b9e935$var$DSEncoderV2 {
constructor(){
super();
/**
* @type {Map}
*/ this.keyMap = new Map();
/**
* Refers to the next uniqe key-identifier to me used.
* See writeKey method for more information.
*
* @type {number}
*/ this.keyClock = 0;
this.keyClockEncoder = new $1p1sv.IntDiffOptRleEncoder();
this.clientEncoder = new $1p1sv.UintOptRleEncoder();
this.leftClockEncoder = new $1p1sv.IntDiffOptRleEncoder();
this.rightClockEncoder = new $1p1sv.IntDiffOptRleEncoder();
this.infoEncoder = new $1p1sv.RleEncoder($1p1sv.writeUint8);
this.stringEncoder = new $1p1sv.StringEncoder();
this.parentInfoEncoder = new $1p1sv.RleEncoder($1p1sv.writeUint8);
this.typeRefEncoder = new $1p1sv.UintOptRleEncoder();
this.lenEncoder = new $1p1sv.UintOptRleEncoder();
}
toUint8Array() {
const encoder = $1p1sv.createEncoder();
$1p1sv.writeVarUint(encoder, 0); // this is a feature flag that we might use in the future
$1p1sv.writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array());
$1p1sv.writeVarUint8Array(encoder, this.clientEncoder.toUint8Array());
$1p1sv.writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array());
$1p1sv.writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array());
$1p1sv.writeVarUint8Array(encoder, $1p1sv.toUint8Array(this.infoEncoder));
$1p1sv.writeVarUint8Array(encoder, this.stringEncoder.toUint8Array());
$1p1sv.writeVarUint8Array(encoder, $1p1sv.toUint8Array(this.parentInfoEncoder));
$1p1sv.writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array());
$1p1sv.writeVarUint8Array(encoder, this.lenEncoder.toUint8Array());
// @note The rest encoder is appended! (note the missing var)
$1p1sv.writeUint8Array(encoder, $1p1sv.toUint8Array(this.restEncoder));
return $1p1sv.toUint8Array(encoder);
}
/**
* @param {ID} id
*/ writeLeftID(id) {
this.clientEncoder.write(id.client);
this.leftClockEncoder.write(id.clock);
}
/**
* @param {ID} id
*/ writeRightID(id) {
this.clientEncoder.write(id.client);
this.rightClockEncoder.write(id.clock);
}
/**
* @param {number} client
*/ writeClient(client) {
this.clientEncoder.write(client);
}
/**
* @param {number} info An unsigned 8-bit integer
*/ writeInfo(info) {
this.infoEncoder.write(info);
}
/**
* @param {string} s
*/ writeString(s) {
this.stringEncoder.write(s);
}
/**
* @param {boolean} isYKey
*/ writeParentInfo(isYKey) {
this.parentInfoEncoder.write(isYKey ? 1 : 0);
}
/**
* @param {number} info An unsigned 8-bit integer
*/ writeTypeRef(info) {
this.typeRefEncoder.write(info);
}
/**
* Write len of a struct - well suited for Opt RLE encoder.
*
* @param {number} len
*/ writeLen(len) {
this.lenEncoder.write(len);
}
/**
* @param {any} any
*/ writeAny(any) {
$1p1sv.writeAny(this.restEncoder, any);
}
/**
* @param {Uint8Array} buf
*/ writeBuf(buf) {
$1p1sv.writeVarUint8Array(this.restEncoder, buf);
}
/**
* This is mainly here for legacy purposes.
*
* Initial we incoded objects using JSON. Now we use the much faster lib0/any-encoder. This method mainly exists for legacy purposes for the v1 encoder.
*
* @param {any} embed
*/ writeJSON(embed) {
$1p1sv.writeAny(this.restEncoder, embed);
}
/**
* Property keys are often reused. For example, in y-prosemirror the key `bold` might
* occur very often. For a 3d application, the key `position` might occur very often.
*
* We cache these keys in a Map and refer to them via a unique number.
*
* @param {string} key
*/ writeKey(key) {
const clock = this.keyMap.get(key);
if (clock === undefined) {
/**
* @todo uncomment to introduce this feature finally
*
* Background. The ContentFormat object was always encoded using writeKey, but the decoder used to use readString.
* Furthermore, I forgot to set the keyclock. So everything was working fine.
*
* However, this feature here is basically useless as it is not being used (it actually only consumes extra memory).
*
* I don't know yet how to reintroduce this feature..
*
* Older clients won't be able to read updates when we reintroduce this feature. So this should probably be done using a flag.
*
*/ // this.keyMap.set(key, this.keyClock)
this.keyClockEncoder.write(this.keyClock++);
this.stringEncoder.write(key);
} else this.keyClockEncoder.write(clock);
}
}
/**
* @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
* @param {Array} structs All structs by `client`
* @param {number} client
* @param {number} clock write structs starting with `ID(client,clock)`
*
* @function
*/ const $52a83e33f2b9e935$var$writeStructs = (encoder, structs, client, clock)=>{
// write first id
clock = $kuitL.max(clock, structs[0].id.clock); // make sure the first id exists
const startNewStructs = $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, clock);
// write # encoded structs
$1p1sv.writeVarUint(encoder.restEncoder, structs.length - startNewStructs);
encoder.writeClient(client);
$1p1sv.writeVarUint(encoder.restEncoder, clock);
const firstStruct = structs[startNewStructs];
// write first struct with an offset
firstStruct.write(encoder, clock - firstStruct.id.clock);
for(let i = startNewStructs + 1; i < structs.length; i++)structs[i].write(encoder, 0);
};
/**
* @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
* @param {StructStore} store
* @param {Map} _sm
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$writeClientsStructs = (encoder, store, _sm)=>{
// we filter all valid _sm entries into sm
const sm = new Map();
_sm.forEach((clock, client)=>{
// only write if new structs are available
if ($52a83e33f2b9e935$export$50fdfeece43146fd(store, client) > clock) sm.set(client, clock);
});
$52a83e33f2b9e935$var$getStateVector(store).forEach((_clock, client)=>{
if (!_sm.has(client)) sm.set(client, 0);
});
// write # states that were updated
$1p1sv.writeVarUint(encoder.restEncoder, sm.size);
// Write items with higher client ids first
// This heavily improves the conflict algorithm.
$7sfdv.from(sm.entries()).sort((a, b)=>b[0] - a[0]).forEach(([client, clock])=>{
$52a83e33f2b9e935$var$writeStructs(encoder, /** @type {Array} */ store.clients.get(client), client, clock);
});
};
/**
* @param {UpdateDecoderV1 | UpdateDecoderV2} decoder The decoder object to read data from.
* @param {Doc} doc
* @return {Map }>}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$readClientsStructRefs = (decoder, doc)=>{
/**
* @type {Map }>}
*/ const clientRefs = $e6DQe.create();
const numOfStateUpdates = $f5RS8.readVarUint(decoder.restDecoder);
for(let i = 0; i < numOfStateUpdates; i++){
const numberOfStructs = $f5RS8.readVarUint(decoder.restDecoder);
/**
* @type {Array}
*/ const refs = new Array(numberOfStructs);
const client = decoder.readClient();
let clock = $f5RS8.readVarUint(decoder.restDecoder);
// const start = performance.now()
clientRefs.set(client, {
i: 0,
refs: refs
});
for(let i = 0; i < numberOfStructs; i++){
const info = decoder.readInfo();
switch($1GdQd.BITS5 & info){
case 0:
{
const len = decoder.readLen();
refs[i] = new $52a83e33f2b9e935$export$12d259ff017e6b58($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock), len);
clock += len;
break;
}
case 10:
{
// @todo we could reduce the amount of checks by adding Skip struct to clientRefs so we know that something is missing.
const len = $f5RS8.readVarUint(decoder.restDecoder);
refs[i] = new $52a83e33f2b9e935$var$Skip($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock), len);
clock += len;
break;
}
default:
{
/**
* The optimized implementation doesn't use any variables because inlining variables is faster.
* Below a non-optimized version is shown that implements the basic algorithm with
* a few comments
*/ const cantCopyParentInfo = (info & ($1GdQd.BIT7 | $1GdQd.BIT8)) === 0;
// If parent = null and neither left nor right are defined, then we know that `parent` is child of `y`
// and we read the next string as parentYKey.
// It indicates how we store/retrieve parent from `y.share`
// @type {string|null}
const struct = new $52a83e33f2b9e935$export$6d08773d2e66f8f2($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock), null, (info & $1GdQd.BIT8) === $1GdQd.BIT8 ? decoder.readLeftID() : null, null, (info & $1GdQd.BIT7) === $1GdQd.BIT7 ? decoder.readRightID() : null, cantCopyParentInfo ? decoder.readParentInfo() ? doc.get(decoder.readString()) : decoder.readLeftID() : null, cantCopyParentInfo && (info & $1GdQd.BIT6) === $1GdQd.BIT6 ? decoder.readString() : null, $52a83e33f2b9e935$var$readItemContent(decoder, info) // item content
);
/* A non-optimized implementation of the above algorithm:
// The item that was originally to the left of this item.
const origin = (info & binary.BIT8) === binary.BIT8 ? decoder.readLeftID() : null
// The item that was originally to the right of this item.
const rightOrigin = (info & binary.BIT7) === binary.BIT7 ? decoder.readRightID() : null
const cantCopyParentInfo = (info & (binary.BIT7 | binary.BIT8)) === 0
const hasParentYKey = cantCopyParentInfo ? decoder.readParentInfo() : false
// If parent = null and neither left nor right are defined, then we know that `parent` is child of `y`
// and we read the next string as parentYKey.
// It indicates how we store/retrieve parent from `y.share`
// @type {string|null}
const parentYKey = cantCopyParentInfo && hasParentYKey ? decoder.readString() : null
const struct = new Item(
createID(client, clock),
null, // leftd
origin, // origin
null, // right
rightOrigin, // right origin
cantCopyParentInfo && !hasParentYKey ? decoder.readLeftID() : (parentYKey !== null ? doc.get(parentYKey) : null), // parent
cantCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoder.readString() : null, // parentSub
readItemContent(decoder, info) // item content
)
*/ refs[i] = struct;
clock += struct.length;
}
}
}
// console.log('time to read: ', performance.now() - start) // @todo remove
}
return clientRefs;
};
/**
* Resume computing structs generated by struct readers.
*
* While there is something to do, we integrate structs in this order
* 1. top element on stack, if stack is not empty
* 2. next element from current struct reader (if empty, use next struct reader)
*
* If struct causally depends on another struct (ref.missing), we put next reader of
* `ref.id.client` on top of stack.
*
* At some point we find a struct that has no causal dependencies,
* then we start emptying the stack.
*
* It is not possible to have circles: i.e. struct1 (from client1) depends on struct2 (from client2)
* depends on struct3 (from client1). Therefore the max stack size is eqaul to `structReaders.length`.
*
* This method is implemented in a way so that we can resume computation if this update
* causally depends on another update.
*
* @param {Transaction} transaction
* @param {StructStore} store
* @param {Map} clientsStructRefs
* @return { null | { update: Uint8Array, missing: Map } }
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$integrateStructs = (transaction, store, clientsStructRefs)=>{
/**
* @type {Array- }
*/ const stack = [];
// sort them so that we take the higher id first, in case of conflicts the lower id will probably not conflict with the id from the higher user.
let clientsStructRefsIds = $7sfdv.from(clientsStructRefs.keys()).sort((a, b)=>a - b);
if (clientsStructRefsIds.length === 0) return null;
const getNextStructTarget = ()=>{
if (clientsStructRefsIds.length === 0) return null;
let nextStructsTarget = /** @type {{i:number,refs:Array}} */ clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]);
while(nextStructsTarget.refs.length === nextStructsTarget.i){
clientsStructRefsIds.pop();
if (clientsStructRefsIds.length > 0) nextStructsTarget = /** @type {{i:number,refs:Array}} */ clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]);
else return null;
}
return nextStructsTarget;
};
let curStructsTarget = getNextStructTarget();
if (curStructsTarget === null && stack.length === 0) return null;
/**
* @type {StructStore}
*/ const restStructs = new $52a83e33f2b9e935$var$StructStore();
const missingSV = new Map();
/**
* @param {number} client
* @param {number} clock
*/ const updateMissingSv = (client, clock)=>{
const mclock = missingSV.get(client);
if (mclock == null || mclock > clock) missingSV.set(client, clock);
};
/**
* @type {GC|Item}
*/ let stackHead = /** @type {any} */ curStructsTarget.refs[/** @type {any} */ curStructsTarget.i++];
// caching the state because it is used very often
const state = new Map();
const addStackToRestSS = ()=>{
for (const item of stack){
const client = item.id.client;
const unapplicableItems = clientsStructRefs.get(client);
if (unapplicableItems) {
// decrement because we weren't able to apply previous operation
unapplicableItems.i--;
restStructs.clients.set(client, unapplicableItems.refs.slice(unapplicableItems.i));
clientsStructRefs.delete(client);
unapplicableItems.i = 0;
unapplicableItems.refs = [];
} else // item was the last item on clientsStructRefs and the field was already cleared. Add item to restStructs and continue
restStructs.clients.set(client, [
item
]);
// remove client from clientsStructRefsIds to prevent users from applying the same update again
clientsStructRefsIds = clientsStructRefsIds.filter((c)=>c !== client);
}
stack.length = 0;
};
// iterate over all struct readers until we are done
while(true){
if (stackHead.constructor !== $52a83e33f2b9e935$var$Skip) {
const localClock = $e6DQe.setIfUndefined(state, stackHead.id.client, ()=>$52a83e33f2b9e935$export$50fdfeece43146fd(store, stackHead.id.client));
const offset = localClock - stackHead.id.clock;
if (offset < 0) {
// update from the same client is missing
stack.push(stackHead);
updateMissingSv(stackHead.id.client, stackHead.id.clock - 1);
// hid a dead wall, add all items from stack to restSS
addStackToRestSS();
} else {
const missing = stackHead.getMissing(transaction, store);
if (missing !== null) {
stack.push(stackHead);
// get the struct reader that has the missing struct
/**
* @type {{ refs: Array, i: number }}
*/ const structRefs = clientsStructRefs.get(/** @type {number} */ missing) || {
refs: [],
i: 0
};
if (structRefs.refs.length === structRefs.i) {
// This update message causally depends on another update message that doesn't exist yet
updateMissingSv(/** @type {number} */ missing, $52a83e33f2b9e935$export$50fdfeece43146fd(store, missing));
addStackToRestSS();
} else {
stackHead = structRefs.refs[structRefs.i++];
continue;
}
} else if (offset === 0 || offset < stackHead.length) {
// all fine, apply the stackhead
stackHead.integrate(transaction, offset);
state.set(stackHead.id.client, stackHead.id.clock + stackHead.length);
}
}
}
// iterate to next stackHead
if (stack.length > 0) stackHead = /** @type {GC|Item} */ stack.pop();
else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) stackHead = /** @type {GC|Item} */ curStructsTarget.refs[curStructsTarget.i++];
else {
curStructsTarget = getNextStructTarget();
if (curStructsTarget === null) break;
else stackHead = /** @type {GC|Item} */ curStructsTarget.refs[curStructsTarget.i++];
}
}
if (restStructs.clients.size > 0) {
const encoder = new $52a83e33f2b9e935$var$UpdateEncoderV2();
$52a83e33f2b9e935$var$writeClientsStructs(encoder, restStructs, new Map());
// write empty deleteset
// writeDeleteSet(encoder, new DeleteSet())
$1p1sv.writeVarUint(encoder.restEncoder, 0); // => no need for an extra function call, just write 0 deletes
return {
missing: missingSV,
update: encoder.toUint8Array()
};
}
return null;
};
/**
* @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
* @param {Transaction} transaction
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$writeStructsFromTransaction = (encoder, transaction)=>$52a83e33f2b9e935$var$writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState);
/**
* Read and apply a document update.
*
* This function has the same effect as `applyUpdate` but accepts an decoder.
*
* @param {decoding.Decoder} decoder
* @param {Doc} ydoc
* @param {any} [transactionOrigin] This will be stored on `transaction.origin` and `.on('update', (update, origin))`
* @param {UpdateDecoderV1 | UpdateDecoderV2} [structDecoder]
*
* @function
*/ const $52a83e33f2b9e935$export$7abe492a0b891b4d = (decoder, ydoc, transactionOrigin, structDecoder = new $52a83e33f2b9e935$var$UpdateDecoderV2(decoder))=>$52a83e33f2b9e935$export$dac1bad6146b2469(ydoc, (transaction)=>{
// force that transaction.local is set to non-local
transaction.local = false;
let retry = false;
const doc = transaction.doc;
const store = doc.store;
// let start = performance.now()
const ss = $52a83e33f2b9e935$var$readClientsStructRefs(structDecoder, doc);
// console.log('time to read structs: ', performance.now() - start) // @todo remove
// start = performance.now()
// console.log('time to merge: ', performance.now() - start) // @todo remove
// start = performance.now()
const restStructs = $52a83e33f2b9e935$var$integrateStructs(transaction, store, ss);
const pending = store.pendingStructs;
if (pending) {
// check if we can apply something
for (const [client, clock] of pending.missing)if (clock < $52a83e33f2b9e935$export$50fdfeece43146fd(store, client)) {
retry = true;
break;
}
if (restStructs) {
// merge restStructs into store.pending
for (const [client, clock] of restStructs.missing){
const mclock = pending.missing.get(client);
if (mclock == null || mclock > clock) pending.missing.set(client, clock);
}
pending.update = $52a83e33f2b9e935$export$ce273d78de0331d1([
pending.update,
restStructs.update
]);
}
} else store.pendingStructs = restStructs;
// console.log('time to integrate: ', performance.now() - start) // @todo remove
// start = performance.now()
const dsRest = $52a83e33f2b9e935$var$readAndApplyDeleteSet(structDecoder, transaction, store);
if (store.pendingDs) {
// @todo we could make a lower-bound state-vector check as we do above
const pendingDSUpdate = new $52a83e33f2b9e935$var$UpdateDecoderV2($f5RS8.createDecoder(store.pendingDs));
$f5RS8.readVarUint(pendingDSUpdate.restDecoder); // read 0 structs, because we only encode deletes in pendingdsupdate
const dsRest2 = $52a83e33f2b9e935$var$readAndApplyDeleteSet(pendingDSUpdate, transaction, store);
if (dsRest && dsRest2) // case 1: ds1 != null && ds2 != null
store.pendingDs = $52a83e33f2b9e935$export$ce273d78de0331d1([
dsRest,
dsRest2
]);
else // case 2: ds1 != null
// case 3: ds2 != null
// case 4: ds1 == null && ds2 == null
store.pendingDs = dsRest || dsRest2;
} else // Either dsRest == null && pendingDs == null OR dsRest != null
store.pendingDs = dsRest;
// console.log('time to cleanup: ', performance.now() - start) // @todo remove
// start = performance.now()
// console.log('time to resume delete readers: ', performance.now() - start) // @todo remove
// start = performance.now()
if (retry) {
const update = /** @type {{update: Uint8Array}} */ store.pendingStructs.update;
store.pendingStructs = null;
$52a83e33f2b9e935$export$acc3b0324aabf1b6(transaction.doc, update);
}
}, transactionOrigin, false);
/**
* Read and apply a document update.
*
* This function has the same effect as `applyUpdate` but accepts an decoder.
*
* @param {decoding.Decoder} decoder
* @param {Doc} ydoc
* @param {any} [transactionOrigin] This will be stored on `transaction.origin` and `.on('update', (update, origin))`
*
* @function
*/ const $52a83e33f2b9e935$export$d67ac8d73b7d336c = (decoder, ydoc, transactionOrigin)=>$52a83e33f2b9e935$export$7abe492a0b891b4d(decoder, ydoc, transactionOrigin, new $52a83e33f2b9e935$var$UpdateDecoderV1(decoder));
/**
* Apply a document update created by, for example, `y.on('update', update => ..)` or `update = encodeStateAsUpdate()`.
*
* This function has the same effect as `readUpdate` but accepts an Uint8Array instead of a Decoder.
*
* @param {Doc} ydoc
* @param {Uint8Array} update
* @param {any} [transactionOrigin] This will be stored on `transaction.origin` and `.on('update', (update, origin))`
* @param {typeof UpdateDecoderV1 | typeof UpdateDecoderV2} [YDecoder]
*
* @function
*/ const $52a83e33f2b9e935$export$acc3b0324aabf1b6 = (ydoc, update, transactionOrigin, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2)=>{
const decoder = $f5RS8.createDecoder(update);
$52a83e33f2b9e935$export$7abe492a0b891b4d(decoder, ydoc, transactionOrigin, new YDecoder(decoder));
};
/**
* Apply a document update created by, for example, `y.on('update', update => ..)` or `update = encodeStateAsUpdate()`.
*
* This function has the same effect as `readUpdate` but accepts an Uint8Array instead of a Decoder.
*
* @param {Doc} ydoc
* @param {Uint8Array} update
* @param {any} [transactionOrigin] This will be stored on `transaction.origin` and `.on('update', (update, origin))`
*
* @function
*/ const $52a83e33f2b9e935$export$c271737a9c02e925 = (ydoc, update, transactionOrigin)=>$52a83e33f2b9e935$export$acc3b0324aabf1b6(ydoc, update, transactionOrigin, $52a83e33f2b9e935$var$UpdateDecoderV1);
/**
* Write all the document as a single update message. If you specify the state of the remote client (`targetStateVector`) it will
* only write the operations that are missing.
*
* @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
* @param {Doc} doc
* @param {Map} [targetStateVector] The state of the target that receives the update. Leave empty to write all known structs
*
* @function
*/ const $52a83e33f2b9e935$var$writeStateAsUpdate = (encoder, doc, targetStateVector = new Map())=>{
$52a83e33f2b9e935$var$writeClientsStructs(encoder, doc.store, targetStateVector);
$52a83e33f2b9e935$var$writeDeleteSet(encoder, $52a83e33f2b9e935$export$8450d668bec558e2(doc.store));
};
/**
* Write all the document as a single update message that can be applied on the remote document. If you specify the state of the remote client (`targetState`) it will
* only write the operations that are missing.
*
* Use `writeStateAsUpdate` instead if you are working with lib0/encoding.js#Encoder
*
* @param {Doc} doc
* @param {Uint8Array} [encodedTargetStateVector] The state of the target that receives the update. Leave empty to write all known structs
* @param {UpdateEncoderV1 | UpdateEncoderV2} [encoder]
* @return {Uint8Array}
*
* @function
*/ const $52a83e33f2b9e935$export$90338e0798f6f64f = (doc, encodedTargetStateVector = new Uint8Array([
0
]), encoder = new $52a83e33f2b9e935$var$UpdateEncoderV2())=>{
const targetStateVector = $52a83e33f2b9e935$export$324ac6fb20a844e3(encodedTargetStateVector);
$52a83e33f2b9e935$var$writeStateAsUpdate(encoder, doc, targetStateVector);
const updates = [
encoder.toUint8Array()
];
// also add the pending updates (if there are any)
if (doc.store.pendingDs) updates.push(doc.store.pendingDs);
if (doc.store.pendingStructs) updates.push($52a83e33f2b9e935$export$a8143edf39d2ad8e(doc.store.pendingStructs.update, encodedTargetStateVector));
if (updates.length > 1) {
if (encoder.constructor === $52a83e33f2b9e935$export$99171b804d9c5b54) return $52a83e33f2b9e935$export$6319871659fd2460(updates.map((update, i)=>i === 0 ? update : $52a83e33f2b9e935$export$afffbdeed14adbd(update)));
else if (encoder.constructor === $52a83e33f2b9e935$var$UpdateEncoderV2) return $52a83e33f2b9e935$export$ce273d78de0331d1(updates);
}
return updates[0];
};
/**
* Write all the document as a single update message that can be applied on the remote document. If you specify the state of the remote client (`targetState`) it will
* only write the operations that are missing.
*
* Use `writeStateAsUpdate` instead if you are working with lib0/encoding.js#Encoder
*
* @param {Doc} doc
* @param {Uint8Array} [encodedTargetStateVector] The state of the target that receives the update. Leave empty to write all known structs
* @return {Uint8Array}
*
* @function
*/ const $52a83e33f2b9e935$export$e5848df80e65bd53 = (doc, encodedTargetStateVector)=>$52a83e33f2b9e935$export$90338e0798f6f64f(doc, encodedTargetStateVector, new $52a83e33f2b9e935$export$99171b804d9c5b54());
/**
* Read state vector from Decoder and return as Map
*
* @param {DSDecoderV1 | DSDecoderV2} decoder
* @return {Map} Maps `client` to the number next expected `clock` from that client.
*
* @function
*/ const $52a83e33f2b9e935$var$readStateVector = (decoder)=>{
const ss = new Map();
const ssLength = $f5RS8.readVarUint(decoder.restDecoder);
for(let i = 0; i < ssLength; i++){
const client = $f5RS8.readVarUint(decoder.restDecoder);
const clock = $f5RS8.readVarUint(decoder.restDecoder);
ss.set(client, clock);
}
return ss;
};
/**
* Read decodedState and return State as Map.
*
* @param {Uint8Array} decodedState
* @return {Map} Maps `client` to the number next expected `clock` from that client.
*
* @function
*/ // export const decodeStateVectorV2 = decodedState => readStateVector(new DSDecoderV2(decoding.createDecoder(decodedState)))
/**
* Read decodedState and return State as Map.
*
* @param {Uint8Array} decodedState
* @return {Map} Maps `client` to the number next expected `clock` from that client.
*
* @function
*/ const $52a83e33f2b9e935$export$324ac6fb20a844e3 = (decodedState)=>$52a83e33f2b9e935$var$readStateVector(new $52a83e33f2b9e935$var$DSDecoderV1($f5RS8.createDecoder(decodedState)));
/**
* @param {DSEncoderV1 | DSEncoderV2} encoder
* @param {Map} sv
* @function
*/ const $52a83e33f2b9e935$var$writeStateVector = (encoder, sv)=>{
$1p1sv.writeVarUint(encoder.restEncoder, sv.size);
$7sfdv.from(sv.entries()).sort((a, b)=>b[0] - a[0]).forEach(([client, clock])=>{
$1p1sv.writeVarUint(encoder.restEncoder, client); // @todo use a special client decoder that is based on mapping
$1p1sv.writeVarUint(encoder.restEncoder, clock);
});
return encoder;
};
/**
* @param {DSEncoderV1 | DSEncoderV2} encoder
* @param {Doc} doc
*
* @function
*/ const $52a83e33f2b9e935$var$writeDocumentStateVector = (encoder, doc)=>$52a83e33f2b9e935$var$writeStateVector(encoder, $52a83e33f2b9e935$var$getStateVector(doc.store));
/**
* Encode State as Uint8Array.
*
* @param {Doc|Map} doc
* @param {DSEncoderV1 | DSEncoderV2} [encoder]
* @return {Uint8Array}
*
* @function
*/ const $52a83e33f2b9e935$var$encodeStateVectorV2 = (doc, encoder = new $52a83e33f2b9e935$var$DSEncoderV2())=>{
if (doc instanceof Map) $52a83e33f2b9e935$var$writeStateVector(encoder, doc);
else $52a83e33f2b9e935$var$writeDocumentStateVector(encoder, doc);
return encoder.toUint8Array();
};
/**
* Encode State as Uint8Array.
*
* @param {Doc|Map} doc
* @return {Uint8Array}
*
* @function
*/ const $52a83e33f2b9e935$export$3e2f5393f32e71f = (doc)=>$52a83e33f2b9e935$var$encodeStateVectorV2(doc, new $52a83e33f2b9e935$var$DSEncoderV1());
/**
* General event handler implementation.
*
* @template ARG0, ARG1
*
* @private
*/ class $52a83e33f2b9e935$var$EventHandler {
constructor(){
/**
* @type {Array}
*/ this.l = [];
}
}
/**
* @template ARG0,ARG1
* @returns {EventHandler}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$createEventHandler = ()=>new $52a83e33f2b9e935$var$EventHandler();
/**
* Adds an event listener that is called when
* {@link EventHandler#callEventListeners} is called.
*
* @template ARG0,ARG1
* @param {EventHandler} eventHandler
* @param {function(ARG0,ARG1):void} f The event handler.
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$addEventHandlerListener = (eventHandler, f)=>eventHandler.l.push(f);
/**
* Removes an event listener.
*
* @template ARG0,ARG1
* @param {EventHandler} eventHandler
* @param {function(ARG0,ARG1):void} f The event handler that was added with
* {@link EventHandler#addEventListener}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$removeEventHandlerListener = (eventHandler, f)=>{
const l = eventHandler.l;
const len = l.length;
eventHandler.l = l.filter((g)=>f !== g);
if (len === eventHandler.l.length) console.error("[yjs] Tried to remove event handler that doesn't exist.");
};
/**
* Call all event listeners that were added via
* {@link EventHandler#addEventListener}.
*
* @template ARG0,ARG1
* @param {EventHandler} eventHandler
* @param {ARG0} arg0
* @param {ARG1} arg1
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$callEventHandlerListeners = (eventHandler, arg0, arg1)=>$kXTKb.callAll(eventHandler.l, [
arg0,
arg1
]);
class $52a83e33f2b9e935$export$8be180ec26319f9f {
/**
* @param {number} client client id
* @param {number} clock unique per client id, continuous number
*/ constructor(client, clock){
/**
* Client id
* @type {number}
*/ this.client = client;
/**
* unique per client id, continuous number
* @type {number}
*/ this.clock = clock;
}
}
/**
* @param {ID | null} a
* @param {ID | null} b
* @return {boolean}
*
* @function
*/ const $52a83e33f2b9e935$export$c0af976e7e459c02 = (a, b)=>a === b || a !== null && b !== null && a.client === b.client && a.clock === b.clock;
/**
* @param {number} client
* @param {number} clock
*
* @private
* @function
*/ const $52a83e33f2b9e935$export$6c7d4e6171d008d0 = (client, clock)=>new $52a83e33f2b9e935$export$8be180ec26319f9f(client, clock);
/**
* @param {encoding.Encoder} encoder
* @param {ID} id
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$writeID = (encoder, id)=>{
$1p1sv.writeVarUint(encoder, id.client);
$1p1sv.writeVarUint(encoder, id.clock);
};
/**
* Read ID.
* * If first varUint read is 0xFFFFFF a RootID is returned.
* * Otherwise an ID is returned
*
* @param {decoding.Decoder} decoder
* @return {ID}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$readID = (decoder)=>$52a83e33f2b9e935$export$6c7d4e6171d008d0($f5RS8.readVarUint(decoder), $f5RS8.readVarUint(decoder));
/**
* The top types are mapped from y.share.get(keyname) => type.
* `type` does not store any information about the `keyname`.
* This function finds the correct `keyname` for `type` and throws otherwise.
*
* @param {AbstractType} type
* @return {string}
*
* @private
* @function
*/ const $52a83e33f2b9e935$export$e726a40920d54663 = (type)=>{
// @ts-ignore _y must be defined, otherwise unexpected case
for (const [key, value] of type.doc.share.entries()){
if (value === type) return key;
}
throw $akmFO.unexpectedCase();
};
/**
* Check if `parent` is a parent of `child`.
*
* @param {AbstractType} parent
* @param {Item|null} child
* @return {Boolean} Whether `parent` is a parent of `child`.
*
* @private
* @function
*/ const $52a83e33f2b9e935$export$3c81af374b054d6a = (parent, child)=>{
while(child !== null){
if (child.parent === parent) return true;
child = /** @type {AbstractType} */ child.parent._item;
}
return false;
};
/**
* Convenient helper to log type information.
*
* Do not use in productive systems as the output can be immense!
*
* @param {AbstractType} type
*/ const $52a83e33f2b9e935$export$e9068ad704ba2f79 = (type)=>{
const res = [];
let n = type._start;
while(n){
res.push(n);
n = n.right;
}
console.log("Children: ", res);
console.log("Children content: ", res.filter((m)=>!m.deleted).map((m)=>m.content));
};
class $52a83e33f2b9e935$export$b9e8b5fa1162ca4e {
/**
* @param {Doc} doc
* @param {YMap} [storeType]
*/ constructor(doc, storeType = doc.getMap("users")){
/**
* @type {Map}
*/ const dss = new Map();
this.yusers = storeType;
this.doc = doc;
/**
* Maps from clientid to userDescription
*
* @type {Map}
*/ this.clients = new Map();
this.dss = dss;
/**
* @param {YMap} user
* @param {string} userDescription
*/ const initUser = (user, userDescription)=>{
/**
* @type {YArray}
*/ const ds = user.get("ds");
const ids = user.get("ids");
const addClientId = /** @param {number} clientid */ (clientid)=>this.clients.set(clientid, userDescription);
ds.observe(/** @param {YArrayEvent} event */ (event)=>{
event.changes.added.forEach((item)=>{
item.content.getContent().forEach((encodedDs)=>{
if (encodedDs instanceof Uint8Array) this.dss.set(userDescription, $52a83e33f2b9e935$var$mergeDeleteSets([
this.dss.get(userDescription) || $52a83e33f2b9e935$export$8cbac0d946238699(),
$52a83e33f2b9e935$var$readDeleteSet(new $52a83e33f2b9e935$var$DSDecoderV1($f5RS8.createDecoder(encodedDs)))
]));
});
});
});
this.dss.set(userDescription, $52a83e33f2b9e935$var$mergeDeleteSets(ds.map((encodedDs)=>$52a83e33f2b9e935$var$readDeleteSet(new $52a83e33f2b9e935$var$DSDecoderV1($f5RS8.createDecoder(encodedDs))))));
ids.observe(/** @param {YArrayEvent} event */ (event)=>event.changes.added.forEach((item)=>item.content.getContent().forEach(addClientId)));
ids.forEach(addClientId);
};
// observe users
storeType.observe((event)=>{
event.keysChanged.forEach((userDescription)=>initUser(storeType.get(userDescription), userDescription));
});
// add intial data
storeType.forEach(initUser);
}
/**
* @param {Doc} doc
* @param {number} clientid
* @param {string} userDescription
* @param {Object} conf
* @param {function(Transaction, DeleteSet):boolean} [conf.filter]
*/ setUserMapping(doc, clientid, userDescription, { filter: filter = ()=>true } = {}) {
const users = this.yusers;
let user = users.get(userDescription);
if (!user) {
user = new $52a83e33f2b9e935$export$a5c7b93649eaf8f8();
user.set("ids", new $52a83e33f2b9e935$export$c4be6576ca6fe4aa());
user.set("ds", new $52a83e33f2b9e935$export$c4be6576ca6fe4aa());
users.set(userDescription, user);
}
user.get("ids").push([
clientid
]);
users.observe((_event)=>{
setTimeout(()=>{
const userOverwrite = users.get(userDescription);
if (userOverwrite !== user) {
// user was overwritten, port all data over to the next user object
// @todo Experiment with Y.Sets here
user = userOverwrite;
// @todo iterate over old type
this.clients.forEach((_userDescription, clientid)=>{
if (userDescription === _userDescription) user.get("ids").push([
clientid
]);
});
const encoder = new $52a83e33f2b9e935$var$DSEncoderV1();
const ds = this.dss.get(userDescription);
if (ds) {
$52a83e33f2b9e935$var$writeDeleteSet(encoder, ds);
user.get("ds").push([
encoder.toUint8Array()
]);
}
}
}, 0);
});
doc.on("afterTransaction", /** @param {Transaction} transaction */ (transaction)=>{
setTimeout(()=>{
const yds = user.get("ds");
const ds = transaction.deleteSet;
if (transaction.local && ds.clients.size > 0 && filter(transaction, ds)) {
const encoder = new $52a83e33f2b9e935$var$DSEncoderV1();
$52a83e33f2b9e935$var$writeDeleteSet(encoder, ds);
yds.push([
encoder.toUint8Array()
]);
}
});
});
}
/**
* @param {number} clientid
* @return {any}
*/ getUserByClientId(clientid) {
return this.clients.get(clientid) || null;
}
/**
* @param {ID} id
* @return {string | null}
*/ getUserByDeletedId(id) {
for (const [userDescription, ds] of this.dss.entries()){
if ($52a83e33f2b9e935$export$dcb04af092e44fde(ds, id)) return userDescription;
}
return null;
}
}
/**
* A relative position is based on the Yjs model and is not affected by document changes.
* E.g. If you place a relative position before a certain character, it will always point to this character.
* If you place a relative position at the end of a type, it will always point to the end of the type.
*
* A numeric position is often unsuited for user selections, because it does not change when content is inserted
* before or after.
*
* ```Insert(0, 'x')('a|bc') = 'xa|bc'``` Where | is the relative position.
*
* One of the properties must be defined.
*
* @example
* // Current cursor position is at position 10
* const relativePosition = createRelativePositionFromIndex(yText, 10)
* // modify yText
* yText.insert(0, 'abc')
* yText.delete(3, 10)
* // Compute the cursor position
* const absolutePosition = createAbsolutePositionFromRelativePosition(y, relativePosition)
* absolutePosition.type === yText // => true
* console.log('cursor location is ' + absolutePosition.index) // => cursor location is 3
*
*/ class $52a83e33f2b9e935$export$da21a415c5907662 {
/**
* @param {ID|null} type
* @param {string|null} tname
* @param {ID|null} item
* @param {number} assoc
*/ constructor(type, tname, item, assoc = 0){
/**
* @type {ID|null}
*/ this.type = type;
/**
* @type {string|null}
*/ this.tname = tname;
/**
* @type {ID | null}
*/ this.item = item;
/**
* A relative position is associated to a specific character. By default
* assoc >= 0, the relative position is associated to the character
* after the meant position.
* I.e. position 1 in 'ab' is associated to character 'b'.
*
* If assoc < 0, then the relative position is associated to the caharacter
* before the meant position.
*
* @type {number}
*/ this.assoc = assoc;
}
}
/**
* @param {RelativePosition} rpos
* @return {any}
*/ const $52a83e33f2b9e935$export$a783b081767a452e = (rpos)=>{
const json = {};
if (rpos.type) json.type = rpos.type;
if (rpos.tname) json.tname = rpos.tname;
if (rpos.item) json.item = rpos.item;
if (rpos.assoc != null) json.assoc = rpos.assoc;
return json;
};
/**
* @param {any} json
* @return {RelativePosition}
*
* @function
*/ const $52a83e33f2b9e935$export$ddad8a1b8f7475d8 = (json)=>new $52a83e33f2b9e935$export$da21a415c5907662(json.type == null ? null : $52a83e33f2b9e935$export$6c7d4e6171d008d0(json.type.client, json.type.clock), json.tname || null, json.item == null ? null : $52a83e33f2b9e935$export$6c7d4e6171d008d0(json.item.client, json.item.clock), json.assoc == null ? 0 : json.assoc);
class $52a83e33f2b9e935$export$64c95a3fb7344864 {
/**
* @param {AbstractType} type
* @param {number} index
* @param {number} [assoc]
*/ constructor(type, index, assoc = 0){
/**
* @type {AbstractType}
*/ this.type = type;
/**
* @type {number}
*/ this.index = index;
this.assoc = assoc;
}
}
/**
* @param {AbstractType} type
* @param {number} index
* @param {number} [assoc]
*
* @function
*/ const $52a83e33f2b9e935$var$createAbsolutePosition = (type, index, assoc = 0)=>new $52a83e33f2b9e935$export$64c95a3fb7344864(type, index, assoc);
/**
* @param {AbstractType} type
* @param {ID|null} item
* @param {number} [assoc]
*
* @function
*/ const $52a83e33f2b9e935$var$createRelativePosition = (type, item, assoc)=>{
let typeid = null;
let tname = null;
if (type._item === null) tname = $52a83e33f2b9e935$export$e726a40920d54663(type);
else typeid = $52a83e33f2b9e935$export$6c7d4e6171d008d0(type._item.id.client, type._item.id.clock);
return new $52a83e33f2b9e935$export$da21a415c5907662(typeid, tname, item, assoc);
};
/**
* Create a relativePosition based on a absolute position.
*
* @param {AbstractType} type The base type (e.g. YText or YArray).
* @param {number} index The absolute position.
* @param {number} [assoc]
* @return {RelativePosition}
*
* @function
*/ const $52a83e33f2b9e935$export$197e7d99e3857e88 = (type, index, assoc = 0)=>{
let t = type._start;
if (assoc < 0) {
// associated to the left character or the beginning of a type, increment index if possible.
if (index === 0) return $52a83e33f2b9e935$var$createRelativePosition(type, null, assoc);
index--;
}
while(t !== null){
if (!t.deleted && t.countable) {
if (t.length > index) // case 1: found position somewhere in the linked list
return $52a83e33f2b9e935$var$createRelativePosition(type, $52a83e33f2b9e935$export$6c7d4e6171d008d0(t.id.client, t.id.clock + index), assoc);
index -= t.length;
}
if (t.right === null && assoc < 0) // left-associated position, return last available id
return $52a83e33f2b9e935$var$createRelativePosition(type, t.lastId, assoc);
t = t.right;
}
return $52a83e33f2b9e935$var$createRelativePosition(type, null, assoc);
};
/**
* @param {encoding.Encoder} encoder
* @param {RelativePosition} rpos
*
* @function
*/ const $52a83e33f2b9e935$var$writeRelativePosition = (encoder, rpos)=>{
const { type: type, tname: tname, item: item, assoc: assoc } = rpos;
if (item !== null) {
$1p1sv.writeVarUint(encoder, 0);
$52a83e33f2b9e935$var$writeID(encoder, item);
} else if (tname !== null) {
// case 2: found position at the end of the list and type is stored in y.share
$1p1sv.writeUint8(encoder, 1);
$1p1sv.writeVarString(encoder, tname);
} else if (type !== null) {
// case 3: found position at the end of the list and type is attached to an item
$1p1sv.writeUint8(encoder, 2);
$52a83e33f2b9e935$var$writeID(encoder, type);
} else throw $akmFO.unexpectedCase();
$1p1sv.writeVarInt(encoder, assoc);
return encoder;
};
/**
* @param {RelativePosition} rpos
* @return {Uint8Array}
*/ const $52a83e33f2b9e935$export$c5c95ef724203575 = (rpos)=>{
const encoder = $1p1sv.createEncoder();
$52a83e33f2b9e935$var$writeRelativePosition(encoder, rpos);
return $1p1sv.toUint8Array(encoder);
};
/**
* @param {decoding.Decoder} decoder
* @return {RelativePosition}
*
* @function
*/ const $52a83e33f2b9e935$var$readRelativePosition = (decoder)=>{
let type = null;
let tname = null;
let itemID = null;
switch($f5RS8.readVarUint(decoder)){
case 0:
// case 1: found position somewhere in the linked list
itemID = $52a83e33f2b9e935$var$readID(decoder);
break;
case 1:
// case 2: found position at the end of the list and type is stored in y.share
tname = $f5RS8.readVarString(decoder);
break;
case 2:
// case 3: found position at the end of the list and type is attached to an item
type = $52a83e33f2b9e935$var$readID(decoder);
}
const assoc = $f5RS8.hasContent(decoder) ? $f5RS8.readVarInt(decoder) : 0;
return new $52a83e33f2b9e935$export$da21a415c5907662(type, tname, itemID, assoc);
};
/**
* @param {Uint8Array} uint8Array
* @return {RelativePosition}
*/ const $52a83e33f2b9e935$export$58a46cebc90e7851 = (uint8Array)=>$52a83e33f2b9e935$var$readRelativePosition($f5RS8.createDecoder(uint8Array));
/**
* @param {RelativePosition} rpos
* @param {Doc} doc
* @return {AbsolutePosition|null}
*
* @function
*/ const $52a83e33f2b9e935$export$8fc3152f62fb7ed1 = (rpos, doc)=>{
const store = doc.store;
const rightID = rpos.item;
const typeID = rpos.type;
const tname = rpos.tname;
const assoc = rpos.assoc;
let type = null;
let index = 0;
if (rightID !== null) {
if ($52a83e33f2b9e935$export$50fdfeece43146fd(store, rightID.client) <= rightID.clock) return null;
const res = $52a83e33f2b9e935$var$followRedone(store, rightID);
const right = res.item;
if (!(right instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2)) return null;
type = /** @type {AbstractType} */ right.parent;
if (type._item === null || !type._item.deleted) {
index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); // adjust position based on left association if necessary
let n = right.left;
while(n !== null){
if (!n.deleted && n.countable) index += n.length;
n = n.left;
}
}
} else {
if (tname !== null) type = doc.get(tname);
else if (typeID !== null) {
if ($52a83e33f2b9e935$export$50fdfeece43146fd(store, typeID.client) <= typeID.clock) // type does not exist yet
return null;
const { item: item } = $52a83e33f2b9e935$var$followRedone(store, typeID);
if (item instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2 && item.content instanceof $52a83e33f2b9e935$export$e2e108cbe2e4f865) type = item.content.type;
else // struct is garbage collected
return null;
} else throw $akmFO.unexpectedCase();
if (assoc >= 0) index = type._length;
else index = 0;
}
return $52a83e33f2b9e935$var$createAbsolutePosition(type, index, rpos.assoc);
};
/**
* @param {RelativePosition|null} a
* @param {RelativePosition|null} b
* @return {boolean}
*
* @function
*/ const $52a83e33f2b9e935$export$fc8bd253c948b475 = (a, b)=>a === b || a !== null && b !== null && a.tname === b.tname && $52a83e33f2b9e935$export$c0af976e7e459c02(a.item, b.item) && $52a83e33f2b9e935$export$c0af976e7e459c02(a.type, b.type) && a.assoc === b.assoc;
class $52a83e33f2b9e935$export$c963130a5525248f {
/**
* @param {DeleteSet} ds
* @param {Map} sv state map
*/ constructor(ds, sv){
/**
* @type {DeleteSet}
*/ this.ds = ds;
/**
* State Map
* @type {Map}
*/ this.sv = sv;
}
}
/**
* @param {Snapshot} snap1
* @param {Snapshot} snap2
* @return {boolean}
*/ const $52a83e33f2b9e935$export$742742a0f55b273d = (snap1, snap2)=>{
const ds1 = snap1.ds.clients;
const ds2 = snap2.ds.clients;
const sv1 = snap1.sv;
const sv2 = snap2.sv;
if (sv1.size !== sv2.size || ds1.size !== ds2.size) return false;
for (const [key, value] of sv1.entries()){
if (sv2.get(key) !== value) return false;
}
for (const [client, dsitems1] of ds1.entries()){
const dsitems2 = ds2.get(client) || [];
if (dsitems1.length !== dsitems2.length) return false;
for(let i = 0; i < dsitems1.length; i++){
const dsitem1 = dsitems1[i];
const dsitem2 = dsitems2[i];
if (dsitem1.clock !== dsitem2.clock || dsitem1.len !== dsitem2.len) return false;
}
}
return true;
};
/**
* @param {Snapshot} snapshot
* @param {DSEncoderV1 | DSEncoderV2} [encoder]
* @return {Uint8Array}
*/ const $52a83e33f2b9e935$export$b946cadc55f8e512 = (snapshot, encoder = new $52a83e33f2b9e935$var$DSEncoderV2())=>{
$52a83e33f2b9e935$var$writeDeleteSet(encoder, snapshot.ds);
$52a83e33f2b9e935$var$writeStateVector(encoder, snapshot.sv);
return encoder.toUint8Array();
};
/**
* @param {Snapshot} snapshot
* @return {Uint8Array}
*/ const $52a83e33f2b9e935$export$a6d29989648e995 = (snapshot)=>$52a83e33f2b9e935$export$b946cadc55f8e512(snapshot, new $52a83e33f2b9e935$var$DSEncoderV1());
/**
* @param {Uint8Array} buf
* @param {DSDecoderV1 | DSDecoderV2} [decoder]
* @return {Snapshot}
*/ const $52a83e33f2b9e935$export$b0049fa299f4f58e = (buf, decoder = new $52a83e33f2b9e935$var$DSDecoderV2($f5RS8.createDecoder(buf)))=>{
return new $52a83e33f2b9e935$export$c963130a5525248f($52a83e33f2b9e935$var$readDeleteSet(decoder), $52a83e33f2b9e935$var$readStateVector(decoder));
};
/**
* @param {Uint8Array} buf
* @return {Snapshot}
*/ const $52a83e33f2b9e935$export$5c696daccf32bd2e = (buf)=>$52a83e33f2b9e935$export$b0049fa299f4f58e(buf, new $52a83e33f2b9e935$var$DSDecoderV1($f5RS8.createDecoder(buf)));
/**
* @param {DeleteSet} ds
* @param {Map} sm
* @return {Snapshot}
*/ const $52a83e33f2b9e935$export$548fae0445f878fd = (ds, sm)=>new $52a83e33f2b9e935$export$c963130a5525248f(ds, sm);
const $52a83e33f2b9e935$export$d4568a81dd107a34 = $52a83e33f2b9e935$export$548fae0445f878fd($52a83e33f2b9e935$export$8cbac0d946238699(), new Map());
/**
* @param {Doc} doc
* @return {Snapshot}
*/ const $52a83e33f2b9e935$export$b8801ea43165ed7d = (doc)=>$52a83e33f2b9e935$export$548fae0445f878fd($52a83e33f2b9e935$export$8450d668bec558e2(doc.store), $52a83e33f2b9e935$var$getStateVector(doc.store));
/**
* @param {Item} item
* @param {Snapshot|undefined} snapshot
*
* @protected
* @function
*/ const $52a83e33f2b9e935$var$isVisible = (item, snapshot)=>snapshot === undefined ? !item.deleted : snapshot.sv.has(item.id.client) && (snapshot.sv.get(item.id.client) || 0) > item.id.clock && !$52a83e33f2b9e935$export$dcb04af092e44fde(snapshot.ds, item.id);
/**
* @param {Transaction} transaction
* @param {Snapshot} snapshot
*/ const $52a83e33f2b9e935$var$splitSnapshotAffectedStructs = (transaction, snapshot)=>{
const meta = $e6DQe.setIfUndefined(transaction.meta, $52a83e33f2b9e935$var$splitSnapshotAffectedStructs, $gB6ZU.create);
const store = transaction.doc.store;
// check if we already split for this snapshot
if (!meta.has(snapshot)) {
snapshot.sv.forEach((clock, client)=>{
if (clock < $52a83e33f2b9e935$export$50fdfeece43146fd(store, client)) $52a83e33f2b9e935$var$getItemCleanStart(transaction, $52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock));
});
$52a83e33f2b9e935$export$8afefebbaf4e4c78(transaction, snapshot.ds, (_item)=>{});
meta.add(snapshot);
}
};
/**
* @example
* const ydoc = new Y.Doc({ gc: false })
* ydoc.getText().insert(0, 'world!')
* const snapshot = Y.snapshot(ydoc)
* ydoc.getText().insert(0, 'hello ')
* const restored = Y.createDocFromSnapshot(ydoc, snapshot)
* assert(restored.getText().toString() === 'world!')
*
* @param {Doc} originDoc
* @param {Snapshot} snapshot
* @param {Doc} [newDoc] Optionally, you may define the Yjs document that receives the data from originDoc
* @return {Doc}
*/ const $52a83e33f2b9e935$export$5be4ae1e1e56a014 = (originDoc, snapshot, newDoc = new $52a83e33f2b9e935$export$bceacc74c2212615())=>{
if (originDoc.gc) // we should not try to restore a GC-ed document, because some of the restored items might have their content deleted
throw new Error("Garbage-collection must be disabled in `originDoc`!");
const { sv: sv, ds: ds } = snapshot;
const encoder = new $52a83e33f2b9e935$var$UpdateEncoderV2();
originDoc.transact((transaction)=>{
let size = 0;
sv.forEach((clock)=>{
if (clock > 0) size++;
});
$1p1sv.writeVarUint(encoder.restEncoder, size);
// splitting the structs before writing them to the encoder
for (const [client, clock] of sv){
if (clock === 0) continue;
if (clock < $52a83e33f2b9e935$export$50fdfeece43146fd(originDoc.store, client)) $52a83e33f2b9e935$var$getItemCleanStart(transaction, $52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock));
const structs = originDoc.store.clients.get(client) || [];
const lastStructIndex = $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, clock - 1);
// write # encoded structs
$1p1sv.writeVarUint(encoder.restEncoder, lastStructIndex + 1);
encoder.writeClient(client);
// first clock written is 0
$1p1sv.writeVarUint(encoder.restEncoder, 0);
for(let i = 0; i <= lastStructIndex; i++)structs[i].write(encoder, 0);
}
$52a83e33f2b9e935$var$writeDeleteSet(encoder, ds);
});
$52a83e33f2b9e935$export$acc3b0324aabf1b6(newDoc, encoder.toUint8Array(), "snapshot");
return newDoc;
};
/**
* @param {Snapshot} snapshot
* @param {Uint8Array} update
* @param {typeof UpdateDecoderV2 | typeof UpdateDecoderV1} [YDecoder]
*/ const $52a83e33f2b9e935$var$snapshotContainsUpdateV2 = (snapshot, update, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2)=>{
const updateDecoder = new YDecoder($f5RS8.createDecoder(update));
const lazyDecoder = new $52a83e33f2b9e935$var$LazyStructReader(updateDecoder, false);
for(let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()){
if ((snapshot.sv.get(curr.id.client) || 0) < curr.id.clock + curr.length) return false;
}
const mergedDS = $52a83e33f2b9e935$var$mergeDeleteSets([
snapshot.ds,
$52a83e33f2b9e935$var$readDeleteSet(updateDecoder)
]);
return $52a83e33f2b9e935$export$9697b72c46fd3a5d(snapshot.ds, mergedDS);
};
/**
* @param {Snapshot} snapshot
* @param {Uint8Array} update
*/ const $52a83e33f2b9e935$export$f938135bed5d8db7 = (snapshot, update)=>$52a83e33f2b9e935$var$snapshotContainsUpdateV2(snapshot, update, $52a83e33f2b9e935$var$UpdateDecoderV1);
class $52a83e33f2b9e935$var$StructStore {
constructor(){
/**
* @type {Map>}
*/ this.clients = new Map();
/**
* @type {null | { missing: Map, update: Uint8Array }}
*/ this.pendingStructs = null;
/**
* @type {null | Uint8Array}
*/ this.pendingDs = null;
}
}
/**
* Return the states as a Map.
* Note that clock refers to the next expected clock id.
*
* @param {StructStore} store
* @return {Map}
*
* @public
* @function
*/ const $52a83e33f2b9e935$var$getStateVector = (store)=>{
const sm = new Map();
store.clients.forEach((structs, client)=>{
const struct = structs[structs.length - 1];
sm.set(client, struct.id.clock + struct.length);
});
return sm;
};
/**
* @param {StructStore} store
* @param {number} client
* @return {number}
*
* @public
* @function
*/ const $52a83e33f2b9e935$export$50fdfeece43146fd = (store, client)=>{
const structs = store.clients.get(client);
if (structs === undefined) return 0;
const lastStruct = structs[structs.length - 1];
return lastStruct.id.clock + lastStruct.length;
};
/**
* @param {StructStore} store
* @param {GC|Item} struct
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$addStruct = (store, struct)=>{
let structs = store.clients.get(struct.id.client);
if (structs === undefined) {
structs = [];
store.clients.set(struct.id.client, structs);
} else {
const lastStruct = structs[structs.length - 1];
if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) throw $akmFO.unexpectedCase();
}
structs.push(struct);
};
/**
* Perform a binary search on a sorted array
* @param {Array
- } structs
* @param {number} clock
* @return {number}
*
* @private
* @function
*/ const $52a83e33f2b9e935$export$5f8f02523cf47b58 = (structs, clock)=>{
let left = 0;
let right = structs.length - 1;
let mid = structs[right];
let midclock = mid.id.clock;
if (midclock === clock) return right;
// @todo does it even make sense to pivot the search?
// If a good split misses, it might actually increase the time to find the correct item.
// Currently, the only advantage is that search with pivoting might find the item on the first try.
let midindex = $kuitL.floor(clock / (midclock + mid.length - 1) * right); // pivoting the search
while(left <= right){
mid = structs[midindex];
midclock = mid.id.clock;
if (midclock <= clock) {
if (clock < midclock + mid.length) return midindex;
left = midindex + 1;
} else right = midindex - 1;
midindex = $kuitL.floor((left + right) / 2);
}
// Always check state before looking for a struct in StructStore
// Therefore the case of not finding a struct is unexpected
throw $akmFO.unexpectedCase();
};
/**
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
*
* @param {StructStore} store
* @param {ID} id
* @return {GC|Item}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$find = (store, id)=>{
/**
* @type {Array}
*/ // @ts-ignore
const structs = store.clients.get(id.client);
return structs[$52a83e33f2b9e935$export$5f8f02523cf47b58(structs, id.clock)];
};
/**
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
* @private
* @function
*/ const $52a83e33f2b9e935$export$f92dfeb71e9bb569 = /** @type {function(StructStore,ID):Item} */ $52a83e33f2b9e935$var$find;
/**
* @param {Transaction} transaction
* @param {Array
- } structs
* @param {number} clock
*/ const $52a83e33f2b9e935$var$findIndexCleanStart = (transaction, structs, clock)=>{
const index = $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, clock);
const struct = structs[index];
if (struct.id.clock < clock && struct instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2) {
structs.splice(index + 1, 0, $52a83e33f2b9e935$var$splitItem(transaction, struct, clock - struct.id.clock));
return index + 1;
}
return index;
};
/**
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
*
* @param {Transaction} transaction
* @param {ID} id
* @return {Item}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$getItemCleanStart = (transaction, id)=>{
const structs = /** @type {Array
- } */ transaction.doc.store.clients.get(id.client);
return structs[$52a83e33f2b9e935$var$findIndexCleanStart(transaction, structs, id.clock)];
};
/**
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
*
* @param {Transaction} transaction
* @param {StructStore} store
* @param {ID} id
* @return {Item}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$getItemCleanEnd = (transaction, store, id)=>{
/**
* @type {Array
- }
*/ // @ts-ignore
const structs = store.clients.get(id.client);
const index = $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, id.clock);
const struct = structs[index];
if (id.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== $52a83e33f2b9e935$export$12d259ff017e6b58) structs.splice(index + 1, 0, $52a83e33f2b9e935$var$splitItem(transaction, struct, id.clock - struct.id.clock + 1));
return struct;
};
/**
* Replace `item` with `newitem` in store
* @param {StructStore} store
* @param {GC|Item} struct
* @param {GC|Item} newStruct
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$replaceStruct = (store, struct, newStruct)=>{
const structs = /** @type {Array} */ store.clients.get(struct.id.client);
structs[$52a83e33f2b9e935$export$5f8f02523cf47b58(structs, struct.id.clock)] = newStruct;
};
/**
* Iterate over a range of structs
*
* @param {Transaction} transaction
* @param {Array
- } structs
* @param {number} clockStart Inclusive start
* @param {number} len
* @param {function(GC|Item):void} f
*
* @function
*/ const $52a83e33f2b9e935$var$iterateStructs = (transaction, structs, clockStart, len, f)=>{
if (len === 0) return;
const clockEnd = clockStart + len;
let index = $52a83e33f2b9e935$var$findIndexCleanStart(transaction, structs, clockStart);
let struct;
do {
struct = structs[index++];
if (clockEnd < struct.id.clock + struct.length) $52a83e33f2b9e935$var$findIndexCleanStart(transaction, structs, clockEnd);
f(struct);
}while (index < structs.length && structs[index].id.clock < clockEnd);
};
/**
* A transaction is created for every change on the Yjs model. It is possible
* to bundle changes on the Yjs model in a single transaction to
* minimize the number on messages sent and the number of observer calls.
* If possible the user of this library should bundle as many changes as
* possible. Here is an example to illustrate the advantages of bundling:
*
* @example
* const map = y.define('map', YMap)
* // Log content when change is triggered
* map.observe(() => {
* console.log('change triggered')
* })
* // Each change on the map type triggers a log message:
* map.set('a', 0) // => "change triggered"
* map.set('b', 0) // => "change triggered"
* // When put in a transaction, it will trigger the log after the transaction:
* y.transact(() => {
* map.set('a', 1)
* map.set('b', 1)
* }) // => "change triggered"
*
* @public
*/ class $52a83e33f2b9e935$export$febc5573c75cefb0 {
/**
* @param {Doc} doc
* @param {any} origin
* @param {boolean} local
*/ constructor(doc, origin, local){
/**
* The Yjs instance.
* @type {Doc}
*/ this.doc = doc;
/**
* Describes the set of deleted items by ids
* @type {DeleteSet}
*/ this.deleteSet = new $52a83e33f2b9e935$var$DeleteSet();
/**
* Holds the state before the transaction started.
* @type {Map}
*/ this.beforeState = $52a83e33f2b9e935$var$getStateVector(doc.store);
/**
* Holds the state after the transaction.
* @type {Map}
*/ this.afterState = new Map();
/**
* All types that were directly modified (property added or child
* inserted/deleted). New types are not included in this Set.
* Maps from type to parentSubs (`item.parentSub = null` for YArray)
* @type {Map>,Set>}
*/ this.changed = new Map();
/**
* Stores the events for the types that observe also child elements.
* It is mainly used by `observeDeep`.
* @type {Map>,Array>>}
*/ this.changedParentTypes = new Map();
/**
* @type {Array}
*/ this._mergeStructs = [];
/**
* @type {any}
*/ this.origin = origin;
/**
* Stores meta information on the transaction
* @type {Map}
*/ this.meta = new Map();
/**
* Whether this change originates from this doc.
* @type {boolean}
*/ this.local = local;
/**
* @type {Set}
*/ this.subdocsAdded = new Set();
/**
* @type {Set}
*/ this.subdocsRemoved = new Set();
/**
* @type {Set}
*/ this.subdocsLoaded = new Set();
/**
* @type {boolean}
*/ this._needFormattingCleanup = false;
}
}
/**
* @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
* @param {Transaction} transaction
* @return {boolean} Whether data was written.
*/ const $52a83e33f2b9e935$var$writeUpdateMessageFromTransaction = (encoder, transaction)=>{
if (transaction.deleteSet.clients.size === 0 && !$e6DQe.any(transaction.afterState, (clock, client)=>transaction.beforeState.get(client) !== clock)) return false;
$52a83e33f2b9e935$var$sortAndMergeDeleteSet(transaction.deleteSet);
$52a83e33f2b9e935$var$writeStructsFromTransaction(encoder, transaction);
$52a83e33f2b9e935$var$writeDeleteSet(encoder, transaction.deleteSet);
return true;
};
/**
* If `type.parent` was added in current transaction, `type` technically
* did not change, it was just added and we should not fire events for `type`.
*
* @param {Transaction} transaction
* @param {AbstractType>} type
* @param {string|null} parentSub
*/ const $52a83e33f2b9e935$var$addChangedTypeToTransaction = (transaction, type, parentSub)=>{
const item = type._item;
if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) $e6DQe.setIfUndefined(transaction.changed, type, $gB6ZU.create).add(parentSub);
};
/**
* @param {Array} structs
* @param {number} pos
* @return {number} # of merged structs
*/ const $52a83e33f2b9e935$var$tryToMergeWithLefts = (structs, pos)=>{
let right = structs[pos];
let left = structs[pos - 1];
let i = pos;
for(; i > 0; right = left, left = structs[--i - 1]){
if (left.deleted === right.deleted && left.constructor === right.constructor) {
if (left.mergeWith(right)) {
if (right instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2 && right.parentSub !== null && /** @type {AbstractType} */ right.parent._map.get(right.parentSub) === right) /** @type {AbstractType} */ right.parent._map.set(right.parentSub, /** @type {Item} */ left);
continue;
}
}
break;
}
const merged = pos - i;
if (merged) // remove all merged structs from the array
structs.splice(pos + 1 - merged, merged);
return merged;
};
/**
* @param {DeleteSet} ds
* @param {StructStore} store
* @param {function(Item):boolean} gcFilter
*/ const $52a83e33f2b9e935$var$tryGcDeleteSet = (ds, store, gcFilter)=>{
for (const [client, deleteItems] of ds.clients.entries()){
const structs = /** @type {Array} */ store.clients.get(client);
for(let di = deleteItems.length - 1; di >= 0; di--){
const deleteItem = deleteItems[di];
const endDeleteItemClock = deleteItem.clock + deleteItem.len;
for(let si = $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]){
const struct = structs[si];
if (deleteItem.clock + deleteItem.len <= struct.id.clock) break;
if (struct instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2 && struct.deleted && !struct.keep && gcFilter(struct)) struct.gc(store, false);
}
}
}
};
/**
* @param {DeleteSet} ds
* @param {StructStore} store
*/ const $52a83e33f2b9e935$var$tryMergeDeleteSet = (ds, store)=>{
// try to merge deleted / gc'd items
// merge from right to left for better efficiecy and so we don't miss any merge targets
ds.clients.forEach((deleteItems, client)=>{
const structs = /** @type {Array} */ store.clients.get(client);
for(let di = deleteItems.length - 1; di >= 0; di--){
const deleteItem = deleteItems[di];
// start with merging the item next to the last deleted item
const mostRightIndexToCheck = $kuitL.min(structs.length - 1, 1 + $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, deleteItem.clock + deleteItem.len - 1));
for(let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si])si -= 1 + $52a83e33f2b9e935$var$tryToMergeWithLefts(structs, si);
}
});
};
/**
* @param {DeleteSet} ds
* @param {StructStore} store
* @param {function(Item):boolean} gcFilter
*/ const $52a83e33f2b9e935$export$c2e5de00fc43f658 = (ds, store, gcFilter)=>{
$52a83e33f2b9e935$var$tryGcDeleteSet(ds, store, gcFilter);
$52a83e33f2b9e935$var$tryMergeDeleteSet(ds, store);
};
/**
* @param {Array} transactionCleanups
* @param {number} i
*/ const $52a83e33f2b9e935$var$cleanupTransactions = (transactionCleanups, i)=>{
if (i < transactionCleanups.length) {
const transaction = transactionCleanups[i];
const doc = transaction.doc;
const store = doc.store;
const ds = transaction.deleteSet;
const mergeStructs = transaction._mergeStructs;
try {
$52a83e33f2b9e935$var$sortAndMergeDeleteSet(ds);
transaction.afterState = $52a83e33f2b9e935$var$getStateVector(transaction.doc.store);
doc.emit("beforeObserverCalls", [
transaction,
doc
]);
/**
* An array of event callbacks.
*
* Each callback is called even if the other ones throw errors.
*
* @type {Array}
*/ const fs = [];
// observe events on changed types
transaction.changed.forEach((subs, itemtype)=>fs.push(()=>{
if (itemtype._item === null || !itemtype._item.deleted) itemtype._callObserver(transaction, subs);
}));
fs.push(()=>{
// deep observe events
transaction.changedParentTypes.forEach((events, type)=>{
// We need to think about the possibility that the user transforms the
// Y.Doc in the event.
if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) {
events = events.filter((event)=>event.target._item === null || !event.target._item.deleted);
events.forEach((event)=>{
event.currentTarget = type;
// path is relative to the current target
event._path = null;
});
// sort events by path length so that top-level events are fired first.
events.sort((event1, event2)=>event1.path.length - event2.path.length);
// We don't need to check for events.length
// because we know it has at least one element
$52a83e33f2b9e935$var$callEventHandlerListeners(type._dEH, events, transaction);
}
});
});
fs.push(()=>doc.emit("afterTransaction", [
transaction,
doc
]));
(0, $kXTKb.callAll)(fs, []);
if (transaction._needFormattingCleanup) $52a83e33f2b9e935$var$cleanupYTextAfterTransaction(transaction);
} finally{
// Replace deleted items with ItemDeleted / GC.
// This is where content is actually remove from the Yjs Doc.
if (doc.gc) $52a83e33f2b9e935$var$tryGcDeleteSet(ds, store, doc.gcFilter);
$52a83e33f2b9e935$var$tryMergeDeleteSet(ds, store);
// on all affected store.clients props, try to merge
transaction.afterState.forEach((clock, client)=>{
const beforeClock = transaction.beforeState.get(client) || 0;
if (beforeClock !== clock) {
const structs = /** @type {Array} */ store.clients.get(client);
// we iterate from right to left so we can safely remove entries
const firstChangePos = $kuitL.max($52a83e33f2b9e935$export$5f8f02523cf47b58(structs, beforeClock), 1);
for(let i = structs.length - 1; i >= firstChangePos;)i -= 1 + $52a83e33f2b9e935$var$tryToMergeWithLefts(structs, i);
}
});
// try to merge mergeStructs
// @todo: it makes more sense to transform mergeStructs to a DS, sort it, and merge from right to left
// but at the moment DS does not handle duplicates
for(let i = mergeStructs.length - 1; i >= 0; i--){
const { client: client, clock: clock } = mergeStructs[i].id;
const structs = /** @type {Array} */ store.clients.get(client);
const replacedStructPos = $52a83e33f2b9e935$export$5f8f02523cf47b58(structs, clock);
if (replacedStructPos + 1 < structs.length) {
if ($52a83e33f2b9e935$var$tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) continue; // no need to perform next check, both are already merged
}
if (replacedStructPos > 0) $52a83e33f2b9e935$var$tryToMergeWithLefts(structs, replacedStructPos);
}
if (!transaction.local && transaction.afterState.get(doc.clientID) !== transaction.beforeState.get(doc.clientID)) {
$dcfNU.print($7i7Pw.ORANGE, $7i7Pw.BOLD, "[yjs] ", $7i7Pw.UNBOLD, $7i7Pw.RED, "Changed the client-id because another client seems to be using it.");
doc.clientID = $52a83e33f2b9e935$var$generateNewClientId();
}
// @todo Merge all the transactions into one and provide send the data as a single update message
doc.emit("afterTransactionCleanup", [
transaction,
doc
]);
if (doc._observers.has("update")) {
const encoder = new $52a83e33f2b9e935$export$99171b804d9c5b54();
const hasContent = $52a83e33f2b9e935$var$writeUpdateMessageFromTransaction(encoder, transaction);
if (hasContent) doc.emit("update", [
encoder.toUint8Array(),
transaction.origin,
doc,
transaction
]);
}
if (doc._observers.has("updateV2")) {
const encoder = new $52a83e33f2b9e935$var$UpdateEncoderV2();
const hasContent = $52a83e33f2b9e935$var$writeUpdateMessageFromTransaction(encoder, transaction);
if (hasContent) doc.emit("updateV2", [
encoder.toUint8Array(),
transaction.origin,
doc,
transaction
]);
}
const { subdocsAdded: subdocsAdded, subdocsLoaded: subdocsLoaded, subdocsRemoved: subdocsRemoved } = transaction;
if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) {
subdocsAdded.forEach((subdoc)=>{
subdoc.clientID = doc.clientID;
if (subdoc.collectionid == null) subdoc.collectionid = doc.collectionid;
doc.subdocs.add(subdoc);
});
subdocsRemoved.forEach((subdoc)=>doc.subdocs.delete(subdoc));
doc.emit("subdocs", [
{
loaded: subdocsLoaded,
added: subdocsAdded,
removed: subdocsRemoved
},
doc,
transaction
]);
subdocsRemoved.forEach((subdoc)=>subdoc.destroy());
}
if (transactionCleanups.length <= i + 1) {
doc._transactionCleanups = [];
doc.emit("afterAllTransactions", [
doc,
transactionCleanups
]);
} else $52a83e33f2b9e935$var$cleanupTransactions(transactionCleanups, i + 1);
}
}
};
/**
* Implements the functionality of `y.transact(()=>{..})`
*
* @template T
* @param {Doc} doc
* @param {function(Transaction):T} f
* @param {any} [origin=true]
* @return {T}
*
* @function
*/ const $52a83e33f2b9e935$export$dac1bad6146b2469 = (doc, f, origin = null, local = true)=>{
const transactionCleanups = doc._transactionCleanups;
let initialCall = false;
/**
* @type {any}
*/ let result = null;
if (doc._transaction === null) {
initialCall = true;
doc._transaction = new $52a83e33f2b9e935$export$febc5573c75cefb0(doc, origin, local);
transactionCleanups.push(doc._transaction);
if (transactionCleanups.length === 1) doc.emit("beforeAllTransactions", [
doc
]);
doc.emit("beforeTransaction", [
doc._transaction,
doc
]);
}
try {
result = f(doc._transaction);
} finally{
if (initialCall) {
const finishCleanup = doc._transaction === transactionCleanups[0];
doc._transaction = null;
if (finishCleanup) // The first transaction ended, now process observer calls.
// Observer call may create new transactions for which we need to call the observers and do cleanup.
// We don't want to nest these calls, so we execute these calls one after
// another.
// Also we need to ensure that all cleanups are called, even if the
// observes throw errors.
// This file is full of hacky try {} finally {} blocks to ensure that an
// event can throw errors and also that the cleanup is called.
$52a83e33f2b9e935$var$cleanupTransactions(transactionCleanups, 0);
}
}
return result;
};
class $52a83e33f2b9e935$var$StackItem {
/**
* @param {DeleteSet} deletions
* @param {DeleteSet} insertions
*/ constructor(deletions, insertions){
this.insertions = insertions;
this.deletions = deletions;
/**
* Use this to save and restore metadata like selection range
*/ this.meta = new Map();
}
}
/**
* @param {Transaction} tr
* @param {UndoManager} um
* @param {StackItem} stackItem
*/ const $52a83e33f2b9e935$var$clearUndoManagerStackItem = (tr, um, stackItem)=>{
$52a83e33f2b9e935$export$8afefebbaf4e4c78(tr, stackItem.deletions, (item)=>{
if (item instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2 && um.scope.some((type)=>$52a83e33f2b9e935$export$3c81af374b054d6a(type, item))) $52a83e33f2b9e935$var$keepItem(item, false);
});
};
/**
* @param {UndoManager} undoManager
* @param {Array} stack
* @param {string} eventType
* @return {StackItem?}
*/ const $52a83e33f2b9e935$var$popStackItem = (undoManager, stack, eventType)=>{
/**
* Whether a change happened
* @type {StackItem?}
*/ let result = null;
/**
* Keep a reference to the transaction so we can fire the event with the changedParentTypes
* @type {any}
*/ let _tr = null;
const doc = undoManager.doc;
const scope = undoManager.scope;
$52a83e33f2b9e935$export$dac1bad6146b2469(doc, (transaction)=>{
while(stack.length > 0 && result === null){
const store = doc.store;
const stackItem = /** @type {StackItem} */ stack.pop();
/**
* @type {Set
- }
*/ const itemsToRedo = new Set();
/**
* @type {Array
- }
*/ const itemsToDelete = [];
let performedChange = false;
$52a83e33f2b9e935$export$8afefebbaf4e4c78(transaction, stackItem.insertions, (struct)=>{
if (struct instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2) {
if (struct.redone !== null) {
let { item: item, diff: diff } = $52a83e33f2b9e935$var$followRedone(store, struct.id);
if (diff > 0) item = $52a83e33f2b9e935$var$getItemCleanStart(transaction, $52a83e33f2b9e935$export$6c7d4e6171d008d0(item.id.client, item.id.clock + diff));
struct = item;
}
if (!struct.deleted && scope.some((type)=>$52a83e33f2b9e935$export$3c81af374b054d6a(type, /** @type {Item} */ struct))) itemsToDelete.push(struct);
}
});
$52a83e33f2b9e935$export$8afefebbaf4e4c78(transaction, stackItem.deletions, (struct)=>{
if (struct instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2 && scope.some((type)=>$52a83e33f2b9e935$export$3c81af374b054d6a(type, struct)) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval.
!$52a83e33f2b9e935$export$dcb04af092e44fde(stackItem.insertions, struct.id)) itemsToRedo.add(struct);
});
itemsToRedo.forEach((struct)=>{
performedChange = $52a83e33f2b9e935$var$redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager.ignoreRemoteMapChanges, undoManager) !== null || performedChange;
});
// We want to delete in reverse order so that children are deleted before
// parents, so we have more information available when items are filtered.
for(let i = itemsToDelete.length - 1; i >= 0; i--){
const item = itemsToDelete[i];
if (undoManager.deleteFilter(item)) {
item.delete(transaction);
performedChange = true;
}
}
result = performedChange ? stackItem : null;
}
transaction.changed.forEach((subProps, type)=>{
// destroy search marker if necessary
if (subProps.has(null) && type._searchMarker) type._searchMarker.length = 0;
});
_tr = transaction;
}, undoManager);
if (result != null) {
const changedParentTypes = _tr.changedParentTypes;
undoManager.emit("stack-item-popped", [
{
stackItem: result,
type: eventType,
changedParentTypes: changedParentTypes
},
undoManager
]);
}
return result;
};
/**
* @typedef {Object} UndoManagerOptions
* @property {number} [UndoManagerOptions.captureTimeout=500]
* @property {function(Transaction):boolean} [UndoManagerOptions.captureTransaction] Do not capture changes of a Transaction if result false.
* @property {function(Item):boolean} [UndoManagerOptions.deleteFilter=()=>true] Sometimes
* it is necessary to filter what an Undo/Redo operation can delete. If this
* filter returns false, the type/item won't be deleted even it is in the
* undo/redo scope.
* @property {Set} [UndoManagerOptions.trackedOrigins=new Set([null])]
* @property {boolean} [ignoreRemoteMapChanges] Experimental. By default, the UndoManager will never overwrite remote changes. Enable this property to enable overwriting remote changes on key-value changes (Y.Map, properties on Y.Xml, etc..).
* @property {Doc} [doc] The document that this UndoManager operates on. Only needed if typeScope is empty.
*/ /**
* Fires 'stack-item-added' event when a stack item was added to either the undo- or
* the redo-stack. You may store additional stack information via the
* metadata property on `event.stackItem.meta` (it is a `Map` of metadata properties).
* Fires 'stack-item-popped' event when a stack item was popped from either the
* undo- or the redo-stack. You may restore the saved stack information from `event.stackItem.meta`.
*
* @extends {Observable<'stack-item-added'|'stack-item-popped'|'stack-cleared'|'stack-item-updated'>}
*/ class $52a83e33f2b9e935$export$932a3f9a7e88971c extends (0, $9XqiC.Observable) {
/**
* @param {AbstractType|Array>} typeScope Accepts either a single type, or an array of types
* @param {UndoManagerOptions} options
*/ constructor(typeScope, { captureTimeout: captureTimeout = 500, captureTransaction: captureTransaction = (_tr)=>true, deleteFilter: deleteFilter = ()=>true, trackedOrigins: trackedOrigins = new Set([
null
]), ignoreRemoteMapChanges: ignoreRemoteMapChanges = false, doc: doc = /** @type {Doc} */ $7sfdv.isArray(typeScope) ? typeScope[0].doc : typeScope.doc } = {}){
super();
/**
* @type {Array>}
*/ this.scope = [];
this.doc = doc;
this.addToScope(typeScope);
this.deleteFilter = deleteFilter;
trackedOrigins.add(this);
this.trackedOrigins = trackedOrigins;
this.captureTransaction = captureTransaction;
/**
* @type {Array}
*/ this.undoStack = [];
/**
* @type {Array}
*/ this.redoStack = [];
/**
* Whether the client is currently undoing (calling UndoManager.undo)
*
* @type {boolean}
*/ this.undoing = false;
this.redoing = false;
this.lastChange = 0;
this.ignoreRemoteMapChanges = ignoreRemoteMapChanges;
this.captureTimeout = captureTimeout;
/**
* @param {Transaction} transaction
*/ this.afterTransactionHandler = (transaction)=>{
// Only track certain transactions
if (!this.captureTransaction(transaction) || !this.scope.some((type)=>transaction.changedParentTypes.has(type)) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) return;
const undoing = this.undoing;
const redoing = this.redoing;
const stack = undoing ? this.redoStack : this.undoStack;
if (undoing) this.stopCapturing(); // next undo should not be appended to last stack item
else if (!redoing) // neither undoing nor redoing: delete redoStack
this.clear(false, true);
const insertions = new $52a83e33f2b9e935$var$DeleteSet();
transaction.afterState.forEach((endClock, client)=>{
const startClock = transaction.beforeState.get(client) || 0;
const len = endClock - startClock;
if (len > 0) $52a83e33f2b9e935$var$addToDeleteSet(insertions, client, startClock, len);
});
const now = $1oyOX.getUnixTime();
let didAdd = false;
if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) {
// append change to last stack op
const lastOp = stack[stack.length - 1];
lastOp.deletions = $52a83e33f2b9e935$var$mergeDeleteSets([
lastOp.deletions,
transaction.deleteSet
]);
lastOp.insertions = $52a83e33f2b9e935$var$mergeDeleteSets([
lastOp.insertions,
insertions
]);
} else {
// create a new stack op
stack.push(new $52a83e33f2b9e935$var$StackItem(transaction.deleteSet, insertions));
didAdd = true;
}
if (!undoing && !redoing) this.lastChange = now;
// make sure that deleted structs are not gc'd
$52a83e33f2b9e935$export$8afefebbaf4e4c78(transaction, transaction.deleteSet, /** @param {Item|GC} item */ (item)=>{
if (item instanceof $52a83e33f2b9e935$export$6d08773d2e66f8f2 && this.scope.some((type)=>$52a83e33f2b9e935$export$3c81af374b054d6a(type, item))) $52a83e33f2b9e935$var$keepItem(item, true);
});
const changeEvent = [
{
stackItem: stack[stack.length - 1],
origin: transaction.origin,
type: undoing ? "redo" : "undo",
changedParentTypes: transaction.changedParentTypes
},
this
];
if (didAdd) this.emit("stack-item-added", changeEvent);
else this.emit("stack-item-updated", changeEvent);
};
this.doc.on("afterTransaction", this.afterTransactionHandler);
this.doc.on("destroy", ()=>{
this.destroy();
});
}
/**
* @param {Array> | AbstractType} ytypes
*/ addToScope(ytypes) {
ytypes = $7sfdv.isArray(ytypes) ? ytypes : [
ytypes
];
ytypes.forEach((ytype)=>{
if (this.scope.every((yt)=>yt !== ytype)) {
if (ytype.doc !== this.doc) $dcfNU.warn("[yjs#509] Not same Y.Doc"); // use MultiDocUndoManager instead. also see https://github.com/yjs/yjs/issues/509
this.scope.push(ytype);
}
});
}
/**
* @param {any} origin
*/ addTrackedOrigin(origin) {
this.trackedOrigins.add(origin);
}
/**
* @param {any} origin
*/ removeTrackedOrigin(origin) {
this.trackedOrigins.delete(origin);
}
clear(clearUndoStack = true, clearRedoStack = true) {
if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) this.doc.transact((tr)=>{
if (clearUndoStack) {
this.undoStack.forEach((item)=>$52a83e33f2b9e935$var$clearUndoManagerStackItem(tr, this, item));
this.undoStack = [];
}
if (clearRedoStack) {
this.redoStack.forEach((item)=>$52a83e33f2b9e935$var$clearUndoManagerStackItem(tr, this, item));
this.redoStack = [];
}
this.emit("stack-cleared", [
{
undoStackCleared: clearUndoStack,
redoStackCleared: clearRedoStack
}
]);
});
}
/**
* UndoManager merges Undo-StackItem if they are created within time-gap
* smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next
* StackItem won't be merged.
*
*
* @example
* // without stopCapturing
* ytext.insert(0, 'a')
* ytext.insert(1, 'b')
* um.undo()
* ytext.toString() // => '' (note that 'ab' was removed)
* // with stopCapturing
* ytext.insert(0, 'a')
* um.stopCapturing()
* ytext.insert(0, 'b')
* um.undo()
* ytext.toString() // => 'a' (note that only 'b' was removed)
*
*/ stopCapturing() {
this.lastChange = 0;
}
/**
* Undo last changes on type.
*
* @return {StackItem?} Returns StackItem if a change was applied
*/ undo() {
this.undoing = true;
let res;
try {
res = $52a83e33f2b9e935$var$popStackItem(this, this.undoStack, "undo");
} finally{
this.undoing = false;
}
return res;
}
/**
* Redo last undo operation.
*
* @return {StackItem?} Returns StackItem if a change was applied
*/ redo() {
this.redoing = true;
let res;
try {
res = $52a83e33f2b9e935$var$popStackItem(this, this.redoStack, "redo");
} finally{
this.redoing = false;
}
return res;
}
/**
* Are undo steps available?
*
* @return {boolean} `true` if undo is possible
*/ canUndo() {
return this.undoStack.length > 0;
}
/**
* Are redo steps available?
*
* @return {boolean} `true` if redo is possible
*/ canRedo() {
return this.redoStack.length > 0;
}
destroy() {
this.trackedOrigins.delete(this);
this.doc.off("afterTransaction", this.afterTransactionHandler);
super.destroy();
}
}
/**
* @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
*/ function* $52a83e33f2b9e935$var$lazyStructReaderGenerator(decoder) {
const numOfStateUpdates = $f5RS8.readVarUint(decoder.restDecoder);
for(let i = 0; i < numOfStateUpdates; i++){
const numberOfStructs = $f5RS8.readVarUint(decoder.restDecoder);
const client = decoder.readClient();
let clock = $f5RS8.readVarUint(decoder.restDecoder);
for(let i = 0; i < numberOfStructs; i++){
const info = decoder.readInfo();
// @todo use switch instead of ifs
if (info === 10) {
const len = $f5RS8.readVarUint(decoder.restDecoder);
yield new $52a83e33f2b9e935$var$Skip($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock), len);
clock += len;
} else if (($1GdQd.BITS5 & info) !== 0) {
const cantCopyParentInfo = (info & ($1GdQd.BIT7 | $1GdQd.BIT8)) === 0;
// If parent = null and neither left nor right are defined, then we know that `parent` is child of `y`
// and we read the next string as parentYKey.
// It indicates how we store/retrieve parent from `y.share`
// @type {string|null}
const struct = new $52a83e33f2b9e935$export$6d08773d2e66f8f2($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock), null, (info & $1GdQd.BIT8) === $1GdQd.BIT8 ? decoder.readLeftID() : null, null, (info & $1GdQd.BIT7) === $1GdQd.BIT7 ? decoder.readRightID() : null, // @ts-ignore Force writing a string here.
cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, cantCopyParentInfo && (info & $1GdQd.BIT6) === $1GdQd.BIT6 ? decoder.readString() : null, $52a83e33f2b9e935$var$readItemContent(decoder, info) // item content
);
yield struct;
clock += struct.length;
} else {
const len = decoder.readLen();
yield new $52a83e33f2b9e935$export$12d259ff017e6b58($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock), len);
clock += len;
}
}
}
}
class $52a83e33f2b9e935$var$LazyStructReader {
/**
* @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
* @param {boolean} filterSkips
*/ constructor(decoder, filterSkips){
this.gen = $52a83e33f2b9e935$var$lazyStructReaderGenerator(decoder);
/**
* @type {null | Item | Skip | GC}
*/ this.curr = null;
this.done = false;
this.filterSkips = filterSkips;
this.next();
}
/**
* @return {Item | GC | Skip |null}
*/ next() {
// ignore "Skip" structs
do this.curr = this.gen.next().value || null;
while (this.filterSkips && this.curr !== null && this.curr.constructor === $52a83e33f2b9e935$var$Skip);
return this.curr;
}
}
/**
* @param {Uint8Array} update
*
*/ const $52a83e33f2b9e935$export$d6235ced6e55ace9 = (update)=>$52a83e33f2b9e935$export$624b3f0248c2dc40(update, $52a83e33f2b9e935$var$UpdateDecoderV1);
/**
* @param {Uint8Array} update
* @param {typeof UpdateDecoderV2 | typeof UpdateDecoderV1} [YDecoder]
*
*/ const $52a83e33f2b9e935$export$624b3f0248c2dc40 = (update, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2)=>{
const structs = [];
const updateDecoder = new YDecoder($f5RS8.createDecoder(update));
const lazyDecoder = new $52a83e33f2b9e935$var$LazyStructReader(updateDecoder, false);
for(let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next())structs.push(curr);
$dcfNU.print("Structs: ", structs);
const ds = $52a83e33f2b9e935$var$readDeleteSet(updateDecoder);
$dcfNU.print("DeleteSet: ", ds);
};
/**
* @param {Uint8Array} update
*
*/ const $52a83e33f2b9e935$export$aa45cba8121663dc = (update)=>$52a83e33f2b9e935$export$2fed33908eb23d71(update, $52a83e33f2b9e935$var$UpdateDecoderV1);
/**
* @param {Uint8Array} update
* @param {typeof UpdateDecoderV2 | typeof UpdateDecoderV1} [YDecoder]
*
*/ const $52a83e33f2b9e935$export$2fed33908eb23d71 = (update, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2)=>{
const structs = [];
const updateDecoder = new YDecoder($f5RS8.createDecoder(update));
const lazyDecoder = new $52a83e33f2b9e935$var$LazyStructReader(updateDecoder, false);
for(let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next())structs.push(curr);
return {
structs: structs,
ds: $52a83e33f2b9e935$var$readDeleteSet(updateDecoder)
};
};
class $52a83e33f2b9e935$var$LazyStructWriter {
/**
* @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
*/ constructor(encoder){
this.currClient = 0;
this.startClock = 0;
this.written = 0;
this.encoder = encoder;
/**
* We want to write operations lazily, but also we need to know beforehand how many operations we want to write for each client.
*
* This kind of meta-information (#clients, #structs-per-client-written) is written to the restEncoder.
*
* We fragment the restEncoder and store a slice of it per-client until we know how many clients there are.
* When we flush (toUint8Array) we write the restEncoder using the fragments and the meta-information.
*
* @type {Array<{ written: number, restEncoder: Uint8Array }>}
*/ this.clientStructs = [];
}
}
/**
* @param {Array} updates
* @return {Uint8Array}
*/ const $52a83e33f2b9e935$export$6319871659fd2460 = (updates)=>$52a83e33f2b9e935$export$ce273d78de0331d1(updates, $52a83e33f2b9e935$var$UpdateDecoderV1, $52a83e33f2b9e935$export$99171b804d9c5b54);
/**
* @param {Uint8Array} update
* @param {typeof DSEncoderV1 | typeof DSEncoderV2} YEncoder
* @param {typeof UpdateDecoderV1 | typeof UpdateDecoderV2} YDecoder
* @return {Uint8Array}
*/ const $52a83e33f2b9e935$export$ed51750cf3ab2381 = (update, YEncoder = $52a83e33f2b9e935$var$DSEncoderV2, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2)=>{
const encoder = new YEncoder();
const updateDecoder = new $52a83e33f2b9e935$var$LazyStructReader(new YDecoder($f5RS8.createDecoder(update)), false);
let curr = updateDecoder.curr;
if (curr !== null) {
let size = 0;
let currClient = curr.id.client;
let stopCounting = curr.id.clock !== 0; // must start at 0
let currClock = stopCounting ? 0 : curr.id.clock + curr.length;
for(; curr !== null; curr = updateDecoder.next()){
if (currClient !== curr.id.client) {
if (currClock !== 0) {
size++;
// We found a new client
// write what we have to the encoder
$1p1sv.writeVarUint(encoder.restEncoder, currClient);
$1p1sv.writeVarUint(encoder.restEncoder, currClock);
}
currClient = curr.id.client;
currClock = 0;
stopCounting = curr.id.clock !== 0;
}
// we ignore skips
if (curr.constructor === $52a83e33f2b9e935$var$Skip) stopCounting = true;
if (!stopCounting) currClock = curr.id.clock + curr.length;
}
// write what we have
if (currClock !== 0) {
size++;
$1p1sv.writeVarUint(encoder.restEncoder, currClient);
$1p1sv.writeVarUint(encoder.restEncoder, currClock);
}
// prepend the size of the state vector
const enc = $1p1sv.createEncoder();
$1p1sv.writeVarUint(enc, size);
$1p1sv.writeBinaryEncoder(enc, encoder.restEncoder);
encoder.restEncoder = enc;
return encoder.toUint8Array();
} else {
$1p1sv.writeVarUint(encoder.restEncoder, 0);
return encoder.toUint8Array();
}
};
/**
* @param {Uint8Array} update
* @return {Uint8Array}
*/ const $52a83e33f2b9e935$export$5c451fd8502b011f = (update)=>$52a83e33f2b9e935$export$ed51750cf3ab2381(update, $52a83e33f2b9e935$var$DSEncoderV1, $52a83e33f2b9e935$var$UpdateDecoderV1);
/**
* @param {Uint8Array} update
* @param {typeof UpdateDecoderV1 | typeof UpdateDecoderV2} YDecoder
* @return {{ from: Map, to: Map }}
*/ const $52a83e33f2b9e935$export$8212a58b2178fdcf = (update, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2)=>{
/**
* @type {Map}
*/ const from = new Map();
/**
* @type {Map}
*/ const to = new Map();
const updateDecoder = new $52a83e33f2b9e935$var$LazyStructReader(new YDecoder($f5RS8.createDecoder(update)), false);
let curr = updateDecoder.curr;
if (curr !== null) {
let currClient = curr.id.client;
let currClock = curr.id.clock;
// write the beginning to `from`
from.set(currClient, currClock);
for(; curr !== null; curr = updateDecoder.next()){
if (currClient !== curr.id.client) {
// We found a new client
// write the end to `to`
to.set(currClient, currClock);
// write the beginning to `from`
from.set(curr.id.client, curr.id.clock);
// update currClient
currClient = curr.id.client;
}
currClock = curr.id.clock + curr.length;
}
// write the end to `to`
to.set(currClient, currClock);
}
return {
from: from,
to: to
};
};
/**
* @param {Uint8Array} update
* @return {{ from: Map, to: Map }}
*/ const $52a83e33f2b9e935$export$e212b06fd4bf78fd = (update)=>$52a83e33f2b9e935$export$8212a58b2178fdcf(update, $52a83e33f2b9e935$var$UpdateDecoderV1);
/**
* This method is intended to slice any kind of struct and retrieve the right part.
* It does not handle side-effects, so it should only be used by the lazy-encoder.
*
* @param {Item | GC | Skip} left
* @param {number} diff
* @return {Item | GC}
*/ const $52a83e33f2b9e935$var$sliceStruct = (left, diff)=>{
if (left.constructor === $52a83e33f2b9e935$export$12d259ff017e6b58) {
const { client: client, clock: clock } = left.id;
return new $52a83e33f2b9e935$export$12d259ff017e6b58($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock + diff), left.length - diff);
} else if (left.constructor === $52a83e33f2b9e935$var$Skip) {
const { client: client, clock: clock } = left.id;
return new $52a83e33f2b9e935$var$Skip($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock + diff), left.length - diff);
} else {
const leftItem = /** @type {Item} */ left;
const { client: client, clock: clock } = leftItem.id;
return new $52a83e33f2b9e935$export$6d08773d2e66f8f2($52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock + diff), null, $52a83e33f2b9e935$export$6c7d4e6171d008d0(client, clock + diff - 1), null, leftItem.rightOrigin, leftItem.parent, leftItem.parentSub, leftItem.content.splice(diff));
}
};
/**
*
* This function works similarly to `readUpdateV2`.
*
* @param {Array} updates
* @param {typeof UpdateDecoderV1 | typeof UpdateDecoderV2} [YDecoder]
* @param {typeof UpdateEncoderV1 | typeof UpdateEncoderV2} [YEncoder]
* @return {Uint8Array}
*/ const $52a83e33f2b9e935$export$ce273d78de0331d1 = (updates, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2, YEncoder = $52a83e33f2b9e935$var$UpdateEncoderV2)=>{
if (updates.length === 1) return updates[0];
const updateDecoders = updates.map((update)=>new YDecoder($f5RS8.createDecoder(update)));
let lazyStructDecoders = updateDecoders.map((decoder)=>new $52a83e33f2b9e935$var$LazyStructReader(decoder, true));
/**
* @todo we don't need offset because we always slice before
* @type {null | { struct: Item | GC | Skip, offset: number }}
*/ let currWrite = null;
const updateEncoder = new YEncoder();
// write structs lazily
const lazyStructEncoder = new $52a83e33f2b9e935$var$LazyStructWriter(updateEncoder);
// Note: We need to ensure that all lazyStructDecoders are fully consumed
// Note: Should merge document updates whenever possible - even from different updates
// Note: Should handle that some operations cannot be applied yet ()
while(true){
// Write higher clients first ⇒ sort by clientID & clock and remove decoders without content
lazyStructDecoders = lazyStructDecoders.filter((dec)=>dec.curr !== null);
lazyStructDecoders.sort(/** @type {function(any,any):number} */ (dec1, dec2)=>{
if (dec1.curr.id.client === dec2.curr.id.client) {
const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock;
if (clockDiff === 0) // @todo remove references to skip since the structDecoders must filter Skips.
return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === $52a83e33f2b9e935$var$Skip ? 1 : -1 // we are filtering skips anyway.
;
else return clockDiff;
} else return dec2.curr.id.client - dec1.curr.id.client;
});
if (lazyStructDecoders.length === 0) break;
const currDecoder = lazyStructDecoders[0];
// write from currDecoder until the next operation is from another client or if filler-struct
// then we need to reorder the decoders and find the next operation to write
const firstClient = /** @type {Item | GC} */ currDecoder.curr.id.client;
if (currWrite !== null) {
let curr = /** @type {Item | GC | null} */ currDecoder.curr;
let iterated = false;
// iterate until we find something that we haven't written already
// remember: first the high client-ids are written
while(curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client){
curr = currDecoder.next();
iterated = true;
}
if (curr === null || // current decoder is empty
curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient`
iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length // the above while loop was used and we are potentially missing updates
) continue;
if (firstClient !== currWrite.struct.id.client) {
$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset);
currWrite = {
struct: curr,
offset: 0
};
currDecoder.next();
} else if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) {
// @todo write currStruct & set currStruct = Skip(clock = currStruct.id.clock + currStruct.length, length = curr.id.clock - self.clock)
if (currWrite.struct.constructor === $52a83e33f2b9e935$var$Skip) // extend existing skip
currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock;
else {
$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset);
const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length;
/**
* @type {Skip}
*/ const struct = new $52a83e33f2b9e935$var$Skip($52a83e33f2b9e935$export$6c7d4e6171d008d0(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff);
currWrite = {
struct: struct,
offset: 0
};
}
} else {
const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock;
if (diff > 0) {
if (currWrite.struct.constructor === $52a83e33f2b9e935$var$Skip) // prefer to slice Skip because the other struct might contain more information
currWrite.struct.length -= diff;
else curr = $52a83e33f2b9e935$var$sliceStruct(curr, diff);
}
if (!currWrite.struct.mergeWith(/** @type {any} */ curr)) {
$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset);
currWrite = {
struct: curr,
offset: 0
};
currDecoder.next();
}
}
} else {
currWrite = {
struct: /** @type {Item | GC} */ currDecoder.curr,
offset: 0
};
currDecoder.next();
}
for(let next = currDecoder.curr; next !== null && next.id.client === firstClient && next.id.clock === currWrite.struct.id.clock + currWrite.struct.length && next.constructor !== $52a83e33f2b9e935$var$Skip; next = currDecoder.next()){
$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset);
currWrite = {
struct: next,
offset: 0
};
}
}
if (currWrite !== null) {
$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset);
currWrite = null;
}
$52a83e33f2b9e935$var$finishLazyStructWriting(lazyStructEncoder);
const dss = updateDecoders.map((decoder)=>$52a83e33f2b9e935$var$readDeleteSet(decoder));
const ds = $52a83e33f2b9e935$var$mergeDeleteSets(dss);
$52a83e33f2b9e935$var$writeDeleteSet(updateEncoder, ds);
return updateEncoder.toUint8Array();
};
/**
* @param {Uint8Array} update
* @param {Uint8Array} sv
* @param {typeof UpdateDecoderV1 | typeof UpdateDecoderV2} [YDecoder]
* @param {typeof UpdateEncoderV1 | typeof UpdateEncoderV2} [YEncoder]
*/ const $52a83e33f2b9e935$export$a8143edf39d2ad8e = (update, sv, YDecoder = $52a83e33f2b9e935$var$UpdateDecoderV2, YEncoder = $52a83e33f2b9e935$var$UpdateEncoderV2)=>{
const state = $52a83e33f2b9e935$export$324ac6fb20a844e3(sv);
const encoder = new YEncoder();
const lazyStructWriter = new $52a83e33f2b9e935$var$LazyStructWriter(encoder);
const decoder = new YDecoder($f5RS8.createDecoder(update));
const reader = new $52a83e33f2b9e935$var$LazyStructReader(decoder, false);
while(reader.curr){
const curr = reader.curr;
const currClient = curr.id.client;
const svClock = state.get(currClient) || 0;
if (reader.curr.constructor === $52a83e33f2b9e935$var$Skip) {
// the first written struct shouldn't be a skip
reader.next();
continue;
}
if (curr.id.clock + curr.length > svClock) {
$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyStructWriter, curr, $kuitL.max(svClock - curr.id.clock, 0));
reader.next();
while(reader.curr && reader.curr.id.client === currClient){
$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0);
reader.next();
}
} else // read until something new comes up
while(reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock)reader.next();
}
$52a83e33f2b9e935$var$finishLazyStructWriting(lazyStructWriter);
// write ds
const ds = $52a83e33f2b9e935$var$readDeleteSet(decoder);
$52a83e33f2b9e935$var$writeDeleteSet(encoder, ds);
return encoder.toUint8Array();
};
/**
* @param {Uint8Array} update
* @param {Uint8Array} sv
*/ const $52a83e33f2b9e935$export$bf60b51d6c283426 = (update, sv)=>$52a83e33f2b9e935$export$a8143edf39d2ad8e(update, sv, $52a83e33f2b9e935$var$UpdateDecoderV1, $52a83e33f2b9e935$export$99171b804d9c5b54);
/**
* @param {LazyStructWriter} lazyWriter
*/ const $52a83e33f2b9e935$var$flushLazyStructWriter = (lazyWriter)=>{
if (lazyWriter.written > 0) {
lazyWriter.clientStructs.push({
written: lazyWriter.written,
restEncoder: $1p1sv.toUint8Array(lazyWriter.encoder.restEncoder)
});
lazyWriter.encoder.restEncoder = $1p1sv.createEncoder();
lazyWriter.written = 0;
}
};
/**
* @param {LazyStructWriter} lazyWriter
* @param {Item | GC} struct
* @param {number} offset
*/ const $52a83e33f2b9e935$var$writeStructToLazyStructWriter = (lazyWriter, struct, offset)=>{
// flush curr if we start another client
if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) $52a83e33f2b9e935$var$flushLazyStructWriter(lazyWriter);
if (lazyWriter.written === 0) {
lazyWriter.currClient = struct.id.client;
// write next client
lazyWriter.encoder.writeClient(struct.id.client);
// write startClock
$1p1sv.writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset);
}
struct.write(lazyWriter.encoder, offset);
lazyWriter.written++;
};
/**
* Call this function when we collected all parts and want to
* put all the parts together. After calling this method,
* you can continue using the UpdateEncoder.
*
* @param {LazyStructWriter} lazyWriter
*/ const $52a83e33f2b9e935$var$finishLazyStructWriting = (lazyWriter)=>{
$52a83e33f2b9e935$var$flushLazyStructWriter(lazyWriter);
// this is a fresh encoder because we called flushCurr
const restEncoder = lazyWriter.encoder.restEncoder;
/**
* Now we put all the fragments together.
* This works similarly to `writeClientsStructs`
*/ // write # states that were updated - i.e. the clients
$1p1sv.writeVarUint(restEncoder, lazyWriter.clientStructs.length);
for(let i = 0; i < lazyWriter.clientStructs.length; i++){
const partStructs = lazyWriter.clientStructs[i];
/**
* Works similarly to `writeStructs`
*/ // write # encoded structs
$1p1sv.writeVarUint(restEncoder, partStructs.written);
// write the rest of the fragment
$1p1sv.writeUint8Array(restEncoder, partStructs.restEncoder);
}
};
/**
* @param {Uint8Array} update
* @param {function(Item|GC|Skip):Item|GC|Skip} blockTransformer
* @param {typeof UpdateDecoderV2 | typeof UpdateDecoderV1} YDecoder
* @param {typeof UpdateEncoderV2 | typeof UpdateEncoderV1 } YEncoder
*/ const $52a83e33f2b9e935$var$convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder)=>{
const updateDecoder = new YDecoder($f5RS8.createDecoder(update));
const lazyDecoder = new $52a83e33f2b9e935$var$LazyStructReader(updateDecoder, false);
const updateEncoder = new YEncoder();
const lazyWriter = new $52a83e33f2b9e935$var$LazyStructWriter(updateEncoder);
for(let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next())$52a83e33f2b9e935$var$writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0);
$52a83e33f2b9e935$var$finishLazyStructWriting(lazyWriter);
const ds = $52a83e33f2b9e935$var$readDeleteSet(updateDecoder);
$52a83e33f2b9e935$var$writeDeleteSet(updateEncoder, ds);
return updateEncoder.toUint8Array();
};
/**
* @typedef {Object} ObfuscatorOptions
* @property {boolean} [ObfuscatorOptions.formatting=true]
* @property {boolean} [ObfuscatorOptions.subdocs=true]
* @property {boolean} [ObfuscatorOptions.yxml=true] Whether to obfuscate nodeName / hookName
*/ /**
* @param {ObfuscatorOptions} obfuscator
*/ const $52a83e33f2b9e935$var$createObfuscator = ({ formatting: formatting = true, subdocs: subdocs = true, yxml: yxml = true } = {})=>{
let i = 0;
const mapKeyCache = $e6DQe.create();
const nodeNameCache = $e6DQe.create();
const formattingKeyCache = $e6DQe.create();
const formattingValueCache = $e6DQe.create();
formattingValueCache.set(null, null); // end of a formatting range should always be the end of a formatting range
/**
* @param {Item|GC|Skip} block
* @return {Item|GC|Skip}
*/ return (block)=>{
switch(block.constructor){
case $52a83e33f2b9e935$export$12d259ff017e6b58:
case $52a83e33f2b9e935$var$Skip:
return block;
case $52a83e33f2b9e935$export$6d08773d2e66f8f2:
{
const item = /** @type {Item} */ block;
const content = item.content;
switch(content.constructor){
case $52a83e33f2b9e935$export$3b06e0b3a2ece602:
break;
case $52a83e33f2b9e935$export$e2e108cbe2e4f865:
if (yxml) {
const type = /** @type {ContentType} */ content.type;
if (type instanceof $52a83e33f2b9e935$export$4db87581d3ca170d) type.nodeName = $e6DQe.setIfUndefined(nodeNameCache, type.nodeName, ()=>"node-" + i);
if (type instanceof $52a83e33f2b9e935$export$ec64c1dd5e7a264) type.hookName = $e6DQe.setIfUndefined(nodeNameCache, type.hookName, ()=>"hook-" + i);
}
break;
case $52a83e33f2b9e935$export$1d788b93bbb631a0:
{
const c = /** @type {ContentAny} */ content;
c.arr = c.arr.map(()=>i);
break;
}
case $52a83e33f2b9e935$export$e8d530cdf62d1cbd:
{
const c = /** @type {ContentBinary} */ content;
c.content = new Uint8Array([
i
]);
break;
}
case $52a83e33f2b9e935$var$ContentDoc:
{
const c = /** @type {ContentDoc} */ content;
if (subdocs) {
c.opts = {};
c.doc.guid = i + "";
}
break;
}
case $52a83e33f2b9e935$export$c3787ba7f6086664:
{
const c = /** @type {ContentEmbed} */ content;
c.embed = {};
break;
}
case $52a83e33f2b9e935$export$3194899188fb5a88:
{
const c = /** @type {ContentFormat} */ content;
if (formatting) {
c.key = $e6DQe.setIfUndefined(formattingKeyCache, c.key, ()=>i + "");
c.value = $e6DQe.setIfUndefined(formattingValueCache, c.value, ()=>({
i: i
}));
}
break;
}
case $52a83e33f2b9e935$export$6a907ea8f733ecf3:
{
const c = /** @type {ContentJSON} */ content;
c.arr = c.arr.map(()=>i);
break;
}
case $52a83e33f2b9e935$export$ee670b2cf091bbb6:
{
const c = /** @type {ContentString} */ content;
c.str = $6rcMi.repeat(i % 10 + "", c.str.length);
break;
}
default:
// unknown content type
$akmFO.unexpectedCase();
}
if (item.parentSub) item.parentSub = $e6DQe.setIfUndefined(mapKeyCache, item.parentSub, ()=>i + "");
i++;
return block;
}
default:
// unknown block-type
$akmFO.unexpectedCase();
}
};
};
/**
* This function obfuscates the content of a Yjs update. This is useful to share
* buggy Yjs documents while significantly limiting the possibility that a
* developer can on the user. Note that it might still be possible to deduce
* some information by analyzing the "structure" of the document or by analyzing
* the typing behavior using the CRDT-related metadata that is still kept fully
* intact.
*
* @param {Uint8Array} update
* @param {ObfuscatorOptions} [opts]
*/ const $52a83e33f2b9e935$export$2dc24d59ec48a24e = (update, opts)=>$52a83e33f2b9e935$var$convertUpdateFormat(update, $52a83e33f2b9e935$var$createObfuscator(opts), $52a83e33f2b9e935$var$UpdateDecoderV1, $52a83e33f2b9e935$export$99171b804d9c5b54);
/**
* @param {Uint8Array} update
* @param {ObfuscatorOptions} [opts]
*/ const $52a83e33f2b9e935$export$90648fb14f8c31aa = (update, opts)=>$52a83e33f2b9e935$var$convertUpdateFormat(update, $52a83e33f2b9e935$var$createObfuscator(opts), $52a83e33f2b9e935$var$UpdateDecoderV2, $52a83e33f2b9e935$var$UpdateEncoderV2);
/**
* @param {Uint8Array} update
*/ const $52a83e33f2b9e935$export$162408325d5832c = (update)=>$52a83e33f2b9e935$var$convertUpdateFormat(update, $kXTKb.id, $52a83e33f2b9e935$var$UpdateDecoderV1, $52a83e33f2b9e935$var$UpdateEncoderV2);
/**
* @param {Uint8Array} update
*/ const $52a83e33f2b9e935$export$afffbdeed14adbd = (update)=>$52a83e33f2b9e935$var$convertUpdateFormat(update, $kXTKb.id, $52a83e33f2b9e935$var$UpdateDecoderV2, $52a83e33f2b9e935$export$99171b804d9c5b54);
const $52a83e33f2b9e935$var$errorComputeChanges = "You must not compute changes after the event-handler fired.";
/**
* @template {AbstractType} T
* YEvent describes the changes on a YType.
*/ class $52a83e33f2b9e935$export$80fac438977fb51c {
/**
* @param {T} target The changed type.
* @param {Transaction} transaction
*/ constructor(target, transaction){
/**
* The type on which this event was created on.
* @type {T}
*/ this.target = target;
/**
* The current target on which the observe callback is called.
* @type {AbstractType}
*/ this.currentTarget = target;
/**
* The transaction that triggered this event.
* @type {Transaction}
*/ this.transaction = transaction;
/**
* @type {Object|null}
*/ this._changes = null;
/**
* @type {null | Map}
*/ this._keys = null;
/**
* @type {null | Array<{ insert?: string | Array | object | AbstractType, retain?: number, delete?: number, attributes?: Object }>}
*/ this._delta = null;
/**
* @type {Array|null}
*/ this._path = null;
}
/**
* Computes the path from `y` to the changed type.
*
* @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with.
*
* The following property holds:
* @example
* let type = y
* event.path.forEach(dir => {
* type = type.get(dir)
* })
* type === event.target // => true
*/ get path() {
return this._path || (this._path = $52a83e33f2b9e935$var$getPathTo(this.currentTarget, this.target));
}
/**
* Check if a struct is deleted by this event.
*
* In contrast to change.deleted, this method also returns true if the struct was added and then deleted.
*
* @param {AbstractStruct} struct
* @return {boolean}
*/ deletes(struct) {
return $52a83e33f2b9e935$export$dcb04af092e44fde(this.transaction.deleteSet, struct.id);
}
/**
* @type {Map}
*/ get keys() {
if (this._keys === null) {
if (this.transaction.doc._transactionCleanups.length === 0) throw $akmFO.create($52a83e33f2b9e935$var$errorComputeChanges);
const keys = new Map();
const target = this.target;
const changed = /** @type Set */ this.transaction.changed.get(target);
changed.forEach((key)=>{
if (key !== null) {
const item = /** @type {Item} */ target._map.get(key);
/**
* @type {'delete' | 'add' | 'update'}
*/ let action;
let oldValue;
if (this.adds(item)) {
let prev = item.left;
while(prev !== null && this.adds(prev))prev = prev.left;
if (this.deletes(item)) {
if (prev !== null && this.deletes(prev)) {
action = "delete";
oldValue = $7sfdv.last(prev.content.getContent());
} else return;
} else if (prev !== null && this.deletes(prev)) {
action = "update";
oldValue = $7sfdv.last(prev.content.getContent());
} else {
action = "add";
oldValue = undefined;
}
} else {
if (this.deletes(item)) {
action = "delete";
oldValue = $7sfdv.last(/** @type {Item} */ item.content.getContent());
} else return; // nop
}
keys.set(key, {
action: action,
oldValue: oldValue
});
}
});
this._keys = keys;
}
return this._keys;
}
/**
* This is a computed property. Note that this can only be safely computed during the
* event call. Computing this property after other changes happened might result in
* unexpected behavior (incorrect computation of deltas). A safe way to collect changes
* is to store the `changes` or the `delta` object. Avoid storing the `transaction` object.
*
* @type {Array<{insert?: string | Array | object | AbstractType, retain?: number, delete?: number, attributes?: Object}>}
*/ get delta() {
return this.changes.delta;
}
/**
* Check if a struct is added by this event.
*
* In contrast to change.deleted, this method also returns true if the struct was added and then deleted.
*
* @param {AbstractStruct} struct
* @return {boolean}
*/ adds(struct) {
return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0);
}
/**
* This is a computed property. Note that this can only be safely computed during the
* event call. Computing this property after other changes happened might result in
* unexpected behavior (incorrect computation of deltas). A safe way to collect changes
* is to store the `changes` or the `delta` object. Avoid storing the `transaction` object.
*
* @type {{added:Set
- ,deleted:Set
- ,keys:Map,delta:Array<{insert?:Array|string, delete?:number, retain?:number}>}}
*/ get changes() {
let changes = this._changes;
if (changes === null) {
if (this.transaction.doc._transactionCleanups.length === 0) throw $akmFO.create($52a83e33f2b9e935$var$errorComputeChanges);
const target = this.target;
const added = $gB6ZU.create();
const deleted = $gB6ZU.create();
/**
* @type {Array<{insert:Array}|{delete:number}|{retain:number}>}
*/ const delta = [];
changes = {
added: added,
deleted: deleted,
delta: delta,
keys: this.keys
};
const changed = /** @type Set */ this.transaction.changed.get(target);
if (changed.has(null)) {
/**
* @type {any}
*/ let lastOp = null;
const packOp = ()=>{
if (lastOp) delta.push(lastOp);
};
for(let item = target._start; item !== null; item = item.right){
if (item.deleted) {
if (this.deletes(item) && !this.adds(item)) {
if (lastOp === null || lastOp.delete === undefined) {
packOp();
lastOp = {
delete: 0
};
}
lastOp.delete += item.length;
deleted.add(item);
} // else nop
} else if (this.adds(item)) {
if (lastOp === null || lastOp.insert === undefined) {
packOp();
lastOp = {
insert: []
};
}
lastOp.insert = lastOp.insert.concat(item.content.getContent());
added.add(item);
} else {
if (lastOp === null || lastOp.retain === undefined) {
packOp();
lastOp = {
retain: 0
};
}
lastOp.retain += item.length;
}
}
if (lastOp !== null && lastOp.retain === undefined) packOp();
}
this._changes = changes;
}
return /** @type {any} */ changes;
}
}
/**
* Compute the path from this type to the specified target.
*
* @example
* // `child` should be accessible via `type.get(path[0]).get(path[1])..`
* const path = type.getPathTo(child)
* // assuming `type instanceof YArray`
* console.log(path) // might look like => [2, 'key1']
* child === type.get(path[0]).get(path[1])
*
* @param {AbstractType} parent
* @param {AbstractType} child target
* @return {Array} Path to the target
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$getPathTo = (parent, child)=>{
const path = [];
while(child._item !== null && child !== parent){
if (child._item.parentSub !== null) // parent is map-ish
path.unshift(child._item.parentSub);
else {
// parent is array-ish
let i = 0;
let c = /** @type {AbstractType} */ child._item.parent._start;
while(c !== child._item && c !== null){
if (!c.deleted) i++;
c = c.right;
}
path.unshift(i);
}
child = /** @type {AbstractType} */ child._item.parent;
}
return path;
};
const $52a83e33f2b9e935$var$maxSearchMarker = 80;
/**
* A unique timestamp that identifies each marker.
*
* Time is relative,.. this is more like an ever-increasing clock.
*
* @type {number}
*/ let $52a83e33f2b9e935$var$globalSearchMarkerTimestamp = 0;
class $52a83e33f2b9e935$var$ArraySearchMarker {
/**
* @param {Item} p
* @param {number} index
*/ constructor(p, index){
p.marker = true;
this.p = p;
this.index = index;
this.timestamp = $52a83e33f2b9e935$var$globalSearchMarkerTimestamp++;
}
}
/**
* @param {ArraySearchMarker} marker
*/ const $52a83e33f2b9e935$var$refreshMarkerTimestamp = (marker)=>{
marker.timestamp = $52a83e33f2b9e935$var$globalSearchMarkerTimestamp++;
};
/**
* This is rather complex so this function is the only thing that should overwrite a marker
*
* @param {ArraySearchMarker} marker
* @param {Item} p
* @param {number} index
*/ const $52a83e33f2b9e935$var$overwriteMarker = (marker, p, index)=>{
marker.p.marker = false;
marker.p = p;
p.marker = true;
marker.index = index;
marker.timestamp = $52a83e33f2b9e935$var$globalSearchMarkerTimestamp++;
};
/**
* @param {Array} searchMarker
* @param {Item} p
* @param {number} index
*/ const $52a83e33f2b9e935$var$markPosition = (searchMarker, p, index)=>{
if (searchMarker.length >= $52a83e33f2b9e935$var$maxSearchMarker) {
// override oldest marker (we don't want to create more objects)
const marker = searchMarker.reduce((a, b)=>a.timestamp < b.timestamp ? a : b);
$52a83e33f2b9e935$var$overwriteMarker(marker, p, index);
return marker;
} else {
// create new marker
const pm = new $52a83e33f2b9e935$var$ArraySearchMarker(p, index);
searchMarker.push(pm);
return pm;
}
};
/**
* Search marker help us to find positions in the associative array faster.
*
* They speed up the process of finding a position without much bookkeeping.
*
* A maximum of `maxSearchMarker` objects are created.
*
* This function always returns a refreshed marker (updated timestamp)
*
* @param {AbstractType} yarray
* @param {number} index
*/ const $52a83e33f2b9e935$var$findMarker = (yarray, index)=>{
if (yarray._start === null || index === 0 || yarray._searchMarker === null) return null;
const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b)=>$kuitL.abs(index - a.index) < $kuitL.abs(index - b.index) ? a : b);
let p = yarray._start;
let pindex = 0;
if (marker !== null) {
p = marker.p;
pindex = marker.index;
$52a83e33f2b9e935$var$refreshMarkerTimestamp(marker); // we used it, we might need to use it again
}
// iterate to right if possible
while(p.right !== null && pindex < index){
if (!p.deleted && p.countable) {
if (index < pindex + p.length) break;
pindex += p.length;
}
p = p.right;
}
// iterate to left if necessary (might be that pindex > index)
while(p.left !== null && pindex > index){
p = p.left;
if (!p.deleted && p.countable) pindex -= p.length;
}
// we want to make sure that p can't be merged with left, because that would screw up everything
// in that cas just return what we have (it is most likely the best marker anyway)
// iterate to left until p can't be merged with left
while(p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock){
p = p.left;
if (!p.deleted && p.countable) pindex -= p.length;
}
// @todo remove!
// assure position
// {
// let start = yarray._start
// let pos = 0
// while (start !== p) {
// if (!start.deleted && start.countable) {
// pos += start.length
// }
// start = /** @type {Item} */ (start.right)
// }
// if (pos !== pindex) {
// debugger
// throw new Error('Gotcha position fail!')
// }
// }
// if (marker) {
// if (window.lengthes == null) {
// window.lengthes = []
// window.getLengthes = () => window.lengthes.sort((a, b) => a - b)
// }
// window.lengthes.push(marker.index - pindex)
// console.log('distance', marker.index - pindex, 'len', p && p.parent.length)
// }
if (marker !== null && $kuitL.abs(marker.index - pindex) < /** @type {YText|YArray} */ p.parent.length / $52a83e33f2b9e935$var$maxSearchMarker) {
// adjust existing marker
$52a83e33f2b9e935$var$overwriteMarker(marker, p, pindex);
return marker;
} else // create new marker
return $52a83e33f2b9e935$var$markPosition(yarray._searchMarker, p, pindex);
};
/**
* Update markers when a change happened.
*
* This should be called before doing a deletion!
*
* @param {Array} searchMarker
* @param {number} index
* @param {number} len If insertion, len is positive. If deletion, len is negative.
*/ const $52a83e33f2b9e935$var$updateMarkerChanges = (searchMarker, index, len)=>{
for(let i = searchMarker.length - 1; i >= 0; i--){
const m = searchMarker[i];
if (len > 0) {
/**
* @type {Item|null}
*/ let p = m.p;
p.marker = false;
// Ideally we just want to do a simple position comparison, but this will only work if
// search markers don't point to deleted items for formats.
// Iterate marker to prev undeleted countable position so we know what to do when updating a position
while(p && (p.deleted || !p.countable)){
p = p.left;
if (p && !p.deleted && p.countable) // adjust position. the loop should break now
m.index -= p.length;
}
if (p === null || p.marker === true) {
// remove search marker if updated position is null or if position is already marked
searchMarker.splice(i, 1);
continue;
}
m.p = p;
p.marker = true;
}
if (index < m.index || len > 0 && index === m.index) m.index = $kuitL.max(index, m.index + len);
}
};
/**
* Accumulate all (list) children of a type and return them as an Array.
*
* @param {AbstractType} t
* @return {Array
- }
*/ const $52a83e33f2b9e935$export$5418d693f13991b3 = (t)=>{
let s = t._start;
const arr = [];
while(s){
arr.push(s);
s = s.right;
}
return arr;
};
/**
* Call event listeners with an event. This will also add an event to all
* parents (for `.observeDeep` handlers).
*
* @template EventType
* @param {AbstractType} type
* @param {Transaction} transaction
* @param {EventType} event
*/ const $52a83e33f2b9e935$var$callTypeObservers = (type, transaction, event)=>{
const changedType = type;
const changedParentTypes = transaction.changedParentTypes;
while(true){
// @ts-ignore
$e6DQe.setIfUndefined(changedParentTypes, type, ()=>[]).push(event);
if (type._item === null) break;
type = /** @type {AbstractType} */ type._item.parent;
}
$52a83e33f2b9e935$var$callEventHandlerListeners(changedType._eH, event, transaction);
};
/**
* @template EventType
* Abstract Yjs Type class
*/ class $52a83e33f2b9e935$export$c265dc8338484497 {
constructor(){
/**
* @type {Item|null}
*/ this._item = null;
/**
* @type {Map}
*/ this._map = new Map();
/**
* @type {Item|null}
*/ this._start = null;
/**
* @type {Doc|null}
*/ this.doc = null;
this._length = 0;
/**
* Event handlers
* @type {EventHandler}
*/ this._eH = $52a83e33f2b9e935$var$createEventHandler();
/**
* Deep event handlers
* @type {EventHandler>,Transaction>}
*/ this._dEH = $52a83e33f2b9e935$var$createEventHandler();
/**
* @type {null | Array}
*/ this._searchMarker = null;
}
/**
* @return {AbstractType|null}
*/ get parent() {
return this._item ? /** @type {AbstractType} */ this._item.parent : null;
}
/**
* Integrate this type into the Yjs instance.
*
* * Save this struct in the os
* * This type is sent to other client
* * Observer functions are fired
*
* @param {Doc} y The Yjs instance
* @param {Item|null} item
*/ _integrate(y, item) {
this.doc = y;
this._item = item;
}
/**
* @return {AbstractType}
*/ _copy() {
throw $akmFO.methodUnimplemented();
}
/**
* @return {AbstractType}
*/ clone() {
throw $akmFO.methodUnimplemented();
}
/**
* @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder
*/ _write(_encoder) {}
/**
* The first non-deleted item
*/ get _first() {
let n = this._start;
while(n !== null && n.deleted)n = n.right;
return n;
}
/**
* Creates YEvent and calls all type observers.
* Must be implemented by each type.
*
* @param {Transaction} transaction
* @param {Set} _parentSubs Keys changed on this type. `null` if list was modified.
*/ _callObserver(transaction, _parentSubs) {
if (!transaction.local && this._searchMarker) this._searchMarker.length = 0;
}
/**
* Observe all events that are created on this type.
*
* @param {function(EventType, Transaction):void} f Observer function
*/ observe(f) {
$52a83e33f2b9e935$var$addEventHandlerListener(this._eH, f);
}
/**
* Observe all events that are created by this type and its children.
*
* @param {function(Array>,Transaction):void} f Observer function
*/ observeDeep(f) {
$52a83e33f2b9e935$var$addEventHandlerListener(this._dEH, f);
}
/**
* Unregister an observer function.
*
* @param {function(EventType,Transaction):void} f Observer function
*/ unobserve(f) {
$52a83e33f2b9e935$var$removeEventHandlerListener(this._eH, f);
}
/**
* Unregister an observer function.
*
* @param {function(Array>,Transaction):void} f Observer function
*/ unobserveDeep(f) {
$52a83e33f2b9e935$var$removeEventHandlerListener(this._dEH, f);
}
/**
* @abstract
* @return {any}
*/ toJSON() {}
}
/**
* @param {AbstractType} type
* @param {number} start
* @param {number} end
* @return {Array}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$typeListSlice = (type, start, end)=>{
if (start < 0) start = type._length + start;
if (end < 0) end = type._length + end;
let len = end - start;
const cs = [];
let n = type._start;
while(n !== null && len > 0){
if (n.countable && !n.deleted) {
const c = n.content.getContent();
if (c.length <= start) start -= c.length;
else {
for(let i = start; i < c.length && len > 0; i++){
cs.push(c[i]);
len--;
}
start = 0;
}
}
n = n.right;
}
return cs;
};
/**
* @param {AbstractType} type
* @return {Array}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$typeListToArray = (type)=>{
const cs = [];
let n = type._start;
while(n !== null){
if (n.countable && !n.deleted) {
const c = n.content.getContent();
for(let i = 0; i < c.length; i++)cs.push(c[i]);
}
n = n.right;
}
return cs;
};
/**
* @param {AbstractType} type
* @param {Snapshot} snapshot
* @return {Array}
*
* @private
* @function
*/ const $52a83e33f2b9e935$export$9de42b6dda4c7e48 = (type, snapshot)=>{
const cs = [];
let n = type._start;
while(n !== null){
if (n.countable && $52a83e33f2b9e935$var$isVisible(n, snapshot)) {
const c = n.content.getContent();
for(let i = 0; i < c.length; i++)cs.push(c[i]);
}
n = n.right;
}
return cs;
};
/**
* Executes a provided function on once on overy element of this YArray.
*
* @param {AbstractType} type
* @param {function(any,number,any):void} f A function to execute on every element of this YArray.
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$typeListForEach = (type, f)=>{
let index = 0;
let n = type._start;
while(n !== null){
if (n.countable && !n.deleted) {
const c = n.content.getContent();
for(let i = 0; i < c.length; i++)f(c[i], index++, type);
}
n = n.right;
}
};
/**
* @template C,R
* @param {AbstractType} type
* @param {function(C,number,AbstractType):R} f
* @return {Array}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$typeListMap = (type, f)=>{
/**
* @type {Array}
*/ const result = [];
$52a83e33f2b9e935$var$typeListForEach(type, (c, i)=>{
result.push(f(c, i, type));
});
return result;
};
/**
* @param {AbstractType} type
* @return {IterableIterator}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$typeListCreateIterator = (type)=>{
let n = type._start;
/**
* @type {Array|null}
*/ let currentContent = null;
let currentContentIndex = 0;
return {
[Symbol.iterator] () {
return this;
},
next: ()=>{
// find some content
if (currentContent === null) {
while(n !== null && n.deleted)n = n.right;
// check if we reached the end, no need to check currentContent, because it does not exist
if (n === null) return {
done: true,
value: undefined
};
// we found n, so we can set currentContent
currentContent = n.content.getContent();
currentContentIndex = 0;
n = n.right; // we used the content of n, now iterate to next
}
const value = currentContent[currentContentIndex++];
// check if we need to empty currentContent
if (currentContent.length <= currentContentIndex) currentContent = null;
return {
done: false,
value: value
};
}
};
};
/**
* @param {AbstractType} type
* @param {number} index
* @return {any}
*
* @private
* @function
*/ const $52a83e33f2b9e935$var$typeListGet = (type, index)=>{
const marker = $52a83e33f2b9e935$var$findMarker(type, index);
let n = type._start;
if (marker !== null) {
n = marker.p;
index -= marker.index;
}
for(; n !== null; n = n.right)if (!n.deleted && n.countable) {
if (index < n.length) return n.content.getContent()[index];
index -= n.length;
}
};
/**
* @param {Transaction} transaction
* @param {AbstractType} parent
* @param {Item?} referenceItem
* @param {Array