globalThis.window = globalThis;
globalThis.self = globalThis;
globalThis.navigator = { userAgent: "KatanA Rust-managed Mermaid runtime" };
globalThis.location = {
href: "https://katana.local/",
origin: "https://katana.local",
protocol: "https:",
host: "katana.local",
hostname: "katana.local",
pathname: "/",
search: "",
hash: "",
};
const KATANA_DETERMINISTIC_NOW = Date.parse("2026-01-01T00:00:00.000Z");
globalThis.Date.now = () => KATANA_DETERMINISTIC_NOW;
globalThis.performance = { now: () => Date.now() };
globalThis.devicePixelRatio = 1;
globalThis.innerWidth = 1520;
globalThis.innerHeight = 845;
globalThis.screen = {
width: globalThis.innerWidth,
height: globalThis.innerHeight,
availWidth: globalThis.innerWidth,
availHeight: globalThis.innerHeight,
};
globalThis.localStorage = katanaStorage();
globalThis.sessionStorage = katanaStorage();
class KatanaMessageChannel {
constructor() {
this.port1 = { onmessage: null };
this.port2 = {
postMessage: (data) => {
queueMicrotask(() => this.port1.onmessage?.({ data }));
},
};
}
}
class KatanaSegmenter {
segment(value) {
const input = String(value);
let index = 0;
return Array.from(input).map((segment) => {
const entry = { segment, index, input };
index += segment.length;
return entry;
});
}
}
const katanaIntl = globalThis.Intl ?? {};
katanaIntl.Segmenter = KatanaSegmenter;
globalThis.Intl = katanaIntl;
globalThis.crypto = {
getRandomValues(array) {
for (let index = 0; index < array.length; index += 1) {
array[index] = katanaDeterministicByte(index);
}
return array;
},
randomUUID() {
return "00000000-0000-4000-8000-000000000000";
},
};
Math.random = katanaDeterministicRandom;
let katanaRandomState = 0x12345678;
globalThis.queueMicrotask = (callback) => Promise.resolve().then(callback);
function katanaDeterministicRandom() {
katanaRandomState = (1664525 * katanaRandomState + 1013904223) >>> 0;
return katanaRandomState / 0x100000000;
}
function katanaDeterministicByte(index) {
return (index * 73 + 41) & 0xff;
}
function katanaStorage() {
const values = {};
return {
get length() {
return Object.keys(values).length;
},
clear() {
Object.keys(values).forEach((key) => delete values[key]);
},
getItem(key) {
return values[String(key)] ?? null;
},
key(index) {
return Object.keys(values)[index] ?? null;
},
removeItem(key) {
delete values[String(key)];
},
setItem(key, value) {
values[String(key)] = String(value);
},
};
}
globalThis.setTimeout = (callback, _delay, ...args) => callback(...args);
globalThis.clearTimeout = () => {};
globalThis.setInterval = (callback, _delay, ...args) => callback(...args);
globalThis.clearInterval = () => {};
globalThis.MessageChannel = KatanaMessageChannel;
let katanaAnimationFrameDepth = 0;
globalThis.requestAnimationFrame = (callback) => katanaRunAnimationFrame(callback);
function katanaRunAnimationFrame(callback) {
if (katanaAnimationFrameDepth > 4) {
return 0;
}
return katanaInvokeAnimationFrame(callback);
}
function katanaInvokeAnimationFrame(callback) {
katanaAnimationFrameDepth += 1;
try {
return callback(Date.now());
} finally {
katanaAnimationFrameDepth -= 1;
}
}
globalThis.cancelAnimationFrame = () => {};
globalThis.addEventListener = () => {};
globalThis.removeEventListener = () => {};
globalThis.__katanaMissingSelectors = [];
const KATANA_BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
globalThis.btoa = (value) => {
const utf8 = unescape(encodeURIComponent(String(value)));
return katanaBase64Triplets(utf8).map(katanaBase64Chunk).join("");
};
function katanaBase64Triplets(value) {
return value.match(/[\s\S]{1,3}/g) ?? [];
}
function katanaBase64Chunk(chunk) {
const first = chunk.charCodeAt(0);
const second = chunk.charCodeAt(1);
const third = chunk.charCodeAt(2);
return [
first >> 2,
((first & 3) << 4) | (second >> 4),
katanaThirdBase64Index(second, third),
katanaFourthBase64Index(third),
]
.map((index) => KATANA_BASE64_CHARS.charAt(index))
.join("");
}
function katanaThirdBase64Index(second, third) {
if (Number.isNaN(second)) {
return 64;
}
return ((second & 15) << 2) | (third >> 6);
}
function katanaFourthBase64Index(third) {
if (Number.isNaN(third)) {
return 64;
}
return third & 63;
}
globalThis.DOMPurify = {
sanitize(value) {
return String(value ?? "");
},
addHook() {},
removeHook() {},
};
class KatanaStyle {
constructor() {
this.values = {};
}
setProperty(name, value) {
this.values[String(name)] = String(value);
}
getPropertyValue(name) {
return this.values[String(name)] ?? "";
}
removeProperty(name) {
const value = this.getPropertyValue(name);
delete this.values[String(name)];
return value;
}
set mixBlendMode(value) {
this.setProperty("mix-blend-mode", value);
}
get mixBlendMode() {
return this.getPropertyValue("mix-blend-mode");
}
get cssText() {
return Object.entries(this.values)
.map(([key, value]) => `${key}: ${value};`)
.join(" ");
}
clone() {
const cloned = new KatanaStyle();
cloned.values = { ...this.values };
return cloned;
}
}
globalThis.getComputedStyle = (node) => ({
getPropertyValue(name) {
return node?.style?.getPropertyValue?.(name) ?? "";
},
});
function katanaEscapeSvgAttribute(value) {
return String(value)
.replace(/&/g, "&")
.replace(/"/g, """)
.replace(/</g, "<")
.replace(/>/g, ">");
}
function katanaEscapeSvgText(value) {
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
}
class KatanaNode {
constructor(tagName, namespaceURI = null) {
const rawName = katanaRawNodeName(tagName);
const preservesCase = katanaPreservesNodeCase(namespaceURI);
this.serializedName = katanaSerializedNodeName(rawName, preservesCase);
this.tagName = katanaTagNodeName(rawName, preservesCase);
this.nodeName = this.tagName;
this.localName = rawName.toLowerCase();
this.namespaceURI = namespaceURI;
this.children = [];
this.childNodes = this.children;
this.parentNode = null;
this.ownerDocument = null;
this.nodeType = katanaNodeType(tagName);
this.attributes = [];
this.attributeMap = {};
this.style = new KatanaStyle();
this.dataset = {};
this._textContent = "";
this.className = "";
this.id = "";
}
appendChild(child) {
child.parentNode = this;
child.ownerDocument = this.ownerDocument;
this.children.push(child);
this.childNodes = this.children;
return child;
}
insertBefore(child, reference) {
child.parentNode = this;
child.ownerDocument = this.ownerDocument;
const index = this.children.indexOf(reference);
if (index < 0) {
this.children.push(child);
this.childNodes = this.children;
return child;
}
this.children.splice(index, 0, child);
this.childNodes = this.children;
return child;
}
removeChild(child) {
this.children = this.children.filter((candidate) => candidate !== child);
this.childNodes = this.children;
return child;
}
remove() {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
}
get firstChild() {
return this.children[0] ?? null;
}
get lastChild() {
return this.children[this.children.length - 1] ?? null;
}
get parentElement() {
return this.parentNode;
}
getRootNode() {
return this.ownerDocument ?? document;
}
hasChildNodes() {
return this.children.length > 0;
}
compareDocumentPosition(other) {
if (this === other) {
return 0;
}
return 4;
}
get nextSibling() {
if (!this.parentNode) {
return null;
}
const index = this.parentNode.children.indexOf(this);
return this.parentNode.children[index + 1] ?? null;
}
get previousSibling() {
if (!this.parentNode) {
return null;
}
const index = this.parentNode.children.indexOf(this);
return this.parentNode.children[index - 1] ?? null;
}
setAttribute(name, value) {
const normalized = String(name);
const attribute = katanaUpsertAttribute(this, normalized);
attribute.value = String(value);
katanaSyncIdAttribute(this, normalized, value);
katanaSyncClassAttribute(this, normalized, value);
}
getAttribute(name) {
return this.attributeMap[String(name)]?.value ?? null;
}
removeAttribute(name) {
const normalized = String(name);
delete this.attributeMap[normalized];
this.attributes = this.attributes.filter((attribute) => attribute.name !== normalized);
}
setAttributeNS(_namespace, name, value) {
this.setAttribute(name, value);
}
getAttributeNS(_namespace, name) {
return this.getAttribute(name);
}
hasAttribute(name) {
return Object.hasOwn(this.attributeMap, String(name));
}
querySelector(selector) {
const result = katanaFirstQuerySelectorResult(this, selector);
if (result === null) {
globalThis.__katanaMissingSelectors.push(`${this.localName}:${selector}`);
}
return result;
}
querySelectorAll(selector) {
const compound = queryCompoundSelector(this, String(selector));
if (compound !== null) {
return compound;
}
return querySimpleSelector(this, String(selector));
}
getElementsByTagName(tagName) {
return this.querySelectorAll(String(tagName).toLowerCase());
}
addEventListener() {}
removeEventListener() {}
dispatchEvent() {
return true;
}
focus() {
document.activeElement = this;
}
click() {}
get isConnected() {
return this === document || document.documentElement.contains(this);
}
toJSON() {
return {};
}
}
function katanaFirstQuerySelectorResult(node, selector) {
return node.querySelectorAll(selector)[0] ?? null;
}
function katanaRawNodeName(tagName) {
return String(tagName || "");
}
function katanaPreservesNodeCase(namespaceURI) {
return [
katanaNamespaceIncludes(namespaceURI, "svg"),
katanaNamespaceIncludes(namespaceURI, "xml"),
].includes(true);
}
function katanaNamespaceIncludes(namespaceURI, value) {
return String(namespaceURI || "").includes(value);
}
function katanaSerializedNodeName(rawName, preservesCase) {
return preservesCase ? rawName : rawName.toLowerCase();
}
function katanaTagNodeName(rawName, preservesCase) {
return preservesCase ? rawName : rawName.toUpperCase();
}
function katanaNodeType(tagName) {
return tagName === "#text" ? 3 : 1;
}
function katanaUpsertAttribute(node, normalized) {
const attribute = node.attributeMap[normalized];
if (attribute) {
return attribute;
}
return katanaCreateAttribute(node, normalized);
}
function katanaCreateAttribute(node, normalized) {
const attribute = { name: normalized, nodeName: normalized, value: "" };
node.attributeMap[normalized] = attribute;
node.attributes.push(attribute);
return attribute;
}
function katanaSyncIdAttribute(node, normalized, value) {
if (normalized === "id") {
node.id = String(value);
}
}
function katanaSyncClassAttribute(node, normalized, value) {
if (normalized === "class") {
node.className = String(value);
}
}
function katanaStyleCamelName(name) {
return String(name).replace(/-([a-z])/g, (_match, char) => char.toUpperCase());
}
function katanaStyleKebabName(name) {
return String(name).replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
}
function katanaApplyCssText(style, value) {
katanaCssEntries(value).forEach((entry) => {
katanaApplyCssEntry(style, entry);
});
}
function katanaCssEntries(value) {
return String(value ?? "").split(";");
}
function katanaApplyCssEntry(style, entry) {
const separator = entry.indexOf(":");
if (separator < 0) return;
style.setProperty(entry.slice(0, separator).trim(), entry.slice(separator + 1).trim());
}
KatanaStyle.prototype.setProperty = function setProperty(name, value) {
const kebab = katanaStyleKebabName(name);
const camel = katanaStyleCamelName(name);
this.values[kebab] = String(value);
this.values[camel] = String(value);
if (!Object.getOwnPropertyDescriptor(KatanaStyle.prototype, camel)) {
this[camel] = String(value);
}
};
KatanaStyle.prototype.getPropertyValue = function getPropertyValue(name) {
const key = String(name);
const kebab = katanaStyleKebabName(key);
const camel = katanaStyleCamelName(key);
return this.values[key] ?? this.values[kebab] ?? this.values[camel] ?? this[camel] ?? "";
};
KatanaStyle.prototype.removeProperty = function removeProperty(name) {
const value = this.getPropertyValue(name);
delete this.values[String(name)];
delete this.values[katanaStyleKebabName(name)];
delete this.values[katanaStyleCamelName(name)];
delete this[katanaStyleCamelName(name)];
return value;
};
Object.defineProperty(KatanaStyle.prototype, "cssText", {
get() {
return Object.entries(this.values)
.filter(([key]) => key.includes("-"))
.map(([key, value]) => `${key}: ${value}`)
.join("; ");
},
set(value) {
this.values = {};
katanaApplyCssText(this, value);
},
});
const katanaSetAttributeBase = KatanaNode.prototype.setAttribute;
KatanaNode.prototype.setAttribute = function setAttribute(name, value) {
katanaSetAttributeBase.call(this, name, value);
if (String(name).toLowerCase() === "style") {
this.style.cssText = value;
}
};
function parseInnerHtml(source, xmlMode = false) {
const root = {
localName: "#root",
children: [],
appendChild(child) {
this.children.push(child);
},
};
const stack = [root];
const tokenRegex = /<\/?([a-zA-Z0-9:_-]+)([^>]*)>|([^<]+)/g;
Array.from(source.matchAll(tokenRegex)).forEach((match) => {
appendHtmlToken(stack, match, xmlMode);
});
return root.children;
}
function appendHtmlToken(stack, match, xmlMode) {
if (match[3] !== undefined) {
appendHtmlText(stack[stack.length - 1], match[3]);
return;
}
appendHtmlTag(stack, match, xmlMode);
}
function appendHtmlTag(stack, match, xmlMode) {
if (match[0].startsWith("</")) {
popHtmlStack(stack, match[1]);
return;
}
appendHtmlStartTag(stack, match, xmlMode);
}
function appendHtmlStartTag(stack, match, xmlMode) {
const node = new KatanaNode(match[1], katanaHtmlNamespace(xmlMode));
node.ownerDocument = document;
parseAttributes(match[2]).forEach(([name, value]) => {
node.setAttribute(name, value);
});
stack[stack.length - 1].appendChild(node);
pushHtmlElementIfOpen(stack, node, match[0], match[1]);
}
function katanaHtmlNamespace(xmlMode) {
return xmlMode ? "katana-xml" : null;
}
function pushHtmlElementIfOpen(stack, node, fullTag, tagName) {
if (katanaIsOpenHtmlTag(fullTag, tagName)) {
stack.push(node);
}
}
function katanaIsOpenHtmlTag(fullTag, tagName) {
return [!fullTag.endsWith("/>"), !isHtmlVoidTag(tagName)].every(Boolean);
}
function appendHtmlText(parent, value) {
const text = decodeHtmlEntities(value);
if (text.length > 0) {
parent.appendChild(new KatanaTextNode(text));
}
}
function popHtmlStack(stack, tagName) {
const normalized = String(tagName).toLowerCase();
const index = stack.findLastIndex((node) => node.localName === normalized);
if (index > 0) {
stack.splice(index);
}
}
function isHtmlVoidTag(tagName) {
return new Set(["br", "hr", "img", "input", "meta", "link"]).has(String(tagName).toLowerCase());
}
function parseAttributes(source) {
const attrRegex = /([a-zA-Z0-9:_-]+)="([^"]*)"/g;
return Array.from(source.matchAll(attrRegex)).map((match) => [
match[1],
decodeHtmlEntities(match[2]),
]);
}
function decodeHtmlEntities(value) {
return String(value)
.replace(/&nbsp;/g, "\u00A0")
.replace(/ /g, "\u00A0")
.replace(/
/gi, "\n")
.replace(/ /g, "\n")
.replace(/ /g, "\u00A0")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/&/g, "&")
.replace(/"/g, '"')
.replace(/'/g, "'");
}
class KatanaTextNode extends KatanaNode {
constructor(value) {
super("#text");
this.textContent = String(value);
}
get outerHTML() {
return katanaEscapeSvgText(this.textContent);
}
}
KatanaNode.prototype.getBBox = function getBBox() {
const text = katanaNodeTextForBox(this);
const childWidth = katanaNodeChildWidth(this);
const width = Math.max(80, childWidth, katanaTextWidth(text));
const height = Math.max(24, this.children.length * 24);
return { x: 0, y: 0, width, height };
};
function katanaNodeTextForBox(node) {
return String(katanaFirstTextValue([node.textContent, node.innerText]));
}
function katanaFirstTextValue(values) {
return values.find(Boolean) ?? "";
}
function katanaNodeChildWidth(node) {
return node.children.reduce((max, child) => Math.max(max, child.getBBox().width), 0);
}
KatanaNode.prototype.getBoundingClientRect = function getBoundingClientRect() {
const box = this.getBBox();
return {
...box,
top: box.y,
left: box.x,
right: box.x + box.width,
bottom: box.y + box.height,
};
};
KatanaNode.prototype.getComputedTextLength = function getComputedTextLength() {
return Math.max(16, katanaTextWidth(String(this.textContent || "")));
};
KatanaNode.prototype.getContext = function getContext() {
return {
font: "",
measureText(value) {
return { width: Math.max(16, katanaTextWidth(String(value || ""))) };
},
};
};
Object.defineProperty(KatanaNode.prototype, "innerHTML", {
get() {
if (this.children.length === 0) {
return this.textContent;
}
return this.children.map((child) => child.outerHTML ?? child.textContent ?? "").join("");
},
set(value) {
katanaClearInnerHtml(this);
katanaApplyInnerHtml(this, String(value), parseInnerHtml(String(value)));
},
});
function katanaClearInnerHtml(node) {
node.textContent = "";
node.children = [];
node.childNodes = node.children;
}
function katanaApplyInnerHtml(node, value, parsed) {
if (parsed.length === 0) {
node.textContent = value;
return;
}
katanaAppendParsedHtml(node, parsed);
}
function katanaAppendParsedHtml(node, parsed) {
for (const child of parsed) {
node.appendChild(child);
}
}
Object.defineProperty(KatanaNode.prototype, "outerHTML", {
get() {
const attrs = katanaSerializedAttributeText(this);
const body = katanaOuterHtmlBody(this);
return `<${this.serializedName}${attrs}>${body}</${this.serializedName}>`;
},
});
function katanaSerializedAttributeText(node) {
return Object.entries({ ...node.serializedAttributes(), ...katanaStyleAttribute(node) })
.map(([key, value]) => ` ${key}="${katanaEscapeSvgAttribute(value)}"`)
.join("");
}
function katanaStyleAttribute(node) {
if (katanaShouldSerializeStyle(node)) {
return { style: node.style.cssText };
}
return {};
}
function katanaShouldSerializeStyle(node) {
return [node.style.cssText, !node.hasAttribute("style")].every(Boolean);
}
function katanaOuterHtmlBody(node) {
if (node.children.length === 0) {
return katanaEscapeSvgText(node.textContent);
}
return node.innerHTML;
}
KatanaNode.prototype.cloneNode = function cloneNode(deep = false) {
const clone = katanaShallowCloneNode(this);
katanaCloneChildrenIfDeep(this, clone, deep);
return clone;
};
function katanaShallowCloneNode(node) {
const clone = new KatanaNode(node.serializedName, node.namespaceURI);
node.attributes.forEach((attribute) => {
clone.setAttribute(attribute.name, attribute.value);
});
clone.style = node.style.clone();
clone._textContent = node._textContent ?? "";
clone.className = node.className;
clone.id = node.id;
clone.ownerDocument = node.ownerDocument;
return clone;
}
function katanaCloneChildrenIfDeep(node, clone, deep) {
if (deep) {
katanaCloneChildren(node, clone);
}
}
function katanaCloneChildren(node, clone) {
for (const child of node.children) {
clone.appendChild(child.cloneNode(true));
}
}
KatanaNode.prototype.serializedAttributes = function serializedAttributes() {
return Object.fromEntries(this.attributes.map((attribute) => [attribute.name, attribute.value]));
};
function matchesSelector(node, selector) {
const matcher = KATANA_SELECTOR_MATCHERS.find((entry) => entry.applies(selector));
if (matcher) {
return matcher.matches(node, selector);
}
return katanaMatchesTag(node, selector);
}
const KATANA_SELECTOR_MATCHERS = [
{ applies: katanaIsBareFirstChildSelector, matches: katanaMatchesBareFirstChild },
{ applies: katanaIsNestedFirstChildSelector, matches: katanaMatchesNestedFirstChild },
{ applies: katanaIsWildcardSelector, matches: katanaMatchesWildcard },
{ applies: katanaIsTagIdSelector, matches: katanaMatchesTagId },
{ applies: katanaIsBodySelector, matches: katanaMatchesBody },
{ applies: katanaIsIdSelector, matches: katanaMatchesId },
{ applies: katanaIsIdAttributeSelector, matches: katanaMatchesIdAttribute },
{ applies: katanaIsClassSelector, matches: katanaMatchesClass },
];
function katanaIsBareFirstChildSelector(selector) {
return [":first-child", "::first-child"].includes(selector);
}
function katanaMatchesBareFirstChild(node) {
return node.parentNode?.firstElementChild === node;
}
function katanaIsNestedFirstChildSelector(selector) {
return selector.endsWith(":first-child");
}
function katanaMatchesNestedFirstChild(node, selector) {
const base = selector.replace(/:{1,2}first-child$/, "");
return [matchesSelector(node, base), katanaMatchesBareFirstChild(node)].every(Boolean);
}
function katanaIsWildcardSelector(selector) {
return selector === "*";
}
function katanaMatchesWildcard(node) {
return node.nodeType === Node.ELEMENT_NODE;
}
function katanaIsTagIdSelector(selector) {
return /^([a-zA-Z0-9:_-]+)#(.+)$/.test(selector);
}
function katanaMatchesTagId(node, selector) {
const match = selector.match(/^([a-zA-Z0-9:_-]+)#(.+)$/);
return [node.localName === match[1].toLowerCase(), node.id === match[2]].every(Boolean);
}
function katanaIsBodySelector(selector) {
return selector === "body";
}
function katanaMatchesBody(node) {
return node === document.body;
}
function katanaIsIdSelector(selector) {
return selector.startsWith("#");
}
function katanaMatchesId(node, selector) {
return node.id === selector.slice(1);
}
function katanaIsIdAttributeSelector(selector) {
return /^\[id="([^"]+)"\]$/.test(selector);
}
function katanaMatchesIdAttribute(node, selector) {
return node.id === selector.match(/^\[id="([^"]+)"\]$/)[1];
}
function katanaIsClassSelector(selector) {
return selector.startsWith(".");
}
function katanaMatchesClass(node, selector) {
return String(node.className).split(/\s+/).includes(selector.slice(1));
}
function katanaMatchesTag(node, selector) {
return node.localName === selector.toLowerCase();
}
function queryCompoundSelector(root, selector) {
const parts = selector.split(/\s+/).filter(Boolean);
if (parts.length <= 1) {
return null;
}
return katanaQuerySelectorParts([root], parts);
}
function katanaQuerySelectorParts(candidates, parts) {
return parts.reduce(
(current, part) => current.flatMap((candidate) => querySimpleSelector(candidate, part)),
candidates,
);
}
function querySimpleSelector(root, selector) {
const results = [];
root.children.forEach((node) => {
katanaVisitSelector(node, selector, results);
});
return results;
}
function katanaVisitSelector(node, selector, results) {
katanaAddMatchingSelector(node, selector, results);
node.children.forEach((child) => {
katanaVisitSelector(child, selector, results);
});
}
function katanaAddMatchingSelector(node, selector, results) {
if (matchesSelector(node, selector)) {
results.push(node);
}
}
const document = {
nodeType: 9,
currentScript: null,
activeElement: null,
addEventListener() {},
removeEventListener() {},
dispatchEvent() {
return true;
},
createElement(tagName) {
const node = new KatanaNode(tagName);
node.ownerDocument = document;
return node;
},
createElementNS(namespaceURI, tagName) {
const node = new KatanaNode(tagName, namespaceURI);
node.ownerDocument = document;
return node;
},
createTextNode(value) {
const node = new KatanaTextNode(value);
node.ownerDocument = document;
return node;
},
createComment(value) {
return this.createTextNode(value);
},
createDocumentFragment() {
const node = new KatanaNode("#document-fragment");
node.nodeType = 11;
node.ownerDocument = document;
return node;
},
createNodeIterator(root) {
const nodes = [];
const visit = (node) => {
nodes.push(node);
node.children.forEach(visit);
};
visit(root);
let index = 0;
return { nextNode: () => nodes[index++] ?? null };
},
getElementsByTagName(tagName) {
return this.documentElement.querySelectorAll(String(tagName).toLowerCase());
},
importNode(node, deep) {
const clone = node.cloneNode(deep);
clone.ownerDocument = document;
return clone;
},
getElementById(id) {
const result = this.documentElement.querySelector(`#${id}`);
if (result === null) {
globalThis.__katanaMissingSelectors.push(`document.getElementById:${id}`);
}
return result;
},
querySelector(selector) {
if (selector === "body") {
return this.body;
}
return this.documentElement.querySelector(selector);
},
querySelectorAll(selector) {
return this.documentElement.querySelectorAll(selector);
},
implementation: {
createHTMLDocument() {
return createDetachedDocument();
},
},
fonts: {
ready: Promise.resolve(),
},
};
document.documentElement = document.createElement("html");
document.head = document.createElement("head");
document.body = document.createElement("body");
document.documentElement.appendChild(document.head);
document.documentElement.appendChild(document.body);
document.defaultView = globalThis;
globalThis.document = document;
globalThis.Element = KatanaNode;
globalThis.HTMLElement = KatanaNode;
globalThis.SVGElement = KatanaNode;
globalThis.Node = KatanaNode;
globalThis.Node.ELEMENT_NODE = 1;
globalThis.Node.TEXT_NODE = 3;
globalThis.Node.DOCUMENT_NODE = 9;
globalThis.Node.DOCUMENT_FRAGMENT_NODE = 11;
globalThis.DocumentFragment = KatanaNode;
globalThis.HTMLTemplateElement = KatanaNode;
globalThis.HTMLFormElement = KatanaNode;
globalThis.HTMLButtonElement = KatanaNode;
globalThis.HTMLCanvasElement = KatanaNode;
globalThis.HTMLFieldSetElement = KatanaNode;
globalThis.HTMLIFrameElement = KatanaNode;
globalThis.HTMLImageElement = KatanaNode;
globalThis.HTMLInputElement = KatanaNode;
globalThis.HTMLLabelElement = KatanaNode;
globalThis.HTMLLegendElement = KatanaNode;
globalThis.HTMLSelectElement = KatanaNode;
globalThis.HTMLTextAreaElement = KatanaNode;
globalThis.HTMLVideoElement = KatanaNode;
globalThis.SVGImageElement = KatanaNode;
globalThis.NamedNodeMap = Array;
globalThis.NodeFilter = { SHOW_ELEMENT: 1, SHOW_TEXT: 4, SHOW_COMMENT: 128 };
globalThis.MutationObserver = class {
constructor(callback) {
this.callback = callback;
}
observe() {}
disconnect() {}
takeRecords() {
return [];
}
};
globalThis.trustedTypes = {
createPolicy() {
return {
createHTML: (value) => String(value),
createScriptURL: (value) => String(value),
};
},
};
globalThis.TextEncoder = class {
encode(value) {
return new Uint8Array(Array.from(String(value)).flatMap((char) => katanaUtf8Bytes(char)));
}
};
function katanaUtf8Bytes(char) {
const code = char.charCodeAt(0);
if (code < 0x80) {
return [code];
}
return katanaMultibyteUtf8Bytes(code);
}
function katanaMultibyteUtf8Bytes(code) {
if (code < 0x800) {
return [0xc0 | (code >> 6), 0x80 | (code & 0x3f)];
}
return [0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f)];
}
globalThis.TextDecoder = class {
decode(value) {
return Array.from(value)
.map((byte) => String.fromCharCode(byte))
.join("");
}
};
globalThis.structuredClone = (value) => JSON.parse(JSON.stringify(value));
globalThis.XMLSerializer = class {
serializeToString(node) {
return node.outerHTML ?? "";
}
};
globalThis.DOMParser = class {
parseFromString(source) {
const parsed = parseInnerHtml(String(source).trim(), true);
const detached = createDetachedDocument();
const root = parsed[0] ?? detached.createElement("xml");
attachOwnerDocument(root, detached);
detached.documentElement = root;
detached.body = root;
return detached;
}
};
function createDetachedDocument() {
const detached = Object.create(document);
detached.documentElement = document.createElement("html");
detached.head = document.createElement("head");
detached.body = document.createElement("body");
detached.documentElement.ownerDocument = detached;
detached.head.ownerDocument = detached;
detached.body.ownerDocument = detached;
detached.documentElement.appendChild(detached.head);
detached.documentElement.appendChild(detached.body);
detached.defaultView = globalThis;
detached.nodeType = 9;
return detached;
}
function attachOwnerDocument(node, ownerDocument) {
node.ownerDocument = ownerDocument;
for (const child of node.children) {
attachOwnerDocument(child, ownerDocument);
}
}
function katanaDetachChild(child) {
const parent = child?.parentNode;
if (!parent) return;
katanaReplaceChildList(
parent,
katanaChildList(parent).filter((candidate) => candidate !== child),
);
child.parentNode = null;
}
function katanaChildList(parent) {
return [parent.children, parent.childNodes, []].find(Array.isArray);
}
function katanaReplaceChildList(parent, children) {
parent.children = children;
parent.childNodes = children;
}
function katanaAdoptChild(parent, child) {
child.parentNode = parent;
child.ownerDocument = parent.ownerDocument ?? parent;
}
function katanaAppendFragment(parent, fragment) {
const nodes = [...fragment.childNodes];
for (const node of nodes) {
parent.appendChild(node);
}
return fragment;
}
KatanaNode.prototype.appendChild = function appendChild(child) {
if (child.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
return katanaAppendFragment(this, child);
}
katanaDetachChild(child);
katanaAdoptChild(this, child);
this.children.push(child);
this.childNodes = this.children;
return child;
};
KatanaNode.prototype.insertBefore = function insertBefore(child, reference) {
if (child.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
return katanaInsertFragmentBefore(this, child, reference);
}
return katanaInsertNodeBefore(this, child, reference);
};
function katanaInsertFragmentBefore(parent, fragment, reference) {
for (const node of fragment.childNodes) {
parent.insertBefore(node, reference);
}
return fragment;
}
function katanaInsertNodeBefore(parent, child, reference) {
if (child === reference) {
return child;
}
return katanaInsertDetachedNodeBefore(parent, child, reference);
}
function katanaInsertDetachedNodeBefore(parent, child, reference) {
katanaDetachChild(child);
katanaAdoptChild(parent, child);
katanaInsertAtReference(parent, child, reference);
parent.childNodes = parent.children;
return child;
}
function katanaInsertAtReference(parent, child, reference) {
const index = parent.children.indexOf(reference);
if (index < 0) {
parent.children.push(child);
return;
}
parent.children.splice(index, 0, child);
}
KatanaNode.prototype.removeChild = function removeChild(child) {
this.children = this.children.filter((candidate) => candidate !== child);
this.childNodes = this.children;
child.parentNode = null;
return child;
};
Object.defineProperty(KatanaNode.prototype, "firstElementChild", {
get() {
return this.children.find((child) => child.nodeType === Node.ELEMENT_NODE) ?? null;
},
});
function katanaDocumentPath(node) {
const path = [];
let current = node;
while (current?.parentNode) {
path.unshift(current.parentNode.children.indexOf(current));
current = current.parentNode;
}
return path;
}
function katanaComparePath(left, right) {
const mismatch = katanaFirstPathMismatch(left, right);
if (mismatch !== null) {
return katanaPathMismatchPosition(left, right, mismatch);
}
return katanaPathLengthPosition(left, right);
}
function katanaFirstPathMismatch(left, right) {
return katanaPathIndexes(left, right).find((index) => left[index] !== right[index]) ?? null;
}
function katanaPathIndexes(left, right) {
return Array.from({ length: Math.min(left.length, right.length) }, (_value, index) => index);
}
function katanaPathMismatchPosition(left, right, index) {
return left[index] < right[index] ? 4 : 2;
}
function katanaPathLengthPosition(left, right) {
if (left.length === right.length) {
return 0;
}
return katanaUnequalPathLengthPosition(left, right);
}
function katanaUnequalPathLengthPosition(left, right) {
return left.length < right.length ? 20 : 10;
}
KatanaNode.prototype.compareDocumentPosition = function compareDocumentPosition(other) {
if (this === other) return 0;
return katanaComparePath(katanaDocumentPath(this), katanaDocumentPath(other));
};
Node.DOCUMENT_POSITION_DISCONNECTED = 1;
Node.DOCUMENT_POSITION_PRECEDING = 2;
Node.DOCUMENT_POSITION_FOLLOWING = 4;
Node.DOCUMENT_POSITION_CONTAINS = 8;
Node.DOCUMENT_POSITION_CONTAINED_BY = 16;
const KATANA_HIDDEN_LAYOUT_TAGS = new Set([
"style",
"script",
"defs",
"marker",
"lineargradient",
"radialgradient",
"stop",
"filter",
"fedropshadow",
"clippath",
"mask",
"pattern",
]);
function katanaOwnText(node) {
return String(node?._textContent ?? "");
}
function katanaTextContent(node) {
return node ? `${katanaOwnText(node)}${katanaTextContentChildren(node)}` : "";
}
function katanaTextContentChildren(node) {
return (node.children ?? []).map((child) => katanaTextContent(child)).join("");
}
function katanaLayoutTextContent(node) {
if (katanaIsHiddenLayoutNode(node)) {
return "";
}
return `${katanaOwnText(node)}${katanaLayoutTextChildren(node)}`;
}
function katanaLayoutTextChildren(node) {
return (node.children ?? []).map((child) => katanaLayoutTextContent(child)).join("");
}
function katanaIsHiddenLayoutNode(node) {
return [!node, KATANA_HIDDEN_LAYOUT_TAGS.has(node?.localName)].includes(true);
}
function katanaNodeValue(value) {
if (value instanceof KatanaNode) {
return value;
}
return document.createTextNode(katanaStringValue(value));
}
function katanaStringValue(value) {
return String(value ?? "");
}
function katanaNumberAttr(node, name) {
return katanaNullableNumber(node?.getAttribute?.(name));
}
function katanaNullableNumber(rawValue) {
return katanaHasNumberValue(rawValue) ? katanaFiniteNumber(Number(rawValue)) : null;
}
function katanaHasNumberValue(rawValue) {
return ![null, undefined, ""].includes(rawValue);
}
function katanaFiniteNumber(value) {
return Number.isFinite(value) ? value : null;
}
function katanaBox(x, y, width, height) {
return { x, y, width, height, w: width, h: height };
}
function katanaUnionBox(boxes) {
if (boxes.length === 0) {
return katanaBox(0, 0, 0, 0);
}
const minX = Math.min(...boxes.map((box) => box.x));
const minY = Math.min(...boxes.map((box) => box.y));
const maxX = Math.max(...boxes.map((box) => box.x + box.width));
const maxY = Math.max(...boxes.map((box) => box.y + box.height));
return katanaBox(minX, minY, maxX - minX, maxY - minY);
}
function katanaVisibleChildBoxes(node) {
return (node.children ?? [])
.filter((child) => !KATANA_HIDDEN_LAYOUT_TAGS.has(child.localName))
.map((child) => {
const box = child.getBBox();
const offset = katanaNodeTranslate(child);
return katanaBox(box.x + offset[0], box.y + offset[1], box.width, box.height);
});
}
function katanaMeasuredBox(node) {
if (KATANA_HIDDEN_LAYOUT_TAGS.has(node.localName)) {
return katanaBox(0, 0, 0, 0);
}
return katanaVisibleMeasuredBox(node);
}
function katanaVisibleMeasuredBox(node) {
return (
katanaExplicitMeasuredBox(node) ??
katanaDirectShapeBox(node) ??
katanaChildTextMeasuredBox(node)
);
}
function katanaExplicitMeasuredBox(node) {
const attrs = katanaBoxAttributes(node);
if ([attrs.width > 0, attrs.height > 0].includes(true)) {
return katanaBox(attrs.x, attrs.y, attrs.width, attrs.height);
}
return null;
}
function katanaBoxAttributes(node) {
return {
x: katanaNumberAttrOrDefault(node, "x", 0),
y: katanaNumberAttrOrDefault(node, "y", 0),
width: katanaNumberAttrOrDefault(node, "width", 0),
height: katanaNumberAttrOrDefault(node, "height", 0),
};
}
function katanaNumberAttrOrDefault(node, name, fallback) {
const value = katanaNumberAttr(node, name);
if (value === null) {
return fallback;
}
return value;
}
function katanaDirectShapeBox(node) {
return katanaLineBox(node) ?? katanaCircleBox(node);
}
function katanaChildTextMeasuredBox(node) {
const childBox = katanaUnionBox(katanaVisibleChildBoxes(node));
const text = katanaMeasuredNodeText(node, childBox);
return katanaBox(
0,
0,
katanaMeasuredTextWidth(text, childBox),
katanaMeasuredTextHeight(text, childBox),
);
}
function katanaMeasuredNodeText(node, childBox) {
return katanaOwnText(node) || katanaFallbackLayoutText(node, childBox);
}
function katanaFallbackLayoutText(node, childBox) {
return childBox.width === 0 ? katanaLayoutTextContent(node) : "";
}
function katanaMeasuredTextWidth(text, childBox) {
return Math.max(16, katanaTextWidthFallback(text), childBox.width);
}
function katanaMeasuredTextHeight(text, childBox) {
return Math.max(24, katanaTextHeightFallback(text), childBox.height);
}
function katanaTextWidthFallback(text) {
return text.length === 0 ? 0 : Math.max(16, katanaTextWidth(text));
}
function katanaTextHeightFallback(text) {
return text.length === 0 ? 0 : 24;
}
function katanaLineBox(node) {
if (node.localName !== "line") {
return null;
}
return katanaLineShapeBox(node);
}
function katanaLineShapeBox(node) {
const x1 = katanaNumberAttrOrDefault(node, "x1", 0);
const y1 = katanaNumberAttrOrDefault(node, "y1", 0);
const x2 = katanaNumberAttrOrDefault(node, "x2", 0);
const y2 = katanaNumberAttrOrDefault(node, "y2", 0);
return katanaBox(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
}
function katanaCircleBox(node) {
if (!katanaIsRoundSvgShape(node)) {
return null;
}
return katanaRoundShapeBox(node);
}
function katanaRoundShapeBox(node) {
const cx = katanaNumberAttrOrDefault(node, "cx", 0);
const cy = katanaNumberAttrOrDefault(node, "cy", 0);
const rx = katanaRoundRadius(node, "rx");
const ry = katanaRoundRadius(node, "ry");
return katanaBox(cx - rx, cy - ry, rx * 2, ry * 2);
}
function katanaRoundRadius(node, name) {
return katanaNumberAttr(node, name) ?? katanaNumberAttrOrDefault(node, "r", 0);
}
function katanaIsRoundSvgShape(node) {
return ["circle", "ellipse"].includes(node.localName);
}
function katanaNodeTranslate(node) {
const match = katanaTransformValue(node).match(/translate\(([-\d.]+)[,\s]+([-\d.]+)\)/);
if (match) {
return [Number(match[1]), Number(match[2])];
}
return [0, 0];
}
function katanaTransformValue(node) {
return String(node?.getAttribute?.("transform") ?? "");
}
const KATANA_DEFAULT_CLIENT_TAGS = new Set(["body", "div", "main", "pre", "section", "article"]);
function katanaMeasuredClientBox(node) {
const context = katanaClientBoxContext(node);
return (
katanaDefaultExplicitZeroBox(context) ??
katanaExplicitClientBox(context) ??
katanaSvgClientBox(context) ??
katanaEmptyDefaultClientBox(context) ??
context.box
);
}
function katanaClientBoxContext(node) {
return {
node,
box: node.getBBox(),
explicitWidth: katanaExplicitClientWidth(node),
explicitHeight: katanaExplicitClientHeight(node),
};
}
function katanaExplicitClientWidth(node) {
return (
katanaCssLength(node.style?.getPropertyValue?.("width")) ?? katanaNumberAttr(node, "width")
);
}
function katanaExplicitClientHeight(node) {
return (
katanaCssLength(node.style?.getPropertyValue?.("height")) ?? katanaNumberAttr(node, "height")
);
}
function katanaDefaultExplicitZeroBox(context) {
if ([katanaNeedsDefaultClientBox(context.node), context.explicitWidth === 0].every(Boolean)) {
return katanaBox(
0,
0,
katanaDefaultViewportWidth(),
katanaPositiveOrDefault(context.explicitHeight, katanaDefaultViewportHeight()),
);
}
return null;
}
function katanaExplicitClientBox(context) {
if (katanaHasExplicitClientSize(context)) {
return katanaResolvedExplicitClientBox(context);
}
return null;
}
function katanaHasExplicitClientSize(context) {
return [context.explicitWidth !== null, context.explicitHeight !== null].includes(true);
}
function katanaResolvedExplicitClientBox(context) {
return katanaBox(
context.box.x,
context.box.y,
katanaExplicitWidthValue(context),
katanaExplicitHeightValue(context),
);
}
function katanaExplicitWidthValue(context) {
return context.explicitWidth ?? context.box.width;
}
function katanaExplicitHeightValue(context) {
return context.explicitHeight ?? context.box.height;
}
function katanaSvgClientBox(context) {
if (context.node.localName === "svg") {
return katanaSvgViewBoxClientBox(context);
}
return null;
}
function katanaSvgViewBoxClientBox(context) {
const viewBox = katanaViewBoxSize(context.node.getAttribute("viewBox"));
return katanaBox(
context.box.x,
context.box.y,
katanaViewBoxWidth(context, viewBox),
katanaViewBoxHeight(context, viewBox),
);
}
function katanaViewBoxWidth(context, viewBox) {
return viewBox?.[0] ?? Math.max(context.box.width, katanaDefaultViewportWidth());
}
function katanaViewBoxHeight(context, viewBox) {
return viewBox?.[1] ?? Math.max(context.box.height, katanaDefaultViewportHeight());
}
function katanaEmptyDefaultClientBox(context) {
if ([katanaNeedsDefaultClientBox(context.node), katanaIsEmptyBox(context.box)].every(Boolean)) {
return katanaBox(0, 0, katanaDefaultViewportWidth(), katanaDefaultViewportHeight());
}
return null;
}
function katanaDefaultViewportWidth() {
return Number(globalThis.innerWidth ?? globalThis.screen?.width ?? 800);
}
function katanaDefaultViewportHeight() {
return Number(globalThis.innerHeight ?? globalThis.screen?.height ?? 600);
}
function katanaNeedsDefaultClientBox(node) {
return [KATANA_DEFAULT_CLIENT_TAGS.has(node.localName), katanaHasSvgChild(node)].includes(true);
}
function katanaIsEmptyBox(box) {
return [box.width === 0, box.height === 0].every(Boolean);
}
function katanaPositiveOrDefault(value, fallback) {
return value > 0 ? value : fallback;
}
function katanaCssLength(value) {
if (!value) {
return null;
}
return katanaFiniteCssLength(value);
}
function katanaFiniteCssLength(value) {
const number = Number(String(value).replace("px", ""));
if (Number.isFinite(number)) {
return number;
}
return null;
}
function katanaViewBoxSize(value) {
const values = katanaViewBoxValues(value);
if (katanaIsValidViewBox(values)) {
return [values[2], values[3]];
}
return null;
}
function katanaViewBoxValues(value) {
return String(value ?? "")
.split(/\s+/)
.map((it) => Number(it));
}
function katanaIsValidViewBox(values) {
return [values.length === 4, values.every((it) => Number.isFinite(it))].every(Boolean);
}
function katanaHasSvgChild(node) {
return (node.children ?? []).some((child) => child.localName === "svg");
}
Object.defineProperty(KatanaNode.prototype, "textContent", {
get() {
return katanaTextContent(this);
},
set(value) {
this._textContent = String(value ?? "");
this.children = [];
this.childNodes = this.children;
},
});
Object.defineProperty(KatanaNode.prototype, "innerText", {
get() {
return this.textContent;
},
set(value) {
this.textContent = value;
},
});
Object.defineProperty(KatanaNode.prototype, "nodeValue", {
get() {
return this.nodeType === 3 ? this.textContent : null;
},
set(value) {
if (this.nodeType === 3) {
this.textContent = value;
}
},
});
KatanaNode.prototype.append = function append(...values) {
for (const value of values) {
this.appendChild(katanaNodeValue(value));
}
};
KatanaNode.prototype.prepend = function prepend(...values) {
for (const value of values.reverse()) {
this.insertBefore(katanaNodeValue(value), this.firstChild);
}
};
KatanaNode.prototype.replaceChildren = function replaceChildren(...values) {
this.children = [];
this.childNodes = this.children;
this.append(...values);
};
KatanaNode.prototype.contains = function contains(candidate) {
if (this === candidate) {
return true;
}
return katanaNodeChildren(this).some((child) => child.contains(candidate));
};
function katanaNodeChildren(node) {
return node.children ?? [];
}
KatanaNode.prototype.text = function text(...values) {
if (values.length === 0) return this.textContent;
this.textContent = values[0];
return this;
};
KatanaNode.prototype.getBBox = function getBBox() {
return katanaMeasuredBox(this);
};
KatanaNode.prototype.getBoundingClientRect = function getBoundingClientRect() {
const box = katanaElementClientBox(this);
return { ...box, top: box.y, left: box.x, right: box.x + box.width, bottom: box.y + box.height };
};
KatanaNode.prototype.getComputedTextLength = function getComputedTextLength() {
return Math.max(16, katanaTextContent(this).length * 8);
};
KatanaNode.prototype.getScreenCTM = function getScreenCTM() {
return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, inverse: () => this.getScreenCTM() };
};
KatanaNode.prototype.createSVGPoint = function createSVGPoint() {
return {
x: 0,
y: 0,
matrixTransform() {
return { x: this.x, y: this.y };
},
};
};
Object.defineProperties(KatanaNode.prototype, {
clientWidth: {
get() {
return Math.ceil(katanaElementClientBox(this).width);
},
},
clientHeight: {
get() {
return Math.ceil(katanaElementClientBox(this).height);
},
},
offsetWidth: {
get() {
return Math.ceil(katanaElementClientBox(this).width);
},
},
offsetHeight: {
get() {
return Math.ceil(katanaElementClientBox(this).height);
},
},
scrollWidth: {
get() {
return Math.ceil(katanaElementClientBox(this).width);
},
},
scrollHeight: {
get() {
return Math.ceil(katanaElementClientBox(this).height);
},
},
});
function katanaElementClientBox(node) {
return katanaMeasuredClientBox(node);
}
function katanaCssComputedStyleValue(node, name) {
const classNames = katanaCssClassNames(node);
if (classNames.length === 0) {
return "";
}
return katanaCssRuleValue(katanaCssText(node), classNames, name);
}
function katanaCssClassNames(node) {
return String(node?.className ?? "")
.split(/\s+/)
.filter(Boolean);
}
function katanaCssText(node) {
const root = katanaCssRoot(node);
return katanaCssStyleNodes(root)
.map((styleNode) => styleNode.textContent)
.join("\n");
}
function katanaCssRoot(node) {
return katanaCssRootNode(node) || document.documentElement;
}
function katanaCssRootNode(node) {
return KATANA_CSS_ROOT_READERS[Number(Boolean(katanaCssParentNode(node)))](node);
}
function katanaCssParentNode(node) {
return node?.parentNode || null;
}
function katanaCssStyleNodes(root) {
return katanaCssDescendantNodes(root).filter(katanaIsCssStyleNode);
}
function katanaCssDescendantNodes(node) {
return [node].filter(Boolean).flatMap(katanaCssNodeWithDescendants);
}
function katanaCssNodeWithDescendants(node) {
return [node].concat(Array.from(node.children || []).flatMap(katanaCssNodeWithDescendants));
}
function katanaIsCssStyleNode(node) {
return node.localName === "style";
}
function katanaCssRuleValue(cssText, classNames, name) {
return (
Array.from(cssText.matchAll(/([^{}]+)\{([^{}]+)\}/g))
.map((rule) => katanaCssRuleDeclarationValue(rule, classNames, name))
.find(Boolean) ?? ""
);
}
function katanaCssRuleDeclarationValue(rule, classNames, name) {
return (
[rule]
.filter((it) => katanaCssRuleMatchesClass(it[1], classNames))
.map((it) => katanaCssDeclarationValue(it[2], name))[0] ?? ""
);
}
const KATANA_CSS_ROOT_READERS = [
(node) => node,
(node) => katanaCssRootNode(katanaCssParentNode(node)),
];
function katanaCssRuleMatchesClass(selectorText, classNames) {
return selectorText
.split(",")
.some((selector) =>
classNames.some((className) => katanaCssSelectorMatches(selector, className)),
);
}
function katanaCssSelectorMatches(selector, className) {
const classSelector = `.${className}`;
return String(selector)
.trim()
.split(/\s+/)
.some((part) => part === classSelector);
}
function katanaCssDeclarationValue(declarations, name) {
return (
String(declarations)
.split(";")
.map((declaration) => katanaCssDeclarationEntry(declaration))
.find((entry) => entry.name === name)?.value ?? ""
);
}
function katanaCssDeclarationEntry(declaration) {
const parts = String(declaration).split(":");
return {
name: String(parts.shift() ?? "").trim(),
value: parts.join(":").trim(),
};
}
globalThis.getComputedStyle = (node) => katanaComputedStyle(node);
function katanaComputedStyle(node) {
const box = katanaComputedStyleBox(node);
return {
width: `${box.width}px`,
height: `${box.height}px`,
display: "block",
fontSize: katanaComputedFontSize(node),
fontFamily: katanaComputedFontFamily(node),
getPropertyValue(name) {
return katanaComputedPropertyValue(node, this, name);
},
};
}
function katanaComputedFontSize(node) {
return katanaComputedStyleValue(node, "font-size") || "16px";
}
function katanaComputedFontFamily(node) {
return (
katanaComputedStyleValue(node, "font-family") || "trebuchet ms, verdana, arial, sans-serif"
);
}
function katanaComputedPropertyValue(node, style, name) {
return katanaComputedStyleValue(node, name) || style[name] || "";
}
function katanaComputedStyleBox(node) {
if (node) {
return katanaElementClientBox(node);
}
return katanaBox(0, 0, 0, 0);
}
function katanaComputedStyleValue(node, name) {
return (
[katanaRawComputedStyleValue(node, name), katanaCssComputedStyleValue(node, name)]
.filter(Boolean)
.concat([katanaDefaultComputedStyleValue(name)])[0] ?? ""
);
}
function katanaRawComputedStyleValue(node, name) {
return node?.style?.getPropertyValue?.(name) ?? "";
}
function katanaDefaultComputedStyleValue(name) {
if (/^(padding|margin|border).*/.test(name)) {
return "0px";
}
return "";
}
function katanaMeasuredBoxAccurate(node) {
if (KATANA_HIDDEN_LAYOUT_TAGS.has(node.localName)) {
return katanaBox(0, 0, 0, 0);
}
return katanaVisibleMeasuredBoxAccurate(node);
}
function katanaVisibleMeasuredBoxAccurate(node) {
return (
katanaTextElementMeasuredBox(node) ??
katanaTextFragmentMeasuredBox(node) ??
katanaExplicitMeasuredBox(node) ??
katanaDirectMeasuredBox(node) ??
katanaChildTextBox(node)
);
}
function katanaTextElementMeasuredBox(node) {
if (node.localName === "text") {
return katanaTextElementBox(node);
}
return null;
}
function katanaTextFragmentMeasuredBox(node) {
if (["tspan", "#text"].includes(node.localName)) {
return katanaTextFragmentBox(node);
}
return null;
}
function katanaDirectMeasuredBox(node) {
return katanaLineBox(node) ?? katanaCircleBox(node) ?? katanaPathBox(node);
}
function katanaChildTextBox(node) {
const childBox = katanaUnionBox(katanaVisibleChildBoxes(node));
const text = katanaMeasuredNodeText(node, childBox);
return katanaUnionBox([childBox, katanaOptionalTextBox(node, text)].filter(katanaHasArea));
}
function katanaOptionalTextBox(node, text) {
return text ? katanaAnchoredTextNodeBox(node, text, 0, 0) : katanaBox(0, 0, 0, 0);
}
function katanaHasArea(box) {
return [box.width > 0, box.height > 0].includes(true);
}
function katanaPathBox(node) {
return katanaSvgPathBox(node) ?? katanaSvgPointsBox(node);
}
function katanaSvgPathBox(node) {
if (node.localName === "path") {
return katanaOptionalNumberListBox(node.getAttribute("d"));
}
return null;
}
function katanaSvgPointsBox(node) {
if (["polygon", "polyline"].includes(node.localName)) {
return katanaOptionalNumberListBox(node.getAttribute("points"));
}
return null;
}
function katanaOptionalNumberListBox(value) {
return value ? katanaNumberListBox(value) : null;
}
function katanaNumberListBox(value) {
const numbers = Array.from(String(value).matchAll(/-?\d+(?:\.\d+)?(?:e-?\d+)?/gi)).map((match) =>
Number(match[0]),
);
if (numbers.length < 2) {
return null;
}
const xs = numbers.filter((_value, index) => index % 2 === 0);
const ys = numbers.filter((_value, index) => index % 2 === 1);
return katanaBox(
Math.min(...xs),
Math.min(...ys),
Math.max(...xs) - Math.min(...xs),
Math.max(...ys) - Math.min(...ys),
);
}
function katanaTextElementBox(node) {
const lines = katanaTextLines(node);
const text = katanaTextElementText(node, lines);
if (!text) {
return katanaBox(0, 0, 0, 0);
}
return katanaUnionBox(
katanaTextLineValues(node, text, lines).map((line, index) =>
katanaTextLineBox(node, line, index),
),
);
}
function katanaTextElementText(node, lines) {
return lines.length === 0 ? katanaTextContent(node) : lines.map((line) => line.text).join("");
}
function katanaTextLineValues(node, text, lines) {
if (lines.length === 0) {
return [{ text, x: katanaNumberAttr(node, "x"), y: katanaNumberAttr(node, "y") }];
}
return lines;
}
function katanaTextLineBox(node, line, index) {
const x = katanaLineValueOrDefault(line.x, katanaNumberAttrOrDefault(node, "x", 0));
const y = katanaLineValueOrDefault(line.y, katanaTextLineFallbackY(node, index));
return katanaAnchoredTextNodeBox(node, line.text, x, y);
}
function katanaLineValueOrDefault(value, fallback) {
return value ?? fallback;
}
function katanaTextLineFallbackY(node, index) {
return (katanaNumberAttr(node, "y") ?? 0) + index * katanaLineHeight(node);
}
function katanaTextFragmentBox(node) {
const text = katanaFragmentText(node);
if (text) {
return katanaAnchoredTextNodeBox(
katanaTextFragmentParent(node),
text,
katanaNumberAttrOrDefault(node, "x", 0),
katanaNumberAttrOrDefault(node, "y", 0),
);
}
return katanaBox(0, 0, 0, 0);
}
function katanaTextFragmentParent(node) {
return node.parentNode ?? node;
}
function katanaFragmentText(node) {
return [katanaOwnText(node), katanaTextContent(node)].find(Boolean) ?? "";
}
KatanaNode.prototype.getBBox = function getBBox() {
return katanaMeasuredBoxAccurate(this);
};
function katanaTextLines(node) {
return katanaTextTspans(node).reduce(katanaAppendTextLine, { lines: [], current: null }).lines;
}
function katanaTextTspans(node) {
return katanaDescendantElements(node, "tspan")
.filter((child) => katanaTextContent(child).length > 0)
.filter((child) => !katanaHasTextTspanAncestor(child, node));
}
function katanaHasTextTspanAncestor(child, root) {
return katanaTextTspanAncestors(child, root).some(katanaIsFilledTextTspan);
}
function katanaTextTspanAncestors(child, root) {
return katanaTextTspanAncestorList(child.parentNode, root);
}
function katanaTextTspanAncestorList(node, root) {
return KATANA_TEXT_TSPAN_ANCESTOR_READERS[Number(katanaHasTextAncestorNode(node, root))](
node,
root,
);
}
function katanaHasTextAncestorNode(node, root) {
return Boolean(node) && node !== root;
}
function katanaIsFilledTextTspan(node) {
return [node.localName === "tspan", katanaTextContent(node).length > 0].every(Boolean);
}
function katanaAppendTextLine(state, tspan, index) {
const next = katanaTextLineState(state, tspan, index);
next.current.text += katanaTextContent(tspan);
return next;
}
function katanaTextLineState(state, tspan, index) {
return KATANA_TEXT_LINE_STATE_READERS[Number(katanaStartsTextLine(tspan, index))](state, tspan);
}
function katanaStartsTextLine(tspan, index) {
return [
index === 0,
tspan.hasAttribute("x"),
Math.abs(katanaSvgTextLengthAttr(tspan, "dy") ?? 0) >= 1,
].includes(true);
}
function katanaStartTextLine(state, tspan) {
const line = { text: "", x: katanaNumberAttr(tspan, "x"), y: katanaTspanLineY(tspan) };
return { lines: [...state.lines, line], current: line };
}
function katanaTspanLineY(tspan) {
const values = [katanaSvgTextLengthAttr(tspan, "y"), katanaSvgTextLengthAttr(tspan, "dy")];
return KATANA_TSPAN_LINE_Y_READERS[Number(values.some(katanaIsSvgTextLengthValue))](values);
}
function katanaIsSvgTextLengthValue(value) {
return value !== null;
}
function katanaSvgTextLengthAttr(node, name) {
return [String(node.getAttribute?.(name) ?? "")]
.filter(Boolean)
.map((raw) => katanaSvgTextLengthValue(node, raw))
.concat([null])[0];
}
function katanaSvgTextLengthValue(node, raw) {
return [raw.match(/^(-?\d+(?:\.\d+)?)([a-z%]*)$/i)]
.filter(Boolean)
.map((match) => katanaSvgTextLengthMatchValue(node, match))
.concat([null])[0];
}
function katanaSvgTextLengthMatchValue(node, match) {
return [Number(match[1])]
.filter(Number.isFinite)
.map((value) => katanaSvgTextLengthPixels(node, value, match[2]))
.concat([null])[0];
}
function katanaSvgTextLengthPixels(node, value, unit) {
return (KATANA_SVG_TEXT_LENGTH_UNITS[unit] ?? KATANA_SVG_TEXT_LENGTH_UNITS.px)(node, value);
}
function katanaDescendantElements(node, tagName) {
return Array.from(node.children).flatMap((child) => katanaDescendantElement(child, tagName));
}
function katanaDescendantElement(child, tagName) {
return [katanaMatchingDescendantElement(child, tagName)]
.filter(Boolean)
.concat(Array.from(child.children).flatMap((node) => katanaDescendantElement(node, tagName)));
}
function katanaMatchingDescendantElement(child, tagName) {
return [child].filter((node) => node.localName === tagName)[0] ?? null;
}
const KATANA_TEXT_TSPAN_ANCESTOR_READERS = [
() => [],
(node, root) => [node].concat(katanaTextTspanAncestorList(node.parentNode, root)),
];
const KATANA_TEXT_LINE_STATE_READERS = [
(state) => state,
(state, tspan) => katanaStartTextLine(state, tspan),
];
function katanaSumTspanLineY(values) {
return katanaOptionalSvgTextLength(values[0]) + katanaOptionalSvgTextLength(values[1]);
}
function katanaOptionalSvgTextLength(value) {
return [value].filter(katanaIsSvgTextLengthValue).concat([0])[0];
}
const KATANA_TSPAN_LINE_Y_READERS = [() => null, (values) => katanaSumTspanLineY(values)];
const KATANA_SVG_TEXT_LENGTH_UNITS = {
em: (node, value) =>
value * katanaFiniteFontSize(Number(String(katanaLineHeightFontSize(node)).replace("px", ""))),
px: (_node, value) => value,
};
const KATANA_ASCII_KERNING_PAIRS = {
'"T': -2.805,
"n'": -0.993,
"'t": -0.985,
"'w": -0.984,
"<<": 0.781,
">>": 0.781,
"E]": -2.117,
"M]": -2.118,
"P]": -2.125,
Pa: -0.75,
Pe: -0.743,
Ph: -0.742,
Po: -0.742,
Pr: -0.75,
Re: -0.649,
Ro: -0.649,
Ta: -1.992,
Te: -1.985,
Ti: -0.665,
To: -1.984,
Tu: -2.062,
Tw: -2.211,
Ty: -1.836,
Ve: -1.031,
Wa: -0.883,
We: -0.735,
Ye: -1.68,
Yo: -1.836,
"e'": -0.993,
"e,": -2.118,
"e?": -2.118,
"k,": -2.117,
"n,": -2.117,
"p;": -2.117,
's"': -2.805,
"s,": -2.118,
"t!": -2.125,
"u!": -2.117,
"u?": -2.117,
"v.": -2.149,
"y?": -2.125,
"y]": -2.125,
};
const KATANA_ASCII_TEXT_WIDTHS = {
" ": 4.82,
"'": 3.547,
$: 8.391,
"(": 5.875,
")": 5.875,
"-": 5.875,
".": 5.875,
":": 5.875,
0: 8.391,
1: 8.391,
2: 8.391,
3: 8.391,
4: 8.391,
5: 8.391,
6: 8.391,
7: 8.391,
8: 8.391,
9: 8.391,
A: 9.438,
B: 9.055,
C: 9.57,
D: 9.813,
E: 8.57,
F: 8.398,
G: 10.82,
H: 10.469,
I: 4.453,
J: 7.625,
K: 9.211,
L: 8.102,
M: 11.352,
N: 10.211,
O: 10.781,
P: 8.922,
Q: 10.813,
R: 9.313,
S: 7.695,
T: 9.289,
U: 10.375,
V: 9.398,
W: 13.633,
X: 8.906,
Y: 9.125,
Z: 8.805,
_: 8.391,
a: 8.406,
b: 8.914,
c: 7.922,
d: 8.914,
e: 8.727,
f: 5.914,
g: 8.031,
h: 8.742,
i: 4.563,
j: 5.867,
k: 8.07,
l: 4.719,
m: 13.281,
n: 8.742,
o: 8.586,
p: 8.914,
q: 8.914,
r: 6.219,
s: 6.477,
t: 6.344,
u: 8.742,
v: 7.836,
w: 11.906,
x: 8.016,
y: 7.891,
z: 7.594,
};
function katanaAnchoredTextNodeBox(node, text, x, y) {
const width = Math.max(1, katanaTextNodeWidth(node, text));
const height = katanaLineHeight(node);
return katanaBox(
katanaAnchoredTextLeft(katanaTextAnchor(node), x, width),
y - height * 0.8,
width,
height,
);
}
function katanaAnchoredTextLeft(anchor, x, width) {
return (KATANA_TEXT_ANCHORS[anchor] ?? KATANA_TEXT_ANCHORS.start)(x, width);
}
const KATANA_TEXT_ANCHORS = {
end: (x, width) => x - width,
middle: (x, width) => x - width / 2,
start: (x) => x,
};
function katanaTextAnchor(node) {
return String(katanaTextAnchorValues(node).find(Boolean) ?? "start");
}
function katanaTextAnchorValues(node) {
return [
node.getAttribute?.("text-anchor"),
node.style?.getPropertyValue?.("text-anchor"),
node.parentNode?.getAttribute?.("text-anchor"),
];
}
function katanaLineHeight(node) {
const fontSize = Number(String(katanaLineHeightFontSize(node)).replace("px", ""));
return katanaBrowserTextBoxHeight(katanaFiniteFontSize(fontSize));
}
function katanaBrowserTextBoxHeight(fontSize) {
const measured = KATANA_TEXT_BOX_HEIGHTS[String(fontSize)];
if (measured) {
return measured;
}
return Math.max(12, Math.ceil(fontSize * 1.15));
}
const KATANA_TEXT_BOX_HEIGHTS = {
10: 11,
11: 12.25,
12: 14,
14: 16,
16: 19,
18: 21,
20: 23,
};
function katanaLineHeightFontSize(node) {
return katanaLineHeightFontSizeValues(node).find(Boolean) ?? "16";
}
function katanaLineHeightFontSizeValues(node) {
return [
node.style?.getPropertyValue?.("font-size"),
katanaCssComputedStyleValue(node, "font-size"),
node.getAttribute?.("font-size"),
node.parentNode?.style?.getPropertyValue?.("font-size"),
katanaCssComputedStyleValue(node.parentNode, "font-size"),
node.parentNode?.getAttribute?.("font-size"),
];
}
function katanaFiniteFontSize(fontSize) {
if (Number.isFinite(fontSize)) {
return fontSize;
}
return 16;
}
function katanaTextNodeWidth(node, text) {
return katanaTextWidth(text) * katanaTextWidthScale(node);
}
function katanaTextWidthScale(node) {
return (
katanaFiniteFontSize(Number(String(katanaLineHeightFontSize(node)).replace("px", ""))) / 16
);
}
function katanaTextWidth(text) {
const chars = Array.from(katanaMeasuredTextValue(text));
const characterWidth = chars
.map((char) => katanaCharacterWidth(char))
.reduce((width, charWidth) => width + charWidth, 0);
return characterWidth + katanaTextKerningWidth(chars);
}
function katanaMeasuredTextValue(text) {
return String(text).replace(/&(?:amp;)?nbsp;| /g, "\u00A0");
}
function katanaTextKerningWidth(chars) {
return chars
.slice(0, -1)
.map((char, index) => katanaKerningPairWidth(char, chars[index + 1]))
.reduce((width, pairWidth) => width + pairWidth, 0);
}
function katanaKerningPairWidth(left, right) {
return KATANA_KERNING_PAIR_WIDTH_READERS[Number(katanaHasWideKerningChar(left, right))](
left,
right,
);
}
function katanaHasWideKerningChar(left, right) {
return [left, right].some(katanaIsWideTextChar);
}
function katanaIsWideTextChar(char) {
return char.charCodeAt(0) > 255;
}
function katanaCharacterWidth(char) {
return KATANA_CHARACTER_WIDTHS[Number(char.charCodeAt(0) > 255)](char);
}
function katanaAsciiCharacterWidth(char) {
if (char.charCodeAt(0) === 160) {
return KATANA_ASCII_TEXT_WIDTHS[" "];
}
return [KATANA_ASCII_TEXT_WIDTHS[char]].filter(Boolean).concat([8])[0];
}
function katanaWideCharacterWidth(char) {
return KATANA_WIDE_CHARACTER_WIDTHS[Number(globalThis.__katanaMermaidDiagramType === "kanban")](
char,
);
}
const KATANA_WIDE_CHARACTER_WIDTHS = [
katanaDefaultWideCharacterWidth,
() => 12.5,
];
function katanaDefaultWideCharacterWidth(char) {
if (katanaIsWidePunctuation(char)) {
return 20;
}
return KATANA_DEFAULT_WIDE_CHARACTER_WIDTHS[Number(katanaIsCjkIdeograph(char))]();
}
function katanaIsCjkIdeograph(char) {
const codePoint = katanaCharacterCodePoint(char);
return KATANA_CJK_IDEOGRAPH_RULES.every((rule) => rule(codePoint));
}
function katanaCharacterCodePoint(char) {
return char.codePointAt(0) ?? 0;
}
function katanaIsCjkIdeographStart(codePoint) {
return codePoint >= 0x4e00;
}
function katanaIsCjkIdeographEnd(codePoint) {
return codePoint <= 0x9fff;
}
function katanaIsWidePunctuation(char) {
return ["。", "、"].includes(char);
}
const KATANA_DEFAULT_WIDE_CHARACTER_WIDTHS = [() => 15.8, () => 16.3];
const KATANA_CJK_IDEOGRAPH_RULES = [katanaIsCjkIdeographStart, katanaIsCjkIdeographEnd];
const KATANA_CHARACTER_WIDTHS = [katanaAsciiCharacterWidth, katanaWideCharacterWidth];
const KATANA_KERNING_PAIR_WIDTH_READERS = [
(left, right) => KATANA_ASCII_KERNING_PAIRS[`${left}${right}`] ?? 0,
() => 0,
];
KatanaNode.prototype.getComputedTextLength = function getComputedTextLength() {
const lines = katanaComputedTextLines(this);
return Math.max(1, ...lines.map((line) => katanaTextNodeWidth(this, line)));
};
function katanaComputedTextLines(node) {
if (node.localName === "text") {
return katanaTextLines(node).map((line) => line.text);
}
return [katanaTextContent(node)];
}
globalThis.navigator = {
userAgent: "KatanA Rust-managed Draw.io runtime",
appName: "Netscape",
language: "en-US",
languages: ["en-US", "en"],
appVersion: "KatanA",
vendor: "",
platform: "MacIntel",
maxTouchPoints: 0,
};
globalThis.location = {
href: "https://viewer.diagrams.net/?offline=1&embed=1&proto=json",
host: "viewer.diagrams.net",
hostname: "viewer.diagrams.net",
protocol: "https:",
search: "?offline=1&embed=1&proto=json",
hash: "",
pathname: "/",
toString() {
return this.href;
},
};
globalThis.window.location = globalThis.location;
globalThis.window.innerWidth = 1280;
globalThis.window.innerHeight = 800;
globalThis.window.top = globalThis.window;
globalThis.document.referrer = "";
globalThis.document.location = globalThis.location;
globalThis.document.compatMode = "CSS1Compat";
globalThis.localStorage = {
getItem() {
return null;
},
setItem() {},
removeItem() {},
};
globalThis.sessionStorage = globalThis.localStorage;
globalThis.atob = katanaDrawioAtob;
Date.prototype.toLocaleDateString = katanaDrawioLocaleDate;
Date.prototype.toLocaleString = katanaDrawioLocaleDate;
function katanaDrawioLocaleDate() {
return this.toISOString().slice(0, 10);
}
function katanaDrawioAtob(value) {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const state = { bits: 0, buffer: 0, output: "", stopped: false };
const input = String(value).replace(/[^A-Za-z0-9+/=]/g, "");
Array.from(input).forEach((char) => {
katanaDrawioReadBase64Char(state, chars.indexOf(char));
});
return state.output;
}
function katanaDrawioReadBase64Char(state, code) {
if (state.stopped) {
return;
}
katanaDrawioApplyBase64Code(state, code);
}
function katanaDrawioApplyBase64Code(state, code) {
if (katanaDrawioStopsBase64(code)) {
state.stopped = true;
return;
}
state.buffer = (state.buffer << 6) | code;
state.bits += 6;
katanaDrawioFlushBase64Byte(state);
}
function katanaDrawioStopsBase64(code) {
return [code < 0, code === 64].some(Boolean);
}
function katanaDrawioFlushBase64Byte(state) {
if (state.bits >= 8) {
state.bits -= 8;
state.output += String.fromCharCode((state.buffer >> state.bits) & 0xff);
}
}
globalThis.urlParams = globalThis.urlParams || {};
globalThis.mxLoadResources = false;
globalThis.mxForceIncludes = false;
globalThis.mxResourceExtension = ".txt";
globalThis.mxBasePath = "";
globalThis.STYLE_PATH = "styles";
globalThis.SHAPES_PATH = "shapes";
globalThis.STENCIL_PATH = "stencils";
globalThis.IMAGE_PATH = "";
globalThis.RESOURCES_PATH = "";
globalThis.GRAPH_IMAGE_PATH = "img";
globalThis.EXPORT_URL = "";
if (typeof KatanaNode === "function") {
Object.defineProperty(KatanaNode.prototype, "classList", {
get() {
return katanaDrawioClassList(this);
},
});
KatanaNode.prototype.toString = function katanaDrawioNodeToString() {
return katanaDrawioNodeClassName(this);
};
}
function katanaDrawioClassList(node) {
return {
add(name) {
katanaSetDrawioClasses(node, [...katanaDrawioClasses(node), name]);
},
remove(name) {
katanaSetDrawioClasses(
node,
katanaDrawioClasses(node).filter((it) => it !== name),
);
},
contains(name) {
return katanaDrawioClasses(node).includes(name);
},
};
}
function katanaDrawioClasses(node) {
return String(node.className || "")
.split(/\s+/)
.filter(Boolean);
}
function katanaSetDrawioClasses(node, values) {
node.setAttribute("class", Array.from(new Set(values)).join(" "));
}
function katanaDrawioNodeClassName(node) {
if (katanaIsDrawioSvgForeignObject(node)) {
return "[object SVGForeignObjectElement]";
}
return "[object Element]";
}
function katanaIsDrawioSvgForeignObject(node) {
return [
katanaDrawioNodeNamespace(node).includes("svg"),
katanaDrawioNodeLocalName(node) === "foreignobject",
].every(Boolean);
}
function katanaDrawioNodeNamespace(node) {
return String(node.namespaceURI || "");
}
function katanaDrawioNodeLocalName(node) {
return String(node.localName || "").toLowerCase();
}
function katanaDrawioRuntimeContext() {
return {
request: globalThis.__katanaDrawioRequest ?? {},
resources: new Map(),
stencilXmlFiles: new Map(),
};
}
function katanaRegisterDrawioResources(context) {
(context.request.resources ?? []).forEach((resource) => {
katanaRegisterDrawioResource(context, resource);
});
}
function katanaRegisterDrawioResource(context, resource) {
const path = katanaDrawioResourcePath(resource.path);
context.resources.set(path, resource);
katanaRunDrawioShapeResource(resource);
katanaStoreDrawioStencilResource(context, path, resource);
}
function katanaRunDrawioShapeResource(resource) {
if (resource.mime_type !== "application/javascript") {
return;
}
katanaExecuteDrawioShapeResource(resource.path, katanaDrawioResourceContent(resource));
}
function katanaExecuteDrawioShapeResource(path, content) {
try {
Function(content).call(globalThis);
} catch (error) {
katanaTrackDrawioResourceError(path, error);
}
}
function katanaTrackDrawioResourceError(path, error) {
globalThis.__katanaDrawioResourceErrors.push(`${path}: ${String(error)}`);
}
function katanaStoreDrawioStencilResource(context, path, resource) {
if (!katanaIsDrawioStencilResource(path, resource)) {
return;
}
context.stencilXmlFiles.set(path, katanaDrawioResourceContent(resource));
}
function katanaIsDrawioStencilResource(path, resource) {
return [
resource.mime_type === "text/xml",
["stencils/", "stencils\\"].some((prefix) => path.indexOf(prefix) === 0),
].every(Boolean);
}
function katanaDrawioResourceResponse(resources, url) {
const path = katanaDrawioResourcePath(url);
const resource = resources.get(path);
katanaTrackDrawioMissingResource(resource, path);
return katanaDrawioResponseForResource(resource);
}
function katanaTrackDrawioMissingResource(resource, path) {
if (!resource) {
globalThis.__katanaDrawioMissingResources.push(path);
}
}
function katanaDrawioResponseForResource(resource) {
return {
getStatus() {
return katanaDrawioResourceStatus(resource);
},
getText() {
return katanaDrawioResourceContent(resource);
},
getXml() {
return new DOMParser().parseFromString(katanaDrawioResourceContent(resource), "text/xml");
},
getDocumentElement() {
return this.getXml().documentElement;
},
isReady() {
return true;
},
};
}
function katanaDrawioResourceStatus(resource) {
if (resource) {
return 200;
}
return 404;
}
function katanaDrawioResourceContent(resource) {
if (resource) {
return katanaDecodeDrawioResourceContent(resource);
}
return "";
}
function katanaDecodeDrawioResourceContent(resource) {
if (resource.encoding === "base64") {
return atob(resource.content);
}
return resource.content;
}
function katanaDrawioResourceBase64(resource) {
if (resource.encoding === "base64") {
return resource.content;
}
return btoa(resource.content);
}
function katanaDrawioResourcePath(url) {
let path = String(url ?? "");
path = path.replace(/^https?:\/\/[^/]+\//, "");
path = path.replace(/^katana:\/\/drawio\//, "");
path = path.replace(/[?#].*$/, "");
path = path.replace(/^\/+/, "");
return path;
}
function katanaInstallDrawioStencilLoader(context) {
if (typeof mxStencilRegistry !== "object") {
return;
}
const originalGetStencil = mxStencilRegistry.getStencil;
mxStencilRegistry.getStencil = function getStencil(name) {
return katanaGetDrawioStencil(this, originalGetStencil, context.stencilXmlFiles, name);
};
}
function katanaGetDrawioStencil(registry, originalGetStencil, stencilXmlFiles, name) {
const stencil = originalGetStencil.call(registry, name);
if (stencil) {
return stencil;
}
return katanaFindDrawioStencil(stencilXmlFiles, name);
}
function katanaFindDrawioStencil(stencilXmlFiles, name) {
const stencil = Array.from(stencilXmlFiles.values())
.map((content) => katanaStencilFromXmlContent(content, name))
.find(Boolean);
return katanaNullableDrawioStencil(stencil);
}
function katanaNullableDrawioStencil(stencil) {
if (stencil) {
return stencil;
}
return null;
}
function katanaStencilFromXmlContent(content, name) {
const stencilName = katanaDrawioStencilName(content, name);
const match = content.match(katanaDrawioStencilPattern(stencilName));
if (!match) {
return null;
}
return katanaCreateDrawioStencil(name, match[0]);
}
function katanaDrawioStencilName(content, name) {
const exactName = String(name);
const groupedName = katanaDrawioGroupedStencilName(content, exactName);
if (groupedName) {
return groupedName;
}
return exactName;
}
function katanaDrawioGroupedStencilName(content, exactName) {
const group = katanaDrawioStencilGroup(content);
if (!katanaDrawioNameBelongsToGroup(exactName, group)) {
return "";
}
return katanaFindDrawioGroupedStencilName(content, exactName.slice(group.length + 1));
}
function katanaDrawioStencilGroup(content) {
const match = content.match(/<shapes[^>]+name="([^"]+)"/);
return match?.[1] ?? "";
}
function katanaDrawioNameBelongsToGroup(name, group) {
return Boolean(group) && name.toLowerCase().startsWith(`${group.toLowerCase()}.`);
}
function katanaFindDrawioGroupedStencilName(content, normalizedName) {
return katanaDrawioShapeNames(content).find(
(shapeName) => katanaNormalizeDrawioStencilName(shapeName) === normalizedName,
);
}
function katanaDrawioShapeNames(content) {
return Array.from(content.matchAll(/<(shape|stencil)[^>]+name="([^"]+)"/gm)).map(
(match) => match[2],
);
}
function katanaNormalizeDrawioStencilName(name) {
return String(name)
.trim()
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
.replace(/[\s-]+/g, "_")
.toLowerCase();
}
function katanaDrawioStencilPattern(name) {
const escapedName = String(name).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
return new RegExp(`<(shape|stencil)[^>]+name="${escapedName}"[^>]*>([\\s\\S]*?)<\\/\\1>`, "m");
}
function katanaCreateDrawioStencil(name, xml) {
try {
const xmlDoc = new DOMParser().parseFromString(xml, "text/xml");
const stencil = new mxStencil(xmlDoc.documentElement);
mxStencilRegistry.addStencil(name, stencil);
return stencil;
} catch {
return null;
}
}
function katanaDrawioCreateXmlDocument() {
const detached = Object.create(document);
katanaSetupDrawioXmlDocumentBase(detached);
katanaSetupDrawioXmlDocumentFactories(detached);
katanaSetupDrawioXmlDocumentQueries(detached);
return detached;
}
function katanaSetupDrawioXmlDocumentBase(detached) {
detached.nodeType = 9;
detached.documentElement = null;
detached.body = null;
detached.defaultView = globalThis;
}
function katanaSetupDrawioXmlDocumentFactories(detached) {
detached.createElement = (tagName) =>
katanaDrawioOwnedNode(document.createElement(tagName), detached);
detached.createElementNS = (namespaceURI, tagName) =>
katanaDrawioOwnedNode(document.createElementNS(namespaceURI, tagName), detached);
detached.createTextNode = (value) =>
katanaDrawioOwnedNode(document.createTextNode(value), detached);
detached.createDocumentFragment = () =>
katanaDrawioOwnedNode(document.createDocumentFragment(), detached);
detached.importNode = (node, deep) => katanaDrawioOwnedTree(node.cloneNode(deep), detached);
detached.appendChild = (child) => katanaDrawioAppendDocumentChild(detached, child);
}
function katanaSetupDrawioXmlDocumentQueries(detached) {
detached.getElementById = (id) =>
katanaDrawioDocumentElement(detached)?.querySelector(`#${id}`) ?? null;
detached.getElementsByTagName = (tagName) =>
katanaDrawioDocumentElement(detached)?.getElementsByTagName(tagName) ?? [];
}
function katanaDrawioAppendDocumentChild(detached, child) {
katanaDrawioOwnedTree(child, detached);
child.parentNode = detached;
detached.documentElement = child;
return child;
}
function katanaDrawioDocumentElement(detached) {
return detached.documentElement;
}
function katanaDrawioOwnedNode(node, ownerDocument) {
node.ownerDocument = ownerDocument;
return node;
}
function katanaDrawioOwnedTree(node, ownerDocument) {
katanaDrawioOwnedNode(node, ownerDocument);
katanaDrawioNodeChildren(node).forEach((child) => {
katanaDrawioOwnedTree(child, ownerDocument);
});
return node;
}
function katanaDrawioNodeChildren(node) {
if (node.children) {
return node.children;
}
return [];
}
function katanaInstallDrawioMxUtils(context) {
if (typeof mxUtils !== "object") {
return;
}
mxUtils.createXmlDocument = katanaDrawioCreateXmlDocument;
mxUtils.load = (url) => katanaDrawioResourceResponse(context.resources, url);
mxUtils.get = (url, onload, onerror) =>
katanaDrawioGetResource(context.resources, url, onload, onerror);
}
function katanaDrawioGetResource(resources, url, onload, onerror) {
const response = katanaDrawioResourceResponse(resources, url);
katanaDispatchDrawioResourceResponse(response, onload, onerror);
return response;
}
function katanaDispatchDrawioResourceResponse(response, onload, onerror) {
if (katanaDrawioIsOkResponse(response)) {
onload?.(response);
return;
}
onerror?.(response);
}
function katanaDrawioIsOkResponse(response) {
return [response.getStatus() >= 200, response.getStatus() < 300].every(Boolean);
}
function katanaInstallDrawioImageBundles(context) {
if (typeof mxGraph !== "function") {
return;
}
const originalGetImageFromBundles = mxGraph.prototype.getImageFromBundles;
mxGraph.prototype.getImageFromBundles = function getImageFromBundles(key, ...args) {
return katanaDrawioImageFromBundles(
context.resources,
originalGetImageFromBundles,
this,
key,
args,
);
};
}
function katanaDrawioImageFromBundles(resources, originalGetImageFromBundles, graph, key, args) {
const resource = resources.get(katanaDrawioResourcePath(key));
if (katanaIsDrawioSvgResource(resource)) {
return katanaDrawioDataUri(resource);
}
return katanaDrawioBundleFallback(originalGetImageFromBundles, graph, key, args);
}
function katanaIsDrawioSvgResource(resource) {
return resource?.mime_type === "image/svg+xml";
}
function katanaDrawioBundleFallback(originalGetImageFromBundles, graph, key, args) {
if (typeof originalGetImageFromBundles === "function") {
return originalGetImageFromBundles.apply(graph, [key, ...args]);
}
return key;
}
function katanaInstallDrawioSvgImages(context) {
if (typeof mxSvgCanvas2D !== "function") {
return;
}
const originalImage = mxSvgCanvas2D.prototype.image;
mxSvgCanvas2D.prototype.image = function image(x, y, width, height, src, aspect, flipH, flipV) {
originalImage.call(
this,
x,
y,
width,
height,
katanaDrawioResolvedImageSrc(context.resources, src),
aspect,
flipH,
flipV,
);
};
}
function katanaDrawioResolvedImageSrc(resources, src) {
const resource = resources.get(katanaDrawioResourcePath(src));
return [katanaDrawioImageResourceSrc(resource), katanaDrawioExternalImageSrc(src), src].filter(
Boolean,
)[0];
}
function katanaDrawioImageResourceSrc(resource) {
return [resource].filter(Boolean).map(katanaDrawioDataUri).concat([""])[0];
}
function katanaDrawioExternalImageSrc(src) {
return [src]
.filter(katanaIsExternalDrawioImageSrc)
.map(() => KATANA_DRAWIO_TRANSPARENT_IMAGE_SRC)
.concat([""])[0];
}
function katanaIsExternalDrawioImageSrc(src) {
return ["http://", "https://"].some((it) => String(src).startsWith(it));
}
function katanaDrawioDataUri(resource) {
return `data:${resource.mime_type};base64,${katanaDrawioResourceBase64(resource)}`;
}
const KATANA_DRAWIO_TRANSPARENT_IMAGE_SRC =
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
function katanaInstallDrawioOwnerSvgElement() {
if (!katanaNeedsDrawioOwnerSvgElement()) {
return;
}
Object.defineProperty(KatanaNode.prototype, "ownerSVGElement", {
get() {
return katanaOwnerSvgElement(this);
},
});
}
function katanaNeedsDrawioOwnerSvgElement() {
return [
typeof KatanaNode === "function",
!Object.getOwnPropertyDescriptor(KatanaNode.prototype, "ownerSVGElement"),
].every(Boolean);
}
function katanaOwnerSvgElement(node) {
const state = { node, result: null };
while (katanaShouldContinueOwnerSvgSearch(state)) {
katanaSearchOwnerSvgStep(state);
}
return state.result;
}
function katanaShouldContinueOwnerSvgSearch(state) {
return [state.node !== null, state.result === null].every(Boolean);
}
function katanaSearchOwnerSvgStep(state) {
if (String(state.node.nodeName).toLowerCase() === "svg") {
state.result = state.node;
return;
}
state.node = state.node.parentNode;
}
function katanaInstallDrawioRuntimeAdapter() {
globalThis.__katanaDrawioMissingResources = [];
globalThis.__katanaDrawioResourceErrors = [];
const context = katanaDrawioRuntimeContext();
katanaRegisterDrawioResources(context);
katanaInstallDrawioStencilLoader(context);
katanaInstallDrawioMxUtils(context);
katanaInstallDrawioTextConversionGuard();
katanaInstallDrawioSvgTextOutput();
katanaInstallDrawioImageBundles(context);
katanaInstallDrawioSvgImages(context);
katanaInstallDrawioOwnerSvgElement();
}
function katanaInstallDrawioTextConversionGuard() {
const originalConvertHtmlToText = Editor.convertHtmlToText;
Editor.convertHtmlToText = function convertHtmlToText(value) {
return KATANA_DRAWIO_TEXT_CONVERSION_HANDLERS[Number(value != null)](
originalConvertHtmlToText,
value,
);
};
}
const KATANA_DRAWIO_TEXT_CONVERSION_HANDLERS = [
() => "",
(originalConvertHtmlToText, value) => originalConvertHtmlToText.call(Editor, value),
];
function katanaDrawioHtmlLabelText(value) {
return decodeHtmlEntities(
String(value)
.replace(/<\s*br\s*\/?>/gi, "\n")
.replace(/<[^>]+>/g, ""),
);
}
function katanaInstallDrawioSvgTextOutput() {
katanaDisableDrawioForeignObjectWarning();
}
function katanaDisableDrawioForeignObjectWarning() {
if (typeof Graph === "function") {
Graph.prototype.addForeignObjectWarning = function addForeignObjectWarning() {};
}
}
function katanaDrawioSourceContentBox(svg) {
return katanaDrawioSourceCropBox(svg, katanaDrawioSourceGeometryEntries());
}
function katanaDrawioSourceGeometryEntries() {
return [
...katanaDrawioSourceCellGeometryEntries(),
...katanaDrawioSourceUserObjectGeometryEntries(),
]
.filter(katanaHasDrawioSourceGeometryEntry)
.filter(katanaDrawioIsTopLevelSourceGeometryEntry);
}
function katanaDrawioSourceCellGeometryEntries() {
return Array.from(
katanaDrawioRequestSource().matchAll(/<mxCell\b([^>]*)>\s*<mxGeometry\b([^>]*)/g),
).map(katanaDrawioSourceGeometryEntry);
}
function katanaDrawioSourceUserObjectGeometryEntries() {
return Array.from(
katanaDrawioRequestSource().matchAll(
/<(?:UserObject|object)\b([^>]*)>\s*<mxCell\b([^>]*)>\s*<mxGeometry\b([^>]*)/g,
),
).map(katanaDrawioSourceUserObjectGeometryEntry);
}
function katanaDrawioSourceGeometryEntry(match) {
const cellAttributes = katanaDrawioXmlAttributes(match[1]);
const geometryAttributes = katanaDrawioXmlAttributes(match[2]);
return katanaDrawioSourceGeometry(cellAttributes, geometryAttributes);
}
function katanaDrawioSourceUserObjectGeometryEntry(match) {
const userObjectAttributes = katanaDrawioXmlAttributes(match[1]);
const cellAttributes = katanaDrawioXmlAttributes(match[2]);
const geometryAttributes = katanaDrawioXmlAttributes(match[3]);
return katanaDrawioSourceGeometry(userObjectAttributes, geometryAttributes, cellAttributes);
}
function katanaDrawioSourceGeometry(cellAttributes, geometryAttributes, fallbackAttributes) {
return {
id: katanaDrawioCellAttribute(cellAttributes, "id"),
parent: katanaDrawioSourceParentAttribute(cellAttributes, fallbackAttributes),
x: katanaDrawioCoordinateAttribute(geometryAttributes, "x"),
y: katanaDrawioCoordinateAttribute(geometryAttributes, "y"),
width: katanaDrawioRequiredNumberAttribute(geometryAttributes, "width"),
height: katanaDrawioRequiredNumberAttribute(geometryAttributes, "height"),
};
}
function katanaDrawioSourceParentAttribute(cellAttributes, fallbackAttributes) {
return [
katanaDrawioOptionalCellAttribute(cellAttributes, "parent"),
katanaDrawioOptionalCellAttribute(fallbackAttributes, "parent"),
]
.filter(Boolean)
.concat([""])[0];
}
function katanaDrawioOptionalCellAttribute(attributes, name) {
return attributes ? katanaDrawioCellAttribute(attributes, name) : "";
}
function katanaHasDrawioSourceGeometryEntry(entry) {
return [
entry.id,
Number.isFinite(entry.x),
Number.isFinite(entry.y),
entry.width > 0,
entry.height > 0,
].every(Boolean);
}
function katanaDrawioIsTopLevelSourceGeometryEntry(entry) {
return [
katanaDrawioIsRootLevelSourceParent(entry.parent),
katanaDrawioSourceCellParentMap().get(entry.parent) === "0",
].some(Boolean);
}
function katanaDrawioIsRootLevelSourceParent(parent) {
return ["", "1"].includes(parent);
}
function katanaDrawioSourceCellParentMap() {
return new Map(
Array.from(katanaDrawioRequestSource().matchAll(/<mxCell\b([^>]*)/g))
.map((match) => katanaDrawioXmlAttributes(match[1]))
.filter(katanaDrawioHasSourceCellParent)
.map(katanaDrawioSourceCellParentEntry),
);
}
function katanaDrawioHasSourceCellParent(attributes) {
return [attributes.has("id"), attributes.has("parent")].every(Boolean);
}
function katanaDrawioSourceCellParentEntry(attributes) {
return [
katanaDrawioCellAttribute(attributes, "id"),
katanaDrawioCellAttribute(attributes, "parent"),
];
}
function katanaDrawioCoordinateAttribute(attributes, name) {
return katanaDrawioOptionalNumberAttribute(attributes, name, 0);
}
function katanaDrawioRequiredNumberAttribute(attributes, name) {
return katanaDrawioOptionalNumberAttribute(attributes, name, Number.NaN);
}
function katanaDrawioOptionalNumberAttribute(attributes, name, fallback) {
const value = katanaDrawioCellAttribute(attributes, name);
return value === "" ? fallback : Number(value);
}
function katanaDrawioSourceCropBox(svg, entries) {
const sourceBox = katanaDrawioUnionBox(entries);
const offset = katanaDrawioSourceCropOffset(svg, entries);
return [sourceBox, offset].every(Boolean)
? katanaDrawioShiftedSourceCropBox(sourceBox, offset)
: null;
}
function katanaDrawioSourceCropOffset(svg, entries) {
return katanaDrawioMedianOffset(katanaDrawioSourceCropOffsets(svg, entries));
}
function katanaDrawioSourceCropOffsets(svg, entries) {
return entries.map((entry) => katanaDrawioSourceCellOffset(svg, entry)).filter(Boolean);
}
function katanaDrawioSourceCellOffset(svg, entry) {
const box = katanaDrawioMeasuredSourceCellBox(svg, entry);
return box ? { x: box.x - entry.x, y: box.y - entry.y } : null;
}
function katanaDrawioMeasuredSourceCellBox(svg, entry) {
return [katanaDrawioCellGroup(svg, entry.id)]
.filter(Boolean)
.map(katanaDrawioCellShapeBox)
.filter(Boolean)
.filter((box) => katanaDrawioSimilarSourceBox(box, entry))
.concat([null])[0];
}
function katanaDrawioSimilarSourceBox(box, entry) {
return [
katanaDrawioSimilarSourceSize(box.width, entry.width),
katanaDrawioSimilarSourceSize(box.height, entry.height),
].every(Boolean);
}
function katanaDrawioSimilarSourceSize(actual, expected) {
return Math.abs(actual - expected) <= Math.max(4, expected * 0.02);
}
function katanaDrawioMedianOffset(offsets) {
return offsets.length === 0
? null
: {
x: katanaDrawioMedianValue(offsets.map((offset) => offset.x)),
y: katanaDrawioMedianValue(offsets.map((offset) => offset.y)),
};
}
function katanaDrawioMedianValue(values) {
const sorted = [...values].sort((left, right) => left - right);
return sorted[Math.floor(sorted.length / 2)];
}
function katanaDrawioShiftedSourceCropBox(box, offset) {
return {
x: Math.floor(box.x + offset.x),
y: Math.floor(box.y + offset.y),
width: Math.ceil(box.width),
height: Math.ceil(box.height),
};
}
const KATANA_DRAWIO_EXTERNAL_IMAGE_EXPORT_BOTTOM_PADDING = 11;
function katanaRemoveOversizedDrawioLabelBackgrounds(svg) {
Array.from(svg.querySelectorAll("rect"))
.filter(katanaIsDrawioTextLabelBackground)
.forEach(katanaRemoveDrawioNode);
Array.from(svg.querySelectorAll("rect"))
.filter(katanaIsDrawioPageSizedLabelBackground)
.forEach(katanaRemoveDrawioNode);
}
function katanaRemoveDrawioNode(node) {
node.parentNode?.removeChild(node);
}
function katanaIsDrawioPageSizedLabelBackground(rect) {
return [
katanaDrawioColorValue(rect, "fill") === "#ffffff",
rect.getAttribute("stroke") === "none",
katanaDrawioNodeWidth(rect) > katanaDrawioSvgBox(rect.ownerSVGElement).width * 0.5,
].every(Boolean);
}
function katanaIsDrawioTextLabelBackground(rect) {
return [
katanaDrawioColorValue(rect, "fill") === "#ffffff",
rect.getAttribute("stroke") === "none",
katanaDrawioNodeWidth(rect) > 16,
katanaHasDrawioTextSibling(rect),
].every(Boolean);
}
function katanaHasDrawioTextSibling(rect) {
return Array.from(rect.parentNode?.querySelectorAll("text") ?? []).length > 0;
}
function katanaDrawioColorValue(node, name) {
return String(node.getAttribute(name) ?? "").toLowerCase();
}
function katanaCropDrawioSvgToContent(svg) {
katanaApplyDrawioCrop(svg, katanaDrawioCropBox(svg));
}
function katanaDrawioCropBox(svg) {
return KATANA_DRAWIO_CROP_BOX_READERS[Number(katanaDrawioShouldMeasureRenderedContent())](svg);
}
const KATANA_DRAWIO_CROP_BOX_READERS = [
(svg) => [katanaDrawioSourceContentBox(svg), katanaDrawioContentBox(svg)].filter(Boolean)[0],
(svg) => katanaDrawioContentBox(svg),
];
function katanaDrawioShouldMeasureRenderedContent() {
return katanaDrawioRequestSource().includes("mxgraph.aws3d.");
}
function katanaDrawioContentBox(svg) {
return katanaDrawioOptionalContentBox(svg) ?? katanaDrawioEmptyContentBox();
}
function katanaDrawioOptionalContentBox(svg) {
const boxes = katanaDrawioContentElements(svg).map(katanaDrawioElementBox);
return katanaDrawioUnionBox(boxes.filter(katanaDrawioHasArea));
}
function katanaDrawioContentElements(svg) {
return katanaDrawioContentTagNames().flatMap((tagName) =>
Array.from(svg.querySelectorAll(tagName)),
);
}
function katanaDrawioContentTagNames() {
return ["rect", "path", "ellipse", "circle", "line", "polygon", "polyline", "image", "text"];
}
function katanaDrawioElementBox(element) {
return katanaDrawioTranslatedBox(element.getBBox(), katanaDrawioTranslate(element));
}
function katanaDrawioTranslatedBox(box, translate) {
return {
x: box.x + translate.x,
y: box.y + translate.y,
width: box.width,
height: box.height,
};
}
function katanaDrawioTranslate(element) {
return katanaDrawioParentTranslate(element.parentNode);
}
function katanaDrawioParentTranslate(node) {
return node
? katanaDrawioAddTranslate(katanaDrawioParentTranslate(node.parentNode), node)
: { x: 0, y: 0 };
}
function katanaDrawioAddTranslate(translate, node) {
const next = katanaDrawioNodeTranslate(node);
return { x: translate.x + next.x, y: translate.y + next.y };
}
function katanaDrawioNodeTranslate(node) {
return katanaDrawioTranslateMatch(String(node?.getAttribute?.("transform") ?? ""));
}
function katanaDrawioTranslateMatch(transform) {
const match = transform.match(/translate\(([-\d.]+)(?:[,\s]+([-\d.]+))?\)/);
return [match]
.filter(Boolean)
.map(katanaDrawioTranslateFromMatch)
.concat([{ x: 0, y: 0 }])[0];
}
function katanaDrawioTranslateFromMatch(match) {
return { x: Number(match[1]), y: Number(match[2] ?? 0) };
}
function katanaDrawioUnionBox(boxes) {
return boxes.length === 0 ? null : katanaDrawioUnionNonEmptyBox(boxes);
}
function katanaDrawioUnionNonEmptyBox(boxes) {
const left = Math.min(...boxes.map((box) => box.x));
const top = Math.min(...boxes.map((box) => box.y));
const right = Math.max(...boxes.map(katanaDrawioBoxRight));
const bottom = Math.max(...boxes.map(katanaDrawioBoxBottom));
return {
x: Math.floor(left),
y: Math.floor(top),
width: Math.ceil(right - left),
height: Math.ceil(bottom - top),
};
}
function katanaDrawioBoxRight(box) {
return box.x + box.width;
}
function katanaDrawioBoxBottom(box) {
return box.y + box.height;
}
function katanaDrawioHasArea(box) {
return [box.width > 0, box.height > 0].every(Boolean);
}
function katanaDrawioEmptyContentBox() {
return { x: 0, y: 0, width: 1, height: 1 };
}
function katanaApplyDrawioCrop(svg, box) {
const paddedBox = katanaDrawioExportPaddedBox(box);
katanaTranslateDrawioContent(svg, box);
svg.setAttribute("viewBox", `0 0 ${paddedBox.width} ${paddedBox.height}`);
svg.setAttribute("width", `${paddedBox.width}px`);
svg.setAttribute("height", `${paddedBox.height}px`);
}
function katanaDrawioExportPaddedBox(box) {
return {
width: box.width + 1,
height: box.height + katanaDrawioExportBottomPadding() + 1,
};
}
function katanaDrawioExportBottomPadding() {
return katanaDrawioHasExternalImageSource()
? KATANA_DRAWIO_EXTERNAL_IMAGE_EXPORT_BOTTOM_PADDING
: 0;
}
function katanaDrawioHasExternalImageSource() {
return /(?:^|;)image=https?:\/\//.test(katanaDrawioRequestSource());
}
function katanaTranslateDrawioContent(svg, box) {
const wrapper = document.createElementNS("http://www.w3.org/2000/svg", "g");
wrapper.setAttribute("transform", `translate(${-box.x},${-box.y})`);
Array.from(svg.childNodes).forEach((child) => {
wrapper.appendChild(child);
});
svg.appendChild(wrapper);
}
function katanaDrawioNodeWidth(node) {
return katanaDrawioCssPixels(node.getAttribute("width"));
}
function katanaDrawioElementCellShape(element) {
return katanaDrawioSourceCellShape(katanaDrawioElementCellId(element));
}
function katanaDrawioElementCellId(element) {
return katanaDrawioElementAncestors(element)
.map(katanaDrawioDirectElementCellId)
.filter(Boolean)
.concat([""])[0];
}
function katanaDrawioElementAncestors(element) {
const parent1 = katanaDrawioParentNode(element);
const parent2 = katanaDrawioParentNode(parent1);
const parent3 = katanaDrawioParentNode(parent2);
const parent4 = katanaDrawioParentNode(parent3);
const parent5 = katanaDrawioParentNode(parent4);
const parent6 = katanaDrawioParentNode(parent5);
const parent7 = katanaDrawioParentNode(parent6);
const parent8 = katanaDrawioParentNode(parent7);
return [element, parent1, parent2, parent3, parent4, parent5, parent6, parent7, parent8].filter(
Boolean,
);
}
function katanaDrawioParentNode(node) {
return [node]
.filter(Boolean)
.map((it) => it.parentNode)
.filter(Boolean)
.concat([null])[0];
}
function katanaDrawioDirectElementCellId(element) {
return [element.getAttribute?.("data-cell-id")].filter(Boolean).concat([""])[0];
}
function katanaDrawioSourceCellShape(id) {
return [KATANA_DRAWIO_SOURCE_CELL_STYLE_CACHE.get(id)]
.filter(Boolean)
.map((style) => style.get("shape"))
.filter(Boolean)
.concat([""])[0];
}
function katanaDrawioSourceCellStyleMap() {
return new Map(
Array.from(katanaDrawioSourceStyleRequestSource().matchAll(/<mxCell\b([^>]*)>/g))
.map(katanaDrawioSourceCellStyleEntry)
.filter((entry) => entry[0]),
);
}
function katanaDrawioSourceCellStyleEntry(match) {
const attributes = katanaDrawioSourceStyleXmlAttributes(match[1]);
return [katanaDrawioSourceCellId(attributes), katanaDrawioSourceCellStyle(attributes)];
}
function katanaDrawioSourceCellId(attributes) {
return [attributes.get("id")].filter(Boolean).concat([""])[0];
}
function katanaDrawioSourceCellStyle(attributes) {
return katanaDrawioSourceStyleMap([attributes.get("style")].filter(Boolean).concat([""])[0]);
}
function katanaDrawioSourceStyleRequestSource() {
return String(globalThis.__katanaDrawioRequest?.source ?? "");
}
function katanaDrawioSourceStyleXmlAttributes(source) {
return new Map(
Array.from(String(source).matchAll(/([a-zA-Z0-9:_-]+)="([^"]*)"/g)).map((match) => [
match[1],
decodeHtmlEntities(match[2]),
]),
);
}
function katanaDrawioSourceStyleMap(style) {
return new Map(
String(style)
.split(";")
.map(katanaDrawioSourceStyleEntry)
.filter((entry) => entry[0]),
);
}
function katanaDrawioSourceStyleEntry(value) {
return String(value).split("=").concat(["", ""]).slice(0, 2);
}
const KATANA_DRAWIO_SOURCE_CELL_STYLE_CACHE = katanaDrawioSourceCellStyleMap();
const KATANA_DRAWIO_LIGHT_DARK_PATTERN =
/light-dark\((rgb\([^)]+\)|#[\da-f]{6}),\s*(rgb\([^)]+\)|#[\da-f]{6}|var\(--ge-dark-color,\s*#[\da-f]{6}\))\)/gi;
const KATANA_DRAWIO_STYLE_SVG_COLOR_ATTRIBUTES = ["fill", "stroke", "stop-color"];
function katanaResolveDrawioLightDarkStyleColors(element) {
const style = element.getAttribute("style");
if (!style?.includes("light-dark(")) {
return;
}
const resolvedStyle = katanaResolvedDrawioLightDarkStyle(style);
element.setAttribute("style", resolvedStyle);
katanaApplyDrawioStyleColorAttributes(element, resolvedStyle);
}
function katanaResolvedDrawioLightDarkStyle(style) {
return style.replace(KATANA_DRAWIO_LIGHT_DARK_PATTERN, (_match, light, dark) =>
katanaDrawioLightDarkStyleChoice(light, dark),
);
}
function katanaDrawioLightDarkStyleChoice(light, dark) {
return katanaDrawioIsDarkMode()
? katanaDrawioLightDarkDarkStyleColor(dark)
: String(light).trim();
}
function katanaDrawioLightDarkDarkStyleColor(dark) {
const value = String(dark).trim();
const fallback = value.match(/var\(--ge-dark-color,\s*(#[\da-f]{6})\)/i);
return fallback?.[1] ?? value;
}
function katanaApplyDrawioStyleColorAttributes(element, style) {
KATANA_DRAWIO_STYLE_SVG_COLOR_ATTRIBUTES.map((name) =>
katanaDrawioStyleColorAttribute(style, name),
)
.filter(katanaHasDrawioStyleColorAttributeValue)
.forEach((attribute) => {
element.setAttribute(attribute.name, attribute.value);
});
}
function katanaDrawioStyleColorAttribute(style, name) {
return { name, value: katanaDrawioStylePropertyValue(style, name) };
}
function katanaHasDrawioStyleColorAttributeValue(attribute) {
return attribute.value !== "";
}
function katanaDrawioStylePropertyValue(style, name) {
return style
.split(";")
.map((declaration) => declaration.trim())
.filter((declaration) => declaration.toLowerCase().startsWith(`${name}:`))
.map(katanaDrawioStyleDeclarationValue)
.filter(Boolean)
.concat([""])[0];
}
function katanaDrawioStyleDeclarationValue(declaration) {
return declaration.slice(declaration.indexOf(":") + 1).trim();
}
function katanaDrawioIsPaintServer(value) {
return String(value).trim().toLowerCase().startsWith("url(");
}
const KATANA_DRAWIO_LARGE_WHITE_PATH_AREA = 10000;
const KATANA_DRAWIO_AWS_SHAPE_PREFIXES = [
"mxgraph.aws.",
"mxgraph.aws2.",
"mxgraph.aws3.",
"mxgraph.aws4.",
"mxgraph.aws3d.",
];
const KATANA_DRAWIO_AZURE_SHAPE_PREFIXES = ["mxgraph.azure.", "mxgraph.mscae.", "mxgraph.office."];
const KATANA_DRAWIO_VISUAL_SHAPE_TAGS = new Set([
"circle",
"ellipse",
"line",
"path",
"polygon",
"polyline",
"rect",
]);
const KATANA_DRAWIO_PAINT_ATTRIBUTES = new Set(["fill", "stroke", "stop-color"]);
const KATANA_DRAWIO_AZURE_DARK_ATTRIBUTES = new Set(["color", "fill", "stroke"]);
const KATANA_DRAWIO_AWS_DOCUMENT_ORIGINAL_COLORS = new Set(["#007cbd", "#545b64"]);
const KATANA_DRAWIO_AWS_ORIGINAL_COLORS = new Set([
"#000000",
"#007cbd",
"#277116",
"#292929",
"#545b64",
"#5e5e5e",
"#60a337",
"#5a30b5",
"#945df2",
"#bc1356",
"#f34482",
"#c7131f",
"#f54749",
"#d05c17",
"#f78e04",
"#ececec",
"#f4b934",
"#3334b9",
"#4d72f3",
"#4ab29a",
"rgb(0, 0, 0)",
"rgb(236, 236, 236)",
]);
function katanaDrawioContextOriginalColor(element, name, value) {
return (
katanaDrawioAzureDocumentDarkColor(element, name, value) ||
katanaDrawioAzureDarkColor(element, name, value) ||
katanaDrawioLegacyAwsDarkColor(element, name, value) ||
katanaDrawioOriginalAwsGradientStopColor(element, name, value) ||
katanaDrawioSimpleDiagramDarkColor(element, name, value) ||
katanaDrawioLargeWhitePathColor(element, name, value) ||
katanaDrawioOriginalAwsShapeColor(element, name, value)
);
}
function katanaDrawioAzureDarkColor(element, name, value) {
return (
KATANA_DRAWIO_AZURE_DARK_COLOR.get(katanaDrawioAzureDarkColorKey(element, name, value)) ?? ""
);
}
function katanaDrawioAzureDarkColorKey(element, name, value) {
return [
katanaDrawioIsDarkMode(),
KATANA_DRAWIO_AZURE_DARK_ATTRIBUTES.has(name),
katanaDrawioIsAzureShapeElement(element),
].every(Boolean)
? `${name}|${value}`
: "";
}
function katanaDrawioLegacyAwsDarkColor(element, name, value) {
return (
KATANA_DRAWIO_AWS_LEGACY_DARK_COLOR.get(
katanaDrawioLegacyAwsDarkColorKey(element, name, value),
) ?? ""
);
}
function katanaDrawioLegacyAwsDarkColorKey(element, name, value) {
return katanaDrawioShouldMapLegacyAwsDarkColor(element, name) ? `${name}|${value}` : "";
}
function katanaDrawioShouldMapLegacyAwsDarkColor(element, name) {
return [
katanaDrawioIsDarkMode(),
katanaDrawioIsPaintAttribute(name),
katanaDrawioIsVisualShapeTag(element),
katanaDrawioIsLegacyAwsShapeElement(element),
].every(Boolean);
}
function katanaDrawioLargeWhitePathColor(element, name, value) {
if (!katanaDrawioIsLargeWhitePath(element, name, value)) {
return "";
}
return "#121212";
}
function katanaDrawioIsLargeWhitePath(element, name, value) {
return [
katanaDrawioIsDarkMode(),
element.localName === "path",
name === "fill",
value === "#ffffff",
katanaDrawioElementArea(element) > KATANA_DRAWIO_LARGE_WHITE_PATH_AREA,
].every(Boolean);
}
function katanaDrawioElementArea(element) {
const box = element.getBBox();
return box.width * box.height;
}
function katanaDrawioOriginalAwsShapeColor(element, name, value) {
return katanaDrawioShouldKeepOriginalAwsShapeColor(element, name, value) ? value : "";
}
function katanaDrawioOriginalAwsGradientStopColor(element, name, value) {
return katanaDrawioShouldKeepOriginalAwsGradientStopColor(element, name, value) ? value : "";
}
function katanaDrawioShouldKeepOriginalAwsShapeColor(element, name, value) {
return [
katanaDrawioIsDarkMode(),
katanaDrawioIsPaintAttribute(name),
katanaDrawioIsVisualShapeTag(element),
KATANA_DRAWIO_AWS_ORIGINAL_COLORS.has(value),
katanaDrawioIsAwsColorContext(element),
].every(Boolean);
}
function katanaDrawioIsPaintAttribute(name) {
return KATANA_DRAWIO_PAINT_ATTRIBUTES.has(name);
}
function katanaDrawioIsVisualShapeTag(element) {
return KATANA_DRAWIO_VISUAL_SHAPE_TAGS.has(element.localName);
}
function katanaDrawioIsAwsShapeElement(element) {
return KATANA_DRAWIO_AWS_SHAPE_PREFIXES.some((it) =>
katanaDrawioElementCellShape(element).startsWith(it),
);
}
function katanaDrawioIsAzureShapeElement(element) {
return KATANA_DRAWIO_AZURE_SHAPE_PREFIXES.some((it) =>
katanaDrawioElementCellShape(element).startsWith(it),
);
}
function katanaDrawioIsAwsColorContext(element) {
return (
katanaDrawioIsAwsShapeElement(element) ||
KATANA_DRAWIO_AWS_DOCUMENT_ORIGINAL_COLORS.has(element.getAttribute("fill")) ||
KATANA_DRAWIO_AWS_DOCUMENT_ORIGINAL_COLORS.has(element.getAttribute("stroke"))
);
}
function katanaDrawioIsLegacyAwsShapeElement(element) {
return ["mxgraph.aws.", "mxgraph.aws3.", "mxgraph.aws4."].some((it) =>
katanaDrawioElementCellShape(element).startsWith(it),
);
}
function katanaDrawioShouldKeepOriginalAwsGradientStopColor(element, name, value) {
return [
katanaDrawioIsDarkMode(),
name === "stop-color",
element.localName === "stop",
KATANA_DRAWIO_AWS_ORIGINAL_COLORS.has(value),
].every(Boolean);
}
const KATANA_DRAWIO_AWS_LEGACY_DARK_COLOR = new Map([
["fill|#000000", "#ededed"],
["fill|#2e73b8", "#5f9bd6"],
["fill|#7d7c7c", "#848383"],
["fill|#d2d3d3", "#373838"],
["fill|#d9a741", "#835801"],
["fill|#e05243", "#ef7568"],
["fill|#f58534", "#bd5c17"],
["fill|#f58536", "#bd5c18"],
["fill|#ffffff", "#232f3e"],
["stroke|#000000", "#ffffff"],
["stroke|#e6e6e6", "#272727"],
]);
const KATANA_DRAWIO_AZURE_DARK_COLOR = new Map([
["color|#ffffff", "#121212"],
["color|rgb(255, 255, 255)", "rgb(18, 18, 18)"],
["fill|#ffffff", "#121212"],
["fill|rgb(255, 255, 255)", "rgb(18, 18, 18)"],
["stroke|#ffffff", "#121212"],
["stroke|rgb(255, 255, 255)", "rgb(18, 18, 18)"],
]);
function katanaDrawioAzureDocumentDarkColor(element, name, value) {
return (
KATANA_DRAWIO_AZURE_DOCUMENT_DARK_COLOR.get(
katanaDrawioAzureDocumentDarkColorKey(element, name, value),
) ?? ""
);
}
function katanaDrawioAzureDocumentDarkColorKey(element, name, value) {
return [
katanaDrawioIsDarkMode(),
katanaDrawioIsAzureDiagramSource(),
KATANA_DRAWIO_AZURE_DARK_ATTRIBUTES.has(name),
katanaDrawioAzureDocumentAllowsAttribute(element, name),
].every(Boolean)
? `${name}|${value}`
: "";
}
function katanaDrawioAzureDocumentAllowsAttribute(element, name) {
return name === "color" || katanaDrawioIsVisualShapeTag(element);
}
function katanaDrawioIsAzureDiagramSource() {
return KATANA_DRAWIO_AZURE_SHAPE_PREFIXES.some(katanaDrawioRequestSourceIncludes);
}
function katanaDrawioRequestSourceIncludes(value) {
return katanaDrawioRequestSource().includes(value);
}
const KATANA_DRAWIO_AZURE_DOCUMENT_DARK_COLOR = new Map([
["color|#ffffff", "#121212"],
["color|rgb(255, 255, 255)", "rgb(18, 18, 18)"],
["fill|#ffffff", "#121212"],
["fill|rgb(255, 255, 255)", "rgb(18, 18, 18)"],
["stroke|#ffffff", "#121212"],
["stroke|rgb(255, 255, 255)", "rgb(18, 18, 18)"],
]);
function katanaNormalizeDrawioSvgColors(svg) {
[svg, ...svg.querySelectorAll("*")].forEach(katanaNormalizeDrawioElementColors);
}
function katanaNormalizeDrawioElementColors(element) {
katanaResolveDrawioLightDarkStyleColors(element);
["fill", "stroke", "stop-color"].forEach((name) => {
katanaNormalizeDrawioColorAttribute(element, name);
});
katanaNormalizeDrawioStyleTextColor(element);
}
function katanaNormalizeDrawioColorAttribute(element, name) {
const color = element.getAttribute(name);
if (color) {
element.setAttribute(name, katanaDrawioResolvedAttributeColor(element, name, color));
}
}
function katanaDrawioResolvedAttributeColor(element, name, color) {
return katanaDrawioShouldResolveTextColor(element, name)
? katanaDrawioResolvedTextColor(color)
: katanaDrawioResolvedColor(element, name, color);
}
function katanaDrawioShouldResolveTextColor(element, name) {
return [element.localName === "text", name === "fill"].every(Boolean);
}
function katanaDrawioResolvedColor(element, name, color) {
return (
katanaDrawioPaintServerPassthrough(color) ||
katanaDrawioResolvedNonPaintColor(element, name, color)
);
}
function katanaDrawioPaintServerPassthrough(color) {
return katanaDrawioIsPaintServer(color) ? color : "";
}
function katanaDrawioResolvedNonPaintColor(element, name, color) {
const value = katanaDrawioColorKey(color);
return (
katanaDrawioShapeMappedColor(element, name, value) ||
katanaDrawioContextMappedColor(element, name, value) ||
katanaDrawioLightDarkExactColor(value) ||
katanaDrawioThemeMappedColor(element, name, value)
);
}
function katanaDrawioLightDarkExactColor(value) {
const colors = KATANA_DRAWIO_LIGHT_DARK_COLORS.get(value);
return colors?.[Number(katanaDrawioIsDarkMode())] ?? "";
}
function katanaDrawioThemeMappedColor(element, name, value) {
return (
katanaDrawioColorMapForTheme().get(value) ||
katanaDrawioFallbackThemeColor(element, name, value) ||
value
);
}
function katanaDrawioContextMappedColor(element, name, value) {
return [
katanaDrawioContextOriginalColor(element, name, value),
katanaDrawioContextColorMapForTheme().get(katanaDrawioContextColorKey(element, name, value)),
]
.filter(Boolean)
.concat([""])[0];
}
function katanaDrawioShapeMappedColor(element, name, value) {
return [katanaDrawioShapeColorMap(element).get(`${name}|${value}`)]
.filter(Boolean)
.concat([""])[0];
}
function katanaDrawioShapeColorMap(element) {
return KATANA_DRAWIO_SHAPE_COLOR_MAPS[Number(katanaDrawioIsAws3dElement(element))];
}
function katanaDrawioIsAws3dElement(element) {
return [
katanaDrawioIsDarkMode(),
katanaDrawioElementCellShape(element).startsWith("mxgraph.aws3d."),
].every(Boolean);
}
function katanaDrawioColorMapForTheme() {
return KATANA_DRAWIO_COLOR_BY_THEME[Number(katanaDrawioIsDarkMode())];
}
function katanaDrawioContextColorMapForTheme() {
return KATANA_DRAWIO_CONTEXT_COLOR_BY_THEME[Number(katanaDrawioIsDarkMode())];
}
function katanaDrawioColorKey(color) {
return String(color).trim().toLowerCase();
}
function katanaDrawioContextColorKey(element, name, value) {
return [element.tagName, name, value].map(katanaDrawioColorKey).join("|");
}
function katanaDrawioIsDarkMode() {
return globalThis.__katanaDrawioRequest?.dark_mode === true;
}
const KATANA_DRAWIO_LIGHT_DARK_COLORS = new Map([
["light-dark(#000000, #ffffff)", ["#000000", "#ffffff"]],
["light-dark(rgb(255, 255, 255), rgb(18, 18, 18))", ["rgb(255, 255, 255)", "rgb(18, 18, 18)"]],
["light-dark(rgb(218, 232, 252), rgb(29, 41, 59))", ["rgb(218, 232, 252)", "rgb(29, 41, 59)"]],
[
"light-dark(rgb(108, 142, 191), rgb(92, 121, 163))",
["rgb(108, 142, 191)", "rgb(92, 121, 163)"],
],
["light-dark(rgb(213, 232, 212), rgb(31, 47, 30))", ["rgb(213, 232, 212)", "rgb(31, 47, 30)"]],
["light-dark(rgb(130, 179, 102), rgb(68, 110, 44))", ["rgb(130, 179, 102)", "rgb(68, 110, 44)"]],
["light-dark(rgb(255, 242, 204), rgb(40, 29, 0))", ["rgb(255, 242, 204)", "rgb(40, 29, 0)"]],
["light-dark(rgb(214, 182, 86), rgb(109, 81, 0))", ["rgb(214, 182, 86)", "rgb(109, 81, 0)"]],
["light-dark(rgb(248, 206, 204), rgb(81, 45, 43))", ["rgb(248, 206, 204)", "rgb(81, 45, 43)"]],
["light-dark(rgb(184, 84, 80), rgb(215, 129, 126))", ["rgb(184, 84, 80)", "rgb(215, 129, 126)"]],
["light-dark(rgb(225, 213, 231), rgb(57, 47, 63))", ["rgb(225, 213, 231)", "rgb(57, 47, 63)"]],
[
"light-dark(rgb(150, 115, 166), rgb(149, 119, 163))",
["rgb(150, 115, 166)", "rgb(149, 119, 163)"],
],
["light-dark(rgb(255, 230, 204), rgb(54, 33, 10))", ["rgb(255, 230, 204)", "rgb(54, 33, 10)"]],
["light-dark(rgb(215, 155, 0), rgb(153, 101, 0))", ["rgb(215, 155, 0)", "rgb(153, 101, 0)"]],
]);
const KATANA_DRAWIO_DARK_COLOR_BY_LIGHT_COLOR = new Map([
["#000000", "#ffffff"],
["rgb(0, 0, 0)", "rgb(255, 255, 255)"],
["#232f3e", "#bdc7d4"],
["rgb(35, 47, 62)", "rgb(189, 199, 212)"],
["#23445d", "#a0bcd2"],
["rgb(35, 68, 93)", "rgb(160, 188, 210)"],
["#545b64", "#9aa0a8"],
["rgb(84, 91, 100)", "rgb(154, 160, 168)"],
["#5a6c86", "#8494aa"],
["rgb(90, 108, 134)", "rgb(132, 148, 170)"],
["#eaeded", "#1f2222"],
["rgb(234, 237, 237)", "rgb(31, 34, 34)"],
["#f59d56", "#9a4e11"],
["rgb(245, 157, 86)", "rgb(154, 78, 17)"],
["#116d5b", "#63b3a3"],
["rgb(17, 109, 91)", "rgb(99, 179, 163)"],
["#4ab29a", "#237d68"],
["rgb(74, 178, 154)", "rgb(35, 125, 104)"],
["#277116", "#72b264"],
["rgb(39, 113, 22)", "rgb(114, 178, 100)"],
["#60a337", "#4d872a"],
["rgb(96, 163, 55)", "rgb(77, 135, 42)"],
["#5a30b5", "#c8a4ff"],
["rgb(90, 48, 181)", "rgb(200, 164, 255)"],
["#945df2", "#a677f7"],
["rgb(148, 93, 242)", "rgb(166, 119, 247)"],
["#3334b9", "#afb0ff"],
["rgb(51, 52, 185)", "rgb(175, 176, 255)"],
["#4d72f3", "#6989f8"],
["rgb(77, 114, 243)", "rgb(105, 137, 248)"],
["#bc1356", "#ff97d1"],
["rgb(188, 19, 86)", "rgb(255, 151, 209)"],
["#f34482", "#ff6ba1"],
["rgb(243, 68, 130)", "rgb(255, 107, 161)"],
["#c7131f", "#ff9aa5"],
["rgb(199, 19, 31)", "rgb(255, 154, 165)"],
["#f54749", "#ff7072"],
["rgb(245, 71, 73)", "rgb(255, 112, 114)"],
["#be0917", "#ffa1ad"],
["rgb(190, 9, 23)", "rgb(255, 161, 173)"],
["#d05c17", "#e07c41"],
["rgb(208, 92, 23)", "rgb(224, 124, 65)"],
["#007cbd", "#3ea8e0"],
["rgb(0, 124, 189)", "rgb(62, 168, 224)"],
["#b3b3b3", "#535353"],
["rgb(179, 179, 179)", "rgb(83, 83, 83)"],
["#f4f4f4", "#1b1b1b"],
["rgb(244, 244, 244)", "rgb(27, 27, 27)"],
["#dae8fc", "#1d293b"],
["rgb(218, 232, 252)", "rgb(29, 41, 59)"],
["#6c8ebf", "#5c79a3"],
["rgb(108, 142, 191)", "rgb(92, 121, 163)"],
["#d5e8d4", "#1f2f1e"],
["rgb(213, 232, 212)", "rgb(31, 47, 30)"],
["#82b366", "#446e2c"],
["rgb(130, 179, 102)", "rgb(68, 110, 44)"],
["#fff2cc", "#281d00"],
["rgb(255, 242, 204)", "rgb(40, 29, 0)"],
["#d6b656", "#6d5100"],
["rgb(214, 182, 86)", "rgb(109, 81, 0)"],
["#f8cecc", "#512d2b"],
["rgb(248, 206, 204)", "rgb(81, 45, 43)"],
["#b85450", "#d7817e"],
["rgb(184, 84, 80)", "rgb(215, 129, 126)"],
["#e1d5e7", "#392f3f"],
["rgb(225, 213, 231)", "rgb(57, 47, 63)"],
["#9673a6", "#9577a3"],
["rgb(150, 115, 166)", "rgb(149, 119, 163)"],
["#ffe6cc", "#36210a"],
["rgb(255, 230, 204)", "rgb(54, 33, 10)"],
["#d79b00", "#996500"],
["rgb(215, 155, 0)", "rgb(153, 101, 0)"],
]);
const KATANA_DRAWIO_COLOR_BY_THEME = [new Map(), KATANA_DRAWIO_DARK_COLOR_BY_LIGHT_COLOR];
const KATANA_DRAWIO_DARK_CONTEXT_COLOR = new Map([["rect|fill|#ffffff", "#121212"]]);
const KATANA_DRAWIO_CONTEXT_COLOR_BY_THEME = [new Map(), KATANA_DRAWIO_DARK_CONTEXT_COLOR];
const KATANA_DRAWIO_GCP_LIGHT_TO_DARK_COLOR_ENTRIES = [
["#000000", "#ededed"],
["rgb(0, 0, 0)", "rgb(237, 237, 237)"],
["#333333", "#c1c1c1"],
["rgb(51, 51, 51)", "rgb(193, 193, 193)"],
["#445962", "#95a7af"],
["rgb(68, 89, 98)", "rgb(149, 167, 175)"],
["#455c66", "#91a5ae"],
["rgb(69, 92, 102)", "rgb(145, 165, 174)"],
["#717171", "#8c8c8c"],
["rgb(113, 113, 113)", "rgb(140, 140, 140)"],
["#757575", "#898989"],
["rgb(117, 117, 117)", "rgb(137, 137, 137)"],
["#999999", "#6a6a6a"],
["rgb(153, 153, 153)", "rgb(106, 106, 106)"],
["#9e9e9e", "#656565"],
["rgb(158, 158, 158)", "rgb(101, 101, 101)"],
["#bdbdbd", "#4b4b4b"],
["rgb(189, 189, 189)", "rgb(75, 75, 75)"],
["#dddddd", "#2f2f2f"],
["rgb(221, 221, 221)", "rgb(47, 47, 47)"],
["#e0e0e0", "#2d2d2d"],
["rgb(224, 224, 224)", "rgb(45, 45, 45)"],
["#e2e2e2", "#2b2b2b"],
["rgb(226, 226, 226)", "rgb(43, 43, 43)"],
["#f6f6f6", "#1a1a1a"],
["rgb(246, 246, 246)", "rgb(26, 26, 26)"],
["#ffffff", "#121212"],
["rgb(255, 255, 255)", "rgb(18, 18, 18)"],
["#288d44", "#4ba263"],
["rgb(40, 141, 68)", "rgb(75, 162, 99)"],
["#34a853", "#2f9249"],
["rgb(52, 168, 83)", "rgb(47, 146, 73)"],
["#3ca759", "#338f4c"],
["rgb(60, 167, 89)", "rgb(51, 143, 76)"],
["#3da858", "#328e4a"],
["rgb(61, 168, 88)", "rgb(50, 142, 74)"],
["#60b878", "#2b7740"],
["rgb(96, 184, 120)", "rgb(43, 119, 64)"],
["#8dc34c", "#396801"],
["rgb(141, 195, 76)", "rgb(57, 104, 1)"],
["#398bef", "#4187dd"],
["rgb(57, 139, 239)", "rgb(65, 135, 221)"],
["#3b8cf0", "#4186dc"],
["rgb(59, 140, 240)", "rgb(65, 134, 220)"],
["#3b8ff3", "#3c84da"],
["rgb(59, 143, 243)", "rgb(60, 132, 218)"],
["#4284f3", "#4e86e6"],
["rgb(66, 132, 243)", "rgb(78, 134, 230)"],
["#4285f4", "#4c85e5"],
["rgb(66, 133, 244)", "rgb(76, 133, 229)"],
["#4da1f5", "#2f77c0"],
["rgb(77, 161, 245)", "rgb(47, 119, 192)"],
["#5184f3", "#5580e0"],
["rgb(81, 132, 243)", "rgb(85, 128, 224)"],
["#528ff5", "#477cd4"],
["rgb(82, 143, 245)", "rgb(71, 124, 212)"],
["#9379cb", "#8872b8"],
["rgb(147, 121, 203)", "rgb(136, 114, 184)"],
["#dc473a", "#fb7b70"],
["rgb(220, 71, 58)", "rgb(251, 123, 112)"],
["#de433a", "#ff7c75"],
["rgb(222, 67, 58)", "rgb(255, 124, 117)"],
["#e61727", "#ff8b98"],
["rgb(230, 23, 39)", "rgb(255, 139, 152)"],
["#e93733", "#ff7d7a"],
["rgb(233, 55, 51)", "rgb(255, 125, 122)"],
["#ea4335", "#ff796d"],
["rgb(234, 67, 53)", "rgb(255, 121, 109)"],
["#e17028", "#ce6d2f"],
["rgb(225, 112, 40)", "rgb(206, 109, 47)"],
["#ee6429", "#e36c39"],
["rgb(238, 100, 41)", "rgb(227, 108, 57)"],
["#ef5402", "#fc7731"],
["rgb(239, 84, 2)", "rgb(252, 119, 49)"],
["#f57a36", "#c95f24"],
["rgb(245, 122, 54)", "rgb(201, 95, 36)"],
["#f5820b", "#c56200"],
["rgb(245, 130, 11)", "rgb(197, 98, 0)"],
["#f59121", "#af5900"],
["rgb(245, 145, 33)", "rgb(175, 89, 0)"],
["#f6a52a", "#965100"],
["rgb(246, 165, 42)", "rgb(150, 81, 0)"],
["#fbb724", "#844900"],
["rgb(251, 183, 36)", "rgb(132, 73, 0)"],
["#fbbb35", "#7c4500"],
["rgb(251, 187, 53)", "rgb(124, 69, 0)"],
["#fbbc04", "#814b00"],
["rgb(251, 188, 4)", "rgb(129, 75, 0)"],
["#ffa40c", "#a05200"],
["rgb(255, 164, 12)", "rgb(160, 82, 0)"],
["#ffcb2b", "#6d4000"],
["rgb(255, 203, 43)", "rgb(109, 64, 0)"],
["#ffcf48", "#633a00"],
["rgb(255, 207, 72)", "rgb(99, 58, 0)"],
["#e1f5fe", "#0f2128"],
["rgb(225, 245, 254)", "rgb(15, 33, 40)"],
["#efebe9", "#252220"],
["rgb(239, 235, 233)", "rgb(37, 34, 32)"],
["#f1f8e9", "#161c0f"],
["rgb(241, 248, 233)", "rgb(22, 28, 15)"],
["#f3e5f5", "#2d212f"],
["rgb(243, 229, 245)", "rgb(45, 33, 47)"],
["#f9bc8d", "#6f3b12"],
["rgb(249, 188, 141)", "rgb(111, 59, 18)"],
["#ffebee", "#2c1b1e"],
["rgb(255, 235, 238)", "rgb(44, 27, 30)"],
["#fff8e1", "#1e1804"],
["rgb(255, 248, 225)", "rgb(30, 24, 4)"],
];
if (katanaDrawioIsGcpDiagramSource()) {
KATANA_DRAWIO_GCP_LIGHT_TO_DARK_COLOR_ENTRIES.forEach((entry) => {
KATANA_DRAWIO_DARK_COLOR_BY_LIGHT_COLOR.set(entry[0], entry[1]);
});
}
function katanaDrawioIsGcpDiagramSource() {
return String(globalThis.__katanaDrawioRequest?.source ?? "").includes("mxgraph.gcp");
}
const KATANA_DRAWIO_AWS3D_DARK_COLOR = new Map([
["fill|#000000", "#ededed"],
["fill|#ececec", "#222222"],
["fill|#ffffff", "#121212"],
["fill|#f4b934", "#7c4900"],
["stroke|#000000", "#ffffff"],
["stroke|#2d6195", "#7aa6d3"],
["stroke|#292929", "#cacaca"],
["stroke|#5e5e5e", "#9c9c9c"],
]);
const KATANA_DRAWIO_SHAPE_COLOR_MAPS = [new Map(), KATANA_DRAWIO_AWS3D_DARK_COLOR];
const KATANA_DRAWIO_EXTRA_LIGHT_TO_DARK_COLOR_ENTRIES = [
["#ffffff", "#121212"],
["rgb(255, 255, 255)", "rgb(18, 18, 18)"],
["#009bff", "#0f94ea"],
["rgb(0, 155, 255)", "rgb(15, 148, 234)"],
["#0072bc", "#49abeb"],
["rgb(0, 114, 188)", "rgb(73, 171, 235)"],
["#00b9e2", "#008db0"],
["rgb(0, 185, 226)", "rgb(0, 141, 176)"],
["#0c343d", "#abced5"],
["rgb(12, 52, 61)", "rgb(171, 206, 213)"],
["#8bc63e", "#376a00"],
["rgb(139, 198, 62)", "rgb(55, 106, 0)"],
["#94ce41", "#3d6b00"],
["rgb(148, 206, 65)", "rgb(61, 107, 0)"],
["#336600", "#88b45c"],
["rgb(51, 102, 0)", "rgb(136, 180, 92)"],
["#f04d22", "#ff7550"],
["rgb(240, 77, 34)", "rgb(255, 117, 80)"],
["#3399ff", "#2b82da"],
["rgb(51, 153, 255)", "rgb(43, 130, 218)"],
["#0080ff", "#309eff"],
["#0075e8", "#41a5ff"],
["#0067cc", "#56aeff"],
["#0062c4", "#5db1ff"],
["#0059b0", "#6ab6ff"],
["#004d99", "#7cbeff"],
["#61baff", "#1865a0"],
["#004c99", "#7dbeff"],
["#ffb366", "#824100"],
["rgb(255, 179, 102)", "rgb(130, 65, 0)"],
["#e6e6e6", "#272727"],
["rgb(230, 230, 230)", "rgb(39, 39, 39)"],
["#e6e7e8", "#282929"],
["rgb(230, 231, 232)", "rgb(40, 41, 41)"],
["#ededed", "#202020"],
["rgb(237, 237, 237)", "rgb(32, 32, 32)"],
["#eeeeee", "#1f1f1f"],
["rgb(238, 238, 238)", "rgb(31, 31, 31)"],
["#cccccc", "#3e3e3e"],
["rgb(204, 204, 204)", "rgb(62, 62, 62)"],
["#999999", "#6a6a6a"],
["rgb(153, 153, 153)", "rgb(106, 106, 106)"],
["#666666", "#959595"],
["rgb(102, 102, 102)", "rgb(149, 149, 149)"],
["#4d4d4d", "#ababab"],
["rgb(77, 77, 77)", "rgb(171, 171, 171)"],
["#003366", "#a1cdf9"],
["rgb(0, 51, 102)", "rgb(161, 205, 249)"],
["#deedff", "#172433"],
["rgb(222, 237, 255)", "rgb(23, 36, 51)"],
["#f5f5f5", "#1a1a1a"],
["rgb(245, 245, 245)", "rgb(26, 26, 26)"],
["#f9f9f9", "#121212"],
["rgb(249, 249, 249)", "rgb(18, 18, 18)"],
["#f08705", "#bd6300"],
["rgb(240, 135, 5)", "rgb(189, 99, 0)"],
["#736ca8", "#8c86b9"],
["rgb(115, 108, 168)", "rgb(140, 134, 185)"],
["#e3e2ee", "#2a2935"],
["rgb(227, 226, 238)", "rgb(42, 41, 53)"],
["#fdf2e3", "#241b0e"],
["rgb(253, 242, 227)", "rgb(36, 27, 14)"],
["#ae4132", "#ec8f82"],
["rgb(174, 65, 50)", "rgb(236, 143, 130)"],
["#cce5ff", "#182e44"],
["rgb(204, 229, 255)", "rgb(24, 46, 68)"],
["#d4e1ff", "#222d47"],
["rgb(212, 225, 255)", "rgb(34, 45, 71)"],
["#adc3d9", "#374a5c"],
["rgb(173, 195, 217)", "rgb(55, 74, 92)"],
["#98bf21", "#4a6b00"],
["rgb(152, 191, 33)", "rgb(74, 107, 0)"],
["#a7c942", "#405e00"],
["rgb(167, 201, 66)", "rgb(64, 94, 0)"],
["#eaf2d3", "#1d2409"],
["rgb(234, 242, 211)", "rgb(29, 36, 9)"],
["#eaf5d9", "#17240a"],
["rgb(234, 245, 217)", "rgb(23, 36, 10)"],
["#c0c0c0", "#484848"],
["rgb(192, 192, 192)", "rgb(72, 72, 72)"],
["#e0e0e0", "#2d2d2d"],
["rgb(224, 224, 224)", "rgb(45, 45, 45)"],
["#ffd966", "#543300"],
["rgb(255, 217, 102)", "rgb(84, 51, 0)"],
["#ffd470", "#5a3400"],
["rgb(255, 212, 112)", "rgb(90, 52, 0)"],
["#fff2a1", "#302700"],
["rgb(255, 242, 161)", "rgb(48, 39, 0)"],
["#fff9b2", "#2e2700"],
["rgb(255, 249, 178)", "rgb(46, 39, 0)"],
["#0000ee", "#cfcfff"],
["rgb(0, 0, 238)", "rgb(207, 207, 255)"],
["#001933", "#c9def5"],
["#660000", "#ffc4c4"],
["rgb(102, 0, 0)", "rgb(255, 196, 196)"],
["#990000", "#ffb5b5"],
["rgb(153, 0, 0)", "rgb(255, 181, 181)"],
["#0d5b9d", "#70b3ec"],
["rgb(13, 91, 157)", "rgb(112, 179, 236)"],
["#efac43", "#a96500"],
["rgb(239, 172, 67)", "rgb(169, 101, 0)"],
["#ab221c", "#ff9999"],
["rgb(171, 34, 28)", "rgb(255, 153, 153)"],
["#55bfe0", "#167f94"],
["rgb(85, 191, 224)", "rgb(22, 127, 148)"],
["#58b957", "#287f28"],
["rgb(88, 185, 87)", "rgb(40, 127, 40)"],
["rgb(18, 170, 181)", "rgb(14, 145, 155)"],
["rgb(255, 133, 89)", "rgb(189, 84, 46)"],
["rgb(240, 142, 129)", "rgb(165, 81, 70)"],
["rgb(245, 175, 88)", "rgb(133, 72, 0)"],
["rgb(100, 187, 226)", "rgb(28, 103, 136)"],
["rgb(162, 157, 197)", "rgb(99, 95, 129)"],
["rgb(86, 81, 126)", "rgb(164, 160, 198)"],
["#bac8d3", "#39454e"],
["rgb(186, 200, 211)", "rgb(57, 69, 78)"],
["rgb(16, 115, 158)", "rgb(84, 169, 206)"],
["rgb(22, 153, 211)", "rgb(34, 146, 196)"],
["rgb(232, 86, 66)", "rgb(237, 112, 95)"],
["rgb(0, 102, 0)", "rgb(111, 199, 111)"],
["#2f5b7c", "#85abc7"],
["rgb(47, 91, 124)", "rgb(133, 171, 199)"],
["rgb(193, 240, 5)", "rgb(37, 77, 0)"],
["rgb(177, 221, 240)", "rgb(23, 61, 77)"],
["rgb(93, 127, 153)", "rgb(108, 137, 159)"],
["rgb(242, 147, 30)", "rgb(173, 91, 0)"],
["rgb(14, 128, 136)", "rgb(70, 168, 175)"],
["rgb(255, 242, 56)", "rgb(58, 47, 0)"],
["rgb(153, 76, 0)", "rgb(219, 153, 88)"],
["rgb(97, 198, 206)", "rgb(16, 103, 110)"],
["#d4e1f5", "#233247"],
["rgb(212, 225, 245)", "rgb(35, 50, 71)"],
["#e6efff", "#1b2535"],
["rgb(230, 239, 255)", "rgb(27, 37, 53)"],
["#e6f2f8", "#102734"],
["rgb(230, 242, 248)", "rgb(16, 39, 52)"],
["#e9f3e6", "#14240f"],
["rgb(233, 243, 230)", "rgb(20, 36, 15)"],
["#d0ebf6", "#153746"],
["rgb(208, 235, 246)", "rgb(21, 55, 70)"],
["#fce7cd", "#2e1d09"],
["rgb(252, 231, 205)", "rgb(46, 29, 9)"],
["#f8c382", "#5a3000"],
["rgb(248, 195, 130)", "rgb(90, 48, 0)"],
["#faddd9", "#351412"],
["rgb(250, 221, 217)", "rgb(53, 20, 18)"],
["#fad9d5", "#3a1512"],
["rgb(250, 217, 213)", "rgb(58, 21, 18)"],
["#fff4f2", "#241413"],
["rgb(255, 244, 242)", "rgb(36, 20, 19)"],
["#b0e3e6", "#12393c"],
["rgb(176, 227, 230)", "rgb(18, 57, 60)"],
["#c3cd2d", "#536000"],
["rgb(195, 205, 45)", "rgb(83, 96, 0)"],
["gray", "rgb(127, 127, 127)"],
];
KATANA_DRAWIO_EXTRA_LIGHT_TO_DARK_COLOR_ENTRIES.forEach((entry) => {
KATANA_DRAWIO_DARK_COLOR_BY_LIGHT_COLOR.set(entry[0], entry[1]);
});
KATANA_DRAWIO_DARK_CONTEXT_COLOR.set("stop|stop-color|#ffffff", "#121212");
const KATANA_DRAWIO_SIMPLE_DIAGRAM_DARK_COLOR = new Map([
["ellipse|fill|#ffffff", "#121212"],
["path|fill|#ffffff", "#121212"],
]);
const KATANA_DRAWIO_DARK_TEXT_COLOR_BY_LIGHT_COLOR = new Map([
["default", "#ffffff"],
["#000000", "#ffffff"],
["rgb(0, 0, 0)", "rgb(255, 255, 255)"],
["#ffffff", "#ffffff"],
["rgb(255, 255, 255)", "rgb(255, 255, 255)"],
["#121212", "#ffffff"],
["rgb(18, 18, 18)", "rgb(255, 255, 255)"],
["#660000", "#ffc4c4"],
["rgb(102, 0, 0)", "rgb(255, 196, 196)"],
["#0d5b9d", "#70b3ec"],
["rgb(13, 91, 157)", "rgb(112, 179, 236)"],
["#232f3e", "#bdc7d4"],
["rgb(35, 47, 62)", "rgb(189, 199, 212)"],
["#23497d", "#bdd7ff"],
["rgb(35, 73, 125)", "rgb(189, 215, 255)"],
["#23445d", "#a0bcd2"],
["rgb(35, 68, 93)", "rgb(160, 188, 210)"],
["#3333ff", "#a8a8ff"],
["rgb(51, 51, 255)", "rgb(168, 168, 255)"],
["#4286c5", "#518bc1"],
["rgb(66, 134, 197)", "rgb(81, 139, 193)"],
["#7f00ff", "#ff9fff"],
["rgb(127, 0, 255)", "rgb(255, 159, 255)"],
["#cc6600", "#d47d25"],
["rgb(204, 102, 0)", "rgb(212, 125, 37)"],
]);
const KATANA_DRAWIO_TEXT_COLOR_BY_THEME = [new Map(), KATANA_DRAWIO_DARK_TEXT_COLOR_BY_LIGHT_COLOR];
const KATANA_DRAWIO_DARK_SCALE_RULES = [
{ luminance: 0.82, saturation: 0.25, scale: 0.14 },
{ luminance: 0.82, saturation: Number.POSITIVE_INFINITY, scale: 0.35 },
{ luminance: 0.62, saturation: 0.2, scale: 0.24 },
{ luminance: 0.62, saturation: Number.POSITIVE_INFINITY, scale: 0.45 },
{ luminance: 0.42, saturation: Number.POSITIVE_INFINITY, scale: 0.62 },
{ luminance: Number.NEGATIVE_INFINITY, saturation: Number.POSITIVE_INFINITY, scale: 1 },
];
const KATANA_DRAWIO_HEX_COLOR_READERS = [katanaDrawioFullHexChannels, katanaDrawioShortHexChannels];
function katanaDrawioDarkScale(color) {
const metrics = katanaDrawioColorMetrics(color);
return KATANA_DRAWIO_DARK_SCALE_RULES.find((rule) =>
katanaDrawioDarkScaleRuleMatches(metrics, rule),
).scale;
}
function katanaDrawioColorMetrics(color) {
return {
luminance: katanaDrawioRgbLuminance(color),
saturation: katanaDrawioRgbSaturation(color),
};
}
function katanaDrawioDarkScaleRuleMatches(metrics, rule) {
return [metrics.luminance > rule.luminance, metrics.saturation < rule.saturation].every(Boolean);
}
function katanaDrawioScaledDarkColor(color, scale) {
return color.map((channel) => Math.round(channel * scale));
}
function katanaDrawioColorLuminance(value) {
return [katanaDrawioParsedColor(value)]
.filter(Boolean)
.map(katanaDrawioRgbLuminance)
.concat([1])[0];
}
function katanaDrawioRgbLuminance(color) {
return (0.2126 * color[0] + 0.7152 * color[1] + 0.0722 * color[2]) / 255;
}
function katanaDrawioRgbSaturation(color) {
const channels = color.map((channel) => channel / 255);
const max = Math.max(...channels);
const min = Math.min(...channels);
return max === 0 ? 0 : (max - min) / max;
}
function katanaDrawioParsedColor(value) {
return katanaDrawioParsedHexColor(value) || katanaDrawioParsedRgbColor(value);
}
function katanaDrawioParsedHexColor(value) {
return KATANA_DRAWIO_HEX_COLOR_READERS.map((reader) => reader(value))
.filter(Boolean)
.concat([null])[0];
}
function katanaDrawioFullHexChannels(value) {
const match = /^#([0-9a-f]{6})$/iu.exec(value);
return match ? katanaDrawioHexChannels(match[1]) : null;
}
function katanaDrawioShortHexChannels(value) {
const match = /^#([0-9a-f]{3})$/iu.exec(value);
return match ? katanaDrawioHexChannels(katanaDrawioExpandedHex(match[1])) : null;
}
function katanaDrawioExpandedHex(hex) {
return hex
.split("")
.map((channel) => `${channel}${channel}`)
.join("");
}
function katanaDrawioHexChannels(hex) {
return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map((channel) =>
Number.parseInt(channel, 16),
);
}
function katanaDrawioParsedRgbColor(value) {
const match = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/iu.exec(value);
return match ? match.slice(1, 4).map(Number) : null;
}
function katanaDrawioRgbHex(color) {
return `#${color.map(katanaDrawioHexChannel).join("")}`;
}
function katanaDrawioHexChannel(channel) {
return channel.toString(16).padStart(2, "0");
}
const KATANA_DRAWIO_DARK_TEXT_FALLBACK_COLORS = ["", "#ffffff"];
function katanaDrawioSimpleDiagramDarkColor(element, name, value) {
return (
KATANA_DRAWIO_SIMPLE_DIAGRAM_DARK_COLOR.get(
katanaDrawioSimpleDiagramDarkColorKey(element, name, value),
) ?? ""
);
}
function katanaDrawioSimpleDiagramDarkColorKey(element, name, value) {
return katanaDrawioShouldUseSimpleDiagramDarkColor(element, name, value)
? katanaDrawioContextColorKey(element, name, value)
: "";
}
function katanaDrawioShouldUseSimpleDiagramDarkColor(element, name, value) {
return [
katanaDrawioIsDarkMode(),
name === "fill",
value === "#ffffff",
katanaDrawioIsTooltipsSource(),
katanaDrawioIsTooltipsDarkFillElement(element),
].every(Boolean);
}
function katanaDrawioIsTooltipsSource() {
return String(globalThis.__katanaDrawioRequest?.source ?? "").includes("tooltip=");
}
function katanaDrawioIsTooltipsDarkFillElement(element) {
return [element.localName === "ellipse", katanaDrawioIsLargeTooltipsPath(element)].some(Boolean);
}
function katanaDrawioIsLargeTooltipsPath(element) {
return [element.localName === "path", katanaDrawioElementArea(element) > 1000].every(Boolean);
}
function katanaNormalizeDrawioStyleTextColor(element) {
const style = String(element.getAttribute("style"));
[katanaDrawioStylePropertyValue(style, "color")]
.filter(Boolean)
.map(katanaDrawioResolvedTextColor)
.filter(Boolean)
.forEach((color) => {
element.setAttribute("style", katanaDrawioStyleWithProperty(style, "color", color));
});
}
function katanaDrawioResolvedTextColor(color) {
const value = katanaDrawioColorKey(color);
return (
katanaDrawioLightDarkExactColor(value) ||
katanaDrawioTextColorMapForTheme().get(value) ||
katanaDrawioFallbackDarkTextColor(value) ||
value
);
}
function katanaDrawioTextColorMapForTheme() {
return KATANA_DRAWIO_TEXT_COLOR_BY_THEME[Number(katanaDrawioIsDarkMode())];
}
function katanaDrawioStyleWithProperty(style, name, value) {
return String(style)
.split(";")
.map((declaration) => katanaDrawioStylePropertyDeclaration(declaration, name, value))
.filter(Boolean)
.join("; ");
}
function katanaDrawioStylePropertyDeclaration(declaration, name, value) {
const text = declaration.trim();
return [text]
.filter(Boolean)
.map((it) => katanaDrawioStylePropertyReplacement(it, name, value) || it)
.concat([""])[0];
}
function katanaDrawioStylePropertyReplacement(declaration, name, value) {
return [declaration]
.filter((it) => katanaDrawioStyleDeclarationName(it) === name)
.map(() => `${name}: ${value}`)
.concat([""])[0];
}
function katanaDrawioStyleDeclarationName(declaration) {
return declaration.slice(0, declaration.indexOf(":")).trim().toLowerCase();
}
function katanaDrawioFallbackThemeColor(element, name, value) {
return katanaDrawioShouldUseFallbackDarkColor(element, name)
? katanaDrawioFallbackDarkColor(value)
: "";
}
function katanaDrawioShouldUseFallbackDarkColor(element, name) {
return [
katanaDrawioIsDarkMode(),
["fill", "stop-color"].includes(name),
element.localName !== "text",
].every(Boolean);
}
function katanaDrawioFallbackDarkTextColor(value) {
return KATANA_DRAWIO_DARK_TEXT_FALLBACK_COLORS[
Number(katanaDrawioShouldUseFallbackDarkTextColor(value))
];
}
function katanaDrawioShouldUseFallbackDarkTextColor(value) {
return [katanaDrawioIsDarkMode(), katanaDrawioColorLuminance(value) < 0.45].every(Boolean);
}
function katanaDrawioFallbackDarkColor(value) {
return [katanaDrawioParsedColor(value)]
.filter(Boolean)
.map(katanaDrawioDarkThemeColor)
.concat([""])[0];
}
function katanaDrawioDarkThemeColor(color) {
return katanaDrawioRgbHex(katanaDrawioScaledDarkColor(color, katanaDrawioDarkScale(color)));
}
function katanaApplyDrawioShadows(svg) {
Array.from(svg.querySelectorAll("g[data-cell-id]"))
.filter(katanaDrawioHasShadowStyle)
.map(katanaDrawioShadowTarget)
.filter(Boolean)
.forEach(katanaSetDrawioShadowStyle);
}
function katanaDrawioHasShadowStyle(group) {
return katanaDrawioSourceStyleForGroup(group).get("shadow") === "1";
}
function katanaDrawioSourceStyleForGroup(group) {
return KATANA_DRAWIO_SOURCE_CELL_STYLE_CACHE.get(katanaDrawioElementCellId(group)) ?? new Map();
}
function katanaDrawioShadowTarget(group) {
return Array.from(group.children).find(katanaDrawioIsShadowShapeGroup) ?? null;
}
function katanaDrawioIsShadowShapeGroup(element) {
return [element.localName === "g", element.hasAttribute("transform")].every(Boolean);
}
function katanaSetDrawioShadowStyle(element) {
element.setAttribute(
"style",
katanaDrawioStyleWithAddedProperty(
katanaDrawioShadowBaseStyle(element),
"filter",
katanaDrawioShadowFilter(),
),
);
}
function katanaDrawioShadowBaseStyle(element) {
return String(element.getAttribute("style") ?? "");
}
function katanaDrawioShadowFilter() {
return katanaDrawioIsDarkMode()
? "drop-shadow(rgba(237, 237, 237, 0.25) 2px 3px 2px)"
: "drop-shadow(rgba(0, 0, 0, 0.25) 2px 3px 2px)";
}
function katanaDrawioStyleWithAddedProperty(style, name, value) {
const rewritten = katanaDrawioStyleWithProperty(style, name, value);
return rewritten.includes(`${name}:`)
? rewritten
: [rewritten, `${name}: ${value}`].filter(Boolean).join("; ");
}
const KATANA_EMPTY_DRAWIO_ATTRIBUTES = new Map();
const KATANA_DRAWIO_ATTRIBUTE_READERS = [
katanaEmptyDrawioAttributes,
katanaReadableDrawioAttributes,
];
function katanaFillMissingDrawioTextLabels(svg) {
katanaDrawioSourceCellLabels().forEach((entry) => {
katanaFillMissingDrawioCellLabel(svg, entry);
});
}
function katanaDrawioSourceCellLabels() {
return Array.from(katanaDrawioRequestSource().matchAll(/<mxCell\b([^>]*)>/g))
.map(katanaDrawioCellLabelEntry)
.filter(katanaHasDrawioCellLabel);
}
function katanaDrawioRequestSource() {
return String(globalThis.__katanaDrawioRequest?.source ?? "");
}
function katanaDrawioCellLabelEntry(match) {
const attributes = katanaDrawioXmlAttributes(match[1]);
return {
id: katanaDrawioCellAttribute(attributes, "id"),
label: katanaDrawioHtmlLabelText(katanaDrawioCellAttribute(attributes, "value")),
style: katanaDrawioCellAttribute(attributes, "style"),
};
}
function katanaDrawioCellAttribute(attributes, name) {
return katanaDrawioAttributeReader(attributes).get(name) ?? "";
}
function katanaDrawioAttributeReader(attributes) {
return KATANA_DRAWIO_ATTRIBUTE_READERS[Number(katanaCanReadDrawioAttributes(attributes))](
attributes,
);
}
function katanaCanReadDrawioAttributes(attributes) {
return typeof attributes?.get === "function";
}
function katanaReadableDrawioAttributes(attributes) {
return attributes;
}
function katanaEmptyDrawioAttributes(_attributes) {
return KATANA_EMPTY_DRAWIO_ATTRIBUTES;
}
function katanaDrawioXmlAttributes(source) {
return new Map(
Array.from(String(source).matchAll(/([a-zA-Z0-9:_-]+)="([^"]*)"/g)).map(
katanaDrawioXmlAttributeEntry,
),
);
}
function katanaDrawioXmlAttributeEntry(match) {
return [match[1], decodeHtmlEntities(match[2])];
}
function katanaHasDrawioCellLabel(entry) {
return [entry.id, entry.label].every(Boolean);
}
function katanaFillMissingDrawioCellLabel(svg, entry) {
[katanaDrawioCellGroup(svg, entry.id)]
.filter(Boolean)
.filter(katanaShouldInsertDrawioText)
.forEach((group) => {
group.appendChild(katanaCreateDrawioTextLabel(group, entry));
});
}
function katanaDrawioCellGroup(svg, id) {
return (
Array.from(svg.querySelectorAll("g")).find(
(node) => node.getAttribute("data-cell-id") === id,
) ?? null
);
}
function katanaShouldInsertDrawioText(group) {
return [group, !katanaDrawioCellHasText(group), katanaDrawioCellShapeBox(group)].every(Boolean);
}
function katanaDrawioCellHasText(group) {
return group.querySelectorAll("text").length > 0;
}
function katanaCreateDrawioTextLabel(group, entry) {
const box = katanaDrawioCellShapeBox(group);
const lines = katanaDrawioTextLines(entry.label);
const text = katanaDrawioTextElement(box, entry, lines);
lines.forEach((line, index) => {
text.appendChild(katanaCreateDrawioTextLine(text, line, index, entry.style));
});
return text;
}
function katanaDrawioTextElement(box, entry, lines) {
const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
const fontSize = katanaDrawioFontSize(entry.style);
const position = katanaDrawioLabelPosition(box, entry, lines, fontSize);
text.setAttribute("x", position.x);
text.setAttribute("y", position.y);
text.setAttribute("fill", katanaDrawioTextColor(entry.style));
text.setAttribute("font-family", "Helvetica");
text.setAttribute("font-size", `${fontSize}px`);
text.setAttribute("text-anchor", position.anchor);
return text;
}
function katanaCreateDrawioTextLine(text, line, index, style) {
const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
tspan.setAttribute("x", text.getAttribute("x"));
tspan.setAttribute("dy", katanaDrawioTextLineDy(index, katanaDrawioFontSize(style)));
tspan.textContent = line;
return tspan;
}
function katanaDrawioCellShapeBox(group) {
return katanaDrawioUnionBox(
katanaDrawioCellShapeElements(group).map(katanaDrawioElementBox).filter(katanaDrawioHasArea),
);
}
function katanaDrawioCellShapeElements(group) {
return katanaDrawioCellShapeTagNames().flatMap((tagName) =>
Array.from(group.querySelectorAll(tagName)),
);
}
function katanaDrawioCellShapeTagNames() {
return ["rect", "path", "ellipse", "circle", "polygon", "polyline", "image"];
}
function katanaDrawioTextLines(label) {
return String(label).split(/\n+/).filter(Boolean);
}
function katanaDrawioLabelPosition(box, entry, lines, fontSize) {
return katanaDrawioLabelPositioner(entry.style)(box, entry, lines, fontSize);
}
function katanaDrawioLabelPositioner(style) {
return (
KATANA_DRAWIO_LABEL_POSITIONERS.get(katanaDrawioStyleValue(style, "labelPosition")) ??
KATANA_DRAWIO_LABEL_POSITIONERS.get(katanaDrawioStyleValue(style, "verticalLabelPosition")) ??
katanaDrawioCenterLabelPosition
);
}
function katanaDrawioCenterLabelPosition(box, _entry, lines, fontSize) {
return katanaDrawioTextPosition(
box.x + box.width / 2,
katanaDrawioCenteredTextY(box, lines, fontSize),
"middle",
);
}
function katanaDrawioBottomLabelPosition(box, entry, _lines, fontSize) {
return katanaDrawioTextPosition(
box.x + box.width / 2,
box.y + box.height + fontSize + 7 + katanaDrawioSpacing(entry.style, "spacingTop"),
"middle",
);
}
function katanaDrawioRightLabelPosition(box, entry, lines, fontSize) {
const x = box.x + box.width + 2 + katanaDrawioSpacing(entry.style, "spacingLeft");
return katanaDrawioTextPosition(x, katanaDrawioCenteredTextY(box, lines, fontSize), "start");
}
function katanaDrawioTextPosition(x, y, anchor) {
return { x, y, anchor };
}
function katanaDrawioCenteredTextY(box, lines, fontSize) {
return box.y + box.height / 2 + fontSize / 3 - ((lines.length - 1) * fontSize * 1.25) / 2;
}
function katanaDrawioSpacing(style, name) {
const value = Number(katanaDrawioStyleValue(style, name));
return [value].filter(Number.isFinite).concat([0])[0];
}
function katanaDrawioTextLineDy(index, fontSize) {
return ["0", String(Math.ceil(fontSize * 1.25))][Number(index > 0)];
}
const KATANA_DRAWIO_LABEL_POSITIONERS = new Map([
["bottom", katanaDrawioBottomLabelPosition],
["right", katanaDrawioRightLabelPosition],
]);
function katanaNormalizeRichDrawioTextLabels(svg) {
katanaDrawioRichTextLabelEntries().forEach((entry) => {
katanaNormalizeRichDrawioTextLabel(svg, entry);
});
}
function katanaDrawioRichTextLabelEntries() {
return Array.from(katanaDrawioRequestSource().matchAll(/<mxCell\b([^>]*)>/g))
.map(katanaDrawioRichTextLabelEntry)
.filter(katanaHasRichDrawioTextLabel);
}
function katanaDrawioRichTextLabelEntry(match) {
const attributes = katanaDrawioXmlAttributes(match[1]);
const label = katanaDrawioCellAttribute(attributes, "value");
return {
id: katanaDrawioCellAttribute(attributes, "id"),
lines: katanaDrawioRichTextLines(label),
};
}
function katanaHasRichDrawioTextLabel(entry) {
return [
entry.id,
entry.lines.length > 0,
entry.lines.some((line) => line.bold || line.italic),
].every(Boolean);
}
function katanaDrawioRichTextLines(label) {
return String(label)
.split(/<\s*br\s*\/?>/i)
.map(katanaDrawioRichTextLine)
.filter((line) => line.text);
}
function katanaDrawioRichTextLine(source) {
return {
text: katanaDrawioHtmlLabelText(source),
bold: /<\s*b\b/i.test(source),
italic: /<\s*i\b/i.test(source),
};
}
function katanaNormalizeRichDrawioTextLabel(svg, entry) {
[katanaDrawioCellGroup(svg, entry.id)]
.filter(Boolean)
.filter((group) => !katanaDrawioGroupHasForeignObject(group))
.map(katanaDrawioRichTextElement)
.filter(Boolean)
.forEach((text) => {
katanaApplyRichDrawioTextLines(text, entry.lines);
});
}
function katanaDrawioRichTextElement(group) {
return Array.from(group.querySelectorAll("text"))[0] ?? null;
}
function katanaApplyRichDrawioTextLines(text, lines) {
const tspans = Array.from(text.querySelectorAll("tspan"));
if (tspans.length === 0) {
katanaApplyRichDrawioTextStyle(text, lines[0]);
return;
}
tspans.forEach((tspan, index) => {
katanaApplyRichDrawioTextStyle(tspan, lines[index]);
});
}
function katanaApplyRichDrawioTextStyle(node, line) {
katanaRichDrawioTextAttributes(line).forEach((attribute) => {
node.setAttribute(attribute.name, attribute.value);
});
}
function katanaRichDrawioTextAttributes(line) {
return [line]
.filter(Boolean)
.flatMap((it) => [
[it.bold, { name: "font-weight", value: "bold" }],
[it.italic, { name: "font-style", value: "italic" }],
])
.filter((entry) => entry[0])
.map((entry) => entry[1]);
}
let KATANA_DRAWIO_LABEL_CLIP_INDEX = 0;
function katanaClipWrappedDrawioTextLabel(text, box) {
[katanaDrawioSvgAncestor(text)].filter(Boolean).forEach((svg) => {
const id = katanaDrawioNextLabelClipId();
katanaDrawioSvgDefs(svg).appendChild(katanaCreateDrawioLabelClipPath(id, box));
text.setAttribute("clip-path", `url(#${id})`);
});
}
function katanaDrawioNextLabelClipId() {
KATANA_DRAWIO_LABEL_CLIP_INDEX += 1;
return `katana-drawio-label-clip-${KATANA_DRAWIO_LABEL_CLIP_INDEX}`;
}
function katanaDrawioSvgAncestor(element) {
return katanaDrawioAncestorElements(element)
.filter((it) => it.localName === "svg")
.concat([null])[0];
}
function katanaDrawioAncestorElements(element) {
const parent1 = katanaDrawioParentNode(element);
const parent2 = katanaDrawioParentNode(parent1);
const parent3 = katanaDrawioParentNode(parent2);
const parent4 = katanaDrawioParentNode(parent3);
const parent5 = katanaDrawioParentNode(parent4);
const parent6 = katanaDrawioParentNode(parent5);
return [element, parent1, parent2, parent3, parent4, parent5, parent6].filter(Boolean);
}
function katanaDrawioSvgDefs(svg) {
return [svg.querySelector("defs")].filter(Boolean).concat([katanaCreateDrawioSvgDefs(svg)])[0];
}
function katanaCreateDrawioSvgDefs(svg) {
const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
svg.insertBefore(defs, svg.firstChild);
return defs;
}
function katanaCreateDrawioLabelClipPath(id, box) {
const clipPath = document.createElementNS("http://www.w3.org/2000/svg", "clipPath");
clipPath.setAttribute("id", id);
clipPath.appendChild(katanaCreateDrawioLabelClipRect(box));
return clipPath;
}
function katanaCreateDrawioLabelClipRect(box) {
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("x", box.x);
rect.setAttribute("y", box.y);
rect.setAttribute("width", box.width);
rect.setAttribute("height", box.height);
return rect;
}
function katanaNormalizeWrappedDrawioTextLabels(svg) {
katanaDrawioSourceCellLabels().forEach((entry) => {
katanaNormalizeWrappedDrawioTextLabel(svg, entry);
});
}
function katanaNormalizeWrappedDrawioTextLabel(svg, entry) {
[katanaDrawioCellGroup(svg, entry.id)]
.filter(Boolean)
.filter((group) => katanaShouldNormalizeWrappedDrawioLabel(group, entry))
.forEach((group) => {
katanaReplaceWrappedDrawioTextLabel(group, entry);
});
}
function katanaShouldNormalizeWrappedDrawioLabel(group, entry) {
if (katanaDrawioGroupHasForeignObject(group)) return false;
return [katanaDrawioCellShapeBox(group)]
.filter(Boolean)
.map((box) => katanaWrappedDrawioLabelNeeded(entry, box))
.concat([false])[0];
}
function katanaDrawioGroupHasForeignObject(group) {
return group.querySelectorAll("foreignObject").length > 0;
}
function katanaWrappedDrawioLabelNeeded(entry, box) {
return [
katanaDrawioStyleValue(entry.style, "whiteSpace") === "wrap",
katanaDrawioTextNeedsWrap(entry.label, box, katanaDrawioFontSize(entry.style)),
].every(Boolean);
}
function katanaDrawioTextNeedsWrap(label, box, fontSize) {
const lineLimit = katanaDrawioMaxLineChars(box, fontSize);
return katanaDrawioTextLines(label).some((line) => line.length > lineLimit);
}
function katanaReplaceWrappedDrawioTextLabel(group, entry) {
[katanaDrawioCellShapeBox(group)].filter(Boolean).forEach((box) => {
const label = katanaCreateWrappedDrawioTextLabel(entry, box);
katanaDrawioTextNodes(group).forEach(katanaRemoveDrawioNode);
group.appendChild(label);
katanaClipWrappedDrawioTextLabel(label, box);
});
}
function katanaDrawioTextNodes(group) {
return Array.from(group.querySelectorAll("text"));
}
function katanaCreateWrappedDrawioTextLabel(entry, box) {
const style = entry.style;
const fontSize = katanaDrawioFontSize(entry.style);
const lines = katanaDrawioWrappedTextLines(entry.label, box, fontSize);
const text = katanaWrappedDrawioTextElement(box, style, lines, fontSize);
lines.forEach((line, index) => {
text.appendChild(katanaWrappedDrawioTextLine(text, line, index, fontSize));
});
return text;
}
function katanaWrappedDrawioTextElement(box, style, lines, fontSize) {
const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
const alignment = katanaDrawioTextAlignment(style);
text.setAttribute("x", katanaDrawioAlignedTextX(box, alignment));
text.setAttribute("y", katanaDrawioAlignedTextY(box, style, lines, fontSize));
text.setAttribute("fill", katanaDrawioTextColor(style));
text.setAttribute("font-family", "Helvetica");
text.setAttribute("font-size", `${fontSize}px`);
text.setAttribute("text-anchor", alignment.anchor);
return text;
}
function katanaWrappedDrawioTextLine(text, line, index, fontSize) {
const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
tspan.setAttribute("x", text.getAttribute("x"));
tspan.setAttribute("dy", katanaWrappedDrawioLineDy(index, fontSize));
tspan.textContent = line;
return tspan;
}
function katanaDrawioWrappedTextLines(label, box, fontSize) {
const lineLimit = katanaDrawioMaxLineChars(box, fontSize);
return katanaDrawioTextLines(label).flatMap((line) => katanaDrawioWrapTextLine(line, lineLimit));
}
function katanaDrawioWrapTextLine(line, lineLimit) {
return String(line)
.split(/\s+/)
.filter(Boolean)
.reduce(katanaAppendDrawioWrappedWord(lineLimit), []);
}
function katanaAppendDrawioWrappedWord(lineLimit) {
return (lines, word) => katanaAppendDrawioWrappedLine(lines, word, lineLimit);
}
function katanaAppendDrawioWrappedLine(lines, word, lineLimit) {
const candidate = [katanaDrawioLastTextLine(lines), word].filter(Boolean).join(" ");
return candidate.length <= lineLimit
? katanaDrawioReplaceLastTextLine(lines, candidate)
: lines.concat([word]);
}
function katanaDrawioLastTextLine(lines) {
return lines.at(-1) ?? "";
}
function katanaDrawioReplaceLastTextLine(lines, line) {
return lines.slice(0, -1).concat([line]);
}
function katanaDrawioMaxLineChars(box, fontSize) {
return Math.max(1, Math.floor((box.width - 8) / katanaDrawioAverageCharWidth(fontSize)));
}
function katanaDrawioAverageCharWidth(fontSize) {
return fontSize * 0.55;
}
function katanaDrawioAlignedTextX(box, alignment) {
return box.x + alignment.offset + box.width * alignment.ratio;
}
function katanaDrawioAlignedTextY(box, style, lines, fontSize) {
return katanaDrawioTextVerticalAlignment(style).y(box, lines, fontSize);
}
function katanaDrawioStyleMap(style) {
return new Map(
String(style)
.split(";")
.map(katanaDrawioStyleEntry)
.filter((entry) => entry[0]),
);
}
function katanaDrawioStyleEntry(value) {
const parts = String(value).split("=").concat(["", ""]);
return [parts[0], parts[1]];
}
function katanaDrawioStyleValue(style, name) {
return katanaDrawioStyleMap(style).get(name) ?? "";
}
function katanaDrawioFontSize(style) {
const value = Number(katanaDrawioStyleValue(style, "fontSize"));
return [value]
.filter(Number.isFinite)
.filter((it) => it > 0)
.concat([12])[0];
}
function katanaDrawioTextColor(style) {
return katanaDrawioStyleValueFromMap(style, "fontColor", "#000000");
}
function katanaDrawioStyleValueFromMap(style, name, fallback) {
return katanaDrawioStyleMap(style).get(name) ?? fallback;
}
function katanaDrawioTextAlignment(style) {
return (
KATANA_DRAWIO_TEXT_ALIGNMENT.get(katanaDrawioStyleValueFromMap(style, "align", "center")) ??
KATANA_DRAWIO_TEXT_ALIGNMENT.get("center")
);
}
function katanaDrawioTextVerticalAlignment(style) {
return (
KATANA_DRAWIO_TEXT_VERTICAL_ALIGNMENT.get(
katanaDrawioStyleValueFromMap(style, "verticalAlign", "middle"),
) ?? KATANA_DRAWIO_TEXT_VERTICAL_ALIGNMENT.get("middle")
);
}
function katanaWrappedDrawioLineDy(index, fontSize) {
return ["0", String(Math.ceil(fontSize * 1.2))][Number(index > 0)];
}
const KATANA_DRAWIO_TEXT_ALIGNMENT = new Map([
["left", { anchor: "start", offset: 4, ratio: 0 }],
["center", { anchor: "middle", offset: 0, ratio: 0.5 }],
["right", { anchor: "end", offset: -4, ratio: 1 }],
]);
const KATANA_DRAWIO_TEXT_VERTICAL_ALIGNMENT = new Map([
["top", { y: (box, _lines, fontSize) => box.y + fontSize }],
[
"middle",
{
y: (box, lines, fontSize) =>
box.y + box.height / 2 + fontSize / 2 - ((lines.length - 1) * fontSize * 1.2) / 2,
},
],
["bottom", { y: (box, lines, fontSize) => box.y + box.height - lines.length * fontSize }],
]);
function katanaDrawioHtmlTextOuterStyle(style, box) {
return [
"display: flex",
`align-items: unsafe ${katanaDrawioHtmlTextAlignItems(style)}`,
`justify-content: unsafe ${katanaDrawioHtmlTextJustifyContent(style)}`,
`width: ${katanaDrawioHtmlTextWidth(style, box)}px`,
"height: 1px",
`padding-top: ${katanaDrawioHtmlTextTop(style, box)}px`,
`margin-left: ${katanaDrawioHtmlTextLeft(style, box)}px`,
].join("; ");
}
function katanaDrawioHtmlTextBoxStyle(style) {
return [
"box-sizing: border-box",
"font-size: 0",
`text-align: ${katanaDrawioTextAlign(style)}`,
`color: ${katanaDrawioTextColor(style)}`,
"",
].join("; ");
}
function katanaDrawioHtmlTextContentStyle(style) {
return [
"display: inline-block",
`font-size: ${katanaDrawioFontSize(style)}px`,
`font-family: ${katanaDrawioHtmlFontFamily(style)}`,
`color: ${katanaDrawioHtmlTextColor(style)}`,
"line-height: 1.2",
"pointer-events: all",
"white-space: normal",
"word-wrap: normal",
"",
].join("; ");
}
function katanaDrawioHtmlTextAlignItems(style) {
return (
KATANA_DRAWIO_HTML_TEXT_ALIGN_ITEMS.get(
katanaDrawioStyleValueFromMap(style, "verticalAlign", "middle"),
) ?? "center"
);
}
function katanaDrawioHtmlTextJustifyContent(style) {
return (
KATANA_DRAWIO_HTML_TEXT_JUSTIFY_CONTENT.get(
katanaDrawioStyleValueFromMap(style, "align", "center"),
) ?? "center"
);
}
function katanaDrawioTextAlign(style) {
return katanaDrawioStyleValueFromMap(style, "align", "center");
}
function katanaDrawioHtmlFontFamily(style) {
const family = katanaDrawioStyleValueFromMap(style, "fontFamily", "Helvetica");
return family.includes(" ") ? `'${family}'` : family;
}
function katanaDrawioHtmlTextTop(style, box) {
return Math.round(
(
KATANA_DRAWIO_HTML_TEXT_TOP_BY_ALIGNMENT.get(
katanaDrawioStyleValueFromMap(style, "verticalAlign", "middle"),
) ?? katanaDrawioMiddleHtmlTextTop
)(box),
);
}
function katanaDrawioTopHtmlTextTop(box) {
return box.y + KATANA_DRAWIO_HTML_TEXT_TOP_PADDING;
}
function katanaDrawioMiddleHtmlTextTop(box) {
return box.y + box.height / 2;
}
function katanaDrawioBottomHtmlTextTop(box) {
return box.y + box.height - KATANA_DRAWIO_HTML_TEXT_TOP_PADDING;
}
function katanaDrawioHtmlTextWidth(style, box) {
return katanaDrawioIsRightHtmlTextLabel(style) ? 1 : Math.max(1, Math.round(box.width - 2));
}
function katanaDrawioHtmlTextLeft(style, box) {
return Math.round(
katanaDrawioIsRightHtmlTextLabel(style)
? box.x + box.width + 2 + katanaDrawioHtmlTextSpacingLeft(style)
: box.x + KATANA_DRAWIO_HTML_TEXT_LEFT_PADDING,
);
}
function katanaDrawioIsRightHtmlTextLabel(style) {
return katanaDrawioStyleValue(style, "labelPosition") === "right";
}
function katanaDrawioHtmlTextSpacingLeft(style) {
const value = Number(katanaDrawioStyleValue(style, "spacingLeft"));
return [value].filter(Number.isFinite).concat([0])[0];
}
function katanaDrawioHtmlTextColor(style) {
const color = katanaDrawioTextColor(style);
return KATANA_DRAWIO_HTML_TEXT_DARK_COLOR.get(color.toLowerCase()) ?? color;
}
const KATANA_DRAWIO_HTML_TEXT_TOP_PADDING = 3;
const KATANA_DRAWIO_HTML_TEXT_LEFT_PADDING = 1;
const KATANA_DRAWIO_HTML_TEXT_TOP_BY_ALIGNMENT = new Map([
["top", katanaDrawioTopHtmlTextTop],
["middle", katanaDrawioMiddleHtmlTextTop],
["bottom", katanaDrawioBottomHtmlTextTop],
]);
const KATANA_DRAWIO_HTML_TEXT_ALIGN_ITEMS = new Map([
["top", "flex-start"],
["middle", "center"],
["bottom", "flex-end"],
]);
const KATANA_DRAWIO_HTML_TEXT_JUSTIFY_CONTENT = new Map([
["left", "flex-start"],
["center", "center"],
["right", "flex-end"],
]);
const KATANA_DRAWIO_HTML_TEXT_DARK_COLOR = new Map([["#000000", "light-dark(#000000, #ffffff)"]]);
function katanaInstallDrawioHtmlTextLabels(svg) {
katanaDrawioHtmlTextLabelEntries().forEach((entry) => {
katanaInstallDrawioHtmlTextLabel(svg, entry);
});
}
function katanaDrawioHtmlTextLabelEntries() {
return Array.from(katanaDrawioRequestSource().matchAll(/<mxCell\b([^>]*)>/g))
.map(katanaDrawioHtmlTextLabelEntry)
.filter(katanaHasDrawioHtmlTextLabel);
}
function katanaDrawioHtmlTextLabelEntry(match) {
const attributes = katanaDrawioXmlAttributes(match[1]);
const html = katanaDrawioCellAttribute(attributes, "value");
return {
id: katanaDrawioCellAttribute(attributes, "id"),
html: katanaDrawioHtmlTextLabelHtml(html),
label: katanaDrawioHtmlLabelText(html),
style: katanaDrawioCellAttribute(attributes, "style"),
};
}
function katanaDrawioHtmlTextLabelHtml(html) {
return katanaDrawioIsDarkMode()
? String(html).replaceAll('color="#000000"', 'color="#ededed"')
: html;
}
function katanaHasDrawioHtmlTextLabel(entry) {
return [
entry.id,
entry.html,
entry.label,
katanaDrawioStyleValue(entry.style, "html") === "1",
].every(Boolean);
}
function katanaInstallDrawioHtmlTextLabel(svg, entry) {
[katanaDrawioCellGroup(svg, entry.id)]
.filter(Boolean)
.filter((group) => !katanaDrawioGroupHasForeignObject(group))
.map((group) => katanaDrawioHtmlTextLabelContext(group, entry))
.filter(katanaHasDrawioHtmlTextLabelContext)
.forEach(katanaApplyDrawioHtmlTextLabel);
}
function katanaDrawioHtmlTextLabelContext(group, entry) {
return {
group,
entry,
box: katanaDrawioCellShapeBox(group),
fallback: katanaDrawioTextNodes(group),
};
}
function katanaHasDrawioHtmlTextLabelContext(context) {
return [context.box, context.fallback.length > 0].every(Boolean);
}
function katanaApplyDrawioHtmlTextLabel(context) {
const label = katanaCreateDrawioHtmlTextLabel(context.entry, context.box, context.fallback);
context.group.appendChild(label);
}
function katanaCreateDrawioHtmlTextLabel(entry, box, fallback) {
const group = katanaCreateDrawioSvgElement("g");
const scaled = katanaCreateDrawioSvgElement("g");
const switchNode = katanaCreateDrawioSvgElement("switch");
scaled.setAttribute("transform", "scale(0.9999999999999999)");
switchNode.appendChild(katanaCreateDrawioHtmlTextForeignObject(entry, box));
fallback.forEach((node) => {
switchNode.appendChild(node);
});
scaled.appendChild(switchNode);
group.appendChild(scaled);
return group;
}
function katanaCreateDrawioHtmlTextForeignObject(entry, box) {
const foreignObject = katanaCreateDrawioSvgElement("foreignObject");
foreignObject.setAttribute(
"style",
`overflow: visible; text-align: ${katanaDrawioTextAlign(entry.style)};`,
);
foreignObject.setAttribute("pointer-events", "none");
foreignObject.setAttribute("width", "101%");
foreignObject.setAttribute("height", "101%");
foreignObject.setAttribute(
"requiredFeatures",
"http://www.w3.org/TR/SVG11/feature#Extensibility",
);
foreignObject.appendChild(katanaCreateDrawioHtmlTextOuterDiv(entry, box));
return foreignObject;
}
function katanaCreateDrawioHtmlTextOuterDiv(entry, box) {
const div = katanaCreateDrawioHtmlElement("div");
div.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
div.setAttribute("style", katanaDrawioHtmlTextOuterStyle(entry.style, box));
div.appendChild(katanaCreateDrawioHtmlTextBoxDiv(entry));
return div;
}
function katanaCreateDrawioHtmlTextBoxDiv(entry) {
const div = katanaCreateDrawioHtmlElement("div");
div.setAttribute("style", katanaDrawioHtmlTextBoxStyle(entry.style));
div.appendChild(katanaCreateDrawioHtmlTextContentDiv(entry));
return div;
}
function katanaCreateDrawioHtmlTextContentDiv(entry) {
const div = katanaCreateDrawioHtmlElement("div");
div.setAttribute("style", katanaDrawioHtmlTextContentStyle(entry.style));
div.innerHTML = entry.html;
return div;
}
function katanaCreateDrawioSvgElement(tagName) {
return document.createElementNS("http://www.w3.org/2000/svg", tagName);
}
function katanaCreateDrawioHtmlElement(tagName) {
return document.createElementNS("http://www.w3.org/1999/xhtml", tagName);
}
function katanaNormalizeDrawioHtmlTables(svg) {
katanaDrawioHtmlTableEntries().forEach((entry) => {
katanaNormalizeDrawioHtmlTable(svg, entry);
});
}
function katanaDrawioHtmlTableEntries() {
return Array.from(katanaDrawioRequestSource().matchAll(/<mxCell\b([^>]*)>/g))
.map(katanaDrawioHtmlTableEntry)
.filter(katanaHasDrawioHtmlTableEntry);
}
function katanaDrawioHtmlTableEntry(match) {
const attributes = katanaDrawioXmlAttributes(match[1]);
return {
id: katanaDrawioCellAttribute(attributes, "id"),
html: katanaDrawioCellAttribute(attributes, "value"),
style: katanaDrawioCellAttribute(attributes, "style"),
};
}
function katanaHasDrawioHtmlTableEntry(entry) {
return [
entry.id,
katanaDrawioStyleValue(entry.style, "html") === "1",
katanaDrawioStyleValue(entry.style, "overflow") === "fill",
entry.html.trim().toLowerCase().startsWith("<table"),
].every(Boolean);
}
function katanaNormalizeDrawioHtmlTable(svg, entry) {
[katanaDrawioHtmlTableContext(svg, entry)]
.filter(katanaHasDrawioHtmlTableContext)
.forEach(katanaApplyDrawioHtmlTable);
}
function katanaDrawioHtmlTableContext(svg, entry) {
const group = katanaDrawioCellGroup(svg, entry.id);
return {
entry,
group,
box: katanaDrawioHtmlTableShapeBox(group),
foreignObject: katanaDrawioHtmlTableForeignObject(group),
};
}
function katanaDrawioHtmlTableShapeBox(group) {
return [group].filter(Boolean).map(katanaDrawioCellShapeBox).concat([null])[0];
}
function katanaDrawioHtmlTableForeignObject(group) {
return [group]
.filter(Boolean)
.map((it) => it.querySelector("foreignObject"))
.concat([null])[0];
}
function katanaHasDrawioHtmlTableContext(context) {
return [context.group, context.box, context.foreignObject].every(Boolean);
}
function katanaApplyDrawioHtmlTable(context) {
const foreignObject = context.foreignObject;
foreignObject.setAttribute("style", "overflow: visible; text-align: left;");
foreignObject.setAttribute("pointer-events", "none");
foreignObject.setAttribute("width", "101%");
foreignObject.setAttribute("height", "101%");
foreignObject.setAttribute(
"requiredFeatures",
"http://www.w3.org/TR/SVG11/feature#Extensibility",
);
katanaReplaceDrawioHtmlTableChildren(foreignObject, context.entry, context.box);
}
function katanaReplaceDrawioHtmlTableChildren(foreignObject, entry, box) {
Array.from(foreignObject.childNodes).forEach((child) => {
child.remove();
});
foreignObject.appendChild(katanaCreateDrawioHtmlTableOuterDiv(entry, box));
}
function katanaCreateDrawioHtmlTableOuterDiv(entry, box) {
const div = katanaCreateDrawioHtmlElement("div");
div.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
div.setAttribute("style", katanaDrawioHtmlTableOuterStyle(box));
div.appendChild(katanaCreateDrawioHtmlTableBoxDiv(entry, box));
return div;
}
function katanaCreateDrawioHtmlTableBoxDiv(entry, box) {
const div = katanaCreateDrawioHtmlElement("div");
div.setAttribute("style", katanaDrawioHtmlTableBoxStyle(entry.style, box));
div.appendChild(katanaCreateDrawioHtmlTableContentDiv(entry, box));
return div;
}
function katanaCreateDrawioHtmlTableContentDiv(entry, box) {
const div = katanaCreateDrawioHtmlElement("div");
div.setAttribute("style", katanaDrawioHtmlTableContentStyle(entry.style, box));
div.innerHTML = katanaDrawioHtmlTableMarkup(entry.html);
return div;
}
function katanaDrawioHtmlTableMarkup(html) {
return katanaDrawioIsDarkMode() ? katanaDrawioDarkHtmlTableMarkup(html) : html;
}
function katanaDrawioDarkHtmlTableMarkup(html) {
return KATANA_DRAWIO_HTML_TABLE_DARK_COLORS.reduce(
(text, entry) => katanaDrawioReplaceHtmlTableColor(text, entry),
html,
).replace(/color:\s*#ffffff/gi, "color: #121212");
}
function katanaDrawioReplaceHtmlTableColor(text, entry) {
return text.replace(new RegExp(katanaDrawioEscapeRegExp(entry[0]), "gi"), entry[1]);
}
function katanaDrawioEscapeRegExp(value) {
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function katanaDrawioHtmlTableOuterStyle(box) {
return [
"display: flex",
"align-items: unsafe flex-start",
"justify-content: unsafe flex-start",
`width: ${Math.round(box.width + 2)}px`,
`height: ${Math.round(box.height)}px`,
`padding-top: ${Math.round(box.y)}px`,
`margin-left: ${Math.round(box.x)}px`,
].join("; ");
}
function katanaDrawioHtmlTableBoxStyle(style, box) {
return [
"box-sizing: border-box",
"font-size: 0",
`text-align: ${katanaDrawioTextAlign(style)}`,
`width: ${Math.round(box.width)}px`,
`height: ${Math.round(box.height)}px`,
"overflow: hidden",
`color: ${katanaDrawioTextColor(style)}`,
"",
].join("; ");
}
function katanaDrawioHtmlTableContentStyle(style, _box) {
return [
"display: inline-block",
`font-size: ${katanaDrawioFontSize(style)}px`,
`font-family: ${katanaDrawioHtmlFontFamily(style)}`,
`color: ${katanaDrawioHtmlTextColor(style)}`,
"line-height: 1.2",
"pointer-events: all",
"width: 100%",
"height: 100%",
"white-space: nowrap",
"",
].join("; ");
}
const KATANA_DRAWIO_HTML_TABLE_DARK_COLORS = [
["#98bf21", "#4a6b00"],
["#a7c942", "#405e00"],
["#eaf2d3", "#1d2409"],
];
const KATANA_DRAWIO_TEXT_BASELINE_OFFSET = 0;
function katanaNormalizeDrawioTextBaselines(svg) {
Array.from(svg.querySelectorAll("text")).forEach(katanaNormalizeDrawioTextBaseline);
}
function katanaNormalizeDrawioTextBaseline(text) {
katanaNormalizeDrawioEncodedLineBreaks(text);
const y = Number(text.getAttribute("y"));
if (Number.isFinite(y)) {
text.setAttribute("y", String(y - KATANA_DRAWIO_TEXT_BASELINE_OFFSET));
}
}
function katanaNormalizeDrawioEncodedLineBreaks(text) {
const lines = decodeHtmlEntities(text.textContent).split(/\n+/).filter(Boolean);
if (lines.length < 2) {
return;
}
text.replaceChildren(
...lines.map((line, index) => katanaDrawioLineBreakTspan(text, line, index)),
);
}
function katanaDrawioLineBreakTspan(text, line, index) {
const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
tspan.setAttribute("x", text.getAttribute("x"));
tspan.setAttribute("dy", katanaDrawioTextLineDy(index, katanaDrawioTextFontSize(text)));
tspan.textContent = line;
return tspan;
}
function katanaDrawioTextFontSize(text) {
return Number.parseFloat(text.getAttribute("font-size")) || 12;
}
const KATANA_DRAWIO_XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
function katanaNormalizeDrawioForeignObjects(svg) {
Array.from(svg.querySelectorAll("foreignObject")).forEach(katanaNormalizeDrawioForeignObject);
}
function katanaNormalizeDrawioForeignObject(foreignObject) {
foreignObject.remove();
}
function katanaApplyDrawioXhtmlNamespace(node) {
if (node.nodeType !== Node.ELEMENT_NODE) {
return;
}
node.setAttribute("xmlns", KATANA_DRAWIO_XHTML_NAMESPACE);
Array.from(node.children).forEach(katanaApplyDrawioXhtmlNamespace);
}
function katanaNormalizeDrawioGeometry(svg) {
if (!katanaDrawioRequestSource().includes("mxgraph.aws")) {
return;
}
Array.from(svg.querySelectorAll("g"))
.filter(katanaDrawioIsCellContentGroup)
.filter(katanaDrawioNeedsHalfPixelTranslate)
.forEach(katanaApplyDrawioHalfPixelTranslate);
}
function katanaDrawioIsCellContentGroup(group) {
return group.parentNode?.getAttribute?.("data-cell-id");
}
function katanaDrawioNeedsHalfPixelTranslate(group) {
return [!group.getAttribute("transform"), katanaDrawioGroupHasDirectShape(group)].every(Boolean);
}
function katanaDrawioGroupHasDirectShape(group) {
return Array.from(group.children).some((child) =>
KATANA_DRAWIO_HALF_PIXEL_SHAPE_TAGS.has(child.localName),
);
}
function katanaApplyDrawioHalfPixelTranslate(group) {
group.setAttribute("transform", "translate(0.5,0.5)");
}
const KATANA_DRAWIO_HALF_PIXEL_SHAPE_TAGS = new Set([
"circle",
"ellipse",
"line",
"path",
"polygon",
"polyline",
"rect",
]);
function katanaPostprocessDrawioSvg(svg) {
katanaRemoveOversizedDrawioLabelBackgrounds(svg);
katanaFillMissingDrawioTextLabels(svg);
katanaNormalizeWrappedDrawioTextLabels(svg);
katanaInstallDrawioHtmlTextLabels(svg);
katanaNormalizeDrawioHtmlTables(svg);
katanaNormalizeRichDrawioTextLabels(svg);
katanaNormalizeDrawioTextBaselines(svg);
katanaNormalizeDrawioForeignObjects(svg);
katanaNormalizeDrawioGeometry(svg);
if (!katanaDrawioRequestSource().includes("mxgraph.aws")) {
katanaCropDrawioSvgToContent(svg);
}
katanaApplyDrawioShadows(svg);
katanaNormalizeDrawioSvgColors(svg);
katanaInstallDrawioPageBackground(svg);
}
function katanaInstallDrawioPageBackground(svg) {
const box = katanaDrawioSvgBox(svg);
const color = katanaDrawioPageBackgroundColor(svg);
if (!color) {
return;
}
const rect = katanaCreateDrawioBackgroundRect(box, color);
katanaSetDrawioPageBackgroundStyle(svg, color);
svg.insertBefore(rect, svg.firstChild);
}
function katanaDrawioPageBackgroundColor(svg) {
return [
katanaDrawioStyleBackground(svg.getAttribute("style")),
katanaDrawioRequestBackground(),
].filter(katanaIsVisibleDrawioBackground)[0];
}
function katanaDrawioRequestBackground() {
return globalThis.__katanaDrawioRequest?.background ?? "";
}
function katanaDrawioStyleBackground(style) {
const match = String(style).match(/background(?:-color)?:\s*([^;]+)/);
return [match].filter(Boolean).map(katanaDrawioMatchValue).concat([""])[0];
}
function katanaDrawioMatchValue(match) {
return match[1].trim();
}
function katanaIsVisibleDrawioBackground(color) {
return !["", "transparent"].includes(String(color).toLowerCase());
}
function katanaSetDrawioPageBackgroundStyle(svg, color) {
svg.setAttribute("style", `background: ${color}; background-color: ${color};`);
}
function katanaCreateDrawioBackgroundRect(box, color) {
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("data-katana-drawio-background", "true");
rect.setAttribute("x", box.x);
rect.setAttribute("y", box.y);
rect.setAttribute("width", box.width);
rect.setAttribute("height", box.height);
rect.setAttribute("fill", color);
return rect;
}
function katanaDrawioSvgBox(svg) {
return katanaParsedDrawioViewBox(svg.getAttribute("viewBox")) ?? katanaDrawioSizeBox(svg);
}
function katanaParsedDrawioViewBox(value) {
const parts = String(value).trim().split(/\s+/).map(Number);
return [parts].filter(katanaIsDrawioBoxParts).map(katanaDrawioBoxFromParts).concat([null])[0];
}
function katanaIsDrawioBoxParts(parts) {
return [parts.length === 4, parts.every(Number.isFinite)].every(Boolean);
}
function katanaDrawioBoxFromParts(parts) {
return { x: parts[0], y: parts[1], width: parts[2], height: parts[3] };
}
function katanaDrawioSizeBox(svg) {
return {
x: 0,
y: 0,
width: katanaDrawioCssPixels(svg.getAttribute("width")),
height: katanaDrawioCssPixels(svg.getAttribute("height")),
};
}
function katanaDrawioCssPixels(value) {
const pixels = Number(String(value).replace(/px$/, ""));
return [pixels].filter(Number.isFinite).concat([0])[0];
}
function katanaRenderDrawioSvg() {
const request = katanaDrawioRenderRequest();
const container = katanaCreateDrawioViewerContainer(request.source);
const viewer = katanaCreateDrawioViewer(container);
return katanaViewerSvgMarkup(viewer);
}
function katanaDrawioRenderRequest() {
const request = globalThis.__katanaDrawioRequest;
katanaAssertDrawioRequest(request);
katanaAssertDrawioViewerRuntime();
return request;
}
function katanaAssertDrawioRequest(request) {
if (!request?.source) {
throw new Error("Draw.io render request is missing");
}
}
function katanaAssertDrawioViewerRuntime() {
if (typeof GraphViewer !== "function") {
throw new Error("Draw.io viewer runtime is not initialized");
}
}
function katanaCreateDrawioViewerContainer(source) {
const container = document.createElement("div");
container.setAttribute("id", "graph-container");
container.setAttribute("class", "mxgraph");
container.setAttribute("data-mxgraph", JSON.stringify(katanaDrawioViewerConfig(source)));
document.body.appendChild(container);
return container;
}
function katanaDrawioViewerConfig(source) {
return {
xml: katanaDrawioSourceForViewer(source),
toolbar: "",
"auto-fit": false,
"auto-crop": false,
"auto-origin": true,
"check-visible-state": false,
};
}
function katanaDrawioSourceForViewer(source) {
const xml = String(source)
.trim()
.replace(/^<\?xml[^>]*>\s*/i, "");
return katanaDrawioUncompressedModel(xml) ?? xml;
}
function katanaDrawioUncompressedModel(xml) {
const start = xml.indexOf("<mxGraphModel");
const end = xml.indexOf("</mxGraphModel>");
if (katanaHasDrawioModelRange(start, end)) {
return xml.slice(start, end + "</mxGraphModel>".length);
}
return null;
}
function katanaHasDrawioModelRange(start, end) {
return [start >= 0, end >= start].every(Boolean);
}
function katanaCreateDrawioViewer(container) {
const state = { viewer: null };
GraphViewer.createViewerForElement(container, (viewer) => {
state.viewer = viewer;
});
return katanaRequiredDrawioViewer(state, container);
}
function katanaRequiredDrawioViewer(state, container) {
if (state.viewer?.graph) {
return state.viewer;
}
throw new Error(katanaDrawioViewerError(container));
}
function katanaDrawioViewerError(container) {
const message = container.innerText || "Draw.io viewer did not produce SVG";
return `Draw.io viewer failed: ${message}`;
}
function katanaViewerSvgMarkup(viewer) {
const svg = viewer.graph.getSvg();
katanaConfigureDrawioSvg(svg);
katanaPostprocessDrawioSvg(svg);
return new XMLSerializer().serializeToString(svg);
}
function katanaConfigureDrawioSvg(svg) {
svg.setAttribute("role", "img");
svg.setAttribute("aria-roledescription", "drawio");
}
function katanaRunDrawioRuntime() {
katanaInstallDrawioRuntimeAdapter();
return katanaRenderDrawioSvg();
}