import { Aa as findParentNodeClosestToPos, Ba as Plugin, Bi as getActiveFormatting, Do as getUnderlineCssString, G as getTrackChanges, Ja as ReplaceStep, Li as isInTable, Pi as isRelativeUrl, Qi as getResolvedParagraphProperties, Ti as yUndoPluginKey, Tr as kebabCase, Ua as TextSelection, Va as PluginKey, Zi as calculateResolvedParagraphProperties, _s as getExtensionConfigField, ba as DecorationSet, gs as callOrGet, io as generateDocxRandomId, ji as undoDepth, ka as findParentNode, ki as redoDepth, qa as ReplaceAroundStep, si as isList, ui as findOrCreateRelationship, ya as Decoration, za as NodeSelection } from "./SuperConverter-CEo_K44C.es.js";
import { R as twipsToLines } from "./constants-DrU4EASo.es.js";
import { t as Buffer } from "./dist-B8HfvhaK.es.js";
var CSS_DIMENSION_REGEX = /[\d-.]+(\w+)$/;
var DOM_SIZE_UNITS = [
	"px",
	"rem",
	"em",
	"in",
	"q",
	"mm",
	"cm",
	"pt",
	"pc",
	"vh",
	"vw",
	"vmin",
	"vmax"
];
function parseSizeUnit(val = "0") {
	const length = val.toString() || "0";
	const value = Number.parseFloat(length);
	const unit = (length.match(CSS_DIMENSION_REGEX)?.[1] ?? "").toLowerCase();
	return [value, DOM_SIZE_UNITS.includes(unit) ? unit : null];
}
var Extension = class Extension {
	constructor(config) {
		this.type = "extension";
		this.name = "extension";
		this.config = {
			...config,
			name: config.name || this.name
		};
		this.name = this.config.name;
		if (this.config.addOptions) this.options = callOrGet(getExtensionConfigField(this, "addOptions", { name: this.name })) || {};
		else this.options = {};
		this.storage = callOrGet(getExtensionConfigField(this, "addStorage", {
			name: this.name,
			options: this.options
		})) || {};
	}
	static create(config) {
		return new Extension(config);
	}
};
const CustomSelectionPluginKey = new PluginKey("CustomSelection");
function getPreservedSelection(state) {
	return CustomSelectionPluginKey.getState(state)?.preservedSelection ?? null;
}
var InclusiveTextSelectionBookmark = class InclusiveTextSelectionBookmark {
	constructor(anchor, head) {
		this.anchor = anchor;
		this.head = head;
	}
	map(mapping) {
		const isForward = this.anchor <= this.head;
		return new InclusiveTextSelectionBookmark(mapping.map(this.anchor, isForward ? -1 : 1), mapping.map(this.head, isForward ? 1 : -1));
	}
	resolve(doc) {
		return TextSelection.between(doc.resolve(this.anchor), doc.resolve(this.head));
	}
};
function createSelectionTrackingBookmark(selection) {
	if (selection instanceof TextSelection && !selection.empty) return new InclusiveTextSelectionBookmark(selection.anchor, selection.head);
	return selection.getBookmark();
}
var nextHandleId = 1;
const SelectionHandlePluginKey = new PluginKey("selectionHandle");
function createSelectionHandlePlugin() {
	return new Plugin({
		key: SelectionHandlePluginKey,
		state: {
			init() {
				return { entries: /* @__PURE__ */ new Map() };
			},
			apply(tr, prev) {
				const meta = tr.getMeta(SelectionHandlePluginKey);
				let entries = prev.entries;
				if (tr.docChanged && entries.size > 0) {
					const next = /* @__PURE__ */ new Map();
					for (const [id, entry] of entries) next.set(id, {
						...entry,
						bookmark: entry.bookmark.map(tr.mapping)
					});
					entries = next;
				}
				if (meta?.action === "capture") {
					if (entries === prev.entries) entries = new Map(entries);
					entries.set(meta.entry.id, meta.entry);
				} else if (meta?.action === "release") {
					if (entries.has(meta.id)) {
						if (entries === prev.entries) entries = new Map(entries);
						entries.delete(meta.id);
					}
				}
				return entries === prev.entries ? prev : { entries };
			}
		}
	});
}
function captureSelectionHandle(owner, selection, surface) {
	const id = nextHandleId++;
	const bookmark = createSelectionTrackingBookmark(selection);
	const wasNonEmpty = !selection.empty;
	const entry = {
		id,
		bookmark,
		wasNonEmpty
	};
	const tr = owner.state.tr.setMeta(SelectionHandlePluginKey, {
		action: "capture",
		entry
	});
	owner.dispatch(tr);
	return {
		id,
		surface,
		wasNonEmpty,
		_owner: owner
	};
}
function resolveHandleToSelection(handle) {
	const { state } = handle._owner;
	const pluginState = SelectionHandlePluginKey.getState(state);
	if (!pluginState) return null;
	const entry = pluginState.entries.get(handle.id);
	if (!entry) return null;
	const resolved = entry.bookmark.resolve(state.doc);
	if (entry.wasNonEmpty && resolved.empty) return null;
	return resolved;
}
function releaseSelectionHandle(handle) {
	const { state, dispatch } = handle._owner;
	dispatch(state.tr.setMeta(SelectionHandlePluginKey, {
		action: "release",
		id: handle.id
	}));
}
var DEFAULT_MIME_TYPE = "application/octet-stream";
var simpleHash = (str) => {
	let hash = 0;
	for (let i = 0; i < str.length; i++) {
		const char = str.charCodeAt(i);
		hash = (hash << 5) - hash + char;
		hash = hash & hash;
	}
	return Math.abs(hash).toString();
};
var decodeBase64ToBinaryString = (data) => {
	if (!data) return "";
	if (typeof atob === "function") return atob(data);
	if (typeof Buffer !== "undefined" && typeof Buffer.from === "function") return Buffer.from(data, "base64").toString("binary");
	throw new Error("Unable to decode base64 payload in the current environment.");
};
var extractBase64Meta = (base64String) => {
	const [meta = "", payload = ""] = base64String.split(",");
	const mimeMatch = meta.match(/:(.*?);/);
	const mimeType = (mimeMatch ? mimeMatch[1] : "") || DEFAULT_MIME_TYPE;
	const binaryString = decodeBase64ToBinaryString(payload);
	return {
		mimeType,
		binaryString,
		filename: `image-${simpleHash(binaryString)}.${mimeType.split("/")[1] || "bin"}`
	};
};
const getBase64FileMeta = (base64String) => {
	const { mimeType, filename } = extractBase64Meta(base64String);
	return {
		mimeType,
		filename
	};
};
const base64ToFile = (base64String) => {
	const { mimeType, binaryString, filename } = extractBase64Meta(base64String);
	const fileType = mimeType || DEFAULT_MIME_TYPE;
	const bytes = new Uint8Array(binaryString.length);
	for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
	const blob = new Blob([bytes], { type: fileType });
	return new File([blob], filename, { type: fileType });
};
const urlToFile = async (url, filename, mimeType) => {
	try {
		const response = await fetch(url, {
			mode: "cors",
			credentials: "omit",
			headers: { Accept: "image/*,*/*;q=0.8" }
		});
		if (!response.ok) {
			console.warn(`Failed to fetch image from ${url}: ${response.status} ${response.statusText}`);
			return null;
		}
		const blob = await response.blob();
		const finalFilename = filename || extractFilenameFromUrl(url);
		const finalMimeType = mimeType || response.headers.get("content-type") || blob.type || "image/jpeg";
		return new File([blob], finalFilename, { type: finalMimeType });
	} catch (error) {
		if (isCorsError(error)) {
			console.warn(`CORS policy prevents accessing image from ${url}:`, error.message);
			return null;
		}
		console.error(`Error fetching image from ${url}:`, error);
		return null;
	}
};
var isCorsError = (error) => {
	const errorMessage = error.message.toLowerCase();
	return error.name.toLowerCase().includes("cors") || errorMessage.includes("cors") || errorMessage.includes("cross-origin") || errorMessage.includes("access-control") || errorMessage.includes("network error") || errorMessage.includes("failed to fetch");
};
var extractFilenameFromUrl = (url) => {
	try {
		const filename = new URL(url).pathname.split("/").pop();
		if (filename && !filename.includes(".")) return `${filename}.jpg`;
		return filename || "image.jpg";
	} catch {
		return "image.jpg";
	}
};
const validateUrlAccessibility = async (url) => {
	try {
		return (await fetch(url, {
			method: "HEAD",
			mode: "cors",
			credentials: "omit"
		})).ok;
	} catch {
		return false;
	}
};
const handleImageUpload = (file) => {
	return new Promise((resolve, reject) => {
		let reader = new FileReader();
		reader.onload = (event) => {
			resolve(event.target.result);
		};
		reader.onerror = reject;
		setTimeout(() => reader.readAsDataURL(file), 250);
	});
};
const processUploadedImage = (fileData, getMaxContentSize) => {
	return new Promise((resolve, reject) => {
		const img = new window.Image();
		img.onload = () => {
			const canvas = document.createElement("canvas");
			const { width: logicalWidth, height: logicalHeight } = getAllowedImageDimensions(img.width, img.height, getMaxContentSize);
			canvas.width = img.width;
			canvas.height = img.height;
			const ctx = canvas.getContext("2d");
			if (ctx) {
				ctx.imageSmoothingEnabled = true;
				try {
					ctx.imageSmoothingQuality = "high";
				} catch {}
			}
			ctx.drawImage(img, 0, 0, img.width, img.height);
			const dpr = typeof window !== "undefined" && window.devicePixelRatio ? window.devicePixelRatio : 1;
			const targetPixelWidth = Math.round(logicalWidth * dpr);
			const targetPixelHeight = Math.round(logicalHeight * dpr);
			const finalTargetWidth = Math.min(targetPixelWidth, img.width);
			const finalTargetHeight = Math.min(targetPixelHeight, img.height);
			if (finalTargetWidth !== img.width || finalTargetHeight !== img.height) multiStepResize(canvas, finalTargetWidth, finalTargetHeight);
			if (typeof fileData === "string") resolve(canvas.toDataURL());
			else canvas.toBlob((blob) => {
				resolve({
					file: new File([blob], fileData.name, {
						type: fileData.type,
						lastModified: Date.now()
					}),
					width: logicalWidth,
					height: logicalHeight
				});
			});
		};
		img.onerror = (error) => reject(error);
		img.src = typeof fileData === "string" ? fileData : URL.createObjectURL(fileData);
	});
};
const getAllowedImageDimensions = (width, height, getMaxContentSize) => {
	const { width: maxWidth, height: maxHeight } = getMaxContentSize();
	if (!maxWidth || !maxHeight) return {
		width,
		height
	};
	let adjustedWidth = width;
	let adjustedHeight = height;
	const aspectRatio = width / height;
	if (height > maxHeight) {
		adjustedHeight = maxHeight;
		adjustedWidth = Math.round(maxHeight * aspectRatio);
	}
	if (adjustedWidth > maxWidth) {
		adjustedWidth = maxWidth;
		adjustedHeight = Math.round(maxWidth / aspectRatio);
	}
	return {
		width: adjustedWidth,
		height: adjustedHeight
	};
};
function resample_high_quality(canvas, width, height, resize_canvas) {
	var width_source = canvas.width;
	var height_source = canvas.height;
	width = Math.round(width);
	height = Math.round(height);
	var ratio_w = width_source / width;
	var ratio_h = height_source / height;
	var ratio_w_half = Math.ceil(ratio_w / 2);
	var ratio_h_half = Math.ceil(ratio_h / 2);
	var ctx = canvas.getContext("2d");
	var img = ctx.getImageData(0, 0, width_source, height_source);
	var img2 = ctx.createImageData(width, height);
	var data = img.data;
	var data2 = img2.data;
	for (var j = 0; j < height; j++) for (var i = 0; i < width; i++) {
		var x2 = (i + j * width) * 4;
		var weight = 0;
		var weights = 0;
		var weights_alpha = 0;
		var gx_r = 0;
		var gx_g = 0;
		var gx_b = 0;
		var gx_a = 0;
		var center_y = (j + .5) * ratio_h;
		var yy_start = Math.floor(j * ratio_h);
		var yy_stop = Math.ceil((j + 1) * ratio_h);
		for (var yy = yy_start; yy < yy_stop; yy++) {
			var dy = Math.abs(center_y - (yy + .5)) / ratio_h_half;
			var center_x = (i + .5) * ratio_w;
			var w0 = dy * dy;
			var xx_start = Math.floor(i * ratio_w);
			var xx_stop = Math.ceil((i + 1) * ratio_w);
			for (var xx = xx_start; xx < xx_stop; xx++) {
				var dx = Math.abs(center_x - (xx + .5)) / ratio_w_half;
				var w = Math.sqrt(w0 + dx * dx);
				if (w >= 1) continue;
				weight = 2 * w * w * w - 3 * w * w + 1;
				var pos_x = 4 * (xx + yy * width_source);
				gx_a += weight * data[pos_x + 3];
				weights_alpha += weight;
				if (data[pos_x + 3] < 255) weight = weight * data[pos_x + 3] / 250;
				gx_r += weight * data[pos_x];
				gx_g += weight * data[pos_x + 1];
				gx_b += weight * data[pos_x + 2];
				weights += weight;
			}
		}
		data2[x2] = gx_r / weights;
		data2[x2 + 1] = gx_g / weights;
		data2[x2 + 2] = gx_b / weights;
		data2[x2 + 3] = gx_a / weights_alpha;
	}
	if (resize_canvas === true) {
		canvas.width = width;
		canvas.height = height;
	} else ctx.clearRect(0, 0, width_source, height_source);
	ctx.putImageData(img2, 0, 0);
}
function multiStepResize(canvas, width, height) {
	let oc = document.createElement("canvas");
	let octx = oc.getContext("2d");
	let ctx = canvas.getContext("2d");
	let steps = Math.ceil(Math.log(canvas.width / width) / Math.log(2));
	steps = Math.max(steps, 1);
	let stepWidth = width * Math.pow(2, steps - 1);
	let stepHeight = height * Math.pow(2, steps - 1);
	let currentWidth = canvas.width;
	let currentHeight = canvas.height;
	oc.width = currentWidth;
	oc.height = currentHeight;
	octx.drawImage(canvas, 0, 0);
	while (steps > 0) {
		stepWidth = Math.max(stepWidth, width);
		stepHeight = Math.max(stepHeight, height);
		canvas.width = stepWidth;
		canvas.height = stepHeight;
		ctx.drawImage(oc, 0, 0, currentWidth, currentHeight, 0, 0, stepWidth, stepHeight);
		currentWidth = stepWidth;
		currentHeight = stepHeight;
		oc.width = currentWidth;
		oc.height = currentHeight;
		octx.drawImage(canvas, 0, 0);
		stepWidth = Math.round(stepWidth / 2);
		stepHeight = Math.round(stepHeight / 2);
		steps--;
	}
	resample_high_quality(canvas, width, height, true);
}
var FALLBACK_NAME = "image";
var stripDiacritics = (value) => value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "");
var sanitizeSegment = (segment, { allowDots = false } = {}) => {
	if (!segment) return "";
	const normalized = stripDiacritics(segment).replace(/[\s\u2000-\u206f]+/g, "_").replace(/[\\/]+/g, "_");
	const allowedPattern = allowDots ? /[^0-9A-Za-z._-]+/g : /[^0-9A-Za-z_-]+/g;
	let sanitized = normalized.replace(allowedPattern, "_");
	sanitized = sanitized.replace(/_+/g, "_");
	sanitized = sanitized.replace(/^[_.-]+/, "");
	sanitized = sanitized.replace(/[_-]+$/, "");
	return sanitized;
};
var splitFileName = (name) => {
	const trimmed = name?.trim?.() ?? "";
	const lastDot = trimmed.lastIndexOf(".");
	if (lastDot <= 0 || lastDot === trimmed.length - 1) return {
		base: trimmed,
		ext: ""
	};
	return {
		base: trimmed.slice(0, lastDot),
		ext: trimmed.slice(lastDot + 1)
	};
};
const sanitizeImageFileName = (inputName) => {
	const { base, ext } = splitFileName(inputName || "");
	const sanitizedBase = sanitizeSegment(base, { allowDots: true }) || FALLBACK_NAME;
	const sanitizedExt = sanitizeSegment(ext, { allowDots: false }).toLowerCase();
	if (!sanitizedExt) return sanitizedBase;
	return `${sanitizedBase}.${sanitizedExt}`;
};
const ensureUniqueFileName = (preferredName, existingNames = /* @__PURE__ */ new Set()) => {
	const sanitized = sanitizeImageFileName(preferredName);
	if (!existingNames || typeof existingNames.has !== "function") return sanitized;
	const existingSet = /* @__PURE__ */ new Set();
	existingNames.forEach((name) => existingSet.add(sanitizeImageFileName(name)));
	if (!existingSet.has(sanitized)) return sanitized;
	const { base, ext } = splitFileName(sanitized);
	let counter = 1;
	let candidate = sanitized;
	const suffix = () => `${base}-${counter}${ext ? `.${ext}` : ""}`;
	while (existingSet.has(candidate)) {
		candidate = suffix();
		counter += 1;
	}
	return candidate;
};
const buildMediaPath = (fileName) => `word/media/${fileName}`;
var fileTooLarge = (file) => {
	if (Number((file.size / (1024 * 1024)).toFixed(4)) > 5) {
		window.alert("Image size must be less than 5MB");
		return true;
	}
	return false;
};
const checkAndProcessImage = async ({ getMaxContentSize, file }) => {
	if (fileTooLarge(file)) return {
		file: null,
		size: {
			width: 0,
			height: 0
		}
	};
	try {
		const process = await processUploadedImage(file, getMaxContentSize);
		return {
			file: process.file,
			size: {
				width: process.width,
				height: process.height
			}
		};
	} catch (err) {
		console.warn("Error processing image:", err);
		return {
			file: null,
			size: {
				width: 0,
				height: 0
			}
		};
	}
};
function replaceSelectionWithImagePlaceholder({ editorOptions, view, id }) {
	let { tr } = view.state;
	let { selection } = tr;
	if (editorOptions.isHeaderOrFooter) selection = editorOptions.lastSelection;
	if (!selection.empty && !editorOptions.isHeaderOrFooter) tr.deleteSelection();
	tr = addImagePlaceholder(view.state, tr, id, selection.from);
	view.dispatch(tr);
}
const generateUniqueDocPrId = (editor) => {
	const existingIds = /* @__PURE__ */ new Set();
	editor?.state?.doc?.descendants((node) => {
		if (node.type.name === "image" && node.attrs.id !== void 0 && node.attrs.id !== null) existingIds.add(String(node.attrs.id));
	});
	let candidate;
	do {
		const hex = generateDocxRandomId();
		candidate = String(parseInt(hex, 16));
	} while (!candidate || existingIds.has(candidate));
	return candidate;
};
async function uploadAndInsertImage({ editor, view, file, size, id }) {
	const imageUploadHandler = typeof editor.options.handleImageUpload === "function" ? editor.options.handleImageUpload : handleImageUpload;
	const placeholderId = id;
	try {
		const existingFileNames = new Set(Object.keys(editor.storage.image.media ?? {}).map((key$1) => key$1.split("/").pop()));
		const uniqueFileName = ensureUniqueFileName(file.name, existingFileNames);
		let url = await imageUploadHandler(uniqueFileName === file.name ? file : new File([file], uniqueFileName, {
			type: file.type,
			lastModified: file.lastModified ?? Date.now()
		}));
		let placeholderPos = findPlaceholder(view.state, placeholderId);
		if (placeholderPos == null) return;
		const mediaPath = buildMediaPath(uniqueFileName);
		const docPrId = generateUniqueDocPrId(editor);
		let rId = null;
		if (editor.options.mode === "docx") {
			const [, path] = mediaPath.split("word/");
			const id$1 = addImageRelationship({
				editor,
				path
			});
			if (id$1) rId = id$1;
		}
		let imageNode = view.state.schema.nodes.image.create({
			src: mediaPath,
			size,
			id: docPrId,
			rId
		});
		editor.storage.image.media = Object.assign(editor.storage.image.media, { [mediaPath]: url });
		if (editor.options.ydoc && typeof editor.commands.addImageToCollaboration === "function") editor.commands.addImageToCollaboration({
			mediaPath,
			fileData: url
		});
		let tr = view.state.tr;
		tr.replaceWith(placeholderPos, placeholderPos, imageNode);
		tr = removeImagePlaceholder(view.state, tr, placeholderId);
		view.dispatch(tr);
	} catch {
		const tr = removeImagePlaceholder(view.state, view.state.tr, placeholderId);
		view.dispatch(tr);
	}
}
function addImageRelationship({ editor, path }) {
	return findOrCreateRelationship(editor, "startImageUpload:addImageRelationship", {
		target: path,
		type: "image"
	});
}
var key = new PluginKey("ImageRegistration");
const needsImageRegistration = (node) => {
	if (!node || node.type?.name !== "image") return false;
	const src = node.attrs?.src;
	if (typeof src !== "string" || src.length === 0) return false;
	if (src.startsWith("word/media")) return false;
	if (src.startsWith("data:") && node.attrs?.rId) return false;
	if (isRelativeUrl(src) && node.attrs?.rId) return false;
	return true;
};
const ImageRegistrationPlugin = ({ editor }) => {
	const { view } = editor;
	return new Plugin({
		key,
		state: {
			init() {
				return { set: DecorationSet.empty };
			},
			apply(tr, { set }) {
				const meta = tr.getMeta(key);
				if (meta) {
					set = meta.set;
					return { set };
				}
				set = set.map(tr.mapping, tr.doc);
				return { set };
			}
		},
		appendTransaction: (trs, _oldState, state) => {
			let foundImages = [];
			if (!trs.some((tr) => tr.docChanged)) return null;
			trs.forEach((tr) => {
				if (tr.docChanged) tr.steps.forEach((step, index) => {
					const stepMap = step.getMap();
					foundImages = foundImages.map(({ node, pos, id }) => {
						return {
							node,
							pos: stepMap.map(pos, -1),
							id
						};
					});
					if (step instanceof ReplaceStep || step instanceof ReplaceAroundStep) (tr.docs[index + 1] || tr.doc).nodesBetween(stepMap.map(step.from, -1), stepMap.map(step.to, 1), (node, pos) => {
						if (node.type.name === "image" && needsImageRegistration(node)) foundImages.push({
							node,
							pos,
							id: {}
						});
						else return true;
					});
				});
			});
			if (!foundImages || foundImages.length === 0) return null;
			if (editor.options.isHeadless) return handleNodePath(foundImages, editor, state);
			return handleBrowserPath(foundImages, editor, view, state);
		},
		props: { decorations(state) {
			let { set } = key.getState(state);
			return set;
		} }
	});
};
var derivePreferredFileName = (src) => {
	if (typeof src !== "string" || src.length === 0) return "image.jpg";
	if (src.startsWith("data:")) return getBase64FileMeta(src).filename;
	const trimmed = (src.split("/").pop() ?? "").split(/[?#]/)[0];
	if (!trimmed) return "image.jpg";
	if (!trimmed.includes(".")) return `${trimmed}.jpg`;
	return trimmed;
};
var parsePositiveInt = (value) => {
	const parsed = Number.parseInt(String(value), 10);
	return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
};
var parseSizeFromImageUrl = (src) => {
	if (typeof src !== "string" || src.length === 0 || !src.startsWith("http")) return null;
	try {
		const url = new URL(src);
		const width = parsePositiveInt(url.searchParams.get("width")) ?? parsePositiveInt(url.searchParams.get("w")) ?? parsePositiveInt(url.searchParams.get("imgw"));
		const height = parsePositiveInt(url.searchParams.get("height")) ?? parsePositiveInt(url.searchParams.get("h")) ?? parsePositiveInt(url.searchParams.get("imgh"));
		if (width && height) return {
			width,
			height
		};
		const segments = url.pathname.split("/").filter(Boolean);
		const last = parsePositiveInt(segments.at(-1));
		const secondLast = parsePositiveInt(segments.at(-2));
		if (secondLast && last) return {
			width: secondLast,
			height: last
		};
		const compact = segments.at(-1)?.match(/^(\d{1,5})x(\d{1,5})$/i);
		if (compact) {
			const compactWidth = parsePositiveInt(compact[1]);
			const compactHeight = parsePositiveInt(compact[2]);
			if (compactWidth && compactHeight) return {
				width: compactWidth,
				height: compactHeight
			};
		}
	} catch {
		return null;
	}
	return null;
};
var hasFinitePositiveSize = (size) => Number.isFinite(size?.width) && size.width > 0 && Number.isFinite(size?.height) && size.height > 0;
var getOrInitMediaStore = (editor) => {
	if (!editor?.storage?.image?.media) editor.storage.image.media = {};
	const mediaStore = editor.storage.image.media;
	return {
		mediaStore,
		existingFileNames: new Set(Object.keys(mediaStore).map((k) => k.split("/").pop()))
	};
};
const handleNodePath = (foundImages, editor, state) => {
	const { tr } = state;
	const { mediaStore, existingFileNames } = getOrInitMediaStore(editor);
	foundImages.forEach(({ node, pos }) => {
		const { src } = node.attrs;
		const uniqueFileName = ensureUniqueFileName(derivePreferredFileName(src), existingFileNames);
		existingFileNames.add(uniqueFileName);
		const mediaPath = buildMediaPath(uniqueFileName);
		mediaStore[mediaPath] = src;
		if (editor.options.ydoc) editor.options.ydoc.getMap("media").set(mediaPath, src);
		const rId = addImageRelationship({
			editor,
			path: mediaPath.startsWith("word/") ? mediaPath.slice(5) : mediaPath
		});
		const inferredSize = hasFinitePositiveSize(node.attrs?.size) ? null : parseSizeFromImageUrl(src);
		tr.setNodeMarkup(pos, void 0, {
			...node.attrs,
			...inferredSize ? { size: inferredSize } : {},
			src: mediaPath,
			rId
		});
	});
	return tr;
};
const handleBrowserPath = (foundImages, editor, view, state) => {
	if (foundImages.length === 0) return null;
	const relativeImages = foundImages.filter(({ node }) => isRelativeUrl(node.attrs?.src));
	const imagesToProcess = foundImages.filter(({ node }) => !isRelativeUrl(node.attrs?.src));
	if (relativeImages.length > 0) registerRelativeImages(relativeImages, editor, view);
	if (imagesToProcess.length === 0) return null;
	registerImages(imagesToProcess, editor, view);
	const tr = state.tr;
	let { set } = key.getState(state);
	imagesToProcess.slice().sort((a, b) => a.pos - b.pos).forEach(({ pos, id }) => {
		let deco = Decoration.widget(pos, () => document.createElement("placeholder"), {
			side: -1,
			id
		});
		set = set.add(tr.doc, [deco]);
	});
	imagesToProcess.slice().sort((a, b) => b.pos - a.pos).forEach(({ node, pos }) => {
		tr.delete(pos, pos + node.nodeSize);
	});
	set = set.map(tr.mapping, tr.doc);
	tr.setMeta(key, { set });
	return tr;
};
const findPlaceholder = (state, id) => {
	let { set } = key.getState(state);
	let found = set?.find(null, null, (spec) => spec.id === id);
	return found?.length ? found[0].from : null;
};
const removeImagePlaceholder = (state, tr, id) => {
	let { set } = key.getState(state);
	set = set.map(tr.mapping, tr.doc);
	set = set.remove(set.find(null, null, (spec) => spec.id == id));
	return tr.setMeta(key, {
		set,
		type: "remove"
	});
};
const addImagePlaceholder = (state, tr, id, pos) => {
	let { set } = key.getState(state);
	set = set.map(tr.mapping, tr.doc);
	let deco = Decoration.widget(pos, () => document.createElement("placeholder"), { id });
	set = set.add(tr.doc, [deco]);
	return tr.setMeta(key, {
		set,
		type: "add"
	});
};
var registerRelativeImages = async (images, editor, view) => {
	const { mediaStore, existingFileNames } = getOrInitMediaStore(editor);
	const { pendingRelativeRegistrations } = editor.storage.image;
	for (const { node } of images) {
		const src = node.attrs.src;
		if (pendingRelativeRegistrations.has(src)) continue;
		pendingRelativeRegistrations.add(src);
		try {
			const filename = derivePreferredFileName(src);
			const file = await urlToFile(src, filename);
			if (!file) continue;
			const dataUrl = await new Promise((resolve, reject) => {
				const reader = new FileReader();
				reader.onload = () => resolve(reader.result);
				reader.onerror = reject;
				reader.readAsDataURL(file);
			});
			const uniqueFileName = ensureUniqueFileName(filename, existingFileNames);
			existingFileNames.add(uniqueFileName);
			const mediaPath = buildMediaPath(uniqueFileName);
			mediaStore[mediaPath] = dataUrl;
			if (editor.options.ydoc) editor.options.ydoc.getMap("media").set(mediaPath, dataUrl);
			const rId = addImageRelationship({
				editor,
				path: mediaPath.startsWith("word/") ? mediaPath.slice(5) : mediaPath
			});
			let nodePos = null;
			view.state.doc.descendants((n, pos) => {
				if (nodePos !== null) return false;
				if (n.type.name === "image" && n.attrs.src === src && !n.attrs.rId) nodePos = pos;
			});
			if (nodePos !== null) {
				const tr = view.state.tr;
				const currentNode = tr.doc.nodeAt(nodePos);
				if (currentNode?.type.name === "image") {
					tr.setNodeMarkup(nodePos, void 0, {
						...currentNode.attrs,
						rId,
						originalSrc: mediaPath
					});
					view.dispatch(tr);
					if (!currentNode.attrs.size?.width || !currentNode.attrs.size?.height) try {
						const size = await new Promise((resolve, reject) => {
							const img = new globalThis.Image();
							img.onload = () => resolve({
								width: img.naturalWidth,
								height: img.naturalHeight
							});
							img.onerror = () => resolve(null);
							setTimeout(() => reject(/* @__PURE__ */ new Error("timeout")), 5e3);
							img.src = dataUrl;
						});
						if (size) {
							let sizePos = null;
							view.state.doc.descendants((n, p) => {
								if (sizePos !== null) return false;
								if (n.type.name === "image" && n.attrs.rId === rId) sizePos = p;
							});
							if (sizePos !== null) {
								const sizeTr = view.state.tr;
								const sizeNode = sizeTr.doc.nodeAt(sizePos);
								if (sizeNode?.type.name === "image") {
									sizeTr.setNodeMarkup(sizePos, void 0, {
										...sizeNode.attrs,
										size
									});
									view.dispatch(sizeTr);
								}
							}
						}
					} catch {}
				}
			}
		} catch (error) {
			console.error(`Error registering relative image ${src}:`, error);
		} finally {
			pendingRelativeRegistrations.delete(src);
		}
	}
};
var registerImages = async (foundImages, editor, view) => {
	foundImages.forEach(async (image) => {
		const src = image.node.attrs.src;
		const id = image.id;
		let file = null;
		if (src.startsWith("http")) if (await validateUrlAccessibility(src)) file = await urlToFile(src);
		else {
			console.warn(`Image URL ${src} is not accessible due to CORS or other restrictions. Using original URL.`);
			const tr = view.state.tr;
			removeImagePlaceholder(view.state, tr, id);
			view.dispatch(tr);
			return;
		}
		else if (src.startsWith("data:")) file = base64ToFile(src);
		else console.error(`Unsupported image source: ${src}`);
		if (!file) {
			const tr = view.state.tr;
			removeImagePlaceholder(view.state, tr, id);
			view.dispatch(tr);
			return;
		}
		try {
			const process = await checkAndProcessImage({
				getMaxContentSize: () => editor.getMaxContentSize(),
				file
			});
			if (!process.file) {
				const tr = view.state.tr;
				removeImagePlaceholder(view.state, tr, id);
				view.dispatch(tr);
				return;
			}
			await uploadAndInsertImage({
				editor,
				view,
				file: process.file,
				size: process.size,
				id
			});
		} catch (error) {
			console.error(`Error processing image from ${src}:`, error);
			const tr = view.state.tr;
			removeImagePlaceholder(view.state, tr, id);
			view.dispatch(tr);
		}
	});
};
var stepHasSlice = (step) => "slice" in step && Boolean(step.slice);
var ImagePositionPluginKey = new PluginKey("ImagePosition");
var pageBreakPositionCache = /* @__PURE__ */ new WeakMap();
const ImagePositionPlugin = ({ editor }) => {
	const { view } = editor;
	let shouldUpdate = true;
	return new Plugin({
		name: "ImagePositionPlugin",
		key: ImagePositionPluginKey,
		state: {
			init() {
				return DecorationSet.empty;
			},
			apply(tr, oldDecorationSet, oldState, newState) {
				if (!tr.docChanged && !shouldUpdate) return oldDecorationSet;
				if (!(typeof document !== "undefined" && !!(document && document.createElement)) || !view || typeof view.domAtPos !== "function") return oldDecorationSet.map(tr.mapping, tr.doc);
				let affectsImages = false;
				tr.steps.forEach((step) => {
					if (stepHasSlice(step)) step.slice.content.descendants((node) => {
						if (node.type.name === "image" || node.attrs?.anchorData) {
							affectsImages = true;
							return false;
						}
					});
				});
				if (!affectsImages && !shouldUpdate) return oldDecorationSet.map(tr.mapping, tr.doc);
				const decorations = getImagePositionDecorations(newState, view);
				shouldUpdate = false;
				return DecorationSet.create(newState.doc, decorations);
			}
		},
		view: () => {
			return { update: (view$1, lastState) => {
				if (!(typeof document !== "undefined" && !!(document && document.createElement)) || !view$1 || typeof view$1.domAtPos !== "function") return;
				if (shouldUpdate) {
					const decorations = getImagePositionDecorations(lastState, view$1);
					const updateTransaction = view$1.state.tr.setMeta(ImagePositionPluginKey, { decorations });
					view$1.dispatch(updateTransaction);
				}
			} };
		},
		props: { decorations(state) {
			return this.getState(state);
		} }
	});
};
var getImagePositionDecorations = (state, view) => {
	let decorations = [];
	if (!(typeof document !== "undefined" && !!(document && document.createElement)) || !view || typeof view.domAtPos !== "function") return decorations;
	let hasAnchoredImages = false;
	state.doc.descendants((node) => {
		if (node.attrs?.anchorData) {
			hasAnchoredImages = true;
			return false;
		}
	});
	if (!hasAnchoredImages) return decorations;
	state.doc.descendants((node, pos) => {
		if (node.attrs.anchorData) {
			let style = "";
			let className = "";
			const { vRelativeFrom, alignH } = node.attrs.anchorData;
			const { size, padding } = node.attrs;
			const pageBreak = findPreviousDomNodeWithClass(view, pos, "pagination-break-wrapper");
			if (pageBreak && vRelativeFrom === "margin" && alignH) {
				let pageBreakPos = pageBreakPositionCache.get(pageBreak);
				if (!pageBreakPos) {
					pageBreakPos = {
						top: pageBreak.offsetTop,
						height: pageBreak.offsetHeight
					};
					pageBreakPositionCache.set(pageBreak, pageBreakPos);
				}
				const topPos = pageBreakPos.top + pageBreakPos.height;
				let horizontalAlignment = `${alignH}: 0;`;
				if (alignH === "center") horizontalAlignment = "left: 50%; transform: translateX(-50%);";
				style += vRelativeFrom === "margin" ? `position: absolute; top: ${topPos}px; ${horizontalAlignment}` : "";
				const nextPos = view.posAtDOM(pageBreak, 1);
				if (nextPos < 0) {
					const $pos = view.state.doc.resolve(pos);
					decorations.push(Decoration.node(pos - 1, pos + $pos.parent.nodeSize - 1, { style: `height: ${size.height + parseInt(padding.top) + parseInt(padding.bottom)}px` }));
				}
				const imageBlock = document.createElement("div");
				imageBlock.className = "anchor-image-placeholder";
				imageBlock.style.float = alignH === "left" || alignH === "right" ? alignH : "none";
				let paddingHorizontal;
				if (alignH === "center") paddingHorizontal = (parseInt(padding.left) || 0) + (parseInt(padding.right) || 0);
				else paddingHorizontal = parseInt(padding[alignH]) || 0;
				imageBlock.style.width = size.width + paddingHorizontal + "px";
				imageBlock.style.height = size.height + parseInt(padding.top) + parseInt(padding.bottom) + "px";
				decorations.push(Decoration.widget(nextPos, imageBlock, { key: "stable-key" }));
				decorations.push(Decoration.inline(pos, pos + node.nodeSize, {
					style,
					class: className
				}));
			}
		}
	});
	return decorations;
};
var findPreviousDomNodeWithClass = (view, pos, className) => {
	if (!(typeof document !== "undefined" && !!(document && document.createElement)) || !view || typeof view.domAtPos !== "function") return null;
	let { node } = view.domAtPos(pos);
	if (node.nodeType === 3) node = node.parentNode;
	while (node) {
		if (node.classList && node.classList.contains(className)) return node;
		if (node.previousSibling) {
			node = node.previousSibling;
			while (node && node.lastChild) node = node.lastChild;
		} else node = node.parentNode;
	}
	return null;
};
const normalizeWrap = (attrs = {}) => {
	const wrap = attrs.wrap;
	if (wrap?.type && wrap.type !== "Inline") return {
		type: wrap.type,
		attrs: wrap.attrs ?? {}
	};
	if (wrap?.type === "Inline" && Object.keys(wrap.attrs ?? {}).length) return {
		type: "Inline",
		attrs: wrap.attrs
	};
	if (!wrap && attrs.wrapText) return {
		type: "Square",
		attrs: { wrapText: attrs.wrapText }
	};
	if (!wrap && attrs.wrapTopAndBottom) return {
		type: "TopAndBottom",
		attrs: {}
	};
	if (wrap?.type === "Inline") return {
		type: "Inline",
		attrs: wrap.attrs ?? {}
	};
	return {
		type: "Inline",
		attrs: {}
	};
};
const normalizeMarginOffset = (marginOffset = {}) => {
	const { left, horizontal, ...rest } = marginOffset;
	return {
		...rest,
		horizontal: horizontal ?? left
	};
};
const getNormalizedImageAttrs = (attrs = {}) => {
	return {
		wrap: normalizeWrap(attrs),
		marginOffset: normalizeMarginOffset(attrs.marginOffset ?? {})
	};
};
const getRotationMargins = (w, h, angleDegrees) => {
	const rad = angleDegrees * (Math.PI / 180);
	const cos = Math.abs(Math.cos(rad));
	const sin = Math.abs(Math.sin(rad));
	const boundingWidth = w * cos + h * sin;
	const boundingHeight = w * sin + h * cos;
	return {
		horizontal: Math.round(Math.max(0, (boundingWidth - w) / 2)),
		vertical: Math.round(Math.max(0, (boundingHeight - h) / 2))
	};
};
var ACCEPT_IMAGE_TYPES = [
	".jpg",
	".jpeg",
	".png",
	"image/jpeg",
	"image/png"
];
const getFileOpener = () => {
	let fileInput = document.createElement("input");
	fileInput.type = "file";
	fileInput.accept = ACCEPT_IMAGE_TYPES.join(",");
	const openFile = () => {
		return new Promise((resolve, reject) => {
			fileInput.onchange = async () => {
				const files = fileInput.files;
				if (!files) return resolve(null);
				const file = files.item(0);
				if (!file) return resolve(null);
				return resolve({ file });
			};
			fileInput.oncancel = () => resolve(null);
			fileInput.onerror = reject;
			fileInput.click();
		});
	};
	return openFile;
};
async function processAndInsertImageFile({ file, editor, view, editorOptions, getMaxContentSize }) {
	const { size, file: processedFile } = await checkAndProcessImage({
		file,
		getMaxContentSize
	});
	if (!processedFile) return "skipped";
	const id = {};
	replaceSelectionWithImagePlaceholder({
		view,
		editorOptions,
		id
	});
	await uploadAndInsertImage({
		editor,
		view,
		file: processedFile,
		size,
		id
	});
	return "success";
}
var FORMATTING_MARK_NAMES = new Set([
	"textStyle",
	"bold",
	"italic",
	"underline",
	"strike",
	"subscript",
	"superscript",
	"highlight"
]);
const getLinkedStyle = (styleId, styles = []) => {
	const linkedStyle = styles.find((style) => style.id === styleId);
	const basedOn = linkedStyle?.definition?.attrs?.basedOn;
	return {
		linkedStyle,
		basedOnStyle: styles.find((style) => style.id === basedOn)
	};
};
const getQuickFormatList = (editor) => {
	if (!editor?.converter?.linkedStyles) return [];
	return editor.converter.linkedStyles.filter((style) => style.type === "paragraph" && style.definition?.attrs).sort((a, b) => {
		const nameA = a.definition.attrs?.name ?? "";
		const nameB = b.definition.attrs?.name ?? "";
		return nameA.localeCompare(nameB);
	});
};
const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, _includeSpacing = true) => {
	if (!linkedStyle?.definition?.styles) return "";
	const markValue = {};
	const linkedDefinitionStyles = { ...linkedStyle.definition.styles };
	const basedOnDefinitionStyles = { ...basedOnStyle?.definition?.styles };
	const resultStyles = { ...linkedDefinitionStyles };
	[
		"font-size",
		"font-family",
		"text-transform",
		"bold",
		"italic",
		"underline",
		"strike",
		"color",
		"highlight"
	].forEach((k) => {
		if (!linkedDefinitionStyles[k] && basedOnDefinitionStyles[k]) resultStyles[k] = basedOnDefinitionStyles[k];
	});
	Object.entries(resultStyles).forEach(([k, value]) => {
		const key$1 = kebabCase(k);
		const flattenedMarks = [];
		node?.marks?.forEach((n) => {
			if (n.type.name === "textStyle") {
				Object.entries(n.attrs).forEach(([styleKey, value$1]) => {
					const parsedKey = kebabCase(styleKey);
					if (!value$1) return;
					flattenedMarks.push({
						key: parsedKey,
						value: value$1
					});
				});
				return;
			}
			flattenedMarks.push({
				key: n.type.name,
				value: n.attrs[key$1]
			});
		});
		if (node?.marks?.some((m) => m.type?.name === "underline" && m.attrs?.underlineType === "none")) markValue["text-decoration"] = "none";
		if (!flattenedMarks.find((n) => n.key === key$1)) {
			if (key$1 === "bold" && node) {
				const boldValue = typeof value === "object" && value !== null ? value.value : value;
				const hasInlineBoldOff = node.marks?.some((m) => m.type?.name === "bold" && m.attrs?.value === "0");
				const hasInlineBoldOn = node.marks?.some((m) => m.type?.name === "bold" && m.attrs?.value !== "0");
				if (!hasInlineBoldOff && !hasInlineBoldOn && boldValue !== "0" && boldValue !== false) markValue["font-weight"] = "bold";
			} else if (key$1 === "italic" && node) {
				const italicValue = typeof value === "object" && value !== null ? value.value : value;
				const hasInlineItalicOff = node.marks?.some((m) => m.type?.name === "italic" && m.attrs?.value === "0");
				const hasInlineItalicOn = node.marks?.some((m) => m.type?.name === "italic" && m.attrs?.value !== "0");
				if (!hasInlineItalicOff && !hasInlineItalicOn && italicValue !== "0" && italicValue !== false) markValue["font-style"] = "italic";
			} else if (key$1 === "strike" && node) {
				const strikeValue = typeof value === "object" && value !== null ? value.value : value;
				const hasInlineStrikeOff = node.marks?.some((m) => m.type?.name === "strike" && m.attrs?.value === "0");
				const hasInlineStrikeOn = node.marks?.some((m) => m.type?.name === "strike" && (m.attrs?.value === void 0 || m.attrs?.value !== "0"));
				if (!hasInlineStrikeOff && !hasInlineStrikeOn && strikeValue !== "0" && strikeValue !== false) markValue["text-decoration"] = "line-through";
			} else if (key$1 === "text-transform" && node) markValue[key$1] = value;
			else if (key$1 === "font-size" && node) markValue[key$1] = value;
			else if (key$1 === "font-family" && node) markValue[key$1] = value;
			else if (key$1 === "color" && node) markValue[key$1] = value;
			else if (key$1 === "highlight" && node) {
				if (!node.marks?.some((m) => m.type?.name === "highlight")) {
					const color = typeof value === "string" ? value : value?.color;
					if (color) markValue["background-color"] = color;
				}
			} else if (key$1 === "underline" && node) {
				const styleVal = (value?.underline ?? value?.underlineType ?? value?.value ?? (typeof value === "string" ? value : "")).toString().toLowerCase();
				const hasInlineUnderlineOff = node.marks?.some((m) => m.type?.name === "underline" && m.attrs?.underlineType === "none");
				const hasInlineUnderlineOn = node.marks?.some((m) => m.type?.name === "underline" && m.attrs?.underlineType && m.attrs.underlineType !== "none");
				if (!hasInlineUnderlineOff && !hasInlineUnderlineOn) {
					if (styleVal && styleVal !== "none" && styleVal !== "0") getUnderlineCssString({
						type: styleVal,
						color: value && typeof value === "object" ? value.color || value.underlineColor || null : null
					}).split(";").forEach((decl) => {
						const d = decl.trim();
						if (!d) return;
						const idx = d.indexOf(":");
						if (idx === -1) return;
						const k$1 = d.slice(0, idx).trim();
						markValue[k$1] = d.slice(idx + 1).trim();
					});
				}
			} else if (typeof value === "string") markValue[key$1] = value;
		}
	});
	return Object.entries(markValue).map(([key$1, value]) => `${key$1}: ${value}`).join(";");
};
var getParagraphTextBounds = (doc, paragraphPos, paragraphNode) => {
	let minPos = null;
	let maxPos = null;
	const innerStart = paragraphPos + 1;
	const innerEnd = paragraphPos + paragraphNode.nodeSize - 1;
	doc.nodesBetween(innerStart, innerEnd, (node, pos) => {
		if (node.isText) {
			if (minPos === null || pos < minPos) minPos = pos;
			maxPos = pos + node.nodeSize;
		}
		return true;
	});
	if (minPos === null || maxPos === null) return null;
	return {
		from: minPos,
		to: maxPos
	};
};
var applyCharacterStyleMarkToRange = (tr, textStyleType, from, to, styleId) => {
	tr.removeMark(from, to, textStyleType);
	tr.addMark(from, to, textStyleType.create({ styleId }));
};
const applyLinkedStyleToTransaction = (tr, editor, style) => {
	if (!style) return false;
	let selection = tr.selection;
	const state = editor.state;
	const textStyleType = editor.schema.marks.textStyle;
	const focusState = CustomSelectionPluginKey.getState(state);
	if (selection.empty && focusState?.preservedSelection && !focusState?.preservedSelection.empty) {
		selection = focusState.preservedSelection;
		tr.setSelection(selection);
	} else if (selection.empty && editor.options.lastSelection) {
		selection = editor.options.lastSelection;
		tr.setSelection(selection);
	}
	const { from, to } = selection;
	const getUpdatedParagraphAttrs = (node) => {
		return {
			...node.attrs,
			paragraphProperties: {
				...node.attrs.paragraphProperties || {},
				styleId: style.id
			}
		};
	};
	const clearFormattingMarks = (rangeFrom, rangeTo) => {
		tr.doc.nodesBetween(rangeFrom, rangeTo, (node, pos) => {
			if (!node.isText || node.marks.length === 0) return true;
			const nodeEnd = pos + node.nodeSize;
			const clearFrom = Math.max(pos, rangeFrom);
			const clearTo = Math.min(nodeEnd, rangeTo);
			if (clearFrom >= clearTo) return true;
			node.marks.forEach((mark) => {
				if (FORMATTING_MARK_NAMES.has(mark.type.name)) tr.removeMark(clearFrom, clearTo, mark);
			});
			return true;
		});
	};
	const clearStoredFormattingMarks = () => {
		const sourceMarks = tr.storedMarks ?? state.storedMarks ?? (selection.empty ? selection.$from.marks() : []);
		if (!sourceMarks?.length) return;
		const nextStoredMarks = sourceMarks.filter((mark) => !FORMATTING_MARK_NAMES.has(mark.type.name));
		if (nextStoredMarks.length !== sourceMarks.length) tr.setStoredMarks(nextStoredMarks);
	};
	if (style.type === "character") {
		if (!textStyleType) return false;
		if (from === to) {
			const filtered = (tr.storedMarks ?? state.storedMarks ?? selection.$from.marks()).filter((mark) => mark.type !== textStyleType);
			tr.setStoredMarks([...filtered, textStyleType.create({ styleId: style.id })]);
			return true;
		}
		clearFormattingMarks(from, to);
		applyCharacterStyleMarkToRange(tr, textStyleType, from, to, style.id);
		clearStoredFormattingMarks();
		return true;
	}
	if (from === to) {
		let pos = from;
		let paragraphNode = tr.doc.nodeAt(from);
		if (paragraphNode?.type.name !== "paragraph") {
			const parentNode = findParentNode((node) => node.type.name === "paragraph")(selection);
			if (!parentNode) return false;
			pos = parentNode.pos;
			paragraphNode = parentNode.node;
		}
		clearFormattingMarks(pos + 1, pos + paragraphNode.nodeSize - 1);
		clearStoredFormattingMarks();
		tr.setNodeMarkup(pos, void 0, getUpdatedParagraphAttrs(paragraphNode));
		return true;
	}
	if (style.type === "paragraph" && textStyleType) {
		const linkedCharStyleId = style.definition?.attrs?.link;
		if (linkedCharStyleId) {
			const $fromPos = tr.doc.resolve(from);
			const $toPos = tr.doc.resolve(to);
			const startPara = findParentNodeClosestToPos($fromPos, (n) => n.type.name === "paragraph");
			const endPara = findParentNodeClosestToPos($toPos, (n) => n.type.name === "paragraph");
			if (startPara && endPara && startPara.pos === endPara.pos) {
				const bounds = getParagraphTextBounds(tr.doc, startPara.pos, startPara.node);
				const coversFullParagraphText = bounds && from <= bounds.from && to >= bounds.to;
				if (bounds && !coversFullParagraphText) {
					clearFormattingMarks(from, to);
					applyCharacterStyleMarkToRange(tr, textStyleType, from, to, linkedCharStyleId);
					clearStoredFormattingMarks();
					return true;
				}
			}
		}
	}
	const paragraphPositions = [];
	tr.doc.nodesBetween(from, to, (node, pos) => {
		if (node.type.name === "paragraph") paragraphPositions.push({
			node,
			pos
		});
		return true;
	});
	if (paragraphPositions.length === 0 && from !== to) {
		const seen = /* @__PURE__ */ new Set();
		const pushParagraph = (info) => {
			if (!info || seen.has(info.pos)) return;
			seen.add(info.pos);
			paragraphPositions.push({
				node: info.node,
				pos: info.pos
			});
		};
		pushParagraph(findParentNodeClosestToPos(tr.doc.resolve(from), (n) => n.type.name === "paragraph"));
		pushParagraph(findParentNodeClosestToPos(tr.doc.resolve(to), (n) => n.type.name === "paragraph"));
	}
	paragraphPositions.forEach(({ node, pos }) => {
		clearFormattingMarks(pos + 1, pos + node.nodeSize - 1);
		tr.setNodeMarkup(pos, void 0, getUpdatedParagraphAttrs(node));
	});
	clearStoredFormattingMarks();
	return true;
};
const stepInsertsTextIntoStyledParagraph = (tr, oldEditorState, step, stepIndex) => {
	if (!step.slice || step.slice.size === 0 || typeof step.from !== "number") return false;
	let insertsText = false;
	step.slice.content.descendants((node) => {
		if (node.type?.name === "text" && node.text?.length) {
			insertsText = true;
			return false;
		}
		return true;
	});
	if (!insertsText) return false;
	const docBeforeStep = tr.docs?.[stepIndex] || oldEditorState.doc;
	if (!docBeforeStep) return false;
	const resolvedPos = Math.min(step.from, docBeforeStep.content.size);
	const $pos = docBeforeStep.resolve(resolvedPos);
	for (let depth = $pos.depth; depth >= 0; depth--) {
		const node = $pos.node(depth);
		if (node?.type?.name === "paragraph") return Boolean(node.attrs?.paragraphProperties?.styleId);
	}
	return false;
};
const LinkedStylesPluginKey = new PluginKey("linkedStyles");
const createLinkedStylesPlugin = (editor) => {
	return new Plugin({
		key: LinkedStylesPluginKey,
		state: {
			init() {
				if (!editor.converter || editor.options.mode !== "docx") return {};
				if (editor.presentationEditor) return {
					styles: editor.converter?.linkedStyles || [],
					decorations: DecorationSet.empty
				};
				const styles = editor.converter?.linkedStyles || [];
				return {
					styles,
					decorations: generateDecorations(editor.state, styles)
				};
			},
			apply(tr, prev, oldEditorState, newEditorState) {
				if (!editor.converter || editor.options.mode !== "docx") return { ...prev };
				if (editor.presentationEditor) return {
					...prev,
					decorations: DecorationSet.empty
				};
				let decorations = prev.decorations || DecorationSet.empty;
				if (tr.docChanged) {
					let mightAffectStyles = false;
					const styleRelatedMarks = new Set([
						"textStyle",
						"bold",
						"italic",
						"underline",
						"strike"
					]);
					tr.steps.forEach((step, index) => {
						if (step.slice) step.slice.content.descendants((node, pos) => {
							if (node.type.name === "paragraph") {
								if (calculateResolvedParagraphProperties(editor, node, newEditorState.doc.resolve(pos)).styleId) mightAffectStyles = true;
								return false;
							}
							if (node.marks.length > 0) {
								if (node.marks.some((mark) => styleRelatedMarks.has(mark.type.name))) {
									mightAffectStyles = true;
									return false;
								}
							}
						});
						if (step.jsonID === "addMark" || step.jsonID === "removeMark") {
							if (step.mark && styleRelatedMarks.has(step.mark.type.name)) mightAffectStyles = true;
						}
						if (!mightAffectStyles && stepInsertsTextIntoStyledParagraph(tr, oldEditorState, step, index)) mightAffectStyles = true;
					});
					if (mightAffectStyles) {
						const styles = LinkedStylesPluginKey.getState(editor.state).styles;
						decorations = generateDecorations(newEditorState, styles);
					} else decorations = decorations.map(tr.mapping, tr.doc);
				}
				return {
					...prev,
					decorations
				};
			}
		},
		props: { decorations(state) {
			return LinkedStylesPluginKey.getState(state)?.decorations;
		} }
	});
};
var generateDecorations = (state, styles) => {
	const decorations = [];
	const doc = state?.doc;
	if (!doc || !state) return DecorationSet.empty;
	const getParagraphStyleId = (pos) => {
		const $pos = state.doc.resolve(pos);
		for (let d = $pos.depth; d >= 0; d--) {
			const n = $pos.node(d);
			if (n?.type?.name === "paragraph") return getResolvedParagraphProperties(n).styleId || null;
		}
		return null;
	};
	doc.descendants((node, pos) => {
		const { name } = node.type;
		if (name !== "text") return;
		const paragraphStyleId = getParagraphStyleId(pos);
		let runStyleId = null;
		let inlineTextStyleId = null;
		for (const mark of node.marks) if (mark.type.name === "run") {
			const rp = mark.attrs?.runProperties;
			if (rp && typeof rp === "object" && !Array.isArray(rp) && rp.styleId) runStyleId = rp.styleId;
			else if (Array.isArray(rp)) {
				const sid = rp.find((e) => e?.xmlName === "w:rStyle")?.attributes?.["w:val"];
				if (sid) runStyleId = sid;
			}
		} else if (mark.type.name === "textStyle" && mark.attrs?.styleId) inlineTextStyleId = mark.attrs.styleId;
		const buildStyleMap = (sid) => {
			if (!sid) return {};
			const { linkedStyle, basedOnStyle: basedOnStyle$1 } = getLinkedStyle(sid, styles);
			if (!linkedStyle) return {};
			return {
				...basedOnStyle$1?.definition?.styles || {},
				...linkedStyle.definition?.styles || {}
			};
		};
		const pMap = buildStyleMap(paragraphStyleId);
		let tMap;
		if (paragraphStyleId?.startsWith("TOC")) tMap = {};
		else tMap = buildStyleMap(inlineTextStyleId);
		const rMap = buildStyleMap(runStyleId);
		const finalStyles = {
			...pMap,
			...tMap,
			...rMap
		};
		if (Object.keys(finalStyles).length === 0) return;
		const mergedLinkedStyle = { definition: {
			styles: finalStyles,
			attrs: {}
		} };
		const basedOnStyle = null;
		const parent = state.doc.resolve(pos).parent;
		const styleString = generateLinkedStyleString(mergedLinkedStyle, basedOnStyle, node, parent);
		if (!styleString) return;
		const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
		decorations.push(decoration);
	});
	return DecorationSet.create(doc, decorations);
};
const LinkedStyles = Extension.create({
	name: "linkedStyles",
	priority: 1,
	addOptions() {
		return {};
	},
	addPmPlugins() {
		return [createLinkedStylesPlugin(this.editor)];
	},
	addCommands() {
		return {
			setLinkedStyle: (style) => (params) => {
				const { tr } = params;
				return applyLinkedStyleToTransaction(tr, this.editor, style);
			},
			toggleLinkedStyle: (style) => (params) => {
				const { tr } = params;
				let node = tr.doc.nodeAt(tr.selection.$from.pos);
				if (!node || node.type.name !== "paragraph") node = findParentNodeClosestToPos(tr.selection.$from, (n) => {
					return n.type.name === "paragraph";
				})?.node;
				if (!node) return false;
				if (getResolvedParagraphProperties(node).styleId === style.id) return applyLinkedStyleToTransaction(tr, this.editor, { id: null });
				return applyLinkedStyleToTransaction(tr, this.editor, style);
			},
			setStyleById: (styleId) => (params) => {
				const { state, tr } = params;
				const pluginState = LinkedStylesPluginKey.getState(state);
				if (!pluginState) return false;
				const style = pluginState.styles?.find((s) => s.id === styleId);
				if (!style) return false;
				return applyLinkedStyleToTransaction(tr, this.editor, style);
			}
		};
	},
	addHelpers() {
		return {
			getStyles: () => {
				return LinkedStylesPluginKey.getState(this.editor.state)?.styles || [];
			},
			getStyleById: (styleId) => {
				return this.editor.helpers[this.name].getStyles().find((s) => s.id === styleId);
			},
			getLinkedStyleString: (styleId) => {
				const style = this.editor.helpers.linkedStyles.getStyles().find((s) => s.id === styleId);
				if (!style) return "";
				return generateLinkedStyleString(style);
			}
		};
	}
});
var PERMISSION_MAP = {
	accept: {
		own: "RESOLVE_OWN",
		other: "RESOLVE_OTHER"
	},
	reject: {
		own: "REJECT_OWN",
		other: "REJECT_OTHER"
	}
};
var buildKey = (change) => {
	return `${change.mark?.attrs?.id ?? `${change.from}-${change.to}`}:${change.mark?.type?.name ?? "unknown"}`;
};
var mergeChange = (bucket, change) => {
	const key$1 = buildKey(change);
	const existing = bucket.get(key$1);
	if (existing) {
		existing.from = Math.min(existing.from, change.from);
		existing.to = Math.max(existing.to, change.to);
		existing.segments.push({
			from: change.from,
			to: change.to
		});
	} else bucket.set(key$1, {
		id: change.mark?.attrs?.id ?? null,
		type: change.mark?.type?.name ?? null,
		attrs: { ...change.mark?.attrs ?? {} },
		from: change.from,
		to: change.to,
		segments: [{
			from: change.from,
			to: change.to
		}]
	});
};
const collectTrackedChanges = ({ state, from, to }) => {
	if (!state) return [];
	const collapsed = from === to;
	const changes = getTrackChanges(state);
	if (!changes?.length) return [];
	const bucket = /* @__PURE__ */ new Map();
	changes.forEach((change) => {
		if (!(collapsed ? change.from <= from && change.to >= from : change.from < to && change.to > from)) return;
		mergeChange(bucket, change);
	});
	return Array.from(bucket.values());
};
var derivePermissionKey = ({ action, isOwn }) => {
	const mapping = PERMISSION_MAP[action];
	if (!mapping) return null;
	return isOwn ? mapping.own : mapping.other;
};
var normalizeEmail = (value) => {
	if (typeof value !== "string") return "";
	return value.trim().toLowerCase();
};
var resolveChanges = (editor) => {
	if (!editor) return {
		role: "editor",
		isInternal: false,
		currentUser: null,
		resolver: null
	};
	return {
		role: editor.options?.role ?? "editor",
		isInternal: Boolean(editor.options?.isInternal),
		currentUser: editor.options?.user ?? null,
		resolver: editor.options?.permissionResolver
	};
};
const isTrackedChangeActionAllowed = ({ editor, action, trackedChanges }) => {
	if (!trackedChanges?.length) return true;
	const { role, isInternal, currentUser, resolver } = resolveChanges(editor);
	if (typeof resolver !== "function") return true;
	const currentEmail = normalizeEmail(currentUser?.email);
	return trackedChanges.every((change) => {
		const authorEmail = normalizeEmail(change.attrs?.authorEmail);
		const permission = derivePermissionKey({
			action,
			isOwn: !currentEmail || !authorEmail || currentEmail === authorEmail
		});
		if (!permission) return true;
		return resolver({
			permission,
			role,
			isInternal,
			trackedChange: {
				id: change.id,
				type: change.type,
				attrs: change.attrs,
				from: change.from,
				to: change.to,
				segments: change.segments,
				commentId: change.id
			},
			comment: change.comment ?? null
		}) !== false;
	});
};
const collectTrackedChangesForContext = ({ state, pos, trackedChangeId }) => {
	if (pos == null) return [];
	const changes = collectTrackedChanges({
		state,
		from: pos,
		to: pos
	});
	if (!trackedChangeId) return changes;
	return changes.filter((change) => change.id === trackedChangeId);
};
var resolveSurfaceFromDocumentId = (documentId) => {
	if (typeof documentId !== "string" || documentId.length === 0) return "body";
	if (documentId.startsWith("footnote:") || documentId.startsWith("fn:")) return "note";
	if (documentId.startsWith("endnote:") || documentId.startsWith("en:")) return "endnote";
	return "body";
};
var resolveSurface = (activeEditor) => {
	if (activeEditor?.options?.isHeaderOrFooter) {
		const headerFooterType = activeEditor.options?.headerFooterType;
		if (headerFooterType === "footer") return "footer";
		if (headerFooterType === "header") return "header";
	}
	return resolveSurfaceFromDocumentId(activeEditor?.options?.documentId);
};
var resolveSelectionEmpty = (editor) => {
	return (editor.state?.selection)?.empty ?? true;
};
var createEditorToolbarTarget = (editor) => {
	return {
		commands: editor.commands ?? {},
		doc: editor.doc
	};
};
var createPresentationToolbarTarget = (editor) => {
	return {
		commands: editor.commands ?? {},
		doc: editor.getActiveEditor()?.doc
	};
};
var resolvePresentationEditor = (superdoc) => {
	const activeEditor = superdoc.activeEditor ?? null;
	const directPresentationEditor = activeEditor?.presentationEditor ?? activeEditor?._presentationEditor ?? null;
	if (directPresentationEditor) return directPresentationEditor;
	const documentId = activeEditor?.options?.documentId;
	if (!documentId) return null;
	return (superdoc.superdocStore?.documents ?? []).find((doc) => doc.getEditor?.()?.options?.documentId === documentId)?.getPresentationEditor?.() ?? null;
};
const resolveToolbarSources = (superdoc) => {
	const presentationEditor = resolvePresentationEditor(superdoc);
	if (presentationEditor) {
		const routedEditor = presentationEditor.getActiveEditor();
		return {
			activeEditor: routedEditor ?? null,
			presentationEditor,
			context: {
				target: createPresentationToolbarTarget(presentationEditor),
				surface: resolveSurface(routedEditor),
				isEditable: presentationEditor.isEditable,
				selectionEmpty: resolveSelectionEmpty(presentationEditor),
				editor: routedEditor ?? void 0,
				presentationEditor
			}
		};
	}
	const activeEditor = superdoc.activeEditor;
	if (!activeEditor) return {
		activeEditor: null,
		presentationEditor: null,
		context: null
	};
	return {
		activeEditor,
		presentationEditor: null,
		context: {
			target: createEditorToolbarTarget(activeEditor),
			surface: "body",
			isEditable: activeEditor.isEditable,
			selectionEmpty: resolveSelectionEmpty(activeEditor),
			editor: activeEditor
		}
	};
};
var buildCommandStateMap = ({ commands = [], superdoc, context, toolbarRegistry }) => {
	const entries = commands.map((command) => {
		const entry = toolbarRegistry[command];
		if (!entry) return [command, {
			active: false,
			disabled: true
		}];
		try {
			return [command, entry.state({
				context,
				superdoc
			})];
		} catch {
			return [command, {
				active: false,
				disabled: true
			}];
		}
	});
	return Object.fromEntries(entries);
};
const createToolbarSnapshot = ({ superdoc, commands = [], toolbarRegistry }) => {
	const { context } = resolveToolbarSources(superdoc);
	return {
		context,
		commands: buildCommandStateMap({
			commands,
			superdoc,
			context,
			toolbarRegistry
		})
	};
};
var subscribeToSuperdocEvents = (superdoc, onChange) => {
	if (!superdoc?.on || !superdoc?.off) return null;
	superdoc.on("editorCreate", onChange);
	superdoc.on("document-mode-change", onChange);
	superdoc.on("zoomChange", onChange);
	return () => {
		superdoc.off?.("editorCreate", onChange);
		superdoc.off?.("document-mode-change", onChange);
		superdoc.off?.("zoomChange", onChange);
	};
};
var subscribeToEditorEvents = (editor, onChange) => {
	if (!editor?.on || !editor?.off) return null;
	editor.on("focus", onChange);
	editor.on("selectionUpdate", onChange);
	editor.on("transaction", onChange);
	return () => {
		editor.off?.("focus", onChange);
		editor.off?.("selectionUpdate", onChange);
		editor.off?.("transaction", onChange);
	};
};
var subscribeToPresentationEvents = (presentationEditor, onChange) => {
	if (!presentationEditor?.on || !presentationEditor?.off) return null;
	presentationEditor.on("headerFooterEditingContext", onChange);
	presentationEditor.on("headerFooterUpdate", onChange);
	presentationEditor.on("headerFooterTransaction", onChange);
	presentationEditor.on("activeSurfaceChange", onChange);
	presentationEditor.on("historyStateChange", onChange);
	return () => {
		presentationEditor.off?.("headerFooterEditingContext", onChange);
		presentationEditor.off?.("headerFooterUpdate", onChange);
		presentationEditor.off?.("headerFooterTransaction", onChange);
		presentationEditor.off?.("activeSurfaceChange", onChange);
		presentationEditor.off?.("historyStateChange", onChange);
	};
};
const subscribeToolbarEvents = (options, onChange) => {
	const { activeEditor: editor, presentationEditor } = resolveToolbarSources(options.superdoc);
	const unbindSuperdocEvents = subscribeToSuperdocEvents(options.superdoc, onChange);
	const unbindEditorEvents = subscribeToEditorEvents(editor, onChange);
	const unbindPresentationEvents = subscribeToPresentationEvents(presentationEditor, onChange);
	return () => {
		unbindEditorEvents?.();
		unbindPresentationEvents?.();
		unbindSuperdocEvents?.();
	};
};
const resolveStateEditor = (context) => {
	if (!context) return null;
	return context.editor ?? context.presentationEditor?.getActiveEditor() ?? null;
};
const getCurrentParagraphParent = (context) => {
	const stateEditor = resolveStateEditor(context);
	const selection = stateEditor?.state?.selection;
	if (!stateEditor || !selection) return null;
	return findParentNode((node) => node.type.name === "paragraph")(selection);
};
const getCurrentResolvedParagraphProperties = (context) => {
	const paragraphParent = getCurrentParagraphParent(context);
	const stateEditor = resolveStateEditor(context);
	if (!stateEditor || !paragraphParent) return null;
	return calculateResolvedParagraphProperties(stateEditor, paragraphParent.node, stateEditor.state.doc.resolve(paragraphParent.pos));
};
const isFieldAnnotationSelection = (context) => {
	const selection = resolveStateEditor(context)?.state?.selection;
	return selection instanceof NodeSelection && selection?.node?.type?.name === "fieldAnnotation";
};
const isCommandDisabled = (context) => {
	if (!context || !context.isEditable) return true;
	return (context.presentationEditor?.editor ?? context.editor)?.options?.documentMode === "viewing";
};
const createDisabledStateDeriver = (options) => ({ context }) => {
	const disabled = isCommandDisabled(context);
	if (options?.withValue) return {
		active: false,
		disabled,
		value: null
	};
	return {
		active: false,
		disabled
	};
};
const createDirectCommandExecute = (commandName) => ({ context, payload }) => {
	const editor = resolveStateEditor(context);
	const command = commandName ? editor?.commands[commandName] : null;
	if (typeof command !== "function") return false;
	const result = payload === void 0 ? command() : command(payload);
	return Boolean(result);
};
var readCoordinatorDepths = (context) => {
	const state = context?.presentationEditor?.getHistoryState?.();
	if (!state) return null;
	return {
		undoDepth: state.undoDepth,
		redoDepth: state.redoDepth
	};
};
const getCurrentUndoDepth = (context) => {
	const coordinatorDepths = readCoordinatorDepths(context);
	if (coordinatorDepths) return coordinatorDepths.undoDepth;
	const stateEditor = resolveStateEditor(context);
	if (!stateEditor?.state) return 0;
	try {
		if (stateEditor.options?.ydoc) return (yUndoPluginKey.getState(stateEditor.state)?.undoManager)?.undoStack?.length ?? 0;
		return undoDepth(stateEditor.state);
	} catch {
		return 0;
	}
};
const getCurrentRedoDepth = (context) => {
	const coordinatorDepths = readCoordinatorDepths(context);
	if (coordinatorDepths) return coordinatorDepths.redoDepth;
	const stateEditor = resolveStateEditor(context);
	if (!stateEditor?.state) return 0;
	try {
		if (stateEditor.options?.ydoc) return (yUndoPluginKey.getState(stateEditor.state)?.undoManager)?.redoStack?.length ?? 0;
		return redoDepth(stateEditor.state);
	} catch {
		return 0;
	}
};
const createHistoryStateDeriver = (kind) => ({ context }) => {
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true
	};
	return {
		active: false,
		disabled: (kind === "undo" ? getCurrentUndoDepth(context) : getCurrentRedoDepth(context)) === 0
	};
};
const createRulerStateDeriver = () => ({ context, superdoc }) => {
	return {
		active: Boolean(superdoc?.config?.rulers),
		disabled: isCommandDisabled(context)
	};
};
const createZoomStateDeriver = () => ({ context, superdoc }) => {
	return {
		active: false,
		disabled: !context,
		value: typeof superdoc?.getZoom === "function" ? superdoc.getZoom() : 100
	};
};
const createDocumentModeStateDeriver = () => ({ context, superdoc }) => {
	return {
		active: false,
		disabled: !context,
		value: superdoc?.config?.documentMode ?? "editing"
	};
};
const createRulerExecute = () => ({ superdoc }) => {
	superdoc.toggleRuler?.();
	return true;
};
const createZoomExecute = () => ({ superdoc, payload }) => {
	const normalizedPayload = Number.parseInt(String(payload), 10);
	if (!Number.isFinite(normalizedPayload) || normalizedPayload <= 0) return false;
	superdoc.setZoom?.(normalizedPayload);
	return true;
};
const createDocumentModeExecute = () => ({ superdoc, payload }) => {
	const validModes = [
		"editing",
		"suggesting",
		"viewing"
	];
	const normalizedPayload = typeof payload === "string" ? payload.toLowerCase() : payload;
	if (typeof superdoc?.setDocumentMode !== "function" || typeof normalizedPayload !== "string" || !validModes.includes(normalizedPayload)) return false;
	superdoc.setDocumentMode(normalizedPayload);
	return true;
};
const isOffValue = (value) => {
	if (value == null) return false;
	const normalized = String(value).toLowerCase();
	return normalized === "0" || normalized === "false" || normalized === "off";
};
const negationChecks = {
	bold: (attrs = {}) => isOffValue(attrs.value),
	italic: (attrs = {}) => isOffValue(attrs.value),
	strike: (attrs = {}) => isOffValue(attrs.value),
	underline: (attrs = {}) => {
		const type = attrs.underlineType ?? attrs.value;
		if (type == null) return false;
		const normalized = String(type).toLowerCase();
		return normalized === "none" || isOffValue(normalized);
	},
	color: (attrs = {}) => {
		const value = attrs.color;
		if (value == null) return true;
		return String(value).toLowerCase() === "inherit";
	},
	highlight: (attrs = {}) => {
		const value = attrs.color;
		if (value == null) return true;
		const normalized = String(value).toLowerCase();
		return normalized === "transparent" || normalized === "none";
	}
};
const isNegatedMark = (name, attrs = {}) => {
	const checker = negationChecks[name];
	if (typeof checker !== "function") return false;
	return Boolean(checker(attrs));
};
const normalizeFontSizeValue = (value) => {
	if (typeof value === "number") return `${value}pt`;
	if (typeof value === "string") {
		const [numericValue, unit] = parseSizeUnit(value);
		if (!Number.isNaN(numericValue)) return `${numericValue}${unit || "pt"}`;
	}
	return value;
};
const normalizeFontFamilyValue = (value) => {
	if (typeof value !== "string") return value;
	return value;
};
const normalizeLinkHrefValue = (value) => {
	return typeof value === "string" && value.length > 0 ? value : null;
};
const normalizeColorValue = (value) => {
	if (typeof value === "string" && value.length > 0) return value.toLowerCase();
	return null;
};
const isFormattingActivatedFromLinkedStyle = (context, styleKey) => {
	const stateEditor = resolveStateEditor(context);
	if (!(stateEditor?.state?.selection)?.$from) return false;
	const styleId = getCurrentResolvedParagraphProperties(context)?.styleId;
	const linkedStyle = stateEditor?.converter?.linkedStyles?.find((style) => style.id === styleId);
	return Boolean(linkedStyle?.definition?.styles && styleKey in linkedStyle.definition.styles);
};
const hasNegatedFormattingMark = (formatting, markName) => {
	const rawActiveMark = formatting.find((mark) => mark.name === markName);
	return rawActiveMark ? isNegatedMark(rawActiveMark.name, rawActiveMark.attrs) : false;
};
const createBoldStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true
	};
	const isActiveFromMark = formatting.some((mark) => mark.name === "bold");
	const markNegated = hasNegatedFormattingMark(formatting, "bold");
	const activeFromLinkedStyle = !isActiveFromMark && !markNegated ? isFormattingActivatedFromLinkedStyle(context, "bold") : false;
	return {
		active: isActiveFromMark || activeFromLinkedStyle,
		disabled: false
	};
};
const createItalicStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true
	};
	return {
		active: !hasNegatedFormattingMark(formatting, "italic") && formatting.some((mark) => mark.name === "italic"),
		disabled: false
	};
};
const createUnderlineStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true
	};
	return {
		active: !hasNegatedFormattingMark(formatting, "underline") && formatting.some((mark) => mark.name === "underline"),
		disabled: false
	};
};
const createStrikethroughStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true
	};
	return {
		active: !hasNegatedFormattingMark(formatting, "strike") && formatting.some((mark) => mark.name === "strike"),
		disabled: false
	};
};
const createFontSizeStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true,
		value: null
	};
	const normalizedValues = formatting.filter((mark) => mark.name === "fontSize").map((mark) => mark.attrs?.fontSize).filter((value$1) => value$1 != null).map((value$1) => normalizeFontSizeValue(value$1));
	const uniqueValues = [...new Set(normalizedValues)];
	const hasDirectValue = uniqueValues.length > 0;
	const canUseLinkedStyle = !hasDirectValue && isFormattingActivatedFromLinkedStyle(context, "font-size");
	const paragraphProps = canUseLinkedStyle ? getCurrentResolvedParagraphProperties(context) : null;
	const documentEditor = context?.presentationEditor?.editor ?? context?.editor ?? null;
	const linkedStyleValue = normalizeFontSizeValue((canUseLinkedStyle ? documentEditor?.converter?.linkedStyles?.find((style) => style.id === paragraphProps?.styleId) : null)?.definition?.styles?.["font-size"]) ?? null;
	const value = uniqueValues.length === 1 ? uniqueValues[0] : linkedStyleValue;
	return {
		active: hasDirectValue || linkedStyleValue != null,
		disabled: false,
		value
	};
};
const createFontFamilyStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true,
		value: null
	};
	const normalizedValues = formatting.filter((mark) => mark.name === "fontFamily").map((mark) => mark.attrs?.fontFamily).filter((value$1) => value$1 != null).map((value$1) => normalizeFontFamilyValue(value$1));
	const uniqueValues = [...new Set(normalizedValues)];
	const canUseLinkedStyle = !(uniqueValues.length > 0) && isFormattingActivatedFromLinkedStyle(context, "font-family");
	const paragraphProps = canUseLinkedStyle ? getCurrentResolvedParagraphProperties(context) : null;
	const documentEditor = context?.presentationEditor?.editor ?? context?.editor ?? null;
	const linkedStyleValue = normalizeFontFamilyValue((canUseLinkedStyle ? documentEditor?.converter?.linkedStyles?.find((style) => style.id === paragraphProps?.styleId) : null)?.definition?.styles?.["font-family"]) ?? null;
	const value = uniqueValues.length === 1 ? uniqueValues[0] : linkedStyleValue;
	return {
		active: uniqueValues.length > 0 || linkedStyleValue != null,
		disabled: false,
		value
	};
};
const createTextColorStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true,
		value: null
	};
	const values = formatting.filter((mark) => mark.name === "color").map((mark) => mark.attrs?.color).filter((value$1) => value$1 != null);
	const markNegated = hasNegatedFormattingMark(formatting, "color");
	const normalizedValues = values.map((value$1) => normalizeColorValue(value$1));
	const uniqueValues = [...new Set(normalizedValues)];
	const value = uniqueValues.length === 1 ? uniqueValues[0] : null;
	return {
		active: !markNegated && uniqueValues.length > 0,
		disabled: false,
		value
	};
};
const createHighlightColorStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true,
		value: null
	};
	const values = formatting.filter((mark) => mark.name === "highlight").map((mark) => mark.attrs?.color).filter((value$1) => value$1 != null);
	const markNegated = hasNegatedFormattingMark(formatting, "highlight");
	const normalizedValues = values.map((value$1) => normalizeColorValue(value$1));
	const uniqueValues = [...new Set(normalizedValues)];
	const value = uniqueValues.length === 1 ? uniqueValues[0] : null;
	return {
		active: !markNegated && uniqueValues.length > 0,
		disabled: false,
		value
	};
};
const createLinkStateDeriver = () => ({ context }) => {
	const stateEditor = resolveStateEditor(context);
	const formatting = stateEditor ? getActiveFormatting(stateEditor) : [];
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true,
		value: null
	};
	const normalizedValues = formatting.filter((mark) => mark.name === "link").map((mark) => mark.attrs?.href).filter((value$1) => value$1 != null).map((value$1) => normalizeLinkHrefValue(value$1));
	const uniqueValues = [...new Set(normalizedValues)];
	const value = uniqueValues.length === 1 ? uniqueValues[0] : null;
	return {
		active: uniqueValues.length > 0,
		disabled: false,
		value
	};
};
const createBoldExecute = () => ({ context, payload }) => {
	const editor = resolveStateEditor(context);
	if (isFieldAnnotationSelection(context)) {
		editor?.commands?.toggleFieldAnnotationsFormat?.("bold", true);
		return true;
	}
	if (!createDirectCommandExecute("toggleBold")({
		context,
		payload
	})) return false;
	editor?.commands?.toggleFieldAnnotationsFormat?.("bold", true);
	return true;
};
const createItalicExecute = () => ({ context, payload }) => {
	const editor = resolveStateEditor(context);
	if (isFieldAnnotationSelection(context)) {
		editor?.commands?.toggleFieldAnnotationsFormat?.("italic", true);
		return true;
	}
	if (!createDirectCommandExecute("toggleItalic")({
		context,
		payload
	})) return false;
	editor?.commands?.toggleFieldAnnotationsFormat?.("italic", true);
	return true;
};
const createUnderlineExecute = () => ({ context, payload }) => {
	const editor = resolveStateEditor(context);
	if (isFieldAnnotationSelection(context)) {
		editor?.commands?.toggleFieldAnnotationsFormat?.("underline", true);
		return true;
	}
	if (!createDirectCommandExecute("toggleUnderline")({
		context,
		payload
	})) return false;
	editor?.commands?.toggleFieldAnnotationsFormat?.("underline", true);
	return true;
};
const createFontSizeExecute = () => ({ context, payload }) => {
	if (payload === void 0) return false;
	const editor = resolveStateEditor(context);
	if (isFieldAnnotationSelection(context)) {
		editor?.commands?.setFieldAnnotationsFontSize?.(payload, true);
		return true;
	}
	if (!createDirectCommandExecute("setFontSize")({
		context,
		payload
	})) return false;
	editor?.commands?.setFieldAnnotationsFontSize?.(payload, true);
	return true;
};
const createFontFamilyExecute = () => ({ context, payload }) => {
	if (payload === void 0) return false;
	const editor = resolveStateEditor(context);
	if (isFieldAnnotationSelection(context)) {
		editor?.commands?.setFieldAnnotationsFontFamily?.(payload, true);
		return true;
	}
	if (!createDirectCommandExecute("setFontFamily")({
		context,
		payload
	})) return false;
	editor?.commands?.setFieldAnnotationsFontFamily?.(payload, true);
	return true;
};
const createTextColorExecute = () => ({ context, payload }) => {
	const editor = resolveStateEditor(context);
	if (typeof payload !== "string" || payload.length === 0) return false;
	const isNone = payload === "none";
	const inlineValue = isNone ? "inherit" : payload;
	const result = createDirectCommandExecute("setColor")({
		context,
		payload: inlineValue
	});
	editor?.commands?.setFieldAnnotationsTextColor?.(isNone ? null : payload, true);
	return result;
};
const createHighlightColorExecute = () => ({ context, payload }) => {
	const editor = resolveStateEditor(context);
	if (typeof payload !== "string" || payload.length === 0) return false;
	const isNone = payload === "none";
	const inlineValue = isNone ? "transparent" : payload;
	const result = createDirectCommandExecute("setHighlight")({
		context,
		payload: inlineValue
	});
	const argValue = isNone ? null : payload;
	editor?.commands?.setFieldAnnotationsTextHighlight?.(argValue, true);
	editor?.commands?.setCellBackground?.(argValue);
	return result;
};
var applyLinkPostExecute = (editor) => {
	const { view } = editor;
	let selection = view.state.selection;
	if (editor.options?.isHeaderOrFooter && editor.options?.lastSelection) selection = editor.options.lastSelection;
	const endPos = selection?.$to?.pos;
	if (typeof endPos !== "number") return;
	try {
		const newSelection = new TextSelection(view.state.doc.resolve(endPos));
		const tr = view.state.tr.setSelection(newSelection);
		const state = view.state.apply(tr);
		view.updateState(state);
		if (!editor.options?.isHeaderOrFooter) setTimeout(() => {
			view.focus();
		}, 100);
	} catch {
		return;
	}
};
const createLinkExecute = () => ({ context, payload }) => {
	const editor = resolveStateEditor(context);
	const result = createDirectCommandExecute("toggleLink")({
		context,
		payload
	});
	if (!result || !editor?.view) return result;
	applyLinkPostExecute(editor);
	return true;
};
const createImageExecute = () => ({ context }) => {
	const editor = resolveStateEditor(context);
	if (!editor?.view) return false;
	getFileOpener()().then(async (result) => {
		if (!result?.file) return;
		await processAndInsertImageFile({
			file: result.file,
			editor,
			view: editor.view,
			editorOptions: editor.options,
			getMaxContentSize: () => editor.getMaxContentSize()
		});
	}).catch((err) => {
		const originalError = err instanceof Error ? err : new Error(String(err));
		const error = /* @__PURE__ */ new Error(`[headless-toolbar] Image insertion failed: ${originalError.message}`);
		editor?.emit?.("exception", {
			error,
			editor
		});
		console.error(error, originalError);
	});
	return true;
};
var getCurrentParagraphJustification = (context) => {
	const justification = getCurrentResolvedParagraphProperties(context)?.justification ?? null;
	if (justification === "both") return "justify";
	return justification;
};
const createTextAlignStateDeriver = () => ({ context }) => {
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true,
		value: null
	};
	const value = getCurrentParagraphJustification(context) ?? null;
	return {
		active: value != null,
		disabled: false,
		value
	};
};
const createLineHeightStateDeriver = () => ({ context }) => {
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true,
		value: null
	};
	const line = getCurrentResolvedParagraphProperties(context)?.spacing?.line;
	const value = line != null ? twipsToLines(line) : null;
	return {
		active: value != null,
		disabled: false,
		value
	};
};
const createLinkedStyleStateDeriver = () => ({ context }) => {
	const isDisabled = isCommandDisabled(context);
	const stateEditor = resolveStateEditor(context);
	if (isDisabled || !stateEditor) return {
		active: false,
		disabled: true,
		value: null
	};
	if (!getQuickFormatList(stateEditor).length) return {
		active: false,
		disabled: true,
		value: null
	};
	const value = getCurrentResolvedParagraphProperties(context)?.styleId ?? null;
	return {
		active: value != null,
		disabled: false,
		value
	};
};
const createListStateDeriver = (numberingType) => ({ context }) => {
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true
	};
	const paragraphNode = getCurrentParagraphParent(context)?.node ?? null;
	const paragraphProperties = getCurrentResolvedParagraphProperties(context);
	const activeNumberingType = isList(paragraphNode) || Boolean(paragraphProperties?.numberingProperties && paragraphNode?.attrs?.listRendering) ? paragraphNode?.attrs?.listRendering?.numberingType : null;
	const isActive = numberingType === "bullet" ? activeNumberingType === "bullet" : activeNumberingType != null && activeNumberingType !== "bullet";
	if (numberingType === "bullet") return {
		active: isActive,
		disabled: false,
		value: isActive ? paragraphNode?.attrs?.listRendering?.markerText ?? null : null
	};
	return {
		active: isActive,
		disabled: false
	};
};
const createIndentIncreaseExecute = () => ({ context }) => {
	if (resolveStateEditor(context)?.commands?.increaseListIndent?.()) return true;
	return createDirectCommandExecute("increaseTextIndent")({ context });
};
const createIndentDecreaseExecute = () => ({ context }) => {
	if (resolveStateEditor(context)?.commands?.decreaseListIndent?.()) return true;
	return createDirectCommandExecute("decreaseTextIndent")({ context });
};
const createTableActionsStateDeriver = () => ({ context }) => {
	const editor = resolveStateEditor(context);
	const inTable = editor?.state?.selection?.$head ? isInTable(editor.state) : false;
	return {
		active: false,
		disabled: isCommandDisabled(context) || !inTable
	};
};
var enrichTrackedChanges = (trackedChanges = [], superdoc) => {
	if (!trackedChanges.length) return trackedChanges;
	const store = superdoc?.commentsStore;
	if (!store?.getComment) return trackedChanges;
	return trackedChanges.map((change) => {
		const commentId = change.id;
		if (!commentId) return change;
		const storeComment = store.getComment(commentId);
		if (!storeComment) return change;
		const comment = typeof storeComment.getValues === "function" ? storeComment.getValues() : storeComment;
		return {
			...change,
			comment
		};
	});
};
const createTrackChangesSelectionActionStateDeriver = (action) => ({ context, superdoc }) => {
	if (isCommandDisabled(context)) return {
		active: false,
		disabled: true
	};
	const editor = resolveStateEditor(context);
	const state = editor?.state;
	const selection = state?.selection;
	if (!editor || !state?.doc || !selection) return {
		active: false,
		disabled: true
	};
	const trackedChanges = enrichTrackedChanges(collectTrackedChanges({
		state,
		from: selection.from,
		to: selection.to
	}), superdoc);
	if (!trackedChanges.length) return {
		active: false,
		disabled: true
	};
	return {
		active: false,
		disabled: !isTrackedChangeActionAllowed({
			editor,
			action,
			trackedChanges
		})
	};
};
const createToolbarRegistry = () => {
	return {
		bold: {
			id: "bold",
			directCommandName: "toggleBold",
			state: createBoldStateDeriver(),
			execute: createBoldExecute()
		},
		italic: {
			id: "italic",
			directCommandName: "toggleItalic",
			state: createItalicStateDeriver(),
			execute: createItalicExecute()
		},
		underline: {
			id: "underline",
			directCommandName: "toggleUnderline",
			state: createUnderlineStateDeriver(),
			execute: createUnderlineExecute()
		},
		strikethrough: {
			id: "strikethrough",
			directCommandName: "toggleStrike",
			state: createStrikethroughStateDeriver()
		},
		"font-size": {
			id: "font-size",
			directCommandName: "setFontSize",
			state: createFontSizeStateDeriver(),
			execute: createFontSizeExecute()
		},
		"font-family": {
			id: "font-family",
			directCommandName: "setFontFamily",
			state: createFontFamilyStateDeriver(),
			execute: createFontFamilyExecute()
		},
		"text-color": {
			id: "text-color",
			directCommandName: "setColor",
			state: createTextColorStateDeriver(),
			execute: createTextColorExecute()
		},
		"highlight-color": {
			id: "highlight-color",
			directCommandName: "setHighlight",
			state: createHighlightColorStateDeriver(),
			execute: createHighlightColorExecute()
		},
		link: {
			id: "link",
			directCommandName: "toggleLink",
			state: createLinkStateDeriver(),
			execute: createLinkExecute()
		},
		"text-align": {
			id: "text-align",
			directCommandName: "setTextAlign",
			state: createTextAlignStateDeriver()
		},
		"line-height": {
			id: "line-height",
			directCommandName: "setLineHeight",
			state: createLineHeightStateDeriver()
		},
		"linked-style": {
			id: "linked-style",
			directCommandName: "setLinkedStyle",
			state: createLinkedStyleStateDeriver(),
			execute: createDirectCommandExecute("setLinkedStyle")
		},
		"bullet-list": {
			id: "bullet-list",
			directCommandName: "toggleBulletListStyle",
			state: createListStateDeriver("bullet")
		},
		"numbered-list": {
			id: "numbered-list",
			directCommandName: "toggleOrderedList",
			state: createListStateDeriver("ordered")
		},
		"indent-increase": {
			id: "indent-increase",
			state: createDisabledStateDeriver(),
			execute: createIndentIncreaseExecute()
		},
		"indent-decrease": {
			id: "indent-decrease",
			state: createDisabledStateDeriver(),
			execute: createIndentDecreaseExecute()
		},
		undo: {
			id: "undo",
			directCommandName: "undo",
			state: createHistoryStateDeriver("undo")
		},
		redo: {
			id: "redo",
			directCommandName: "redo",
			state: createHistoryStateDeriver("redo")
		},
		ruler: {
			id: "ruler",
			state: createRulerStateDeriver(),
			execute: createRulerExecute()
		},
		zoom: {
			id: "zoom",
			state: createZoomStateDeriver(),
			execute: createZoomExecute()
		},
		"document-mode": {
			id: "document-mode",
			state: createDocumentModeStateDeriver(),
			execute: createDocumentModeExecute()
		},
		"clear-formatting": {
			id: "clear-formatting",
			directCommandName: "clearFormat",
			state: createDisabledStateDeriver()
		},
		"copy-format": {
			id: "copy-format",
			directCommandName: "copyFormat",
			state: createDisabledStateDeriver()
		},
		"track-changes-accept-selection": {
			id: "track-changes-accept-selection",
			directCommandName: "acceptTrackedChangeFromToolbar",
			state: createTrackChangesSelectionActionStateDeriver("accept")
		},
		"track-changes-reject-selection": {
			id: "track-changes-reject-selection",
			directCommandName: "rejectTrackedChangeFromToolbar",
			state: createTrackChangesSelectionActionStateDeriver("reject")
		},
		image: {
			id: "image",
			state: createDisabledStateDeriver(),
			execute: createImageExecute()
		},
		"table-insert": {
			id: "table-insert",
			directCommandName: "insertTable",
			state: createDisabledStateDeriver(),
			execute: createDirectCommandExecute("insertTable")
		},
		"table-add-row-before": {
			id: "table-add-row-before",
			directCommandName: "addRowBefore",
			state: createTableActionsStateDeriver()
		},
		"table-add-row-after": {
			id: "table-add-row-after",
			directCommandName: "addRowAfter",
			state: createTableActionsStateDeriver()
		},
		"table-delete-row": {
			id: "table-delete-row",
			directCommandName: "deleteRow",
			state: createTableActionsStateDeriver()
		},
		"table-add-column-before": {
			id: "table-add-column-before",
			directCommandName: "addColumnBefore",
			state: createTableActionsStateDeriver()
		},
		"table-add-column-after": {
			id: "table-add-column-after",
			directCommandName: "addColumnAfter",
			state: createTableActionsStateDeriver()
		},
		"table-delete-column": {
			id: "table-delete-column",
			directCommandName: "deleteColumn",
			state: createTableActionsStateDeriver()
		},
		"table-delete": {
			id: "table-delete",
			directCommandName: "deleteTable",
			state: createTableActionsStateDeriver()
		},
		"table-merge-cells": {
			id: "table-merge-cells",
			directCommandName: "mergeCells",
			state: createTableActionsStateDeriver()
		},
		"table-split-cell": {
			id: "table-split-cell",
			directCommandName: "splitCell",
			state: createTableActionsStateDeriver()
		},
		"table-remove-borders": {
			id: "table-remove-borders",
			directCommandName: "deleteCellAndTableBorders",
			state: createTableActionsStateDeriver()
		},
		"table-fix": {
			id: "table-fix",
			directCommandName: "fixTables",
			state: createTableActionsStateDeriver()
		}
	};
};
var executeDirectCommand = (id, snapshot, toolbarRegistry, payload) => {
	const commandName = toolbarRegistry[id]?.directCommandName;
	const command = commandName ? snapshot.context?.target?.commands?.[commandName] : null;
	if (typeof command !== "function") return false;
	const result = payload === void 0 ? command() : command(payload);
	return typeof result === "boolean" ? result : Boolean(result);
};
var executeRegistryCommand = (id, superdoc, snapshot, toolbarRegistry, payload) => {
	const entry = toolbarRegistry[id];
	if (!entry) return false;
	if (typeof entry.execute === "function") return entry.execute({
		context: snapshot.context,
		superdoc,
		payload
	});
	return executeDirectCommand(id, snapshot, toolbarRegistry, payload);
};
const createHeadlessToolbar = (options) => {
	const listeners = /* @__PURE__ */ new Set();
	const toolbarRegistry = createToolbarRegistry();
	const buildSnapshot = () => {
		return createToolbarSnapshot({
			...options,
			toolbarRegistry
		});
	};
	let snapshot = buildSnapshot();
	let destroyed = false;
	let unsubscribeEvents = null;
	const notifyListeners = () => {
		listeners.forEach((listener) => listener({ snapshot }));
	};
	const rebindEvents = () => {
		unsubscribeEvents?.();
		unsubscribeEvents = subscribeToolbarEvents(options, handleChange);
	};
	const rebuildSnapshot = () => {
		snapshot = buildSnapshot();
	};
	const refreshControllerState = () => {
		rebuildSnapshot();
		rebindEvents();
		notifyListeners();
	};
	const handleChange = () => {
		if (destroyed) return;
		refreshControllerState();
	};
	rebindEvents();
	return {
		getSnapshot() {
			return snapshot;
		},
		subscribe(listener) {
			if (destroyed) return () => {};
			listeners.add(listener);
			listener({ snapshot });
			return () => {
				listeners.delete(listener);
			};
		},
		execute(id, payload) {
			const result = executeRegistryCommand(id, options.superdoc, snapshot, toolbarRegistry, payload);
			if (result && !destroyed) refreshControllerState();
			return result;
		},
		destroy() {
			if (destroyed) return;
			destroyed = true;
			unsubscribeEvents?.();
			unsubscribeEvents = null;
			listeners.clear();
		}
	};
};
export { getPreservedSelection as C, parseSizeUnit as D, Extension as E, createSelectionTrackingBookmark as S, resolveHandleToSelection as T, generateUniqueDocPrId as _, collectTrackedChangesForContext as a, captureSelectionHandle as b, LinkedStylesPluginKey as c, processAndInsertImageFile as d, getFileOpener as f, ImageRegistrationPlugin as g, ImagePositionPlugin as h, collectTrackedChanges as i, generateLinkedStyleString as l, getNormalizedImageAttrs as m, createToolbarRegistry as n, isTrackedChangeActionAllowed as o, getRotationMargins as p, resolveToolbarSources as r, LinkedStyles as s, createHeadlessToolbar as t, getQuickFormatList as u, getAllowedImageDimensions as v, releaseSelectionHandle as w, createSelectionHandlePlugin as x, CustomSelectionPluginKey as y };
