@portabletext/editor
Version:
Portable Text Editor made in React
1,013 lines • 296 kB
JavaScript
"use strict";
var jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), React = require("react"), slateReact = require("slate-react"), reactCompilerRuntime = require("react-compiler-runtime"), debug$g = require("debug"), isEqual = require("lodash/isEqual.js"), slate = require("slate"), xstate = require("xstate"), patches = require("@portabletext/patches"), types = require("@sanity/types"), flatten = require("lodash/flatten.js"), isPlainObject = require("lodash/isPlainObject.js"), uniq = require("lodash/uniq.js"), getRandomValues = require("get-random-values-esm"), parseBlocks = require("./parse-blocks.cjs"), util_sliceBlocks = require("./util.slice-blocks.cjs"), blockTools = require("@portabletext/block-tools"), toHtml = require("@portabletext/to-html"), schema = require("@sanity/schema"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), omit = require("lodash/omit.js"), util_selectionPointToBlockOffset = require("./util.selection-point-to-block-offset.cjs"), selector_isSelectingEntireBlocks = require("./selector.is-selecting-entire-blocks.cjs"), slateDom = require("slate-dom"), startCase = require("lodash.startcase"), behavior_core = require("./behavior.core.cjs"), selector_isOverlappingSelection = require("./selector.is-overlapping-selection.cjs"), rxjs = require("rxjs"), useEffectEvent = require("use-effect-event");
function _interopDefaultCompat(e) {
return e && typeof e == "object" && "default" in e ? e : { default: e };
}
var React__default = /* @__PURE__ */ _interopDefaultCompat(React), debug__default = /* @__PURE__ */ _interopDefaultCompat(debug$g), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual), flatten__default = /* @__PURE__ */ _interopDefaultCompat(flatten), isPlainObject__default = /* @__PURE__ */ _interopDefaultCompat(isPlainObject), uniq__default = /* @__PURE__ */ _interopDefaultCompat(uniq), getRandomValues__default = /* @__PURE__ */ _interopDefaultCompat(getRandomValues), get__default = /* @__PURE__ */ _interopDefaultCompat(get), isUndefined__default = /* @__PURE__ */ _interopDefaultCompat(isUndefined), omitBy__default = /* @__PURE__ */ _interopDefaultCompat(omitBy), omit__default = /* @__PURE__ */ _interopDefaultCompat(omit), startCase__default = /* @__PURE__ */ _interopDefaultCompat(startCase);
const rootName = "sanity-pte:";
debug__default.default(rootName);
function debugWithName(name) {
const namespace = `${rootName}${name}`;
return debug__default.default && debug__default.default.enabled(namespace) ? debug__default.default(namespace) : debug__default.default(rootName);
}
const VOID_CHILD_KEY = "void-child";
function keepObjectEquality(object, keyMap) {
const value = keyMap[object._key];
return value && isEqual__default.default(object, value) ? value : (keyMap[object._key] = object, object);
}
function toSlateValue(value, {
schemaTypes
}, keyMap = {}) {
return value && Array.isArray(value) ? value.map((block) => {
const {
_type,
_key,
...rest
} = block;
if (block && block._type === schemaTypes.block.name) {
const textBlock = block;
let hasInlines = !1;
const hasMissingStyle = typeof textBlock.style > "u", hasMissingMarkDefs = typeof textBlock.markDefs > "u", hasMissingChildren = typeof textBlock.children > "u", children = (textBlock.children || []).map((child) => {
const {
_type: cType,
_key: cKey,
...cRest
} = child;
return cType !== "span" ? (hasInlines = !0, keepObjectEquality({
_type: cType,
_key: cKey,
children: [{
_key: VOID_CHILD_KEY,
_type: "span",
text: "",
marks: []
}],
value: cRest,
__inline: !0
}, keyMap)) : child;
});
return !hasMissingStyle && !hasMissingMarkDefs && !hasMissingChildren && !hasInlines && slate.Element.isElement(block) ? block : (hasMissingStyle && (rest.style = schemaTypes.styles[0].name), keepObjectEquality({
_type,
_key,
...rest,
children
}, keyMap));
}
return keepObjectEquality({
_type,
_key,
children: [{
_key: VOID_CHILD_KEY,
_type: "span",
text: "",
marks: []
}],
value: rest
}, keyMap);
}) : [];
}
function fromSlateValue(value, textBlockType, keyMap = {}) {
return value.map((block) => {
const {
_key,
_type
} = block;
if (!_key || !_type)
throw new Error("Not a valid block");
if (_type === textBlockType && "children" in block && Array.isArray(block.children) && _key) {
let hasInlines = !1;
const children = block.children.map((child) => {
const {
_type: _cType
} = child;
if ("value" in child && _cType !== "span") {
hasInlines = !0;
const {
value: v,
_key: k,
_type: t,
__inline: _i,
children: _c,
...rest
} = child;
return keepObjectEquality({
...rest,
...v,
_key: k,
_type: t
}, keyMap);
}
return child;
});
return hasInlines ? keepObjectEquality({
...block,
children,
_key,
_type
}, keyMap) : block;
}
const blockValue = "value" in block && block.value;
return keepObjectEquality({
_key,
_type,
...typeof blockValue == "object" ? blockValue : {}
}, keyMap);
});
}
function isEqualToEmptyEditor(children, schemaTypes) {
return children === void 0 || children && Array.isArray(children) && children.length === 0 || children && Array.isArray(children) && children.length === 1 && slate.Element.isElement(children[0]) && children[0]._type === schemaTypes.block.name && "style" in children[0] && children[0].style === schemaTypes.styles[0].name && !("listItem" in children[0]) && Array.isArray(children[0].children) && children[0].children.length === 1 && slate.Text.isText(children[0].children[0]) && children[0].children[0]._type === "span" && !children[0].children[0].marks?.join("") && children[0].children[0].text === "";
}
const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE_ELEMENT = /* @__PURE__ */ new WeakMap(), KEY_TO_VALUE_ELEMENT = /* @__PURE__ */ new WeakMap(), SLATE_TO_PORTABLE_TEXT_RANGE = /* @__PURE__ */ new WeakMap(), mutationMachine = xstate.setup({
types: {
context: {},
events: {},
input: {},
emitted: {}
},
actions: {
"emit has pending patches": xstate.emit({
type: "has pending patches"
}),
"emit mutations": xstate.enqueueActions(({
context,
enqueue
}) => {
for (const bulk of context.pendingMutations)
enqueue.emit({
type: "mutation",
patches: bulk.patches,
snapshot: bulk.value
});
}),
"clear pending mutations": xstate.assign({
pendingMutations: []
}),
"defer patch": xstate.assign({
pendingMutations: ({
context,
event
}) => {
if (xstate.assertEvent(event, "patch"), context.pendingMutations.length === 0)
return [{
actionId: event.actionId,
value: event.value,
patches: [event.patch]
}];
const lastBulk = context.pendingMutations.at(-1);
return lastBulk && lastBulk.actionId === event.actionId ? context.pendingMutations.slice(0, -1).concat({
value: event.value,
actionId: lastBulk.actionId,
patches: [...lastBulk.patches, event.patch]
}) : context.pendingMutations.concat({
value: event.value,
actionId: event.actionId,
patches: [event.patch]
});
}
})
},
actors: {
"type listener": xstate.fromCallback(({
input,
sendBack
}) => {
const originalApply = input.slateEditor.apply;
return input.slateEditor.apply = (op) => {
op.type === "insert_text" || op.type === "remove_text" ? sendBack({
type: "typing"
}) : sendBack({
type: "not typing"
}), originalApply(op);
}, () => {
input.slateEditor.apply = originalApply;
};
})
},
guards: {
"is typing": xstate.stateIn({
typing: "typing"
}),
"no pending mutations": ({
context
}) => context.pendingMutations.length === 0,
"slate is normalizing": ({
context
}) => slate.Editor.isNormalizing(context.slateEditor)
},
delays: {
"mutation debounce": process.env.NODE_ENV === "test" ? 250 : 0,
"type debounce": process.env.NODE_ENV === "test" ? 0 : 250
}
}).createMachine({
id: "mutation",
context: ({
input
}) => ({
pendingMutations: [],
schema: input.schema,
slateEditor: input.slateEditor
}),
type: "parallel",
states: {
typing: {
initial: "idle",
invoke: {
src: "type listener",
input: ({
context
}) => ({
slateEditor: context.slateEditor
})
},
states: {
idle: {
on: {
typing: {
target: "typing"
}
}
},
typing: {
after: {
"type debounce": {
target: "idle"
}
},
on: {
"not typing": {
target: "idle"
},
typing: {
target: "typing",
reenter: !0
}
}
}
}
},
mutations: {
initial: "idle",
states: {
idle: {
on: {
patch: {
actions: ["defer patch", "emit has pending patches"],
target: "emitting mutations"
}
}
},
"emitting mutations": {
after: {
"mutation debounce": [{
guard: xstate.and([xstate.not("is typing"), "slate is normalizing"]),
target: "idle",
actions: ["emit mutations", "clear pending mutations"]
}, {
target: "emitting mutations",
reenter: !0
}]
},
on: {
patch: {
target: "emitting mutations",
actions: ["defer patch"],
reenter: !0
}
}
}
}
}
}
});
function validateValue(value, types$1, keyGenerator) {
let resolution = null, valid = !0;
const validChildTypes = [types$1.span.name, ...types$1.inlineObjects.map((t) => t.name)], validBlockTypes = [types$1.block.name, ...types$1.blockObjects.map((t) => t.name)];
return value === void 0 ? {
valid: !0,
resolution: null,
value
} : !Array.isArray(value) || value.length === 0 ? {
valid: !1,
resolution: {
patches: [patches.unset([])],
description: "Editor value must be an array of Portable Text blocks, or undefined.",
action: "Unset the value",
item: value,
i18n: {
description: "inputs.portable-text.invalid-value.not-an-array.description",
action: "inputs.portable-text.invalid-value.not-an-array.action"
}
},
value
} : (value.some((blk, index) => {
if (!isPlainObject__default.default(blk))
return resolution = {
patches: [patches.unset([index])],
description: `Block must be an object, got ${String(blk)}`,
action: "Unset invalid item",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.not-an-object.description",
action: "inputs.portable-text.invalid-value.not-an-object.action",
values: {
index
}
}
}, !0;
if (!blk._key || typeof blk._key != "string")
return resolution = {
patches: [patches.set({
...blk,
_key: keyGenerator()
}, [index])],
description: `Block at index ${index} is missing required _key.`,
action: "Set the block with a random _key value",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.missing-key.description",
action: "inputs.portable-text.invalid-value.missing-key.action",
values: {
index
}
}
}, !0;
if (!blk._type || !validBlockTypes.includes(blk._type)) {
if (blk._type === "block") {
const currentBlockTypeName = types$1.block.name;
return resolution = {
patches: [patches.set({
...blk,
_type: currentBlockTypeName
}, [{
_key: blk._key
}])],
description: `Block with _key '${blk._key}' has invalid type name '${blk._type}'. According to the schema, the block type name is '${currentBlockTypeName}'`,
action: `Use type '${currentBlockTypeName}'`,
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.incorrect-block-type.description",
action: "inputs.portable-text.invalid-value.incorrect-block-type.action",
values: {
key: blk._key,
expectedTypeName: currentBlockTypeName
}
}
}, !0;
}
return !blk._type && types.isPortableTextTextBlock({
...blk,
_type: types$1.block.name
}) ? (resolution = {
patches: [patches.set({
...blk,
_type: types$1.block.name
}, [{
_key: blk._key
}])],
description: `Block with _key '${blk._key}' is missing a type name. According to the schema, the block type name is '${types$1.block.name}'`,
action: `Use type '${types$1.block.name}'`,
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.missing-block-type.description",
action: "inputs.portable-text.invalid-value.missing-block-type.action",
values: {
key: blk._key,
expectedTypeName: types$1.block.name
}
}
}, !0) : blk._type ? (resolution = {
patches: [patches.unset([{
_key: blk._key
}])],
description: `Block with _key '${blk._key}' has invalid _type '${blk._type}'`,
action: "Remove the block",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.disallowed-type.description",
action: "inputs.portable-text.invalid-value.disallowed-type.action",
values: {
key: blk._key,
typeName: blk._type
}
}
}, !0) : (resolution = {
patches: [patches.unset([{
_key: blk._key
}])],
description: `Block with _key '${blk._key}' is missing an _type property`,
action: "Remove the block",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.missing-type.description",
action: "inputs.portable-text.invalid-value.missing-type.action",
values: {
key: blk._key
}
}
}, !0);
}
if (blk._type === types$1.block.name) {
const textBlock = blk;
if (textBlock.children && !Array.isArray(textBlock.children))
return resolution = {
patches: [patches.set({
children: []
}, [{
_key: textBlock._key
}])],
description: `Text block with _key '${textBlock._key}' has a invalid required property 'children'.`,
action: "Reset the children property",
item: textBlock,
i18n: {
description: "inputs.portable-text.invalid-value.missing-or-invalid-children.description",
action: "inputs.portable-text.invalid-value.missing-or-invalid-children.action",
values: {
key: textBlock._key
}
}
}, !0;
if (textBlock.children === void 0 || Array.isArray(textBlock.children) && textBlock.children.length === 0) {
const newSpan = {
_type: types$1.span.name,
_key: keyGenerator(),
text: "",
marks: []
};
return resolution = {
autoResolve: !0,
patches: [patches.setIfMissing([], [{
_key: blk._key
}, "children"]), patches.insert([newSpan], "after", [{
_key: blk._key
}, "children", 0])],
description: `Children for text block with _key '${blk._key}' is empty.`,
action: "Insert an empty text",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.empty-children.description",
action: "inputs.portable-text.invalid-value.empty-children.action",
values: {
key: blk._key
}
}
}, !0;
}
const allUsedMarks = uniq__default.default(flatten__default.default(textBlock.children.filter((cld) => cld._type === types$1.span.name).map((cld) => cld.marks || [])));
if (Array.isArray(blk.markDefs) && blk.markDefs.length > 0) {
const unusedMarkDefs = uniq__default.default(blk.markDefs.map((def) => def._key).filter((key) => !allUsedMarks.includes(key)));
if (unusedMarkDefs.length > 0)
return resolution = {
autoResolve: !0,
patches: unusedMarkDefs.map((markDefKey) => patches.unset([{
_key: blk._key
}, "markDefs", {
_key: markDefKey
}])),
description: `Block contains orphaned data (unused mark definitions): ${unusedMarkDefs.join(", ")}.`,
action: "Remove unused mark definition item",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.orphaned-mark-defs.description",
action: "inputs.portable-text.invalid-value.orphaned-mark-defs.action",
values: {
key: blk._key,
unusedMarkDefs: unusedMarkDefs.map((m) => m.toString())
}
}
}, !0;
}
const orphanedMarks = allUsedMarks.filter((mark) => !types$1.decorators.map((dec) => dec.name).includes(mark)).filter((mark) => textBlock.markDefs === void 0 || !textBlock.markDefs.find((def) => def._key === mark));
if (orphanedMarks.length > 0) {
const spanChildren = textBlock.children.filter((cld) => cld._type === types$1.span.name && Array.isArray(cld.marks) && cld.marks.some((mark) => orphanedMarks.includes(mark)));
if (spanChildren) {
const orphaned = orphanedMarks.join(", ");
return resolution = {
autoResolve: !0,
patches: spanChildren.map((child) => patches.set((child.marks || []).filter((cMrk) => !orphanedMarks.includes(cMrk)), [{
_key: blk._key
}, "children", {
_key: child._key
}, "marks"])),
description: `Block with _key '${blk._key}' contains marks (${orphaned}) not supported by the current content model.`,
action: "Remove invalid marks",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.orphaned-marks.description",
action: "inputs.portable-text.invalid-value.orphaned-marks.action",
values: {
key: blk._key,
orphanedMarks: orphanedMarks.map((m) => m.toString())
}
}
}, !0;
}
}
textBlock.children.some((child, cIndex) => {
if (!isPlainObject__default.default(child))
return resolution = {
patches: [patches.unset([{
_key: blk._key
}, "children", cIndex])],
description: `Child at index '${cIndex}' in block with key '${blk._key}' is not an object.`,
action: "Remove the item",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.non-object-child.description",
action: "inputs.portable-text.invalid-value.non-object-child.action",
values: {
key: blk._key,
index: cIndex
}
}
}, !0;
if (!child._key || typeof child._key != "string") {
const newChild = {
...child,
_key: keyGenerator()
};
return resolution = {
autoResolve: !0,
patches: [patches.set(newChild, [{
_key: blk._key
}, "children", cIndex])],
description: `Child at index ${cIndex} is missing required _key in block with _key ${blk._key}.`,
action: "Set a new random _key on the object",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.missing-child-key.description",
action: "inputs.portable-text.invalid-value.missing-child-key.action",
values: {
key: blk._key,
index: cIndex
}
}
}, !0;
}
return child._type ? validChildTypes.includes(child._type) ? child._type === types$1.span.name && typeof child.text != "string" ? (resolution = {
patches: [patches.set({
...child,
text: ""
}, [{
_key: blk._key
}, "children", {
_key: child._key
}])],
description: `Child with _key '${child._key}' in block with key '${blk._key}' has missing or invalid text property!`,
action: "Write an empty text property to the object",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.invalid-span-text.description",
action: "inputs.portable-text.invalid-value.invalid-span-text.action",
values: {
key: blk._key,
childKey: child._key
}
}
}, !0) : !1 : (resolution = {
patches: [patches.unset([{
_key: blk._key
}, "children", {
_key: child._key
}])],
description: `Child with _key '${child._key}' in block with key '${blk._key}' has invalid '_type' property (${child._type}).`,
action: "Remove the object",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.disallowed-child-type.description",
action: "inputs.portable-text.invalid-value.disallowed-child-type.action",
values: {
key: blk._key,
childKey: child._key,
childType: child._type
}
}
}, !0) : (resolution = {
patches: [patches.unset([{
_key: blk._key
}, "children", {
_key: child._key
}])],
description: `Child with _key '${child._key}' in block with key '${blk._key}' is missing '_type' property.`,
action: "Remove the object",
item: blk,
i18n: {
description: "inputs.portable-text.invalid-value.missing-child-type.description",
action: "inputs.portable-text.invalid-value.missing-child-type.action",
values: {
key: blk._key,
childKey: child._key
}
}
}, !0);
}) && (valid = !1);
}
return !1;
}) && (valid = !1), {
valid,
resolution,
value
});
}
function withRemoteChanges(editor, fn) {
const prev = isChangingRemotely(editor) || !1;
IS_PROCESSING_REMOTE_CHANGES.set(editor, !0), fn(), IS_PROCESSING_REMOTE_CHANGES.set(editor, prev);
}
function isChangingRemotely(editor) {
return IS_PROCESSING_REMOTE_CHANGES.get(editor);
}
const PATCHING = /* @__PURE__ */ new WeakMap();
function withoutPatching(editor, fn) {
const prev = isPatching(editor);
PATCHING.set(editor, !1), fn(), PATCHING.set(editor, prev);
}
function isPatching(editor) {
return PATCHING.get(editor);
}
function cloneDiff(diff2) {
const [type, patch] = diff2;
return [type, patch];
}
function getCommonOverlap(textA, textB) {
let text1 = textA, text2 = textB;
const text1Length = text1.length, text2Length = text2.length;
if (text1Length === 0 || text2Length === 0) return 0;
text1Length > text2Length ? text1 = text1.substring(text1Length - text2Length) : text1Length < text2Length && (text2 = text2.substring(0, text1Length));
const textLength = Math.min(text1Length, text2Length);
if (text1 === text2) return textLength;
let best = 0, length = 1;
for (let found = 0; found !== -1; ) {
const pattern = text1.substring(textLength - length);
if (found = text2.indexOf(pattern), found === -1) return best;
length += found, (found === 0 || text1.substring(textLength - length) === text2.substring(0, length)) && (best = length, length++);
}
return best;
}
function getCommonPrefix(text1, text2) {
if (!text1 || !text2 || text1[0] !== text2[0]) return 0;
let pointerMin = 0, pointerMax = Math.min(text1.length, text2.length), pointerMid = pointerMax, pointerStart = 0;
for (; pointerMin < pointerMid; ) text1.substring(pointerStart, pointerMid) === text2.substring(pointerStart, pointerMid) ? (pointerMin = pointerMid, pointerStart = pointerMin) : pointerMax = pointerMid, pointerMid = Math.floor((pointerMax - pointerMin) / 2 + pointerMin);
return pointerMid;
}
function getCommonSuffix(text1, text2) {
if (!text1 || !text2 || text1[text1.length - 1] !== text2[text2.length - 1]) return 0;
let pointerMin = 0, pointerMax = Math.min(text1.length, text2.length), pointerMid = pointerMax, pointerEnd = 0;
for (; pointerMin < pointerMid; ) text1.substring(text1.length - pointerMid, text1.length - pointerEnd) === text2.substring(text2.length - pointerMid, text2.length - pointerEnd) ? (pointerMin = pointerMid, pointerEnd = pointerMin) : pointerMax = pointerMid, pointerMid = Math.floor((pointerMax - pointerMin) / 2 + pointerMin);
return pointerMid;
}
function isHighSurrogate(char) {
const charCode = char.charCodeAt(0);
return charCode >= 55296 && charCode <= 56319;
}
function isLowSurrogate(char) {
const charCode = char.charCodeAt(0);
return charCode >= 56320 && charCode <= 57343;
}
function bisect(text1, text2, deadline) {
const text1Length = text1.length, text2Length = text2.length, maxD = Math.ceil((text1Length + text2Length) / 2), vOffset = maxD, vLength = 2 * maxD, v1 = new Array(vLength), v2 = new Array(vLength);
for (let x = 0; x < vLength; x++) v1[x] = -1, v2[x] = -1;
v1[vOffset + 1] = 0, v2[vOffset + 1] = 0;
const delta = text1Length - text2Length, front = delta % 2 !== 0;
let k1start = 0, k1end = 0, k2start = 0, k2end = 0;
for (let d = 0; d < maxD && !(Date.now() > deadline); d++) {
for (let k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
const k1Offset = vOffset + k1;
let x1;
k1 === -d || k1 !== d && v1[k1Offset - 1] < v1[k1Offset + 1] ? x1 = v1[k1Offset + 1] : x1 = v1[k1Offset - 1] + 1;
let y1 = x1 - k1;
for (; x1 < text1Length && y1 < text2Length && text1.charAt(x1) === text2.charAt(y1); ) x1++, y1++;
if (v1[k1Offset] = x1, x1 > text1Length) k1end += 2;
else if (y1 > text2Length) k1start += 2;
else if (front) {
const k2Offset = vOffset + delta - k1;
if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] !== -1) {
const x2 = text1Length - v2[k2Offset];
if (x1 >= x2) return bisectSplit(text1, text2, x1, y1, deadline);
}
}
}
for (let k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
const k2Offset = vOffset + k2;
let x2;
k2 === -d || k2 !== d && v2[k2Offset - 1] < v2[k2Offset + 1] ? x2 = v2[k2Offset + 1] : x2 = v2[k2Offset - 1] + 1;
let y2 = x2 - k2;
for (; x2 < text1Length && y2 < text2Length && text1.charAt(text1Length - x2 - 1) === text2.charAt(text2Length - y2 - 1); ) x2++, y2++;
if (v2[k2Offset] = x2, x2 > text1Length) k2end += 2;
else if (y2 > text2Length) k2start += 2;
else if (!front) {
const k1Offset = vOffset + delta - k2;
if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] !== -1) {
const x1 = v1[k1Offset], y1 = vOffset + x1 - k1Offset;
if (x2 = text1Length - x2, x1 >= x2) return bisectSplit(text1, text2, x1, y1, deadline);
}
}
}
}
return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
}
function bisectSplit(text1, text2, x, y, deadline) {
const text1a = text1.substring(0, x), text2a = text2.substring(0, y), text1b = text1.substring(x), text2b = text2.substring(y), diffs = doDiff(text1a, text2a, {
checkLines: !1,
deadline
}), diffsb = doDiff(text1b, text2b, {
checkLines: !1,
deadline
});
return diffs.concat(diffsb);
}
function findHalfMatch(text1, text2, timeout = 1) {
if (timeout <= 0) return null;
const longText = text1.length > text2.length ? text1 : text2, shortText = text1.length > text2.length ? text2 : text1;
if (longText.length < 4 || shortText.length * 2 < longText.length) return null;
const halfMatch1 = halfMatchI(longText, shortText, Math.ceil(longText.length / 4)), halfMatch2 = halfMatchI(longText, shortText, Math.ceil(longText.length / 2));
let halfMatch;
if (halfMatch1 && halfMatch2) halfMatch = halfMatch1[4].length > halfMatch2[4].length ? halfMatch1 : halfMatch2;
else {
if (!halfMatch1 && !halfMatch2) return null;
halfMatch2 ? halfMatch1 || (halfMatch = halfMatch2) : halfMatch = halfMatch1;
}
if (!halfMatch) throw new Error("Unable to find a half match.");
let text1A, text1B, text2A, text2B;
text1.length > text2.length ? (text1A = halfMatch[0], text1B = halfMatch[1], text2A = halfMatch[2], text2B = halfMatch[3]) : (text2A = halfMatch[0], text2B = halfMatch[1], text1A = halfMatch[2], text1B = halfMatch[3]);
const midCommon = halfMatch[4];
return [text1A, text1B, text2A, text2B, midCommon];
}
function halfMatchI(longText, shortText, i) {
const seed = longText.slice(i, i + Math.floor(longText.length / 4));
let j = -1, bestCommon = "", bestLongTextA, bestLongTextB, bestShortTextA, bestShortTextB;
for (; (j = shortText.indexOf(seed, j + 1)) !== -1; ) {
const prefixLength = getCommonPrefix(longText.slice(i), shortText.slice(j)), suffixLength = getCommonSuffix(longText.slice(0, i), shortText.slice(0, j));
bestCommon.length < suffixLength + prefixLength && (bestCommon = shortText.slice(j - suffixLength, j) + shortText.slice(j, j + prefixLength), bestLongTextA = longText.slice(0, i - suffixLength), bestLongTextB = longText.slice(i + prefixLength), bestShortTextA = shortText.slice(0, j - suffixLength), bestShortTextB = shortText.slice(j + prefixLength));
}
return bestCommon.length * 2 >= longText.length ? [bestLongTextA || "", bestLongTextB || "", bestShortTextA || "", bestShortTextB || "", bestCommon || ""] : null;
}
function charsToLines(diffs, lineArray) {
for (let x = 0; x < diffs.length; x++) {
const chars = diffs[x][1], text = [];
for (let y = 0; y < chars.length; y++) text[y] = lineArray[chars.charCodeAt(y)];
diffs[x][1] = text.join("");
}
}
function linesToChars(textA, textB) {
const lineArray = [], lineHash = {};
lineArray[0] = "";
function diffLinesToMunge(text) {
let chars = "", lineStart = 0, lineEnd = -1, lineArrayLength = lineArray.length;
for (; lineEnd < text.length - 1; ) {
lineEnd = text.indexOf(`
`, lineStart), lineEnd === -1 && (lineEnd = text.length - 1);
let line = text.slice(lineStart, lineEnd + 1);
(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : lineHash[line] !== void 0) ? chars += String.fromCharCode(lineHash[line]) : (lineArrayLength === maxLines && (line = text.slice(lineStart), lineEnd = text.length), chars += String.fromCharCode(lineArrayLength), lineHash[line] = lineArrayLength, lineArray[lineArrayLength++] = line), lineStart = lineEnd + 1;
}
return chars;
}
let maxLines = 4e4;
const chars1 = diffLinesToMunge(textA);
maxLines = 65535;
const chars2 = diffLinesToMunge(textB);
return {
chars1,
chars2,
lineArray
};
}
function doLineModeDiff(textA, textB, opts) {
let text1 = textA, text2 = textB;
const a = linesToChars(text1, text2);
text1 = a.chars1, text2 = a.chars2;
const linearray = a.lineArray;
let diffs = doDiff(text1, text2, {
checkLines: !1,
deadline: opts.deadline
});
charsToLines(diffs, linearray), diffs = cleanupSemantic(diffs), diffs.push([DIFF_EQUAL, ""]);
let pointer = 0, countDelete = 0, countInsert = 0, textDelete = "", textInsert = "";
for (; pointer < diffs.length; ) {
switch (diffs[pointer][0]) {
case DIFF_INSERT:
countInsert++, textInsert += diffs[pointer][1];
break;
case DIFF_DELETE:
countDelete++, textDelete += diffs[pointer][1];
break;
case DIFF_EQUAL:
if (countDelete >= 1 && countInsert >= 1) {
diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert), pointer = pointer - countDelete - countInsert;
const aa = doDiff(textDelete, textInsert, {
checkLines: !1,
deadline: opts.deadline
});
for (let j = aa.length - 1; j >= 0; j--) diffs.splice(pointer, 0, aa[j]);
pointer += aa.length;
}
countInsert = 0, countDelete = 0, textDelete = "", textInsert = "";
break;
default:
throw new Error("Unknown diff operation.");
}
pointer++;
}
return diffs.pop(), diffs;
}
function computeDiff(text1, text2, opts) {
let diffs;
if (!text1) return [[DIFF_INSERT, text2]];
if (!text2) return [[DIFF_DELETE, text1]];
const longtext = text1.length > text2.length ? text1 : text2, shorttext = text1.length > text2.length ? text2 : text1, i = longtext.indexOf(shorttext);
if (i !== -1) return diffs = [[DIFF_INSERT, longtext.substring(0, i)], [DIFF_EQUAL, shorttext], [DIFF_INSERT, longtext.substring(i + shorttext.length)]], text1.length > text2.length && (diffs[0][0] = DIFF_DELETE, diffs[2][0] = DIFF_DELETE), diffs;
if (shorttext.length === 1) return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
const halfMatch = findHalfMatch(text1, text2);
if (halfMatch) {
const text1A = halfMatch[0], text1B = halfMatch[1], text2A = halfMatch[2], text2B = halfMatch[3], midCommon = halfMatch[4], diffsA = doDiff(text1A, text2A, opts), diffsB = doDiff(text1B, text2B, opts);
return diffsA.concat([[DIFF_EQUAL, midCommon]], diffsB);
}
return opts.checkLines && text1.length > 100 && text2.length > 100 ? doLineModeDiff(text1, text2, opts) : bisect(text1, text2, opts.deadline);
}
var __defProp$2 = Object.defineProperty, __getOwnPropSymbols$2 = Object.getOwnPropertySymbols, __hasOwnProp$2 = Object.prototype.hasOwnProperty, __propIsEnum$2 = Object.prototype.propertyIsEnumerable, __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {
enumerable: !0,
configurable: !0,
writable: !0,
value
}) : obj[key] = value, __spreadValues$2 = (a, b) => {
for (var prop in b || (b = {})) __hasOwnProp$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
if (__getOwnPropSymbols$2) for (var prop of __getOwnPropSymbols$2(b)) __propIsEnum$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
return a;
};
const DIFF_DELETE = -1, DIFF_INSERT = 1, DIFF_EQUAL = 0;
function diff(textA, textB, opts) {
if (textA === null || textB === null) throw new Error("Null input. (diff)");
const diffs = doDiff(textA, textB, createInternalOpts(opts || {}));
return adjustDiffForSurrogatePairs(diffs), diffs;
}
function doDiff(textA, textB, options) {
let text1 = textA, text2 = textB;
if (text1 === text2) return text1 ? [[DIFF_EQUAL, text1]] : [];
let commonlength = getCommonPrefix(text1, text2);
const commonprefix = text1.substring(0, commonlength);
text1 = text1.substring(commonlength), text2 = text2.substring(commonlength), commonlength = getCommonSuffix(text1, text2);
const commonsuffix = text1.substring(text1.length - commonlength);
text1 = text1.substring(0, text1.length - commonlength), text2 = text2.substring(0, text2.length - commonlength);
let diffs = computeDiff(text1, text2, options);
return commonprefix && diffs.unshift([DIFF_EQUAL, commonprefix]), commonsuffix && diffs.push([DIFF_EQUAL, commonsuffix]), diffs = cleanupMerge(diffs), diffs;
}
function createDeadLine(timeout) {
let t = 1;
return typeof timeout < "u" && (t = timeout <= 0 ? Number.MAX_VALUE : timeout), Date.now() + t * 1e3;
}
function createInternalOpts(opts) {
return __spreadValues$2({
checkLines: !0,
deadline: createDeadLine(opts.timeout || 1)
}, opts);
}
function combineChar(data, char, dir) {
return dir === 1 ? data + char : char + data;
}
function splitChar(data, dir) {
return dir === 1 ? [data.substring(0, data.length - 1), data[data.length - 1]] : [data.substring(1), data[0]];
}
function hasSharedChar(diffs, i, j, dir) {
return dir === 1 ? diffs[i][1][diffs[i][1].length - 1] === diffs[j][1][diffs[j][1].length - 1] : diffs[i][1][0] === diffs[j][1][0];
}
function deisolateChar(diffs, i, dir) {
const inv = dir === 1 ? -1 : 1;
let insertIdx = null, deleteIdx = null, j = i + dir;
for (; j >= 0 && j < diffs.length && (insertIdx === null || deleteIdx === null); j += dir) {
const [op, text2] = diffs[j];
if (text2.length !== 0) {
if (op === DIFF_INSERT) {
insertIdx === null && (insertIdx = j);
continue;
} else if (op === DIFF_DELETE) {
deleteIdx === null && (deleteIdx = j);
continue;
} else if (op === DIFF_EQUAL) {
if (insertIdx === null && deleteIdx === null) {
const [rest, char2] = splitChar(diffs[i][1], dir);
diffs[i][1] = rest, diffs[j][1] = combineChar(diffs[j][1], char2, inv);
return;
}
break;
}
}
}
if (insertIdx !== null && deleteIdx !== null && hasSharedChar(diffs, insertIdx, deleteIdx, dir)) {
const [insertText, insertChar] = splitChar(diffs[insertIdx][1], inv), [deleteText] = splitChar(diffs[deleteIdx][1], inv);
diffs[insertIdx][1] = insertText, diffs[deleteIdx][1] = deleteText, diffs[i][1] = combineChar(diffs[i][1], insertChar, dir);
return;
}
const [text, char] = splitChar(diffs[i][1], dir);
diffs[i][1] = text, insertIdx === null ? (diffs.splice(j, 0, [DIFF_INSERT, char]), deleteIdx !== null && deleteIdx >= j && deleteIdx++) : diffs[insertIdx][1] = combineChar(diffs[insertIdx][1], char, inv), deleteIdx === null ? diffs.splice(j, 0, [DIFF_DELETE, char]) : diffs[deleteIdx][1] = combineChar(diffs[deleteIdx][1], char, inv);
}
function adjustDiffForSurrogatePairs(diffs) {
for (let i = 0; i < diffs.length; i++) {
const [diffType, diffText] = diffs[i];
if (diffText.length === 0) continue;
const firstChar = diffText[0], lastChar = diffText[diffText.length - 1];
isHighSurrogate(lastChar) && diffType === DIFF_EQUAL && deisolateChar(diffs, i, 1), isLowSurrogate(firstChar) && diffType === DIFF_EQUAL && deisolateChar(diffs, i, -1);
}
for (let i = 0; i < diffs.length; i++) diffs[i][1].length === 0 && diffs.splice(i, 1);
}
function cleanupSemantic(rawDiffs) {
let diffs = rawDiffs.map((diff2) => cloneDiff(diff2)), hasChanges = !1;
const equalities = [];
let equalitiesLength = 0, lastEquality = null, pointer = 0, lengthInsertions1 = 0, lengthDeletions1 = 0, lengthInsertions2 = 0, lengthDeletions2 = 0;
for (; pointer < diffs.length; ) diffs[pointer][0] === DIFF_EQUAL ? (equalities[equalitiesLength++] = pointer, lengthInsertions1 = lengthInsertions2, lengthDeletions1 = lengthDeletions2, lengthInsertions2 = 0, lengthDeletions2 = 0, lastEquality = diffs[pointer][1]) : (diffs[pointer][0] === DIFF_INSERT ? lengthInsertions2 += diffs[pointer][1].length : lengthDeletions2 += diffs[pointer][1].length, lastEquality && lastEquality.length <= Math.max(lengthInsertions1, lengthDeletions1) && lastEquality.length <= Math.max(lengthInsertions2, lengthDeletions2) && (diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastEquality]), diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT, equalitiesLength--, equalitiesLength--, pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1, lengthInsertions1 = 0, lengthDeletions1 = 0, lengthInsertions2 = 0, lengthDeletions2 = 0, lastEquality = null, hasChanges = !0)), pointer++;
for (hasChanges && (diffs = cleanupMerge(diffs)), diffs = cleanupSemanticLossless(diffs), pointer = 1; pointer < diffs.length; ) {
if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) {
const deletion = diffs[pointer - 1][1], insertion = diffs[pointer][1], overlapLength1 = getCommonOverlap(deletion, insertion), overlapLength2 = getCommonOverlap(insertion, deletion);
overlapLength1 >= overlapLength2 ? (overlapLength1 >= deletion.length / 2 || overlapLength1 >= insertion.length / 2) && (diffs.splice(pointer, 0, [DIFF_EQUAL, insertion.substring(0, overlapLength1)]), diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlapLength1), diffs[pointer + 1][1] = insertion.substring(overlapLength1), pointer++) : (overlapLength2 >= deletion.length / 2 || overlapLength2 >= insertion.length / 2) && (diffs.splice(pointer, 0, [DIFF_EQUAL, deletion.substring(0, overlapLength2)]), diffs[pointer - 1][0] = DIFF_INSERT, diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlapLength2), diffs[pointer + 1][0] = DIFF_DELETE, diffs[pointer + 1][1] = deletion.substring(overlapLength2), pointer++), pointer++;
}
pointer++;
}
return diffs;
}
const nonAlphaNumericRegex = /[^a-zA-Z0-9]/, whitespaceRegex = /\s/, linebreakRegex = /[\r\n]/, blanklineEndRegex = /\n\r?\n$/, blanklineStartRegex = /^\r?\n\r?\n/;
function cleanupSemanticLossless(rawDiffs) {
const diffs = rawDiffs.map((diff2) => cloneDiff(diff2));
function diffCleanupSemanticScore(one, two) {
if (!one || !two) return 6;
const char1 = one.charAt(one.length - 1), char2 = two.charAt(0), nonAlphaNumeric1 = char1.match(nonAlphaNumericRegex), nonAlphaNumeric2 = char2.match(nonAlphaNumericRegex), whitespace1 = nonAlphaNumeric1 && char1.match(whitespaceRegex), whitespace2 = nonAlphaNumeric2 && char2.match(whitespaceRegex), lineBreak1 = whitespace1 && char1.match(linebreakRegex), lineBreak2 = whitespace2 && char2.match(linebreakRegex), blankLine1 = lineBreak1 && one.match(blanklineEndRegex), blankLine2 = lineBreak2 && two.match(blanklineStartRegex);
return blankLine1 || blankLine2 ? 5 : lineBreak1 || lineBreak2 ? 4 : nonAlphaNumeric1 && !whitespace1 && whitespace2 ? 3 : whitespace1 || whitespace2 ? 2 : nonAlphaNumeric1 || nonAlphaNumeric2 ? 1 : 0;
}
let pointer = 1;
for (; pointer < diffs.length - 1; ) {
if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) {
let equality1 = diffs[pointer - 1][1], edit = diffs[pointer][1], equality2 = diffs[pointer + 1][1];
const commonOffset = getCommonSuffix(equality1, edit);
if (commonOffset) {
const commonString = edit.substring(edit.length - commonOffset);
equality1 = equality1.substring(0, equality1.length - commonOffset), edit = commonString + edit.substring(0, edit.length - commonOffset), equality2 = commonString + equality2;
}
let bestEquality1 = equality1, bestEdit = edit, bestEquality2 = equality2, bestScore = diffCleanupSemanticScore(equality1, edit) + diffCleanupSemanticScore(edit, equality2);
for (; edit.charAt(0) === equality2.charAt(0); ) {
equality1 += edit.charAt(0), edit = edit.substring(1) + equality2.charAt(0), equality2 = equality2.substring(1);
const score = diffCleanupSemanticScore(equality1, edit) + diffCleanupSemanticScore(edit, equality2);
score >= bestScore && (bestScore = score, bestEquality1 = equality1, bestEdit = edit, bestEquality2 = equality2);
}
diffs[pointer - 1][1] !== bestEquality1 && (bestEquality1 ? diffs[pointer - 1][1] = bestEquality1 : (diffs.splice(pointer - 1, 1), pointer--), diffs[pointer][1] = bestEdit, bestEquality2 ? diffs[pointer + 1][1] = bestEquality2 : (diffs.splice(pointer + 1, 1), pointer--));
}
pointer++;
}
return diffs;
}
function cleanupMerge(rawDiffs) {
let diffs = rawDiffs.map((diff2) => cloneDiff(diff2));
diffs.push([DIFF_EQUAL, ""]);
let pointer = 0, countDelete = 0, countInsert = 0, textDelete = "", textInsert = "", commonlength;
for (; pointer < diffs.length; ) switch (diffs[pointer][0]) {
case DIFF_INSERT:
countInsert++, textInsert += diffs[pointer][1], pointer++;
break;
case DIFF_DELETE:
countDelete++, textDelete += diffs[pointer][1], pointer++;
break;
case DIFF_EQUAL:
countDelete + countInsert > 1 ? (countDelete !== 0 && countInsert !== 0 && (commonlength = getCommonPrefix(textInsert, textDelete), commonlength !== 0 && (pointer - countDelete - countInsert > 0 && diffs[pointer - countDelete - countInsert - 1][0] === DIFF_EQUAL ? diffs[pointer - countDelete - countInsert - 1][1] += textInsert.substring(0, commonlength) : (diffs.splice(0, 0, [DIFF_EQUAL, textInsert.substring(0, commonlength)]), pointer++), textInsert = textInsert.substring(commonlength), textDelete = textDelete.substring(commonlength)), commonlength = getCommonSuffix(textInsert, textDelete), commonlength !== 0 && (diffs[pointer][1] = textInsert.substring(textInsert.length - commonlength) + diffs[pointer][1], textInsert = textInsert.substring(0, textInsert.length - commonlength), textDelete = textDelete.substring(0, textDelete.length - commonlength))), pointer -= countDelete + countInsert, diffs.splice(pointer, countDelete + countInsert), textDelete.length && (diffs.splice(pointer, 0, [DIFF_DELETE, textDelete]), pointer++), textInsert.length && (diffs.splice(pointer, 0, [DIFF_INSERT, textInsert]), pointer++), pointer++) : pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL ? (diffs[pointer - 1][1] += diffs[pointer][1], diffs.splice(pointer, 1)) : pointer++, countInsert = 0, countDelete = 0, textDelete = "", textInsert = "";
break;
default:
throw new Error("Unknown diff operation");
}
diffs[diffs.length - 1][1] === "" && diffs.pop();
let hasChanges = !1;
for (pointer = 1; pointer < diffs.length - 1; ) diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL && (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1] ? (diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length), diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1], diffs.splice(pointer - 1, 1), hasChanges = !0) : diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1] && (diffs[pointer - 1][1] += diffs[pointer + 1][1], diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1], diffs.splice(pointer + 1, 1), hasChanges = !0)), pointer++;
return hasChanges && (diffs = cleanupMerge(diffs)), diffs;
}
function trueCount(...args) {
return args.reduce((n, bool) => n + (bool ? 1 : 0), 0);
}
function cleanupEfficiency(rawDiffs, editCost = 4) {
let diffs = rawDiffs.map((diff2) => cloneDiff(diff2)), hasChanges = !1;
const equalities = [];
let equalitiesLength = 0, lastEquality = null, pointer = 0, preIns = !1, preDel = !1, postIns = !1, postDel = !1;
for (; pointer < diffs.length; ) diffs[pointer][0] === DIFF_EQUAL ? (diffs[pointer][1].length < editCost && (postIns || postDel) ? (equalities[equalitiesLength++] = pointer, preIns = postIns, preDel = postDel, lastEquality = diffs[pointer][1]) : (equalitiesLength = 0, lastEquality = null), postIns = !1, postDel = !1) : (diffs[pointer][0] === DIFF_DELETE ? postDel = !0 : postIns = !0, lastEquality && (preIns && preDel && postIns && postDel || lastEquality.length < editCost / 2 && trueCount(preIns, preDel, postIns, postDel) === 3) && (diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastEquality]), diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT, equalitiesLength--, lastEquality = null, preIns && preDel ? (postIns = !0, postDel = !0, equalitiesLength = 0) : (equalitiesLength--, pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1, postIns = !1, postDel = !1), hasChanges = !0)), pointer++;
return hasChanges && (diffs = cleanupMerge(diffs)), diffs;
}
var __defProp$1 = Object.defineProperty, __getOwnPropSymbols$1 = Object.getOwnPropertySymbols, __hasOwnProp$1 = Object.prototype.hasOwnProperty, __propIsEnum$1 = Object.prototype.propertyIsEnumerable, __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
enumerable: !0,
configurable: !0,
writable: !0,
value
}) : obj[key] = value, __spreadValues$1 = (a, b) => {
for (var prop in b || (b = {})) __hasOwnProp$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
if (__getOwnPropSymbols$1) for (var prop of __getOwnPropSymbols$1(b)) __propIsEnum$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
return a;
};
const DEFAULT_OPTIONS = {
/**
* At what point is no match declared (0.0 = perfection, 1.0 = very loose).
*/
threshold: 0.5,
/**
* How far to search for a match (0 = exact location, 1000+ = broad match).
* A match this many characters away from the expected location will add
* 1.0 to the score (0.0 is a perfect match).
*/
distance: 1e3
};
function applyDefaults(options) {
return __spreadValues$1(__spreadValues$1({}, DEFAULT_OPTIONS), options);
}
const MAX_BITS$1 = 32;
function bitap(text, pattern, loc, opts = {}) {
if (pattern.length > MAX_BITS$1) throw new Error("Pattern too long for this browser.");
const options = applyDefaults(opts), s = getAlphabetFromPattern(p