UNPKG

@threepipe/plugin-tweakpane

Version:

Tweakpane UI Plugin for ThreePipe

1,553 lines (1,552 loc) 282 kB
/** * @license * @threepipe/plugin-tweakpane v0.6.0 * Copyright 2022-2025 repalash <palash@shaders.app> * Apache-2.0 License * See ./dependencies.txt for any bundled third-party dependencies and licenses. */ import { makeTextSvg, getOrCall, generateUUID, CustomContextMenu, SVGTextureLoader, Texture, upgradeTexture, imageBitmapToBase64, textureToDataUrl, HalfFloatType, FloatType, EXRExporter2, LinearSRGBColorSpace, SRGBColorSpace, RepeatWrapping, onChange, uiDropdown, uiFolderContainer, Vector2, Vector3, Vector4, Color, createStyles, WebGLRenderTarget, WebGLCubeRenderTarget, WebGLMultipleRenderTargets, mobileAndTabletCheck, UndoManagerPlugin, createDiv, downloadBlob, uploadFile } from "threepipe"; function forceCast(v) { return v; } const PREFIX = "tp"; function ClassName(viewName) { const fn = (opt_elementName, opt_modifier) => { return [ PREFIX, "-", viewName, "v", opt_elementName ? `_${opt_elementName}` : "", opt_modifier ? `-${opt_modifier}` : "" ].join(""); }; return fn; } function parseObject(value, keyToParserMap) { const keys = Object.keys(keyToParserMap); const result = keys.reduce((tmp, key) => { if (tmp === void 0) { return void 0; } const parser = keyToParserMap[key]; const result2 = parser(value[key]); return result2.succeeded ? Object.assign(Object.assign({}, tmp), { [key]: result2.value }) : void 0; }, {}); return forceCast(result); } function parseArray(value, parseItem) { return value.reduce((tmp, item) => { if (tmp === void 0) { return void 0; } const result = parseItem(item); if (!result.succeeded || result.value === void 0) { return void 0; } return [...tmp, result.value]; }, []); } function isObject(value) { if (value === null) { return false; } return typeof value === "object"; } function createParamsParserBuilder(parse) { return (optional) => (v) => { if (!optional && v === void 0) { return { succeeded: false, value: void 0 }; } if (optional && v === void 0) { return { succeeded: true, value: void 0 }; } const result = parse(v); return result !== void 0 ? { succeeded: true, value: result } : { succeeded: false, value: void 0 }; }; } function createParamsParserBuilders(optional) { return { custom: (parse) => createParamsParserBuilder(parse)(optional), boolean: createParamsParserBuilder((v) => typeof v === "boolean" ? v : void 0)(optional), number: createParamsParserBuilder((v) => typeof v === "number" ? v : void 0)(optional), string: createParamsParserBuilder((v) => typeof v === "string" ? v : void 0)(optional), function: createParamsParserBuilder((v) => typeof v === "function" ? v : void 0)(optional), constant: (value) => createParamsParserBuilder((v) => v === value ? value : void 0)(optional), raw: createParamsParserBuilder((v) => v)(optional), object: (keyToParserMap) => createParamsParserBuilder((v) => { if (!isObject(v)) { return void 0; } return parseObject(v, keyToParserMap); })(optional), array: (itemParser) => createParamsParserBuilder((v) => { if (!Array.isArray(v)) { return void 0; } return parseArray(v, itemParser); })(optional) }; } const ParamsParsers = { optional: createParamsParserBuilders(true), required: createParamsParserBuilders(false) }; function parseParams(value, keyToParserMap) { const result = ParamsParsers.required.object(keyToParserMap)(value); return result.succeeded ? result.value : void 0; } function createNumberFormatter(digits) { return (value) => { return value.toFixed(Math.max(Math.min(digits, 20), 0)); }; } const innerFormatter = createNumberFormatter(0); function formatPercentage(value) { return innerFormatter(value) + "%"; } function constrainRange(value, min, max) { return Math.min(Math.max(value, min), max); } function removeAlphaComponent(comps) { return [comps[0], comps[1], comps[2]]; } function zerofill(comp) { const hex = constrainRange(Math.floor(comp), 0, 255).toString(16); return hex.length === 1 ? `0${hex}` : hex; } function colorToHexRgbString(value, prefix = "#") { const hexes = removeAlphaComponent(value.getComponents("rgb")).map(zerofill).join(""); return `${prefix}${hexes}`; } function colorToHexRgbaString(value, prefix = "#") { const rgbaComps = value.getComponents("rgb"); const hexes = [rgbaComps[0], rgbaComps[1], rgbaComps[2], rgbaComps[3] * 255].map(zerofill).join(""); return `${prefix}${hexes}`; } function colorToFunctionalRgbString(value, opt_type) { const formatter = createNumberFormatter(opt_type === "float" ? 2 : 0); const comps = removeAlphaComponent(value.getComponents("rgb", opt_type)).map((comp) => formatter(comp)); return `rgb(${comps.join(", ")})`; } function createFunctionalRgbColorFormatter(type) { return (value) => { return colorToFunctionalRgbString(value, type); }; } function colorToFunctionalRgbaString(value, opt_type) { const aFormatter = createNumberFormatter(2); const rgbFormatter = createNumberFormatter(opt_type === "float" ? 2 : 0); const comps = value.getComponents("rgb", opt_type).map((comp, index) => { const formatter = index === 3 ? aFormatter : rgbFormatter; return formatter(comp); }); return `rgba(${comps.join(", ")})`; } function createFunctionalRgbaColorFormatter(type) { return (value) => { return colorToFunctionalRgbaString(value, type); }; } function colorToFunctionalHslString(value) { const formatters = [ createNumberFormatter(0), formatPercentage, formatPercentage ]; const comps = removeAlphaComponent(value.getComponents("hsl")).map((comp, index) => formatters[index](comp)); return `hsl(${comps.join(", ")})`; } function colorToFunctionalHslaString(value) { const formatters = [ createNumberFormatter(0), formatPercentage, formatPercentage, createNumberFormatter(2) ]; const comps = value.getComponents("hsl").map((comp, index) => formatters[index](comp)); return `hsla(${comps.join(", ")})`; } function colorToObjectRgbString(value, type) { const formatter = createNumberFormatter(type === "float" ? 2 : 0); const names = ["r", "g", "b"]; const comps = removeAlphaComponent(value.getComponents("rgb", type)).map((comp, index) => `${names[index]}: ${formatter(comp)}`); return `{${comps.join(", ")}}`; } function createObjectRgbColorFormatter(type) { return (value) => colorToObjectRgbString(value, type); } function colorToObjectRgbaString(value, type) { const aFormatter = createNumberFormatter(2); const rgbFormatter = createNumberFormatter(type === "float" ? 2 : 0); const names = ["r", "g", "b", "a"]; const comps = value.getComponents("rgb", type).map((comp, index) => { const formatter = index === 3 ? aFormatter : rgbFormatter; return `${names[index]}: ${formatter(comp)}`; }); return `{${comps.join(", ")}}`; } function createObjectRgbaColorFormatter(type) { return (value) => colorToObjectRgbaString(value, type); } [ { format: { alpha: false, mode: "rgb", notation: "hex", type: "int" }, stringifier: colorToHexRgbString }, { format: { alpha: true, mode: "rgb", notation: "hex", type: "int" }, stringifier: colorToHexRgbaString }, { format: { alpha: false, mode: "hsl", notation: "func", type: "int" }, stringifier: colorToFunctionalHslString }, { format: { alpha: true, mode: "hsl", notation: "func", type: "int" }, stringifier: colorToFunctionalHslaString }, ...["int", "float"].reduce((prev, type) => { return [ ...prev, { format: { alpha: false, mode: "rgb", notation: "func", type }, stringifier: createFunctionalRgbColorFormatter(type) }, { format: { alpha: true, mode: "rgb", notation: "func", type }, stringifier: createFunctionalRgbaColorFormatter(type) }, { format: { alpha: false, mode: "rgb", notation: "object", type }, stringifier: createObjectRgbColorFormatter(type) }, { format: { alpha: true, mode: "rgb", notation: "object", type }, stringifier: createObjectRgbaColorFormatter(type) } ]; }, []) ]; function createPlaceholderImage() { const canvas = document.createElement("canvas"); canvas.width = 320; canvas.height = 50; const ctx = canvas.getContext("2d"); ctx.fillStyle = "#00000004"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "#eee"; ctx.font = '1.25rem "Roboto Mono", "Source Code Pro", Menlo, Courier, monospace'; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText("No image", canvas.width * 0.5, canvas.height * 0.5); const image = new Image(); image.src = canvas.toDataURL("image/png", 0.8); image.isPlaceholder = true; return image; } function loadImage(src) { const image = new Image(); image.crossOrigin = "anonymous"; image.src = src; return image; } const className = ClassName("img"); class PluginView { constructor(doc, config) { this.element = doc.createElement("div"); this.element.classList.add(className()); config.viewProps.bindClassModifiers(this.element); this.input = doc.createElement("input"); this.input.classList.add(className("input")); this.input.setAttribute("type", "file"); this.input.setAttribute("accept", config.extensions.join(",")); this.image_ = doc.createElement("img"); this.image_.id = "tpimg_" + Math.random().toString(36).slice(2); this.image_.classList.add(className("image")); this.image_.classList.add(className(`image_${config.imageFit}`)); this.image_.crossOrigin = "anonymous"; this.image_.onclick = (event) => { config.clickCallback ? config.clickCallback(event, this.input) : this.input.click(); }; this.element.classList.add(className("area_root")); this.element.appendChild(this.image_); this.element.appendChild(this.input); } changeImage(src) { this.image_.src = src; } changeDraggingState(state) { const el = this.element; if (state) { el === null || el === void 0 ? void 0 : el.classList.add(className("area_dragging")); } else { el === null || el === void 0 ? void 0 : el.classList.remove(className("area_dragging")); } } } let placeholderImage = null; class PluginController { constructor(doc, config) { this.value = config.value; this.viewProps = config.viewProps; this.view = new PluginView(doc, { viewProps: this.viewProps, extensions: config.extensions, imageFit: config.imageFit, clickCallback: config.clickCallback }); this.onFile = this.onFile.bind(this); this.onDrop = this.onDrop.bind(this); this.onDragStart = this.onDragStart.bind(this); this.onDragOver = this.onDragOver.bind(this); this.onDragLeave = this.onDragLeave.bind(this); this.view.input.addEventListener("change", this.onFile); this.view.element.addEventListener("drop", this.onDrop); this.view.element.addEventListener("dragstart", this.onDragStart); this.view.element.addEventListener("dragover", this.onDragOver); this.view.element.addEventListener("dragleave", this.onDragLeave); this.viewProps.handleDispose(() => { this.view.input.removeEventListener("change", this.onFile); this.view.element.removeEventListener("drop", this.onDrop); this.view.element.removeEventListener("dragstart", this.onDragStart); this.view.element.removeEventListener("dragover", this.onDragOver); this.view.element.removeEventListener("dragleave", this.onDragLeave); }); this.value.emitter.on("change", () => this.handleValueChange()); this.handleValueChange(); } onFile(event) { const files = (event === null || event === void 0 ? void 0 : event.target).files; if (!files || !files.length) return; const file = files[0]; this.setValue(file); } onDrop(event) { event.preventDefault(); try { const { dataTransfer } = event; const file = dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.files[0]; if (file) { this.setValue(file); } else { const imgId = dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.getData("img-id"); if (imgId) { const img = document.getElementById(imgId); this.setValue(img); } else { const url = dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.getData("url"); if (!url) throw new Error("No url"); this.setValue(url); } } } catch (e) { console.error("Could not parse the dropped image", e); } finally { this.view.changeDraggingState(false); } } onDragStart(event) { var _a2, _b; (_a2 = event.dataTransfer) === null || _a2 === void 0 ? void 0 : _a2.setData("img-id", this.view.image_.id); (_b = event.dataTransfer) === null || _b === void 0 ? void 0 : _b.setDragImage(this.view.image_, 0, 0); } onDragOver(event) { event.preventDefault(); this.view.changeDraggingState(true); } onDragLeave() { this.view.changeDraggingState(false); } handleImage(image) { if (image instanceof HTMLImageElement) { this.updateImage(image.src); } else if (typeof image === "string" || !image) { if (image === "placeholder" || !image) { image = this.handlePlaceholderImage().src; } this.updateImage(image); } else { this.setValue(image); } } updateImage(src) { this.view.changeImage(src); } setValue(src) { if (src instanceof HTMLImageElement) { this.value.setRawValue(src); } else if (src instanceof File) { const url = URL.createObjectURL(src) + "#" + src.name; src.src = url; const img = loadImage(url); this.value.setRawValue(img || src); } else if (src) { this.value.setRawValue(loadImage(src)); } else { this.value.setRawValue(this.handlePlaceholderImage()); } } handleValueChange() { this.handleImage(this.value.rawValue); } handlePlaceholderImage() { if (!placeholderImage) { placeholderImage = createPlaceholderImage(); } return placeholderImage; } } const DEFAULT_EXTENSIONS = [".jpg", ".png", ".gif"]; const TweakpaneImagePlugin = { id: "input-image", type: "input", css: ".tp-imgv{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:rgba(0,0,0,0);border-width:0;font-family:inherit;font-size:inherit;font-weight:inherit;margin:0;outline:none;padding:0}.tp-imgv{background-color:var(--in-bg);border-radius:var(--elm-br);box-sizing:border-box;color:var(--in-fg);font-family:inherit;height:var(--bld-us);line-height:var(--bld-us);min-width:0;width:100%}.tp-imgv:hover{background-color:var(--in-bg-h)}.tp-imgv:focus{background-color:var(--in-bg-f)}.tp-imgv:active{background-color:var(--in-bg-a)}.tp-imgv:disabled{opacity:.5}:root{--tp-plugin-image-dragging-color: hsla(230, 100%, 66%, 1.00)}.tp-imgv{cursor:pointer;display:inline-flex;height:auto !important;max-height:calc(var(--bld-us)*3);border-radius:4px;position:relative}.tp-imgv.tp-v-disabled{opacity:.5}.tp-imgv_input{width:0;height:0;pointer-events:none;visibility:hidden}.tp-imgv_image{width:100%;height:-moz-max-content;height:max-content;max-height:calc(var(--bld-us)*3);border:0}.tp-imgv_image_contain{-o-object-fit:contain;object-fit:contain}.tp-imgv_image_cover{-o-object-fit:cover;object-fit:cover}.tp-imgv_area_root{transition:opacity .16s ease-in-out}.tp-imgv_area_dragging{border:2px dashed var(--tp-plugin-image-dragging-color);border-radius:4px;opacity:.6}", accept(exValue, params) { if (!(exValue instanceof HTMLImageElement || typeof exValue === "string")) { return null; } const p = ParamsParsers; const result = parseParams(params, { view: p.required.constant("input-image"), acceptUrl: p.optional.boolean, clickCallback: p.optional.function, imageFit: p.optional.custom((v) => v === "contain" || v === "cover" ? v : void 0), extensions: p.optional.array(p.required.string) }); if (!result) { return null; } return { initialValue: exValue, params: result }; }, binding: { reader(_args) { return (exValue) => { if (exValue.src !== void 0) { return exValue.src === "" ? "placeholder" : exValue.src; } else { return typeof exValue === "string" ? exValue : exValue; } }; }, writer(_args) { return (target, inValue) => { target.write(inValue); }; } }, controller(args) { var _a2, _b; return new PluginController(args.document, { value: args.value, imageFit: (_a2 = args.params.imageFit) !== null && _a2 !== void 0 ? _a2 : "cover", clickCallback: args.params.clickCallback, viewProps: args.viewProps, extensions: (_b = args.params.extensions) !== null && _b !== void 0 ? _b : DEFAULT_EXTENSIONS }); } }; const plugin = TweakpaneImagePlugin; const TweakpaneImagePlugin$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, plugin }, Symbol.toStringTag, { value: "Module" })); /** * @license * uiconfig-tweakpane v0.0.10 * Copyright 2022-2024 repalash <palash@shaders.app> * MIT License * See ./dependencies.txt for bundled third-party dependencies and licenses. */ /** * @license * ts-browser-helpers v0.16.0 * Copyright 2022-2024 repalash <palash@shaders.app> * MIT License * See ./dependencies.txt for bundled third-party dependencies and licenses. */ function ua({ innerHTML: u = "", id: s, classList: o, addToBody: p = true, elementTag: l = "div" }) { const c = document.createElement(l); return c.id = s, c.innerHTML = u, o && c.classList.add(...o), p && document.body.appendChild(c), c; } function ca(u, s = document.head) { const o = document.createElement("style"); return o.type = "text/css", o.innerText = u, s == null || s.appendChild(o), o; } const ha = (u, ...s) => String.raw({ raw: u }, ...s); function va(u, s) { let o; do o = Object.getOwnPropertyDescriptor(u, s); while (!o && (u = Object.getPrototypeOf(u))); return o; } function ma(u, s, o = true, p = false) { const l = va(u, s); return !!(l != null && l.set) || o && (l == null ? void 0 : l.writable) !== false && (l == null ? void 0 : l.get) === void 0 || p && !l; } function ba(u, s, o, p = true, l = false) { return u && ma(u, s, p, l) ? (u[s] = o, true) : false; } function $(u, ...s) { return typeof u == "function" && (u = u(...s)), u; } function fa(u, s) { return Object.hasOwn ? Object.hasOwn(u, s) : u.hasOwnProperty(s); } var _a = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, Xe = { exports: {} }; /*! Tweakpane 3.1.10 (c) 2016 cocopon, licensed under the MIT license. */ (function(u, s) { (function(o, p) { p(s); })(_a, function(o) { class p { /** * @hidden */ constructor(t) { const [e, i] = t.split("-"), r = e.split("."); this.major = parseInt(r[0], 10), this.minor = parseInt(r[1], 10), this.patch = parseInt(r[2], 10), this.prerelease = i ?? null; } toString() { const t = [this.major, this.minor, this.patch].join("."); return this.prerelease !== null ? [t, this.prerelease].join("-") : t; } } class l { constructor(t) { this.controller_ = t; } get element() { return this.controller_.view.element; } get disabled() { return this.controller_.viewProps.get("disabled"); } set disabled(t) { this.controller_.viewProps.set("disabled", t); } get hidden() { return this.controller_.viewProps.get("hidden"); } set hidden(t) { this.controller_.viewProps.set("hidden", t); } dispose() { this.controller_.viewProps.set("disposed", true); } } class c { constructor(t) { this.target = t; } } class v extends c { constructor(t, e, i, r) { super(t), this.value = e, this.presetKey = i, this.last = r ?? true; } } class w extends c { constructor(t, e, i) { super(t), this.value = e, this.presetKey = i; } } class b extends c { constructor(t, e) { super(t), this.expanded = e; } } class S extends c { constructor(t, e) { super(t), this.index = e; } } function g(n) { return n == null; } function P(n, t) { if (n.length !== t.length) return false; for (let e = 0; e < n.length; e++) if (n[e] !== t[e]) return false; return true; } function y(n, t) { let e = n; do { const i = Object.getOwnPropertyDescriptor(e, t); if (i && (i.set !== void 0 || i.writable === true)) return true; e = Object.getPrototypeOf(e); } while (e !== null); return false; } const A = { alreadydisposed: () => "View has been already disposed", invalidparams: (n) => `Invalid parameters for '${n.name}'`, nomatchingcontroller: (n) => `No matching controller for '${n.key}'`, nomatchingview: (n) => `No matching view for '${JSON.stringify(n.params)}'`, notbindable: () => "Value is not bindable", propertynotfound: (n) => `Property '${n.name}' not found`, shouldneverhappen: () => "This error should never happen" }; class _ { static alreadyDisposed() { return new _({ type: "alreadydisposed" }); } static notBindable() { return new _({ type: "notbindable" }); } static propertyNotFound(t) { return new _({ type: "propertynotfound", context: { name: t } }); } static shouldNeverHappen() { return new _({ type: "shouldneverhappen" }); } constructor(t) { var e; this.message = (e = A[t.type](t.context)) !== null && e !== void 0 ? e : "Unexpected error", this.name = this.constructor.name, this.stack = new Error(this.message).stack, this.type = t.type; } } class L { constructor(t, e, i) { this.obj_ = t, this.key_ = e, this.presetKey_ = i ?? e; } static isBindable(t) { return !(t === null || typeof t != "object" && typeof t != "function"); } get key() { return this.key_; } get presetKey() { return this.presetKey_; } read() { return this.obj_[this.key_]; } write(t) { this.obj_[this.key_] = t; } writeProperty(t, e) { const i = this.read(); if (!L.isBindable(i)) throw _.notBindable(); if (!(t in i)) throw _.propertyNotFound(t); i[t] = e; } } class et extends l { get label() { return this.controller_.props.get("label"); } set label(t) { this.controller_.props.set("label", t); } get title() { var t; return (t = this.controller_.valueController.props.get("title")) !== null && t !== void 0 ? t : ""; } set title(t) { this.controller_.valueController.props.set("title", t); } on(t, e) { const i = e.bind(this); return this.controller_.valueController.emitter.on(t, () => { i(new c(this)); }), this; } } class M { constructor() { this.observers_ = {}; } on(t, e) { let i = this.observers_[t]; return i || (i = this.observers_[t] = []), i.push({ handler: e }), this; } off(t, e) { const i = this.observers_[t]; return i && (this.observers_[t] = i.filter((r) => r.handler !== e)), this; } emit(t, e) { const i = this.observers_[t]; i && i.forEach((r) => { r.handler(e); }); } } const Qt = "tp"; function E(n) { return (e, i) => [ Qt, "-", n, "v", e ? `_${e}` : "", i ? `-${i}` : "" ].join(""); } function ki(n, t) { return (e) => t(n(e)); } function Vi(n) { return n.rawValue; } function Y(n, t) { n.emitter.on("change", ki(Vi, t)), t(n.rawValue); } function H(n, t, e) { Y(n.value(t), e); } function Si(n, t, e) { e ? n.classList.add(t) : n.classList.remove(t); } function ft(n, t) { return (e) => { Si(n, t, e); }; } function ce(n, t) { Y(n, (e) => { t.textContent = e ?? ""; }); } const he = E("btn"); class Li { constructor(t, e) { this.element = t.createElement("div"), this.element.classList.add(he()), e.viewProps.bindClassModifiers(this.element); const i = t.createElement("button"); i.classList.add(he("b")), e.viewProps.bindDisabled(i), this.element.appendChild(i), this.buttonElement = i; const r = t.createElement("div"); r.classList.add(he("t")), ce(e.props.value("title"), r), this.buttonElement.appendChild(r); } } class Ze { constructor(t, e) { this.emitter = new M(), this.onClick_ = this.onClick_.bind(this), this.props = e.props, this.viewProps = e.viewProps, this.view = new Li(t, { props: this.props, viewProps: this.viewProps }), this.view.buttonElement.addEventListener("click", this.onClick_); } onClick_() { this.emitter.emit("click", { sender: this }); } } class Ai { constructor(t, e) { var i; this.constraint_ = e == null ? void 0 : e.constraint, this.equals_ = (i = e == null ? void 0 : e.equals) !== null && i !== void 0 ? i : (r, a) => r === a, this.emitter = new M(), this.rawValue_ = t; } get constraint() { return this.constraint_; } get rawValue() { return this.rawValue_; } set rawValue(t) { this.setRawValue(t, { forceEmit: false, last: true }); } setRawValue(t, e) { const i = e ?? { forceEmit: false, last: true }, r = this.constraint_ ? this.constraint_.constrain(t) : t, a = this.rawValue_; this.equals_(a, r) && !i.forceEmit || (this.emitter.emit("beforechange", { sender: this }), this.rawValue_ = r, this.emitter.emit("change", { options: i, previousRawValue: a, rawValue: r, sender: this })); } } class Mi { constructor(t) { this.emitter = new M(), this.value_ = t; } get rawValue() { return this.value_; } set rawValue(t) { this.setRawValue(t, { forceEmit: false, last: true }); } setRawValue(t, e) { const i = e ?? { forceEmit: false, last: true }, r = this.value_; r === t && !i.forceEmit || (this.emitter.emit("beforechange", { sender: this }), this.value_ = t, this.emitter.emit("change", { options: i, previousRawValue: r, rawValue: this.value_, sender: this })); } } function N(n, t) { const e = t == null ? void 0 : t.constraint, i = t == null ? void 0 : t.equals; return !e && !i ? new Mi(n) : new Ai(n, t); } class C { constructor(t) { this.emitter = new M(), this.valMap_ = t; for (const e in this.valMap_) this.valMap_[e].emitter.on("change", () => { this.emitter.emit("change", { key: e, sender: this }); }); } static createCore(t) { return Object.keys(t).reduce((i, r) => Object.assign(i, { [r]: N(t[r]) }), {}); } static fromObject(t) { const e = this.createCore(t); return new C(e); } get(t) { return this.valMap_[t].rawValue; } set(t, e) { this.valMap_[t].rawValue = e; } value(t) { return this.valMap_[t]; } } function Ri(n, t) { const i = Object.keys(t).reduce((r, a) => { if (r === void 0) return; const d = t[a], h = d(n[a]); return h.succeeded ? Object.assign(Object.assign({}, r), { [a]: h.value }) : void 0; }, {}); return i; } function Di(n, t) { return n.reduce((e, i) => { if (e === void 0) return; const r = t(i); if (!(!r.succeeded || r.value === void 0)) return [...e, r.value]; }, []); } function Oi(n) { return n === null ? false : typeof n == "object"; } function Q(n) { return (t) => (e) => { if (!t && e === void 0) return { succeeded: false, value: void 0 }; if (t && e === void 0) return { succeeded: true, value: void 0 }; const i = n(e); return i !== void 0 ? { succeeded: true, value: i } : { succeeded: false, value: void 0 }; }; } function Je(n) { return { custom: (t) => Q(t)(n), boolean: Q((t) => typeof t == "boolean" ? t : void 0)(n), number: Q((t) => typeof t == "number" ? t : void 0)(n), string: Q((t) => typeof t == "string" ? t : void 0)(n), function: Q((t) => typeof t == "function" ? t : void 0)(n), constant: (t) => Q((e) => e === t ? t : void 0)(n), raw: Q((t) => t)(n), object: (t) => Q((e) => { if (Oi(e)) return Ri(e, t); })(n), array: (t) => Q((e) => { if (Array.isArray(e)) return Di(e, t); })(n) }; } const R = { optional: Je(true), required: Je(false) }; function I(n, t) { const e = R.required.object(t)(n); return e.succeeded ? e.value : void 0; } function ve(n) { console.warn([ `Missing '${n.key}' of ${n.target} in ${n.place}.`, "Please rebuild plugins with the latest core package." ].join(" ")); } function Ti(n) { return n && n.parentElement && n.parentElement.removeChild(n), null; } class me { constructor(t) { this.value_ = t; } static create(t) { return [ new me(t), (e, i) => { t.setRawValue(e, i); } ]; } get emitter() { return this.value_.emitter; } get rawValue() { return this.value_.rawValue; } } const Ni = E(""); function tn(n, t) { return ft(n, Ni(void 0, t)); } class W extends C { constructor(t) { var e; super(t), this.onDisabledChange_ = this.onDisabledChange_.bind(this), this.onParentChange_ = this.onParentChange_.bind(this), this.onParentGlobalDisabledChange_ = this.onParentGlobalDisabledChange_.bind(this), [this.globalDisabled_, this.setGlobalDisabled_] = me.create(N(this.getGlobalDisabled_())), this.value("disabled").emitter.on("change", this.onDisabledChange_), this.value("parent").emitter.on("change", this.onParentChange_), (e = this.get("parent")) === null || e === void 0 || e.globalDisabled.emitter.on("change", this.onParentGlobalDisabledChange_); } static create(t) { var e, i, r; const a = t ?? {}; return new W(C.createCore({ disabled: (e = a.disabled) !== null && e !== void 0 ? e : false, disposed: false, hidden: (i = a.hidden) !== null && i !== void 0 ? i : false, parent: (r = a.parent) !== null && r !== void 0 ? r : null })); } get globalDisabled() { return this.globalDisabled_; } bindClassModifiers(t) { Y(this.globalDisabled_, tn(t, "disabled")), H(this, "hidden", tn(t, "hidden")); } bindDisabled(t) { Y(this.globalDisabled_, (e) => { t.disabled = e; }); } bindTabIndex(t) { Y(this.globalDisabled_, (e) => { t.tabIndex = e ? -1 : 0; }); } handleDispose(t) { this.value("disposed").emitter.on("change", (e) => { e && t(); }); } getGlobalDisabled_() { const t = this.get("parent"); return (t ? t.globalDisabled.rawValue : false) || this.get("disabled"); } updateGlobalDisabled_() { this.setGlobalDisabled_(this.getGlobalDisabled_()); } onDisabledChange_() { this.updateGlobalDisabled_(); } onParentGlobalDisabledChange_() { this.updateGlobalDisabled_(); } onParentChange_(t) { var e; const i = t.previousRawValue; i == null || i.globalDisabled.emitter.off("change", this.onParentGlobalDisabledChange_), (e = this.get("parent")) === null || e === void 0 || e.globalDisabled.emitter.on("change", this.onParentGlobalDisabledChange_), this.updateGlobalDisabled_(); } } function Ii() { return ["veryfirst", "first", "last", "verylast"]; } const en = E(""), nn = { veryfirst: "vfst", first: "fst", last: "lst", verylast: "vlst" }; class Vt { constructor(t) { this.parent_ = null, this.blade = t.blade, this.view = t.view, this.viewProps = t.viewProps; const e = this.view.element; this.blade.value("positions").emitter.on("change", () => { Ii().forEach((i) => { e.classList.remove(en(void 0, nn[i])); }), this.blade.get("positions").forEach((i) => { e.classList.add(en(void 0, nn[i])); }); }), this.viewProps.handleDispose(() => { Ti(e); }); } get parent() { return this.parent_; } set parent(t) { if (this.parent_ = t, !("parent" in this.viewProps.valMap_)) { ve({ key: "parent", target: W.name, place: "BladeController.parent" }); return; } this.viewProps.set("parent", this.parent_ ? this.parent_.viewProps : null); } } const z = "http://www.w3.org/2000/svg"; function Wt(n) { n.offsetHeight; } function Bi(n, t) { const e = n.style.transition; n.style.transition = "none", t(), n.style.transition = e; } function be(n) { return n.ontouchstart !== void 0; } function Ui() { return globalThis; } function ji() { return Ui().document; } function Fi(n) { const t = n.ownerDocument.defaultView; return t && "document" in t ? n.getContext("2d", { willReadFrequently: true }) : null; } const Ki = { check: '<path d="M2 8l4 4l8 -8"/>', dropdown: '<path d="M5 7h6l-3 3 z"/>', p2dpad: '<path d="M8 4v8"/><path d="M4 8h8"/><circle cx="12" cy="12" r="1.2"/>' }; function Xt(n, t) { const e = n.createElementNS(z, "svg"); return e.innerHTML = Ki[t], e; } function rn(n, t, e) { n.insertBefore(t, n.children[e]); } function sn(n) { n.parentElement && n.parentElement.removeChild(n); } function on(n) { for (; n.children.length > 0; ) n.removeChild(n.children[0]); } function $i(n) { for (; n.childNodes.length > 0; ) n.removeChild(n.childNodes[0]); } function an(n) { return n.relatedTarget ? n.relatedTarget : "explicitOriginalTarget" in n ? n.explicitOriginalTarget : null; } const St = E("lbl"); function Hi(n, t) { const e = n.createDocumentFragment(); return t.split(` `).map((r) => n.createTextNode(r)).forEach((r, a) => { a > 0 && e.appendChild(n.createElement("br")), e.appendChild(r); }), e; } class ln { constructor(t, e) { this.element = t.createElement("div"), this.element.classList.add(St()), e.viewProps.bindClassModifiers(this.element); const i = t.createElement("div"); i.classList.add(St("l")), H(e.props, "label", (a) => { g(a) ? this.element.classList.add(St(void 0, "nol")) : (this.element.classList.remove(St(void 0, "nol")), $i(i), i.appendChild(Hi(t, a))); }), this.element.appendChild(i), this.labelElement = i; const r = t.createElement("div"); r.classList.add(St("v")), this.element.appendChild(r), this.valueElement = r; } } class Zt extends Vt { constructor(t, e) { const i = e.valueController.viewProps; super(Object.assign(Object.assign({}, e), { view: new ln(t, { props: e.props, viewProps: i }), viewProps: i })), this.props = e.props, this.valueController = e.valueController, this.view.valueElement.appendChild(this.valueController.view.element); } } const zi = { id: "button", type: "blade", accept(n) { const t = R, e = I(n, { title: t.required.string, view: t.required.constant("button"), label: t.optional.string }); return e ? { params: e } : null; }, controller(n) { return new Zt(n.document, { blade: n.blade, props: C.fromObject({ label: n.params.label }), valueController: new Ze(n.document, { props: C.fromObject({ title: n.params.title }), viewProps: n.viewProps }) }); }, api(n) { return !(n.controller instanceof Zt) || !(n.controller.valueController instanceof Ze) ? null : new et(n.controller); } }; class _t extends Vt { constructor(t) { super(t), this.value = t.value; } } function Lt() { return new C({ positions: N([], { equals: P }) }); } class At extends C { constructor(t) { super(t); } static create(t) { const e = { completed: true, expanded: t, expandedHeight: null, shouldFixHeight: false, temporaryExpanded: null }, i = C.createCore(e); return new At(i); } get styleExpanded() { var t; return (t = this.get("temporaryExpanded")) !== null && t !== void 0 ? t : this.get("expanded"); } get styleHeight() { if (!this.styleExpanded) return "0"; const t = this.get("expandedHeight"); return this.get("shouldFixHeight") && !g(t) ? `${t}px` : "auto"; } bindExpandedClass(t, e) { const i = () => { this.styleExpanded ? t.classList.add(e) : t.classList.remove(e); }; H(this, "expanded", i), H(this, "temporaryExpanded", i); } cleanUpTransition() { this.set("shouldFixHeight", false), this.set("expandedHeight", null), this.set("completed", true); } } function Gi(n, t) { let e = 0; return Bi(t, () => { n.set("expandedHeight", null), n.set("temporaryExpanded", true), Wt(t), e = t.clientHeight, n.set("temporaryExpanded", null), Wt(t); }), e; } function pn(n, t) { t.style.height = n.styleHeight; } function fe(n, t) { n.value("expanded").emitter.on("beforechange", () => { if (n.set("completed", false), g(n.get("expandedHeight"))) { const e = Gi(n, t); e > 0 && n.set("expandedHeight", e); } n.set("shouldFixHeight", true), Wt(t); }), n.emitter.on("change", () => { pn(n, t); }), pn(n, t), t.addEventListener("transitionend", (e) => { e.propertyName === "height" && n.cleanUpTransition(); }); } class _e extends l { constructor(t, e) { super(t), this.rackApi_ = e; } } function qi(n, t) { return n.addBlade(Object.assign(Object.assign({}, t), { view: "button" })); } function Yi(n, t) { return n.addBlade(Object.assign(Object.assign({}, t), { view: "folder" })); } function Qi(n, t) { const e = t ?? {}; return n.addBlade(Object.assign(Object.assign({}, e), { view: "separator" })); } function Wi(n, t) { return n.addBlade(Object.assign(Object.assign({}, t), { view: "tab" })); } class we { constructor(t) { this.emitter = new M(), this.items_ = [], this.cache_ = /* @__PURE__ */ new Set(), this.onSubListAdd_ = this.onSubListAdd_.bind(this), this.onSubListRemove_ = this.onSubListRemove_.bind(this), this.extract_ = t; } get items() { return this.items_; } allItems() { return Array.from(this.cache_); } find(t) { for (const e of this.allItems()) if (t(e)) return e; return null; } includes(t) { return this.cache_.has(t); } add(t, e) { if (this.includes(t)) throw _.shouldNeverHappen(); const i = e !== void 0 ? e : this.items_.length; this.items_.splice(i, 0, t), this.cache_.add(t); const r = this.extract_(t); r && (r.emitter.on("add", this.onSubListAdd_), r.emitter.on("remove", this.onSubListRemove_), r.allItems().forEach((a) => { this.cache_.add(a); })), this.emitter.emit("add", { index: i, item: t, root: this, target: this }); } remove(t) { const e = this.items_.indexOf(t); if (e < 0) return; this.items_.splice(e, 1), this.cache_.delete(t); const i = this.extract_(t); i && (i.emitter.off("add", this.onSubListAdd_), i.emitter.off("remove", this.onSubListRemove_)), this.emitter.emit("remove", { index: e, item: t, root: this, target: this }); } onSubListAdd_(t) { this.cache_.add(t.item), this.emitter.emit("add", { index: t.index, item: t.item, root: this, target: t.target }); } onSubListRemove_(t) { this.cache_.delete(t.item), this.emitter.emit("remove", { index: t.index, item: t.item, root: this, target: t.target }); } } class ge extends l { constructor(t) { super(t), this.onBindingChange_ = this.onBindingChange_.bind(this), this.emitter_ = new M(), this.controller_.binding.emitter.on("change", this.onBindingChange_); } get label() { return this.controller_.props.get("label"); } set label(t) { this.controller_.props.set("label", t); } on(t, e) { const i = e.bind(this); return this.emitter_.on(t, (r) => { i(r.event); }), this; } refresh() { this.controller_.binding.read(); } onBindingChange_(t) { const e = t.sender.target.read(); this.emitter_.emit("change", { event: new v(this, e, this.controller_.binding.target.presetKey, t.options.last) }); } } class G extends Zt { constructor(t, e) { super(t, e), this.binding = e.binding; } } class Ce extends l { constructor(t) { super(t), this.onBindingUpdate_ = this.onBindingUpdate_.bind(this), this.emitter_ = new M(), this.controller_.binding.emitter.on("update", this.onBindingUpdate_); } get label() { return this.controller_.props.get("label"); } set label(t) { this.controller_.props.set("label", t); } on(t, e) { const i = e.bind(this); return this.emitter_.on(t, (r) => { i(r.event); }), this; } refresh() { this.controller_.binding.read(); } onBindingUpdate_(t) { const e = t.sender.target.read(); this.emitter_.emit("update", { event: new w(this, e, this.controller_.binding.target.presetKey) }); } } class nt extends Zt { constructor(t, e) { super(t, e), this.binding = e.binding, this.viewProps.bindDisabled(this.binding.ticker), this.viewProps.handleDispose(() => { this.binding.dispose(); }); } } function Xi(n) { return n instanceof Jt ? n.apiSet_ : n instanceof _e ? n.rackApi_.apiSet_ : null; } function Mt(n, t) { const e = n.find((i) => i.controller_ === t); if (!e) throw _.shouldNeverHappen(); return e; } function dn(n, t, e) { if (!L.isBindable(n)) throw _.notBindable(); return new L(n, t, e); } class Jt extends l { constructor(t, e) { super(t), this.onRackAdd_ = this.onRackAdd_.bind(this), this.onRackRemove_ = this.onRackRemove_.bind(this), this.onRackInputChange_ = this.onRackInputChange_.bind(this), this.onRackMonitorUpdate_ = this.onRackMonitorUpdate_.bind(this), this.emitter_ = new M(), this.apiSet_ = new we(Xi), this.pool_ = e; const i = this.controller_.rack; i.emitter.on("add", this.onRackAdd_), i.emitter.on("remove", this.onRackRemove_), i.emitter.on("inputchange", this.onRackInputChange_), i.emitter.on("monitorupdate", this.onRackMonitorUpdate_), i.children.forEach((r) => { this.setUpApi_(r); }); } get children() { return this.controller_.rack.children.map((t) => Mt(this.apiSet_, t)); } addInput(t, e, i) { const r = i ?? {}, a = this.controller_.view.element.ownerDocument, d = this.pool_.createInput(a, dn(t, e, r.presetKey), r), h = new ge(d); return this.add(h, r.index); } addMonitor(t, e, i) { const r = i ?? {}, a = this.controller_.view.element.ownerDocument, d = this.pool_.createMonitor(a, dn(t, e), r), h = new Ce(d); return this.add(h, r.index); } addFolder(t) { return Yi(this, t); } addButton(t) { return qi(this, t); } addSeparator(t) { return Qi(this, t); } addTab(t) { return Wi(this, t); } add(t, e) { this.controller_.rack.add(t.controller_, e); const i = this.apiSet_.find((r) => r.controller_ === t.controller_); return i && this.apiSet_.remove(i), this.apiSet_.add(t), t; } remove(t) { this.controller_.rack.remove(t.controller_); } addBlade(t) { const e = this.controller_.view.element.ownerDocument, i = this.pool_.createBlade(e, t), r = this.pool_.createBladeApi(i); return this.add(r, t.index); } on(t, e) { const i = e.bind(this); return this.emitter_.on(t, (r) => { i(r.event); }), this; } setUpApi_(t) { this.apiSet_.find((i) => i.controller_ === t) || this.apiSet_.add(this.pool_.createBladeApi(t)); } onRackAdd_(t) { this.setUpApi_(t.bladeController); } onRackRemove_(t) { if (t.isRoot) { const e = Mt(this.apiSet_, t.bladeController); this.apiSet_.remove(e); } } onRackInputChange_(t) { const e = t.bladeController; if (e instanceof G) { const i = Mt(this.apiSet_, e), r = e.binding; this.emitter_.emit("change", { event: new v(i, r.target.read(), r.target.presetKey, t.options.last) }); } else if (e instanceof _t) { const i = Mt(this.apiSet_, e); this.emitter_.emit("change", { event: new v(i, e.value.rawValue, void 0, t.options.last) }); } } onRackMonitorUpdate_(t) { if (!(t.bladeController instanceof nt)) throw _.shouldNeverHappen(); const e = Mt(this.apiSet_, t.bladeController), i = t.bladeController.binding; this.emitter_.emit("update", { event: new w(e, i.target.read(), i.target.presetKey) }); } } class xe extends _e { constructor(t, e) { super(t, new Jt(t.rackController, e)), this.emitter_ = new M(), this.controller_.foldable.value("expanded").emitter.on("change", (i) => { this.emitter_.emit("fold", { event: new b(this, i.sender.rawValue) }); }), this.rackApi_.on("change", (i) => { this.emitter_.emit("change", { event: i }); }), this.rackApi_.on("update", (i) => { this.emitter_.emit("update", { event: i }); }); } get expanded() { return this.controller_.foldable.get("expanded"); } set expanded(t) { this.controller_.foldable.set("expanded", t); } get title() { return this.controller_.props.get("title"); } set title(t) { this.controller_.props.set("title", t); } get children() { return this.rackApi_.children; } addInput(t, e, i) { return this.rackApi_.addInput(t, e, i); } addMonitor(t, e, i) { return this.rackApi_.addMonitor(t, e, i); } addFolder(t) { return this.rackApi_.addFolder(t); } addButton(t) {