import {
  VisuallyHidden
} from "./chunk-VXJXQW5O.js";
import {
  _extends
} from "./chunk-7RVXTONK.js";
import {
  Content,
  DialogClose,
  DialogTitle,
  Overlay,
  Portal as Portal2,
  Root as Root2
} from "./chunk-FGBSNFAB.js";
import {
  Anchor2,
  Arrow2,
  CheckboxItem,
  CheckboxItem2,
  Content2,
  Content22,
  Group,
  Group2,
  Item2,
  Item22,
  ItemIndicator,
  ItemIndicator2,
  Label,
  Portal as Portal3,
  Portal2 as Portal22,
  RadioGroup,
  RadioItem,
  Root2 as Root22,
  Root3,
  Separator,
  Sub,
  Sub2,
  SubContent,
  SubContent2,
  SubTrigger,
  SubTrigger2,
  Trigger,
  createMenuScope
} from "./chunk-A4L6H3JD.js";
import {
  createCollection,
  useDirection
} from "./chunk-SBOC772F.js";
import {
  useSize
} from "./chunk-ADRVA6BL.js";
import {
  RemoveScrollBar,
  __assign,
  __rest,
  __spreadArray,
  createSidecarMedium,
  exportSidecar,
  fullWidthClassName,
  hideOthers,
  styleSingleton,
  useMergeRefs,
  zeroRightClassName
} from "./chunk-3II6XBGW.js";
import {
  Branch,
  Portal,
  Root
} from "./chunk-7QCPQX5P.js";
import {
  Presence,
  composeEventHandlers,
  useControllableState
} from "./chunk-2NJBJH53.js";
import {
  useCallbackRef,
  useLayoutEffect2
} from "./chunk-AB6ZV2XR.js";
import {
  createContextScope
} from "./chunk-GUCB4VV7.js";
import {
  Primitive,
  dispatchDiscreteCustomEvent
} from "./chunk-QMZ62V7Z.js";
import {
  useComposedRefs
} from "./chunk-N5TPNWD3.js";
import {
  require_react_dom
} from "./chunk-EK5KU4LC.js";
import {
  require_jsx_runtime
} from "./chunk-M2BG764J.js";
import {
  require_react
} from "./chunk-PWIQPVSF.js";
import {
  __commonJS,
  __export,
  __toESM
} from "./chunk-5WWUZCGV.js";

// node_modules/.deno/classnames@2.5.1/node_modules/classnames/index.js
var require_classnames = __commonJS({
  "node_modules/.deno/classnames@2.5.1/node_modules/classnames/index.js"(exports, module) {
    (function() {
      "use strict";
      var hasOwn = {}.hasOwnProperty;
      function classNames27() {
        var classes = "";
        for (var i = 0; i < arguments.length; i++) {
          var arg = arguments[i];
          if (arg) {
            classes = appendClass(classes, parseValue(arg));
          }
        }
        return classes;
      }
      function parseValue(arg) {
        if (typeof arg === "string" || typeof arg === "number") {
          return arg;
        }
        if (typeof arg !== "object") {
          return "";
        }
        if (Array.isArray(arg)) {
          return classNames27.apply(null, arg);
        }
        if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) {
          return arg.toString();
        }
        var classes = "";
        for (var key in arg) {
          if (hasOwn.call(arg, key) && arg[key]) {
            classes = appendClass(classes, key);
          }
        }
        return classes;
      }
      function appendClass(value, newClass) {
        if (!newClass) {
          return value;
        }
        if (value) {
          return value + " " + newClass;
        }
        return value + newClass;
      }
      if (typeof module !== "undefined" && module.exports) {
        classNames27.default = classNames27;
        module.exports = classNames27;
      } else if (typeof define === "function" && typeof define.amd === "object" && define.amd) {
        define("classnames", [], function() {
          return classNames27;
        });
      } else {
        window.classNames = classNames27;
      }
    })();
  }
});

// node_modules/.deno/lodash.isequal@4.5.0/node_modules/lodash.isequal/index.js
var require_lodash = __commonJS({
  "node_modules/.deno/lodash.isequal@4.5.0/node_modules/lodash.isequal/index.js"(exports, module) {
    var LARGE_ARRAY_SIZE = 200;
    var HASH_UNDEFINED = "__lodash_hash_undefined__";
    var COMPARE_PARTIAL_FLAG = 1;
    var COMPARE_UNORDERED_FLAG = 2;
    var MAX_SAFE_INTEGER = 9007199254740991;
    var argsTag = "[object Arguments]";
    var arrayTag = "[object Array]";
    var asyncTag = "[object AsyncFunction]";
    var boolTag = "[object Boolean]";
    var dateTag = "[object Date]";
    var errorTag = "[object Error]";
    var funcTag = "[object Function]";
    var genTag = "[object GeneratorFunction]";
    var mapTag = "[object Map]";
    var numberTag = "[object Number]";
    var nullTag = "[object Null]";
    var objectTag = "[object Object]";
    var promiseTag = "[object Promise]";
    var proxyTag = "[object Proxy]";
    var regexpTag = "[object RegExp]";
    var setTag = "[object Set]";
    var stringTag = "[object String]";
    var symbolTag = "[object Symbol]";
    var undefinedTag = "[object Undefined]";
    var weakMapTag = "[object WeakMap]";
    var arrayBufferTag = "[object ArrayBuffer]";
    var dataViewTag = "[object DataView]";
    var float32Tag = "[object Float32Array]";
    var float64Tag = "[object Float64Array]";
    var int8Tag = "[object Int8Array]";
    var int16Tag = "[object Int16Array]";
    var int32Tag = "[object Int32Array]";
    var uint8Tag = "[object Uint8Array]";
    var uint8ClampedTag = "[object Uint8ClampedArray]";
    var uint16Tag = "[object Uint16Array]";
    var uint32Tag = "[object Uint32Array]";
    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
    var reIsHostCtor = /^\[object .+?Constructor\]$/;
    var reIsUint = /^(?:0|[1-9]\d*)$/;
    var typedArrayTags = {};
    typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
    typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
    var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
    var freeSelf = typeof self == "object" && self && self.Object === Object && self;
    var root = freeGlobal || freeSelf || Function("return this")();
    var freeExports = typeof exports == "object" && exports && !exports.nodeType && exports;
    var freeModule = freeExports && typeof module == "object" && module && !module.nodeType && module;
    var moduleExports = freeModule && freeModule.exports === freeExports;
    var freeProcess = moduleExports && freeGlobal.process;
    var nodeUtil = function() {
      try {
        return freeProcess && freeProcess.binding && freeProcess.binding("util");
      } catch (e) {
      }
    }();
    var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
    function arrayFilter(array2, predicate) {
      var index2 = -1, length = array2 == null ? 0 : array2.length, resIndex = 0, result = [];
      while (++index2 < length) {
        var value = array2[index2];
        if (predicate(value, index2, array2)) {
          result[resIndex++] = value;
        }
      }
      return result;
    }
    function arrayPush(array2, values) {
      var index2 = -1, length = values.length, offset2 = array2.length;
      while (++index2 < length) {
        array2[offset2 + index2] = values[index2];
      }
      return array2;
    }
    function arraySome(array2, predicate) {
      var index2 = -1, length = array2 == null ? 0 : array2.length;
      while (++index2 < length) {
        if (predicate(array2[index2], index2, array2)) {
          return true;
        }
      }
      return false;
    }
    function baseTimes(n, iteratee) {
      var index2 = -1, result = Array(n);
      while (++index2 < n) {
        result[index2] = iteratee(index2);
      }
      return result;
    }
    function baseUnary(func) {
      return function(value) {
        return func(value);
      };
    }
    function cacheHas(cache, key) {
      return cache.has(key);
    }
    function getValue(object2, key) {
      return object2 == null ? void 0 : object2[key];
    }
    function mapToArray(map) {
      var index2 = -1, result = Array(map.size);
      map.forEach(function(value, key) {
        result[++index2] = [key, value];
      });
      return result;
    }
    function overArg(func, transform) {
      return function(arg) {
        return func(transform(arg));
      };
    }
    function setToArray(set) {
      var index2 = -1, result = Array(set.size);
      set.forEach(function(value) {
        result[++index2] = value;
      });
      return result;
    }
    var arrayProto = Array.prototype;
    var funcProto = Function.prototype;
    var objectProto = Object.prototype;
    var coreJsData = root["__core-js_shared__"];
    var funcToString = funcProto.toString;
    var hasOwnProperty2 = objectProto.hasOwnProperty;
    var maskSrcKey = function() {
      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || "");
      return uid ? "Symbol(src)_1." + uid : "";
    }();
    var nativeObjectToString = objectProto.toString;
    var reIsNative = RegExp(
      "^" + funcToString.call(hasOwnProperty2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
    );
    var Buffer = moduleExports ? root.Buffer : void 0;
    var Symbol2 = root.Symbol;
    var Uint8Array2 = root.Uint8Array;
    var propertyIsEnumerable = objectProto.propertyIsEnumerable;
    var splice = arrayProto.splice;
    var symToStringTag = Symbol2 ? Symbol2.toStringTag : void 0;
    var nativeGetSymbols = Object.getOwnPropertySymbols;
    var nativeIsBuffer = Buffer ? Buffer.isBuffer : void 0;
    var nativeKeys = overArg(Object.keys, Object);
    var DataView2 = getNative(root, "DataView");
    var Map2 = getNative(root, "Map");
    var Promise2 = getNative(root, "Promise");
    var Set2 = getNative(root, "Set");
    var WeakMap2 = getNative(root, "WeakMap");
    var nativeCreate = getNative(Object, "create");
    var dataViewCtorString = toSource(DataView2);
    var mapCtorString = toSource(Map2);
    var promiseCtorString = toSource(Promise2);
    var setCtorString = toSource(Set2);
    var weakMapCtorString = toSource(WeakMap2);
    var symbolProto = Symbol2 ? Symbol2.prototype : void 0;
    var symbolValueOf = symbolProto ? symbolProto.valueOf : void 0;
    function Hash(entries) {
      var index2 = -1, length = entries == null ? 0 : entries.length;
      this.clear();
      while (++index2 < length) {
        var entry = entries[index2];
        this.set(entry[0], entry[1]);
      }
    }
    function hashClear() {
      this.__data__ = nativeCreate ? nativeCreate(null) : {};
      this.size = 0;
    }
    function hashDelete(key) {
      var result = this.has(key) && delete this.__data__[key];
      this.size -= result ? 1 : 0;
      return result;
    }
    function hashGet(key) {
      var data = this.__data__;
      if (nativeCreate) {
        var result = data[key];
        return result === HASH_UNDEFINED ? void 0 : result;
      }
      return hasOwnProperty2.call(data, key) ? data[key] : void 0;
    }
    function hashHas(key) {
      var data = this.__data__;
      return nativeCreate ? data[key] !== void 0 : hasOwnProperty2.call(data, key);
    }
    function hashSet(key, value) {
      var data = this.__data__;
      this.size += this.has(key) ? 0 : 1;
      data[key] = nativeCreate && value === void 0 ? HASH_UNDEFINED : value;
      return this;
    }
    Hash.prototype.clear = hashClear;
    Hash.prototype["delete"] = hashDelete;
    Hash.prototype.get = hashGet;
    Hash.prototype.has = hashHas;
    Hash.prototype.set = hashSet;
    function ListCache(entries) {
      var index2 = -1, length = entries == null ? 0 : entries.length;
      this.clear();
      while (++index2 < length) {
        var entry = entries[index2];
        this.set(entry[0], entry[1]);
      }
    }
    function listCacheClear() {
      this.__data__ = [];
      this.size = 0;
    }
    function listCacheDelete(key) {
      var data = this.__data__, index2 = assocIndexOf(data, key);
      if (index2 < 0) {
        return false;
      }
      var lastIndex = data.length - 1;
      if (index2 == lastIndex) {
        data.pop();
      } else {
        splice.call(data, index2, 1);
      }
      --this.size;
      return true;
    }
    function listCacheGet(key) {
      var data = this.__data__, index2 = assocIndexOf(data, key);
      return index2 < 0 ? void 0 : data[index2][1];
    }
    function listCacheHas(key) {
      return assocIndexOf(this.__data__, key) > -1;
    }
    function listCacheSet(key, value) {
      var data = this.__data__, index2 = assocIndexOf(data, key);
      if (index2 < 0) {
        ++this.size;
        data.push([key, value]);
      } else {
        data[index2][1] = value;
      }
      return this;
    }
    ListCache.prototype.clear = listCacheClear;
    ListCache.prototype["delete"] = listCacheDelete;
    ListCache.prototype.get = listCacheGet;
    ListCache.prototype.has = listCacheHas;
    ListCache.prototype.set = listCacheSet;
    function MapCache(entries) {
      var index2 = -1, length = entries == null ? 0 : entries.length;
      this.clear();
      while (++index2 < length) {
        var entry = entries[index2];
        this.set(entry[0], entry[1]);
      }
    }
    function mapCacheClear() {
      this.size = 0;
      this.__data__ = {
        "hash": new Hash(),
        "map": new (Map2 || ListCache)(),
        "string": new Hash()
      };
    }
    function mapCacheDelete(key) {
      var result = getMapData(this, key)["delete"](key);
      this.size -= result ? 1 : 0;
      return result;
    }
    function mapCacheGet(key) {
      return getMapData(this, key).get(key);
    }
    function mapCacheHas(key) {
      return getMapData(this, key).has(key);
    }
    function mapCacheSet(key, value) {
      var data = getMapData(this, key), size2 = data.size;
      data.set(key, value);
      this.size += data.size == size2 ? 0 : 1;
      return this;
    }
    MapCache.prototype.clear = mapCacheClear;
    MapCache.prototype["delete"] = mapCacheDelete;
    MapCache.prototype.get = mapCacheGet;
    MapCache.prototype.has = mapCacheHas;
    MapCache.prototype.set = mapCacheSet;
    function SetCache(values) {
      var index2 = -1, length = values == null ? 0 : values.length;
      this.__data__ = new MapCache();
      while (++index2 < length) {
        this.add(values[index2]);
      }
    }
    function setCacheAdd(value) {
      this.__data__.set(value, HASH_UNDEFINED);
      return this;
    }
    function setCacheHas(value) {
      return this.__data__.has(value);
    }
    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
    SetCache.prototype.has = setCacheHas;
    function Stack(entries) {
      var data = this.__data__ = new ListCache(entries);
      this.size = data.size;
    }
    function stackClear() {
      this.__data__ = new ListCache();
      this.size = 0;
    }
    function stackDelete(key) {
      var data = this.__data__, result = data["delete"](key);
      this.size = data.size;
      return result;
    }
    function stackGet(key) {
      return this.__data__.get(key);
    }
    function stackHas(key) {
      return this.__data__.has(key);
    }
    function stackSet(key, value) {
      var data = this.__data__;
      if (data instanceof ListCache) {
        var pairs = data.__data__;
        if (!Map2 || pairs.length < LARGE_ARRAY_SIZE - 1) {
          pairs.push([key, value]);
          this.size = ++data.size;
          return this;
        }
        data = this.__data__ = new MapCache(pairs);
      }
      data.set(key, value);
      this.size = data.size;
      return this;
    }
    Stack.prototype.clear = stackClear;
    Stack.prototype["delete"] = stackDelete;
    Stack.prototype.get = stackGet;
    Stack.prototype.has = stackHas;
    Stack.prototype.set = stackSet;
    function arrayLikeKeys(value, inherited) {
      var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length;
      for (var key in value) {
        if ((inherited || hasOwnProperty2.call(value, key)) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode.
        (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers.
        isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays.
        isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties.
        isIndex(key, length)))) {
          result.push(key);
        }
      }
      return result;
    }
    function assocIndexOf(array2, key) {
      var length = array2.length;
      while (length--) {
        if (eq(array2[length][0], key)) {
          return length;
        }
      }
      return -1;
    }
    function baseGetAllKeys(object2, keysFunc, symbolsFunc) {
      var result = keysFunc(object2);
      return isArray(object2) ? result : arrayPush(result, symbolsFunc(object2));
    }
    function baseGetTag(value) {
      if (value == null) {
        return value === void 0 ? undefinedTag : nullTag;
      }
      return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
    }
    function baseIsArguments(value) {
      return isObjectLike(value) && baseGetTag(value) == argsTag;
    }
    function baseIsEqual(value, other, bitmask, customizer, stack3) {
      if (value === other) {
        return true;
      }
      if (value == null || other == null || !isObjectLike(value) && !isObjectLike(other)) {
        return value !== value && other !== other;
      }
      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack3);
    }
    function baseIsEqualDeep(object2, other, bitmask, customizer, equalFunc, stack3) {
      var objIsArr = isArray(object2), othIsArr = isArray(other), objTag = objIsArr ? arrayTag : getTag(object2), othTag = othIsArr ? arrayTag : getTag(other);
      objTag = objTag == argsTag ? objectTag : objTag;
      othTag = othTag == argsTag ? objectTag : othTag;
      var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag;
      if (isSameTag && isBuffer(object2)) {
        if (!isBuffer(other)) {
          return false;
        }
        objIsArr = true;
        objIsObj = false;
      }
      if (isSameTag && !objIsObj) {
        stack3 || (stack3 = new Stack());
        return objIsArr || isTypedArray(object2) ? equalArrays(object2, other, bitmask, customizer, equalFunc, stack3) : equalByTag(object2, other, objTag, bitmask, customizer, equalFunc, stack3);
      }
      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
        var objIsWrapped = objIsObj && hasOwnProperty2.call(object2, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty2.call(other, "__wrapped__");
        if (objIsWrapped || othIsWrapped) {
          var objUnwrapped = objIsWrapped ? object2.value() : object2, othUnwrapped = othIsWrapped ? other.value() : other;
          stack3 || (stack3 = new Stack());
          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack3);
        }
      }
      if (!isSameTag) {
        return false;
      }
      stack3 || (stack3 = new Stack());
      return equalObjects(object2, other, bitmask, customizer, equalFunc, stack3);
    }
    function baseIsNative(value) {
      if (!isObject(value) || isMasked(value)) {
        return false;
      }
      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
      return pattern.test(toSource(value));
    }
    function baseIsTypedArray(value) {
      return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
    }
    function baseKeys(object2) {
      if (!isPrototype(object2)) {
        return nativeKeys(object2);
      }
      var result = [];
      for (var key in Object(object2)) {
        if (hasOwnProperty2.call(object2, key) && key != "constructor") {
          result.push(key);
        }
      }
      return result;
    }
    function equalArrays(array2, other, bitmask, customizer, equalFunc, stack3) {
      var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array2.length, othLength = other.length;
      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
        return false;
      }
      var stacked = stack3.get(array2);
      if (stacked && stack3.get(other)) {
        return stacked == other;
      }
      var index2 = -1, result = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache() : void 0;
      stack3.set(array2, other);
      stack3.set(other, array2);
      while (++index2 < arrLength) {
        var arrValue = array2[index2], othValue = other[index2];
        if (customizer) {
          var compared = isPartial ? customizer(othValue, arrValue, index2, other, array2, stack3) : customizer(arrValue, othValue, index2, array2, other, stack3);
        }
        if (compared !== void 0) {
          if (compared) {
            continue;
          }
          result = false;
          break;
        }
        if (seen) {
          if (!arraySome(other, function(othValue2, othIndex) {
            if (!cacheHas(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack3))) {
              return seen.push(othIndex);
            }
          })) {
            result = false;
            break;
          }
        } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack3))) {
          result = false;
          break;
        }
      }
      stack3["delete"](array2);
      stack3["delete"](other);
      return result;
    }
    function equalByTag(object2, other, tag, bitmask, customizer, equalFunc, stack3) {
      switch (tag) {
        case dataViewTag:
          if (object2.byteLength != other.byteLength || object2.byteOffset != other.byteOffset) {
            return false;
          }
          object2 = object2.buffer;
          other = other.buffer;
        case arrayBufferTag:
          if (object2.byteLength != other.byteLength || !equalFunc(new Uint8Array2(object2), new Uint8Array2(other))) {
            return false;
          }
          return true;
        case boolTag:
        case dateTag:
        case numberTag:
          return eq(+object2, +other);
        case errorTag:
          return object2.name == other.name && object2.message == other.message;
        case regexpTag:
        case stringTag:
          return object2 == other + "";
        case mapTag:
          var convert = mapToArray;
        case setTag:
          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
          convert || (convert = setToArray);
          if (object2.size != other.size && !isPartial) {
            return false;
          }
          var stacked = stack3.get(object2);
          if (stacked) {
            return stacked == other;
          }
          bitmask |= COMPARE_UNORDERED_FLAG;
          stack3.set(object2, other);
          var result = equalArrays(convert(object2), convert(other), bitmask, customizer, equalFunc, stack3);
          stack3["delete"](object2);
          return result;
        case symbolTag:
          if (symbolValueOf) {
            return symbolValueOf.call(object2) == symbolValueOf.call(other);
          }
      }
      return false;
    }
    function equalObjects(object2, other, bitmask, customizer, equalFunc, stack3) {
      var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object2), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length;
      if (objLength != othLength && !isPartial) {
        return false;
      }
      var index2 = objLength;
      while (index2--) {
        var key = objProps[index2];
        if (!(isPartial ? key in other : hasOwnProperty2.call(other, key))) {
          return false;
        }
      }
      var stacked = stack3.get(object2);
      if (stacked && stack3.get(other)) {
        return stacked == other;
      }
      var result = true;
      stack3.set(object2, other);
      stack3.set(other, object2);
      var skipCtor = isPartial;
      while (++index2 < objLength) {
        key = objProps[index2];
        var objValue = object2[key], othValue = other[key];
        if (customizer) {
          var compared = isPartial ? customizer(othValue, objValue, key, other, object2, stack3) : customizer(objValue, othValue, key, object2, other, stack3);
        }
        if (!(compared === void 0 ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack3) : compared)) {
          result = false;
          break;
        }
        skipCtor || (skipCtor = key == "constructor");
      }
      if (result && !skipCtor) {
        var objCtor = object2.constructor, othCtor = other.constructor;
        if (objCtor != othCtor && ("constructor" in object2 && "constructor" in other) && !(typeof objCtor == "function" && objCtor instanceof objCtor && typeof othCtor == "function" && othCtor instanceof othCtor)) {
          result = false;
        }
      }
      stack3["delete"](object2);
      stack3["delete"](other);
      return result;
    }
    function getAllKeys(object2) {
      return baseGetAllKeys(object2, keys, getSymbols);
    }
    function getMapData(map, key) {
      var data = map.__data__;
      return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
    }
    function getNative(object2, key) {
      var value = getValue(object2, key);
      return baseIsNative(value) ? value : void 0;
    }
    function getRawTag(value) {
      var isOwn = hasOwnProperty2.call(value, symToStringTag), tag = value[symToStringTag];
      try {
        value[symToStringTag] = void 0;
        var unmasked = true;
      } catch (e) {
      }
      var result = nativeObjectToString.call(value);
      if (unmasked) {
        if (isOwn) {
          value[symToStringTag] = tag;
        } else {
          delete value[symToStringTag];
        }
      }
      return result;
    }
    var getSymbols = !nativeGetSymbols ? stubArray : function(object2) {
      if (object2 == null) {
        return [];
      }
      object2 = Object(object2);
      return arrayFilter(nativeGetSymbols(object2), function(symbol) {
        return propertyIsEnumerable.call(object2, symbol);
      });
    };
    var getTag = baseGetTag;
    if (DataView2 && getTag(new DataView2(new ArrayBuffer(1))) != dataViewTag || Map2 && getTag(new Map2()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set2 && getTag(new Set2()) != setTag || WeakMap2 && getTag(new WeakMap2()) != weakMapTag) {
      getTag = function(value) {
        var result = baseGetTag(value), Ctor = result == objectTag ? value.constructor : void 0, ctorString = Ctor ? toSource(Ctor) : "";
        if (ctorString) {
          switch (ctorString) {
            case dataViewCtorString:
              return dataViewTag;
            case mapCtorString:
              return mapTag;
            case promiseCtorString:
              return promiseTag;
            case setCtorString:
              return setTag;
            case weakMapCtorString:
              return weakMapTag;
          }
        }
        return result;
      };
    }
    function isIndex(value, length) {
      length = length == null ? MAX_SAFE_INTEGER : length;
      return !!length && (typeof value == "number" || reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
    }
    function isKeyable(value) {
      var type = typeof value;
      return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null;
    }
    function isMasked(func) {
      return !!maskSrcKey && maskSrcKey in func;
    }
    function isPrototype(value) {
      var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto;
      return value === proto;
    }
    function objectToString(value) {
      return nativeObjectToString.call(value);
    }
    function toSource(func) {
      if (func != null) {
        try {
          return funcToString.call(func);
        } catch (e) {
        }
        try {
          return func + "";
        } catch (e) {
        }
      }
      return "";
    }
    function eq(value, other) {
      return value === other || value !== value && other !== other;
    }
    var isArguments = baseIsArguments(function() {
      return arguments;
    }()) ? baseIsArguments : function(value) {
      return isObjectLike(value) && hasOwnProperty2.call(value, "callee") && !propertyIsEnumerable.call(value, "callee");
    };
    var isArray = Array.isArray;
    function isArrayLike(value) {
      return value != null && isLength(value.length) && !isFunction(value);
    }
    var isBuffer = nativeIsBuffer || stubFalse;
    function isEqual2(value, other) {
      return baseIsEqual(value, other);
    }
    function isFunction(value) {
      if (!isObject(value)) {
        return false;
      }
      var tag = baseGetTag(value);
      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
    }
    function isLength(value) {
      return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
    }
    function isObject(value) {
      var type = typeof value;
      return value != null && (type == "object" || type == "function");
    }
    function isObjectLike(value) {
      return value != null && typeof value == "object";
    }
    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
    function keys(object2) {
      return isArrayLike(object2) ? arrayLikeKeys(object2) : baseKeys(object2);
    }
    function stubArray() {
      return [];
    }
    function stubFalse() {
      return false;
    }
    module.exports = isEqual2;
  }
});

// node_modules/.deno/lodash.throttle@4.1.1/node_modules/lodash.throttle/index.js
var require_lodash2 = __commonJS({
  "node_modules/.deno/lodash.throttle@4.1.1/node_modules/lodash.throttle/index.js"(exports, module) {
    var FUNC_ERROR_TEXT = "Expected a function";
    var NAN = 0 / 0;
    var symbolTag = "[object Symbol]";
    var reTrim = /^\s+|\s+$/g;
    var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
    var reIsBinary = /^0b[01]+$/i;
    var reIsOctal = /^0o[0-7]+$/i;
    var freeParseInt = parseInt;
    var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
    var freeSelf = typeof self == "object" && self && self.Object === Object && self;
    var root = freeGlobal || freeSelf || Function("return this")();
    var objectProto = Object.prototype;
    var objectToString = objectProto.toString;
    var nativeMax = Math.max;
    var nativeMin = Math.min;
    var now = function() {
      return root.Date.now();
    };
    function debounce2(func, wait, options) {
      var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
      if (typeof func != "function") {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      wait = toNumber(wait) || 0;
      if (isObject(options)) {
        leading = !!options.leading;
        maxing = "maxWait" in options;
        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
        trailing = "trailing" in options ? !!options.trailing : trailing;
      }
      function invokeFunc(time) {
        var args = lastArgs, thisArg = lastThis;
        lastArgs = lastThis = void 0;
        lastInvokeTime = time;
        result = func.apply(thisArg, args);
        return result;
      }
      function leadingEdge(time) {
        lastInvokeTime = time;
        timerId = setTimeout(timerExpired, wait);
        return leading ? invokeFunc(time) : result;
      }
      function remainingWait(time) {
        var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result2 = wait - timeSinceLastCall;
        return maxing ? nativeMin(result2, maxWait - timeSinceLastInvoke) : result2;
      }
      function shouldInvoke(time) {
        var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
        return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
      }
      function timerExpired() {
        var time = now();
        if (shouldInvoke(time)) {
          return trailingEdge(time);
        }
        timerId = setTimeout(timerExpired, remainingWait(time));
      }
      function trailingEdge(time) {
        timerId = void 0;
        if (trailing && lastArgs) {
          return invokeFunc(time);
        }
        lastArgs = lastThis = void 0;
        return result;
      }
      function cancel() {
        if (timerId !== void 0) {
          clearTimeout(timerId);
        }
        lastInvokeTime = 0;
        lastArgs = lastCallTime = lastThis = timerId = void 0;
      }
      function flush() {
        return timerId === void 0 ? result : trailingEdge(now());
      }
      function debounced() {
        var time = now(), isInvoking = shouldInvoke(time);
        lastArgs = arguments;
        lastThis = this;
        lastCallTime = time;
        if (isInvoking) {
          if (timerId === void 0) {
            return leadingEdge(lastCallTime);
          }
          if (maxing) {
            timerId = setTimeout(timerExpired, wait);
            return invokeFunc(lastCallTime);
          }
        }
        if (timerId === void 0) {
          timerId = setTimeout(timerExpired, wait);
        }
        return result;
      }
      debounced.cancel = cancel;
      debounced.flush = flush;
      return debounced;
    }
    function throttle3(func, wait, options) {
      var leading = true, trailing = true;
      if (typeof func != "function") {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      if (isObject(options)) {
        leading = "leading" in options ? !!options.leading : leading;
        trailing = "trailing" in options ? !!options.trailing : trailing;
      }
      return debounce2(func, wait, {
        "leading": leading,
        "maxWait": wait,
        "trailing": trailing
      });
    }
    function isObject(value) {
      var type = typeof value;
      return !!value && (type == "object" || type == "function");
    }
    function isObjectLike(value) {
      return !!value && typeof value == "object";
    }
    function isSymbol(value) {
      return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag;
    }
    function toNumber(value) {
      if (typeof value == "number") {
        return value;
      }
      if (isSymbol(value)) {
        return NAN;
      }
      if (isObject(value)) {
        var other = typeof value.valueOf == "function" ? value.valueOf() : value;
        value = isObject(other) ? other + "" : other;
      }
      if (typeof value != "string") {
        return value === 0 ? value : +value;
      }
      value = value.replace(reTrim, "");
      var isBinary = reIsBinary.test(value);
      return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
    }
    module.exports = throttle3;
  }
});

// node_modules/.deno/lodash.uniq@4.5.0/node_modules/lodash.uniq/index.js
var require_lodash3 = __commonJS({
  "node_modules/.deno/lodash.uniq@4.5.0/node_modules/lodash.uniq/index.js"(exports, module) {
    var LARGE_ARRAY_SIZE = 200;
    var HASH_UNDEFINED = "__lodash_hash_undefined__";
    var INFINITY = 1 / 0;
    var funcTag = "[object Function]";
    var genTag = "[object GeneratorFunction]";
    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
    var reIsHostCtor = /^\[object .+?Constructor\]$/;
    var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
    var freeSelf = typeof self == "object" && self && self.Object === Object && self;
    var root = freeGlobal || freeSelf || Function("return this")();
    function arrayIncludes(array2, value) {
      var length = array2 ? array2.length : 0;
      return !!length && baseIndexOf(array2, value, 0) > -1;
    }
    function arrayIncludesWith(array2, value, comparator) {
      var index2 = -1, length = array2 ? array2.length : 0;
      while (++index2 < length) {
        if (comparator(value, array2[index2])) {
          return true;
        }
      }
      return false;
    }
    function baseFindIndex(array2, predicate, fromIndex, fromRight) {
      var length = array2.length, index2 = fromIndex + (fromRight ? 1 : -1);
      while (fromRight ? index2-- : ++index2 < length) {
        if (predicate(array2[index2], index2, array2)) {
          return index2;
        }
      }
      return -1;
    }
    function baseIndexOf(array2, value, fromIndex) {
      if (value !== value) {
        return baseFindIndex(array2, baseIsNaN, fromIndex);
      }
      var index2 = fromIndex - 1, length = array2.length;
      while (++index2 < length) {
        if (array2[index2] === value) {
          return index2;
        }
      }
      return -1;
    }
    function baseIsNaN(value) {
      return value !== value;
    }
    function cacheHas(cache, key) {
      return cache.has(key);
    }
    function getValue(object2, key) {
      return object2 == null ? void 0 : object2[key];
    }
    function isHostObject(value) {
      var result = false;
      if (value != null && typeof value.toString != "function") {
        try {
          result = !!(value + "");
        } catch (e) {
        }
      }
      return result;
    }
    function setToArray(set) {
      var index2 = -1, result = Array(set.size);
      set.forEach(function(value) {
        result[++index2] = value;
      });
      return result;
    }
    var arrayProto = Array.prototype;
    var funcProto = Function.prototype;
    var objectProto = Object.prototype;
    var coreJsData = root["__core-js_shared__"];
    var maskSrcKey = function() {
      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || "");
      return uid ? "Symbol(src)_1." + uid : "";
    }();
    var funcToString = funcProto.toString;
    var hasOwnProperty2 = objectProto.hasOwnProperty;
    var objectToString = objectProto.toString;
    var reIsNative = RegExp(
      "^" + funcToString.call(hasOwnProperty2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
    );
    var splice = arrayProto.splice;
    var Map2 = getNative(root, "Map");
    var Set2 = getNative(root, "Set");
    var nativeCreate = getNative(Object, "create");
    function Hash(entries) {
      var index2 = -1, length = entries ? entries.length : 0;
      this.clear();
      while (++index2 < length) {
        var entry = entries[index2];
        this.set(entry[0], entry[1]);
      }
    }
    function hashClear() {
      this.__data__ = nativeCreate ? nativeCreate(null) : {};
    }
    function hashDelete(key) {
      return this.has(key) && delete this.__data__[key];
    }
    function hashGet(key) {
      var data = this.__data__;
      if (nativeCreate) {
        var result = data[key];
        return result === HASH_UNDEFINED ? void 0 : result;
      }
      return hasOwnProperty2.call(data, key) ? data[key] : void 0;
    }
    function hashHas(key) {
      var data = this.__data__;
      return nativeCreate ? data[key] !== void 0 : hasOwnProperty2.call(data, key);
    }
    function hashSet(key, value) {
      var data = this.__data__;
      data[key] = nativeCreate && value === void 0 ? HASH_UNDEFINED : value;
      return this;
    }
    Hash.prototype.clear = hashClear;
    Hash.prototype["delete"] = hashDelete;
    Hash.prototype.get = hashGet;
    Hash.prototype.has = hashHas;
    Hash.prototype.set = hashSet;
    function ListCache(entries) {
      var index2 = -1, length = entries ? entries.length : 0;
      this.clear();
      while (++index2 < length) {
        var entry = entries[index2];
        this.set(entry[0], entry[1]);
      }
    }
    function listCacheClear() {
      this.__data__ = [];
    }
    function listCacheDelete(key) {
      var data = this.__data__, index2 = assocIndexOf(data, key);
      if (index2 < 0) {
        return false;
      }
      var lastIndex = data.length - 1;
      if (index2 == lastIndex) {
        data.pop();
      } else {
        splice.call(data, index2, 1);
      }
      return true;
    }
    function listCacheGet(key) {
      var data = this.__data__, index2 = assocIndexOf(data, key);
      return index2 < 0 ? void 0 : data[index2][1];
    }
    function listCacheHas(key) {
      return assocIndexOf(this.__data__, key) > -1;
    }
    function listCacheSet(key, value) {
      var data = this.__data__, index2 = assocIndexOf(data, key);
      if (index2 < 0) {
        data.push([key, value]);
      } else {
        data[index2][1] = value;
      }
      return this;
    }
    ListCache.prototype.clear = listCacheClear;
    ListCache.prototype["delete"] = listCacheDelete;
    ListCache.prototype.get = listCacheGet;
    ListCache.prototype.has = listCacheHas;
    ListCache.prototype.set = listCacheSet;
    function MapCache(entries) {
      var index2 = -1, length = entries ? entries.length : 0;
      this.clear();
      while (++index2 < length) {
        var entry = entries[index2];
        this.set(entry[0], entry[1]);
      }
    }
    function mapCacheClear() {
      this.__data__ = {
        "hash": new Hash(),
        "map": new (Map2 || ListCache)(),
        "string": new Hash()
      };
    }
    function mapCacheDelete(key) {
      return getMapData(this, key)["delete"](key);
    }
    function mapCacheGet(key) {
      return getMapData(this, key).get(key);
    }
    function mapCacheHas(key) {
      return getMapData(this, key).has(key);
    }
    function mapCacheSet(key, value) {
      getMapData(this, key).set(key, value);
      return this;
    }
    MapCache.prototype.clear = mapCacheClear;
    MapCache.prototype["delete"] = mapCacheDelete;
    MapCache.prototype.get = mapCacheGet;
    MapCache.prototype.has = mapCacheHas;
    MapCache.prototype.set = mapCacheSet;
    function SetCache(values) {
      var index2 = -1, length = values ? values.length : 0;
      this.__data__ = new MapCache();
      while (++index2 < length) {
        this.add(values[index2]);
      }
    }
    function setCacheAdd(value) {
      this.__data__.set(value, HASH_UNDEFINED);
      return this;
    }
    function setCacheHas(value) {
      return this.__data__.has(value);
    }
    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
    SetCache.prototype.has = setCacheHas;
    function assocIndexOf(array2, key) {
      var length = array2.length;
      while (length--) {
        if (eq(array2[length][0], key)) {
          return length;
        }
      }
      return -1;
    }
    function baseIsNative(value) {
      if (!isObject(value) || isMasked(value)) {
        return false;
      }
      var pattern = isFunction(value) || isHostObject(value) ? reIsNative : reIsHostCtor;
      return pattern.test(toSource(value));
    }
    function baseUniq(array2, iteratee, comparator) {
      var index2 = -1, includes = arrayIncludes, length = array2.length, isCommon = true, result = [], seen = result;
      if (comparator) {
        isCommon = false;
        includes = arrayIncludesWith;
      } else if (length >= LARGE_ARRAY_SIZE) {
        var set = iteratee ? null : createSet(array2);
        if (set) {
          return setToArray(set);
        }
        isCommon = false;
        includes = cacheHas;
        seen = new SetCache();
      } else {
        seen = iteratee ? [] : result;
      }
      outer:
        while (++index2 < length) {
          var value = array2[index2], computed2 = iteratee ? iteratee(value) : value;
          value = comparator || value !== 0 ? value : 0;
          if (isCommon && computed2 === computed2) {
            var seenIndex = seen.length;
            while (seenIndex--) {
              if (seen[seenIndex] === computed2) {
                continue outer;
              }
            }
            if (iteratee) {
              seen.push(computed2);
            }
            result.push(value);
          } else if (!includes(seen, computed2, comparator)) {
            if (seen !== result) {
              seen.push(computed2);
            }
            result.push(value);
          }
        }
      return result;
    }
    var createSet = !(Set2 && 1 / setToArray(new Set2([, -0]))[1] == INFINITY) ? noop4 : function(values) {
      return new Set2(values);
    };
    function getMapData(map, key) {
      var data = map.__data__;
      return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
    }
    function getNative(object2, key) {
      var value = getValue(object2, key);
      return baseIsNative(value) ? value : void 0;
    }
    function isKeyable(value) {
      var type = typeof value;
      return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null;
    }
    function isMasked(func) {
      return !!maskSrcKey && maskSrcKey in func;
    }
    function toSource(func) {
      if (func != null) {
        try {
          return funcToString.call(func);
        } catch (e) {
        }
        try {
          return func + "";
        } catch (e) {
        }
      }
      return "";
    }
    function uniq2(array2) {
      return array2 && array2.length ? baseUniq(array2) : [];
    }
    function eq(value, other) {
      return value === other || value !== value && other !== other;
    }
    function isFunction(value) {
      var tag = isObject(value) ? objectToString.call(value) : "";
      return tag == funcTag || tag == genTag;
    }
    function isObject(value) {
      var type = typeof value;
      return !!value && (type == "object" || type == "function");
    }
    function noop4() {
    }
    module.exports = uniq2;
  }
});

// node_modules/.deno/eventemitter3@4.0.7/node_modules/eventemitter3/index.js
var require_eventemitter3 = __commonJS({
  "node_modules/.deno/eventemitter3@4.0.7/node_modules/eventemitter3/index.js"(exports, module) {
    "use strict";
    var has = Object.prototype.hasOwnProperty;
    var prefix = "~";
    function Events() {
    }
    if (Object.create) {
      Events.prototype = /* @__PURE__ */ Object.create(null);
      if (!new Events().__proto__)
        prefix = false;
    }
    function EE(fn, context, once) {
      this.fn = fn;
      this.context = context;
      this.once = once || false;
    }
    function addListener(emitter, event, fn, context, once) {
      if (typeof fn !== "function") {
        throw new TypeError("The listener must be a function");
      }
      var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
      if (!emitter._events[evt])
        emitter._events[evt] = listener, emitter._eventsCount++;
      else if (!emitter._events[evt].fn)
        emitter._events[evt].push(listener);
      else
        emitter._events[evt] = [emitter._events[evt], listener];
      return emitter;
    }
    function clearEvent(emitter, evt) {
      if (--emitter._eventsCount === 0)
        emitter._events = new Events();
      else
        delete emitter._events[evt];
    }
    function EventEmitter2() {
      this._events = new Events();
      this._eventsCount = 0;
    }
    EventEmitter2.prototype.eventNames = function eventNames() {
      var names = [], events, name;
      if (this._eventsCount === 0)
        return names;
      for (name in events = this._events) {
        if (has.call(events, name))
          names.push(prefix ? name.slice(1) : name);
      }
      if (Object.getOwnPropertySymbols) {
        return names.concat(Object.getOwnPropertySymbols(events));
      }
      return names;
    };
    EventEmitter2.prototype.listeners = function listeners(event) {
      var evt = prefix ? prefix + event : event, handlers = this._events[evt];
      if (!handlers)
        return [];
      if (handlers.fn)
        return [handlers.fn];
      for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
        ee[i] = handlers[i].fn;
      }
      return ee;
    };
    EventEmitter2.prototype.listenerCount = function listenerCount(event) {
      var evt = prefix ? prefix + event : event, listeners = this._events[evt];
      if (!listeners)
        return 0;
      if (listeners.fn)
        return 1;
      return listeners.length;
    };
    EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
      var evt = prefix ? prefix + event : event;
      if (!this._events[evt])
        return false;
      var listeners = this._events[evt], len = arguments.length, args, i;
      if (listeners.fn) {
        if (listeners.once)
          this.removeListener(event, listeners.fn, void 0, true);
        switch (len) {
          case 1:
            return listeners.fn.call(listeners.context), true;
          case 2:
            return listeners.fn.call(listeners.context, a1), true;
          case 3:
            return listeners.fn.call(listeners.context, a1, a2), true;
          case 4:
            return listeners.fn.call(listeners.context, a1, a2, a3), true;
          case 5:
            return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
          case 6:
            return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
        }
        for (i = 1, args = new Array(len - 1); i < len; i++) {
          args[i - 1] = arguments[i];
        }
        listeners.fn.apply(listeners.context, args);
      } else {
        var length = listeners.length, j;
        for (i = 0; i < length; i++) {
          if (listeners[i].once)
            this.removeListener(event, listeners[i].fn, void 0, true);
          switch (len) {
            case 1:
              listeners[i].fn.call(listeners[i].context);
              break;
            case 2:
              listeners[i].fn.call(listeners[i].context, a1);
              break;
            case 3:
              listeners[i].fn.call(listeners[i].context, a1, a2);
              break;
            case 4:
              listeners[i].fn.call(listeners[i].context, a1, a2, a3);
              break;
            default:
              if (!args)
                for (j = 1, args = new Array(len - 1); j < len; j++) {
                  args[j - 1] = arguments[j];
                }
              listeners[i].fn.apply(listeners[i].context, args);
          }
        }
      }
      return true;
    };
    EventEmitter2.prototype.on = function on(event, fn, context) {
      return addListener(this, event, fn, context, false);
    };
    EventEmitter2.prototype.once = function once(event, fn, context) {
      return addListener(this, event, fn, context, true);
    };
    EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) {
      var evt = prefix ? prefix + event : event;
      if (!this._events[evt])
        return this;
      if (!fn) {
        clearEvent(this, evt);
        return this;
      }
      var listeners = this._events[evt];
      if (listeners.fn) {
        if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
          clearEvent(this, evt);
        }
      } else {
        for (var i = 0, events = [], length = listeners.length; i < length; i++) {
          if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
            events.push(listeners[i]);
          }
        }
        if (events.length)
          this._events[evt] = events.length === 1 ? events[0] : events;
        else
          clearEvent(this, evt);
      }
      return this;
    };
    EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) {
      var evt;
      if (event) {
        evt = prefix ? prefix + event : event;
        if (this._events[evt])
          clearEvent(this, evt);
      } else {
        this._events = new Events();
        this._eventsCount = 0;
      }
      return this;
    };
    EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
    EventEmitter2.prototype.addListener = EventEmitter2.prototype.on;
    EventEmitter2.prefixed = prefix;
    EventEmitter2.EventEmitter = EventEmitter2;
    if ("undefined" !== typeof module) {
      module.exports = EventEmitter2;
    }
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/global-this.js
var require_global_this = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/global-this.js"(exports, module) {
    "use strict";
    var check = function(it) {
      return it && it.Math === Math && it;
    };
    module.exports = // eslint-disable-next-line es/no-global-this -- safe
    check(typeof globalThis == "object" && globalThis) || check(typeof window == "object" && window) || // eslint-disable-next-line no-restricted-globals -- safe
    check(typeof self == "object" && self) || check(typeof global == "object" && global) || check(typeof exports == "object" && exports) || // eslint-disable-next-line no-new-func -- fallback
    function() {
      return this;
    }() || Function("return this")();
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/fails.js
var require_fails = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/fails.js"(exports, module) {
    "use strict";
    module.exports = function(exec) {
      try {
        return !!exec();
      } catch (error) {
        return true;
      }
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/descriptors.js
var require_descriptors = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/descriptors.js"(exports, module) {
    "use strict";
    var fails = require_fails();
    module.exports = !fails(function() {
      return Object.defineProperty({}, 1, { get: function() {
        return 7;
      } })[1] !== 7;
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-bind-native.js
var require_function_bind_native = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-bind-native.js"(exports, module) {
    "use strict";
    var fails = require_fails();
    module.exports = !fails(function() {
      var test2 = function() {
      }.bind();
      return typeof test2 != "function" || test2.hasOwnProperty("prototype");
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-call.js
var require_function_call = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-call.js"(exports, module) {
    "use strict";
    var NATIVE_BIND = require_function_bind_native();
    var call2 = Function.prototype.call;
    module.exports = NATIVE_BIND ? call2.bind(call2) : function() {
      return call2.apply(call2, arguments);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-property-is-enumerable.js
var require_object_property_is_enumerable = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-property-is-enumerable.js"(exports) {
    "use strict";
    var $propertyIsEnumerable = {}.propertyIsEnumerable;
    var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
    var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);
    exports.f = NASHORN_BUG ? function propertyIsEnumerable(V2) {
      var descriptor = getOwnPropertyDescriptor(this, V2);
      return !!descriptor && descriptor.enumerable;
    } : $propertyIsEnumerable;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/create-property-descriptor.js
var require_create_property_descriptor = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/create-property-descriptor.js"(exports, module) {
    "use strict";
    module.exports = function(bitmap, value) {
      return {
        enumerable: !(bitmap & 1),
        configurable: !(bitmap & 2),
        writable: !(bitmap & 4),
        value
      };
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-uncurry-this.js
var require_function_uncurry_this = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-uncurry-this.js"(exports, module) {
    "use strict";
    var NATIVE_BIND = require_function_bind_native();
    var FunctionPrototype = Function.prototype;
    var call2 = FunctionPrototype.call;
    var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call2, call2);
    module.exports = NATIVE_BIND ? uncurryThisWithBind : function(fn) {
      return function() {
        return call2.apply(fn, arguments);
      };
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/classof-raw.js
var require_classof_raw = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/classof-raw.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var toString = uncurryThis({}.toString);
    var stringSlice = uncurryThis("".slice);
    module.exports = function(it) {
      return stringSlice(toString(it), 8, -1);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/indexed-object.js
var require_indexed_object = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/indexed-object.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var fails = require_fails();
    var classof = require_classof_raw();
    var $Object = Object;
    var split = uncurryThis("".split);
    module.exports = fails(function() {
      return !$Object("z").propertyIsEnumerable(0);
    }) ? function(it) {
      return classof(it) === "String" ? split(it, "") : $Object(it);
    } : $Object;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-null-or-undefined.js
var require_is_null_or_undefined = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-null-or-undefined.js"(exports, module) {
    "use strict";
    module.exports = function(it) {
      return it === null || it === void 0;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/require-object-coercible.js
var require_require_object_coercible = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/require-object-coercible.js"(exports, module) {
    "use strict";
    var isNullOrUndefined = require_is_null_or_undefined();
    var $TypeError = TypeError;
    module.exports = function(it) {
      if (isNullOrUndefined(it))
        throw new $TypeError("Can't call method on " + it);
      return it;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-indexed-object.js
var require_to_indexed_object = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-indexed-object.js"(exports, module) {
    "use strict";
    var IndexedObject = require_indexed_object();
    var requireObjectCoercible = require_require_object_coercible();
    module.exports = function(it) {
      return IndexedObject(requireObjectCoercible(it));
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-callable.js
var require_is_callable = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-callable.js"(exports, module) {
    "use strict";
    var documentAll = typeof document == "object" && document.all;
    module.exports = typeof documentAll == "undefined" && documentAll !== void 0 ? function(argument) {
      return typeof argument == "function" || argument === documentAll;
    } : function(argument) {
      return typeof argument == "function";
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-object.js
var require_is_object = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-object.js"(exports, module) {
    "use strict";
    var isCallable = require_is_callable();
    module.exports = function(it) {
      return typeof it == "object" ? it !== null : isCallable(it);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/get-built-in.js
var require_get_built_in = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/get-built-in.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var isCallable = require_is_callable();
    var aFunction = function(argument) {
      return isCallable(argument) ? argument : void 0;
    };
    module.exports = function(namespace, method) {
      return arguments.length < 2 ? aFunction(globalThis2[namespace]) : globalThis2[namespace] && globalThis2[namespace][method];
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-is-prototype-of.js
var require_object_is_prototype_of = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-is-prototype-of.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    module.exports = uncurryThis({}.isPrototypeOf);
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/environment-user-agent.js
var require_environment_user_agent = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/environment-user-agent.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var navigator2 = globalThis2.navigator;
    var userAgent = navigator2 && navigator2.userAgent;
    module.exports = userAgent ? String(userAgent) : "";
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/environment-v8-version.js
var require_environment_v8_version = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/environment-v8-version.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var userAgent = require_environment_user_agent();
    var process2 = globalThis2.process;
    var Deno = globalThis2.Deno;
    var versions = process2 && process2.versions || Deno && Deno.version;
    var v8 = versions && versions.v8;
    var match;
    var version2;
    if (v8) {
      match = v8.split(".");
      version2 = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);
    }
    if (!version2 && userAgent) {
      match = userAgent.match(/Edge\/(\d+)/);
      if (!match || match[1] >= 74) {
        match = userAgent.match(/Chrome\/(\d+)/);
        if (match)
          version2 = +match[1];
      }
    }
    module.exports = version2;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/symbol-constructor-detection.js
var require_symbol_constructor_detection = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/symbol-constructor-detection.js"(exports, module) {
    "use strict";
    var V8_VERSION = require_environment_v8_version();
    var fails = require_fails();
    var globalThis2 = require_global_this();
    var $String = globalThis2.String;
    module.exports = !!Object.getOwnPropertySymbols && !fails(function() {
      var symbol = Symbol("symbol detection");
      return !$String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
      !Symbol.sham && V8_VERSION && V8_VERSION < 41;
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/use-symbol-as-uid.js
var require_use_symbol_as_uid = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/use-symbol-as-uid.js"(exports, module) {
    "use strict";
    var NATIVE_SYMBOL = require_symbol_constructor_detection();
    module.exports = NATIVE_SYMBOL && !Symbol.sham && typeof Symbol.iterator == "symbol";
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-symbol.js
var require_is_symbol = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-symbol.js"(exports, module) {
    "use strict";
    var getBuiltIn = require_get_built_in();
    var isCallable = require_is_callable();
    var isPrototypeOf = require_object_is_prototype_of();
    var USE_SYMBOL_AS_UID = require_use_symbol_as_uid();
    var $Object = Object;
    module.exports = USE_SYMBOL_AS_UID ? function(it) {
      return typeof it == "symbol";
    } : function(it) {
      var $Symbol = getBuiltIn("Symbol");
      return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/try-to-string.js
var require_try_to_string = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/try-to-string.js"(exports, module) {
    "use strict";
    var $String = String;
    module.exports = function(argument) {
      try {
        return $String(argument);
      } catch (error) {
        return "Object";
      }
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/a-callable.js
var require_a_callable = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/a-callable.js"(exports, module) {
    "use strict";
    var isCallable = require_is_callable();
    var tryToString = require_try_to_string();
    var $TypeError = TypeError;
    module.exports = function(argument) {
      if (isCallable(argument))
        return argument;
      throw new $TypeError(tryToString(argument) + " is not a function");
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/get-method.js
var require_get_method = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/get-method.js"(exports, module) {
    "use strict";
    var aCallable = require_a_callable();
    var isNullOrUndefined = require_is_null_or_undefined();
    module.exports = function(V2, P) {
      var func = V2[P];
      return isNullOrUndefined(func) ? void 0 : aCallable(func);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/ordinary-to-primitive.js
var require_ordinary_to_primitive = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/ordinary-to-primitive.js"(exports, module) {
    "use strict";
    var call2 = require_function_call();
    var isCallable = require_is_callable();
    var isObject = require_is_object();
    var $TypeError = TypeError;
    module.exports = function(input, pref) {
      var fn, val;
      if (pref === "string" && isCallable(fn = input.toString) && !isObject(val = call2(fn, input)))
        return val;
      if (isCallable(fn = input.valueOf) && !isObject(val = call2(fn, input)))
        return val;
      if (pref !== "string" && isCallable(fn = input.toString) && !isObject(val = call2(fn, input)))
        return val;
      throw new $TypeError("Can't convert object to primitive value");
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-pure.js
var require_is_pure = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-pure.js"(exports, module) {
    "use strict";
    module.exports = false;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/define-global-property.js
var require_define_global_property = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/define-global-property.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var defineProperty = Object.defineProperty;
    module.exports = function(key, value) {
      try {
        defineProperty(globalThis2, key, { value, configurable: true, writable: true });
      } catch (error) {
        globalThis2[key] = value;
      }
      return value;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/shared-store.js
var require_shared_store = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/shared-store.js"(exports, module) {
    "use strict";
    var IS_PURE = require_is_pure();
    var globalThis2 = require_global_this();
    var defineGlobalProperty = require_define_global_property();
    var SHARED = "__core-js_shared__";
    var store = module.exports = globalThis2[SHARED] || defineGlobalProperty(SHARED, {});
    (store.versions || (store.versions = [])).push({
      version: "3.45.1",
      mode: IS_PURE ? "pure" : "global",
      copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
      license: "https://github.com/zloirock/core-js/blob/v3.45.1/LICENSE",
      source: "https://github.com/zloirock/core-js"
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/shared.js
var require_shared = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/shared.js"(exports, module) {
    "use strict";
    var store = require_shared_store();
    module.exports = function(key, value) {
      return store[key] || (store[key] = value || {});
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-object.js
var require_to_object = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-object.js"(exports, module) {
    "use strict";
    var requireObjectCoercible = require_require_object_coercible();
    var $Object = Object;
    module.exports = function(argument) {
      return $Object(requireObjectCoercible(argument));
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/has-own-property.js
var require_has_own_property = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/has-own-property.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var toObject = require_to_object();
    var hasOwnProperty2 = uncurryThis({}.hasOwnProperty);
    module.exports = Object.hasOwn || function hasOwn(it, key) {
      return hasOwnProperty2(toObject(it), key);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/uid.js
var require_uid = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/uid.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var id = 0;
    var postfix = Math.random();
    var toString = uncurryThis(1.1.toString);
    module.exports = function(key) {
      return "Symbol(" + (key === void 0 ? "" : key) + ")_" + toString(++id + postfix, 36);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/well-known-symbol.js
var require_well_known_symbol = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/well-known-symbol.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var shared = require_shared();
    var hasOwn = require_has_own_property();
    var uid = require_uid();
    var NATIVE_SYMBOL = require_symbol_constructor_detection();
    var USE_SYMBOL_AS_UID = require_use_symbol_as_uid();
    var Symbol2 = globalThis2.Symbol;
    var WellKnownSymbolsStore = shared("wks");
    var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol2["for"] || Symbol2 : Symbol2 && Symbol2.withoutSetter || uid;
    module.exports = function(name) {
      if (!hasOwn(WellKnownSymbolsStore, name)) {
        WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol2, name) ? Symbol2[name] : createWellKnownSymbol("Symbol." + name);
      }
      return WellKnownSymbolsStore[name];
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-primitive.js
var require_to_primitive = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-primitive.js"(exports, module) {
    "use strict";
    var call2 = require_function_call();
    var isObject = require_is_object();
    var isSymbol = require_is_symbol();
    var getMethod2 = require_get_method();
    var ordinaryToPrimitive = require_ordinary_to_primitive();
    var wellKnownSymbol = require_well_known_symbol();
    var $TypeError = TypeError;
    var TO_PRIMITIVE = wellKnownSymbol("toPrimitive");
    module.exports = function(input, pref) {
      if (!isObject(input) || isSymbol(input))
        return input;
      var exoticToPrim = getMethod2(input, TO_PRIMITIVE);
      var result;
      if (exoticToPrim) {
        if (pref === void 0)
          pref = "default";
        result = call2(exoticToPrim, input, pref);
        if (!isObject(result) || isSymbol(result))
          return result;
        throw new $TypeError("Can't convert object to primitive value");
      }
      if (pref === void 0)
        pref = "number";
      return ordinaryToPrimitive(input, pref);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-property-key.js
var require_to_property_key = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-property-key.js"(exports, module) {
    "use strict";
    var toPrimitive = require_to_primitive();
    var isSymbol = require_is_symbol();
    module.exports = function(argument) {
      var key = toPrimitive(argument, "string");
      return isSymbol(key) ? key : key + "";
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/document-create-element.js
var require_document_create_element = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/document-create-element.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var isObject = require_is_object();
    var document2 = globalThis2.document;
    var EXISTS = isObject(document2) && isObject(document2.createElement);
    module.exports = function(it) {
      return EXISTS ? document2.createElement(it) : {};
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/ie8-dom-define.js
var require_ie8_dom_define = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/ie8-dom-define.js"(exports, module) {
    "use strict";
    var DESCRIPTORS = require_descriptors();
    var fails = require_fails();
    var createElement4 = require_document_create_element();
    module.exports = !DESCRIPTORS && !fails(function() {
      return Object.defineProperty(createElement4("div"), "a", {
        get: function() {
          return 7;
        }
      }).a !== 7;
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-get-own-property-descriptor.js
var require_object_get_own_property_descriptor = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-get-own-property-descriptor.js"(exports) {
    "use strict";
    var DESCRIPTORS = require_descriptors();
    var call2 = require_function_call();
    var propertyIsEnumerableModule = require_object_property_is_enumerable();
    var createPropertyDescriptor = require_create_property_descriptor();
    var toIndexedObject = require_to_indexed_object();
    var toPropertyKey = require_to_property_key();
    var hasOwn = require_has_own_property();
    var IE8_DOM_DEFINE = require_ie8_dom_define();
    var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
    exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
      O = toIndexedObject(O);
      P = toPropertyKey(P);
      if (IE8_DOM_DEFINE)
        try {
          return $getOwnPropertyDescriptor(O, P);
        } catch (error) {
        }
      if (hasOwn(O, P))
        return createPropertyDescriptor(!call2(propertyIsEnumerableModule.f, O, P), O[P]);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/v8-prototype-define-bug.js
var require_v8_prototype_define_bug = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/v8-prototype-define-bug.js"(exports, module) {
    "use strict";
    var DESCRIPTORS = require_descriptors();
    var fails = require_fails();
    module.exports = DESCRIPTORS && fails(function() {
      return Object.defineProperty(function() {
      }, "prototype", {
        value: 42,
        writable: false
      }).prototype !== 42;
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/an-object.js
var require_an_object = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/an-object.js"(exports, module) {
    "use strict";
    var isObject = require_is_object();
    var $String = String;
    var $TypeError = TypeError;
    module.exports = function(argument) {
      if (isObject(argument))
        return argument;
      throw new $TypeError($String(argument) + " is not an object");
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-define-property.js
var require_object_define_property = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-define-property.js"(exports) {
    "use strict";
    var DESCRIPTORS = require_descriptors();
    var IE8_DOM_DEFINE = require_ie8_dom_define();
    var V8_PROTOTYPE_DEFINE_BUG = require_v8_prototype_define_bug();
    var anObject = require_an_object();
    var toPropertyKey = require_to_property_key();
    var $TypeError = TypeError;
    var $defineProperty = Object.defineProperty;
    var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
    var ENUMERABLE = "enumerable";
    var CONFIGURABLE = "configurable";
    var WRITABLE = "writable";
    exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {
      anObject(O);
      P = toPropertyKey(P);
      anObject(Attributes);
      if (typeof O === "function" && P === "prototype" && "value" in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {
        var current = $getOwnPropertyDescriptor(O, P);
        if (current && current[WRITABLE]) {
          O[P] = Attributes.value;
          Attributes = {
            configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],
            enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],
            writable: false
          };
        }
      }
      return $defineProperty(O, P, Attributes);
    } : $defineProperty : function defineProperty(O, P, Attributes) {
      anObject(O);
      P = toPropertyKey(P);
      anObject(Attributes);
      if (IE8_DOM_DEFINE)
        try {
          return $defineProperty(O, P, Attributes);
        } catch (error) {
        }
      if ("get" in Attributes || "set" in Attributes)
        throw new $TypeError("Accessors not supported");
      if ("value" in Attributes)
        O[P] = Attributes.value;
      return O;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/create-non-enumerable-property.js
var require_create_non_enumerable_property = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/create-non-enumerable-property.js"(exports, module) {
    "use strict";
    var DESCRIPTORS = require_descriptors();
    var definePropertyModule = require_object_define_property();
    var createPropertyDescriptor = require_create_property_descriptor();
    module.exports = DESCRIPTORS ? function(object2, key, value) {
      return definePropertyModule.f(object2, key, createPropertyDescriptor(1, value));
    } : function(object2, key, value) {
      object2[key] = value;
      return object2;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-name.js
var require_function_name = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-name.js"(exports, module) {
    "use strict";
    var DESCRIPTORS = require_descriptors();
    var hasOwn = require_has_own_property();
    var FunctionPrototype = Function.prototype;
    var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;
    var EXISTS = hasOwn(FunctionPrototype, "name");
    var PROPER = EXISTS && function something() {
    }.name === "something";
    var CONFIGURABLE = EXISTS && (!DESCRIPTORS || DESCRIPTORS && getDescriptor(FunctionPrototype, "name").configurable);
    module.exports = {
      EXISTS,
      PROPER,
      CONFIGURABLE
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/inspect-source.js
var require_inspect_source = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/inspect-source.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var isCallable = require_is_callable();
    var store = require_shared_store();
    var functionToString = uncurryThis(Function.toString);
    if (!isCallable(store.inspectSource)) {
      store.inspectSource = function(it) {
        return functionToString(it);
      };
    }
    module.exports = store.inspectSource;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/weak-map-basic-detection.js
var require_weak_map_basic_detection = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/weak-map-basic-detection.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var isCallable = require_is_callable();
    var WeakMap2 = globalThis2.WeakMap;
    module.exports = isCallable(WeakMap2) && /native code/.test(String(WeakMap2));
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/shared-key.js
var require_shared_key = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/shared-key.js"(exports, module) {
    "use strict";
    var shared = require_shared();
    var uid = require_uid();
    var keys = shared("keys");
    module.exports = function(key) {
      return keys[key] || (keys[key] = uid(key));
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/hidden-keys.js
var require_hidden_keys = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/hidden-keys.js"(exports, module) {
    "use strict";
    module.exports = {};
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/internal-state.js
var require_internal_state = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/internal-state.js"(exports, module) {
    "use strict";
    var NATIVE_WEAK_MAP = require_weak_map_basic_detection();
    var globalThis2 = require_global_this();
    var isObject = require_is_object();
    var createNonEnumerableProperty = require_create_non_enumerable_property();
    var hasOwn = require_has_own_property();
    var shared = require_shared_store();
    var sharedKey = require_shared_key();
    var hiddenKeys = require_hidden_keys();
    var OBJECT_ALREADY_INITIALIZED = "Object already initialized";
    var TypeError2 = globalThis2.TypeError;
    var WeakMap2 = globalThis2.WeakMap;
    var set;
    var get;
    var has;
    var enforce = function(it) {
      return has(it) ? get(it) : set(it, {});
    };
    var getterFor = function(TYPE) {
      return function(it) {
        var state;
        if (!isObject(it) || (state = get(it)).type !== TYPE) {
          throw new TypeError2("Incompatible receiver, " + TYPE + " required");
        }
        return state;
      };
    };
    if (NATIVE_WEAK_MAP || shared.state) {
      store = shared.state || (shared.state = new WeakMap2());
      store.get = store.get;
      store.has = store.has;
      store.set = store.set;
      set = function(it, metadata) {
        if (store.has(it))
          throw new TypeError2(OBJECT_ALREADY_INITIALIZED);
        metadata.facade = it;
        store.set(it, metadata);
        return metadata;
      };
      get = function(it) {
        return store.get(it) || {};
      };
      has = function(it) {
        return store.has(it);
      };
    } else {
      STATE = sharedKey("state");
      hiddenKeys[STATE] = true;
      set = function(it, metadata) {
        if (hasOwn(it, STATE))
          throw new TypeError2(OBJECT_ALREADY_INITIALIZED);
        metadata.facade = it;
        createNonEnumerableProperty(it, STATE, metadata);
        return metadata;
      };
      get = function(it) {
        return hasOwn(it, STATE) ? it[STATE] : {};
      };
      has = function(it) {
        return hasOwn(it, STATE);
      };
    }
    var store;
    var STATE;
    module.exports = {
      set,
      get,
      has,
      enforce,
      getterFor
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/make-built-in.js
var require_make_built_in = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/make-built-in.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var fails = require_fails();
    var isCallable = require_is_callable();
    var hasOwn = require_has_own_property();
    var DESCRIPTORS = require_descriptors();
    var CONFIGURABLE_FUNCTION_NAME = require_function_name().CONFIGURABLE;
    var inspectSource = require_inspect_source();
    var InternalStateModule = require_internal_state();
    var enforceInternalState = InternalStateModule.enforce;
    var getInternalState = InternalStateModule.get;
    var $String = String;
    var defineProperty = Object.defineProperty;
    var stringSlice = uncurryThis("".slice);
    var replace = uncurryThis("".replace);
    var join = uncurryThis([].join);
    var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {
      return defineProperty(function() {
      }, "length", { value: 8 }).length !== 8;
    });
    var TEMPLATE = String(String).split("String");
    var makeBuiltIn = module.exports = function(value, name, options) {
      if (stringSlice($String(name), 0, 7) === "Symbol(") {
        name = "[" + replace($String(name), /^Symbol\(([^)]*)\).*$/, "$1") + "]";
      }
      if (options && options.getter)
        name = "get " + name;
      if (options && options.setter)
        name = "set " + name;
      if (!hasOwn(value, "name") || CONFIGURABLE_FUNCTION_NAME && value.name !== name) {
        if (DESCRIPTORS)
          defineProperty(value, "name", { value: name, configurable: true });
        else
          value.name = name;
      }
      if (CONFIGURABLE_LENGTH && options && hasOwn(options, "arity") && value.length !== options.arity) {
        defineProperty(value, "length", { value: options.arity });
      }
      try {
        if (options && hasOwn(options, "constructor") && options.constructor) {
          if (DESCRIPTORS)
            defineProperty(value, "prototype", { writable: false });
        } else if (value.prototype)
          value.prototype = void 0;
      } catch (error) {
      }
      var state = enforceInternalState(value);
      if (!hasOwn(state, "source")) {
        state.source = join(TEMPLATE, typeof name == "string" ? name : "");
      }
      return value;
    };
    Function.prototype.toString = makeBuiltIn(function toString() {
      return isCallable(this) && getInternalState(this).source || inspectSource(this);
    }, "toString");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/define-built-in.js
var require_define_built_in = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/define-built-in.js"(exports, module) {
    "use strict";
    var isCallable = require_is_callable();
    var definePropertyModule = require_object_define_property();
    var makeBuiltIn = require_make_built_in();
    var defineGlobalProperty = require_define_global_property();
    module.exports = function(O, key, value, options) {
      if (!options)
        options = {};
      var simple = options.enumerable;
      var name = options.name !== void 0 ? options.name : key;
      if (isCallable(value))
        makeBuiltIn(value, name, options);
      if (options.global) {
        if (simple)
          O[key] = value;
        else
          defineGlobalProperty(key, value);
      } else {
        try {
          if (!options.unsafe)
            delete O[key];
          else if (O[key])
            simple = true;
        } catch (error) {
        }
        if (simple)
          O[key] = value;
        else
          definePropertyModule.f(O, key, {
            value,
            enumerable: false,
            configurable: !options.nonConfigurable,
            writable: !options.nonWritable
          });
      }
      return O;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/math-trunc.js
var require_math_trunc = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/math-trunc.js"(exports, module) {
    "use strict";
    var ceil = Math.ceil;
    var floor = Math.floor;
    module.exports = Math.trunc || function trunc(x) {
      var n = +x;
      return (n > 0 ? floor : ceil)(n);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-integer-or-infinity.js
var require_to_integer_or_infinity = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-integer-or-infinity.js"(exports, module) {
    "use strict";
    var trunc = require_math_trunc();
    module.exports = function(argument) {
      var number2 = +argument;
      return number2 !== number2 || number2 === 0 ? 0 : trunc(number2);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-absolute-index.js
var require_to_absolute_index = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-absolute-index.js"(exports, module) {
    "use strict";
    var toIntegerOrInfinity = require_to_integer_or_infinity();
    var max3 = Math.max;
    var min4 = Math.min;
    module.exports = function(index2, length) {
      var integer2 = toIntegerOrInfinity(index2);
      return integer2 < 0 ? max3(integer2 + length, 0) : min4(integer2, length);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-length.js
var require_to_length = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-length.js"(exports, module) {
    "use strict";
    var toIntegerOrInfinity = require_to_integer_or_infinity();
    var min4 = Math.min;
    module.exports = function(argument) {
      var len = toIntegerOrInfinity(argument);
      return len > 0 ? min4(len, 9007199254740991) : 0;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/length-of-array-like.js
var require_length_of_array_like = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/length-of-array-like.js"(exports, module) {
    "use strict";
    var toLength = require_to_length();
    module.exports = function(obj) {
      return toLength(obj.length);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/array-includes.js
var require_array_includes = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/array-includes.js"(exports, module) {
    "use strict";
    var toIndexedObject = require_to_indexed_object();
    var toAbsoluteIndex = require_to_absolute_index();
    var lengthOfArrayLike = require_length_of_array_like();
    var createMethod = function(IS_INCLUDES) {
      return function($this, el, fromIndex) {
        var O = toIndexedObject($this);
        var length = lengthOfArrayLike(O);
        if (length === 0)
          return !IS_INCLUDES && -1;
        var index2 = toAbsoluteIndex(fromIndex, length);
        var value;
        if (IS_INCLUDES && el !== el)
          while (length > index2) {
            value = O[index2++];
            if (value !== value)
              return true;
          }
        else
          for (; length > index2; index2++) {
            if ((IS_INCLUDES || index2 in O) && O[index2] === el)
              return IS_INCLUDES || index2 || 0;
          }
        return !IS_INCLUDES && -1;
      };
    };
    module.exports = {
      // `Array.prototype.includes` method
      // https://tc39.es/ecma262/#sec-array.prototype.includes
      includes: createMethod(true),
      // `Array.prototype.indexOf` method
      // https://tc39.es/ecma262/#sec-array.prototype.indexof
      indexOf: createMethod(false)
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-keys-internal.js
var require_object_keys_internal = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-keys-internal.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var hasOwn = require_has_own_property();
    var toIndexedObject = require_to_indexed_object();
    var indexOf = require_array_includes().indexOf;
    var hiddenKeys = require_hidden_keys();
    var push = uncurryThis([].push);
    module.exports = function(object2, names) {
      var O = toIndexedObject(object2);
      var i = 0;
      var result = [];
      var key;
      for (key in O)
        !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);
      while (names.length > i)
        if (hasOwn(O, key = names[i++])) {
          ~indexOf(result, key) || push(result, key);
        }
      return result;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/enum-bug-keys.js
var require_enum_bug_keys = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/enum-bug-keys.js"(exports, module) {
    "use strict";
    module.exports = [
      "constructor",
      "hasOwnProperty",
      "isPrototypeOf",
      "propertyIsEnumerable",
      "toLocaleString",
      "toString",
      "valueOf"
    ];
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-get-own-property-names.js
var require_object_get_own_property_names = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-get-own-property-names.js"(exports) {
    "use strict";
    var internalObjectKeys = require_object_keys_internal();
    var enumBugKeys = require_enum_bug_keys();
    var hiddenKeys = enumBugKeys.concat("length", "prototype");
    exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
      return internalObjectKeys(O, hiddenKeys);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-get-own-property-symbols.js
var require_object_get_own_property_symbols = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-get-own-property-symbols.js"(exports) {
    "use strict";
    exports.f = Object.getOwnPropertySymbols;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/own-keys.js
var require_own_keys = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/own-keys.js"(exports, module) {
    "use strict";
    var getBuiltIn = require_get_built_in();
    var uncurryThis = require_function_uncurry_this();
    var getOwnPropertyNamesModule = require_object_get_own_property_names();
    var getOwnPropertySymbolsModule = require_object_get_own_property_symbols();
    var anObject = require_an_object();
    var concat = uncurryThis([].concat);
    module.exports = getBuiltIn("Reflect", "ownKeys") || function ownKeys3(it) {
      var keys = getOwnPropertyNamesModule.f(anObject(it));
      var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
      return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/copy-constructor-properties.js
var require_copy_constructor_properties = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/copy-constructor-properties.js"(exports, module) {
    "use strict";
    var hasOwn = require_has_own_property();
    var ownKeys3 = require_own_keys();
    var getOwnPropertyDescriptorModule = require_object_get_own_property_descriptor();
    var definePropertyModule = require_object_define_property();
    module.exports = function(target, source, exceptions) {
      var keys = ownKeys3(source);
      var defineProperty = definePropertyModule.f;
      var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
      for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {
          defineProperty(target, key, getOwnPropertyDescriptor(source, key));
        }
      }
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-forced.js
var require_is_forced = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-forced.js"(exports, module) {
    "use strict";
    var fails = require_fails();
    var isCallable = require_is_callable();
    var replacement = /#|\.prototype\./;
    var isForced = function(feature, detection) {
      var value = data[normalize(feature)];
      return value === POLYFILL ? true : value === NATIVE ? false : isCallable(detection) ? fails(detection) : !!detection;
    };
    var normalize = isForced.normalize = function(string2) {
      return String(string2).replace(replacement, ".").toLowerCase();
    };
    var data = isForced.data = {};
    var NATIVE = isForced.NATIVE = "N";
    var POLYFILL = isForced.POLYFILL = "P";
    module.exports = isForced;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/export.js
var require_export = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/export.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var getOwnPropertyDescriptor = require_object_get_own_property_descriptor().f;
    var createNonEnumerableProperty = require_create_non_enumerable_property();
    var defineBuiltIn = require_define_built_in();
    var defineGlobalProperty = require_define_global_property();
    var copyConstructorProperties = require_copy_constructor_properties();
    var isForced = require_is_forced();
    module.exports = function(options, source) {
      var TARGET = options.target;
      var GLOBAL = options.global;
      var STATIC = options.stat;
      var FORCED, target, key, targetProperty, sourceProperty, descriptor;
      if (GLOBAL) {
        target = globalThis2;
      } else if (STATIC) {
        target = globalThis2[TARGET] || defineGlobalProperty(TARGET, {});
      } else {
        target = globalThis2[TARGET] && globalThis2[TARGET].prototype;
      }
      if (target)
        for (key in source) {
          sourceProperty = source[key];
          if (options.dontCallGetSet) {
            descriptor = getOwnPropertyDescriptor(target, key);
            targetProperty = descriptor && descriptor.value;
          } else
            targetProperty = target[key];
          FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced);
          if (!FORCED && targetProperty !== void 0) {
            if (typeof sourceProperty == typeof targetProperty)
              continue;
            copyConstructorProperties(sourceProperty, targetProperty);
          }
          if (options.sham || targetProperty && targetProperty.sham) {
            createNonEnumerableProperty(sourceProperty, "sham", true);
          }
          defineBuiltIn(target, key, sourceProperty, options);
        }
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-keys.js
var require_object_keys = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-keys.js"(exports, module) {
    "use strict";
    var internalObjectKeys = require_object_keys_internal();
    var enumBugKeys = require_enum_bug_keys();
    module.exports = Object.keys || function keys(O) {
      return internalObjectKeys(O, enumBugKeys);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-define-properties.js
var require_object_define_properties = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-define-properties.js"(exports) {
    "use strict";
    var DESCRIPTORS = require_descriptors();
    var V8_PROTOTYPE_DEFINE_BUG = require_v8_prototype_define_bug();
    var definePropertyModule = require_object_define_property();
    var anObject = require_an_object();
    var toIndexedObject = require_to_indexed_object();
    var objectKeys = require_object_keys();
    exports.f = DESCRIPTORS && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O, Properties) {
      anObject(O);
      var props = toIndexedObject(Properties);
      var keys = objectKeys(Properties);
      var length = keys.length;
      var index2 = 0;
      var key;
      while (length > index2)
        definePropertyModule.f(O, key = keys[index2++], props[key]);
      return O;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/html.js
var require_html = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/html.js"(exports, module) {
    "use strict";
    var getBuiltIn = require_get_built_in();
    module.exports = getBuiltIn("document", "documentElement");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-create.js
var require_object_create = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/object-create.js"(exports, module) {
    "use strict";
    var anObject = require_an_object();
    var definePropertiesModule = require_object_define_properties();
    var enumBugKeys = require_enum_bug_keys();
    var hiddenKeys = require_hidden_keys();
    var html = require_html();
    var documentCreateElement = require_document_create_element();
    var sharedKey = require_shared_key();
    var GT = ">";
    var LT = "<";
    var PROTOTYPE = "prototype";
    var SCRIPT = "script";
    var IE_PROTO = sharedKey("IE_PROTO");
    var EmptyConstructor = function() {
    };
    var scriptTag = function(content) {
      return LT + SCRIPT + GT + content + LT + "/" + SCRIPT + GT;
    };
    var NullProtoObjectViaActiveX = function(activeXDocument2) {
      activeXDocument2.write(scriptTag(""));
      activeXDocument2.close();
      var temp = activeXDocument2.parentWindow.Object;
      activeXDocument2 = null;
      return temp;
    };
    var NullProtoObjectViaIFrame = function() {
      var iframe = documentCreateElement("iframe");
      var JS = "java" + SCRIPT + ":";
      var iframeDocument;
      iframe.style.display = "none";
      html.appendChild(iframe);
      iframe.src = String(JS);
      iframeDocument = iframe.contentWindow.document;
      iframeDocument.open();
      iframeDocument.write(scriptTag("document.F=Object"));
      iframeDocument.close();
      return iframeDocument.F;
    };
    var activeXDocument;
    var NullProtoObject = function() {
      try {
        activeXDocument = new ActiveXObject("htmlfile");
      } catch (error) {
      }
      NullProtoObject = typeof document != "undefined" ? document.domain && activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame() : NullProtoObjectViaActiveX(activeXDocument);
      var length = enumBugKeys.length;
      while (length--)
        delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
      return NullProtoObject();
    };
    hiddenKeys[IE_PROTO] = true;
    module.exports = Object.create || function create(O, Properties) {
      var result;
      if (O !== null) {
        EmptyConstructor[PROTOTYPE] = anObject(O);
        result = new EmptyConstructor();
        EmptyConstructor[PROTOTYPE] = null;
        result[IE_PROTO] = O;
      } else
        result = NullProtoObject();
      return Properties === void 0 ? result : definePropertiesModule.f(result, Properties);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/add-to-unscopables.js
var require_add_to_unscopables = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/add-to-unscopables.js"(exports, module) {
    "use strict";
    var wellKnownSymbol = require_well_known_symbol();
    var create = require_object_create();
    var defineProperty = require_object_define_property().f;
    var UNSCOPABLES = wellKnownSymbol("unscopables");
    var ArrayPrototype = Array.prototype;
    if (ArrayPrototype[UNSCOPABLES] === void 0) {
      defineProperty(ArrayPrototype, UNSCOPABLES, {
        configurable: true,
        value: create(null)
      });
    }
    module.exports = function(key) {
      ArrayPrototype[UNSCOPABLES][key] = true;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.at.js
var require_es_array_at = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.at.js"() {
    "use strict";
    var $ = require_export();
    var toObject = require_to_object();
    var lengthOfArrayLike = require_length_of_array_like();
    var toIntegerOrInfinity = require_to_integer_or_infinity();
    var addToUnscopables = require_add_to_unscopables();
    $({ target: "Array", proto: true }, {
      at: function at(index2) {
        var O = toObject(this);
        var len = lengthOfArrayLike(O);
        var relativeIndex = toIntegerOrInfinity(index2);
        var k = relativeIndex >= 0 ? relativeIndex : len + relativeIndex;
        return k < 0 || k >= len ? void 0 : O[k];
      }
    });
    addToUnscopables("at");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/entry-unbind.js
var require_entry_unbind = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/entry-unbind.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var uncurryThis = require_function_uncurry_this();
    module.exports = function(CONSTRUCTOR, METHOD) {
      return uncurryThis(globalThis2[CONSTRUCTOR].prototype[METHOD]);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/array/at.js
var require_at = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/array/at.js"(exports, module) {
    "use strict";
    require_es_array_at();
    var entryUnbind = require_entry_unbind();
    module.exports = entryUnbind("Array", "at");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/array/at.js
var require_at2 = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/array/at.js"(exports, module) {
    "use strict";
    var parent = require_at();
    module.exports = parent;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-array.js
var require_is_array = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-array.js"(exports, module) {
    "use strict";
    var classof = require_classof_raw();
    module.exports = Array.isArray || function isArray(argument) {
      return classof(argument) === "Array";
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/does-not-exceed-safe-integer.js
var require_does_not_exceed_safe_integer = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/does-not-exceed-safe-integer.js"(exports, module) {
    "use strict";
    var $TypeError = TypeError;
    var MAX_SAFE_INTEGER = 9007199254740991;
    module.exports = function(it) {
      if (it > MAX_SAFE_INTEGER)
        throw $TypeError("Maximum allowed index exceeded");
      return it;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-uncurry-this-clause.js
var require_function_uncurry_this_clause = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-uncurry-this-clause.js"(exports, module) {
    "use strict";
    var classofRaw = require_classof_raw();
    var uncurryThis = require_function_uncurry_this();
    module.exports = function(fn) {
      if (classofRaw(fn) === "Function")
        return uncurryThis(fn);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-bind-context.js
var require_function_bind_context = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-bind-context.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this_clause();
    var aCallable = require_a_callable();
    var NATIVE_BIND = require_function_bind_native();
    var bind = uncurryThis(uncurryThis.bind);
    module.exports = function(fn, that) {
      aCallable(fn);
      return that === void 0 ? fn : NATIVE_BIND ? bind(fn, that) : function() {
        return fn.apply(that, arguments);
      };
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/flatten-into-array.js
var require_flatten_into_array = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/flatten-into-array.js"(exports, module) {
    "use strict";
    var isArray = require_is_array();
    var lengthOfArrayLike = require_length_of_array_like();
    var doesNotExceedSafeInteger = require_does_not_exceed_safe_integer();
    var bind = require_function_bind_context();
    var flattenIntoArray = function(target, original, source, sourceLen, start, depth, mapper, thisArg) {
      var targetIndex = start;
      var sourceIndex = 0;
      var mapFn = mapper ? bind(mapper, thisArg) : false;
      var element, elementLen;
      while (sourceIndex < sourceLen) {
        if (sourceIndex in source) {
          element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
          if (depth > 0 && isArray(element)) {
            elementLen = lengthOfArrayLike(element);
            targetIndex = flattenIntoArray(target, original, element, elementLen, targetIndex, depth - 1) - 1;
          } else {
            doesNotExceedSafeInteger(targetIndex + 1);
            target[targetIndex] = element;
          }
          targetIndex++;
        }
        sourceIndex++;
      }
      return targetIndex;
    };
    module.exports = flattenIntoArray;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-string-tag-support.js
var require_to_string_tag_support = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-string-tag-support.js"(exports, module) {
    "use strict";
    var wellKnownSymbol = require_well_known_symbol();
    var TO_STRING_TAG = wellKnownSymbol("toStringTag");
    var test2 = {};
    test2[TO_STRING_TAG] = "z";
    module.exports = String(test2) === "[object z]";
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/classof.js
var require_classof = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/classof.js"(exports, module) {
    "use strict";
    var TO_STRING_TAG_SUPPORT = require_to_string_tag_support();
    var isCallable = require_is_callable();
    var classofRaw = require_classof_raw();
    var wellKnownSymbol = require_well_known_symbol();
    var TO_STRING_TAG = wellKnownSymbol("toStringTag");
    var $Object = Object;
    var CORRECT_ARGUMENTS = classofRaw(function() {
      return arguments;
    }()) === "Arguments";
    var tryGet = function(it, key) {
      try {
        return it[key];
      } catch (error) {
      }
    };
    module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) {
      var O, tag, result;
      return it === void 0 ? "Undefined" : it === null ? "Null" : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == "string" ? tag : CORRECT_ARGUMENTS ? classofRaw(O) : (result = classofRaw(O)) === "Object" && isCallable(O.callee) ? "Arguments" : result;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-constructor.js
var require_is_constructor = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-constructor.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var fails = require_fails();
    var isCallable = require_is_callable();
    var classof = require_classof();
    var getBuiltIn = require_get_built_in();
    var inspectSource = require_inspect_source();
    var noop4 = function() {
    };
    var construct = getBuiltIn("Reflect", "construct");
    var constructorRegExp = /^\s*(?:class|function)\b/;
    var exec = uncurryThis(constructorRegExp.exec);
    var INCORRECT_TO_STRING = !constructorRegExp.test(noop4);
    var isConstructorModern = function isConstructor(argument) {
      if (!isCallable(argument))
        return false;
      try {
        construct(noop4, [], argument);
        return true;
      } catch (error) {
        return false;
      }
    };
    var isConstructorLegacy = function isConstructor(argument) {
      if (!isCallable(argument))
        return false;
      switch (classof(argument)) {
        case "AsyncFunction":
        case "GeneratorFunction":
        case "AsyncGeneratorFunction":
          return false;
      }
      try {
        return INCORRECT_TO_STRING || !!exec(constructorRegExp, inspectSource(argument));
      } catch (error) {
        return true;
      }
    };
    isConstructorLegacy.sham = true;
    module.exports = !construct || fails(function() {
      var called;
      return isConstructorModern(isConstructorModern.call) || !isConstructorModern(Object) || !isConstructorModern(function() {
        called = true;
      }) || called;
    }) ? isConstructorLegacy : isConstructorModern;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/array-species-constructor.js
var require_array_species_constructor = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/array-species-constructor.js"(exports, module) {
    "use strict";
    var isArray = require_is_array();
    var isConstructor = require_is_constructor();
    var isObject = require_is_object();
    var wellKnownSymbol = require_well_known_symbol();
    var SPECIES = wellKnownSymbol("species");
    var $Array = Array;
    module.exports = function(originalArray) {
      var C;
      if (isArray(originalArray)) {
        C = originalArray.constructor;
        if (isConstructor(C) && (C === $Array || isArray(C.prototype)))
          C = void 0;
        else if (isObject(C)) {
          C = C[SPECIES];
          if (C === null)
            C = void 0;
        }
      }
      return C === void 0 ? $Array : C;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/array-species-create.js
var require_array_species_create = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/array-species-create.js"(exports, module) {
    "use strict";
    var arraySpeciesConstructor = require_array_species_constructor();
    module.exports = function(originalArray, length) {
      return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.flat.js
var require_es_array_flat = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.flat.js"() {
    "use strict";
    var $ = require_export();
    var flattenIntoArray = require_flatten_into_array();
    var toObject = require_to_object();
    var lengthOfArrayLike = require_length_of_array_like();
    var toIntegerOrInfinity = require_to_integer_or_infinity();
    var arraySpeciesCreate = require_array_species_create();
    $({ target: "Array", proto: true }, {
      flat: function flat() {
        var depthArg = arguments.length ? arguments[0] : void 0;
        var O = toObject(this);
        var sourceLen = lengthOfArrayLike(O);
        var A = arraySpeciesCreate(O, 0);
        A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === void 0 ? 1 : toIntegerOrInfinity(depthArg));
        return A;
      }
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.unscopables.flat.js
var require_es_array_unscopables_flat = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.unscopables.flat.js"() {
    "use strict";
    var addToUnscopables = require_add_to_unscopables();
    addToUnscopables("flat");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/array/flat.js
var require_flat = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/array/flat.js"(exports, module) {
    "use strict";
    require_es_array_flat();
    require_es_array_unscopables_flat();
    var entryUnbind = require_entry_unbind();
    module.exports = entryUnbind("Array", "flat");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/array/flat.js
var require_flat2 = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/array/flat.js"(exports, module) {
    "use strict";
    var parent = require_flat();
    module.exports = parent;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.flat-map.js
var require_es_array_flat_map = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.flat-map.js"() {
    "use strict";
    var $ = require_export();
    var flattenIntoArray = require_flatten_into_array();
    var aCallable = require_a_callable();
    var toObject = require_to_object();
    var lengthOfArrayLike = require_length_of_array_like();
    var arraySpeciesCreate = require_array_species_create();
    $({ target: "Array", proto: true }, {
      flatMap: function flatMap(callbackfn) {
        var O = toObject(this);
        var sourceLen = lengthOfArrayLike(O);
        var A;
        aCallable(callbackfn);
        A = arraySpeciesCreate(O, 0);
        A.length = flattenIntoArray(A, O, O, sourceLen, 0, 1, callbackfn, arguments.length > 1 ? arguments[1] : void 0);
        return A;
      }
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.unscopables.flat-map.js
var require_es_array_unscopables_flat_map = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.array.unscopables.flat-map.js"() {
    "use strict";
    var addToUnscopables = require_add_to_unscopables();
    addToUnscopables("flatMap");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/array/flat-map.js
var require_flat_map = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/array/flat-map.js"(exports, module) {
    "use strict";
    require_es_array_flat_map();
    require_es_array_unscopables_flat_map();
    var entryUnbind = require_entry_unbind();
    module.exports = entryUnbind("Array", "flatMap");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/array/flat-map.js
var require_flat_map2 = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/array/flat-map.js"(exports, module) {
    "use strict";
    var parent = require_flat_map();
    module.exports = parent;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-string.js
var require_to_string = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/to-string.js"(exports, module) {
    "use strict";
    var classof = require_classof();
    var $String = String;
    module.exports = function(argument) {
      if (classof(argument) === "Symbol")
        throw new TypeError("Cannot convert a Symbol value to a string");
      return $String(argument);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.string.at-alternative.js
var require_es_string_at_alternative = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.string.at-alternative.js"() {
    "use strict";
    var $ = require_export();
    var uncurryThis = require_function_uncurry_this();
    var requireObjectCoercible = require_require_object_coercible();
    var toIntegerOrInfinity = require_to_integer_or_infinity();
    var toString = require_to_string();
    var fails = require_fails();
    var charAt = uncurryThis("".charAt);
    var FORCED = fails(function() {
      return "𠮷".at(-2) !== "\uD842";
    });
    $({ target: "String", proto: true, forced: FORCED }, {
      at: function at(index2) {
        var S = toString(requireObjectCoercible(this));
        var len = S.length;
        var relativeIndex = toIntegerOrInfinity(index2);
        var k = relativeIndex >= 0 ? relativeIndex : len + relativeIndex;
        return k < 0 || k >= len ? void 0 : charAt(S, k);
      }
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/string/at.js
var require_at3 = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/string/at.js"(exports, module) {
    "use strict";
    require_es_string_at_alternative();
    var entryUnbind = require_entry_unbind();
    module.exports = entryUnbind("String", "at");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/string/at.js
var require_at4 = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/string/at.js"(exports, module) {
    "use strict";
    var parent = require_at3();
    module.exports = parent;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-flags.js
var require_regexp_flags = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-flags.js"(exports, module) {
    "use strict";
    var anObject = require_an_object();
    module.exports = function() {
      var that = anObject(this);
      var result = "";
      if (that.hasIndices)
        result += "d";
      if (that.global)
        result += "g";
      if (that.ignoreCase)
        result += "i";
      if (that.multiline)
        result += "m";
      if (that.dotAll)
        result += "s";
      if (that.unicode)
        result += "u";
      if (that.unicodeSets)
        result += "v";
      if (that.sticky)
        result += "y";
      return result;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-sticky-helpers.js
var require_regexp_sticky_helpers = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-sticky-helpers.js"(exports, module) {
    "use strict";
    var fails = require_fails();
    var globalThis2 = require_global_this();
    var $RegExp = globalThis2.RegExp;
    var UNSUPPORTED_Y = fails(function() {
      var re = $RegExp("a", "y");
      re.lastIndex = 2;
      return re.exec("abcd") !== null;
    });
    var MISSED_STICKY = UNSUPPORTED_Y || fails(function() {
      return !$RegExp("a", "y").sticky;
    });
    var BROKEN_CARET = UNSUPPORTED_Y || fails(function() {
      var re = $RegExp("^r", "gy");
      re.lastIndex = 2;
      return re.exec("str") !== null;
    });
    module.exports = {
      BROKEN_CARET,
      MISSED_STICKY,
      UNSUPPORTED_Y
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-unsupported-dot-all.js
var require_regexp_unsupported_dot_all = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-unsupported-dot-all.js"(exports, module) {
    "use strict";
    var fails = require_fails();
    var globalThis2 = require_global_this();
    var $RegExp = globalThis2.RegExp;
    module.exports = fails(function() {
      var re = $RegExp(".", "s");
      return !(re.dotAll && re.test("\n") && re.flags === "s");
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-unsupported-ncg.js
var require_regexp_unsupported_ncg = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-unsupported-ncg.js"(exports, module) {
    "use strict";
    var fails = require_fails();
    var globalThis2 = require_global_this();
    var $RegExp = globalThis2.RegExp;
    module.exports = fails(function() {
      var re = $RegExp("(?<a>b)", "g");
      return re.exec("b").groups.a !== "b" || "b".replace(re, "$<a>c") !== "bc";
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-exec.js
var require_regexp_exec = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-exec.js"(exports, module) {
    "use strict";
    var call2 = require_function_call();
    var uncurryThis = require_function_uncurry_this();
    var toString = require_to_string();
    var regexpFlags = require_regexp_flags();
    var stickyHelpers = require_regexp_sticky_helpers();
    var shared = require_shared();
    var create = require_object_create();
    var getInternalState = require_internal_state().get;
    var UNSUPPORTED_DOT_ALL = require_regexp_unsupported_dot_all();
    var UNSUPPORTED_NCG = require_regexp_unsupported_ncg();
    var nativeReplace = shared("native-string-replace", String.prototype.replace);
    var nativeExec = RegExp.prototype.exec;
    var patchedExec = nativeExec;
    var charAt = uncurryThis("".charAt);
    var indexOf = uncurryThis("".indexOf);
    var replace = uncurryThis("".replace);
    var stringSlice = uncurryThis("".slice);
    var UPDATES_LAST_INDEX_WRONG = function() {
      var re1 = /a/;
      var re2 = /b*/g;
      call2(nativeExec, re1, "a");
      call2(nativeExec, re2, "a");
      return re1.lastIndex !== 0 || re2.lastIndex !== 0;
    }();
    var UNSUPPORTED_Y = stickyHelpers.BROKEN_CARET;
    var NPCG_INCLUDED = /()??/.exec("")[1] !== void 0;
    var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG;
    if (PATCH) {
      patchedExec = function exec(string2) {
        var re = this;
        var state = getInternalState(re);
        var str = toString(string2);
        var raw = state.raw;
        var result, reCopy, lastIndex, match, i, object2, group;
        if (raw) {
          raw.lastIndex = re.lastIndex;
          result = call2(patchedExec, raw, str);
          re.lastIndex = raw.lastIndex;
          return result;
        }
        var groups = state.groups;
        var sticky = UNSUPPORTED_Y && re.sticky;
        var flags = call2(regexpFlags, re);
        var source = re.source;
        var charsAdded = 0;
        var strCopy = str;
        if (sticky) {
          flags = replace(flags, "y", "");
          if (indexOf(flags, "g") === -1) {
            flags += "g";
          }
          strCopy = stringSlice(str, re.lastIndex);
          if (re.lastIndex > 0 && (!re.multiline || re.multiline && charAt(str, re.lastIndex - 1) !== "\n")) {
            source = "(?: " + source + ")";
            strCopy = " " + strCopy;
            charsAdded++;
          }
          reCopy = new RegExp("^(?:" + source + ")", flags);
        }
        if (NPCG_INCLUDED) {
          reCopy = new RegExp("^" + source + "$(?!\\s)", flags);
        }
        if (UPDATES_LAST_INDEX_WRONG)
          lastIndex = re.lastIndex;
        match = call2(nativeExec, sticky ? reCopy : re, strCopy);
        if (sticky) {
          if (match) {
            match.input = stringSlice(match.input, charsAdded);
            match[0] = stringSlice(match[0], charsAdded);
            match.index = re.lastIndex;
            re.lastIndex += match[0].length;
          } else
            re.lastIndex = 0;
        } else if (UPDATES_LAST_INDEX_WRONG && match) {
          re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
        }
        if (NPCG_INCLUDED && match && match.length > 1) {
          call2(nativeReplace, match[0], reCopy, function() {
            for (i = 1; i < arguments.length - 2; i++) {
              if (arguments[i] === void 0)
                match[i] = void 0;
            }
          });
        }
        if (match && groups) {
          match.groups = object2 = create(null);
          for (i = 0; i < groups.length; i++) {
            group = groups[i];
            object2[group[0]] = match[group[1]];
          }
        }
        return match;
      };
    }
    module.exports = patchedExec;
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.regexp.exec.js
var require_es_regexp_exec = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.regexp.exec.js"() {
    "use strict";
    var $ = require_export();
    var exec = require_regexp_exec();
    $({ target: "RegExp", proto: true, forced: /./.exec !== exec }, {
      exec
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-apply.js
var require_function_apply = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/function-apply.js"(exports, module) {
    "use strict";
    var NATIVE_BIND = require_function_bind_native();
    var FunctionPrototype = Function.prototype;
    var apply = FunctionPrototype.apply;
    var call2 = FunctionPrototype.call;
    module.exports = typeof Reflect == "object" && Reflect.apply || (NATIVE_BIND ? call2.bind(apply) : function() {
      return call2.apply(apply, arguments);
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js
var require_fix_regexp_well_known_symbol_logic = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js"(exports, module) {
    "use strict";
    require_es_regexp_exec();
    var call2 = require_function_call();
    var defineBuiltIn = require_define_built_in();
    var regexpExec = require_regexp_exec();
    var fails = require_fails();
    var wellKnownSymbol = require_well_known_symbol();
    var createNonEnumerableProperty = require_create_non_enumerable_property();
    var SPECIES = wellKnownSymbol("species");
    var RegExpPrototype = RegExp.prototype;
    module.exports = function(KEY, exec, FORCED, SHAM) {
      var SYMBOL = wellKnownSymbol(KEY);
      var DELEGATES_TO_SYMBOL = !fails(function() {
        var O = {};
        O[SYMBOL] = function() {
          return 7;
        };
        return ""[KEY](O) !== 7;
      });
      var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function() {
        var execCalled = false;
        var re = /a/;
        if (KEY === "split") {
          re = {};
          re.constructor = {};
          re.constructor[SPECIES] = function() {
            return re;
          };
          re.flags = "";
          re[SYMBOL] = /./[SYMBOL];
        }
        re.exec = function() {
          execCalled = true;
          return null;
        };
        re[SYMBOL]("");
        return !execCalled;
      });
      if (!DELEGATES_TO_SYMBOL || !DELEGATES_TO_EXEC || FORCED) {
        var nativeRegExpMethod = /./[SYMBOL];
        var methods = exec(SYMBOL, ""[KEY], function(nativeMethod, regexp, str, arg2, forceStringMethod) {
          var $exec = regexp.exec;
          if ($exec === regexpExec || $exec === RegExpPrototype.exec) {
            if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
              return { done: true, value: call2(nativeRegExpMethod, regexp, str, arg2) };
            }
            return { done: true, value: call2(nativeMethod, str, regexp, arg2) };
          }
          return { done: false };
        });
        defineBuiltIn(String.prototype, KEY, methods[0]);
        defineBuiltIn(RegExpPrototype, SYMBOL, methods[1]);
      }
      if (SHAM)
        createNonEnumerableProperty(RegExpPrototype[SYMBOL], "sham", true);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/string-multibyte.js
var require_string_multibyte = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/string-multibyte.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var toIntegerOrInfinity = require_to_integer_or_infinity();
    var toString = require_to_string();
    var requireObjectCoercible = require_require_object_coercible();
    var charAt = uncurryThis("".charAt);
    var charCodeAt = uncurryThis("".charCodeAt);
    var stringSlice = uncurryThis("".slice);
    var createMethod = function(CONVERT_TO_STRING) {
      return function($this, pos) {
        var S = toString(requireObjectCoercible($this));
        var position = toIntegerOrInfinity(pos);
        var size2 = S.length;
        var first, second;
        if (position < 0 || position >= size2)
          return CONVERT_TO_STRING ? "" : void 0;
        first = charCodeAt(S, position);
        return first < 55296 || first > 56319 || position + 1 === size2 || (second = charCodeAt(S, position + 1)) < 56320 || second > 57343 ? CONVERT_TO_STRING ? charAt(S, position) : first : CONVERT_TO_STRING ? stringSlice(S, position, position + 2) : (first - 55296 << 10) + (second - 56320) + 65536;
      };
    };
    module.exports = {
      // `String.prototype.codePointAt` method
      // https://tc39.es/ecma262/#sec-string.prototype.codepointat
      codeAt: createMethod(false),
      // `String.prototype.at` method
      // https://github.com/mathiasbynens/String.prototype.at
      charAt: createMethod(true)
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/advance-string-index.js
var require_advance_string_index = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/advance-string-index.js"(exports, module) {
    "use strict";
    var charAt = require_string_multibyte().charAt;
    module.exports = function(S, index2, unicode) {
      return index2 + (unicode ? charAt(S, index2).length : 1);
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/get-substitution.js
var require_get_substitution = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/get-substitution.js"(exports, module) {
    "use strict";
    var uncurryThis = require_function_uncurry_this();
    var toObject = require_to_object();
    var floor = Math.floor;
    var charAt = uncurryThis("".charAt);
    var replace = uncurryThis("".replace);
    var stringSlice = uncurryThis("".slice);
    var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g;
    var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g;
    module.exports = function(matched, str, position, captures, namedCaptures, replacement) {
      var tailPos = position + matched.length;
      var m = captures.length;
      var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
      if (namedCaptures !== void 0) {
        namedCaptures = toObject(namedCaptures);
        symbols = SUBSTITUTION_SYMBOLS;
      }
      return replace(replacement, symbols, function(match, ch) {
        var capture;
        switch (charAt(ch, 0)) {
          case "$":
            return "$";
          case "&":
            return matched;
          case "`":
            return stringSlice(str, 0, position);
          case "'":
            return stringSlice(str, tailPos);
          case "<":
            capture = namedCaptures[stringSlice(ch, 1, -1)];
            break;
          default:
            var n = +ch;
            if (n === 0)
              return match;
            if (n > m) {
              var f = floor(n / 10);
              if (f === 0)
                return match;
              if (f <= m)
                return captures[f - 1] === void 0 ? charAt(ch, 1) : captures[f - 1] + charAt(ch, 1);
              return match;
            }
            capture = captures[n - 1];
        }
        return capture === void 0 ? "" : capture;
      });
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-flags-detection.js
var require_regexp_flags_detection = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-flags-detection.js"(exports, module) {
    "use strict";
    var globalThis2 = require_global_this();
    var fails = require_fails();
    var RegExp2 = globalThis2.RegExp;
    var FLAGS_GETTER_IS_CORRECT = !fails(function() {
      var INDICES_SUPPORT = true;
      try {
        RegExp2(".", "d");
      } catch (error) {
        INDICES_SUPPORT = false;
      }
      var O = {};
      var calls = "";
      var expected = INDICES_SUPPORT ? "dgimsy" : "gimsy";
      var addGetter = function(key2, chr) {
        Object.defineProperty(O, key2, { get: function() {
          calls += chr;
          return true;
        } });
      };
      var pairs = {
        dotAll: "s",
        global: "g",
        ignoreCase: "i",
        multiline: "m",
        sticky: "y"
      };
      if (INDICES_SUPPORT)
        pairs.hasIndices = "d";
      for (var key in pairs)
        addGetter(key, pairs[key]);
      var result = Object.getOwnPropertyDescriptor(RegExp2.prototype, "flags").get.call(O);
      return result !== expected || calls !== expected;
    });
    module.exports = { correct: FLAGS_GETTER_IS_CORRECT };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-get-flags.js
var require_regexp_get_flags = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-get-flags.js"(exports, module) {
    "use strict";
    var call2 = require_function_call();
    var hasOwn = require_has_own_property();
    var isPrototypeOf = require_object_is_prototype_of();
    var regExpFlagsDetection = require_regexp_flags_detection();
    var regExpFlagsGetterImplementation = require_regexp_flags();
    var RegExpPrototype = RegExp.prototype;
    module.exports = regExpFlagsDetection.correct ? function(it) {
      return it.flags;
    } : function(it) {
      return !regExpFlagsDetection.correct && isPrototypeOf(RegExpPrototype, it) && !hasOwn(it, "flags") ? call2(regExpFlagsGetterImplementation, it) : it.flags;
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-exec-abstract.js
var require_regexp_exec_abstract = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/regexp-exec-abstract.js"(exports, module) {
    "use strict";
    var call2 = require_function_call();
    var anObject = require_an_object();
    var isCallable = require_is_callable();
    var classof = require_classof_raw();
    var regexpExec = require_regexp_exec();
    var $TypeError = TypeError;
    module.exports = function(R, S) {
      var exec = R.exec;
      if (isCallable(exec)) {
        var result = call2(exec, R, S);
        if (result !== null)
          anObject(result);
        return result;
      }
      if (classof(R) === "RegExp")
        return call2(regexpExec, R, S);
      throw new $TypeError("RegExp#exec called on incompatible receiver");
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.string.replace.js
var require_es_string_replace = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.string.replace.js"() {
    "use strict";
    var apply = require_function_apply();
    var call2 = require_function_call();
    var uncurryThis = require_function_uncurry_this();
    var fixRegExpWellKnownSymbolLogic = require_fix_regexp_well_known_symbol_logic();
    var fails = require_fails();
    var anObject = require_an_object();
    var isCallable = require_is_callable();
    var isObject = require_is_object();
    var toIntegerOrInfinity = require_to_integer_or_infinity();
    var toLength = require_to_length();
    var toString = require_to_string();
    var requireObjectCoercible = require_require_object_coercible();
    var advanceStringIndex = require_advance_string_index();
    var getMethod2 = require_get_method();
    var getSubstitution = require_get_substitution();
    var getRegExpFlags = require_regexp_get_flags();
    var regExpExec = require_regexp_exec_abstract();
    var wellKnownSymbol = require_well_known_symbol();
    var REPLACE = wellKnownSymbol("replace");
    var max3 = Math.max;
    var min4 = Math.min;
    var concat = uncurryThis([].concat);
    var push = uncurryThis([].push);
    var stringIndexOf = uncurryThis("".indexOf);
    var stringSlice = uncurryThis("".slice);
    var maybeToString = function(it) {
      return it === void 0 ? it : String(it);
    };
    var REPLACE_KEEPS_$0 = function() {
      return "a".replace(/./, "$0") === "$0";
    }();
    var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = function() {
      if (/./[REPLACE]) {
        return /./[REPLACE]("a", "$0") === "";
      }
      return false;
    }();
    var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function() {
      var re = /./;
      re.exec = function() {
        var result = [];
        result.groups = { a: "7" };
        return result;
      };
      return "".replace(re, "$<a>") !== "7";
    });
    fixRegExpWellKnownSymbolLogic("replace", function(_, nativeReplace, maybeCallNative) {
      var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? "$" : "$0";
      return [
        // `String.prototype.replace` method
        // https://tc39.es/ecma262/#sec-string.prototype.replace
        function replace(searchValue, replaceValue) {
          var O = requireObjectCoercible(this);
          var replacer = isObject(searchValue) ? getMethod2(searchValue, REPLACE) : void 0;
          return replacer ? call2(replacer, searchValue, O, replaceValue) : call2(nativeReplace, toString(O), searchValue, replaceValue);
        },
        // `RegExp.prototype[@@replace]` method
        // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace
        function(string2, replaceValue) {
          var rx = anObject(this);
          var S = toString(string2);
          if (typeof replaceValue == "string" && stringIndexOf(replaceValue, UNSAFE_SUBSTITUTE) === -1 && stringIndexOf(replaceValue, "$<") === -1) {
            var res = maybeCallNative(nativeReplace, rx, S, replaceValue);
            if (res.done)
              return res.value;
          }
          var functionalReplace = isCallable(replaceValue);
          if (!functionalReplace)
            replaceValue = toString(replaceValue);
          var flags = toString(getRegExpFlags(rx));
          var global2 = stringIndexOf(flags, "g") !== -1;
          var fullUnicode;
          if (global2) {
            fullUnicode = stringIndexOf(flags, "u") !== -1;
            rx.lastIndex = 0;
          }
          var results = [];
          var result;
          while (true) {
            result = regExpExec(rx, S);
            if (result === null)
              break;
            push(results, result);
            if (!global2)
              break;
            var matchStr = toString(result[0]);
            if (matchStr === "")
              rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
          }
          var accumulatedResult = "";
          var nextSourcePosition = 0;
          for (var i = 0; i < results.length; i++) {
            result = results[i];
            var matched = toString(result[0]);
            var position = max3(min4(toIntegerOrInfinity(result.index), S.length), 0);
            var captures = [];
            var replacement;
            for (var j = 1; j < result.length; j++)
              push(captures, maybeToString(result[j]));
            var namedCaptures = result.groups;
            if (functionalReplace) {
              var replacerArgs = concat([matched], captures, position, S);
              if (namedCaptures !== void 0)
                push(replacerArgs, namedCaptures);
              replacement = toString(apply(replaceValue, void 0, replacerArgs));
            } else {
              replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
            }
            if (position >= nextSourcePosition) {
              accumulatedResult += stringSlice(S, nextSourcePosition, position) + replacement;
              nextSourcePosition = position + matched.length;
            }
          }
          return accumulatedResult + stringSlice(S, nextSourcePosition);
        }
      ];
    }, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE);
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-regexp.js
var require_is_regexp = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/internals/is-regexp.js"(exports, module) {
    "use strict";
    var isObject = require_is_object();
    var classof = require_classof_raw();
    var wellKnownSymbol = require_well_known_symbol();
    var MATCH = wellKnownSymbol("match");
    module.exports = function(it) {
      var isRegExp;
      return isObject(it) && ((isRegExp = it[MATCH]) !== void 0 ? !!isRegExp : classof(it) === "RegExp");
    };
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.string.replace-all.js
var require_es_string_replace_all = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/modules/es.string.replace-all.js"() {
    "use strict";
    var $ = require_export();
    var call2 = require_function_call();
    var uncurryThis = require_function_uncurry_this();
    var requireObjectCoercible = require_require_object_coercible();
    var isCallable = require_is_callable();
    var isObject = require_is_object();
    var isRegExp = require_is_regexp();
    var toString = require_to_string();
    var getMethod2 = require_get_method();
    var getRegExpFlags = require_regexp_get_flags();
    var getSubstitution = require_get_substitution();
    var wellKnownSymbol = require_well_known_symbol();
    var IS_PURE = require_is_pure();
    var REPLACE = wellKnownSymbol("replace");
    var $TypeError = TypeError;
    var indexOf = uncurryThis("".indexOf);
    var replace = uncurryThis("".replace);
    var stringSlice = uncurryThis("".slice);
    var max3 = Math.max;
    $({ target: "String", proto: true }, {
      replaceAll: function replaceAll(searchValue, replaceValue) {
        var O = requireObjectCoercible(this);
        var IS_REG_EXP, flags, replacer, string2, searchString, functionalReplace, searchLength, advanceBy, position, replacement;
        var endOfLastMatch = 0;
        var result = "";
        if (isObject(searchValue)) {
          IS_REG_EXP = isRegExp(searchValue);
          if (IS_REG_EXP) {
            flags = toString(requireObjectCoercible(getRegExpFlags(searchValue)));
            if (!~indexOf(flags, "g"))
              throw new $TypeError("`.replaceAll` does not allow non-global regexes");
          }
          replacer = getMethod2(searchValue, REPLACE);
          if (replacer)
            return call2(replacer, searchValue, O, replaceValue);
          if (IS_PURE && IS_REG_EXP)
            return replace(toString(O), searchValue, replaceValue);
        }
        string2 = toString(O);
        searchString = toString(searchValue);
        functionalReplace = isCallable(replaceValue);
        if (!functionalReplace)
          replaceValue = toString(replaceValue);
        searchLength = searchString.length;
        advanceBy = max3(1, searchLength);
        position = indexOf(string2, searchString);
        while (position !== -1) {
          replacement = functionalReplace ? toString(replaceValue(searchString, position, string2)) : getSubstitution(searchString, string2, position, [], void 0, replaceValue);
          result += stringSlice(string2, endOfLastMatch, position) + replacement;
          endOfLastMatch = position + searchLength;
          position = position + advanceBy > string2.length ? -1 : indexOf(string2, searchString, position + advanceBy);
        }
        if (endOfLastMatch < string2.length) {
          result += stringSlice(string2, endOfLastMatch);
        }
        return result;
      }
    });
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/string/replace-all.js
var require_replace_all = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/es/string/replace-all.js"(exports, module) {
    "use strict";
    require_es_regexp_exec();
    require_es_string_replace();
    require_es_string_replace_all();
    var entryUnbind = require_entry_unbind();
    module.exports = entryUnbind("String", "replaceAll");
  }
});

// node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/string/replace-all.js
var require_replace_all2 = __commonJS({
  "node_modules/.deno/core-js@3.45.1/node_modules/core-js/stable/string/replace-all.js"(exports, module) {
    "use strict";
    var parent = require_replace_all();
    module.exports = parent;
  }
});

// node_modules/.deno/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
var require_lz_string = __commonJS({
  "node_modules/.deno/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
    var LZString = function() {
      var f = String.fromCharCode;
      var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
      var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
      var baseReverseDic = {};
      function getBaseValue(alphabet, character) {
        if (!baseReverseDic[alphabet]) {
          baseReverseDic[alphabet] = {};
          for (var i = 0; i < alphabet.length; i++) {
            baseReverseDic[alphabet][alphabet.charAt(i)] = i;
          }
        }
        return baseReverseDic[alphabet][character];
      }
      var LZString2 = {
        compressToBase64: function(input) {
          if (input == null)
            return "";
          var res = LZString2._compress(input, 6, function(a) {
            return keyStrBase64.charAt(a);
          });
          switch (res.length % 4) {
            default:
            case 0:
              return res;
            case 1:
              return res + "===";
            case 2:
              return res + "==";
            case 3:
              return res + "=";
          }
        },
        decompressFromBase64: function(input) {
          if (input == null)
            return "";
          if (input == "")
            return null;
          return LZString2._decompress(input.length, 32, function(index2) {
            return getBaseValue(keyStrBase64, input.charAt(index2));
          });
        },
        compressToUTF16: function(input) {
          if (input == null)
            return "";
          return LZString2._compress(input, 15, function(a) {
            return f(a + 32);
          }) + " ";
        },
        decompressFromUTF16: function(compressed) {
          if (compressed == null)
            return "";
          if (compressed == "")
            return null;
          return LZString2._decompress(compressed.length, 16384, function(index2) {
            return compressed.charCodeAt(index2) - 32;
          });
        },
        //compress into uint8array (UCS-2 big endian format)
        compressToUint8Array: function(uncompressed) {
          var compressed = LZString2.compress(uncompressed);
          var buf = new Uint8Array(compressed.length * 2);
          for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
            var current_value = compressed.charCodeAt(i);
            buf[i * 2] = current_value >>> 8;
            buf[i * 2 + 1] = current_value % 256;
          }
          return buf;
        },
        //decompress from uint8array (UCS-2 big endian format)
        decompressFromUint8Array: function(compressed) {
          if (compressed === null || compressed === void 0) {
            return LZString2.decompress(compressed);
          } else {
            var buf = new Array(compressed.length / 2);
            for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
              buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
            }
            var result = [];
            buf.forEach(function(c) {
              result.push(f(c));
            });
            return LZString2.decompress(result.join(""));
          }
        },
        //compress into a string that is already URI encoded
        compressToEncodedURIComponent: function(input) {
          if (input == null)
            return "";
          return LZString2._compress(input, 6, function(a) {
            return keyStrUriSafe.charAt(a);
          });
        },
        //decompress from an output of compressToEncodedURIComponent
        decompressFromEncodedURIComponent: function(input) {
          if (input == null)
            return "";
          if (input == "")
            return null;
          input = input.replace(/ /g, "+");
          return LZString2._decompress(input.length, 32, function(index2) {
            return getBaseValue(keyStrUriSafe, input.charAt(index2));
          });
        },
        compress: function(uncompressed) {
          return LZString2._compress(uncompressed, 16, function(a) {
            return f(a);
          });
        },
        _compress: function(uncompressed, bitsPerChar, getCharFromInt) {
          if (uncompressed == null)
            return "";
          var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
          for (ii = 0; ii < uncompressed.length; ii += 1) {
            context_c = uncompressed.charAt(ii);
            if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
              context_dictionary[context_c] = context_dictSize++;
              context_dictionaryToCreate[context_c] = true;
            }
            context_wc = context_w + context_c;
            if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
              context_w = context_wc;
            } else {
              if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
                if (context_w.charCodeAt(0) < 256) {
                  for (i = 0; i < context_numBits; i++) {
                    context_data_val = context_data_val << 1;
                    if (context_data_position == bitsPerChar - 1) {
                      context_data_position = 0;
                      context_data.push(getCharFromInt(context_data_val));
                      context_data_val = 0;
                    } else {
                      context_data_position++;
                    }
                  }
                  value = context_w.charCodeAt(0);
                  for (i = 0; i < 8; i++) {
                    context_data_val = context_data_val << 1 | value & 1;
                    if (context_data_position == bitsPerChar - 1) {
                      context_data_position = 0;
                      context_data.push(getCharFromInt(context_data_val));
                      context_data_val = 0;
                    } else {
                      context_data_position++;
                    }
                    value = value >> 1;
                  }
                } else {
                  value = 1;
                  for (i = 0; i < context_numBits; i++) {
                    context_data_val = context_data_val << 1 | value;
                    if (context_data_position == bitsPerChar - 1) {
                      context_data_position = 0;
                      context_data.push(getCharFromInt(context_data_val));
                      context_data_val = 0;
                    } else {
                      context_data_position++;
                    }
                    value = 0;
                  }
                  value = context_w.charCodeAt(0);
                  for (i = 0; i < 16; i++) {
                    context_data_val = context_data_val << 1 | value & 1;
                    if (context_data_position == bitsPerChar - 1) {
                      context_data_position = 0;
                      context_data.push(getCharFromInt(context_data_val));
                      context_data_val = 0;
                    } else {
                      context_data_position++;
                    }
                    value = value >> 1;
                  }
                }
                context_enlargeIn--;
                if (context_enlargeIn == 0) {
                  context_enlargeIn = Math.pow(2, context_numBits);
                  context_numBits++;
                }
                delete context_dictionaryToCreate[context_w];
              } else {
                value = context_dictionary[context_w];
                for (i = 0; i < context_numBits; i++) {
                  context_data_val = context_data_val << 1 | value & 1;
                  if (context_data_position == bitsPerChar - 1) {
                    context_data_position = 0;
                    context_data.push(getCharFromInt(context_data_val));
                    context_data_val = 0;
                  } else {
                    context_data_position++;
                  }
                  value = value >> 1;
                }
              }
              context_enlargeIn--;
              if (context_enlargeIn == 0) {
                context_enlargeIn = Math.pow(2, context_numBits);
                context_numBits++;
              }
              context_dictionary[context_wc] = context_dictSize++;
              context_w = String(context_c);
            }
          }
          if (context_w !== "") {
            if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
              if (context_w.charCodeAt(0) < 256) {
                for (i = 0; i < context_numBits; i++) {
                  context_data_val = context_data_val << 1;
                  if (context_data_position == bitsPerChar - 1) {
                    context_data_position = 0;
                    context_data.push(getCharFromInt(context_data_val));
                    context_data_val = 0;
                  } else {
                    context_data_position++;
                  }
                }
                value = context_w.charCodeAt(0);
                for (i = 0; i < 8; i++) {
                  context_data_val = context_data_val << 1 | value & 1;
                  if (context_data_position == bitsPerChar - 1) {
                    context_data_position = 0;
                    context_data.push(getCharFromInt(context_data_val));
                    context_data_val = 0;
                  } else {
                    context_data_position++;
                  }
                  value = value >> 1;
                }
              } else {
                value = 1;
                for (i = 0; i < context_numBits; i++) {
                  context_data_val = context_data_val << 1 | value;
                  if (context_data_position == bitsPerChar - 1) {
                    context_data_position = 0;
                    context_data.push(getCharFromInt(context_data_val));
                    context_data_val = 0;
                  } else {
                    context_data_position++;
                  }
                  value = 0;
                }
                value = context_w.charCodeAt(0);
                for (i = 0; i < 16; i++) {
                  context_data_val = context_data_val << 1 | value & 1;
                  if (context_data_position == bitsPerChar - 1) {
                    context_data_position = 0;
                    context_data.push(getCharFromInt(context_data_val));
                    context_data_val = 0;
                  } else {
                    context_data_position++;
                  }
                  value = value >> 1;
                }
              }
              context_enlargeIn--;
              if (context_enlargeIn == 0) {
                context_enlargeIn = Math.pow(2, context_numBits);
                context_numBits++;
              }
              delete context_dictionaryToCreate[context_w];
            } else {
              value = context_dictionary[context_w];
              for (i = 0; i < context_numBits; i++) {
                context_data_val = context_data_val << 1 | value & 1;
                if (context_data_position == bitsPerChar - 1) {
                  context_data_position = 0;
                  context_data.push(getCharFromInt(context_data_val));
                  context_data_val = 0;
                } else {
                  context_data_position++;
                }
                value = value >> 1;
              }
            }
            context_enlargeIn--;
            if (context_enlargeIn == 0) {
              context_enlargeIn = Math.pow(2, context_numBits);
              context_numBits++;
            }
          }
          value = 2;
          for (i = 0; i < context_numBits; i++) {
            context_data_val = context_data_val << 1 | value & 1;
            if (context_data_position == bitsPerChar - 1) {
              context_data_position = 0;
              context_data.push(getCharFromInt(context_data_val));
              context_data_val = 0;
            } else {
              context_data_position++;
            }
            value = value >> 1;
          }
          while (true) {
            context_data_val = context_data_val << 1;
            if (context_data_position == bitsPerChar - 1) {
              context_data.push(getCharFromInt(context_data_val));
              break;
            } else
              context_data_position++;
          }
          return context_data.join("");
        },
        decompress: function(compressed) {
          if (compressed == null)
            return "";
          if (compressed == "")
            return null;
          return LZString2._decompress(compressed.length, 32768, function(index2) {
            return compressed.charCodeAt(index2);
          });
        },
        _decompress: function(length, resetValue, getNextValue) {
          var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
          for (i = 0; i < 3; i += 1) {
            dictionary[i] = i;
          }
          bits = 0;
          maxpower = Math.pow(2, 2);
          power = 1;
          while (power != maxpower) {
            resb = data.val & data.position;
            data.position >>= 1;
            if (data.position == 0) {
              data.position = resetValue;
              data.val = getNextValue(data.index++);
            }
            bits |= (resb > 0 ? 1 : 0) * power;
            power <<= 1;
          }
          switch (next = bits) {
            case 0:
              bits = 0;
              maxpower = Math.pow(2, 8);
              power = 1;
              while (power != maxpower) {
                resb = data.val & data.position;
                data.position >>= 1;
                if (data.position == 0) {
                  data.position = resetValue;
                  data.val = getNextValue(data.index++);
                }
                bits |= (resb > 0 ? 1 : 0) * power;
                power <<= 1;
              }
              c = f(bits);
              break;
            case 1:
              bits = 0;
              maxpower = Math.pow(2, 16);
              power = 1;
              while (power != maxpower) {
                resb = data.val & data.position;
                data.position >>= 1;
                if (data.position == 0) {
                  data.position = resetValue;
                  data.val = getNextValue(data.index++);
                }
                bits |= (resb > 0 ? 1 : 0) * power;
                power <<= 1;
              }
              c = f(bits);
              break;
            case 2:
              return "";
          }
          dictionary[3] = c;
          w = c;
          result.push(c);
          while (true) {
            if (data.index > length) {
              return "";
            }
            bits = 0;
            maxpower = Math.pow(2, numBits);
            power = 1;
            while (power != maxpower) {
              resb = data.val & data.position;
              data.position >>= 1;
              if (data.position == 0) {
                data.position = resetValue;
                data.val = getNextValue(data.index++);
              }
              bits |= (resb > 0 ? 1 : 0) * power;
              power <<= 1;
            }
            switch (c = bits) {
              case 0:
                bits = 0;
                maxpower = Math.pow(2, 8);
                power = 1;
                while (power != maxpower) {
                  resb = data.val & data.position;
                  data.position >>= 1;
                  if (data.position == 0) {
                    data.position = resetValue;
                    data.val = getNextValue(data.index++);
                  }
                  bits |= (resb > 0 ? 1 : 0) * power;
                  power <<= 1;
                }
                dictionary[dictSize++] = f(bits);
                c = dictSize - 1;
                enlargeIn--;
                break;
              case 1:
                bits = 0;
                maxpower = Math.pow(2, 16);
                power = 1;
                while (power != maxpower) {
                  resb = data.val & data.position;
                  data.position >>= 1;
                  if (data.position == 0) {
                    data.position = resetValue;
                    data.val = getNextValue(data.index++);
                  }
                  bits |= (resb > 0 ? 1 : 0) * power;
                  power <<= 1;
                }
                dictionary[dictSize++] = f(bits);
                c = dictSize - 1;
                enlargeIn--;
                break;
              case 2:
                return result.join("");
            }
            if (enlargeIn == 0) {
              enlargeIn = Math.pow(2, numBits);
              numBits++;
            }
            if (dictionary[c]) {
              entry = dictionary[c];
            } else {
              if (c === dictSize) {
                entry = w + w.charAt(0);
              } else {
                return null;
              }
            }
            result.push(entry);
            dictionary[dictSize++] = w + entry.charAt(0);
            enlargeIn--;
            w = entry;
            if (enlargeIn == 0) {
              enlargeIn = Math.pow(2, numBits);
              numBits++;
            }
          }
        }
      };
      return LZString2;
    }();
    if (typeof define === "function" && define.amd) {
      define(function() {
        return LZString;
      });
    } else if (typeof module !== "undefined" && module != null) {
      module.exports = LZString;
    } else if (typeof angular !== "undefined" && angular != null) {
      angular.module("LZString", []).factory("LZString", function() {
        return LZString;
      });
    }
  }
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Dialog.mjs
var Dialog_exports = {};
__export(Dialog_exports, {
  Body: () => Body,
  CloseButton: () => CloseButton,
  Footer: () => Footer,
  Header: () => Header,
  Title: () => Title
});
var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
var import_classnames14 = __toESM(require_classnames(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Button.mjs
var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
var import_classnames13 = __toESM(require_classnames(), 1);
var React18 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs
var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/ArraySet.mjs
var ARRAY_SIZE_THRESHOLD = 8;
var ArraySet = class {
  arraySize = 0;
  array = Array(ARRAY_SIZE_THRESHOLD);
  set = null;
  /**
   * Get whether this ArraySet has any elements.
   *
   * @returns True if this ArraySet has any elements, false otherwise.
   */
  get isEmpty() {
    if (this.array) {
      return this.arraySize === 0;
    }
    if (this.set) {
      return this.set.size === 0;
    }
    throw new Error("no set or array");
  }
  /**
   * Add an item to the ArraySet if it is not already present.
   *
   * @param elem - The element to add.
   */
  add(elem) {
    if (this.array) {
      const idx = this.array.indexOf(elem);
      if (idx !== -1) {
        return false;
      }
      if (this.arraySize < ARRAY_SIZE_THRESHOLD) {
        this.array[this.arraySize] = elem;
        this.arraySize++;
        return true;
      } else {
        this.set = new Set(this.array);
        this.array = null;
        this.set.add(elem);
        return true;
      }
    }
    if (this.set) {
      if (this.set.has(elem)) {
        return false;
      }
      this.set.add(elem);
      return true;
    }
    throw new Error("no set or array");
  }
  /**
   * Remove an item from the ArraySet if it is present.
   *
   * @param elem - The element to remove
   */
  remove(elem) {
    if (this.array) {
      const idx = this.array.indexOf(elem);
      if (idx === -1) {
        return false;
      }
      this.array[idx] = void 0;
      this.arraySize--;
      if (idx !== this.arraySize) {
        this.array[idx] = this.array[this.arraySize];
        this.array[this.arraySize] = void 0;
      }
      return true;
    }
    if (this.set) {
      if (!this.set.has(elem)) {
        return false;
      }
      this.set.delete(elem);
      return true;
    }
    throw new Error("no set or array");
  }
  /**
   * Run a callback for each element in the ArraySet.
   *
   * @param visitor - The callback to run for each element.
   */
  visit(visitor) {
    if (this.array) {
      for (let i = 0; i < this.arraySize; i++) {
        const elem = this.array[i];
        if (typeof elem !== "undefined") {
          visitor(elem);
        }
      }
      return;
    }
    if (this.set) {
      this.set.forEach(visitor);
      return;
    }
    throw new Error("no set or array");
  }
};

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/helpers.mjs
function isChild(x) {
  return x && typeof x === "object" && "parents" in x;
}
function haveParentsChanged(child) {
  for (let i = 0, n = child.parents.length; i < n; i++) {
    child.parents[i].__unsafe__getWithoutCapture();
    if (child.parents[i].lastChangedEpoch !== child.parentEpochs[i]) {
      return true;
    }
  }
  return false;
}
var detach = (parent, child) => {
  if (!parent.children.remove(child)) {
    return;
  }
  if (parent.children.isEmpty && isChild(parent)) {
    for (let i = 0, n = parent.parents.length; i < n; i++) {
      detach(parent.parents[i], parent);
    }
  }
};
var attach = (parent, child) => {
  if (!parent.children.add(child)) {
    return;
  }
  if (isChild(parent)) {
    for (let i = 0, n = parent.parents.length; i < n; i++) {
      attach(parent.parents[i], parent);
    }
  }
};
function equals(a, b) {
  const shallowEquals = a === b || Object.is(a, b) || Boolean(a && b && typeof a.equals === "function" && a.equals(b));
  return shallowEquals;
}
var EMPTY_ARRAY = Object.freeze([]);

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/capture.mjs
var tldrawStateGlobalKey = Symbol.for("__@tldraw/state__");
var tldrawStateGlobal = globalThis;
if (tldrawStateGlobal[tldrawStateGlobalKey]) {
  console.error(
    'Multiple versions of @tldraw/state detected. This will cause unexpected behavior. Please add "resolutions" (yarn/pnpm) or "overrides" (npm) in your package.json to ensure only one version of @tldraw/state is loaded.'
  );
} else {
  tldrawStateGlobal[tldrawStateGlobalKey] = true;
}
var CaptureStackFrame = class {
  constructor(below, child) {
    this.below = below;
    this.child = child;
  }
  offset = 0;
  numNewParents = 0;
  maybeRemoved;
};
var stack = null;
function startCapturingParents(child) {
  stack = new CaptureStackFrame(stack, child);
}
function stopCapturingParents() {
  const frame2 = stack;
  stack = frame2.below;
  const didParentsChange = frame2.numNewParents > 0 || frame2.offset !== frame2.child.parents.length;
  if (!didParentsChange) {
    return;
  }
  for (let i = frame2.offset; i < frame2.child.parents.length; i++) {
    const p = frame2.child.parents[i];
    const parentWasRemoved = frame2.child.parents.indexOf(p) >= frame2.offset;
    if (parentWasRemoved) {
      detach(p, frame2.child);
    }
  }
  frame2.child.parents.length = frame2.offset;
  frame2.child.parentEpochs.length = frame2.offset;
  if (stack?.maybeRemoved) {
    for (let i = 0; i < stack.maybeRemoved.length; i++) {
      const maybeRemovedParent = stack.maybeRemoved[i];
      if (frame2.child.parents.indexOf(maybeRemovedParent) === -1) {
        detach(maybeRemovedParent, frame2.child);
      }
    }
  }
}
function maybeCaptureParent(p) {
  if (stack) {
    const idx = stack.child.parents.indexOf(p);
    if (idx < 0) {
      stack.numNewParents++;
      if (stack.child.isActivelyListening) {
        attach(p, stack.child);
      }
    }
    if (idx < 0 || idx >= stack.offset) {
      if (idx !== stack.offset && idx > 0) {
        const maybeRemovedParent = stack.child.parents[stack.offset];
        if (!stack.maybeRemoved) {
          stack.maybeRemoved = [maybeRemovedParent];
        } else if (stack.maybeRemoved.indexOf(maybeRemovedParent) === -1) {
          stack.maybeRemoved.push(maybeRemovedParent);
        }
      }
      stack.child.parents[stack.offset] = p;
      stack.child.parentEpochs[stack.offset] = p.lastChangedEpoch;
      stack.offset++;
    }
  }
}
function whyAmIRunning() {
  const child = stack?.child;
  if (!child) {
    throw new Error("whyAmIRunning() called outside of a reactive context");
  }
  const changedParents = [];
  for (let i = 0; i < child.parents.length; i++) {
    const parent = child.parents[i];
    if (parent.lastChangedEpoch > child.parentEpochs[i]) {
      changedParents.push(parent);
    }
  }
  if (changedParents.length === 0) {
    console.log(child.name, "is running but none of the parents changed");
  } else {
    console.log(child.name, "is running because:");
    for (const changedParent of changedParents) {
      console.log(
        "	",
        changedParent.name,
        "changed =>",
        changedParent.__unsafe__getWithoutCapture()
      );
    }
  }
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/types.mjs
var RESET_VALUE = Symbol("RESET_VALUE");

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/HistoryBuffer.mjs
var HistoryBuffer = class {
  constructor(capacity) {
    this.capacity = capacity;
    this.buffer = new Array(capacity);
  }
  index = 0;
  // use a wrap around buffer to store the last N values
  buffer;
  /**
   * Add a diff to the history buffer.
   *
   * @param lastComputedEpoch - The epoch when the diff was computed.
   * @param currentEpoch - The current epoch.
   * @param diff - (optional) The diff to add, or else a reset value.
   */
  pushEntry(lastComputedEpoch, currentEpoch, diff) {
    if (diff === void 0) {
      return;
    }
    if (diff === RESET_VALUE) {
      this.clear();
      return;
    }
    this.buffer[this.index] = [lastComputedEpoch, currentEpoch, diff];
    this.index = (this.index + 1) % this.capacity;
  }
  /**
   * Clear the history buffer.
   */
  clear() {
    this.index = 0;
    this.buffer.fill(void 0);
  }
  /**
   * Get the diffs since the given epoch.
   *
   * @param epoch - The epoch to get diffs since.
   * @returns An array of diffs or a flag to reset the history buffer.
   */
  getChangesSince(sinceEpoch) {
    const { index: index2, capacity, buffer } = this;
    for (let i = 0; i < capacity; i++) {
      const offset2 = (index2 - 1 + capacity - i) % capacity;
      const elem = buffer[offset2];
      if (!elem) {
        return RESET_VALUE;
      }
      const [fromEpoch, toEpoch] = elem;
      if (i === 0 && sinceEpoch >= toEpoch) {
        return [];
      }
      if (fromEpoch <= sinceEpoch && sinceEpoch < toEpoch) {
        const len = i + 1;
        const result = new Array(len);
        for (let j = 0; j < len; j++) {
          result[j] = buffer[(offset2 + j) % capacity][2];
        }
        return result;
      }
    }
    return RESET_VALUE;
  }
};

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/constants.mjs
var GLOBAL_START_EPOCH = -1;

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/transactions.mjs
var globalEpoch = GLOBAL_START_EPOCH + 1;
var globalIsReacting = false;
function advanceGlobalEpoch() {
  globalEpoch++;
}
var Transaction = class {
  constructor(parent) {
    this.parent = parent;
  }
  initialAtomValues = /* @__PURE__ */ new Map();
  /**
   * Get whether this transaction is a root (no parents).
   *
   * @public
   */
  get isRoot() {
    return this.parent === null;
  }
  /**
   * Commit the transaction's changes.
   *
   * @public
   */
  commit() {
    if (this.isRoot) {
      const atoms = this.initialAtomValues;
      this.initialAtomValues = /* @__PURE__ */ new Map();
      flushChanges(atoms.keys());
    } else {
      this.initialAtomValues.forEach((value, atom2) => {
        if (!this.parent.initialAtomValues.has(atom2)) {
          this.parent.initialAtomValues.set(atom2, value);
        }
      });
    }
  }
  /**
   * Abort the transaction.
   *
   * @public
   */
  abort() {
    globalEpoch++;
    this.initialAtomValues.forEach((value, atom2) => {
      atom2.set(value);
      atom2.historyBuffer?.clear();
    });
    this.commit();
  }
};
function flushChanges(atoms) {
  if (globalIsReacting) {
    throw new Error("cannot change atoms during reaction cycle");
  }
  try {
    globalIsReacting = true;
    const reactors = /* @__PURE__ */ new Set();
    const traverse = (node) => {
      if (node.lastTraversedEpoch === globalEpoch) {
        return;
      }
      node.lastTraversedEpoch = globalEpoch;
      if ("maybeScheduleEffect" in node) {
        reactors.add(node);
      } else {
        ;
        node.children.visit(traverse);
      }
    };
    for (const atom2 of atoms) {
      atom2.children.visit(traverse);
    }
    for (const r of reactors) {
      r.maybeScheduleEffect();
    }
  } finally {
    globalIsReacting = false;
  }
}
function atomDidChange(atom2, previousValue) {
  if (!currentTransaction) {
    flushChanges([atom2]);
  } else if (!currentTransaction.initialAtomValues.has(atom2)) {
    currentTransaction.initialAtomValues.set(atom2, previousValue);
  }
}
var currentTransaction = null;
function transaction(fn) {
  const txn = new Transaction(currentTransaction);
  currentTransaction = txn;
  try {
    let rollback = false;
    const result = fn(() => rollback = true);
    if (rollback) {
      txn.abort();
    } else {
      txn.commit();
    }
    return result;
  } catch (e) {
    txn.abort();
    throw e;
  } finally {
    currentTransaction = currentTransaction.parent;
  }
}
function transact(fn) {
  if (currentTransaction) {
    return fn();
  }
  return transaction(fn);
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/Atom.mjs
var _Atom = class {
  constructor(name, current, options) {
    this.name = name;
    this.current = current;
    this.isEqual = options?.isEqual ?? null;
    if (!options)
      return;
    if (options.historyLength) {
      this.historyBuffer = new HistoryBuffer(options.historyLength);
    }
    this.computeDiff = options.computeDiff;
  }
  isEqual;
  computeDiff;
  lastChangedEpoch = globalEpoch;
  children = new ArraySet();
  historyBuffer;
  __unsafe__getWithoutCapture() {
    return this.current;
  }
  get value() {
    maybeCaptureParent(this);
    return this.current;
  }
  set(value, diff) {
    if (this.isEqual?.(this.current, value) ?? equals(this.current, value)) {
      return this.current;
    }
    advanceGlobalEpoch();
    if (this.historyBuffer) {
      this.historyBuffer.pushEntry(
        this.lastChangedEpoch,
        globalEpoch,
        diff ?? this.computeDiff?.(this.current, value, this.lastChangedEpoch, globalEpoch) ?? RESET_VALUE
      );
    }
    this.lastChangedEpoch = globalEpoch;
    const oldValue = this.current;
    this.current = value;
    atomDidChange(this, oldValue);
    return value;
  }
  update(updater) {
    return this.set(updater(this.current));
  }
  getDiffSince(epoch) {
    maybeCaptureParent(this);
    if (epoch >= this.lastChangedEpoch) {
      return EMPTY_ARRAY;
    }
    return this.historyBuffer?.getChangesSince(epoch) ?? RESET_VALUE;
  }
};
function atom(name, initialValue, options) {
  return new _Atom(name, initialValue, options);
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/Computed.mjs
var UNINITIALIZED = Symbol("UNINITIALIZED");
var isUninitialized = (value) => {
  return value === UNINITIALIZED;
};
var WithDiff = class {
  constructor(value, diff) {
    this.value = value;
    this.diff = diff;
  }
};
function withDiff(value, diff) {
  return new WithDiff(value, diff);
}
var _Computed = class {
  constructor(name, derive, options) {
    this.name = name;
    this.derive = derive;
    if (options?.historyLength) {
      this.historyBuffer = new HistoryBuffer(options.historyLength);
    }
    this.computeDiff = options?.computeDiff;
    this.isEqual = options?.isEqual ?? equals;
  }
  lastChangedEpoch = GLOBAL_START_EPOCH;
  lastTraversedEpoch = GLOBAL_START_EPOCH;
  /**
   * The epoch when the reactor was last checked.
   */
  lastCheckedEpoch = GLOBAL_START_EPOCH;
  parents = [];
  parentEpochs = [];
  children = new ArraySet();
  get isActivelyListening() {
    return !this.children.isEmpty;
  }
  historyBuffer;
  // The last-computed value of this signal.
  state = UNINITIALIZED;
  computeDiff;
  isEqual;
  __unsafe__getWithoutCapture() {
    const isNew = this.lastChangedEpoch === GLOBAL_START_EPOCH;
    if (!isNew && (this.lastCheckedEpoch === globalEpoch || !haveParentsChanged(this))) {
      this.lastCheckedEpoch = globalEpoch;
      return this.state;
    }
    try {
      startCapturingParents(this);
      const result = this.derive(this.state, this.lastCheckedEpoch);
      const newState = result instanceof WithDiff ? result.value : result;
      if (this.state === UNINITIALIZED || !this.isEqual(newState, this.state)) {
        if (this.historyBuffer && !isNew) {
          const diff = result instanceof WithDiff ? result.diff : void 0;
          this.historyBuffer.pushEntry(
            this.lastChangedEpoch,
            globalEpoch,
            diff ?? this.computeDiff?.(this.state, newState, this.lastCheckedEpoch, globalEpoch) ?? RESET_VALUE
          );
        }
        this.lastChangedEpoch = globalEpoch;
        this.state = newState;
      }
      this.lastCheckedEpoch = globalEpoch;
      return this.state;
    } finally {
      stopCapturingParents();
    }
  }
  get value() {
    const value = this.__unsafe__getWithoutCapture();
    maybeCaptureParent(this);
    return value;
  }
  getDiffSince(epoch) {
    this.value;
    if (epoch >= this.lastChangedEpoch) {
      return EMPTY_ARRAY;
    }
    return this.historyBuffer?.getChangesSince(epoch) ?? RESET_VALUE;
  }
};
function computedAnnotation(options = {}, _target, key, descriptor) {
  const originalMethod = descriptor.get;
  const derivationKey = Symbol.for("__@tldraw/state__computed__" + key);
  descriptor.get = function() {
    let d = this[derivationKey];
    if (!d) {
      d = new _Computed(key, originalMethod.bind(this), options);
      Object.defineProperty(this, derivationKey, {
        enumerable: false,
        configurable: false,
        writable: false,
        value: d
      });
    }
    return d.value;
  };
  return descriptor;
}
function computed() {
  if (arguments.length === 1) {
    const options = arguments[0];
    return (target, key, descriptor) => computedAnnotation(options, target, key, descriptor);
  } else if (typeof arguments[0] === "string") {
    return new _Computed(arguments[0], arguments[1], arguments[2]);
  } else {
    return computedAnnotation(void 0, arguments[0], arguments[1], arguments[2]);
  }
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/core/EffectScheduler.mjs
var EffectScheduler = class {
  constructor(name, runEffect, options) {
    this.name = name;
    this.runEffect = runEffect;
    this._scheduleEffect = options?.scheduleEffect;
  }
  _isActivelyListening = false;
  /**
   * Whether this scheduler is attached and actively listening to its parents.
   * @public
   */
  get isActivelyListening() {
    return this._isActivelyListening;
  }
  /** @internal */
  lastTraversedEpoch = GLOBAL_START_EPOCH;
  lastReactedEpoch = GLOBAL_START_EPOCH;
  _scheduleCount = 0;
  /**
   * The number of times this effect has been scheduled.
   * @public
   */
  get scheduleCount() {
    return this._scheduleCount;
  }
  /** @internal */
  parentEpochs = [];
  /** @internal */
  parents = [];
  _scheduleEffect;
  /** @internal */
  maybeScheduleEffect() {
    if (!this._isActivelyListening)
      return;
    if (this.lastReactedEpoch === globalEpoch)
      return;
    if (this.parents.length && !haveParentsChanged(this)) {
      this.lastReactedEpoch = globalEpoch;
      return;
    }
    this.scheduleEffect();
  }
  /** @internal */
  scheduleEffect() {
    this._scheduleCount++;
    if (this._scheduleEffect) {
      this._scheduleEffect(this.maybeExecute);
    } else {
      this.execute();
    }
  }
  maybeExecute = () => {
    if (!this._isActivelyListening)
      return;
    this.execute();
  };
  /**
   * Makes this scheduler become 'actively listening' to its parents.
   * If it has been executed before it will immediately become eligible to receive 'maybeScheduleEffect' calls.
   * If it has not executed before it will need to be manually executed once to become eligible for scheduling, i.e. by calling [[EffectScheduler.execute]].
   * @public
   */
  attach() {
    this._isActivelyListening = true;
    for (let i = 0, n = this.parents.length; i < n; i++) {
      attach(this.parents[i], this);
    }
  }
  /**
   * Makes this scheduler stop 'actively listening' to its parents.
   * It will no longer be eligible to receive 'maybeScheduleEffect' calls until [[EffectScheduler.attach]] is called again.
   */
  detach() {
    this._isActivelyListening = false;
    for (let i = 0, n = this.parents.length; i < n; i++) {
      detach(this.parents[i], this);
    }
  }
  /**
   * Executes the effect immediately and returns the result.
   * @returns The result of the effect.
   */
  execute() {
    try {
      startCapturingParents(this);
      const result = this.runEffect(this.lastReactedEpoch);
      this.lastReactedEpoch = globalEpoch;
      return result;
    } finally {
      stopCapturingParents();
    }
  }
};
function react(name, fn, options) {
  const scheduler = new EffectScheduler(name, fn, options);
  scheduler.attach();
  scheduler.scheduleEffect();
  return () => {
    scheduler.detach();
  };
}
function reactor(name, fn, options) {
  const scheduler = new EffectScheduler(name, fn, options);
  return {
    scheduler,
    start: (options2) => {
      const force = options2?.force ?? false;
      scheduler.attach();
      if (force) {
        scheduler.scheduleEffect();
      } else {
        scheduler.maybeScheduleEffect();
      }
    },
    stop: () => {
      scheduler.detach();
    }
  };
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/track.mjs
var import_react2 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/useStateTracking.mjs
var import_react = __toESM(require_react(), 1);
function useStateTracking(name, render) {
  const renderRef = import_react.default.useRef(render);
  renderRef.current = render;
  const [scheduler, subscribe, getSnapshot] = import_react.default.useMemo(() => {
    let scheduleUpdate = null;
    const subscribe2 = (cb) => {
      scheduleUpdate = cb;
      return () => {
        scheduleUpdate = null;
      };
    };
    const scheduler2 = new EffectScheduler(
      `useStateTracking(${name})`,
      // this is what `scheduler.execute()` will call
      () => renderRef.current?.(),
      // this is what will be invoked when @tldraw/state detects a change in an upstream reactive value
      {
        scheduleEffect() {
          scheduleUpdate?.();
        }
      }
    );
    const getSnapshot2 = () => scheduler2.scheduleCount;
    return [scheduler2, subscribe2, getSnapshot2];
  }, [name]);
  import_react.default.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
  import_react.default.useEffect(() => {
    scheduler.attach();
    scheduler.maybeScheduleEffect();
    return () => {
      scheduler.detach();
    };
  }, [scheduler]);
  return scheduler.execute();
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/track.mjs
var ProxyHandlers = {
  /**
   * This is a function call trap for functional components. When this is called, we know it means
   * React did run 'Component()', that means we can use any hooks here to setup our effect and
   * store.
   *
   * With the native Proxy, all other calls such as access/setting to/of properties will be
   * forwarded to the target Component, so we don't need to copy the Component's own or inherited
   * properties.
   *
   * @see https://github.com/facebook/react/blob/2d80a0cd690bb5650b6c8a6c079a87b5dc42bd15/packages/react-reconciler/src/ReactFiberHooks.old.js#L460
   */
  apply(Component2, thisArg, argumentsList) {
    return useStateTracking(
      Component2.displayName ?? Component2.name ?? "tracked(???)",
      () => Component2.apply(thisArg, argumentsList)
    );
  }
};
var ReactMemoSymbol = Symbol.for("react.memo");
var ReactForwardRefSymbol = Symbol.for("react.forward_ref");
function track(baseComponent) {
  let compare = null;
  const $$typeof = baseComponent["$$typeof"];
  if ($$typeof === ReactMemoSymbol) {
    baseComponent = baseComponent.type;
    compare = baseComponent.compare;
  }
  if ($$typeof === ReactForwardRefSymbol) {
    return (0, import_react2.memo)((0, import_react2.forwardRef)(new Proxy(baseComponent.render, ProxyHandlers)));
  }
  return (0, import_react2.memo)(new Proxy(baseComponent, ProxyHandlers), compare);
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/useAtom.mjs
var import_react3 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/useComputed.mjs
var import_react4 = __toESM(require_react(), 1);
function useComputed() {
  const name = arguments[0];
  const compute = arguments[1];
  const opts = arguments.length === 3 ? void 0 : arguments[2];
  const deps = arguments.length === 3 ? arguments[2] : arguments[3];
  return (0, import_react4.useMemo)(() => computed(`useComputed(${name})`, compute, opts), deps);
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/useQuickReactor.mjs
var import_react5 = __toESM(require_react(), 1);
function useQuickReactor(name, reactFn, deps = EMPTY_ARRAY) {
  (0, import_react5.useEffect)(() => {
    const scheduler = new EffectScheduler(name, reactFn);
    scheduler.attach();
    scheduler.execute();
    return () => {
      scheduler.detach();
    };
  }, deps);
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/useReactor.mjs
var import_react6 = __toESM(require_react(), 1);
function useReactor(name, reactFn, deps = []) {
  const scheduler = (0, import_react6.useMemo)(
    () => new EffectScheduler(name, reactFn, { scheduleEffect: (cb) => requestAnimationFrame(cb) }),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    deps
  );
  (0, import_react6.useEffect)(() => {
    scheduler.attach();
    scheduler.execute();
    return () => {
      scheduler.detach();
    };
  }, [scheduler]);
}

// node_modules/.deno/@tldraw+state@2.0.0-alpha.17/node_modules/@tldraw/state/dist-esm/lib/react/useValue.mjs
var import_react7 = __toESM(require_react(), 1);
function useValue() {
  const args = arguments;
  const deps = args.length === 3 ? args[2] : [args[0]];
  const name = args.length === 3 ? args[0] : `useValue(${args[0].name})`;
  const isInRender = (0, import_react7.useRef)(true);
  isInRender.current = true;
  const $val = (0, import_react7.useMemo)(() => {
    if (args.length === 1) {
      return args[0];
    }
    return computed(name, () => {
      if (isInRender.current) {
        return args[1]();
      } else {
        try {
          return args[1]();
        } catch {
          return {};
        }
      }
    });
  }, deps);
  try {
    const { subscribe, getSnapshot } = (0, import_react7.useMemo)(() => {
      return {
        subscribe: (listen) => {
          return react(`useValue(${name})`, () => {
            $val.value;
            listen();
          });
        },
        getSnapshot: () => $val.value
      };
    }, [$val]);
    return (0, import_react7.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
  } finally {
    isInRender.current = false;
  }
}

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/IncrementalSetConstructor.mjs
var IncrementalSetConstructor = class {
  constructor(previousValue) {
    this.previousValue = previousValue;
  }
  /**
   * The next value of the set.
   *
   * @internal
   */
  nextValue;
  /**
   * The diff of the set.
   *
   * @internal
   */
  diff;
  /**
   * Get the next value of the set.
   *
   * @public
   */
  get() {
    const numRemoved = this.diff?.removed?.size ?? 0;
    const numAdded = this.diff?.added?.size ?? 0;
    if (numRemoved === 0 && numAdded === 0) {
      return void 0;
    }
    return { value: this.nextValue, diff: this.diff };
  }
  /**
   * Add an item to the set.
   *
   * @param item - The item to add.
   * @param wasAlreadyPresent - Whether the item was already present in the set.
   * @internal
   */
  _add(item, wasAlreadyPresent) {
    this.nextValue ??= new Set(this.previousValue);
    this.nextValue.add(item);
    this.diff ??= {};
    if (wasAlreadyPresent) {
      this.diff.removed?.delete(item);
    } else {
      this.diff.added ??= /* @__PURE__ */ new Set();
      this.diff.added.add(item);
    }
  }
  /**
   * Add an item to the set.
   *
   * @param item - The item to add.
   * @public
   */
  add(item) {
    const wasAlreadyPresent = this.previousValue.has(item);
    if (wasAlreadyPresent) {
      const wasRemoved = this.diff?.removed?.has(item);
      if (!wasRemoved)
        return;
      return this._add(item, wasAlreadyPresent);
    }
    const isCurrentlyPresent = this.nextValue?.has(item);
    if (isCurrentlyPresent)
      return;
    this._add(item, wasAlreadyPresent);
  }
  /**
   * Remove an item from the set.
   *
   * @param item - The item to remove.
   * @param wasAlreadyPresent - Whether the item was already present in the set.
   * @internal
   */
  _remove(item, wasAlreadyPresent) {
    this.nextValue ??= new Set(this.previousValue);
    this.nextValue.delete(item);
    this.diff ??= {};
    if (wasAlreadyPresent) {
      this.diff.removed ??= /* @__PURE__ */ new Set();
      this.diff.removed.add(item);
    } else {
      this.diff.added?.delete(item);
    }
  }
  /**
   * Remove an item from the set.
   *
   * @param item - The item to remove.
   * @public
   */
  remove(item) {
    const wasAlreadyPresent = this.previousValue.has(item);
    if (!wasAlreadyPresent) {
      const wasAdded = this.diff?.added?.has(item);
      if (!wasAdded)
        return;
      return this._remove(item, wasAlreadyPresent);
    }
    const hasAlreadyBeenRemoved = this.diff?.removed?.has(item);
    if (hasAlreadyBeenRemoved)
      return;
    this._remove(item, wasAlreadyPresent);
  }
};

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/array.mjs
function rotateArray(arr, offset2) {
  return arr.map((_, i) => arr[(i + offset2) % arr.length]);
}
function dedupe(input, equals2) {
  const result = [];
  mainLoop:
    for (const item of input) {
      for (const existing of result) {
        if (equals2 ? equals2(item, existing) : item === existing) {
          continue mainLoop;
        }
      }
      result.push(item);
    }
  return result;
}
function compact(arr) {
  return arr.filter((i) => i !== void 0 && i !== null);
}
function last(arr) {
  return arr[arr.length - 1];
}
function minBy(arr, fn) {
  let min4;
  let minVal = Infinity;
  for (const item of arr) {
    const val = fn(item);
    if (val < minVal) {
      min4 = item;
      minVal = val;
    }
  }
  return min4;
}
function partition(arr, predicate) {
  const satisfies = [];
  const doesNotSatisfy = [];
  for (const item of arr) {
    if (predicate(item)) {
      satisfies.push(item);
    } else {
      doesNotSatisfy.push(item);
    }
  }
  return [satisfies, doesNotSatisfy];
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/function.mjs
function throttle(func, limit) {
  let inThrottle;
  let lastResult;
  return function(...args) {
    if (!inThrottle) {
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
      lastResult = func(...args);
    }
    return lastResult;
  };
}
function omitFromStackTrace(fn) {
  const wrappedFn = (...args) => {
    try {
      return fn(...args);
    } catch (error) {
      if (error instanceof Error && Error.captureStackTrace) {
        Error.captureStackTrace(error, wrappedFn);
      }
      throw error;
    }
  };
  return wrappedFn;
}
function noop() {
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/control.mjs
var Result = {
  ok(value) {
    return { ok: true, value };
  },
  err(error) {
    return { ok: false, error };
  }
};
function exhaustiveSwitchError(value, property) {
  const debugValue = property && value && typeof value === "object" && property in value ? value[property] : value;
  throw new Error(`Unknown switch case ${debugValue}`);
}
var assert = omitFromStackTrace(
  (value, message) => {
    if (!value) {
      throw new Error(message || "Assertion Error");
    }
  }
);
var assertExists = omitFromStackTrace((value, message) => {
  if (value == null) {
    throw new Error(message ?? "value must be defined");
  }
  return value;
});
function promiseWithResolve() {
  let resolve;
  let reject;
  const promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
  });
  return Object.assign(promise, {
    resolve,
    reject
  });
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/debounce.mjs
function debounce(callback, wait) {
  let state = void 0;
  const fn = (...args) => {
    if (!state) {
      state = {};
      state.promise = new Promise((resolve, reject) => {
        state.resolve = resolve;
        state.reject = reject;
      });
    }
    clearTimeout(state.timeout);
    state.latestArgs = args;
    state.timeout = setTimeout(() => {
      const s = state;
      state = void 0;
      try {
        s.resolve(callback(...s.latestArgs));
      } catch (e) {
        s.reject(e);
      }
    }, wait);
    return state.promise;
  };
  fn.cancel = () => {
    if (!state)
      return;
    clearTimeout(state.timeout);
  };
  return fn;
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/error.mjs
var annotationsByError = /* @__PURE__ */ new WeakMap();
function annotateError(error, annotations) {
  if (typeof error !== "object" || error === null)
    return;
  let currentAnnotations = annotationsByError.get(error);
  if (!currentAnnotations) {
    currentAnnotations = { tags: {}, extras: {} };
    annotationsByError.set(error, currentAnnotations);
  }
  if (annotations.tags) {
    currentAnnotations.tags = {
      ...currentAnnotations.tags,
      ...annotations.tags
    };
  }
  if (annotations.extras) {
    currentAnnotations.extras = {
      ...currentAnnotations.extras,
      ...annotations.extras
    };
  }
}
function getErrorAnnotations(error) {
  return annotationsByError.get(error) ?? { tags: {}, extras: {} };
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/file.mjs
var FileHelpers = class {
  /**
   * @param dataURL - The file as a string.
   * @internal
   *
   * from https://stackoverflow.com/a/53817185
   */
  static async base64ToFile(dataURL) {
    return fetch(dataURL).then(function(result) {
      return result.arrayBuffer();
    });
  }
  /**
   * Convert a file to base64.
   *
   * @example
   *
   * ```ts
   * const A = fileToBase64('./test.png')
   * ```
   *
   * @param value - The file as a blob.
   * @public
   */
  static async fileToBase64(file) {
    return await new Promise((resolve, reject) => {
      if (file) {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = (error) => reject(error);
        reader.onabort = (error) => reject(error);
      }
    });
  }
};

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/hash.mjs
function getHashForString(string2) {
  let hash2 = 0;
  for (let i = 0; i < string2.length; i++) {
    hash2 = (hash2 << 5) - hash2 + string2.charCodeAt(i);
    hash2 |= 0;
  }
  return hash2 + "";
}
function getHashForObject(obj) {
  return getHashForString(JSON.stringify(obj));
}
function lns(str) {
  const result = str.split("");
  result.push(...result.splice(0, Math.round(result.length / 5)));
  result.push(...result.splice(0, Math.round(result.length / 4)));
  result.push(...result.splice(0, Math.round(result.length / 3)));
  result.push(...result.splice(0, Math.round(result.length / 2)));
  return result.reverse().map((n) => +n ? +n < 5 ? 5 + +n : +n > 5 ? +n - 5 : n : n).join("");
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/iterable.mjs
function getFirstFromIterable(set) {
  return set.values().next().value;
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/png.mjs
var TABLE = [
  0,
  1996959894,
  3993919788,
  2567524794,
  124634137,
  1886057615,
  3915621685,
  2657392035,
  249268274,
  2044508324,
  3772115230,
  2547177864,
  162941995,
  2125561021,
  3887607047,
  2428444049,
  498536548,
  1789927666,
  4089016648,
  2227061214,
  450548861,
  1843258603,
  4107580753,
  2211677639,
  325883990,
  1684777152,
  4251122042,
  2321926636,
  335633487,
  1661365465,
  4195302755,
  2366115317,
  997073096,
  1281953886,
  3579855332,
  2724688242,
  1006888145,
  1258607687,
  3524101629,
  2768942443,
  901097722,
  1119000684,
  3686517206,
  2898065728,
  853044451,
  1172266101,
  3705015759,
  2882616665,
  651767980,
  1373503546,
  3369554304,
  3218104598,
  565507253,
  1454621731,
  3485111705,
  3099436303,
  671266974,
  1594198024,
  3322730930,
  2970347812,
  795835527,
  1483230225,
  3244367275,
  3060149565,
  1994146192,
  31158534,
  2563907772,
  4023717930,
  1907459465,
  112637215,
  2680153253,
  3904427059,
  2013776290,
  251722036,
  2517215374,
  3775830040,
  2137656763,
  141376813,
  2439277719,
  3865271297,
  1802195444,
  476864866,
  2238001368,
  4066508878,
  1812370925,
  453092731,
  2181625025,
  4111451223,
  1706088902,
  314042704,
  2344532202,
  4240017532,
  1658658271,
  366619977,
  2362670323,
  4224994405,
  1303535960,
  984961486,
  2747007092,
  3569037538,
  1256170817,
  1037604311,
  2765210733,
  3554079995,
  1131014506,
  879679996,
  2909243462,
  3663771856,
  1141124467,
  855842277,
  2852801631,
  3708648649,
  1342533948,
  654459306,
  3188396048,
  3373015174,
  1466479909,
  544179635,
  3110523913,
  3462522015,
  1591671054,
  702138776,
  2966460450,
  3352799412,
  1504918807,
  783551873,
  3082640443,
  3233442989,
  3988292384,
  2596254646,
  62317068,
  1957810842,
  3939845945,
  2647816111,
  81470997,
  1943803523,
  3814918930,
  2489596804,
  225274430,
  2053790376,
  3826175755,
  2466906013,
  167816743,
  2097651377,
  4027552580,
  2265490386,
  503444072,
  1762050814,
  4150417245,
  2154129355,
  426522225,
  1852507879,
  4275313526,
  2312317920,
  282753626,
  1742555852,
  4189708143,
  2394877945,
  397917763,
  1622183637,
  3604390888,
  2714866558,
  953729732,
  1340076626,
  3518719985,
  2797360999,
  1068828381,
  1219638859,
  3624741850,
  2936675148,
  906185462,
  1090812512,
  3747672003,
  2825379669,
  829329135,
  1181335161,
  3412177804,
  3160834842,
  628085408,
  1382605366,
  3423369109,
  3138078467,
  570562233,
  1426400815,
  3317316542,
  2998733608,
  733239954,
  1555261956,
  3268935591,
  3050360625,
  752459403,
  1541320221,
  2607071920,
  3965973030,
  1969922972,
  40735498,
  2617837225,
  3943577151,
  1913087877,
  83908371,
  2512341634,
  3803740692,
  2075208622,
  213261112,
  2463272603,
  3855990285,
  2094854071,
  198958881,
  2262029012,
  4057260610,
  1759359992,
  534414190,
  2176718541,
  4139329115,
  1873836001,
  414664567,
  2282248934,
  4279200368,
  1711684554,
  285281116,
  2405801727,
  4167216745,
  1634467795,
  376229701,
  2685067896,
  3608007406,
  1308918612,
  956543938,
  2808555105,
  3495958263,
  1231636301,
  1047427035,
  2932959818,
  3654703836,
  1088359270,
  936918e3,
  2847714899,
  3736837829,
  1202900863,
  817233897,
  3183342108,
  3401237130,
  1404277552,
  615818150,
  3134207493,
  3453421203,
  1423857449,
  601450431,
  3009837614,
  3294710456,
  1567103746,
  711928724,
  3020668471,
  3272380065,
  1510334235,
  755167117
];
if (typeof Int32Array !== "undefined") {
  TABLE = new Int32Array(TABLE);
}
var crc = (current, previous) => {
  let crc2 = previous === 0 ? 0 : ~~previous ^ -1;
  for (let index2 = 0; index2 < current.length; index2++) {
    crc2 = TABLE[(crc2 ^ current[index2]) & 255] ^ crc2 >>> 8;
  }
  return crc2 ^ -1;
};
var LEN_SIZE = 4;
var CRC_SIZE = 4;
var PngHelpers = class _PngHelpers {
  static isPng(view, offset2) {
    if (view.getUint8(offset2 + 0) === 137 && view.getUint8(offset2 + 1) === 80 && view.getUint8(offset2 + 2) === 78 && view.getUint8(offset2 + 3) === 71 && view.getUint8(offset2 + 4) === 13 && view.getUint8(offset2 + 5) === 10 && view.getUint8(offset2 + 6) === 26 && view.getUint8(offset2 + 7) === 10) {
      return true;
    }
    return false;
  }
  static getChunkType(view, offset2) {
    return [
      String.fromCharCode(view.getUint8(offset2)),
      String.fromCharCode(view.getUint8(offset2 + 1)),
      String.fromCharCode(view.getUint8(offset2 + 2)),
      String.fromCharCode(view.getUint8(offset2 + 3))
    ].join("");
  }
  static readChunks(view, offset2 = 0) {
    const chunks = {};
    if (!_PngHelpers.isPng(view, offset2)) {
      throw new Error("Not a PNG");
    }
    offset2 += 8;
    while (offset2 <= view.buffer.byteLength) {
      const start = offset2;
      const len = view.getInt32(offset2);
      offset2 += 4;
      const chunkType = _PngHelpers.getChunkType(view, offset2);
      if (chunkType === "IDAT" && chunks[chunkType]) {
        offset2 += len + LEN_SIZE + CRC_SIZE;
        continue;
      }
      if (chunkType === "IEND") {
        break;
      }
      chunks[chunkType] = {
        start,
        dataOffset: offset2 + 4,
        size: len
      };
      offset2 += len + LEN_SIZE + CRC_SIZE;
    }
    return chunks;
  }
  static parsePhys(view, offset2) {
    return {
      ppux: view.getUint32(offset2),
      ppuy: view.getUint32(offset2 + 4),
      unit: view.getUint8(offset2 + 4)
    };
  }
  static findChunk(view, type) {
    const chunks = _PngHelpers.readChunks(view);
    return chunks[type];
  }
  static setPhysChunk(view, dpr = 1, options) {
    let offset2 = 46;
    let size2 = 0;
    const res1 = _PngHelpers.findChunk(view, "pHYs");
    if (res1) {
      offset2 = res1.start;
      size2 = res1.size;
    }
    const res2 = _PngHelpers.findChunk(view, "IDAT");
    if (res2) {
      offset2 = res2.start;
      size2 = 0;
    }
    const pHYsData = new ArrayBuffer(21);
    const pHYsDataView = new DataView(pHYsData);
    pHYsDataView.setUint32(0, 9);
    pHYsDataView.setUint8(4, "p".charCodeAt(0));
    pHYsDataView.setUint8(5, "H".charCodeAt(0));
    pHYsDataView.setUint8(6, "Y".charCodeAt(0));
    pHYsDataView.setUint8(7, "s".charCodeAt(0));
    const DPI_96 = 2835.5;
    pHYsDataView.setInt32(8, DPI_96 * dpr);
    pHYsDataView.setInt32(12, DPI_96 * dpr);
    pHYsDataView.setInt8(16, 1);
    const crcBit = new Uint8Array(pHYsData.slice(4, 17));
    pHYsDataView.setInt32(17, crc(crcBit));
    const startBuf = view.buffer.slice(0, offset2);
    const endBuf = view.buffer.slice(offset2 + size2);
    return new Blob([startBuf, pHYsData, endBuf], options);
  }
};

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/media.mjs
var MediaHelpers = class {
  /**
   * Get the size of a video from its source.
   *
   * @param src - The source of the video.
   * @public
   */
  static async getVideoSizeFromSrc(src) {
    return await new Promise((resolve, reject) => {
      const video = document.createElement("video");
      video.onloadeddata = () => resolve({ w: video.videoWidth, h: video.videoHeight });
      video.onerror = (e) => {
        console.error(e);
        reject(new Error("Could not get video size"));
      };
      video.crossOrigin = "anonymous";
      video.src = src;
    });
  }
  /**
   * Get the size of an image from its source.
   *
   * @param dataURL - The file as a string.
   * @public
   */
  static async getImageSizeFromSrc(dataURL) {
    return await new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = async () => {
        try {
          const blob = await FileHelpers.base64ToFile(dataURL);
          const view = new DataView(blob);
          if (PngHelpers.isPng(view, 0)) {
            const physChunk = PngHelpers.findChunk(view, "pHYs");
            if (physChunk) {
              const physData = PngHelpers.parsePhys(view, physChunk.dataOffset);
              if (physData.unit === 0 && physData.ppux === physData.ppuy) {
                const pixelRatio = Math.round(physData.ppux / 2834.5);
                resolve({ w: img.width / pixelRatio, h: img.height / pixelRatio });
                return;
              }
            }
          }
          resolve({ w: img.width, h: img.height });
        } catch (err) {
          console.error(err);
          resolve({ w: img.width, h: img.height });
        }
      };
      img.onerror = (err) => {
        console.error(err);
        reject(new Error("Could not get image size"));
      };
      img.crossOrigin = "anonymous";
      img.src = dataURL;
    });
  }
};

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/number.mjs
function lerp(a, b, t2) {
  return a + (b - a) * t2;
}
function rng(seed = "") {
  let x = 0;
  let y = 0;
  let z = 0;
  let w = 0;
  function next() {
    const t2 = x ^ x << 11;
    x = y;
    y = z;
    z = w;
    w ^= (w >>> 19 ^ t2 ^ t2 >>> 8) >>> 0;
    return w / 4294967296 * 2;
  }
  for (let k = 0; k < seed.length + 64; k++) {
    x ^= seed.charCodeAt(k) | 0;
    next();
  }
  return next;
}
function modulate(value, rangeA, rangeB, clamp4 = false) {
  const [fromLow, fromHigh] = rangeA;
  const [v0, v1] = rangeB;
  const result = v0 + (value - fromLow) / (fromHigh - fromLow) * (v1 - v0);
  return clamp4 ? v0 < v1 ? Math.max(Math.min(result, v1), v0) : Math.max(Math.min(result, v0), v1) : result;
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/object.mjs
function hasOwnProperty(obj, key) {
  return Object.prototype.hasOwnProperty.call(obj, key);
}
function getOwnProperty(obj, key) {
  if (!hasOwnProperty(obj, key)) {
    return void 0;
  }
  return obj[key];
}
function deepCopy(obj) {
  if (!obj)
    return obj;
  if (Array.isArray(obj)) {
    const arr = [];
    const length = obj.length;
    for (let i = 0; i < length; i++)
      arr.push(deepCopy(obj[i]));
    return arr;
  } else if (typeof obj === "object") {
    const keys = Object.keys(obj);
    const length = keys.length;
    const newObject = {};
    for (let i = 0; i < length; i++) {
      const key = keys[i];
      newObject[key] = deepCopy(obj[key]);
    }
    return newObject;
  }
  return obj;
}
function objectMapKeys(object2) {
  return Object.keys(object2);
}
function objectMapValues(object2) {
  return Object.values(object2);
}
function objectMapEntries(object2) {
  return Object.entries(object2);
}
function objectMapFromEntries(entries) {
  return Object.fromEntries(entries);
}
function filterEntries(object2, predicate) {
  const result = {};
  let didChange = false;
  for (const [key, value] of objectMapEntries(object2)) {
    if (predicate(key, value)) {
      result[key] = value;
    } else {
      didChange = true;
    }
  }
  return didChange ? result : object2;
}
function mapObjectMapValues(object2, mapper) {
  const result = {};
  for (const [key, value] of objectMapEntries(object2)) {
    const newValue = mapper(key, value);
    result[key] = newValue;
  }
  return result;
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/raf.mjs
var isTest = () => typeof process !== "undefined" && false;
var rafQueue = [];
var tick = () => {
  const queue = rafQueue.splice(0, rafQueue.length);
  for (const fn of queue) {
    fn();
  }
};
var frame;
function raf() {
  if (frame) {
    return;
  }
  frame = requestAnimationFrame(() => {
    frame = void 0;
    tick();
  });
}
function rafThrottle(fn) {
  if (isTest()) {
    return fn;
  }
  return () => {
    if (rafQueue.includes(fn)) {
      return;
    }
    rafQueue.push(fn);
    raf();
  };
}
function throttledRaf(fn) {
  if (isTest()) {
    return fn();
  }
  if (rafQueue.includes(fn)) {
    return;
  }
  rafQueue.push(fn);
  raf();
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/sort.mjs
function sortById(a, b) {
  return a.id > b.id ? 1 : -1;
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/url.mjs
var VALID_URL_REGEX = new RegExp(
  /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i
);
function isValidUrl(url) {
  return VALID_URL_REGEX.test(url);
}

// node_modules/.deno/@tldraw+utils@2.0.0-alpha.17/node_modules/@tldraw/utils/dist-esm/lib/value.mjs
function isDefined(value) {
  return value !== void 0;
}
function isNonNull(value) {
  return value !== null;
}
function isNonNullish(value) {
  return value !== null && value !== void 0;
}
var structuredClone2 = typeof window !== "undefined" && window.structuredClone ? window.structuredClone : (i) => i ? JSON.parse(JSON.stringify(i)) : i;

// node_modules/.deno/nanoid@4.0.2/node_modules/nanoid/index.browser.js
var nanoid = (size2 = 21) => crypto.getRandomValues(new Uint8Array(size2)).reduce((id, byte) => {
  byte &= 63;
  if (byte < 36) {
    id += byte.toString(36);
  } else if (byte < 62) {
    id += (byte - 26).toString(36).toUpperCase();
  } else if (byte > 62) {
    id += "-";
  } else {
    id += "_";
  }
  return id;
}, "");

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/RecordType.mjs
var RecordType = class _RecordType {
  constructor(typeName, config) {
    this.typeName = typeName;
    this.createDefaultProperties = config.createDefaultProperties;
    this.migrations = config.migrations;
    this.validator = config.validator ?? { validate: (r) => r };
    this.scope = config.scope ?? "document";
  }
  createDefaultProperties;
  migrations;
  validator;
  scope;
  /**
   * Create a new record of this type.
   *
   * @param properties - The properties of the record.
   * @returns The new record.
   */
  create(properties) {
    const result = { ...this.createDefaultProperties(), id: this.createId() };
    for (const [k, v] of Object.entries(properties)) {
      if (v !== void 0) {
        result[k] = v;
      }
    }
    result.typeName = this.typeName;
    return result;
  }
  /**
   * Clone a record of this type.
   *
   * @param record - The record to clone.
   * @returns The cloned record.
   * @public
   */
  clone(record) {
    return { ...structuredClone2(record), id: this.createId() };
  }
  /**
   * Create a new ID for this record type.
   *
   * @example
   *
   * ```ts
   * const id = recordType.createId()
   * ```
   *
   * @returns The new ID.
   * @public
   */
  createId(customUniquePart) {
    return this.typeName + ":" + (customUniquePart ?? nanoid());
  }
  /**
   * Create a new ID for this record type based on the given ID.
   *
   * @example
   *
   * ```ts
   * const id = recordType.createCustomId('myId')
   * ```
   *
   * @deprecated - Use `createId` instead.
   * @param id - The ID to base the new ID on.
   * @returns The new ID.
   */
  createCustomId(id) {
    return this.typeName + ":" + id;
  }
  /**
   * Takes an id like `user:123` and returns the part after the colon `123`
   *
   * @param id - The id
   * @returns
   */
  parseId(id) {
    if (!this.isId(id)) {
      throw new Error(`ID "${id}" is not a valid ID for type "${this.typeName}"`);
    }
    return id.slice(this.typeName.length + 1);
  }
  /**
   * Check whether a record is an instance of this record type.
   *
   * @example
   *
   * ```ts
   * const result = recordType.isInstance(someRecord)
   * ```
   *
   * @param record - The record to check.
   * @returns Whether the record is an instance of this record type.
   */
  isInstance = (record) => {
    return record?.typeName === this.typeName;
  };
  /**
   * Check whether an id is an id of this type.
   *
   * @example
   *
   * ```ts
   * const result = recordType.isIn('someId')
   * ```
   *
   * @param id - The id to check.
   * @returns Whether the id is an id of this type.
   */
  isId(id) {
    if (!id)
      return false;
    for (let i = 0; i < this.typeName.length; i++) {
      if (id[i] !== this.typeName[i])
        return false;
    }
    return id[this.typeName.length] === ":";
  }
  /**
   * Create a new RecordType that has the same type name as this RecordType and includes the given
   * default properties.
   *
   * @example
   *
   * ```ts
   * const authorType = createRecordType('author', () => ({ living: true }))
   * const deadAuthorType = authorType.withDefaultProperties({ living: false })
   * ```
   *
   * @param fn - A function that returns the default properties of the new RecordType.
   * @returns The new RecordType.
   */
  withDefaultProperties(createDefaultProperties) {
    return new _RecordType(this.typeName, {
      createDefaultProperties,
      migrations: this.migrations,
      validator: this.validator,
      scope: this.scope
    });
  }
  /**
   * Check that the passed in record passes the validations for this type. Returns its input
   * correctly typed if it does, but throws an error otherwise.
   */
  validate(record) {
    return this.validator.validate(record);
  }
};
function createRecordType(typeName, config) {
  return new RecordType(typeName, {
    createDefaultProperties: () => ({}),
    migrations: config.migrations ?? { currentVersion: 0, firstVersion: 0, migrators: {} },
    validator: config.validator,
    scope: config.scope
  });
}
function assertIdType(id, type) {
  if (!id || !type.isId(id)) {
    throw new Error(`string ${JSON.stringify(id)} is not a valid ${type.typeName} id`);
  }
}

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/Cache.mjs
var Cache = class {
  /** The map of items to their cached values. */
  items = /* @__PURE__ */ new WeakMap();
  /**
   * Get the cached value for a given record. If the record is not present in the map, the callback
   * will be used to create the value (with the result being stored in the cache for next time).
   *
   * @param item - The item to get.
   * @param cb - The callback to use to create the value when a cached value is not found.
   */
  get(item, cb) {
    if (!this.items.has(item)) {
      this.items.set(item, cb(item));
    }
    return this.items.get(item);
  }
};

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/StoreQueries.mjs
var import_lodash = __toESM(require_lodash(), 1);

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/setUtils.mjs
function intersectSets(sets) {
  if (sets.length === 0)
    return /* @__PURE__ */ new Set();
  const first = sets[0];
  const rest = sets.slice(1);
  const result = /* @__PURE__ */ new Set();
  for (const val of first) {
    if (rest.every((set) => set.has(val))) {
      result.add(val);
    }
  }
  return result;
}
function diffSets(prev, next) {
  const result = {};
  for (const val of next) {
    if (!prev.has(val)) {
      result.added ??= /* @__PURE__ */ new Set();
      result.added.add(val);
    }
  }
  for (const val of prev) {
    if (!next.has(val)) {
      result.removed ??= /* @__PURE__ */ new Set();
      result.removed.add(val);
    }
  }
  return result.added || result.removed ? result : void 0;
}

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/executeQuery.mjs
function objectMatchesQuery(query, object2) {
  for (const [key, _matcher] of Object.entries(query)) {
    const matcher = _matcher;
    const value = object2[key];
    if ("eq" in matcher && value !== matcher.eq)
      return false;
    if ("neq" in matcher && value === matcher.neq)
      return false;
    if ("gt" in matcher && (typeof value !== "number" || value <= matcher.gt))
      return false;
  }
  return true;
}
function executeQuery(store, typeName, query) {
  const matchIds = Object.fromEntries(Object.keys(query).map((key) => [key, /* @__PURE__ */ new Set()]));
  for (const [k, matcher] of Object.entries(query)) {
    if ("eq" in matcher) {
      const index2 = store.index(typeName, k);
      const ids = index2.value.get(matcher.eq);
      if (ids) {
        for (const id of ids) {
          matchIds[k].add(id);
        }
      }
    } else if ("neq" in matcher) {
      const index2 = store.index(typeName, k);
      for (const [value, ids] of index2.value) {
        if (value !== matcher.neq) {
          for (const id of ids) {
            matchIds[k].add(id);
          }
        }
      }
    } else if ("gt" in matcher) {
      const index2 = store.index(typeName, k);
      for (const [value, ids] of index2.value) {
        if (value > matcher.gt) {
          for (const id of ids) {
            matchIds[k].add(id);
          }
        }
      }
    }
  }
  return intersectSets(Object.values(matchIds));
}

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/StoreQueries.mjs
var StoreQueries = class {
  constructor(atoms, history) {
    this.atoms = atoms;
    this.history = history;
  }
  /**
   * A cache of derivations (indexes).
   *
   * @internal
   */
  indexCache = /* @__PURE__ */ new Map();
  /**
   * A cache of derivations (filtered histories).
   *
   * @internal
   */
  historyCache = /* @__PURE__ */ new Map();
  /**
   * Create a derivation that contains the hisotry for a given type
   *
   * @param typeName - The name of the type to filter by.
   * @returns A derivation that returns the ids of all records of the given type.
   * @public
   */
  filterHistory(typeName) {
    if (this.historyCache.has(typeName)) {
      return this.historyCache.get(typeName);
    }
    const filtered = computed(
      "filterHistory:" + typeName,
      (lastValue, lastComputedEpoch) => {
        if (isUninitialized(lastValue)) {
          return this.history.value;
        }
        const diff = this.history.getDiffSince(lastComputedEpoch);
        if (diff === RESET_VALUE)
          return this.history.value;
        const res = { added: {}, removed: {}, updated: {} };
        let numAdded = 0;
        let numRemoved = 0;
        let numUpdated = 0;
        for (const changes of diff) {
          for (const added of objectMapValues(changes.added)) {
            if (added.typeName === typeName) {
              if (res.removed[added.id]) {
                const original = res.removed[added.id];
                delete res.removed[added.id];
                numRemoved--;
                if (original !== added) {
                  res.updated[added.id] = [original, added];
                  numUpdated++;
                }
              } else {
                res.added[added.id] = added;
                numAdded++;
              }
            }
          }
          for (const [from, to] of objectMapValues(changes.updated)) {
            if (to.typeName === typeName) {
              if (res.added[to.id]) {
                res.added[to.id] = to;
              } else if (res.updated[to.id]) {
                res.updated[to.id] = [res.updated[to.id][0], to];
              } else {
                res.updated[to.id] = [from, to];
                numUpdated++;
              }
            }
          }
          for (const removed of objectMapValues(changes.removed)) {
            if (removed.typeName === typeName) {
              if (res.added[removed.id]) {
                delete res.added[removed.id];
                numAdded--;
              } else if (res.updated[removed.id]) {
                res.removed[removed.id] = res.updated[removed.id][0];
                delete res.updated[removed.id];
                numUpdated--;
                numRemoved++;
              } else {
                res.removed[removed.id] = removed;
                numRemoved++;
              }
            }
          }
        }
        if (numAdded || numRemoved || numUpdated) {
          return withDiff(this.history.value, res);
        } else {
          return lastValue;
        }
      },
      { historyLength: 100 }
    );
    this.historyCache.set(typeName, filtered);
    return filtered;
  }
  /**
   * Create a derivation that returns an index on a property for the given type.
   *
   * @param typeName - The name of the type.
   * @param property - The name of the property.
   * @public
   */
  index(typeName, property) {
    const cacheKey = typeName + ":" + property;
    if (this.indexCache.has(cacheKey)) {
      return this.indexCache.get(cacheKey);
    }
    const index2 = this.__uncached_createIndex(typeName, property);
    this.indexCache.set(cacheKey, index2);
    return index2;
  }
  /**
   * Create a derivation that returns an index on a property for the given type.
   *
   * @param typeName - The name of the type?.
   * @param property - The name of the property?.
   * @internal
   */
  __uncached_createIndex(typeName, property) {
    const typeHistory = this.filterHistory(typeName);
    const fromScratch = () => {
      typeHistory.value;
      const res = /* @__PURE__ */ new Map();
      for (const atom2 of objectMapValues(this.atoms.value)) {
        const record = atom2.value;
        if (record.typeName === typeName) {
          const value = record[property];
          if (!res.has(value)) {
            res.set(value, /* @__PURE__ */ new Set());
          }
          res.get(value).add(record.id);
        }
      }
      return res;
    };
    return computed(
      "index:" + typeName + ":" + property,
      (prevValue, lastComputedEpoch) => {
        if (isUninitialized(prevValue))
          return fromScratch();
        const history = typeHistory.getDiffSince(lastComputedEpoch);
        if (history === RESET_VALUE) {
          return fromScratch();
        }
        const setConstructors = /* @__PURE__ */ new Map();
        const add = (value, id) => {
          let setConstructor = setConstructors.get(value);
          if (!setConstructor)
            setConstructor = new IncrementalSetConstructor(
              prevValue.get(value) ?? /* @__PURE__ */ new Set()
            );
          setConstructor.add(id);
          setConstructors.set(value, setConstructor);
        };
        const remove2 = (value, id) => {
          let set = setConstructors.get(value);
          if (!set)
            set = new IncrementalSetConstructor(prevValue.get(value) ?? /* @__PURE__ */ new Set());
          set.remove(id);
          setConstructors.set(value, set);
        };
        for (const changes of history) {
          for (const record of objectMapValues(changes.added)) {
            if (record.typeName === typeName) {
              const value = record[property];
              add(value, record.id);
            }
          }
          for (const [from, to] of objectMapValues(changes.updated)) {
            if (to.typeName === typeName) {
              const prev = from[property];
              const next = to[property];
              if (prev !== next) {
                remove2(prev, to.id);
                add(next, to.id);
              }
            }
          }
          for (const record of objectMapValues(changes.removed)) {
            if (record.typeName === typeName) {
              const value = record[property];
              remove2(value, record.id);
            }
          }
        }
        let nextValue = void 0;
        let nextDiff = void 0;
        for (const [value, setConstructor] of setConstructors) {
          const result = setConstructor.get();
          if (!result)
            continue;
          if (!nextValue)
            nextValue = new Map(prevValue);
          if (!nextDiff)
            nextDiff = /* @__PURE__ */ new Map();
          if (result.value.size === 0) {
            nextValue.delete(value);
          } else {
            nextValue.set(value, result.value);
          }
          nextDiff.set(value, result.diff);
        }
        if (nextValue && nextDiff) {
          return withDiff(nextValue, nextDiff);
        }
        return prevValue;
      },
      { historyLength: 100 }
    );
  }
  /**
   * Create a derivation that will return a signle record matching the given query.
   *
   * It will return undefined if there is no matching record
   *
   * @param typeName - The name of the type?
   * @param queryCreator - A function that returns the query expression.
   * @param name - (optinal) The name of the query.
   */
  record(typeName, queryCreator = () => ({}), name = "record:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) {
    const ids = this.ids(typeName, queryCreator, name);
    return computed(name, () => {
      for (const id of ids.value) {
        return this.atoms.value[id]?.value;
      }
      return void 0;
    });
  }
  /**
   * Create a derivation that will return an array of records matching the given query
   *
   * @param typeName - The name of the type?
   * @param queryCreator - A function that returns the query expression.
   * @param name - (optinal) The name of the query.
   */
  records(typeName, queryCreator = () => ({}), name = "records:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) {
    const ids = this.ids(typeName, queryCreator, "ids:" + name);
    return computed(name, () => {
      return [...ids.value].map((id) => {
        const atom2 = this.atoms.value[id];
        if (!atom2) {
          throw new Error("no atom found for record id: " + id);
        }
        return atom2.value;
      });
    });
  }
  /**
   * Create a derivation that will return the ids of all records of the given type.
   *
   * @param typeName - The name of the type.
   * @param queryCreator - A function that returns the query expression.
   * @param name - (optinal) The name of the query.
   */
  ids(typeName, queryCreator = () => ({}), name = "ids:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) {
    const typeHistory = this.filterHistory(typeName);
    const fromScratch = () => {
      typeHistory.value;
      const query = queryCreator();
      if (Object.keys(query).length === 0) {
        return new Set(
          objectMapValues(this.atoms.value).flatMap((v) => {
            const r = v.value;
            if (r.typeName === typeName) {
              return r.id;
            } else {
              return [];
            }
          })
        );
      }
      return executeQuery(this, typeName, query);
    };
    const fromScratchWithDiff = (prevValue) => {
      const nextValue = fromScratch();
      const diff = diffSets(prevValue, nextValue);
      if (diff) {
        return withDiff(nextValue, diff);
      } else {
        return prevValue;
      }
    };
    const cachedQuery = computed("ids_query:" + name, queryCreator, {
      isEqual: import_lodash.default
    });
    return computed(
      "query:" + name,
      (prevValue, lastComputedEpoch) => {
        const query = cachedQuery.value;
        if (isUninitialized(prevValue)) {
          return fromScratch();
        }
        if (lastComputedEpoch < cachedQuery.lastChangedEpoch) {
          return fromScratchWithDiff(prevValue);
        }
        const history = typeHistory.getDiffSince(lastComputedEpoch);
        if (history === RESET_VALUE) {
          return fromScratchWithDiff(prevValue);
        }
        const setConstructor = new IncrementalSetConstructor(
          prevValue
        );
        for (const changes of history) {
          for (const added of objectMapValues(changes.added)) {
            if (added.typeName === typeName && objectMatchesQuery(query, added)) {
              setConstructor.add(added.id);
            }
          }
          for (const [_, updated] of objectMapValues(changes.updated)) {
            if (updated.typeName === typeName) {
              if (objectMatchesQuery(query, updated)) {
                setConstructor.add(updated.id);
              } else {
                setConstructor.remove(updated.id);
              }
            }
          }
          for (const removed of objectMapValues(changes.removed)) {
            if (removed.typeName === typeName) {
              setConstructor.remove(removed.id);
            }
          }
        }
        const result = setConstructor.get();
        if (!result) {
          return prevValue;
        }
        return withDiff(result.value, result.diff);
      },
      { historyLength: 50 }
    );
  }
  exec(typeName, query) {
    const ids = executeQuery(this, typeName, query);
    if (ids.size === 0) {
      return EMPTY_ARRAY;
    }
    const atoms = this.atoms.value;
    return [...ids].map((id) => atoms[id].value);
  }
};

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/devFreeze.mjs
function devFreeze(object2) {
  if (false) {
    return object2;
  }
  const proto = Object.getPrototypeOf(object2);
  if (proto && !(proto === Array.prototype || proto === Object.prototype)) {
    console.error("cannot include non-js data in a record", object2);
    throw new Error("cannot include non-js data in a record");
  }
  const propNames = Object.getOwnPropertyNames(object2);
  for (const name of propNames) {
    const value = object2[name];
    if (value && typeof value === "object") {
      devFreeze(value);
    }
  }
  return Object.freeze(object2);
}

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/Store.mjs
var Store = class {
  /**
   * The random id of the store.
   */
  id = nanoid();
  /**
   * An atom containing the store's atoms.
   *
   * @internal
   * @readonly
   */
  atoms = atom("store_atoms", {});
  /**
   * An atom containing the store's history.
   *
   * @public
   * @readonly
   */
  history = atom("history", 0, {
    historyLength: 1e3
  });
  /**
   * A StoreQueries instance for this store.
   *
   * @public
   * @readonly
   */
  query = new StoreQueries(this.atoms, this.history);
  /**
   * A set containing listeners that have been added to this store.
   *
   * @internal
   */
  listeners = /* @__PURE__ */ new Set();
  /**
   * An array of history entries that have not yet been flushed.
   *
   * @internal
   */
  historyAccumulator = new HistoryAccumulator();
  /**
   * A reactor that responds to changes to the history by squashing the accumulated history and
   * notifying listeners of the changes.
   *
   * @internal
   */
  historyReactor;
  schema;
  props;
  scopedTypes;
  constructor(config) {
    const { initialData, schema } = config;
    this.schema = schema;
    this.props = config.props;
    if (initialData) {
      this.atoms.set(
        objectMapFromEntries(
          objectMapEntries(initialData).map(([id, record]) => [
            id,
            atom("atom:" + id, this.schema.validateRecord(this, record, "initialize", null))
          ])
        )
      );
    }
    this.historyReactor = reactor(
      "Store.historyReactor",
      () => {
        this.history.value;
        this._flushHistory();
      },
      { scheduleEffect: (cb) => throttledRaf(cb) }
    );
    this.scopedTypes = {
      document: new Set(
        objectMapValues(this.schema.types).filter((t2) => t2.scope === "document").map((t2) => t2.typeName)
      ),
      session: new Set(
        objectMapValues(this.schema.types).filter((t2) => t2.scope === "session").map((t2) => t2.typeName)
      ),
      presence: new Set(
        objectMapValues(this.schema.types).filter((t2) => t2.scope === "presence").map((t2) => t2.typeName)
      )
    };
  }
  _flushHistory() {
    if (this.historyAccumulator.hasChanges()) {
      const entries = this.historyAccumulator.flush();
      for (const { changes, source } of entries) {
        let instanceChanges = null;
        let documentChanges = null;
        let presenceChanges = null;
        for (const { onHistory, filters } of this.listeners) {
          if (filters.source !== "all" && filters.source !== source) {
            continue;
          }
          if (filters.scope !== "all") {
            if (filters.scope === "document") {
              documentChanges ??= this.filterChangesByScope(changes, "document");
              if (!documentChanges)
                continue;
              onHistory({ changes: documentChanges, source });
            } else if (filters.scope === "session") {
              instanceChanges ??= this.filterChangesByScope(changes, "session");
              if (!instanceChanges)
                continue;
              onHistory({ changes: instanceChanges, source });
            } else {
              presenceChanges ??= this.filterChangesByScope(changes, "presence");
              if (!presenceChanges)
                continue;
              onHistory({ changes: presenceChanges, source });
            }
          } else {
            onHistory({ changes, source });
          }
        }
      }
    }
  }
  /**
   * Filters out non-document changes from a diff. Returns null if there are no changes left.
   * @param change - the records diff
   * @returns
   */
  filterChangesByScope(change, scope) {
    const result = {
      added: filterEntries(change.added, (_, r) => this.scopedTypes[scope].has(r.typeName)),
      updated: filterEntries(change.updated, (_, r) => this.scopedTypes[scope].has(r[1].typeName)),
      removed: filterEntries(change.removed, (_, r) => this.scopedTypes[scope].has(r.typeName))
    };
    if (Object.keys(result.added).length === 0 && Object.keys(result.updated).length === 0 && Object.keys(result.removed).length === 0) {
      return null;
    }
    return result;
  }
  /**
   * Update the history with a diff of changes.
   *
   * @param changes - The changes to add to the history.
   */
  updateHistory(changes) {
    this.historyAccumulator.add({
      changes,
      source: this.isMergingRemoteChanges ? "remote" : "user"
    });
    if (this.listeners.size === 0) {
      this.historyAccumulator.clear();
    }
    this.history.set(this.history.value + 1, changes);
  }
  validate(phase) {
    this.allRecords().forEach((record) => this.schema.validateRecord(this, record, phase, null));
  }
  /**
   * A callback fired after each record's change.
   *
   * @param prev - The previous value, if any.
   * @param next - The next value.
   */
  onBeforeCreate;
  /**
   * A callback fired after a record is created. Use this to perform related updates to other
   * records in the store.
   *
   * @param record - The record to be created
   */
  onAfterCreate;
  /**
   * A callback before after each record's change.
   *
   * @param prev - The previous value, if any.
   * @param next - The next value.
   */
  onBeforeChange;
  /**
   * A callback fired after each record's change.
   *
   * @param prev - The previous value, if any.
   * @param next - The next value.
   */
  onAfterChange;
  /**
   * A callback fired before a record is deleted.
   *
   * @param prev - The record that will be deleted.
   */
  onBeforeDelete;
  /**
   * A callback fired after a record is deleted.
   *
   * @param prev - The record that will be deleted.
   */
  onAfterDelete;
  // used to avoid running callbacks when rolling back changes in sync client
  _runCallbacks = true;
  /**
   * Add some records to the store. It's an error if they already exist.
   *
   * @param records - The records to add.
   * @public
   */
  put = (records, phaseOverride) => {
    transact(() => {
      const updates = {};
      const additions = {};
      const currentMap = this.atoms.__unsafe__getWithoutCapture();
      let map = null;
      let record;
      let didChange = false;
      const beforeCreate = this.onBeforeCreate && this._runCallbacks ? this.onBeforeCreate : null;
      const beforeUpdate = this.onBeforeChange && this._runCallbacks ? this.onBeforeChange : null;
      const source = this.isMergingRemoteChanges ? "remote" : "user";
      for (let i = 0, n = records.length; i < n; i++) {
        record = records[i];
        const recordAtom = (map ?? currentMap)[record.id];
        if (recordAtom) {
          if (beforeUpdate)
            record = beforeUpdate(recordAtom.value, record, source);
          const initialValue = recordAtom.__unsafe__getWithoutCapture();
          record = this.schema.validateRecord(
            this,
            record,
            phaseOverride ?? "updateRecord",
            initialValue
          );
          recordAtom.set(devFreeze(record));
          const finalValue = recordAtom.__unsafe__getWithoutCapture();
          if (initialValue !== finalValue) {
            didChange = true;
            updates[record.id] = [initialValue, finalValue];
          }
        } else {
          if (beforeCreate)
            record = beforeCreate(record, source);
          didChange = true;
          record = this.schema.validateRecord(
            this,
            record,
            phaseOverride ?? "createRecord",
            null
          );
          additions[record.id] = record;
          if (!map) {
            map = { ...currentMap };
          }
          map[record.id] = atom("atom:" + record.id, record);
        }
      }
      if (map) {
        this.atoms.set(map);
      }
      if (!didChange)
        return;
      this.updateHistory({
        added: additions,
        updated: updates,
        removed: {}
      });
      if (this._runCallbacks) {
        const { onAfterCreate, onAfterChange } = this;
        if (onAfterCreate) {
          Object.values(additions).forEach((record2) => {
            onAfterCreate(record2, source);
          });
        }
        if (onAfterChange) {
          Object.values(updates).forEach(([from, to]) => {
            onAfterChange(from, to, source);
          });
        }
      }
    });
  };
  /**
   * Remove some records from the store via their ids.
   *
   * @param ids - The ids of the records to remove.
   * @public
   */
  remove = (ids) => {
    transact(() => {
      const cancelled = [];
      const source = this.isMergingRemoteChanges ? "remote" : "user";
      if (this.onBeforeDelete && this._runCallbacks) {
        for (const id of ids) {
          const atom2 = this.atoms.__unsafe__getWithoutCapture()[id];
          if (!atom2)
            continue;
          if (this.onBeforeDelete(atom2.value, source) === false) {
            cancelled.push(id);
          }
        }
      }
      let removed = void 0;
      this.atoms.update((atoms) => {
        let result = void 0;
        for (const id of ids) {
          if (cancelled.includes(id))
            continue;
          if (!(id in atoms))
            continue;
          if (!result)
            result = { ...atoms };
          if (!removed)
            removed = {};
          delete result[id];
          removed[id] = atoms[id].value;
        }
        return result ?? atoms;
      });
      if (!removed)
        return;
      this.updateHistory({ added: {}, updated: {}, removed });
      if (this.onAfterDelete && this._runCallbacks) {
        let record;
        for (let i = 0, n = ids.length; i < n; i++) {
          record = removed[ids[i]];
          if (record) {
            this.onAfterDelete(record, source);
          }
        }
      }
    });
  };
  /**
   * Get the value of a store record by its id.
   *
   * @param id - The id of the record to get.
   * @public
   */
  get = (id) => {
    return this.atoms.value[id]?.value;
  };
  /**
   * Get the value of a store record by its id without updating its epoch.
   *
   * @param id - The id of the record to get.
   * @public
   */
  unsafeGetWithoutCapture = (id) => {
    return this.atoms.value[id]?.__unsafe__getWithoutCapture();
  };
  /**
   * Creates a JSON payload from the record store.
   *
   * @param scope - The scope of records to serialize. Defaults to 'document'.
   * @returns The record store snapshot as a JSON payload.
   */
  serialize = (scope = "document") => {
    const result = {};
    for (const [id, atom2] of objectMapEntries(this.atoms.value)) {
      const record = atom2.value;
      if (scope === "all" || this.scopedTypes[scope].has(record.typeName)) {
        result[id] = record;
      }
    }
    return result;
  };
  /**
   * Get a serialized snapshot of the store and its schema.
   *
   * ```ts
   * const snapshot = store.getSnapshot()
   * store.loadSnapshot(snapshot)
   * ```
   *
   * @param scope - The scope of records to serialize. Defaults to 'document'.
   *
   * @public
   */
  getSnapshot(scope = "document") {
    return {
      store: this.serialize(scope),
      schema: this.schema.serialize()
    };
  }
  /**
   * Migrate a serialized snapshot of the store and its schema.
   *
   * ```ts
   * const snapshot = store.getSnapshot()
   * store.migrateSnapshot(snapshot)
   * ```
   *
   * @param snapshot - The snapshot to load.
   * @public
   */
  migrateSnapshot(snapshot) {
    const migrationResult = this.schema.migrateStoreSnapshot(snapshot);
    if (migrationResult.type === "error") {
      throw new Error(`Failed to migrate snapshot: ${migrationResult.reason}`);
    }
    return {
      store: migrationResult.value,
      schema: this.schema.serialize()
    };
  }
  /**
   * Load a serialized snapshot.
   *
   * ```ts
   * const snapshot = store.getSnapshot()
   * store.loadSnapshot(snapshot)
   * ```
   *
   * @param snapshot - The snapshot to load.
   * @public
   */
  loadSnapshot(snapshot) {
    const migrationResult = this.schema.migrateStoreSnapshot(snapshot);
    if (migrationResult.type === "error") {
      throw new Error(`Failed to migrate snapshot: ${migrationResult.reason}`);
    }
    transact(() => {
      this.clear();
      this.put(Object.values(migrationResult.value));
      this.ensureStoreIsUsable();
    });
  }
  /**
   * Get an array of all values in the store.
   *
   * @returns An array of all values in the store.
   * @public
   */
  allRecords = () => {
    return objectMapValues(this.atoms.value).map((atom2) => atom2.value);
  };
  /**
   * Removes all records from the store.
   *
   * @public
   */
  clear = () => {
    this.remove(objectMapKeys(this.atoms.value));
  };
  /**
   * Update a record. To update multiple records at once, use the `update` method of the
   * `TypedStore` class.
   *
   * @param id - The id of the record to update.
   * @param updater - A function that updates the record.
   */
  update = (id, updater) => {
    const atom2 = this.atoms.value[id];
    if (!atom2) {
      console.error(`Record ${id} not found. This is probably an error`);
      return;
    }
    this.put([updater(atom2.__unsafe__getWithoutCapture())]);
  };
  /**
   * Get whether the record store has a id.
   *
   * @param id - The id of the record to check.
   * @public
   */
  has = (id) => {
    return !!this.atoms.value[id];
  };
  /**
   * Add a new listener to the store.
   *
   * @param onHistory - The listener to call when the store updates.
   * @param filters - Filters to apply to the listener.
   * @returns A function to remove the listener.
   */
  listen = (onHistory, filters) => {
    this._flushHistory();
    const listener = {
      onHistory,
      filters: {
        source: filters?.source ?? "all",
        scope: filters?.scope ?? "all"
      }
    };
    this.listeners.add(listener);
    if (!this.historyReactor.scheduler.isActivelyListening) {
      this.historyReactor.start();
    }
    return () => {
      this.listeners.delete(listener);
      if (this.listeners.size === 0) {
        this.historyReactor.stop();
      }
    };
  };
  isMergingRemoteChanges = false;
  /**
   * Merge changes from a remote source without triggering listeners.
   *
   * @param fn - A function that merges the external changes.
   * @public
   */
  mergeRemoteChanges = (fn) => {
    if (this.isMergingRemoteChanges) {
      return fn();
    }
    try {
      this.isMergingRemoteChanges = true;
      transact(fn);
    } finally {
      this.isMergingRemoteChanges = false;
    }
  };
  extractingChanges(fn) {
    const changes = [];
    const dispose = this.historyAccumulator.intercepting((entry) => changes.push(entry.changes));
    try {
      transact(fn);
      return squashRecordDiffs(changes);
    } finally {
      dispose();
    }
  }
  applyDiff(diff, runCallbacks = true) {
    const prevRunCallbacks = this._runCallbacks;
    try {
      this._runCallbacks = runCallbacks;
      transact(() => {
        const toPut = objectMapValues(diff.added).concat(
          objectMapValues(diff.updated).map(([_from, to]) => to)
        );
        const toRemove = objectMapKeys(diff.removed);
        if (toPut.length) {
          this.put(toPut);
        }
        if (toRemove.length) {
          this.remove(toRemove);
        }
      });
    } finally {
      this._runCallbacks = prevRunCallbacks;
    }
  }
  /**
   * Create a computed cache.
   *
   * @param name - The name of the derivation cache.
   * @param derive - A function used to derive the value of the cache.
   * @public
   */
  createComputedCache = (name, derive, isEqual2) => {
    const cache = new Cache();
    return {
      get: (id) => {
        const atom2 = this.atoms.value[id];
        if (!atom2) {
          return void 0;
        }
        return cache.get(atom2, () => {
          const recordSignal = isEqual2 ? computed(atom2.name + ":equals", () => atom2.value, { isEqual: isEqual2 }) : atom2;
          return computed(name + ":" + id, () => {
            return derive(recordSignal.value);
          });
        }).value;
      }
    };
  };
  /**
   * Create a computed cache from a selector
   *
   * @param name - The name of the derivation cache.
   * @param selector - A function that returns a subset of the original shape
   * @param derive - A function used to derive the value of the cache.
   * @public
   */
  createSelectedComputedCache = (name, selector, derive) => {
    const cache = new Cache();
    return {
      get: (id) => {
        const atom2 = this.atoms.value[id];
        if (!atom2) {
          return void 0;
        }
        const d = computed(
          name + ":" + id + ":selector",
          () => selector(atom2.value)
        );
        return cache.get(
          atom2,
          () => computed(name + ":" + id, () => derive(d.value))
        ).value;
      }
    };
  };
  getRecordType = (record) => {
    const type = this.schema.types[record.typeName];
    if (!type) {
      throw new Error(`Record type ${record.typeName} not found`);
    }
    return type;
  };
  _integrityChecker;
  /** @internal */
  ensureStoreIsUsable() {
    this._integrityChecker ??= this.schema.createIntegrityChecker(this);
    this._integrityChecker?.();
  }
  _isPossiblyCorrupted = false;
  /** @internal */
  markAsPossiblyCorrupted() {
    this._isPossiblyCorrupted = true;
  }
  /** @internal */
  isPossiblyCorrupted() {
    return this._isPossiblyCorrupted;
  }
};
function squashRecordDiffs(diffs) {
  const result = { added: {}, removed: {}, updated: {} };
  for (const diff of diffs) {
    for (const [id, value] of objectMapEntries(diff.added)) {
      if (result.removed[id]) {
        const original = result.removed[id];
        delete result.removed[id];
        if (original !== value) {
          result.updated[id] = [original, value];
        }
      } else {
        result.added[id] = value;
      }
    }
    for (const [id, [_from, to]] of objectMapEntries(diff.updated)) {
      if (result.added[id]) {
        result.added[id] = to;
        delete result.updated[id];
        delete result.removed[id];
        continue;
      }
      if (result.updated[id]) {
        result.updated[id][1] = to;
        delete result.removed[id];
        continue;
      }
      result.updated[id] = diff.updated[id];
      delete result.removed[id];
    }
    for (const [id, value] of objectMapEntries(diff.removed)) {
      if (result.added[id]) {
        delete result.added[id];
      } else if (result.updated[id]) {
        result.removed[id] = result.updated[id][0];
        delete result.updated[id];
      } else {
        result.removed[id] = value;
      }
    }
  }
  return result;
}
function squashHistoryEntries(entries) {
  const result = [];
  let current = entries[0];
  let entry;
  for (let i = 1, n = entries.length; i < n; i++) {
    entry = entries[i];
    if (current.source !== entry.source) {
      result.push(current);
      current = entry;
    } else {
      current = {
        source: current.source,
        changes: squashRecordDiffs([current.changes, entry.changes])
      };
    }
  }
  result.push(current);
  return result;
}
function reverseRecordsDiff(diff) {
  const result = { added: diff.removed, removed: diff.added, updated: {} };
  for (const [from, to] of Object.values(diff.updated)) {
    result.updated[from.id] = [to, from];
  }
  return result;
}
var HistoryAccumulator = class {
  _history = [];
  _interceptors = /* @__PURE__ */ new Set();
  intercepting(fn) {
    this._interceptors.add(fn);
    return () => {
      this._interceptors.delete(fn);
    };
  }
  add(entry) {
    this._history.push(entry);
    for (const interceptor of this._interceptors) {
      interceptor(entry);
    }
  }
  flush() {
    const history = squashHistoryEntries(this._history);
    this._history = [];
    return history;
  }
  clear() {
    this._history = [];
  }
  hasChanges() {
    return this._history.length > 0;
  }
};

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/BaseRecord.mjs
function isRecord(record) {
  return typeof record === "object" && record !== null && "id" in record && "typeName" in record;
}

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/migrate.mjs
function defineMigrations(opts) {
  const { currentVersion, firstVersion, migrators = {}, subTypeKey, subTypeMigrations } = opts;
  if (typeof currentVersion === "number" && typeof firstVersion === "number") {
    if (currentVersion === firstVersion) {
      throw Error(`Current version is equal to initial version.`);
    } else if (currentVersion < firstVersion) {
      throw Error(`Current version is lower than initial version.`);
    }
  }
  return {
    firstVersion: firstVersion ?? 0,
    // defaults
    currentVersion: currentVersion ?? 0,
    // defaults
    migrators,
    subTypeKey,
    subTypeMigrations
  };
}
var MigrationFailureReason = ((MigrationFailureReason2) => {
  MigrationFailureReason2["IncompatibleSubtype"] = "incompatible-subtype";
  MigrationFailureReason2["UnknownType"] = "unknown-type";
  MigrationFailureReason2["TargetVersionTooNew"] = "target-version-too-new";
  MigrationFailureReason2["TargetVersionTooOld"] = "target-version-too-old";
  MigrationFailureReason2["MigrationError"] = "migration-error";
  MigrationFailureReason2["UnrecognizedSubtype"] = "unrecognized-subtype";
  return MigrationFailureReason2;
})(MigrationFailureReason || {});
function getRecordVersion(record, serializedSchema) {
  const persistedType = serializedSchema.recordVersions[record.typeName];
  if (!persistedType) {
    return { rootVersion: 0 };
  }
  if ("subTypeKey" in persistedType) {
    const subType = record[persistedType.subTypeKey];
    const subTypeVersion = persistedType.subTypeVersions[subType];
    return { rootVersion: persistedType.version, subTypeVersion };
  }
  return { rootVersion: persistedType.version };
}
function compareRecordVersions(a, b) {
  if (a.rootVersion > b.rootVersion) {
    return 1;
  }
  if (a.rootVersion < b.rootVersion) {
    return -1;
  }
  if (a.subTypeVersion != null && b.subTypeVersion != null) {
    if (a.subTypeVersion > b.subTypeVersion) {
      return 1;
    }
    if (a.subTypeVersion < b.subTypeVersion) {
      return -1;
    }
  }
  return 0;
}
function migrateRecord({
  record,
  migrations,
  fromVersion,
  toVersion
}) {
  let currentVersion = fromVersion;
  if (!isRecord(record))
    throw new Error("[migrateRecord] object is not a record");
  const { typeName, id, ...others } = record;
  let recordWithoutMeta = others;
  while (currentVersion < toVersion) {
    const nextVersion = currentVersion + 1;
    const migrator = migrations.migrators[nextVersion];
    if (!migrator) {
      return {
        type: "error",
        reason: "target-version-too-new"
        /* TargetVersionTooNew */
      };
    }
    recordWithoutMeta = migrator.up(recordWithoutMeta);
    currentVersion = nextVersion;
  }
  while (currentVersion > toVersion) {
    const nextVersion = currentVersion - 1;
    const migrator = migrations.migrators[currentVersion];
    if (!migrator) {
      return {
        type: "error",
        reason: "target-version-too-old"
        /* TargetVersionTooOld */
      };
    }
    recordWithoutMeta = migrator.down(recordWithoutMeta);
    currentVersion = nextVersion;
  }
  return {
    type: "success",
    value: { ...recordWithoutMeta, id, typeName }
  };
}
function migrate({
  value,
  migrations,
  fromVersion,
  toVersion
}) {
  let currentVersion = fromVersion;
  while (currentVersion < toVersion) {
    const nextVersion = currentVersion + 1;
    const migrator = migrations.migrators[nextVersion];
    if (!migrator) {
      return {
        type: "error",
        reason: "target-version-too-new"
        /* TargetVersionTooNew */
      };
    }
    value = migrator.up(value);
    currentVersion = nextVersion;
  }
  while (currentVersion > toVersion) {
    const nextVersion = currentVersion - 1;
    const migrator = migrations.migrators[currentVersion];
    if (!migrator) {
      return {
        type: "error",
        reason: "target-version-too-old"
        /* TargetVersionTooOld */
      };
    }
    value = migrator.down(value);
    currentVersion = nextVersion;
  }
  return {
    type: "success",
    value
  };
}

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/StoreSchema.mjs
var StoreSchema = class _StoreSchema {
  constructor(types, options) {
    this.types = types;
    this.options = options;
  }
  static create(types, options) {
    return new _StoreSchema(types, options ?? {});
  }
  get currentStoreVersion() {
    return this.options.snapshotMigrations?.currentVersion ?? 0;
  }
  validateRecord(store, record, phase, recordBefore) {
    try {
      const recordType = getOwnProperty(this.types, record.typeName);
      if (!recordType) {
        throw new Error(`Missing definition for record type ${record.typeName}`);
      }
      return recordType.validate(record);
    } catch (error) {
      if (this.options.onValidationFailure) {
        return this.options.onValidationFailure({
          store,
          record,
          phase,
          recordBefore,
          error
        });
      } else {
        throw error;
      }
    }
  }
  migratePersistedRecord(record, persistedSchema, direction = "up") {
    const ourType = getOwnProperty(this.types, record.typeName);
    const persistedType = persistedSchema.recordVersions[record.typeName];
    if (!persistedType || !ourType) {
      return { type: "error", reason: MigrationFailureReason.UnknownType };
    }
    const ourVersion = ourType.migrations.currentVersion;
    const persistedVersion = persistedType.version;
    if (ourVersion !== persistedVersion) {
      const result2 = direction === "up" ? migrateRecord({
        record,
        migrations: ourType.migrations,
        fromVersion: persistedVersion,
        toVersion: ourVersion
      }) : migrateRecord({
        record,
        migrations: ourType.migrations,
        fromVersion: ourVersion,
        toVersion: persistedVersion
      });
      if (result2.type === "error") {
        return result2;
      }
      record = result2.value;
    }
    if (!ourType.migrations.subTypeKey) {
      return { type: "success", value: record };
    }
    const ourSubTypeMigrations = ourType.migrations.subTypeMigrations?.[record[ourType.migrations.subTypeKey]];
    const persistedSubTypeVersion = "subTypeVersions" in persistedType ? persistedType.subTypeVersions[record[ourType.migrations.subTypeKey]] : void 0;
    if (ourSubTypeMigrations === void 0) {
      return { type: "error", reason: MigrationFailureReason.UnrecognizedSubtype };
    }
    if (persistedSubTypeVersion === void 0) {
      return { type: "error", reason: MigrationFailureReason.IncompatibleSubtype };
    }
    const result = direction === "up" ? migrateRecord({
      record,
      migrations: ourSubTypeMigrations,
      fromVersion: persistedSubTypeVersion,
      toVersion: ourSubTypeMigrations.currentVersion
    }) : migrateRecord({
      record,
      migrations: ourSubTypeMigrations,
      fromVersion: ourSubTypeMigrations.currentVersion,
      toVersion: persistedSubTypeVersion
    });
    if (result.type === "error") {
      return result;
    }
    return { type: "success", value: result.value };
  }
  migrateStoreSnapshot(snapshot) {
    let { store } = snapshot;
    const migrations = this.options.snapshotMigrations;
    if (!migrations) {
      return { type: "success", value: store };
    }
    const ourStoreVersion = migrations.currentVersion;
    const persistedStoreVersion = snapshot.schema.storeVersion ?? 0;
    if (ourStoreVersion < persistedStoreVersion) {
      return { type: "error", reason: MigrationFailureReason.TargetVersionTooOld };
    }
    if (ourStoreVersion > persistedStoreVersion) {
      const result = migrate({
        value: store,
        migrations,
        fromVersion: persistedStoreVersion,
        toVersion: ourStoreVersion
      });
      if (result.type === "error") {
        return result;
      }
      store = result.value;
    }
    const updated = [];
    for (const r of objectMapValues(store)) {
      const result = this.migratePersistedRecord(r, snapshot.schema);
      if (result.type === "error") {
        return result;
      } else if (result.value && result.value !== r) {
        updated.push(result.value);
      }
    }
    if (updated.length) {
      store = { ...store };
      for (const r of updated) {
        store[r.id] = r;
      }
    }
    return { type: "success", value: store };
  }
  /** @internal */
  createIntegrityChecker(store) {
    return this.options.createIntegrityChecker?.(store) ?? void 0;
  }
  serialize() {
    return {
      schemaVersion: 1,
      storeVersion: this.options.snapshotMigrations?.currentVersion ?? 0,
      recordVersions: Object.fromEntries(
        objectMapValues(this.types).map((type) => [
          type.typeName,
          type.migrations.subTypeKey && type.migrations.subTypeMigrations ? {
            version: type.migrations.currentVersion,
            subTypeKey: type.migrations.subTypeKey,
            subTypeVersions: type.migrations.subTypeMigrations ? Object.fromEntries(
              Object.entries(type.migrations.subTypeMigrations).map(([k, v]) => [
                k,
                v.currentVersion
              ])
            ) : void 0
          } : {
            version: type.migrations.currentVersion
          }
        ])
      )
    };
  }
  serializeEarliestVersion() {
    return {
      schemaVersion: 1,
      storeVersion: this.options.snapshotMigrations?.firstVersion ?? 0,
      recordVersions: Object.fromEntries(
        objectMapValues(this.types).map((type) => [
          type.typeName,
          type.migrations.subTypeKey && type.migrations.subTypeMigrations ? {
            version: type.migrations.firstVersion,
            subTypeKey: type.migrations.subTypeKey,
            subTypeVersions: type.migrations.subTypeMigrations ? Object.fromEntries(
              Object.entries(type.migrations.subTypeMigrations).map(([k, v]) => [
                k,
                v.firstVersion
              ])
            ) : void 0
          } : {
            version: type.migrations.firstVersion
          }
        ])
      )
    };
  }
};

// node_modules/.deno/@tldraw+store@2.0.0-alpha.17/node_modules/@tldraw/store/dist-esm/lib/compareSchemas.mjs
var compareSchemas = (a, b) => {
  if (a.schemaVersion > b.schemaVersion) {
    return 1;
  }
  if (a.schemaVersion < b.schemaVersion) {
    return -1;
  }
  if (a.storeVersion > b.storeVersion) {
    return 1;
  }
  if (a.storeVersion < b.storeVersion) {
    return -1;
  }
  for (const key of Object.keys(a.recordVersions)) {
    const aRecordVersion = a.recordVersions[key];
    const bRecordVersion = b.recordVersions[key];
    if (aRecordVersion.version > bRecordVersion.version) {
      return 1;
    }
    if (aRecordVersion.version < bRecordVersion.version) {
      return -1;
    }
    if ("subTypeVersions" in aRecordVersion && !("subTypeVersions" in bRecordVersion)) {
      return 1;
    }
    if (!("subTypeVersions" in aRecordVersion) && "subTypeVersions" in bRecordVersion) {
      return -1;
    }
    if (!("subTypeVersions" in aRecordVersion) || !("subTypeVersions" in bRecordVersion)) {
      continue;
    }
    for (const subType of Object.keys(aRecordVersion.subTypeVersions)) {
      const aSubTypeVersion = aRecordVersion.subTypeVersions[subType];
      const bSubTypeVersion = bRecordVersion.subTypeVersions[subType];
      if (aSubTypeVersion > bSubTypeVersion) {
        return 1;
      }
      if (aSubTypeVersion < bSubTypeVersion) {
        return -1;
      }
    }
  }
  return 0;
};

// node_modules/.deno/@tldraw+validate@2.0.0-alpha.17/node_modules/@tldraw/validate/dist-esm/lib/validation.mjs
var validation_exports = {};
__export(validation_exports, {
  ArrayOfValidator: () => ArrayOfValidator,
  DictValidator: () => DictValidator,
  ObjectValidator: () => ObjectValidator,
  UnionValidator: () => UnionValidator,
  ValidationError: () => ValidationError,
  Validator: () => Validator,
  any: () => any,
  array: () => array,
  arrayOf: () => arrayOf,
  bigint: () => bigint,
  boolean: () => boolean,
  dict: () => dict,
  integer: () => integer,
  jsonDict: () => jsonDict,
  jsonValue: () => jsonValue,
  literal: () => literal,
  literalEnum: () => literalEnum,
  model: () => model,
  nonZeroInteger: () => nonZeroInteger,
  nonZeroNumber: () => nonZeroNumber,
  nullable: () => nullable,
  number: () => number,
  object: () => object,
  optional: () => optional,
  positiveInteger: () => positiveInteger,
  positiveNumber: () => positiveNumber,
  setEnum: () => setEnum,
  string: () => string,
  union: () => union,
  unknown: () => unknown,
  unknownObject: () => unknownObject
});
function formatPath(path) {
  if (!path.length) {
    return null;
  }
  let formattedPath = "";
  for (const item of path) {
    if (typeof item === "number") {
      formattedPath += `.${item}`;
    } else if (item.startsWith("(")) {
      if (formattedPath.endsWith(")")) {
        formattedPath = `${formattedPath.slice(0, -1)}, ${item.slice(1)}`;
      } else {
        formattedPath += item;
      }
    } else {
      formattedPath += `.${item}`;
    }
  }
  if (formattedPath.startsWith(".")) {
    return formattedPath.slice(1);
  }
  return formattedPath;
}
var ValidationError = class extends Error {
  constructor(rawMessage, path = []) {
    const formattedPath = formatPath(path);
    const indentedMessage = rawMessage.split("\n").map((line, i) => i === 0 ? line : `  ${line}`).join("\n");
    super(path ? `At ${formattedPath}: ${indentedMessage}` : indentedMessage);
    this.rawMessage = rawMessage;
    this.path = path;
  }
  name = "ValidationError";
};
function prefixError(path, fn) {
  try {
    return fn();
  } catch (err) {
    if (err instanceof ValidationError) {
      throw new ValidationError(err.rawMessage, [path, ...err.path]);
    }
    throw new ValidationError(err.toString(), [path]);
  }
}
function typeToString(value) {
  if (value === null)
    return "null";
  if (Array.isArray(value))
    return "an array";
  const type = typeof value;
  switch (type) {
    case "bigint":
    case "boolean":
    case "function":
    case "number":
    case "string":
    case "symbol":
      return `a ${type}`;
    case "object":
      return `an ${type}`;
    case "undefined":
      return "undefined";
    default:
      exhaustiveSwitchError(type);
  }
}
var Validator = class _Validator {
  constructor(validationFn) {
    this.validationFn = validationFn;
  }
  /**
   * Asserts that the passed value is of the correct type and returns it. The returned value is
   * guaranteed to be referentially equal to the passed value.
   */
  validate(value) {
    const validated = this.validationFn(value);
    if (!Object.is(value, validated)) {
      throw new ValidationError("Validator functions must return the same value they were passed");
    }
    return validated;
  }
  /**
   * Returns a new validator that also accepts null or undefined. The resulting value will always be
   * null.
   */
  nullable() {
    return nullable(this);
  }
  /**
   * Returns a new validator that also accepts null or undefined. The resulting value will always be
   * null.
   */
  optional() {
    return optional(this);
  }
  /**
   * Refine this validation to a new type. The passed-in validation function should throw an error
   * if the value can't be converted to the new type, or return the new type otherwise.
   */
  refine(otherValidationFn) {
    return new _Validator((value) => {
      return otherValidationFn(this.validate(value));
    });
  }
  check(nameOrCheckFn, checkFn) {
    if (typeof nameOrCheckFn === "string") {
      return this.refine((value) => {
        prefixError(`(check ${nameOrCheckFn})`, () => checkFn(value));
        return value;
      });
    } else {
      return this.refine((value) => {
        nameOrCheckFn(value);
        return value;
      });
    }
  }
};
var ArrayOfValidator = class extends Validator {
  constructor(itemValidator) {
    super((value) => {
      const arr = array.validate(value);
      for (let i = 0; i < arr.length; i++) {
        prefixError(i, () => itemValidator.validate(arr[i]));
      }
      return arr;
    });
    this.itemValidator = itemValidator;
  }
  nonEmpty() {
    return this.check((value) => {
      if (value.length === 0) {
        throw new ValidationError("Expected a non-empty array");
      }
    });
  }
  lengthGreaterThan1() {
    return this.check((value) => {
      if (value.length <= 1) {
        throw new ValidationError("Expected an array with length greater than 1");
      }
    });
  }
};
var ObjectValidator = class _ObjectValidator extends Validator {
  constructor(config, shouldAllowUnknownProperties = false) {
    super((object2) => {
      if (typeof object2 !== "object" || object2 === null) {
        throw new ValidationError(`Expected object, got ${typeToString(object2)}`);
      }
      for (const [key, validator] of Object.entries(config)) {
        prefixError(key, () => {
          ;
          validator.validate(getOwnProperty(object2, key));
        });
      }
      if (!shouldAllowUnknownProperties) {
        for (const key of Object.keys(object2)) {
          if (!hasOwnProperty(config, key)) {
            throw new ValidationError(`Unexpected property`, [key]);
          }
        }
      }
      return object2;
    });
    this.config = config;
    this.shouldAllowUnknownProperties = shouldAllowUnknownProperties;
  }
  allowUnknownProperties() {
    return new _ObjectValidator(this.config, true);
  }
  /**
   * Extend an object validator by adding additional properties.
   *
   * @example
   *
   * ```ts
   * const animalValidator = T.object({
   * 	name: T.string,
   * })
   * const catValidator = animalValidator.extend({
   * 	meowVolume: T.number,
   * })
   * ```
   */
  extend(extension) {
    return new _ObjectValidator({ ...this.config, ...extension });
  }
};
var UnionValidator = class _UnionValidator extends Validator {
  constructor(key, config, unknownValueValidation) {
    super((input) => {
      if (typeof input !== "object" || input === null) {
        throw new ValidationError(`Expected an object, got ${typeToString(input)}`, []);
      }
      const variant = getOwnProperty(input, key);
      if (typeof variant !== "string") {
        throw new ValidationError(
          `Expected a string for key "${key}", got ${typeToString(variant)}`
        );
      }
      const matchingSchema = hasOwnProperty(config, variant) ? config[variant] : void 0;
      if (matchingSchema === void 0) {
        return this.unknownValueValidation(input, variant);
      }
      return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input));
    });
    this.key = key;
    this.config = config;
    this.unknownValueValidation = unknownValueValidation;
  }
  validateUnknownVariants(unknownValueValidation) {
    return new _UnionValidator(this.key, this.config, unknownValueValidation);
  }
};
var DictValidator = class extends Validator {
  constructor(keyValidator, valueValidator) {
    super((object2) => {
      if (typeof object2 !== "object" || object2 === null) {
        throw new ValidationError(`Expected object, got ${typeToString(object2)}`);
      }
      for (const [key, value] of Object.entries(object2)) {
        prefixError(key, () => {
          keyValidator.validate(key);
          valueValidator.validate(value);
        });
      }
      return object2;
    });
    this.keyValidator = keyValidator;
    this.valueValidator = valueValidator;
  }
};
function typeofValidator(type) {
  return new Validator((value) => {
    if (typeof value !== type) {
      throw new ValidationError(`Expected ${type}, got ${typeToString(value)}`);
    }
    return value;
  });
}
var unknown = new Validator((value) => value);
var any = new Validator((value) => value);
var string = typeofValidator("string");
var number = typeofValidator("number").check((number2) => {
  if (Number.isNaN(number2)) {
    throw new ValidationError("Expected a number, got NaN");
  }
  if (!Number.isFinite(number2)) {
    throw new ValidationError(`Expected a finite number, got ${number2}`);
  }
});
var positiveNumber = number.check((value) => {
  if (value < 0)
    throw new ValidationError(`Expected a positive number, got ${value}`);
});
var nonZeroNumber = number.check((value) => {
  if (value <= 0)
    throw new ValidationError(`Expected a non-zero positive number, got ${value}`);
});
var integer = number.check((value) => {
  if (!Number.isInteger(value))
    throw new ValidationError(`Expected an integer, got ${value}`);
});
var positiveInteger = integer.check((value) => {
  if (value < 0)
    throw new ValidationError(`Expected a positive integer, got ${value}`);
});
var nonZeroInteger = integer.check((value) => {
  if (value <= 0)
    throw new ValidationError(`Expected a non-zero positive integer, got ${value}`);
});
var boolean = typeofValidator("boolean");
var bigint = typeofValidator("bigint");
function literal(expectedValue) {
  return new Validator((actualValue) => {
    if (actualValue !== expectedValue) {
      throw new ValidationError(`Expected ${expectedValue}, got ${JSON.stringify(actualValue)}`);
    }
    return expectedValue;
  });
}
var array = new Validator((value) => {
  if (!Array.isArray(value)) {
    throw new ValidationError(`Expected an array, got ${typeToString(value)}`);
  }
  return value;
});
function arrayOf(itemValidator) {
  return new ArrayOfValidator(itemValidator);
}
var unknownObject = new Validator((value) => {
  if (typeof value !== "object" || value === null) {
    throw new ValidationError(`Expected object, got ${typeToString(value)}`);
  }
  return value;
});
function object(config) {
  return new ObjectValidator(config);
}
function isValidJson(value) {
  if (value === null || typeof value === "number" || typeof value === "string" || typeof value === "boolean") {
    return true;
  }
  if (Array.isArray(value)) {
    return value.every(isValidJson);
  }
  if (typeof value === "object") {
    return Object.values(value).every(isValidJson);
  }
  return false;
}
var jsonValue = new Validator((value) => {
  if (isValidJson(value)) {
    return value;
  }
  throw new ValidationError(`Expected json serializable value, got ${typeof value}`);
});
function jsonDict() {
  return dict(string, jsonValue);
}
function dict(keyValidator, valueValidator) {
  return new DictValidator(keyValidator, valueValidator);
}
function union(key, config) {
  return new UnionValidator(key, config, (unknownValue, unknownVariant) => {
    throw new ValidationError(
      `Expected one of ${Object.keys(config).map((key2) => JSON.stringify(key2)).join(" or ")}, got ${JSON.stringify(unknownVariant)}`,
      [key]
    );
  });
}
function model(name, validator) {
  return new Validator((value) => {
    const prefix = value && typeof value === "object" && "id" in value && typeof value.id === "string" ? `${name}(id = ${value.id})` : name;
    return prefixError(prefix, () => validator.validate(value));
  });
}
function setEnum(values) {
  return new Validator((value) => {
    if (!values.has(value)) {
      const valuesString = Array.from(values, (value2) => JSON.stringify(value2)).join(" or ");
      throw new ValidationError(`Expected ${valuesString}, got ${value}`);
    }
    return value;
  });
}
function optional(validator) {
  return new Validator((value) => {
    if (value === void 0)
      return void 0;
    return validator.validate(value);
  });
}
function nullable(validator) {
  return new Validator((value) => {
    if (value === null)
      return null;
    return validator.validate(value);
  });
}
function literalEnum(...values) {
  return setEnum(new Set(values));
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/misc/id-validator.mjs
function idValidator(prefix) {
  return validation_exports.string.refine((id) => {
    if (!id.startsWith(`${prefix}:`)) {
      throw new Error(`${prefix} ID must start with "${prefix}:"`);
    }
    return id;
  });
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/assets/TLBaseAsset.mjs
var assetIdValidator = idValidator("asset");
function createAssetValidator(type, props) {
  return validation_exports.object({
    id: assetIdValidator,
    typeName: validation_exports.literal("asset"),
    type: validation_exports.literal(type),
    props,
    meta: validation_exports.jsonValue
  });
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLCamera.mjs
var cameraValidator = validation_exports.model(
  "camera",
  validation_exports.object({
    typeName: validation_exports.literal("camera"),
    id: idValidator("camera"),
    x: validation_exports.number,
    y: validation_exports.number,
    z: validation_exports.number,
    meta: validation_exports.jsonValue
  })
);
var cameraVersions = {
  AddMeta: 1
};
var cameraMigrations = defineMigrations({
  currentVersion: cameraVersions.AddMeta,
  migrators: {
    [cameraVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    }
  }
});
var CameraRecordType = createRecordType("camera", {
  validator: cameraValidator,
  migrations: cameraMigrations,
  scope: "session"
}).withDefaultProperties(
  () => ({
    x: 0,
    y: 0,
    z: 1,
    meta: {}
  })
);

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/misc/geometry-types.mjs
var vec2dModelValidator = validation_exports.object({
  x: validation_exports.number,
  y: validation_exports.number,
  z: validation_exports.number.optional()
});
var box2dModelValidator = validation_exports.object({
  x: validation_exports.number,
  y: validation_exports.number,
  w: validation_exports.number,
  h: validation_exports.number
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/misc/TLCursor.mjs
var TL_CURSOR_TYPES = /* @__PURE__ */ new Set([
  "none",
  "default",
  "pointer",
  "cross",
  "grab",
  "rotate",
  "grabbing",
  "resize-edge",
  "resize-corner",
  "text",
  "move",
  "ew-resize",
  "ns-resize",
  "nesw-resize",
  "nwse-resize",
  "nesw-rotate",
  "nwse-rotate",
  "swne-rotate",
  "senw-rotate",
  "zoom-in",
  "zoom-out"
]);
var cursorTypeValidator = validation_exports.setEnum(TL_CURSOR_TYPES);
var cursorValidator = validation_exports.object({
  type: cursorTypeValidator,
  rotation: validation_exports.number
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/misc/TLOpacity.mjs
var opacityValidator = validation_exports.number.check((n) => {
  if (n < 0 || n > 1) {
    throw new validation_exports.ValidationError("Opacity must be between 0 and 1");
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/misc/TLColor.mjs
var TL_CANVAS_UI_COLOR_TYPES = /* @__PURE__ */ new Set([
  "accent",
  "white",
  "black",
  "selection-stroke",
  "selection-fill",
  "laser",
  "muted-1"
]);
var canvasUiColorTypeValidator = validation_exports.setEnum(TL_CANVAS_UI_COLOR_TYPES);

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/misc/TLScribble.mjs
var TL_SCRIBBLE_STATES = /* @__PURE__ */ new Set(["starting", "paused", "active", "stopping"]);
var scribbleValidator = validation_exports.object({
  points: validation_exports.arrayOf(vec2dModelValidator),
  size: validation_exports.positiveNumber,
  color: canvasUiColorTypeValidator,
  opacity: validation_exports.number,
  state: validation_exports.setEnum(TL_SCRIBBLE_STATES),
  delay: validation_exports.number
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLPage.mjs
var pageIdValidator = idValidator("page");
var pageValidator = validation_exports.model(
  "page",
  validation_exports.object({
    typeName: validation_exports.literal("page"),
    id: pageIdValidator,
    name: validation_exports.string,
    index: validation_exports.string,
    meta: validation_exports.jsonValue
  })
);
var pageVersions = {
  AddMeta: 1
};
var pageMigrations = defineMigrations({
  currentVersion: pageVersions.AddMeta,
  migrators: {
    [pageVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    }
  }
});
var PageRecordType = createRecordType("page", {
  validator: pageValidator,
  migrations: pageMigrations,
  scope: "document"
}).withDefaultProperties(() => ({
  meta: {}
}));
function isPageId(id) {
  return PageRecordType.isId(id);
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLInstance.mjs
var instanceIdValidator = idValidator("instance");
function createInstanceRecordType(stylesById) {
  const stylesForNextShapeValidators = {};
  for (const [id, style] of stylesById) {
    stylesForNextShapeValidators[id] = validation_exports.optional(style);
  }
  const instanceTypeValidator = validation_exports.model(
    "instance",
    validation_exports.object({
      typeName: validation_exports.literal("instance"),
      id: idValidator("instance"),
      currentPageId: pageIdValidator,
      followingUserId: validation_exports.string.nullable(),
      brush: box2dModelValidator.nullable(),
      opacityForNextShape: opacityValidator,
      stylesForNextShape: validation_exports.object(stylesForNextShapeValidators),
      cursor: cursorValidator,
      scribble: scribbleValidator.nullable(),
      isFocusMode: validation_exports.boolean,
      isDebugMode: validation_exports.boolean,
      isToolLocked: validation_exports.boolean,
      exportBackground: validation_exports.boolean,
      screenBounds: box2dModelValidator,
      zoomBrush: box2dModelValidator.nullable(),
      isPenMode: validation_exports.boolean,
      isGridMode: validation_exports.boolean,
      chatMessage: validation_exports.string,
      isChatting: validation_exports.boolean,
      highlightedUserIds: validation_exports.arrayOf(validation_exports.string),
      canMoveCamera: validation_exports.boolean,
      isFocused: validation_exports.boolean,
      devicePixelRatio: validation_exports.number,
      isCoarsePointer: validation_exports.boolean,
      isHoveringCanvas: validation_exports.boolean.nullable(),
      openMenus: validation_exports.arrayOf(validation_exports.string),
      isChangingStyle: validation_exports.boolean,
      isReadonly: validation_exports.boolean,
      meta: validation_exports.jsonValue
    })
  );
  return createRecordType("instance", {
    migrations: instanceMigrations,
    validator: instanceTypeValidator,
    scope: "session"
  }).withDefaultProperties(
    () => ({
      followingUserId: null,
      opacityForNextShape: 1,
      stylesForNextShape: {},
      brush: null,
      scribble: null,
      cursor: {
        type: "default",
        rotation: 0
      },
      isFocusMode: false,
      exportBackground: false,
      isDebugMode: true,
      isToolLocked: false,
      screenBounds: { x: 0, y: 0, w: 1080, h: 720 },
      zoomBrush: null,
      isGridMode: false,
      isPenMode: false,
      chatMessage: "",
      isChatting: false,
      highlightedUserIds: [],
      canMoveCamera: true,
      isFocused: false,
      devicePixelRatio: typeof window === "undefined" ? 1 : window.devicePixelRatio,
      isCoarsePointer: false,
      isHoveringCanvas: null,
      openMenus: [],
      isChangingStyle: false,
      isReadonly: false,
      meta: {}
    })
  );
}
var instanceVersions = {
  AddTransparentExportBgs: 1,
  RemoveDialog: 2,
  AddToolLockMode: 3,
  RemoveExtraPropsForNextShape: 4,
  AddLabelColor: 5,
  AddFollowingUserId: 6,
  RemoveAlignJustify: 7,
  AddZoom: 8,
  AddVerticalAlign: 9,
  AddScribbleDelay: 10,
  RemoveUserId: 11,
  AddIsPenModeAndIsGridMode: 12,
  HoistOpacity: 13,
  AddChat: 14,
  AddHighlightedUserIds: 15,
  ReplacePropsForNextShapeWithStylesForNextShape: 16,
  AddMeta: 17,
  RemoveCursorColor: 18,
  AddLonelyProperties: 19,
  ReadOnlyReadonly: 20,
  AddHoveringCanvas: 21
};
var instanceMigrations = defineMigrations({
  currentVersion: instanceVersions.AddHoveringCanvas,
  migrators: {
    [instanceVersions.AddTransparentExportBgs]: {
      up: (instance) => {
        return { ...instance, exportBackground: true };
      },
      down: ({ exportBackground: _, ...instance }) => {
        return instance;
      }
    },
    [instanceVersions.RemoveDialog]: {
      up: ({ dialog: _, ...instance }) => {
        return instance;
      },
      down: (instance) => {
        return { ...instance, dialog: null };
      }
    },
    [instanceVersions.AddToolLockMode]: {
      up: (instance) => {
        return { ...instance, isToolLocked: false };
      },
      down: ({ isToolLocked: _, ...instance }) => {
        return instance;
      }
    },
    [instanceVersions.RemoveExtraPropsForNextShape]: {
      up: ({ propsForNextShape, ...instance }) => {
        return {
          ...instance,
          propsForNextShape: Object.fromEntries(
            Object.entries(propsForNextShape).filter(
              ([key]) => [
                "color",
                "labelColor",
                "dash",
                "fill",
                "size",
                "font",
                "align",
                "verticalAlign",
                "icon",
                "geo",
                "arrowheadStart",
                "arrowheadEnd",
                "spline"
              ].includes(key)
            )
          )
        };
      },
      down: (instance) => {
        return instance;
      }
    },
    [instanceVersions.AddLabelColor]: {
      up: ({ propsForNextShape, ...instance }) => {
        return {
          ...instance,
          propsForNextShape: {
            ...propsForNextShape,
            labelColor: "black"
          }
        };
      },
      down: (instance) => {
        const { labelColor: _, ...rest } = instance.propsForNextShape;
        return {
          ...instance,
          propsForNextShape: {
            ...rest
          }
        };
      }
    },
    [instanceVersions.AddFollowingUserId]: {
      up: (instance) => {
        return { ...instance, followingUserId: null };
      },
      down: ({ followingUserId: _, ...instance }) => {
        return instance;
      }
    },
    [instanceVersions.RemoveAlignJustify]: {
      up: (instance) => {
        let newAlign = instance.propsForNextShape.align;
        if (newAlign === "justify") {
          newAlign = "start";
        }
        return {
          ...instance,
          propsForNextShape: {
            ...instance.propsForNextShape,
            align: newAlign
          }
        };
      },
      down: (instance) => {
        return { ...instance };
      }
    },
    [instanceVersions.AddZoom]: {
      up: (instance) => {
        return { ...instance, zoomBrush: null };
      },
      down: ({ zoomBrush: _, ...instance }) => {
        return instance;
      }
    },
    [instanceVersions.AddVerticalAlign]: {
      up: (instance) => {
        return {
          ...instance,
          propsForNextShape: {
            ...instance.propsForNextShape,
            verticalAlign: "middle"
          }
        };
      },
      down: (instance) => {
        const { verticalAlign: _, ...propsForNextShape } = instance.propsForNextShape;
        return {
          ...instance,
          propsForNextShape
        };
      }
    },
    [instanceVersions.AddScribbleDelay]: {
      up: (instance) => {
        if (instance.scribble !== null) {
          return { ...instance, scribble: { ...instance.scribble, delay: 0 } };
        }
        return { ...instance };
      },
      down: (instance) => {
        if (instance.scribble !== null) {
          const { delay: _delay, ...rest } = instance.scribble;
          return { ...instance, scribble: rest };
        }
        return { ...instance };
      }
    },
    [instanceVersions.RemoveUserId]: {
      up: ({ userId: _, ...instance }) => {
        return instance;
      },
      down: (instance) => {
        return { ...instance, userId: "user:none" };
      }
    },
    [instanceVersions.AddIsPenModeAndIsGridMode]: {
      up: (instance) => {
        return { ...instance, isPenMode: false, isGridMode: false };
      },
      down: ({ isPenMode: _, isGridMode: __, ...instance }) => {
        return instance;
      }
    },
    [instanceVersions.HoistOpacity]: {
      up: ({ propsForNextShape: { opacity, ...propsForNextShape }, ...instance }) => {
        return { ...instance, opacityForNextShape: Number(opacity ?? "1"), propsForNextShape };
      },
      down: ({ opacityForNextShape: opacity, ...instance }) => {
        return {
          ...instance,
          propsForNextShape: {
            ...instance.propsForNextShape,
            opacity: opacity < 0.175 ? "0.1" : opacity < 0.375 ? "0.25" : opacity < 0.625 ? "0.5" : opacity < 0.875 ? "0.75" : "1"
          }
        };
      }
    },
    [instanceVersions.AddChat]: {
      up: (instance) => {
        return { ...instance, chatMessage: "", isChatting: false };
      },
      down: ({ chatMessage: _, isChatting: __, ...instance }) => {
        return instance;
      }
    },
    [instanceVersions.AddHighlightedUserIds]: {
      up: (instance) => {
        return { ...instance, highlightedUserIds: [] };
      },
      down: ({ highlightedUserIds: _, ...instance }) => {
        return instance;
      }
    },
    [instanceVersions.ReplacePropsForNextShapeWithStylesForNextShape]: {
      up: ({ propsForNextShape: _, ...instance }) => {
        return { ...instance, stylesForNextShape: {} };
      },
      down: ({ stylesForNextShape: _, ...instance }) => {
        return {
          ...instance,
          propsForNextShape: {
            color: "black",
            labelColor: "black",
            dash: "draw",
            fill: "none",
            size: "m",
            icon: "file",
            font: "draw",
            align: "middle",
            verticalAlign: "middle",
            geo: "rectangle",
            arrowheadStart: "none",
            arrowheadEnd: "arrow",
            spline: "line"
          }
        };
      }
    },
    [instanceVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    },
    [instanceVersions.RemoveCursorColor]: {
      up: (record) => {
        const { color: _, ...cursor } = record.cursor;
        return {
          ...record,
          cursor
        };
      },
      down: (record) => {
        return {
          ...record,
          cursor: {
            ...record.cursor,
            color: "black"
          }
        };
      }
    },
    [instanceVersions.AddLonelyProperties]: {
      up: (record) => {
        return {
          ...record,
          canMoveCamera: true,
          isFocused: false,
          devicePixelRatio: 1,
          isCoarsePointer: false,
          openMenus: [],
          isChangingStyle: false,
          isReadOnly: false
        };
      },
      down: ({
        canMoveCamera: _canMoveCamera,
        isFocused: _isFocused,
        devicePixelRatio: _devicePixelRatio,
        isCoarsePointer: _isCoarsePointer,
        openMenus: _openMenus,
        isChangingStyle: _isChangingStyle,
        isReadOnly: _isReadOnly,
        ...record
      }) => {
        return {
          ...record
        };
      }
    },
    [instanceVersions.ReadOnlyReadonly]: {
      up: ({ isReadOnly: _isReadOnly, ...record }) => {
        return {
          ...record,
          isReadonly: _isReadOnly
        };
      },
      down: ({ isReadonly: _isReadonly, ...record }) => {
        return {
          ...record,
          isReadOnly: _isReadonly
        };
      }
    },
    [instanceVersions.AddHoveringCanvas]: {
      up: (record) => {
        return {
          ...record,
          isHoveringCanvas: null
        };
      },
      down: ({ isHoveringCanvas: _, ...record }) => {
        return {
          ...record
        };
      }
    }
  }
});
var TLINSTANCE_ID = "instance:instance";

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLBaseShape.mjs
var parentIdValidator = validation_exports.string.refine((id) => {
  if (!id.startsWith("page:") && !id.startsWith("shape:")) {
    throw new Error('Parent ID must start with "page:" or "shape:"');
  }
  return id;
});
var shapeIdValidator = idValidator("shape");
function createShapeValidator(type, props, meta) {
  return validation_exports.object({
    id: shapeIdValidator,
    typeName: validation_exports.literal("shape"),
    x: validation_exports.number,
    y: validation_exports.number,
    rotation: validation_exports.number,
    index: validation_exports.string,
    parentId: parentIdValidator,
    type: validation_exports.literal(type),
    isLocked: validation_exports.boolean,
    opacity: opacityValidator,
    props: props ? validation_exports.object(props) : validation_exports.jsonValue,
    meta: meta ? validation_exports.object(meta) : validation_exports.jsonValue
  });
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLPageState.mjs
var instancePageStateValidator = validation_exports.model(
  "instance_page_state",
  validation_exports.object({
    typeName: validation_exports.literal("instance_page_state"),
    id: idValidator("instance_page_state"),
    pageId: pageIdValidator,
    selectedShapeIds: validation_exports.arrayOf(shapeIdValidator),
    hintingShapeIds: validation_exports.arrayOf(shapeIdValidator),
    erasingShapeIds: validation_exports.arrayOf(shapeIdValidator),
    hoveredShapeId: shapeIdValidator.nullable(),
    editingShapeId: shapeIdValidator.nullable(),
    croppingShapeId: shapeIdValidator.nullable(),
    focusedGroupId: shapeIdValidator.nullable(),
    meta: validation_exports.jsonValue
  })
);
var instancePageStateVersions = {
  AddCroppingId: 1,
  RemoveInstanceIdAndCameraId: 2,
  AddMeta: 3,
  RenameProperties: 4,
  RenamePropertiesAgain: 5
};
var instancePageStateMigrations = defineMigrations({
  currentVersion: instancePageStateVersions.RenamePropertiesAgain,
  migrators: {
    [instancePageStateVersions.AddCroppingId]: {
      up(instance) {
        return { ...instance, croppingShapeId: null };
      },
      down({ croppingShapeId: _croppingShapeId, ...instance }) {
        return instance;
      }
    },
    [instancePageStateVersions.RemoveInstanceIdAndCameraId]: {
      up({ instanceId: _, cameraId: __, ...instance }) {
        return instance;
      },
      down(instance) {
        return {
          ...instance,
          instanceId: TLINSTANCE_ID,
          cameraId: CameraRecordType.createId("void")
        };
      }
    },
    [instancePageStateVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    },
    [instancePageStateVersions.RenameProperties]: {
      // this migration is cursed: it was written wrong and doesn't do anything.
      // rather than replace it, I've added another migration below that fixes it.
      up: (record) => {
        const {
          selectedShapeIds,
          hintingShapeIds,
          erasingShapeIds,
          hoveredShapeId,
          editingShapeId,
          croppingShapeId,
          focusedGroupId,
          ...rest
        } = record;
        return {
          selectedShapeIds,
          hintingShapeIds,
          erasingShapeIds,
          hoveredShapeId,
          editingShapeId,
          croppingShapeId,
          focusedGroupId,
          ...rest
        };
      },
      down: (record) => {
        const {
          selectedShapeIds,
          hintingShapeIds,
          erasingShapeIds,
          hoveredShapeId,
          editingShapeId,
          croppingShapeId,
          focusedGroupId,
          ...rest
        } = record;
        return {
          selectedShapeIds,
          hintingShapeIds,
          erasingShapeIds,
          hoveredShapeId,
          editingShapeId,
          croppingShapeId,
          focusedGroupId,
          ...rest
        };
      }
    },
    [instancePageStateVersions.RenamePropertiesAgain]: {
      up: (record) => {
        const {
          selectedIds,
          hintingIds,
          erasingIds,
          hoveredId,
          editingId,
          croppingId,
          focusLayerId,
          ...rest
        } = record;
        return {
          ...rest,
          selectedShapeIds: selectedIds,
          hintingShapeIds: hintingIds,
          erasingShapeIds: erasingIds,
          hoveredShapeId: hoveredId,
          editingShapeId: editingId,
          croppingShapeId: croppingId,
          focusedGroupId: focusLayerId
        };
      },
      down: (record) => {
        const {
          selectedShapeIds,
          hintingShapeIds,
          erasingShapeIds,
          hoveredShapeId,
          editingShapeId,
          croppingShapeId,
          focusedGroupId,
          ...rest
        } = record;
        return {
          ...rest,
          selectedIds: selectedShapeIds,
          hintingIds: hintingShapeIds,
          erasingIds: erasingShapeIds,
          hoveredId: hoveredShapeId,
          editingId: editingShapeId,
          croppingId: croppingShapeId,
          focusLayerId: focusedGroupId
        };
      }
    }
  }
});
var InstancePageStateRecordType = createRecordType(
  "instance_page_state",
  {
    migrations: instancePageStateMigrations,
    validator: instancePageStateValidator,
    scope: "session"
  }
).withDefaultProperties(
  () => ({
    editingShapeId: null,
    croppingShapeId: null,
    selectedShapeIds: [],
    hoveredShapeId: null,
    erasingShapeIds: [],
    hintingShapeIds: [],
    focusedGroupId: null,
    meta: {}
  })
);

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLPointer.mjs
var pointerValidator = validation_exports.model(
  "pointer",
  validation_exports.object({
    typeName: validation_exports.literal("pointer"),
    id: idValidator("pointer"),
    x: validation_exports.number,
    y: validation_exports.number,
    lastActivityTimestamp: validation_exports.number,
    meta: validation_exports.jsonValue
  })
);
var pointerVersions = {
  AddMeta: 1
};
var pointerMigrations = defineMigrations({
  currentVersion: pointerVersions.AddMeta,
  migrators: {
    [pointerVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    }
  }
});
var PointerRecordType = createRecordType("pointer", {
  validator: pointerValidator,
  migrations: pointerMigrations,
  scope: "session"
}).withDefaultProperties(
  () => ({
    x: 0,
    y: 0,
    lastActivityTimestamp: 0,
    meta: {}
  })
);
var TLPOINTER_ID = PointerRecordType.createId("pointer");

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLPresence.mjs
var instancePresenceValidator = validation_exports.model(
  "instance_presence",
  validation_exports.object({
    typeName: validation_exports.literal("instance_presence"),
    id: idValidator("instance_presence"),
    userId: validation_exports.string,
    userName: validation_exports.string,
    lastActivityTimestamp: validation_exports.number,
    followingUserId: validation_exports.string.nullable(),
    cursor: validation_exports.object({
      x: validation_exports.number,
      y: validation_exports.number,
      type: cursorTypeValidator,
      rotation: validation_exports.number
    }),
    color: validation_exports.string,
    camera: validation_exports.object({
      x: validation_exports.number,
      y: validation_exports.number,
      z: validation_exports.number
    }),
    screenBounds: box2dModelValidator,
    selectedShapeIds: validation_exports.arrayOf(idValidator("shape")),
    currentPageId: idValidator("page"),
    brush: box2dModelValidator.nullable(),
    scribble: scribbleValidator.nullable(),
    chatMessage: validation_exports.string,
    meta: validation_exports.jsonValue
  })
);
var instancePresenceVersions = {
  AddScribbleDelay: 1,
  RemoveInstanceId: 2,
  AddChatMessage: 3,
  AddMeta: 4,
  RenameSelectedShapeIds: 5
};
var instancePresenceMigrations = defineMigrations({
  currentVersion: instancePresenceVersions.RenameSelectedShapeIds,
  migrators: {
    [instancePresenceVersions.AddScribbleDelay]: {
      up: (instance) => {
        if (instance.scribble !== null) {
          return { ...instance, scribble: { ...instance.scribble, delay: 0 } };
        }
        return { ...instance };
      },
      down: (instance) => {
        if (instance.scribble !== null) {
          const { delay: _delay, ...rest } = instance.scribble;
          return { ...instance, scribble: rest };
        }
        return { ...instance };
      }
    },
    [instancePresenceVersions.RemoveInstanceId]: {
      up: ({ instanceId: _, ...instance }) => {
        return instance;
      },
      down: (instance) => {
        return { ...instance, instanceId: TLINSTANCE_ID };
      }
    },
    [instancePresenceVersions.AddChatMessage]: {
      up: (instance) => {
        return { ...instance, chatMessage: "" };
      },
      down: ({ chatMessage: _, ...instance }) => {
        return instance;
      }
    },
    [instancePresenceVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    },
    [instancePresenceVersions.RenameSelectedShapeIds]: {
      up: (record) => {
        const { selectedShapeIds, ...rest } = record;
        return {
          selectedShapeIds,
          ...rest
        };
      },
      down: (record) => {
        const { selectedShapeIds, ...rest } = record;
        return {
          selectedShapeIds,
          ...rest
        };
      }
    }
  }
});
var InstancePresenceRecordType = createRecordType(
  "instance_presence",
  {
    migrations: instancePresenceMigrations,
    validator: instancePresenceValidator,
    scope: "presence"
  }
).withDefaultProperties(() => ({
  lastActivityTimestamp: 0,
  followingUserId: null,
  color: "#FF0000",
  camera: {
    x: 0,
    y: 0,
    z: 1
  },
  cursor: {
    x: 0,
    y: 0,
    type: "default",
    rotation: 0
  },
  screenBounds: {
    x: 0,
    y: 0,
    w: 1,
    h: 1
  },
  selectedShapeIds: [],
  brush: null,
  scribble: null,
  chatMessage: "",
  meta: {}
}));

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/createPresenceStateDerivation.mjs
var createPresenceStateDerivation = ($user, instanceId) => (store) => {
  return computed("instancePresence", () => {
    const instance = store.get(TLINSTANCE_ID);
    const pageState = store.get(InstancePageStateRecordType.createId(instance?.currentPageId));
    const camera = store.get(CameraRecordType.createId(instance?.currentPageId));
    const pointer = store.get(TLPOINTER_ID);
    const user = $user.value;
    if (!pageState || !instance || !camera || !pointer || !user) {
      return null;
    }
    return InstancePresenceRecordType.create({
      id: instanceId ?? InstancePresenceRecordType.createId(store.id),
      selectedShapeIds: pageState.selectedShapeIds,
      brush: instance.brush,
      scribble: instance.scribble,
      userId: user.id,
      userName: user.name,
      followingUserId: instance.followingUserId,
      camera: {
        x: camera.x,
        y: camera.y,
        z: camera.z
      },
      color: user.color,
      currentPageId: instance.currentPageId,
      cursor: {
        x: pointer.x,
        y: pointer.y,
        rotation: instance.cursor.rotation,
        type: instance.cursor.type
      },
      lastActivityTimestamp: pointer.lastActivityTimestamp,
      screenBounds: instance.screenBounds,
      chatMessage: instance.chatMessage,
      meta: {}
    });
  });
};

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLDocument.mjs
var documentValidator = validation_exports.model(
  "document",
  validation_exports.object({
    typeName: validation_exports.literal("document"),
    id: validation_exports.literal("document:document"),
    gridSize: validation_exports.number,
    name: validation_exports.string,
    meta: validation_exports.jsonValue
  })
);
var documentVersions = {
  AddName: 1,
  AddMeta: 2
};
var documentMigrations = defineMigrations({
  currentVersion: documentVersions.AddMeta,
  migrators: {
    [documentVersions.AddName]: {
      up: (document2) => {
        return { ...document2, name: "" };
      },
      down: ({ name: _, ...document2 }) => {
        return document2;
      }
    },
    [documentVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    }
  }
});
var DocumentRecordType = createRecordType("document", {
  migrations: documentMigrations,
  validator: documentValidator,
  scope: "document"
}).withDefaultProperties(
  () => ({
    gridSize: 10,
    name: "",
    meta: {}
  })
);
var TLDOCUMENT_ID = DocumentRecordType.createId("document");

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/TLStore.mjs
function sortByIndex(a, b) {
  if (a.index < b.index) {
    return -1;
  } else if (a.index > b.index) {
    return 1;
  }
  return 0;
}
function redactRecordForErrorReporting(record) {
  if (record.typeName === "asset") {
    if ("src" in record) {
      record.src = "<redacted>";
    }
    if ("src" in record.props) {
      record.props.src = "<redacted>";
    }
  }
}
var onValidationFailure = ({ error, phase, record, recordBefore }) => {
  const isExistingValidationIssue = (
    // if we're initializing the store for the first time, we should
    // allow invalid records so people can load old buggy data:
    phase === "initialize"
  );
  annotateError(error, {
    tags: {
      origin: "store.validateRecord",
      storePhase: phase,
      isExistingValidationIssue
    },
    extras: {
      recordBefore: recordBefore ? redactRecordForErrorReporting(structuredClone2(recordBefore)) : void 0,
      recordAfter: redactRecordForErrorReporting(structuredClone2(record))
    }
  });
  throw error;
};
function getDefaultPages() {
  return [
    PageRecordType.create({ id: "page:page", name: "Page 1", index: "a1", meta: {} })
  ];
}
function createIntegrityChecker(store) {
  const $pageIds = store.query.ids("page");
  const ensureStoreIsUsable = () => {
    if (!store.has(TLDOCUMENT_ID)) {
      store.put([DocumentRecordType.create({ id: TLDOCUMENT_ID, name: store.props.defaultName })]);
      return ensureStoreIsUsable();
    }
    if (!store.has(TLPOINTER_ID)) {
      store.put([PointerRecordType.create({ id: TLPOINTER_ID })]);
      return ensureStoreIsUsable();
    }
    const pageIds = $pageIds.value;
    if (pageIds.size === 0) {
      store.put(getDefaultPages());
      return ensureStoreIsUsable();
    }
    const getFirstPageId = () => [...pageIds].map((id) => store.get(id)).sort(sortByIndex)[0].id;
    const instanceState = store.get(TLINSTANCE_ID);
    if (!instanceState) {
      store.put([
        store.schema.types.instance.create({
          id: TLINSTANCE_ID,
          currentPageId: getFirstPageId(),
          exportBackground: true
        })
      ]);
      return ensureStoreIsUsable();
    } else if (!pageIds.has(instanceState.currentPageId)) {
      store.put([{ ...instanceState, currentPageId: getFirstPageId() }]);
      return ensureStoreIsUsable();
    }
    const missingPageStateIds = /* @__PURE__ */ new Set();
    const missingCameraIds = /* @__PURE__ */ new Set();
    for (const id of pageIds) {
      const pageStateId = InstancePageStateRecordType.createId(id);
      if (!store.has(pageStateId)) {
        missingPageStateIds.add(pageStateId);
      }
      const cameraId = CameraRecordType.createId(id);
      if (!store.has(cameraId)) {
        missingCameraIds.add(cameraId);
      }
    }
    if (missingPageStateIds.size > 0) {
      store.put(
        [...missingPageStateIds].map(
          (id) => InstancePageStateRecordType.create({
            id,
            pageId: InstancePageStateRecordType.parseId(id)
          })
        )
      );
    }
    if (missingCameraIds.size > 0) {
      store.put([...missingCameraIds].map((id) => CameraRecordType.create({ id })));
    }
  };
  return ensureStoreIsUsable;
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/assets/TLBookmarkAsset.mjs
var bookmarkAssetValidator = createAssetValidator(
  "bookmark",
  validation_exports.object({
    title: validation_exports.string,
    description: validation_exports.string,
    image: validation_exports.string,
    src: validation_exports.string.nullable()
  })
);
var bookmarkAssetMigrations = defineMigrations({});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/assets/TLImageAsset.mjs
var imageAssetValidator = createAssetValidator(
  "image",
  validation_exports.object({
    w: validation_exports.number,
    h: validation_exports.number,
    name: validation_exports.string,
    isAnimated: validation_exports.boolean,
    mimeType: validation_exports.string.nullable(),
    src: validation_exports.string.nullable()
  })
);
var Versions = {
  AddIsAnimated: 1,
  RenameWidthHeight: 2
};
var imageAssetMigrations = defineMigrations({
  currentVersion: Versions.RenameWidthHeight,
  migrators: {
    [Versions.AddIsAnimated]: {
      up: (asset) => {
        return {
          ...asset,
          props: {
            ...asset.props,
            isAnimated: false
          }
        };
      },
      down: (asset) => {
        const { isAnimated: isAnimated2, ...rest } = asset.props;
        return {
          ...asset,
          props: rest
        };
      }
    },
    [Versions.RenameWidthHeight]: {
      up: (asset) => {
        const { width, height, ...others } = asset.props;
        return { ...asset, props: { w: width, h: height, ...others } };
      },
      down: (asset) => {
        const { w, h, ...others } = asset.props;
        return { ...asset, props: { width: w, height: h, ...others } };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/assets/TLVideoAsset.mjs
var videoAssetValidator = createAssetValidator(
  "video",
  validation_exports.object({
    w: validation_exports.number,
    h: validation_exports.number,
    name: validation_exports.string,
    isAnimated: validation_exports.boolean,
    mimeType: validation_exports.string.nullable(),
    src: validation_exports.string.nullable()
  })
);
var Versions2 = {
  AddIsAnimated: 1,
  RenameWidthHeight: 2
};
var videoAssetMigrations = defineMigrations({
  currentVersion: Versions2.RenameWidthHeight,
  migrators: {
    [Versions2.AddIsAnimated]: {
      up: (asset) => {
        return {
          ...asset,
          props: {
            ...asset.props,
            isAnimated: false
          }
        };
      },
      down: (asset) => {
        const { isAnimated: isAnimated2, ...rest } = asset.props;
        return {
          ...asset,
          props: rest
        };
      }
    },
    [Versions2.RenameWidthHeight]: {
      up: (asset) => {
        const { width, height, ...others } = asset.props;
        return { ...asset, props: { w: width, h: height, ...others } };
      },
      down: (asset) => {
        const { w, h, ...others } = asset.props;
        return { ...asset, props: { width: w, height: h, ...others } };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLAsset.mjs
var assetValidator = validation_exports.model(
  "asset",
  validation_exports.union("type", {
    image: imageAssetValidator,
    video: videoAssetValidator,
    bookmark: bookmarkAssetValidator
  })
);
var assetVersions = {
  AddMeta: 1
};
var assetMigrations = defineMigrations({
  subTypeKey: "type",
  subTypeMigrations: {
    image: imageAssetMigrations,
    video: videoAssetMigrations,
    bookmark: bookmarkAssetMigrations
  },
  currentVersion: assetVersions.AddMeta,
  migrators: {
    [assetVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    }
  }
});
var AssetRecordType = createRecordType("asset", {
  migrations: assetMigrations,
  validator: assetValidator,
  scope: "document"
}).withDefaultProperties(() => ({
  meta: {}
}));

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/StyleProp.mjs
var StyleProp = class _StyleProp {
  /** @internal */
  constructor(id, defaultValue, type) {
    this.id = id;
    this.defaultValue = defaultValue;
    this.type = type;
  }
  /**
   * Define a new {@link StyleProp}.
   *
   * @param uniqueId - Each StyleProp must have a unique ID. We recommend you prefix this with
   * your app/library name.
   * @param options -
   * - `defaultValue`: The default value for this style prop.
   *
   * - `type`: Optionally, describe what type of data you expect for this style prop.
   *
   * @example
   * ```ts
   * import {T} from '@tldraw/validate'
   * import {StyleProp} from '@tldraw/tlschema'
   *
   * const MyLineWidthProp = StyleProp.define('myApp:lineWidth', {
   *   defaultValue: 1,
   *   type: T.number,
   * })
   * ```
   * @public
   */
  static define(uniqueId2, options) {
    const { defaultValue, type = validation_exports.any } = options;
    return new _StyleProp(uniqueId2, defaultValue, type);
  }
  /**
   * Define a new {@link StyleProp} as a list of possible values.
   *
   * @param uniqueId - Each StyleProp must have a unique ID. We recommend you prefix this with
   * your app/library name.
   * @param options -
   * - `defaultValue`: The default value for this style prop.
   *
   * - `values`: An array of possible values of this style prop.
   *
   * @example
   * ```ts
   * import {StyleProp} from '@tldraw/tlschema'
   *
   * const MySizeProp = StyleProp.defineEnum('myApp:size', {
   *   defaultValue: 'medium',
   *   values: ['small', 'medium', 'large'],
   * })
   * ```
   */
  static defineEnum(uniqueId2, options) {
    const { defaultValue, values } = options;
    return new EnumStyleProp(uniqueId2, defaultValue, values);
  }
  validate(value) {
    return this.type.validate(value);
  }
};
var EnumStyleProp = class extends StyleProp {
  /** @internal */
  constructor(id, defaultValue, values) {
    super(id, defaultValue, validation_exports.literalEnum(...values));
    this.values = values;
  }
};

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/records/TLShape.mjs
var rootShapeVersions = {
  AddIsLocked: 1,
  HoistOpacity: 2,
  AddMeta: 3
};
var rootShapeMigrations = defineMigrations({
  currentVersion: rootShapeVersions.AddMeta,
  migrators: {
    [rootShapeVersions.AddIsLocked]: {
      up: (record) => {
        return {
          ...record,
          isLocked: false
        };
      },
      down: (record) => {
        const { isLocked: _, ...rest } = record;
        return {
          ...rest
        };
      }
    },
    [rootShapeVersions.HoistOpacity]: {
      up: ({ props: { opacity, ...props }, ...record }) => {
        return {
          ...record,
          opacity: Number(opacity ?? "1"),
          props
        };
      },
      down: ({ opacity, ...record }) => {
        return {
          ...record,
          props: {
            ...record.props,
            opacity: opacity < 0.175 ? "0.1" : opacity < 0.375 ? "0.25" : opacity < 0.625 ? "0.5" : opacity < 0.875 ? "0.75" : "1"
          }
        };
      }
    },
    [rootShapeVersions.AddMeta]: {
      up: (record) => {
        return {
          ...record,
          meta: {}
        };
      },
      down: ({ meta: _, ...record }) => {
        return {
          ...record
        };
      }
    }
  }
});
function isShape(record) {
  if (!record)
    return false;
  return record.typeName === "shape";
}
function isShapeId(id) {
  if (!id)
    return false;
  return id.startsWith("shape:");
}
function createShapeId(id) {
  return `shape:${id ?? nanoid()}`;
}
function getShapePropKeysByStyle(props) {
  const propKeysByStyle = /* @__PURE__ */ new Map();
  for (const [key, prop] of Object.entries(props)) {
    if (prop instanceof StyleProp) {
      if (propKeysByStyle.has(prop)) {
        throw new Error(
          `Duplicate style prop ${prop.id}. Each style prop can only be used once within a shape.`
        );
      }
      propKeysByStyle.set(prop, key);
    }
  }
  return propKeysByStyle;
}
function createShapeRecordType(shapes) {
  return createRecordType("shape", {
    migrations: defineMigrations({
      currentVersion: rootShapeMigrations.currentVersion,
      firstVersion: rootShapeMigrations.firstVersion,
      migrators: rootShapeMigrations.migrators,
      subTypeKey: "type",
      subTypeMigrations: mapObjectMapValues(shapes, (_, v) => v.migrations ?? defineMigrations({}))
    }),
    scope: "document",
    validator: validation_exports.model(
      "shape",
      validation_exports.union(
        "type",
        mapObjectMapValues(
          shapes,
          (type, { props, meta }) => createShapeValidator(type, props, meta)
        )
      )
    )
  }).withDefaultProperties(() => ({
    x: 0,
    y: 0,
    rotation: 0,
    isLocked: false,
    opacity: 1,
    meta: {}
  }));
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/store-migrations.mjs
var Versions3 = {
  RemoveCodeAndIconShapeTypes: 1,
  AddInstancePresenceType: 2,
  RemoveTLUserAndPresenceAndAddPointer: 3,
  RemoveUserDocument: 4
};
var storeMigrations = defineMigrations({
  currentVersion: Versions3.RemoveUserDocument,
  migrators: {
    [Versions3.RemoveCodeAndIconShapeTypes]: {
      up: (store) => {
        return Object.fromEntries(
          Object.entries(store).filter(
            ([_, v]) => v.typeName !== "shape" || v.type !== "icon" && v.type !== "code"
          )
        );
      },
      down: (store) => {
        return store;
      }
    },
    [Versions3.AddInstancePresenceType]: {
      up: (store) => {
        return store;
      },
      down: (store) => {
        return Object.fromEntries(
          Object.entries(store).filter(([_, v]) => v.typeName !== "instance_presence")
        );
      }
    },
    [Versions3.RemoveTLUserAndPresenceAndAddPointer]: {
      up: (store) => {
        return Object.fromEntries(
          Object.entries(store).filter(([_, v]) => !v.typeName.match(/^(user|user_presence)$/))
        );
      },
      down: (store) => {
        return Object.fromEntries(
          Object.entries(store).filter(([_, v]) => v.typeName !== "pointer")
        );
      }
    },
    [Versions3.RemoveUserDocument]: {
      up: (store) => {
        return Object.fromEntries(
          Object.entries(store).filter(([_, v]) => !v.typeName.match("user_document"))
        );
      },
      down: (store) => {
        return store;
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/createTLSchema.mjs
function createTLSchema({ shapes }) {
  const stylesById = /* @__PURE__ */ new Map();
  for (const shape of objectMapValues(shapes)) {
    for (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) {
      if (stylesById.has(style.id) && stylesById.get(style.id) !== style) {
        throw new Error(`Multiple StyleProp instances with the same id: ${style.id}`);
      }
      stylesById.set(style.id, style);
    }
  }
  const ShapeRecordType = createShapeRecordType(shapes);
  const InstanceRecordType = createInstanceRecordType(stylesById);
  return StoreSchema.create(
    {
      asset: AssetRecordType,
      camera: CameraRecordType,
      document: DocumentRecordType,
      instance: InstanceRecordType,
      instance_page_state: InstancePageStateRecordType,
      page: PageRecordType,
      shape: ShapeRecordType,
      instance_presence: InstancePresenceRecordType,
      pointer: PointerRecordType
    },
    {
      snapshotMigrations: storeMigrations,
      onValidationFailure,
      createIntegrityChecker
    }
  );
}

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/TLColorStyle.mjs
var colors = [
  "black",
  "grey",
  "light-violet",
  "violet",
  "blue",
  "light-blue",
  "yellow",
  "orange",
  "green",
  "light-green",
  "light-red",
  "red"
];
var DefaultColorThemePalette = {
  lightMode: {
    id: "light",
    text: "#000000",
    background: "rgb(249, 250, 251)",
    solid: "#fcfffe",
    black: {
      solid: "#1d1d1d",
      semi: "#e8e8e8",
      pattern: "#494949",
      highlight: {
        srgb: "#fddd00",
        p3: "color(display-p3 0.972 0.8705 0.05)"
      }
    },
    blue: {
      solid: "#4263eb",
      semi: "#dce1f8",
      pattern: "#6681ee",
      highlight: {
        srgb: "#10acff",
        p3: "color(display-p3 0.308 0.6632 0.9996)"
      }
    },
    green: {
      solid: "#099268",
      semi: "#d3e9e3",
      pattern: "#39a785",
      highlight: {
        srgb: "#00ffc8",
        p3: "color(display-p3 0.2536 0.984 0.7981)"
      }
    },
    grey: {
      solid: "#adb5bd",
      semi: "#eceef0",
      pattern: "#bcc3c9",
      highlight: {
        srgb: "#cbe7f1",
        p3: "color(display-p3 0.8163 0.9023 0.9416)"
      }
    },
    "light-blue": {
      solid: "#4dabf7",
      semi: "#ddedfa",
      pattern: "#6fbbf8",
      highlight: {
        srgb: "#00f4ff",
        p3: "color(display-p3 0.1512 0.9414 0.9996)"
      }
    },
    "light-green": {
      solid: "#40c057",
      semi: "#dbf0e0",
      pattern: "#65cb78",
      highlight: {
        srgb: "#65f641",
        p3: "color(display-p3 0.563 0.9495 0.3857)"
      }
    },
    "light-red": {
      solid: "#ff8787",
      semi: "#f4dadb",
      pattern: "#fe9e9e",
      highlight: {
        srgb: "#ff7fa3",
        p3: "color(display-p3 0.9988 0.5301 0.6397)"
      }
    },
    "light-violet": {
      solid: "#e599f7",
      semi: "#f5eafa",
      pattern: "#e9acf8",
      highlight: {
        srgb: "#ff88ff",
        p3: "color(display-p3 0.9676 0.5652 0.9999)"
      }
    },
    orange: {
      solid: "#f76707",
      semi: "#f8e2d4",
      pattern: "#f78438",
      highlight: {
        srgb: "#ffa500",
        p3: "color(display-p3 0.9988 0.6905 0.266)"
      }
    },
    red: {
      solid: "#e03131",
      semi: "#f4dadb",
      pattern: "#e55959",
      highlight: {
        srgb: "#ff636e",
        p3: "color(display-p3 0.9992 0.4376 0.45)"
      }
    },
    violet: {
      solid: "#ae3ec9",
      semi: "#ecdcf2",
      pattern: "#bd63d3",
      highlight: {
        srgb: "#c77cff",
        p3: "color(display-p3 0.7469 0.5089 0.9995)"
      }
    },
    yellow: {
      solid: "#ffc078",
      semi: "#f9f0e6",
      pattern: "#fecb92",
      highlight: {
        srgb: "#fddd00",
        p3: "color(display-p3 0.972 0.8705 0.05)"
      }
    }
  },
  darkMode: {
    id: "dark",
    text: "#f8f9fa",
    background: "#212529",
    solid: "#28292e",
    black: {
      solid: "#e1e1e1",
      semi: "#2c3036",
      pattern: "#989898",
      highlight: {
        srgb: "#d2b700",
        p3: "color(display-p3 0.8078 0.7225 0.0312)"
      }
    },
    blue: {
      solid: "#4156be",
      semi: "#262d40",
      pattern: "#3a4b9e",
      highlight: {
        srgb: "#0079d2",
        p3: "color(display-p3 0.0032 0.4655 0.7991)"
      }
    },
    green: {
      solid: "#3b7b5e",
      semi: "#253231",
      pattern: "#366a53",
      highlight: {
        srgb: "#009774",
        p3: "color(display-p3 0.0085 0.582 0.4604)"
      }
    },
    grey: {
      solid: "#93989f",
      semi: "#33373c",
      pattern: "#7c8187",
      highlight: {
        srgb: "#9cb4cb",
        p3: "color(display-p3 0.6299 0.7012 0.7856)"
      }
    },
    "light-blue": {
      solid: "#588fc9",
      semi: "#2a3642",
      pattern: "#4d7aa9",
      highlight: {
        srgb: "#00bdc8",
        p3: "color(display-p3 0.0023 0.7259 0.7735)"
      }
    },
    "light-green": {
      solid: "#599f57",
      semi: "#2a3830",
      pattern: "#4e874e",
      highlight: {
        srgb: "#00a000",
        p3: "color(display-p3 0.2711 0.6172 0.0195)"
      }
    },
    "light-red": {
      solid: "#c67877",
      semi: "#3b3235",
      pattern: "#a56767",
      highlight: {
        srgb: "#db005b",
        p3: "color(display-p3 0.7849 0.0585 0.3589)"
      }
    },
    "light-violet": {
      solid: "#b583c9",
      semi: "#383442",
      pattern: "#9770a9",
      highlight: {
        srgb: "#c400c7",
        p3: "color(display-p3 0.7024 0.0403 0.753)"
      }
    },
    orange: {
      solid: "#bf612e",
      semi: "#3a2e2a",
      pattern: "#9f552d",
      highlight: {
        srgb: "#d07a00",
        p3: "color(display-p3 0.7699 0.4937 0.0085)"
      }
    },
    red: {
      solid: "#aa3c37",
      semi: "#36292b",
      pattern: "#8f3734",
      highlight: {
        srgb: "#de002c",
        p3: "color(display-p3 0.7978 0.0509 0.2035)"
      }
    },
    violet: {
      solid: "#873fa3",
      semi: "#31293c",
      pattern: "#763a8b",
      highlight: {
        srgb: "#9e00ee",
        p3: "color(display-p3 0.5651 0.0079 0.8986)"
      }
    },
    yellow: {
      solid: "#cba371",
      semi: "#3c3934",
      pattern: "#fecb92",
      highlight: {
        srgb: "#d2b700",
        p3: "color(display-p3 0.8078 0.7225 0.0312)"
      }
    }
  }
};
function getDefaultColorTheme(opts) {
  return opts.isDarkMode ? DefaultColorThemePalette.darkMode : DefaultColorThemePalette.lightMode;
}
var DefaultColorStyle = StyleProp.defineEnum("tldraw:color", {
  defaultValue: "black",
  values: colors
});
var DefaultLabelColorStyle = StyleProp.defineEnum("tldraw:labelColor", {
  defaultValue: "black",
  values: colors
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/TLDashStyle.mjs
var DefaultDashStyle = StyleProp.defineEnum("tldraw:dash", {
  defaultValue: "draw",
  values: ["draw", "solid", "dashed", "dotted"]
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/TLFillStyle.mjs
var DefaultFillStyle = StyleProp.defineEnum("tldraw:fill", {
  defaultValue: "none",
  values: ["none", "semi", "solid", "pattern"]
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/TLFontStyle.mjs
var DefaultFontStyle = StyleProp.defineEnum("tldraw:font", {
  defaultValue: "draw",
  values: ["draw", "sans", "serif", "mono"]
});
var DefaultFontFamilies = {
  draw: "'tldraw_draw', sans-serif",
  sans: "'tldraw_sans', sans-serif",
  serif: "'tldraw_serif', serif",
  mono: "'tldraw_mono', monospace"
};

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/TLSizeStyle.mjs
var DefaultSizeStyle = StyleProp.defineEnum("tldraw:size", {
  defaultValue: "m",
  values: ["s", "m", "l", "xl"]
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLArrowShape.mjs
var arrowheadTypes = [
  "arrow",
  "triangle",
  "square",
  "dot",
  "pipe",
  "diamond",
  "inverted",
  "bar",
  "none"
];
var ArrowShapeArrowheadStartStyle = StyleProp.defineEnum("tldraw:arrowheadStart", {
  defaultValue: "none",
  values: arrowheadTypes
});
var ArrowShapeArrowheadEndStyle = StyleProp.defineEnum("tldraw:arrowheadEnd", {
  defaultValue: "arrow",
  values: arrowheadTypes
});
var ArrowShapeTerminal = validation_exports.union("type", {
  binding: validation_exports.object({
    type: validation_exports.literal("binding"),
    boundShapeId: shapeIdValidator,
    normalizedAnchor: vec2dModelValidator,
    isExact: validation_exports.boolean
  }),
  point: validation_exports.object({
    type: validation_exports.literal("point"),
    x: validation_exports.number,
    y: validation_exports.number
  })
});
var arrowShapeProps = {
  labelColor: DefaultLabelColorStyle,
  color: DefaultColorStyle,
  fill: DefaultFillStyle,
  dash: DefaultDashStyle,
  size: DefaultSizeStyle,
  arrowheadStart: ArrowShapeArrowheadStartStyle,
  arrowheadEnd: ArrowShapeArrowheadEndStyle,
  font: DefaultFontStyle,
  start: ArrowShapeTerminal,
  end: ArrowShapeTerminal,
  bend: validation_exports.number,
  text: validation_exports.string
};
var Versions4 = {
  AddLabelColor: 1
};
var arrowShapeMigrations = defineMigrations({
  currentVersion: Versions4.AddLabelColor,
  migrators: {
    [Versions4.AddLabelColor]: {
      up: (record) => {
        return {
          ...record,
          props: {
            ...record.props,
            labelColor: "black"
          }
        };
      },
      down: (record) => {
        const { labelColor: _, ...props } = record.props;
        return {
          ...record,
          props
        };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLBookmarkShape.mjs
var bookmarkShapeProps = {
  w: validation_exports.nonZeroNumber,
  h: validation_exports.nonZeroNumber,
  assetId: assetIdValidator.nullable(),
  url: validation_exports.string
};
var Versions5 = {
  NullAssetId: 1
};
var bookmarkShapeMigrations = defineMigrations({
  currentVersion: Versions5.NullAssetId,
  migrators: {
    [Versions5.NullAssetId]: {
      up: (shape) => {
        if (shape.props.assetId === void 0) {
          return { ...shape, props: { ...shape.props, assetId: null } };
        }
        return shape;
      },
      down: (shape) => {
        if (shape.props.assetId === null) {
          const { assetId: _, ...props } = shape.props;
          return { ...shape, props };
        }
        return shape;
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLDrawShape.mjs
var DrawShapeSegment = validation_exports.object({
  type: validation_exports.literalEnum("free", "straight"),
  points: validation_exports.arrayOf(vec2dModelValidator)
});
var drawShapeProps = {
  color: DefaultColorStyle,
  fill: DefaultFillStyle,
  dash: DefaultDashStyle,
  size: DefaultSizeStyle,
  segments: validation_exports.arrayOf(DrawShapeSegment),
  isComplete: validation_exports.boolean,
  isClosed: validation_exports.boolean,
  isPen: validation_exports.boolean
};
var Versions6 = {
  AddInPen: 1
};
var drawShapeMigrations = defineMigrations({
  currentVersion: Versions6.AddInPen,
  migrators: {
    [Versions6.AddInPen]: {
      up: (shape) => {
        const { points } = shape.props.segments[0];
        if (points.length === 0) {
          return {
            ...shape,
            props: {
              ...shape.props,
              isPen: false
            }
          };
        }
        let isPen = !(points[0].z === 0 || points[0].z === 0.5);
        if (points[1]) {
          isPen = isPen && !(points[1].z === 0 || points[1].z === 0.5);
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            isPen
          }
        };
      },
      down: (shape) => {
        const { isPen: _isPen, ...propsWithOutIsPen } = shape.props;
        return {
          ...shape,
          props: {
            ...propsWithOutIsPen
          }
        };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLEmbedShape.mjs
var TLDRAW_APP_RE = /(^\/r\/[^/]+\/?$)/;
var safeParseUrl = (url) => {
  try {
    return new URL(url);
  } catch (err) {
    return;
  }
};
var EMBED_DEFINITIONS = [
  {
    type: "tldraw",
    title: "tldraw",
    hostnames: ["beta.tldraw.com", "tldraw.com"],
    minWidth: 300,
    minHeight: 300,
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: true,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(TLDRAW_APP_RE)) {
        return url;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(TLDRAW_APP_RE)) {
        return url;
      }
      return;
    }
  },
  {
    type: "figma",
    title: "Figma",
    hostnames: ["figma.com"],
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: true,
    toEmbedUrl: (url) => {
      if (!!url.match(
        // eslint-disable-next-line no-useless-escape
        /https:\/\/([\w\.-]+\.)?figma.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?$/
      ) && !url.includes("figma.com/embed")) {
        return `https://www.figma.com/embed?embed_host=share&url=${url}`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/^\/embed\/?$/)) {
        const outUrl = urlObj.searchParams.get("url");
        if (outUrl) {
          return outUrl;
        }
      }
      return;
    }
  },
  {
    type: "google_maps",
    title: "Google Maps",
    hostnames: ["google.*"],
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      if (url.includes("/maps/")) {
        const match = url.match(/@(.*),(.*),(.*)z/);
        let result;
        if (match) {
          const [, lat, lng, z] = match;
          const host = new URL(url).host.replace("www.", "");
          result = `https://${host}/maps/embed/v1/view?key=${process.env.NEXT_PUBLIC_GC_API_KEY}&center=${lat},${lng}&zoom=${z}`;
        } else {
          result = "";
        }
        return result;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (!urlObj)
        return;
      const matches = urlObj.pathname.match(/^\/maps\/embed\/v1\/view\/?$/);
      if (matches && urlObj.searchParams.has("center") && urlObj.searchParams.get("zoom")) {
        const zoom = urlObj.searchParams.get("zoom");
        const [lat, lon] = urlObj.searchParams.get("center").split(",");
        return `https://www.google.com/maps/@${lat},${lon},${zoom}z`;
      }
      return;
    }
  },
  {
    type: "val_town",
    title: "Val Town",
    hostnames: ["val.town"],
    minWidth: 260,
    minHeight: 100,
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      const matches = urlObj && urlObj.pathname.match(/\/v\/([^/]+)\/?/);
      if (matches) {
        return `https://www.val.town/embed/${matches[1]}`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      const matches = urlObj && urlObj.pathname.match(/\/embed\/([^/]+)\/?/);
      if (matches) {
        return `https://www.val.town/v/${matches[1]}`;
      }
      return;
    }
  },
  {
    type: "codesandbox",
    title: "CodeSandbox",
    hostnames: ["codesandbox.io"],
    minWidth: 300,
    minHeight: 300,
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      const matches = urlObj && urlObj.pathname.match(/\/s\/([^/]+)\/?/);
      if (matches) {
        return `https://codesandbox.io/embed/${matches[1]}`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      const matches = urlObj && urlObj.pathname.match(/\/embed\/([^/]+)\/?/);
      if (matches) {
        return `https://codesandbox.io/s/${matches[1]}`;
      }
      return;
    }
  },
  {
    type: "codepen",
    title: "Codepen",
    hostnames: ["codepen.io"],
    minWidth: 300,
    minHeight: 300,
    width: 520,
    height: 400,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const CODEPEN_URL_REGEXP = /https:\/\/codepen.io\/([^/]+)\/pen\/([^/]+)/;
      const matches = url.match(CODEPEN_URL_REGEXP);
      if (matches) {
        const [_, user, id] = matches;
        return `https://codepen.io/${user}/embed/${id}`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const CODEPEN_EMBED_REGEXP = /https:\/\/codepen.io\/([^/]+)\/embed\/([^/]+)/;
      const matches = url.match(CODEPEN_EMBED_REGEXP);
      if (matches) {
        const [_, user, id] = matches;
        return `https://codepen.io/${user}/pen/${id}`;
      }
      return;
    }
  },
  {
    type: "scratch",
    title: "Scratch",
    hostnames: ["scratch.mit.edu"],
    width: 520,
    height: 400,
    doesResize: false,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const SCRATCH_URL_REGEXP = /https?:\/\/scratch.mit.edu\/projects\/([^/]+)/;
      const matches = url.match(SCRATCH_URL_REGEXP);
      if (matches) {
        const [_, id] = matches;
        return `https://scratch.mit.edu/projects/embed/${id}`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const SCRATCH_EMBED_REGEXP = /https:\/\/scratch.mit.edu\/projects\/embed\/([^/]+)/;
      const matches = url.match(SCRATCH_EMBED_REGEXP);
      if (matches) {
        const [_, id] = matches;
        return `https://scratch.mit.edu/projects/${id}`;
      }
      return;
    }
  },
  {
    type: "youtube",
    title: "YouTube",
    hostnames: ["*.youtube.com", "youtube.com", "youtu.be"],
    width: 800,
    height: 450,
    doesResize: true,
    canUnmount: false,
    overridePermissions: {
      "allow-presentation": true
    },
    isAspectRatioLocked: true,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (!urlObj)
        return;
      const hostname = urlObj.hostname.replace(/^www./, "");
      if (hostname === "youtu.be") {
        const videoId = urlObj.pathname.split("/").filter(Boolean)[0];
        return `https://www.youtube.com/embed/${videoId}`;
      } else if ((hostname === "youtube.com" || hostname === "m.youtube.com") && urlObj.pathname.match(/^\/watch/)) {
        const videoId = urlObj.searchParams.get("v");
        return `https://www.youtube.com/embed/${videoId}`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (!urlObj)
        return;
      const hostname = urlObj.hostname.replace(/^www./, "");
      if (hostname === "youtube.com") {
        const matches = urlObj.pathname.match(/^\/embed\/([^/]+)\/?/);
        if (matches) {
          return `https://www.youtube.com/watch?v=${matches[1]}`;
        }
      }
      return;
    }
  },
  {
    type: "google_calendar",
    title: "Google Calendar",
    hostnames: ["calendar.google.*"],
    width: 720,
    height: 500,
    minWidth: 460,
    minHeight: 360,
    doesResize: true,
    canUnmount: false,
    instructionLink: "https://support.google.com/calendar/answer/41207?hl=en",
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      const cidQs = urlObj?.searchParams.get("cid");
      if (urlObj?.pathname.match(/\/calendar\/u\/0/) && cidQs) {
        urlObj.pathname = "/calendar/embed";
        const keys = Array.from(urlObj.searchParams.keys());
        for (const key of keys) {
          urlObj.searchParams.delete(key);
        }
        urlObj.searchParams.set("src", cidQs);
        return urlObj.href;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      const srcQs = urlObj?.searchParams.get("src");
      if (urlObj?.pathname.match(/\/calendar\/embed/) && srcQs) {
        urlObj.pathname = "/calendar/u/0";
        const keys = Array.from(urlObj.searchParams.keys());
        for (const key of keys) {
          urlObj.searchParams.delete(key);
        }
        urlObj.searchParams.set("cid", srcQs);
        return urlObj.href;
      }
      return;
    }
  },
  {
    type: "google_slides",
    title: "Google Slides",
    hostnames: ["docs.google.*"],
    width: 720,
    height: 500,
    minWidth: 460,
    minHeight: 360,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj?.pathname.match(/^\/presentation/) && urlObj?.pathname.match(/\/pub\/?$/)) {
        urlObj.pathname = urlObj.pathname.replace(/\/pub$/, "/embed");
        const keys = Array.from(urlObj.searchParams.keys());
        for (const key of keys) {
          urlObj.searchParams.delete(key);
        }
        return urlObj.href;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj?.pathname.match(/^\/presentation/) && urlObj?.pathname.match(/\/embed\/?$/)) {
        urlObj.pathname = urlObj.pathname.replace(/\/embed$/, "/pub");
        const keys = Array.from(urlObj.searchParams.keys());
        for (const key of keys) {
          urlObj.searchParams.delete(key);
        }
        return urlObj.href;
      }
      return;
    }
  },
  {
    type: "github_gist",
    title: "GitHub Gist",
    hostnames: ["gist.github.com"],
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: true,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/\/([^/]+)\/([^/]+)/)) {
        if (!url.split("/").pop())
          return;
        return url;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/\/([^/]+)\/([^/]+)/)) {
        if (!url.split("/").pop())
          return;
        return url;
      }
      return;
    }
  },
  {
    type: "replit",
    title: "Replit",
    hostnames: ["replit.com"],
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/\/@([^/]+)\/([^/]+)/)) {
        return `${url}?embed=true`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/\/@([^/]+)\/([^/]+)/) && urlObj.searchParams.has("embed")) {
        urlObj.searchParams.delete("embed");
        return urlObj.href;
      }
      return;
    }
  },
  {
    type: "felt",
    title: "Felt",
    hostnames: ["felt.com"],
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/^\/map\//)) {
        return urlObj.origin + "/embed" + urlObj.pathname;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/^\/embed\/map\//)) {
        urlObj.pathname = urlObj.pathname.replace(/^\/embed/, "");
        return urlObj.href;
      }
      return;
    }
  },
  {
    type: "spotify",
    title: "Spotify",
    hostnames: ["open.spotify.com"],
    width: 720,
    height: 500,
    minHeight: 500,
    overrideOutlineRadius: 12,
    doesResize: true,
    canUnmount: false,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/^\/(artist|album)\//)) {
        return urlObj.origin + "/embed" + urlObj.pathname;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/^\/embed\/(artist|album)\//)) {
        return urlObj.origin + urlObj.pathname.replace(/^\/embed/, "");
      }
      return;
    }
  },
  {
    type: "vimeo",
    title: "Vimeo",
    hostnames: ["vimeo.com", "player.vimeo.com"],
    width: 640,
    height: 360,
    doesResize: true,
    canUnmount: false,
    isAspectRatioLocked: true,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.hostname === "vimeo.com") {
        if (urlObj.pathname.match(/^\/[0-9]+/)) {
          return "https://player.vimeo.com/video/" + urlObj.pathname.split("/")[1] + "?title=0&byline=0";
        }
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.hostname === "player.vimeo.com") {
        const matches = urlObj.pathname.match(/^\/video\/([^/]+)\/?$/);
        if (matches) {
          return "https://vimeo.com/" + matches[1];
        }
      }
      return;
    }
  },
  {
    type: "excalidraw",
    title: "Excalidraw",
    hostnames: ["excalidraw.com"],
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: false,
    isAspectRatioLocked: true,
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.hash.match(/#room=/)) {
        return url;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.hash.match(/#room=/)) {
        return url;
      }
      return;
    }
  },
  {
    type: "observable",
    title: "Observable",
    hostnames: ["observablehq.com"],
    width: 720,
    height: 500,
    doesResize: true,
    canUnmount: false,
    isAspectRatioLocked: false,
    backgroundColor: "#fff",
    toEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/^\/@([^/]+)\/([^/]+)\/?$/)) {
        return `${urlObj.origin}/embed${urlObj.pathname}?cell=*`;
      }
      if (urlObj && urlObj.pathname.match(/^\/d\/([^/]+)\/?$/)) {
        const pathName = urlObj.pathname.replace(/^\/d/, "");
        return `${urlObj.origin}/embed${pathName}?cell=*`;
      }
      return;
    },
    fromEmbedUrl: (url) => {
      const urlObj = safeParseUrl(url);
      if (urlObj && urlObj.pathname.match(/^\/embed\/@([^/]+)\/([^/]+)\/?$/)) {
        return `${urlObj.origin}${urlObj.pathname.replace("/embed", "")}#cell-*`;
      }
      if (urlObj && urlObj.pathname.match(/^\/embed\/([^/]+)\/?$/)) {
        return `${urlObj.origin}${urlObj.pathname.replace("/embed", "/d")}#cell-*`;
      }
      return;
    }
  }
];
var embedShapePermissionDefaults = {
  // ========================================================================================
  // Disabled permissions
  // ========================================================================================
  // [MDN] Experimental: Allows for downloads to occur without a gesture from the user.
  // [REASON] Disabled because otherwise the <iframe/> trick the user on behalf of us to performing an action
  "allow-downloads-without-user-activation": false,
  // [MDN] Allows for downloads to occur with a gesture from the user.
  // [REASON] Disabled because otherwise the <iframe/> trick the user on behalf of us to performing an action
  "allow-downloads": false,
  // [MDN] Lets the resource open modal windows.
  // [REASON] The <iframe/> could 'window.prompt("Enter your tldraw password")'
  "allow-modals": false,
  // [MDN] Lets the resource lock the screen orientation.
  // [REASON] Would interfer with tldraw interface
  "allow-orientation-lock": false,
  // [MDN] Lets the resource use the Pointer Lock API.
  // [REASON] Maybe we should allow this for games embeds (scratch/codepen/codesandbox)
  "allow-pointer-lock": false,
  // [MDN] Allows popups (such as window.open(), target="_blank", or showModalDialog()). If this keyword is not used, the popup will silently fail to open.
  // [REASON] We shouldn't allow popups as a embed could pretend to be us by opening a mocked version of tldraw. This is very unobvious when it is performed as an action within out app
  "allow-popups": true,
  // [MDN] Lets the sandboxed document open new windows without those windows inheriting the sandboxing. For example, this can safely sandbox an advertisement without forcing the same restrictions upon the page the ad links to.
  // [REASON] We're alread disabling popups.
  "allow-popups-to-escape-sandbox": false,
  // [MDN] Lets the resource start a presentation session.
  // [REASON] Prevents embed from navigating away from tldraw and pretending to be us
  "allow-presentation": false,
  // [MDN] Experimental: Lets the resource request access to the parent's storage capabilities with the Storage Access API.
  // [REASON] We don't want anyone else to access our storage
  "allow-storage-access-by-user-activation": false,
  // [MDN] Lets the resource navigate the top-level browsing context (the one named _top).
  // [REASON] Prevents embed from navigating away from tldraw and pretending to be us
  "allow-top-navigation": false,
  // [MDN] Lets the resource navigate the top-level browsing context, but only if initiated by a user gesture.
  // [REASON] Prevents embed from navigating away from tldraw and pretending to be us
  "allow-top-navigation-by-user-activation": false,
  // ========================================================================================
  // Enabled permissions
  // ========================================================================================
  // [MDN] Lets the resource run scripts (but not create popup windows).
  "allow-scripts": true,
  // [MDN] If this token is not used, the resource is treated as being from a special origin that always fails the same-origin policy (potentially preventing access to data storage/cookies and some JavaScript APIs).
  "allow-same-origin": true,
  // [MDN] Allows the resource to submit forms. If this keyword is not used, form submission is blocked.
  "allow-forms": true
};
var embedShapeProps = {
  w: validation_exports.nonZeroNumber,
  h: validation_exports.nonZeroNumber,
  url: validation_exports.string
};
var Versions7 = {
  GenOriginalUrlInEmbed: 1,
  RemoveDoesResize: 2,
  RemoveTmpOldUrl: 3,
  RemovePermissionOverrides: 4
};
var embedShapeMigrations = defineMigrations({
  currentVersion: Versions7.RemovePermissionOverrides,
  migrators: {
    [Versions7.GenOriginalUrlInEmbed]: {
      // add tmpOldUrl property
      up: (shape) => {
        const url = shape.props.url;
        const host = new URL(url).host.replace("www.", "");
        let originalUrl;
        for (const localEmbedDef of EMBED_DEFINITIONS) {
          if (localEmbedDef.hostnames.includes(host)) {
            try {
              originalUrl = localEmbedDef.fromEmbedUrl(url);
            } catch (err) {
              console.warn(err);
            }
          }
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            tmpOldUrl: shape.props.url,
            url: originalUrl ?? ""
          }
        };
      },
      // remove tmpOldUrl property
      down: (shape) => {
        let newUrl = shape.props.tmpOldUrl;
        if (!newUrl || newUrl === "") {
          const url = shape.props.url;
          const host = new URL(url).host.replace("www.", "");
          for (const localEmbedDef of EMBED_DEFINITIONS) {
            if (localEmbedDef.hostnames.includes(host)) {
              try {
                newUrl = localEmbedDef.toEmbedUrl(url);
              } catch (err) {
                console.warn(err);
              }
            }
          }
        }
        const { tmpOldUrl, ...props } = shape.props;
        return {
          ...shape,
          props: {
            ...props,
            url: newUrl ?? ""
          }
        };
      }
    },
    [Versions7.RemoveDoesResize]: {
      up: (shape) => {
        const { doesResize: _, ...props } = shape.props;
        return {
          ...shape,
          props: {
            ...props
          }
        };
      },
      down: (shape) => {
        return {
          ...shape,
          props: {
            ...shape.props,
            doesResize: true
          }
        };
      }
    },
    [Versions7.RemoveTmpOldUrl]: {
      up: (shape) => {
        const { tmpOldUrl: _, ...props } = shape.props;
        return {
          ...shape,
          props: {
            ...props
          }
        };
      },
      down: (shape) => {
        return {
          ...shape,
          props: {
            ...shape.props
          }
        };
      }
    },
    [Versions7.RemovePermissionOverrides]: {
      up: (shape) => {
        const { overridePermissions: _, ...props } = shape.props;
        return {
          ...shape,
          props: {
            ...props
          }
        };
      },
      down: (shape) => {
        return {
          ...shape,
          props: {
            ...shape.props
          }
        };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLFrameShape.mjs
var frameShapeProps = {
  w: validation_exports.nonZeroNumber,
  h: validation_exports.nonZeroNumber,
  name: validation_exports.string
};
var frameShapeMigrations = defineMigrations({});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/TLHorizontalAlignStyle.mjs
var DefaultHorizontalAlignStyle = StyleProp.defineEnum("tldraw:horizontalAlign", {
  defaultValue: "middle",
  values: ["start", "middle", "end", "start-legacy", "end-legacy", "middle-legacy"]
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/styles/TLVerticalAlignStyle.mjs
var DefaultVerticalAlignStyle = StyleProp.defineEnum("tldraw:verticalAlign", {
  defaultValue: "middle",
  values: ["start", "middle", "end"]
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLGeoShape.mjs
var GeoShapeGeoStyle = StyleProp.defineEnum("tldraw:geo", {
  defaultValue: "rectangle",
  values: [
    "cloud",
    "rectangle",
    "ellipse",
    "triangle",
    "diamond",
    "pentagon",
    "hexagon",
    "octagon",
    "star",
    "rhombus",
    "rhombus-2",
    "oval",
    "trapezoid",
    "arrow-right",
    "arrow-left",
    "arrow-up",
    "arrow-down",
    "x-box",
    "check-box"
  ]
});
var geoShapeProps = {
  geo: GeoShapeGeoStyle,
  labelColor: DefaultLabelColorStyle,
  color: DefaultColorStyle,
  fill: DefaultFillStyle,
  dash: DefaultDashStyle,
  size: DefaultSizeStyle,
  font: DefaultFontStyle,
  align: DefaultHorizontalAlignStyle,
  verticalAlign: DefaultVerticalAlignStyle,
  url: validation_exports.string,
  w: validation_exports.nonZeroNumber,
  h: validation_exports.nonZeroNumber,
  growY: validation_exports.positiveNumber,
  text: validation_exports.string
};
var Versions8 = {
  AddUrlProp: 1,
  AddLabelColor: 2,
  RemoveJustify: 3,
  AddCheckBox: 4,
  AddVerticalAlign: 5,
  MigrateLegacyAlign: 6,
  AddCloud: 7
};
var geoShapeMigrations = defineMigrations({
  currentVersion: Versions8.AddCloud,
  migrators: {
    [Versions8.AddUrlProp]: {
      up: (shape) => {
        return { ...shape, props: { ...shape.props, url: "" } };
      },
      down: (shape) => {
        const { url: _, ...props } = shape.props;
        return { ...shape, props };
      }
    },
    [Versions8.AddLabelColor]: {
      up: (record) => {
        return {
          ...record,
          props: {
            ...record.props,
            labelColor: "black"
          }
        };
      },
      down: (record) => {
        const { labelColor: _, ...props } = record.props;
        return {
          ...record,
          props
        };
      }
    },
    [Versions8.RemoveJustify]: {
      up: (shape) => {
        let newAlign = shape.props.align;
        if (newAlign === "justify") {
          newAlign = "start";
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            align: newAlign
          }
        };
      },
      down: (shape) => {
        return { ...shape };
      }
    },
    [Versions8.AddCheckBox]: {
      up: (shape) => {
        return { ...shape };
      },
      down: (shape) => {
        return {
          ...shape,
          props: {
            ...shape.props,
            geo: shape.props.geo === "check-box" ? "rectangle" : shape.props.geo
          }
        };
      }
    },
    [Versions8.AddVerticalAlign]: {
      up: (shape) => {
        return {
          ...shape,
          props: {
            ...shape.props,
            verticalAlign: "middle"
          }
        };
      },
      down: (shape) => {
        const { verticalAlign: _, ...props } = shape.props;
        return {
          ...shape,
          props
        };
      }
    },
    [Versions8.MigrateLegacyAlign]: {
      up: (shape) => {
        let newAlign;
        switch (shape.props.align) {
          case "start":
            newAlign = "start-legacy";
            break;
          case "end":
            newAlign = "end-legacy";
            break;
          default:
            newAlign = "middle-legacy";
            break;
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            align: newAlign
          }
        };
      },
      down: (shape) => {
        let oldAlign;
        switch (shape.props.align) {
          case "start-legacy":
            oldAlign = "start";
            break;
          case "end-legacy":
            oldAlign = "end";
            break;
          case "middle-legacy":
            oldAlign = "middle";
            break;
          default:
            oldAlign = shape.props.align;
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            align: oldAlign
          }
        };
      }
    },
    [Versions8.AddCloud]: {
      up: (shape) => {
        return shape;
      },
      down: (shape) => {
        if (shape.props.geo === "cloud") {
          return {
            ...shape,
            props: {
              ...shape.props,
              geo: "rectangle"
            }
          };
        }
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLGroupShape.mjs
var groupShapeProps = {};
var groupShapeMigrations = defineMigrations({});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLHighlightShape.mjs
var highlightShapeProps = {
  color: DefaultColorStyle,
  size: DefaultSizeStyle,
  segments: validation_exports.arrayOf(DrawShapeSegment),
  isComplete: validation_exports.boolean,
  isPen: validation_exports.boolean
};
var highlightShapeMigrations = defineMigrations({});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLImageShape.mjs
var ImageShapeCrop = validation_exports.object({
  topLeft: vec2dModelValidator,
  bottomRight: vec2dModelValidator
});
var imageShapeProps = {
  w: validation_exports.nonZeroNumber,
  h: validation_exports.nonZeroNumber,
  playing: validation_exports.boolean,
  url: validation_exports.string,
  assetId: assetIdValidator.nullable(),
  crop: ImageShapeCrop.nullable()
};
var Versions9 = {
  AddUrlProp: 1,
  AddCropProp: 2
};
var imageShapeMigrations = defineMigrations({
  currentVersion: Versions9.AddCropProp,
  migrators: {
    [Versions9.AddUrlProp]: {
      up: (shape) => {
        return { ...shape, props: { ...shape.props, url: "" } };
      },
      down: (shape) => {
        const { url: _, ...props } = shape.props;
        return { ...shape, props };
      }
    },
    [Versions9.AddCropProp]: {
      up: (shape) => {
        return { ...shape, props: { ...shape.props, crop: null } };
      },
      down: (shape) => {
        const { crop: _, ...props } = shape.props;
        return { ...shape, props };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/misc/TLHandle.mjs
var TL_HANDLE_TYPES = /* @__PURE__ */ new Set(["vertex", "virtual", "create"]);
var handleValidator = validation_exports.object({
  id: validation_exports.string,
  type: validation_exports.setEnum(TL_HANDLE_TYPES),
  canBind: validation_exports.boolean.optional(),
  canSnap: validation_exports.boolean.optional(),
  index: validation_exports.string,
  x: validation_exports.number,
  y: validation_exports.number
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLLineShape.mjs
var LineShapeSplineStyle = StyleProp.defineEnum("tldraw:spline", {
  defaultValue: "line",
  values: ["cubic", "line"]
});
var lineShapeProps = {
  color: DefaultColorStyle,
  dash: DefaultDashStyle,
  size: DefaultSizeStyle,
  spline: LineShapeSplineStyle,
  handles: validation_exports.dict(validation_exports.string, handleValidator)
};
var lineShapeVersions = {
  AddSnapHandles: 1
};
var lineShapeMigrations = defineMigrations({
  currentVersion: lineShapeVersions.AddSnapHandles,
  migrators: {
    [lineShapeVersions.AddSnapHandles]: {
      up: (record) => {
        const handles = deepCopy(record.props.handles);
        for (const id in handles) {
          handles[id].canSnap = true;
        }
        return { ...record, props: { ...record.props, handles } };
      },
      down: (record) => {
        const handles = deepCopy(record.props.handles);
        for (const id in handles) {
          delete handles[id].canSnap;
        }
        return { ...record, props: { ...record.props, handles } };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLNoteShape.mjs
var noteShapeProps = {
  color: DefaultColorStyle,
  size: DefaultSizeStyle,
  font: DefaultFontStyle,
  align: DefaultHorizontalAlignStyle,
  verticalAlign: DefaultVerticalAlignStyle,
  growY: validation_exports.positiveNumber,
  url: validation_exports.string,
  text: validation_exports.string
};
var Versions10 = {
  AddUrlProp: 1,
  RemoveJustify: 2,
  MigrateLegacyAlign: 3,
  AddVerticalAlign: 4
};
var noteShapeMigrations = defineMigrations({
  currentVersion: Versions10.AddVerticalAlign,
  migrators: {
    [Versions10.AddUrlProp]: {
      up: (shape) => {
        return { ...shape, props: { ...shape.props, url: "" } };
      },
      down: (shape) => {
        const { url: _, ...props } = shape.props;
        return { ...shape, props };
      }
    },
    [Versions10.RemoveJustify]: {
      up: (shape) => {
        let newAlign = shape.props.align;
        if (newAlign === "justify") {
          newAlign = "start";
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            align: newAlign
          }
        };
      },
      down: (shape) => {
        return { ...shape };
      }
    },
    [Versions10.MigrateLegacyAlign]: {
      up: (shape) => {
        let newAlign;
        switch (shape.props.align) {
          case "start":
            newAlign = "start-legacy";
            break;
          case "end":
            newAlign = "end-legacy";
            break;
          default:
            newAlign = "middle-legacy";
            break;
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            align: newAlign
          }
        };
      },
      down: (shape) => {
        let oldAlign;
        switch (shape.props.align) {
          case "start-legacy":
            oldAlign = "start";
            break;
          case "end-legacy":
            oldAlign = "end";
            break;
          case "middle-legacy":
            oldAlign = "middle";
            break;
          default:
            oldAlign = shape.props.align;
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            align: oldAlign
          }
        };
      }
    },
    [Versions10.AddVerticalAlign]: {
      up: (shape) => {
        return {
          ...shape,
          props: {
            ...shape.props,
            verticalAlign: "middle"
          }
        };
      },
      down: (shape) => {
        const { verticalAlign: _, ...props } = shape.props;
        return {
          ...shape,
          props
        };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLTextShape.mjs
var textShapeProps = {
  color: DefaultColorStyle,
  size: DefaultSizeStyle,
  font: DefaultFontStyle,
  align: DefaultHorizontalAlignStyle,
  w: validation_exports.nonZeroNumber,
  text: validation_exports.string,
  scale: validation_exports.nonZeroNumber,
  autoSize: validation_exports.boolean
};
var Versions11 = {
  RemoveJustify: 1
};
var textShapeMigrations = defineMigrations({
  currentVersion: Versions11.RemoveJustify,
  migrators: {
    [Versions11.RemoveJustify]: {
      up: (shape) => {
        let newAlign = shape.props.align;
        if (newAlign === "justify") {
          newAlign = "start";
        }
        return {
          ...shape,
          props: {
            ...shape.props,
            align: newAlign
          }
        };
      },
      down: (shape) => {
        return { ...shape };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/shapes/TLVideoShape.mjs
var videoShapeProps = {
  w: validation_exports.nonZeroNumber,
  h: validation_exports.nonZeroNumber,
  time: validation_exports.number,
  playing: validation_exports.boolean,
  url: validation_exports.string,
  assetId: assetIdValidator.nullable()
};
var Versions12 = {
  AddUrlProp: 1
};
var videoShapeMigrations = defineMigrations({
  currentVersion: Versions12.AddUrlProp,
  migrators: {
    [Versions12.AddUrlProp]: {
      up: (shape) => {
        return { ...shape, props: { ...shape.props, url: "" } };
      },
      down: (shape) => {
        const { url: _, ...props } = shape.props;
        return { ...shape, props };
      }
    }
  }
});

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/translations/languages.mjs
var LANGUAGES = [
  { locale: "ar", label: "عربي" },
  { locale: "ca", label: "Català" },
  { locale: "da", label: "Danish" },
  { locale: "de", label: "Deutsch" },
  { locale: "en", label: "English" },
  { locale: "es", label: "Español" },
  { locale: "fa", label: "فارسی" },
  { locale: "fi", label: "Suomi" },
  { locale: "fr", label: "Français" },
  { locale: "gl", label: "Galego" },
  { locale: "he", label: "עברית" },
  { locale: "it", label: "Italiano" },
  { locale: "ja", label: "日本語" },
  { locale: "ko-kr", label: "한국어" },
  { locale: "ku", label: "کوردی" },
  { locale: "hi-in", label: "हिन्दी" },
  { locale: "hu", label: "Magyar" },
  { locale: "my", label: "မြန်မာစာ" },
  { locale: "ne", label: "नेपाली" },
  { locale: "no", label: "Norwegian" },
  { locale: "pl", label: "Polski" },
  { locale: "pt-br", label: "Português - Brasil" },
  { locale: "pt-pt", label: "Português - Europeu" },
  { locale: "ro", label: "Română" },
  { locale: "ru", label: "Russian" },
  { locale: "sv", label: "Svenska" },
  { locale: "te", label: "తెలుగు" },
  { locale: "th", label: "ภาษาไทย" },
  { locale: "tr", label: "Türkçe" },
  { locale: "uk", label: "Ukrainian" },
  { locale: "vi", label: "Tiếng Việt" },
  { locale: "zh-cn", label: "Chinese - Simplified" },
  { locale: "zh-tw", label: "繁體中文 (台灣)" }
];

// node_modules/.deno/@tldraw+tlschema@2.0.0-alpha.17/node_modules/@tldraw/tlschema/dist-esm/translations/translations.mjs
function getDefaultTranslationLocale() {
  const locales = typeof window !== "undefined" ? window.navigator.languages ?? ["en"] : ["en"];
  return _getDefaultTranslationLocale(locales);
}
function _getDefaultTranslationLocale(locales) {
  for (const locale of locales) {
    const supportedLocale = getSupportedLocale(locale);
    if (supportedLocale) {
      return supportedLocale;
    }
  }
  return "en";
}
var DEFAULT_LOCALE_REGIONS = {
  zh: "zh-cn",
  pt: "pt-br",
  ko: "ko-kr",
  hi: "hi-in"
};
function getSupportedLocale(locale) {
  const exactMatch = LANGUAGES.find((t2) => t2.locale === locale.toLowerCase());
  if (exactMatch) {
    return exactMatch.locale;
  }
  const [language, region] = locale.split(/[-_]/).map((s) => s.toLowerCase());
  if (region) {
    const languageMatch = LANGUAGES.find((t2) => t2.locale === language);
    if (languageMatch) {
      return languageMatch.locale;
    }
  }
  if (language in DEFAULT_LOCALE_REGIONS) {
    return DEFAULT_LOCALE_REGIONS[language];
  }
  return null;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/TldrawEditor.mjs
var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
var import_react35 = __toESM(require_react(), 1);
var import_classnames10 = __toESM(require_classnames(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/Canvas.mjs
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
var import_classnames9 = __toESM(require_classnames(), 1);
var import_react28 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useCanvasEvents.mjs
var import_react9 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/debug-flags.mjs
var featureFlags = {
  // todo: remove this. it's not used, but we only have one feature flag and i
  // wanted an example :(
};
var debugFlags = {
  // --- DEBUG VALUES ---
  preventDefaultLogging: createDebugValue("preventDefaultLogging", {
    defaults: { all: false }
  }),
  pointerCaptureLogging: createDebugValue("pointerCaptureLogging", {
    defaults: { all: false }
  }),
  pointerCaptureTracking: createDebugValue("pointerCaptureTracking", {
    defaults: { all: false }
  }),
  pointerCaptureTrackingObject: createDebugValue(
    "pointerCaptureTrackingObject",
    // ideally we wouldn't store this mutable value in an atom but it's not
    // a big deal for debug values
    {
      defaults: { all: /* @__PURE__ */ new Map() },
      shouldStoreForSession: false
    }
  ),
  elementRemovalLogging: createDebugValue("elementRemovalLogging", {
    defaults: { all: false }
  }),
  debugSvg: createDebugValue("debugSvg", {
    defaults: { all: false }
  }),
  throwToBlob: createDebugValue("throwToBlob", {
    defaults: { all: false }
  }),
  logMessages: createDebugValue("uiLog", { defaults: { all: [] } }),
  resetConnectionEveryPing: createDebugValue("resetConnectionEveryPing", {
    defaults: { all: false }
  }),
  debugCursors: createDebugValue("debugCursors", {
    defaults: { all: false }
  }),
  forceSrgb: createDebugValue("forceSrgbColors", { defaults: { all: false } }),
  debugGeometry: createDebugValue("debugGeometry", { defaults: { all: false } }),
  hideShapes: createDebugValue("hideShapes", { defaults: { all: false } })
};
if (typeof window !== "undefined") {
  window.tldrawLog = (message) => {
    debugFlags.logMessages.set(debugFlags.logMessages.value.concat(message));
  };
}
if (typeof Element !== "undefined") {
  const nativeElementRemoveChild = Element.prototype.removeChild;
  react("element removal logging", () => {
    if (debugFlags.elementRemovalLogging.value) {
      Element.prototype.removeChild = function(child) {
        console.warn("[tldraw] removing child:", child);
        return nativeElementRemoveChild.call(this, child);
      };
    } else {
      Element.prototype.removeChild = nativeElementRemoveChild;
    }
  });
}
function createDebugValue(name, {
  defaults: defaults2,
  shouldStoreForSession = true
}) {
  return createDebugValueBase({
    name,
    defaults: defaults2,
    shouldStoreForSession
  });
}
function createDebugValueBase(def) {
  const defaultValue = getDefaultValue(def);
  const storedValue = def.shouldStoreForSession ? getStoredInitialValue(def.name) : null;
  const valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue);
  if (typeof window !== "undefined") {
    if (def.shouldStoreForSession) {
      react(`debug:${def.name}`, () => {
        const currentValue = valueAtom.value;
        try {
          if (currentValue === defaultValue) {
            window.sessionStorage.removeItem(`tldraw_debug:${def.name}`);
          } else {
            window.sessionStorage.setItem(`tldraw_debug:${def.name}`, JSON.stringify(currentValue));
          }
        } catch {
        }
      });
    }
    Object.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l) => l.toUpperCase())}`, {
      get() {
        return valueAtom.value;
      },
      set(newValue) {
        valueAtom.set(newValue);
      },
      configurable: true
    });
  }
  return Object.assign(valueAtom, def);
}
function getStoredInitialValue(name) {
  try {
    return JSON.parse(window?.sessionStorage.getItem(`tldraw_debug:${name}`) ?? "null");
  } catch (err) {
    return null;
  }
}
function readEnv(fn) {
  try {
    return fn();
  } catch {
    return null;
  }
}
function getDefaultValue(def) {
  const env = readEnv(() => process.env.TLDRAW_ENV) ?? readEnv(() => process.env.VERCEL_PUBLIC_TLDRAW_ENV) ?? readEnv(() => process.env.NEXT_PUBLIC_TLDRAW_ENV) ?? // default to production because if we don't have one of these, this is probably a library use
  "production";
  switch (env) {
    case "production":
      return def.defaults.production ?? def.defaults.all;
    case "preview":
    case "staging":
      return def.defaults.staging ?? def.defaults.all;
    default:
      return def.defaults.development ?? def.defaults.all;
  }
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs
function loopToHtmlElement(elm) {
  if (elm instanceof HTMLElement)
    return elm;
  if (elm.parentElement)
    return loopToHtmlElement(elm.parentElement);
  else
    throw Error("Could not find a parent element of an HTML type!");
}
function preventDefault(event) {
  event.preventDefault();
  if (debugFlags.preventDefaultLogging.value) {
    console.warn("preventDefault called on event:", event);
  }
}
function setPointerCapture(element, event) {
  element.setPointerCapture(event.pointerId);
  if (debugFlags.pointerCaptureTracking.value) {
    const trackingObj = debugFlags.pointerCaptureTrackingObject.value;
    trackingObj.set(element, (trackingObj.get(element) ?? 0) + 1);
  }
  if (debugFlags.pointerCaptureLogging.value) {
    console.warn("setPointerCapture called on element:", element, event);
  }
}
function releasePointerCapture(element, event) {
  if (!element.hasPointerCapture(event.pointerId)) {
    return;
  }
  element.releasePointerCapture(event.pointerId);
  if (debugFlags.pointerCaptureTracking.value) {
    const trackingObj = debugFlags.pointerCaptureTrackingObject.value;
    if (trackingObj.get(element) === 1) {
      trackingObj.delete(element);
    } else if (trackingObj.has(element)) {
      trackingObj.set(element, trackingObj.get(element) - 1);
    } else {
      console.warn("Release without capture");
    }
  }
  if (debugFlags.pointerCaptureLogging.value) {
    console.warn("releasePointerCapture called on element:", element, event);
  }
}
var stopEventPropagation = (e) => e.stopPropagation();

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/getPointerInfo.mjs
function getPointerInfo(e) {
  ;
  e.isKilled = true;
  return {
    point: {
      x: e.clientX,
      y: e.clientY,
      z: e.pressure
    },
    shiftKey: e.shiftKey,
    altKey: e.altKey,
    ctrlKey: e.metaKey || e.ctrlKey,
    pointerId: e.pointerId,
    button: e.button,
    isPen: e.pointerType === "pen"
  };
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useEditor.mjs
var import_react8 = __toESM(require_react(), 1);
var EditorContext = import_react8.default.createContext({});
var useEditor = () => {
  return import_react8.default.useContext(EditorContext);
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useCanvasEvents.mjs
function useCanvasEvents() {
  const editor = useEditor();
  const events = (0, import_react9.useMemo)(
    function canvasEvents() {
      let lastX, lastY;
      function onPointerDown(e) {
        if (e.isKilled)
          return;
        if (e.button === 2) {
          editor.dispatch({
            type: "pointer",
            target: "canvas",
            name: "right_click",
            ...getPointerInfo(e)
          });
          return;
        }
        if (e.button !== 0 && e.button !== 1 && e.button !== 5)
          return;
        setPointerCapture(e.currentTarget, e);
        editor.dispatch({
          type: "pointer",
          target: "canvas",
          name: "pointer_down",
          ...getPointerInfo(e)
        });
        if (editor.openMenus.length > 0) {
          document.body.click();
          editor.getContainer().focus();
        }
      }
      function onPointerMove(e) {
        if (e.isKilled)
          return;
        if (e.clientX === lastX && e.clientY === lastY)
          return;
        lastX = e.clientX;
        lastY = e.clientY;
        editor.dispatch({
          type: "pointer",
          target: "canvas",
          name: "pointer_move",
          ...getPointerInfo(e)
        });
      }
      function onPointerUp(e) {
        if (e.isKilled)
          return;
        if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5)
          return;
        lastX = e.clientX;
        lastY = e.clientY;
        releasePointerCapture(e.currentTarget, e);
        editor.dispatch({
          type: "pointer",
          target: "canvas",
          name: "pointer_up",
          ...getPointerInfo(e)
        });
      }
      function onPointerEnter(e) {
        if (e.isKilled)
          return;
        if (editor.instanceState.isPenMode && e.pointerType !== "pen")
          return;
        const canHover = e.pointerType === "mouse" || e.pointerType === "pen";
        editor.updateInstanceState({ isHoveringCanvas: canHover ? true : null });
      }
      function onPointerLeave(e) {
        if (e.isKilled)
          return;
        if (editor.instanceState.isPenMode && e.pointerType !== "pen")
          return;
        const canHover = e.pointerType === "mouse" || e.pointerType === "pen";
        editor.updateInstanceState({ isHoveringCanvas: canHover ? false : null });
      }
      function onTouchStart(e) {
        ;
        e.isKilled = true;
        document.body.click();
        preventDefault(e);
      }
      function onTouchEnd(e) {
        ;
        e.isKilled = true;
        if (e.target.tagName !== "A" && e.target.tagName !== "TEXTAREA") {
          preventDefault(e);
        }
      }
      function onDragOver(e) {
        preventDefault(e);
      }
      async function onDrop(e) {
        preventDefault(e);
        if (!e.dataTransfer?.files?.length)
          return;
        const files = Array.from(e.dataTransfer.files);
        await editor.putExternalContent({
          type: "files",
          files,
          point: editor.screenToPage({ x: e.clientX, y: e.clientY }),
          ignoreParent: false
        });
      }
      function onClick(e) {
        stopEventPropagation(e);
      }
      return {
        onPointerDown,
        onPointerMove,
        onPointerUp,
        onPointerEnter,
        onPointerLeave,
        onDragOver,
        onDrop,
        onTouchStart,
        onTouchEnd,
        onClick
      };
    },
    [editor]
  );
  return events;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useCoarsePointer.mjs
var import_react10 = __toESM(require_react(), 1);
function useCoarsePointer() {
  const editor = useEditor();
  (0, import_react10.useEffect)(() => {
    if (editor.environment.isFirefox && !editor.environment.isAndroid && !editor.environment.isIos) {
      editor.updateInstanceState({ isCoarsePointer: false });
      return;
    }
    if (window.matchMedia) {
      const mql = window.matchMedia("(pointer: coarse)");
      const handler = () => {
        editor.updateInstanceState({ isCoarsePointer: !!mql.matches });
      };
      handler();
      if (mql) {
        mql.addEventListener("change", handler);
        return () => mql.removeEventListener("change", handler);
      }
    }
  }, [editor]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs
var import_react12 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useContainer.mjs
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
var import_react11 = __toESM(require_react(), 1);
var ContainerContext = (0, import_react11.createContext)(null);
function ContainerProvider({
  container,
  children
}) {
  return (0, import_jsx_runtime.jsx)(ContainerContext.Provider, { value: container, children });
}
function useContainer() {
  return assertExists((0, import_react11.useContext)(ContainerContext), "useContainer used outside of <Tldraw />");
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs
function useDocumentEvents() {
  const editor = useEditor();
  const container = useContainer();
  const isAppFocused = useValue("isFocused", () => editor.instanceState.isFocused, [editor]);
  (0, import_react12.useEffect)(() => {
    if (typeof matchMedia === void 0)
      return;
    let remove2 = null;
    const updatePixelRatio = () => {
      if (remove2 != null) {
        remove2();
      }
      const mqString = `(resolution: ${window.devicePixelRatio}dppx)`;
      const media = matchMedia(mqString);
      media.addEventListener("change", updatePixelRatio);
      remove2 = () => {
        media.removeEventListener("change", updatePixelRatio);
      };
      editor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio });
    };
    updatePixelRatio();
    return () => {
      remove2?.();
    };
  }, [editor]);
  (0, import_react12.useEffect)(() => {
    if (!isAppFocused)
      return;
    const handleKeyDown = (e) => {
      if (e.altKey && // todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them?
      (editor.isIn("zoom") || !editor.root.path.value.endsWith(".idle")) && !isFocusingInput()) {
        preventDefault(e);
      }
      if (e.isKilled)
        return;
      e.isKilled = true;
      switch (e.key) {
        case "=":
        case "-":
        case "0": {
          if (e.metaKey || e.ctrlKey) {
            preventDefault(e);
            return;
          }
          break;
        }
        case "Tab": {
          if (isFocusingInput() || editor.isMenuOpen) {
            return;
          }
          break;
        }
        case ",": {
          if (!isFocusingInput()) {
            preventDefault(e);
            if (!editor.inputs.keys.has("Comma")) {
              const { x, y, z } = editor.inputs.currentScreenPoint;
              editor.inputs.keys.add("Comma");
              const info2 = {
                type: "pointer",
                name: "pointer_down",
                point: { x, y, z },
                shiftKey: e.shiftKey,
                altKey: e.altKey,
                ctrlKey: e.metaKey || e.ctrlKey,
                pointerId: 0,
                button: 0,
                isPen: editor.instanceState.isPenMode,
                target: "canvas"
              };
              editor.dispatch(info2);
              return;
            }
          }
          break;
        }
        case "Escape": {
          if (editor.editingShape || editor.selectedShapeIds.length > 0) {
            e.preventDefault();
          }
          if (editor.openMenus.length > 0)
            return;
          if (!editor.inputs.keys.has("Escape")) {
            editor.inputs.keys.add("Escape");
            editor.cancel();
            container.focus();
          }
          return;
        }
        default: {
          if (isFocusingInput() || editor.isMenuOpen) {
            return;
          }
        }
      }
      const info = {
        type: "keyboard",
        name: e.repeat ? "key_repeat" : "key_down",
        key: e.key,
        code: e.code,
        shiftKey: e.shiftKey,
        altKey: e.altKey,
        ctrlKey: e.metaKey || e.ctrlKey
      };
      editor.dispatch(info);
    };
    const handleKeyUp = (e) => {
      if (e.isKilled)
        return;
      e.isKilled = true;
      if (isFocusingInput() || editor.isMenuOpen) {
        return;
      }
      if (e.key === ",") {
        if (document.activeElement?.ELEMENT_NODE)
          preventDefault(e);
        if (editor.inputs.keys.has(e.code)) {
          const { x, y, z } = editor.inputs.currentScreenPoint;
          editor.inputs.keys.delete(e.code);
          const info2 = {
            type: "pointer",
            name: "pointer_up",
            point: { x, y, z },
            shiftKey: e.shiftKey,
            altKey: e.altKey,
            ctrlKey: e.metaKey || e.ctrlKey,
            pointerId: 0,
            button: 0,
            isPen: editor.instanceState.isPenMode,
            target: "canvas"
          };
          editor.dispatch(info2);
          return;
        }
      }
      const info = {
        type: "keyboard",
        name: "key_up",
        key: e.key,
        code: e.code,
        shiftKey: e.shiftKey,
        altKey: e.altKey,
        ctrlKey: e.metaKey || e.ctrlKey
      };
      editor.dispatch(info);
    };
    function handleTouchStart(e) {
      if (container.contains(e.target)) {
        const touchXPosition = e.touches[0].pageX;
        const touchXRadius = e.touches[0].radiusX || 0;
        if (touchXPosition - touchXRadius < 10 || touchXPosition + touchXRadius > editor.viewportScreenBounds.width - 10) {
          if (e.target?.tagName === "BUTTON") {
            ;
            e.target?.click();
          }
          preventDefault(e);
        }
      }
    }
    const handleWheel = (e) => {
      if (container.contains(e.target) && (e.ctrlKey || e.metaKey)) {
        preventDefault(e);
      }
    };
    container.addEventListener("touchstart", handleTouchStart, { passive: false });
    container.addEventListener("wheel", handleWheel, { passive: false });
    document.addEventListener("gesturestart", preventDefault);
    document.addEventListener("gesturechange", preventDefault);
    document.addEventListener("gestureend", preventDefault);
    container.addEventListener("keydown", handleKeyDown);
    container.addEventListener("keyup", handleKeyUp);
    return () => {
      container.removeEventListener("touchstart", handleTouchStart);
      container.removeEventListener("wheel", handleWheel);
      document.removeEventListener("gesturestart", preventDefault);
      document.removeEventListener("gesturechange", preventDefault);
      document.removeEventListener("gestureend", preventDefault);
      container.removeEventListener("keydown", handleKeyDown);
      container.removeEventListener("keyup", handleKeyUp);
    };
  }, [editor, container, isAppFocused]);
}
var INPUTS = ["input", "select", "button", "textarea"];
function isFocusingInput() {
  const { activeElement } = document;
  if (activeElement && (activeElement.getAttribute("contenteditable") || INPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)) {
    return true;
  }
  return false;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useEditorComponents.mjs
var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
var import_react19 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/ShapeIndicator.mjs
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
var import_classnames = __toESM(require_classnames(), 1);
var React4 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/ErrorBoundary.mjs
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
var React3 = __toESM(require_react(), 1);
var initialState = { error: null };
var ErrorBoundary = class extends React3.Component {
  static getDerivedStateFromError(error) {
    return { error };
  }
  state = initialState;
  componentDidCatch(error) {
    this.props.onError?.(error);
  }
  render() {
    const { error } = this.state;
    if (error !== null) {
      const { fallback: Fallback } = this.props;
      return (0, import_jsx_runtime2.jsx)(Fallback, { error });
    }
    return this.props.children;
  }
};
function OptionalErrorBoundary({
  children,
  fallback,
  ...props
}) {
  if (fallback === null) {
    return (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
  }
  return (0, import_jsx_runtime2.jsx)(ErrorBoundary, { fallback, ...props, children });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/ShapeIndicator.mjs
var ShapeWithPropsEquality = class {
  constructor(shape) {
    this.shape = shape;
  }
  equals(other) {
    return this.shape?.isLocked === other?.shape?.isLocked && this.shape?.props === other?.shape?.props && this.shape?.meta === other?.shape?.meta;
  }
};
var EvenInnererIndicator = ({ shape, util }) => {
  return useStateTracking("Indicator:" + shape.type, () => util.indicator(shape));
};
var InnerIndicator = ({ editor, id }) => {
  const shape = useValue("shape", () => new ShapeWithPropsEquality(editor.store.get(id)), [
    editor,
    id
  ]);
  const { ShapeIndicatorErrorFallback } = useEditorComponents();
  if (!shape.shape || shape.shape.isLocked)
    return null;
  return (0, import_jsx_runtime3.jsx)(
    OptionalErrorBoundary,
    {
      fallback: ShapeIndicatorErrorFallback,
      onError: (error) => editor.annotateError(error, { origin: "react.shapeIndicator", willCrashApp: false }),
      children: (0, import_jsx_runtime3.jsx)(
        EvenInnererIndicator,
        {
          shape: shape.shape,
          util: editor.getShapeUtil(shape.shape)
        },
        shape.shape.id
      )
    }
  );
};
var _ShapeIndicator = ({ id, className, color, opacity }) => {
  const editor = useEditor();
  const transform = useValue(
    "transform",
    () => {
      const pageTransform = editor.getShapePageTransform(id);
      if (!pageTransform)
        return "";
      return pageTransform.toCssString();
    },
    [editor, id]
  );
  return (0, import_jsx_runtime3.jsx)("svg", { className: (0, import_classnames.default)("tl-overlays__item", className), children: (0, import_jsx_runtime3.jsx)(
    "g",
    {
      className: "tl-shape-indicator",
      transform,
      stroke: color ?? "var(--color-selected)",
      opacity,
      children: (0, import_jsx_runtime3.jsx)(InnerIndicator, { editor, id })
    }
  ) });
};
var ShapeIndicator = React4.memo(_ShapeIndicator);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultBackground.mjs
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
function DefaultBackground() {
  return (0, import_jsx_runtime4.jsx)("div", { className: "tl-background" });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultBrush.mjs
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
var import_react14 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useTransform.mjs
var import_react13 = __toESM(require_react(), 1);
function useTransform(ref, x, y, scale, rotate, additionalOffset) {
  (0, import_react13.useLayoutEffect)(() => {
    const elm = ref.current;
    if (!elm)
      return;
    if (x === void 0)
      return;
    let trans = `translate(${x}px, ${y}px)`;
    if (scale !== void 0) {
      trans += ` scale(${scale})`;
    }
    if (rotate !== void 0) {
      trans += ` rotate(${rotate}rad)`;
    }
    if (additionalOffset) {
      trans += ` translate(${additionalOffset.x}px, ${additionalOffset.y}px)`;
    }
    elm.style.transform = trans;
  });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/easings.mjs
var EASINGS = {
  linear: (t2) => t2,
  easeInQuad: (t2) => t2 * t2,
  easeOutQuad: (t2) => t2 * (2 - t2),
  easeInOutQuad: (t2) => t2 < 0.5 ? 2 * t2 * t2 : -1 + (4 - 2 * t2) * t2,
  easeInCubic: (t2) => t2 * t2 * t2,
  easeOutCubic: (t2) => --t2 * t2 * t2 + 1,
  easeInOutCubic: (t2) => t2 < 0.5 ? 4 * t2 * t2 * t2 : (t2 - 1) * (2 * t2 - 2) * (2 * t2 - 2) + 1,
  easeInQuart: (t2) => t2 * t2 * t2 * t2,
  easeOutQuart: (t2) => 1 - --t2 * t2 * t2 * t2,
  easeInOutQuart: (t2) => t2 < 0.5 ? 8 * t2 * t2 * t2 * t2 : 1 - 8 * --t2 * t2 * t2 * t2,
  easeInQuint: (t2) => t2 * t2 * t2 * t2 * t2,
  easeOutQuint: (t2) => 1 + --t2 * t2 * t2 * t2 * t2,
  easeInOutQuint: (t2) => t2 < 0.5 ? 16 * t2 * t2 * t2 * t2 * t2 : 1 + 16 * --t2 * t2 * t2 * t2 * t2,
  easeInSine: (t2) => 1 - Math.cos(t2 * Math.PI / 2),
  easeOutSine: (t2) => Math.sin(t2 * Math.PI / 2),
  easeInOutSine: (t2) => -(Math.cos(Math.PI * t2) - 1) / 2,
  easeInExpo: (t2) => t2 <= 0 ? 0 : Math.pow(2, 10 * t2 - 10),
  easeOutExpo: (t2) => t2 >= 1 ? 1 : 1 - Math.pow(2, -10 * t2),
  easeInOutExpo: (t2) => t2 <= 0 ? 0 : t2 >= 1 ? 1 : t2 < 0.5 ? Math.pow(2, 20 * t2 - 10) / 2 : (2 - Math.pow(2, -20 * t2 + 10)) / 2
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/Vec2d.mjs
var Vec2d = class _Vec2d {
  constructor(x = 0, y = 0, z = 1) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
  get pressure() {
    return this.z;
  }
  set(x = this.x, y = this.y, z = this.z) {
    this.x = x;
    this.y = y;
    this.z = z;
    return this;
  }
  setTo({ x = 0, y = 0, z = 1 }) {
    this.x = x;
    this.y = y;
    this.z = z;
    return this;
  }
  rot(r) {
    if (r === 0)
      return this;
    const { x, y } = this;
    const s = Math.sin(r);
    const c = Math.cos(r);
    this.x = x * c - y * s;
    this.y = x * s + y * c;
    return this;
  }
  rotWith(C, r) {
    if (r === 0)
      return this;
    const x = this.x - C.x;
    const y = this.y - C.y;
    const s = Math.sin(r);
    const c = Math.cos(r);
    this.x = C.x + (x * c - y * s);
    this.y = C.y + (x * s + y * c);
    return this;
  }
  clone() {
    const { x, y, z } = this;
    return new _Vec2d(x, y, z);
  }
  sub(V2) {
    this.x -= V2.x;
    this.y -= V2.y;
    return this;
  }
  subXY(x, y) {
    this.x -= x;
    this.y -= y;
    return this;
  }
  subScalar(n) {
    this.x -= n;
    this.y -= n;
    return this;
  }
  add(V2) {
    this.x += V2.x;
    this.y += V2.y;
    return this;
  }
  addXY(x, y) {
    this.x += x;
    this.y += y;
    return this;
  }
  addScalar(n) {
    this.x += n;
    this.y += n;
    return this;
  }
  clamp(min4, max3) {
    this.x = Math.max(this.x, min4);
    this.y = Math.max(this.y, min4);
    if (max3 !== void 0) {
      this.x = Math.min(this.x, max3);
      this.y = Math.min(this.y, max3);
    }
    return this;
  }
  div(t2) {
    this.x /= t2;
    this.y /= t2;
    return this;
  }
  divV(V2) {
    this.x /= V2.x;
    this.y /= V2.y;
    return this;
  }
  mul(t2) {
    this.x *= t2;
    this.y *= t2;
    return this;
  }
  mulV(V2) {
    this.x *= V2.x;
    this.y *= V2.y;
    return this;
  }
  abs() {
    this.x = Math.abs(this.x);
    this.y = Math.abs(this.y);
    return this;
  }
  nudge(B, distance) {
    const tan = _Vec2d.Tan(B, this);
    return this.add(tan.mul(distance));
  }
  neg() {
    this.x *= -1;
    this.y *= -1;
    return this;
  }
  cross(V2) {
    this.x = this.y * V2.z - this.z * V2.y;
    this.y = this.z * V2.x - this.x * V2.z;
    return this;
  }
  dpr(V2) {
    return _Vec2d.Dpr(this, V2);
  }
  cpr(V2) {
    return _Vec2d.Cpr(this, V2);
  }
  len2() {
    return _Vec2d.Len2(this);
  }
  len() {
    return _Vec2d.Len(this);
  }
  pry(V2) {
    return _Vec2d.Pry(this, V2);
  }
  per() {
    const { x, y } = this;
    this.x = y;
    this.y = -x;
    return this;
  }
  uni() {
    return _Vec2d.Uni(this);
  }
  tan(V2) {
    return _Vec2d.Tan(this, V2);
  }
  dist(V2) {
    return _Vec2d.Dist(this, V2);
  }
  distanceToLineSegment(A, B) {
    return _Vec2d.DistanceToLineSegment(A, B, this);
  }
  slope(B) {
    return _Vec2d.Slope(this, B);
  }
  snapToGrid(gridSize) {
    this.x = Math.round(this.x / gridSize) * gridSize;
    this.y = Math.round(this.y / gridSize) * gridSize;
    return this;
  }
  angle(B) {
    return _Vec2d.Angle(this, B);
  }
  toAngle() {
    return _Vec2d.ToAngle(this);
  }
  lrp(B, t2) {
    this.x = this.x + (B.x - this.x) * t2;
    this.y = this.y + (B.y - this.y) * t2;
    return this;
  }
  equals(B) {
    return _Vec2d.Equals(this, B);
  }
  equalsXY(x, y) {
    return _Vec2d.EqualsXY(this, x, y);
  }
  norm() {
    const l = this.len();
    this.x = l === 0 ? 0 : this.x / l;
    this.y = l === 0 ? 0 : this.y / l;
    return this;
  }
  toFixed() {
    return _Vec2d.ToFixed(this);
  }
  toString() {
    return _Vec2d.ToString(_Vec2d.ToFixed(this));
  }
  toJson() {
    return _Vec2d.ToJson(this);
  }
  toArray() {
    return _Vec2d.ToArray(this);
  }
  static Add(A, B) {
    return new _Vec2d(A.x + B.x, A.y + B.y);
  }
  static AddXY(A, x, y) {
    return new _Vec2d(A.x + x, A.y + y);
  }
  static Sub(A, B) {
    return new _Vec2d(A.x - B.x, A.y - B.y);
  }
  static SubXY(A, x, y) {
    return new _Vec2d(A.x - x, A.y - y);
  }
  static AddScalar(A, n) {
    return new _Vec2d(A.x + n, A.y + n);
  }
  static SubScalar(A, n) {
    return new _Vec2d(A.x - n, A.y - n);
  }
  static Div(A, t2) {
    return new _Vec2d(A.x / t2, A.y / t2);
  }
  static Mul(A, t2) {
    return new _Vec2d(A.x * t2, A.y * t2);
  }
  static DivV(A, B) {
    return new _Vec2d(A.x / B.x, A.y / B.y);
  }
  static MulV(A, B) {
    return new _Vec2d(A.x * B.x, A.y * B.y);
  }
  static Neg(A) {
    return new _Vec2d(-A.x, -A.y);
  }
  static Per(A) {
    return new _Vec2d(A.y, -A.x);
  }
  static Dist2(A, B) {
    return _Vec2d.Sub(A, B).len2();
  }
  static Abs(A) {
    return new _Vec2d(Math.abs(A.x), Math.abs(A.y));
  }
  static Dist(A, B) {
    return Math.hypot(A.y - B.y, A.x - B.x);
  }
  static Dpr(A, B) {
    return A.x * B.x + A.y * B.y;
  }
  static Cross(A, V2) {
    return new _Vec2d(
      A.y * V2.z - A.z * V2.y,
      A.z * V2.x - A.x * V2.z
      // A.z = A.x * V.y - A.y * V.x
    );
  }
  static Cpr(A, B) {
    return A.x * B.y - B.x * A.y;
  }
  static Len2(A) {
    return A.x * A.x + A.y * A.y;
  }
  static Len(A) {
    return Math.hypot(A.x, A.y);
  }
  static Pry(A, B) {
    return _Vec2d.Dpr(A, B) / _Vec2d.Len(B);
  }
  static Uni(A) {
    return _Vec2d.Div(A, _Vec2d.Len(A));
  }
  static Tan(A, B) {
    return _Vec2d.Uni(_Vec2d.Sub(A, B));
  }
  static Min(A, B) {
    return new _Vec2d(Math.min(A.x, B.x), Math.min(A.y, B.y));
  }
  static Max(A, B) {
    return new _Vec2d(Math.max(A.x, B.x), Math.max(A.y, B.y));
  }
  static From({ x, y, z = 1 }) {
    return new _Vec2d(x, y, z);
  }
  static FromArray(v) {
    return new _Vec2d(v[0], v[1]);
  }
  static Rot(A, r = 0) {
    const s = Math.sin(r);
    const c = Math.cos(r);
    return new _Vec2d(A.x * c - A.y * s, A.x * s + A.y * c);
  }
  static RotWith(A, C, r) {
    const x = A.x - C.x;
    const y = A.y - C.y;
    const s = Math.sin(r);
    const c = Math.cos(r);
    return new _Vec2d(C.x + (x * c - y * s), C.y + (x * s + y * c));
  }
  /**
   * Get the nearest point on a line with a known unit vector that passes through point A
   *
   * ```ts
   * Vec.nearestPointOnLineThroughPoint(A, u, Point)
   * ```
   *
   * @param A - Any point on the line
   * @param u - The unit vector for the line.
   * @param P - A point not on the line to test.
   */
  static NearestPointOnLineThroughPoint(A, u, P) {
    return _Vec2d.Mul(u, _Vec2d.Sub(P, A).pry(u)).add(A);
  }
  static NearestPointOnLineSegment(A, B, P, clamp4 = true) {
    const u = _Vec2d.Tan(B, A);
    const C = _Vec2d.Add(A, _Vec2d.Mul(u, _Vec2d.Sub(P, A).pry(u)));
    if (clamp4) {
      if (C.x < Math.min(A.x, B.x))
        return _Vec2d.Cast(A.x < B.x ? A : B);
      if (C.x > Math.max(A.x, B.x))
        return _Vec2d.Cast(A.x > B.x ? A : B);
      if (C.y < Math.min(A.y, B.y))
        return _Vec2d.Cast(A.y < B.y ? A : B);
      if (C.y > Math.max(A.y, B.y))
        return _Vec2d.Cast(A.y > B.y ? A : B);
    }
    return C;
  }
  static DistanceToLineThroughPoint(A, u, P) {
    return _Vec2d.Dist(P, _Vec2d.NearestPointOnLineThroughPoint(A, u, P));
  }
  static DistanceToLineSegment(A, B, P, clamp4 = true) {
    return _Vec2d.Dist(P, _Vec2d.NearestPointOnLineSegment(A, B, P, clamp4));
  }
  static Snap(A, step = 1) {
    return new _Vec2d(Math.round(A.x / step) * step, Math.round(A.y / step) * step);
  }
  static Cast(A) {
    if (A instanceof _Vec2d)
      return A;
    return _Vec2d.From(A);
  }
  static Slope(A, B) {
    if (A.x === B.y)
      return NaN;
    return (A.y - B.y) / (A.x - B.x);
  }
  static Angle(A, B) {
    return Math.atan2(B.y - A.y, B.x - A.x);
  }
  static Lrp(A, B, t2) {
    return _Vec2d.Sub(B, A).mul(t2).add(A);
  }
  static Med(A, B) {
    return new _Vec2d((A.x + B.x) / 2, (A.y + B.y) / 2);
  }
  static Equals(A, B) {
    return Math.abs(A.x - B.x) < 1e-4 && Math.abs(A.y - B.y) < 1e-4;
  }
  static EqualsXY(A, x, y) {
    return A.x === x && A.y === y;
  }
  static Clockwise(A, B, C) {
    return (C.x - A.x) * (B.y - A.y) - (B.x - A.x) * (C.y - A.y) < 0;
  }
  static Rescale(A, n) {
    const l = _Vec2d.Len(A);
    return new _Vec2d(n * A.x / l, n * A.y / l);
  }
  static ScaleWithOrigin(A, scale, origin) {
    return _Vec2d.Sub(A, origin).mul(scale).add(origin);
  }
  static ToFixed(A, n = 2) {
    return new _Vec2d(+A.x.toFixed(n), +A.y.toFixed(n), +A.z.toFixed(n));
  }
  static Nudge(A, B, distance) {
    return _Vec2d.Add(A, _Vec2d.Tan(B, A).mul(distance));
  }
  static ToString(A) {
    return `${A.x}, ${A.y}`;
  }
  static ToAngle(A) {
    let r = Math.atan2(A.y, A.x);
    if (r < 0)
      r += Math.PI * 2;
    return r;
  }
  static FromAngle(r, length = 1) {
    return new _Vec2d(Math.cos(r) * length, Math.sin(r) * length);
  }
  static ToArray(A) {
    return [A.x, A.y, A.z];
  }
  static ToJson(A) {
    const { x, y, z } = A;
    return { x, y, z };
  }
  static Average(arr) {
    const len = arr.length;
    const avg = new _Vec2d(0, 0);
    for (let i = 0; i < len; i++) {
      avg.add(arr[i]);
    }
    return avg.div(len);
  }
  static Clamp(A, min4, max3) {
    if (max3 === void 0) {
      return new _Vec2d(Math.min(Math.max(A.x, min4)), Math.min(Math.max(A.y, min4)));
    }
    return new _Vec2d(Math.min(Math.max(A.x, min4), max3), Math.min(Math.max(A.y, min4), max3));
  }
  /**
   * Get an array of points (with simulated pressure) between two points.
   *
   * @param A - The first point.
   * @param B - The second point.
   * @param steps - The number of points to return.
   */
  static PointsBetween(A, B, steps = 6) {
    const results = [];
    for (let i = 0; i < steps; i++) {
      const t2 = EASINGS.easeInQuad(i / (steps - 1));
      const point = _Vec2d.Lrp(A, B, t2);
      point.z = Math.min(1, 0.5 + Math.abs(0.5 - ease(t2)) * 0.65);
      results.push(point);
    }
    return results;
  }
  static SnapToGrid(A, gridSize = 8) {
    return new _Vec2d(Math.round(A.x / gridSize) * gridSize, Math.round(A.y / gridSize) * gridSize);
  }
};
var ease = (t2) => t2 < 0.5 ? 2 * t2 * t2 : -1 + (4 - 2 * t2) * t2;

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/Box2d.mjs
var Box2d = class _Box2d {
  constructor(x = 0, y = 0, w = 0, h = 0) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }
  x = 0;
  y = 0;
  w = 0;
  h = 0;
  get point() {
    return new Vec2d(this.x, this.y);
  }
  set point(val) {
    this.x = val.x;
    this.y = val.y;
  }
  get minX() {
    return this.x;
  }
  set minX(n) {
    this.x = n;
  }
  get midX() {
    return this.x + this.w / 2;
  }
  get maxX() {
    return this.x + this.w;
  }
  get minY() {
    return this.y;
  }
  set minY(n) {
    this.y = n;
  }
  get midY() {
    return this.y + this.h / 2;
  }
  get maxY() {
    return this.y + this.h;
  }
  get width() {
    return this.w;
  }
  set width(n) {
    this.w = n;
  }
  get height() {
    return this.h;
  }
  set height(n) {
    this.h = n;
  }
  get aspectRatio() {
    return this.width / this.height;
  }
  get center() {
    return new Vec2d(this.midX, this.midY);
  }
  set center(v) {
    this.minX = v.x - this.width / 2;
    this.minY = v.y - this.height / 2;
  }
  get corners() {
    return [
      new Vec2d(this.minX, this.minY),
      new Vec2d(this.maxX, this.minY),
      new Vec2d(this.maxX, this.maxY),
      new Vec2d(this.minX, this.maxY)
    ];
  }
  get snapPoints() {
    return [
      new Vec2d(this.minX, this.minY),
      new Vec2d(this.maxX, this.minY),
      new Vec2d(this.maxX, this.maxY),
      new Vec2d(this.minX, this.maxY),
      this.center
    ];
  }
  get sides() {
    const { corners } = this;
    return [
      [corners[0], corners[1]],
      [corners[1], corners[2]],
      [corners[2], corners[3]],
      [corners[3], corners[0]]
    ];
  }
  get size() {
    return new Vec2d(this.w, this.h);
  }
  toFixed() {
    this.x = toPrecision(this.x);
    this.y = toPrecision(this.y);
    this.w = toPrecision(this.w);
    this.h = toPrecision(this.h);
    return this;
  }
  setTo(B) {
    this.x = B.x;
    this.y = B.y;
    this.w = B.w;
    this.h = B.h;
    return this;
  }
  set(x = 0, y = 0, w = 0, h = 0) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    return this;
  }
  expand(A) {
    const minX = Math.min(this.minX, A.minX);
    const minY = Math.min(this.minY, A.minY);
    const maxX = Math.max(this.maxX, A.maxX);
    const maxY = Math.max(this.maxY, A.maxY);
    this.x = minX;
    this.y = minY;
    this.w = maxX - minX;
    this.h = maxY - minY;
    return this;
  }
  expandBy(n) {
    this.x -= n;
    this.y -= n;
    this.w += n * 2;
    this.h += n * 2;
    return this;
  }
  scale(n) {
    this.x /= n;
    this.y /= n;
    this.w /= n;
    this.h /= n;
    return this;
  }
  clone() {
    const { x, y, w, h } = this;
    return new _Box2d(x, y, w, h);
  }
  translate(delta) {
    this.x += delta.x;
    this.y += delta.y;
    return this;
  }
  snapToGrid(size2) {
    const minX = Math.round(this.minX / size2) * size2;
    const minY = Math.round(this.minY / size2) * size2;
    const maxX = Math.round(this.maxX / size2) * size2;
    const maxY = Math.round(this.maxY / size2) * size2;
    this.minX = minX;
    this.minY = minY;
    this.width = Math.max(1, maxX - minX);
    this.height = Math.max(1, maxY - minY);
  }
  collides(B) {
    return _Box2d.Collides(this, B);
  }
  contains(B) {
    return _Box2d.Contains(this, B);
  }
  includes(B) {
    return _Box2d.Includes(this, B);
  }
  containsPoint(V2, margin = 0) {
    return _Box2d.ContainsPoint(this, V2, margin);
  }
  getHandlePoint(handle) {
    switch (handle) {
      case "top_left":
        return new Vec2d(this.minX, this.minY);
      case "top_right":
        return new Vec2d(this.maxX, this.minY);
      case "bottom_left":
        return new Vec2d(this.minX, this.maxY);
      case "bottom_right":
        return new Vec2d(this.maxX, this.maxY);
      case "top":
        return new Vec2d(this.midX, this.minY);
      case "right":
        return new Vec2d(this.maxX, this.midY);
      case "bottom":
        return new Vec2d(this.midX, this.maxY);
      case "left":
        return new Vec2d(this.minX, this.midY);
    }
  }
  toJson() {
    return { x: this.minX, y: this.minY, w: this.w, h: this.h };
  }
  resize(handle, dx, dy) {
    const { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = this;
    let { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = this;
    switch (handle) {
      case "left":
      case "top_left":
      case "bottom_left": {
        b0x += dx;
        break;
      }
      case "right":
      case "top_right":
      case "bottom_right": {
        b1x += dx;
        break;
      }
    }
    switch (handle) {
      case "top":
      case "top_left":
      case "top_right": {
        b0y += dy;
        break;
      }
      case "bottom":
      case "bottom_left":
      case "bottom_right": {
        b1y += dy;
        break;
      }
    }
    const scaleX = (b1x - b0x) / (a1x - a0x);
    const scaleY = (b1y - b0y) / (a1y - a0y);
    const flipX = scaleX < 0;
    const flipY = scaleY < 0;
    if (flipX) {
      const t2 = b1x;
      b1x = b0x;
      b0x = t2;
    }
    if (flipY) {
      const t2 = b1y;
      b1y = b0y;
      b0y = t2;
    }
    this.minX = b0x;
    this.minY = b0y;
    this.width = Math.abs(b1x - b0x);
    this.height = Math.abs(b1y - b0y);
  }
  union(box) {
    const minX = Math.min(this.minX, box.x);
    const minY = Math.min(this.minY, box.y);
    const maxX = Math.max(this.maxX, box.w + box.x);
    const maxY = Math.max(this.maxY, box.h + box.y);
    this.x = minX;
    this.y = minY;
    this.width = maxX - minX;
    this.height = maxY - minY;
    return this;
  }
  static From(box) {
    return new _Box2d(box.x, box.y, box.w, box.h);
  }
  static FromPoints(points) {
    if (points.length === 0)
      return new _Box2d();
    let minX = Infinity;
    let minY = Infinity;
    let maxX = -Infinity;
    let maxY = -Infinity;
    let point;
    for (let i = 0, n = points.length; i < n; i++) {
      point = points[i];
      minX = Math.min(point.x, minX);
      minY = Math.min(point.y, minY);
      maxX = Math.max(point.x, maxX);
      maxY = Math.max(point.y, maxY);
    }
    return new _Box2d(minX, minY, maxX - minX, maxY - minY);
  }
  static Expand(A, B) {
    const minX = Math.min(B.minX, A.minX);
    const minY = Math.min(B.minY, A.minY);
    const maxX = Math.max(B.maxX, A.maxX);
    const maxY = Math.max(B.maxY, A.maxY);
    return new _Box2d(minX, minY, maxX - minX, maxY - minY);
  }
  static ExpandBy(A, n) {
    return new _Box2d(A.minX - n, A.minY - n, A.width + n * 2, A.height + n * 2);
  }
  static Collides = (A, B) => {
    return !(A.maxX < B.minX || A.minX > B.maxX || A.maxY < B.minY || A.minY > B.maxY);
  };
  static Contains = (A, B) => {
    return A.minX < B.minX && A.minY < B.minY && A.maxY > B.maxY && A.maxX > B.maxX;
  };
  static Includes = (A, B) => {
    return _Box2d.Collides(A, B) || _Box2d.Contains(A, B);
  };
  static ContainsPoint = (A, B, margin = 0) => {
    return !(B.x < A.minX - margin || B.y < A.minY - margin || B.x > A.maxX + margin || B.y > A.maxY + margin);
  };
  static Common = (boxes) => {
    let minX = Infinity;
    let minY = Infinity;
    let maxX = -Infinity;
    let maxY = -Infinity;
    for (let i = 0; i < boxes.length; i++) {
      const B = boxes[i];
      minX = Math.min(minX, B.minX);
      minY = Math.min(minY, B.minY);
      maxX = Math.max(maxX, B.maxX);
      maxY = Math.max(maxY, B.maxY);
    }
    return new _Box2d(minX, minY, maxX - minX, maxY - minY);
  };
  static Sides = (A, inset = 0) => {
    const { corners } = A;
    if (inset) {
    }
    return [
      [corners[0], corners[1]],
      [corners[1], corners[2]],
      [corners[2], corners[3]],
      [corners[3], corners[0]]
    ];
  };
  static Resize(box, handle, dx, dy, isAspectRatioLocked = false) {
    const { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = box;
    let { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = box;
    switch (handle) {
      case "left":
      case "top_left":
      case "bottom_left": {
        b0x += dx;
        break;
      }
      case "right":
      case "top_right":
      case "bottom_right": {
        b1x += dx;
        break;
      }
    }
    switch (handle) {
      case "top":
      case "top_left":
      case "top_right": {
        b0y += dy;
        break;
      }
      case "bottom":
      case "bottom_left":
      case "bottom_right": {
        b1y += dy;
        break;
      }
    }
    const scaleX = (b1x - b0x) / (a1x - a0x);
    const scaleY = (b1y - b0y) / (a1y - a0y);
    const flipX = scaleX < 0;
    const flipY = scaleY < 0;
    if (isAspectRatioLocked) {
      const aspectRatio = (a1x - a0x) / (a1y - a0y);
      const bw = Math.abs(b1x - b0x);
      const bh = Math.abs(b1y - b0y);
      const tw = bw * (scaleY < 0 ? 1 : -1) * (1 / aspectRatio);
      const th = bh * (scaleX < 0 ? 1 : -1) * aspectRatio;
      const isTall = aspectRatio < bw / bh;
      switch (handle) {
        case "top_left": {
          if (isTall)
            b0y = b1y + tw;
          else
            b0x = b1x + th;
          break;
        }
        case "top_right": {
          if (isTall)
            b0y = b1y + tw;
          else
            b1x = b0x - th;
          break;
        }
        case "bottom_right": {
          if (isTall)
            b1y = b0y - tw;
          else
            b1x = b0x - th;
          break;
        }
        case "bottom_left": {
          if (isTall)
            b1y = b0y - tw;
          else
            b0x = b1x + th;
          break;
        }
        case "bottom":
        case "top": {
          const m = (b0x + b1x) / 2;
          const w = bh * aspectRatio;
          b0x = m - w / 2;
          b1x = m + w / 2;
          break;
        }
        case "left":
        case "right": {
          const m = (b0y + b1y) / 2;
          const h = bw / aspectRatio;
          b0y = m - h / 2;
          b1y = m + h / 2;
          break;
        }
      }
    }
    if (flipX) {
      const t2 = b1x;
      b1x = b0x;
      b0x = t2;
    }
    if (flipY) {
      const t2 = b1y;
      b1y = b0y;
      b0y = t2;
    }
    const final = new _Box2d(b0x, b0y, Math.abs(b1x - b0x), Math.abs(b1y - b0y));
    return {
      box: final,
      scaleX: +(final.width / box.width * (scaleX > 0 ? 1 : -1)).toFixed(5),
      scaleY: +(final.height / box.height * (scaleY > 0 ? 1 : -1)).toFixed(5)
    };
  }
  equals(other) {
    return _Box2d.Equals(this, other);
  }
  static Equals(a, b) {
    return b.x === a.x && b.y === a.y && b.w === a.w && b.h === a.h;
  }
  zeroFix() {
    this.w = Math.max(1, this.w);
    this.h = Math.max(1, this.h);
    return this;
  }
  static ZeroFix(other) {
    return new _Box2d(other.x, other.y, Math.max(1, other.w), Math.max(1, other.h));
  }
};
function flipSelectionHandleY(handle) {
  switch (handle) {
    case "top":
      return "bottom";
    case "bottom":
      return "top";
    case "top_left":
      return "bottom_left";
    case "top_right":
      return "bottom_right";
    case "bottom_left":
      return "top_left";
    case "bottom_right":
      return "top_right";
    default:
      return handle;
  }
}
function flipSelectionHandleX(handle) {
  switch (handle) {
    case "left":
      return "right";
    case "right":
      return "left";
    case "top_left":
      return "top_right";
    case "top_right":
      return "top_left";
    case "bottom_left":
      return "bottom_right";
    case "bottom_right":
      return "bottom_left";
    default:
      return handle;
  }
}
var ORDERED_SELECTION_HANDLES = [
  "top",
  "top_right",
  "right",
  "bottom_right",
  "bottom",
  "bottom_left",
  "left",
  "top_left"
];
function rotateSelectionHandle(handle, rotation) {
  rotation = rotation % PI2;
  const numSteps = Math.round(rotation / (PI / 4));
  const currentIndex = ORDERED_SELECTION_HANDLES.indexOf(handle);
  return ORDERED_SELECTION_HANDLES[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES.length];
}
function isSelectionCorner(selection) {
  return selection === "top_left" || selection === "top_right" || selection === "bottom_right" || selection === "bottom_left";
}
var ROTATE_CORNER_TO_SELECTION_CORNER = {
  top_left_rotate: "top_left",
  top_right_rotate: "top_right",
  bottom_right_rotate: "bottom_right",
  bottom_left_rotate: "bottom_left",
  mobile_rotate: "top_left"
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/utils.mjs
function precise(A) {
  return `${toDomPrecision(A.x)},${toDomPrecision(A.y)} `;
}
function average(A, B) {
  return `${toDomPrecision((A.x + B.x) / 2)},${toDomPrecision((A.y + B.y) / 2)} `;
}
var PI = Math.PI;
var TAU = PI / 2;
var PI2 = PI * 2;
var EPSILON = Math.PI / 180;
var SIN = Math.sin;
function clamp(n, min4, max3) {
  return Math.max(min4, typeof max3 !== "undefined" ? Math.min(n, max3) : n);
}
function toPrecision(n, precision = 1e10) {
  if (!n)
    return 0;
  return Math.round(n * precision) / precision;
}
function approximately(a, b, precision = 1e-6) {
  return Math.abs(a - b) <= precision;
}
function perimeterOfEllipse(rx, ry) {
  const h = Math.pow(rx - ry, 2) / Math.pow(rx + ry, 2);
  const p = PI * (rx + ry) * (1 + 3 * h / (10 + Math.sqrt(4 - 3 * h)));
  return p;
}
function canonicalizeRotation(a) {
  a = a % PI2;
  if (a < 0) {
    a = a + PI2;
  } else if (a === 0) {
    a = 0;
  }
  return a;
}
function clockwiseAngleDist(a0, a1) {
  a0 = canonicalizeRotation(a0);
  a1 = canonicalizeRotation(a1);
  if (a0 > a1) {
    a1 += PI2;
  }
  return a1 - a0;
}
function counterClockwiseAngleDist(a0, a1) {
  return PI2 - clockwiseAngleDist(a0, a1);
}
function shortAngleDist(a0, a1) {
  const da = (a1 - a0) % PI2;
  return 2 * da % PI2 - da;
}
function longAngleDist(a0, a1) {
  return PI2 - shortAngleDist(a0, a1);
}
function lerpAngles(a0, a1, t2) {
  return a0 + shortAngleDist(a0, a1) * t2;
}
function angleDelta(a0, a1) {
  return shortAngleDist(a0, a1);
}
function getSweep(C, A, B) {
  return angleDelta(Vec2d.Angle(C, A), Vec2d.Angle(C, B));
}
function clampRadians(r) {
  return (PI2 + r) % PI2;
}
function snapAngle(r, segments) {
  const seg = PI2 / segments;
  let ang = Math.floor((clampRadians(r) + seg / 2) / seg) * seg % PI2;
  if (ang < PI)
    ang += PI2;
  if (ang > PI)
    ang -= PI2;
  return ang;
}
function areAnglesCompatible(a, b) {
  return a === b || approximately(a % (Math.PI / 2) - b % (Math.PI / 2), 0);
}
function isAngleBetween(a, b, c) {
  a = canonicalizeRotation(a);
  b = canonicalizeRotation(b);
  c = canonicalizeRotation(c);
  const ax = Math.cos(a);
  const ay = Math.sin(a);
  const bx = Math.cos(b);
  const by = Math.sin(b);
  const cx = Math.cos(c);
  const cy = Math.sin(c);
  const dotAc = ax * cx + ay * cy;
  const dotBc = bx * cx + by * cy;
  return dotAc >= 0 && dotBc >= 0;
}
function degreesToRadians(d) {
  return d * PI / 180;
}
function radiansToDegrees(r) {
  return r * 180 / PI;
}
function getArcLength(C, r, A, B) {
  const sweep = getSweep(C, A, B);
  return r * PI2 * (sweep / PI2);
}
function getPointOnCircle(cx, cy, r, a) {
  return new Vec2d(cx + r * Math.cos(a), cy + r * Math.sin(a));
}
function getPolygonVertices(width, height, sides2) {
  const cx = width / 2;
  const cy = height / 2;
  const pointsOnPerimeter = [];
  let minX = Infinity;
  let minY = Infinity;
  for (let i = 0; i < sides2; i++) {
    const step = PI2 / sides2;
    const t2 = -TAU + i * step;
    const x = cx + cx * Math.cos(t2);
    const y = cy + cy * Math.sin(t2);
    if (x < minX)
      minX = x;
    if (y < minY)
      minY = y;
    pointsOnPerimeter.push(new Vec2d(x, y));
  }
  if (minX !== 0 || minY !== 0) {
    for (let i = 0; i < pointsOnPerimeter.length; i++) {
      const pt = pointsOnPerimeter[i];
      pt.x -= minX;
      pt.y -= minY;
    }
  }
  return pointsOnPerimeter;
}
function rangesOverlap(a0, a1, b0, b1) {
  return a0 < b1 && b0 < a1;
}
function rangeIntersection(a0, a1, b0, b1) {
  const min4 = Math.max(a0, b0);
  const max3 = Math.min(a1, b1);
  if (min4 <= max3) {
    return [min4, max3];
  }
  return null;
}
var getStarBounds = (sides2, w, h) => {
  const step = PI2 / sides2 / 2;
  const rightMostIndex = Math.floor(sides2 / 4) * 2;
  const leftMostIndex = sides2 * 2 - rightMostIndex;
  const topMostIndex = 0;
  const bottomMostIndex = Math.floor(sides2 / 2) * 2;
  const maxX = Math.cos(-TAU + rightMostIndex * step) * w / 2;
  const minX = Math.cos(-TAU + leftMostIndex * step) * w / 2;
  const minY = Math.sin(-TAU + topMostIndex * step) * h / 2;
  const maxY = Math.sin(-TAU + bottomMostIndex * step) * h / 2;
  return new Box2d(0, 0, maxX - minX, maxY - minY);
};
function cross(x, y, z) {
  return (y.x - x.x) * (z.y - x.y) - (z.x - x.x) * (y.y - x.y);
}
function pointInCircle(A, C, r) {
  return Vec2d.Dist(A, C) <= r;
}
function pointInEllipse(A, C, rx, ry, rotation = 0) {
  rotation = rotation || 0;
  const cos = Math.cos(rotation);
  const sin = Math.sin(rotation);
  const delta = Vec2d.Sub(A, C);
  const tdx = cos * delta.x + sin * delta.y;
  const tdy = sin * delta.x - cos * delta.y;
  return tdx * tdx / (rx * rx) + tdy * tdy / (ry * ry) <= 1;
}
function pointInRect(A, point, size2) {
  return !(A.x < point.x || A.x > point.x + size2.x || A.y < point.y || A.y > point.y + size2.y);
}
function pointInPolygon(A, points) {
  let windingNumber = 0;
  let a;
  let b;
  for (let i = 0; i < points.length; i++) {
    a = points[i];
    b = points[(i + 1) % points.length];
    if (a.y <= A.y) {
      if (b.y > A.y && cross(a, b, A) > 0) {
        windingNumber += 1;
      }
    } else if (b.y <= A.y && cross(a, b, A) < 0) {
      windingNumber -= 1;
    }
  }
  return windingNumber !== 0;
}
function pointInBounds(A, b) {
  return !(A.x < b.minX || A.x > b.maxX || A.y < b.minY || A.y > b.maxY);
}
function pointInPolyline(A, points, distance = 3) {
  for (let i = 1; i < points.length; i++) {
    if (Vec2d.DistanceToLineSegment(points[i - 1], points[i], A) < distance) {
      return true;
    }
  }
  return false;
}
function pointNearToPolyline(A, points, distance = 8) {
  const len = points.length;
  for (let i = 1; i < len; i++) {
    const p1 = points[i - 1];
    const p2 = points[i];
    const d = Vec2d.DistanceToLineSegment(p1, p2, A);
    if (d < distance)
      return true;
  }
  return false;
}
function pointNearToLineSegment(A, p1, p2, distance = 8) {
  const d = Vec2d.DistanceToLineSegment(p1, p2, A);
  if (d < distance)
    return true;
  return false;
}
function toDomPrecision(v) {
  return +v.toFixed(4);
}
function toFixed(v) {
  return +v.toFixed(2);
}
var isSafeFloat = (n) => {
  return Math.abs(n) < Number.MAX_SAFE_INTEGER;
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultBrush.mjs
var DefaultBrush = ({ brush, color, opacity }) => {
  const rSvg = (0, import_react14.useRef)(null);
  useTransform(rSvg, brush.x, brush.y);
  const w = toDomPrecision(Math.max(1, brush.w));
  const h = toDomPrecision(Math.max(1, brush.h));
  return (0, import_jsx_runtime5.jsx)("svg", { className: "tl-overlays__item", ref: rSvg, children: color ? (0, import_jsx_runtime5.jsxs)("g", { className: "tl-brush", opacity, children: [
    (0, import_jsx_runtime5.jsx)("rect", { width: w, height: h, fill: color, opacity: 0.75 }),
    (0, import_jsx_runtime5.jsx)("rect", { width: w, height: h, fill: "none", stroke: color, opacity: 0.1 })
  ] }) : (0, import_jsx_runtime5.jsx)("rect", { className: "tl-brush tl-brush__default", width: w, height: h }) });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs
var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
var import_classnames2 = __toESM(require_classnames(), 1);
var import_react15 = __toESM(require_react(), 1);
var DefaultCollaboratorHint = ({
  className,
  zoom,
  point,
  color,
  viewport,
  opacity = 1
}) => {
  const rSvg = (0, import_react15.useRef)(null);
  useTransform(
    rSvg,
    clamp(point.x, viewport.minX + 5 / zoom, viewport.maxX - 5 / zoom),
    clamp(point.y, viewport.minY + 5 / zoom, viewport.maxY - 5 / zoom),
    1 / zoom,
    Vec2d.Angle(viewport.center, point)
  );
  return (0, import_jsx_runtime6.jsxs)("svg", { ref: rSvg, className: (0, import_classnames2.default)("tl-overlays__item", className), children: [
    (0, import_jsx_runtime6.jsx)("use", { href: "#cursor_hint", color, strokeWidth: 3, stroke: "var(--color-background)" }),
    (0, import_jsx_runtime6.jsx)("use", { href: "#cursor_hint", color, opacity })
  ] });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultCursor.mjs
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
var import_classnames3 = __toESM(require_classnames(), 1);
var import_react16 = __toESM(require_react(), 1);
var _Cursor = ({ className, zoom, point, color, name, chatMessage }) => {
  const rCursor = (0, import_react16.useRef)(null);
  useTransform(rCursor, point?.x, point?.y, 1 / zoom);
  if (!point)
    return null;
  return (0, import_jsx_runtime7.jsxs)("div", { ref: rCursor, className: (0, import_classnames3.default)("tl-overlays__item", className), children: [
    (0, import_jsx_runtime7.jsx)("svg", { className: "tl-cursor", children: (0, import_jsx_runtime7.jsx)("use", { href: "#cursor", color }) }),
    chatMessage ? (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
      name && (0, import_jsx_runtime7.jsx)("div", { className: "tl-nametag-title", style: { color }, children: name }),
      (0, import_jsx_runtime7.jsx)("div", { className: "tl-nametag-chat", style: { backgroundColor: color }, children: chatMessage })
    ] }) : name && (0, import_jsx_runtime7.jsx)("div", { className: "tl-nametag", style: { backgroundColor: color }, children: name })
  ] });
};
var DefaultCursor = (0, import_react16.memo)(_Cursor);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs
var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
var import_classnames4 = __toESM(require_classnames(), 1);
var import_react17 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/runtime.mjs
var runtime = {
  openWindow: (url, target) => window.open(url, target, "noopener noreferrer"),
  refreshPage: () => window.location.reload(),
  hardReset: async () => await window.__tldraw__hardReset?.()
};
function setRuntimeOverrides(input) {
  Object.assign(runtime, input);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/hardResetEditor.mjs
function hardResetEditor() {
  runtime.hardReset();
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/refreshPage.mjs
function refreshPage() {
  runtime.refreshPage();
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs
var BASE_ERROR_URL = "https://github.com/tldraw/tldraw/issues/new";
function noop2() {
}
var DefaultErrorFallback = ({ error, editor }) => {
  const containerRef = (0, import_react17.useRef)(null);
  const [shouldShowError, setShouldShowError] = (0, import_react17.useState)(true);
  const [didCopy, setDidCopy] = (0, import_react17.useState)(false);
  const [shouldShowResetConfirmation, setShouldShowResetConfirmation] = (0, import_react17.useState)(false);
  const errorMessage = error instanceof Error ? error.message : String(error);
  const errorStack = error instanceof Error ? error.stack : null;
  const isDarkModeFromApp = useValue(
    "isDarkMode",
    () => {
      try {
        if (editor) {
          return editor.user.isDarkMode;
        }
      } catch {
      }
      return null;
    },
    [editor]
  );
  const [isDarkMode, setIsDarkMode] = (0, import_react17.useState)(null);
  (0, import_react17.useLayoutEffect)(() => {
    if (isDarkModeFromApp !== null) {
      setIsDarkMode(isDarkModeFromApp);
    }
    let parent = containerRef.current?.parentElement;
    let foundParentThemeClass = false;
    while (parent) {
      if (parent.classList.contains("tl-theme__dark") || parent.classList.contains("tl-theme__light")) {
        foundParentThemeClass = true;
        break;
      }
      parent = parent.parentElement;
    }
    if (foundParentThemeClass) {
      setIsDarkMode(null);
      return;
    }
    setIsDarkMode(window.matchMedia("(prefers-color-scheme: dark)").matches);
  }, [isDarkModeFromApp]);
  (0, import_react17.useEffect)(() => {
    if (didCopy) {
      const timeout = setTimeout(() => {
        setDidCopy(false);
      }, 2e3);
      return () => clearTimeout(timeout);
    }
  }, [didCopy]);
  const copyError = () => {
    const textarea = document.createElement("textarea");
    textarea.value = errorStack ?? errorMessage;
    document.body.appendChild(textarea);
    textarea.select();
    document.execCommand("copy");
    textarea.remove();
    setDidCopy(true);
  };
  const refresh = () => {
    refreshPage();
  };
  const resetLocalState = async () => {
    hardResetEditor();
  };
  const url = new URL(BASE_ERROR_URL);
  url.searchParams.set("title", errorMessage);
  url.searchParams.set("labels", `bug`);
  url.searchParams.set(
    "body",
    `Hey, I ran into an error while using tldraw:

\`\`\`js
${errorStack ?? errorMessage}
\`\`\`

My browser: ${navigator.userAgent}`
  );
  return (0, import_jsx_runtime8.jsxs)(
    "div",
    {
      ref: containerRef,
      className: (0, import_classnames4.default)(
        "tl-container tl-error-boundary",
        // error-boundary is sometimes used outside of the theme
        // container, so we need to provide it with a theme for our
        // styles to work correctly
        isDarkMode === null ? "" : isDarkMode ? "tl-theme__dark" : "tl-theme__light"
      ),
      children: [
        (0, import_jsx_runtime8.jsx)("div", { className: "tl-error-boundary__overlay" }),
        editor && // opportunistically attempt to render the canvas to reassure
        // the user that their document is still there. there's a good
        // chance this won't work (ie the error that we're currently
        // notifying the user about originates in the canvas) so it's
        // not a big deal if it doesn't work - in that case we just have
        // a plain grey background.
        (0, import_jsx_runtime8.jsx)(ErrorBoundary, { onError: noop2, fallback: () => null, children: (0, import_jsx_runtime8.jsx)(EditorContext.Provider, { value: editor, children: (0, import_jsx_runtime8.jsx)("div", { className: "tl-overlay tl-error-boundary__canvas", children: (0, import_jsx_runtime8.jsx)(Canvas, {}) }) }) }),
        (0, import_jsx_runtime8.jsx)(
          "div",
          {
            className: (0, import_classnames4.default)("tl-modal", "tl-error-boundary__content", {
              "tl-error-boundary__content__expanded": shouldShowError && !shouldShowResetConfirmation
            }),
            children: shouldShowResetConfirmation ? (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
              (0, import_jsx_runtime8.jsx)("h2", { children: "Are you sure?" }),
              (0, import_jsx_runtime8.jsx)("p", { children: "Resetting your data will delete your drawing and cannot be undone." }),
              (0, import_jsx_runtime8.jsxs)("div", { className: "tl-error-boundary__content__actions", children: [
                (0, import_jsx_runtime8.jsx)("button", { onClick: () => setShouldShowResetConfirmation(false), children: "Cancel" }),
                (0, import_jsx_runtime8.jsx)("button", { className: "tl-error-boundary__reset", onClick: resetLocalState, children: "Reset data" })
              ] })
            ] }) : (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
              (0, import_jsx_runtime8.jsx)("h2", { children: "Something's gone wrong." }),
              (0, import_jsx_runtime8.jsxs)("p", { children: [
                "Sorry, we encountered an error. Please refresh the page to continue. If you keep seeing this error, you can ",
                (0, import_jsx_runtime8.jsx)("a", { href: url.toString(), children: "create a GitHub issue" }),
                " or",
                " ",
                (0, import_jsx_runtime8.jsx)("a", { href: "https://discord.gg/Cq6cPsTfNy", children: "ask for help on Discord" }),
                "."
              ] }),
              shouldShowError && (0, import_jsx_runtime8.jsxs)("div", { className: "tl-error-boundary__content__error", children: [
                (0, import_jsx_runtime8.jsx)("pre", { children: (0, import_jsx_runtime8.jsx)("code", { children: errorStack ?? errorMessage }) }),
                (0, import_jsx_runtime8.jsx)("button", { onClick: copyError, children: didCopy ? "Copied!" : "Copy" })
              ] }),
              (0, import_jsx_runtime8.jsxs)("div", { className: "tl-error-boundary__content__actions", children: [
                (0, import_jsx_runtime8.jsx)("button", { onClick: () => setShouldShowError(!shouldShowError), children: shouldShowError ? "Hide details" : "Show details" }),
                (0, import_jsx_runtime8.jsxs)("div", { className: "tl-error-boundary__content__actions__group", children: [
                  (0, import_jsx_runtime8.jsx)(
                    "button",
                    {
                      className: "tl-error-boundary__reset",
                      onClick: () => setShouldShowResetConfirmation(true),
                      children: "Reset data"
                    }
                  ),
                  (0, import_jsx_runtime8.jsx)("button", { className: "tl-error-boundary__refresh", onClick: refresh, children: "Refresh Page" })
                ] })
              ] })
            ] })
          }
        )
      ]
    }
  );
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultGrid.mjs
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/constants.mjs
var MAX_SHAPES_PER_PAGE = 2e3;
var MAX_PAGES = 40;
var ANIMATION_SHORT_MS = 80;
var ANIMATION_MEDIUM_MS = 320;
var ZOOMS = [0.1, 0.25, 0.5, 1, 2, 4, 8];
var MIN_ZOOM = 0.1;
var MAX_ZOOM = 8;
var FOLLOW_CHASE_PROPORTION = 0.5;
var FOLLOW_CHASE_PAN_SNAP = 0.1;
var FOLLOW_CHASE_PAN_UNSNAP = 0.2;
var FOLLOW_CHASE_ZOOM_SNAP = 5e-3;
var FOLLOW_CHASE_ZOOM_UNSNAP = 0.05;
var DOUBLE_CLICK_DURATION = 450;
var MULTI_CLICK_DURATION = 200;
var COARSE_DRAG_DISTANCE = 6;
var DRAG_DISTANCE = 4;
var SVG_PADDING = 32;
var HASH_PATTERN_ZOOM_NAMES = {};
for (let zoom = 1; zoom <= Math.ceil(MAX_ZOOM); zoom++) {
  HASH_PATTERN_ZOOM_NAMES[zoom + "_dark"] = `hash_pattern_zoom_${zoom}_dark`;
  HASH_PATTERN_ZOOM_NAMES[zoom + "_light"] = `hash_pattern_zoom_${zoom}_light`;
}
var DEFAULT_ANIMATION_OPTIONS = {
  duration: 0,
  easing: EASINGS.easeInOutCubic
};
var CAMERA_SLIDE_FRICTION = 0.09;
var GRID_STEPS = [
  { min: -1, mid: 0.15, step: 64 },
  { min: 0.05, mid: 0.375, step: 16 },
  { min: 0.15, mid: 1, step: 4 },
  { min: 0.7, mid: 2.5, step: 1 }
];
var COLLABORATOR_INACTIVE_TIMEOUT = 6e4;
var COLLABORATOR_IDLE_TIMEOUT = 3e3;
var COLLABORATOR_CHECK_INTERVAL = 1200;
var INTERNAL_POINTER_IDS = {
  CAMERA_MOVE: -10
};
var CAMERA_MOVING_TIMEOUT = 64;
var CAMERA_MAX_RENDERING_INTERVAL = 620;
var HIT_TEST_MARGIN = 8;

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultGrid.mjs
var DefaultGrid = ({ x, y, z, size: size2 }) => {
  return (0, import_jsx_runtime9.jsxs)("svg", { className: "tl-grid", version: "1.1", xmlns: "http://www.w3.org/2000/svg", children: [
    (0, import_jsx_runtime9.jsx)("defs", { children: GRID_STEPS.map(({ min: min4, mid, step }, i) => {
      const s = step * size2 * z;
      const xo = 0.5 + x * z;
      const yo = 0.5 + y * z;
      const gxo = xo > 0 ? xo % s : s + xo % s;
      const gyo = yo > 0 ? yo % s : s + yo % s;
      const opacity = z < mid ? modulate(z, [min4, mid], [0, 1]) : 1;
      return (0, import_jsx_runtime9.jsx)(
        "pattern",
        {
          id: `grid-${step}`,
          width: s,
          height: s,
          patternUnits: "userSpaceOnUse",
          children: (0, import_jsx_runtime9.jsx)("circle", { className: "tl-grid-dot", cx: gxo, cy: gyo, r: 1, opacity })
        },
        `grid-pattern-${i}`
      );
    }) }),
    GRID_STEPS.map(({ step }, i) => (0, import_jsx_runtime9.jsx)("rect", { width: "100%", height: "100%", fill: `url(#grid-${step})` }, `grid-rect-${i}`))
  ] });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultHandle.mjs
var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
var import_classnames5 = __toESM(require_classnames(), 1);
var DefaultHandle = ({ handle, isCoarse, className, zoom }) => {
  const bgRadius = (isCoarse ? 20 : 12) / zoom;
  const fgRadius = (handle.type === "create" && isCoarse ? 3 : 4) / zoom;
  return (0, import_jsx_runtime10.jsxs)(
    "g",
    {
      className: (0, import_classnames5.default)(
        "tl-handle",
        {
          "tl-handle__virtual": handle.type === "virtual",
          "tl-handle__create": handle.type === "create"
        },
        className
      ),
      children: [
        (0, import_jsx_runtime10.jsx)("circle", { className: "tl-handle__bg", r: bgRadius }),
        (0, import_jsx_runtime10.jsx)("circle", { className: "tl-handle__fg", r: fgRadius })
      ]
    }
  );
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultHandles.mjs
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
var DefaultHandles = ({ children }) => {
  return (0, import_jsx_runtime11.jsx)("svg", { className: "tl-user-handles tl-overlays__item", children });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultHoveredShapeIndicator.mjs
var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
var DefaultHoveredShapeIndicator = ({ shapeId }) => {
  return (0, import_jsx_runtime12.jsx)(ShapeIndicator, { className: "tl-user-indicator__hovered", id: shapeId });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultScribble.mjs
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
var import_classnames6 = __toESM(require_classnames(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/getSvgPathFromPoints.mjs
function getSvgPathFromPoints(points, closed = true) {
  const len = points.length;
  if (len < 2) {
    return "";
  }
  let a = points[0];
  let b = points[1];
  if (len === 2) {
    return `M${precise(a)}L${precise(b)}`;
  }
  let result = "";
  for (let i = 2, max3 = len - 1; i < max3; i++) {
    a = points[i];
    b = points[i + 1];
    result += average(a, b);
  }
  if (closed) {
    return `M${average(points[0], points[1])}Q${precise(points[1])}${average(
      points[1],
      points[2]
    )}T${result}${average(points[len - 1], points[0])}${average(points[0], points[1])}Z`;
  } else {
    return `M${precise(points[0])}Q${precise(points[1])}${average(points[1], points[2])}${points.length > 3 ? "T" : ""}${result}L${precise(points[len - 1])}`;
  }
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultScribble.mjs
var DefaultScribble = ({
  scribble,
  zoom,
  color,
  opacity,
  className
}) => {
  if (!scribble.points.length)
    return null;
  return (0, import_jsx_runtime13.jsx)("svg", { className: className ? (0, import_classnames6.default)("tl-overlays__item", className) : className, children: (0, import_jsx_runtime13.jsx)(
    "path",
    {
      className: "tl-scribble",
      d: getSvgPathFromPoints(scribble.points, false),
      stroke: color ?? `var(--color-${scribble.color})`,
      fill: "none",
      strokeWidth: 8 / zoom,
      opacity: opacity ?? scribble.opacity
    }
  ) });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultSelectionBackground.mjs
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
var React5 = __toESM(require_react(), 1);
var DefaultSelectionBackground = ({
  bounds,
  rotation
}) => {
  const rDiv = React5.useRef(null);
  useTransform(rDiv, bounds.x, bounds.y, 1, rotation);
  React5.useLayoutEffect(() => {
    const div = rDiv.current;
    if (!div)
      return;
    div.style.width = toDomPrecision(Math.max(1, bounds.width)) + "px";
    div.style.height = toDomPrecision(Math.max(1, bounds.height)) + "px";
  }, [bounds.width, bounds.height]);
  return (0, import_jsx_runtime14.jsx)("div", { ref: rDiv, className: "tl-selection__bg", draggable: false });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs
var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
var import_classnames7 = __toESM(require_classnames(), 1);
var import_react18 = __toESM(require_react(), 1);
var DefaultSelectionForeground = ({
  bounds,
  rotation
}) => {
  const editor = useEditor();
  const rSvg = (0, import_react18.useRef)(null);
  const onlyShape = useValue("only selected shape", () => editor.onlySelectedShape, [editor]);
  const expandOutlineBy = onlyShape ? editor.getShapeUtil(onlyShape).expandSelectionOutlinePx(onlyShape) : 0;
  useTransform(rSvg, bounds?.x, bounds?.y, 1, rotation, {
    x: -expandOutlineBy,
    y: -expandOutlineBy
  });
  bounds = bounds.clone().expandBy(expandOutlineBy).zeroFix();
  return (0, import_jsx_runtime15.jsx)(
    "svg",
    {
      ref: rSvg,
      className: "tl-overlays__item tl-selection__fg",
      "data-testid": "selection-foreground",
      children: (0, import_jsx_runtime15.jsx)(
        "rect",
        {
          className: (0, import_classnames7.default)("tl-selection__fg__outline"),
          width: toDomPrecision(bounds.width),
          height: toDomPrecision(bounds.height)
        }
      )
    }
  );
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
var DefaultShapeErrorFallback = () => {
  return (0, import_jsx_runtime16.jsx)("div", { className: "tl-shape-error-boundary" });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
var DefaultShapeIndicatorErrorFallback = () => {
  return (0, import_jsx_runtime17.jsx)("circle", { cx: 4, cy: 4, r: 8, strokeWidth: "1", stroke: "red" });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultSnapLine.mjs
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
var import_classnames8 = __toESM(require_classnames(), 1);
var React6 = __toESM(require_react(), 1);
function PointsSnapLine({ points, zoom }) {
  const l = 2.5 / zoom;
  const minX = points.reduce((acc, p) => Math.min(acc, p.x), Infinity);
  const maxX = points.reduce((acc, p) => Math.max(acc, p.x), -Infinity);
  const minY = points.reduce((acc, p) => Math.min(acc, p.y), Infinity);
  const maxY = points.reduce((acc, p) => Math.max(acc, p.y), -Infinity);
  const useNWtoSEdireciton = points.some((p) => p.x === minX && p.y === minY);
  let firstX, firstY, secondX, secondY;
  if (useNWtoSEdireciton) {
    firstX = minX;
    firstY = minY;
    secondX = maxX;
    secondY = maxY;
  } else {
    firstX = minX;
    firstY = maxY;
    secondX = maxX;
    secondY = minY;
  }
  return (0, import_jsx_runtime18.jsxs)("g", { className: "tl-snap-line", children: [
    (0, import_jsx_runtime18.jsx)("line", { x1: firstX, y1: firstY, x2: secondX, y2: secondY }),
    points.map((p, i) => (0, import_jsx_runtime18.jsx)("g", { transform: `translate(${p.x},${p.y})`, children: (0, import_jsx_runtime18.jsx)(
      "path",
      {
        className: "tl-snap-point",
        d: `M ${-l},${-l} L ${l},${l} M ${-l},${l} L ${l},${-l}`
      }
    ) }, i))
  ] });
}
function GapsSnapLine({ gaps, direction, zoom }) {
  const l = 3.5 / zoom;
  let edgeIntersection = [-Infinity, Infinity];
  let nextEdgeIntersection = null;
  const horizontal = direction === "horizontal";
  for (const gap of gaps) {
    nextEdgeIntersection = rangeIntersection(
      edgeIntersection[0],
      edgeIntersection[1],
      horizontal ? gap.startEdge[0].y : gap.startEdge[0].x,
      horizontal ? gap.startEdge[1].y : gap.startEdge[1].x
    );
    if (nextEdgeIntersection) {
      edgeIntersection = nextEdgeIntersection;
    } else {
      continue;
    }
    nextEdgeIntersection = rangeIntersection(
      edgeIntersection[0],
      edgeIntersection[1],
      horizontal ? gap.endEdge[0].y : gap.endEdge[0].x,
      horizontal ? gap.endEdge[1].y : gap.endEdge[1].x
    );
    if (nextEdgeIntersection) {
      edgeIntersection = nextEdgeIntersection;
    } else {
      continue;
    }
  }
  if (edgeIntersection === null) {
    return null;
  }
  const midPoint = (edgeIntersection[0] + edgeIntersection[1]) / 2;
  return (0, import_jsx_runtime18.jsx)("g", { className: "tl-snap-line", children: gaps.map(({ startEdge, endEdge }, i) => (0, import_jsx_runtime18.jsx)(React6.Fragment, { children: horizontal ? (
    // horizontal gap
    (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
      (0, import_jsx_runtime18.jsx)(
        "line",
        {
          x1: startEdge[0].x,
          y1: midPoint - 2 * l,
          x2: startEdge[1].x,
          y2: midPoint + 2 * l
        }
      ),
      (0, import_jsx_runtime18.jsx)(
        "line",
        {
          x1: endEdge[0].x,
          y1: midPoint - 2 * l,
          x2: endEdge[1].x,
          y2: midPoint + 2 * l
        }
      ),
      (0, import_jsx_runtime18.jsx)("line", { x1: startEdge[0].x, y1: midPoint, x2: endEdge[0].x, y2: midPoint }),
      (0, import_jsx_runtime18.jsx)(
        "line",
        {
          x1: (startEdge[0].x + endEdge[0].x) / 2,
          y1: midPoint - l,
          x2: (startEdge[0].x + endEdge[0].x) / 2,
          y2: midPoint + l
        }
      )
    ] })
  ) : (
    // vertical gap
    (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
      (0, import_jsx_runtime18.jsx)(
        "line",
        {
          x1: midPoint - 2 * l,
          y1: startEdge[0].y,
          x2: midPoint + 2 * l,
          y2: startEdge[1].y
        }
      ),
      (0, import_jsx_runtime18.jsx)(
        "line",
        {
          x1: midPoint - 2 * l,
          y1: endEdge[0].y,
          x2: midPoint + 2 * l,
          y2: endEdge[1].y
        }
      ),
      (0, import_jsx_runtime18.jsx)("line", { x1: midPoint, y1: startEdge[0].y, x2: midPoint, y2: endEdge[0].y }),
      (0, import_jsx_runtime18.jsx)(
        "line",
        {
          x1: midPoint - l,
          y1: (startEdge[0].y + endEdge[0].y) / 2,
          x2: midPoint + l,
          y2: (startEdge[0].y + endEdge[0].y) / 2
        }
      )
    ] })
  ) }, i)) });
}
var DefaultSnapLine = ({ className, line, zoom }) => {
  return (0, import_jsx_runtime18.jsx)("svg", { className: (0, import_classnames8.default)("tl-overlays__item", className), children: line.type === "points" ? (0, import_jsx_runtime18.jsx)(PointsSnapLine, { ...line, zoom }) : line.type === "gaps" ? (0, import_jsx_runtime18.jsx)(GapsSnapLine, { ...line, zoom }) : null });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultSpinner.mjs
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
var DefaultSpinner = () => {
  return (0, import_jsx_runtime19.jsx)("svg", { width: 16, height: 16, viewBox: "0 0 16 16", children: (0, import_jsx_runtime19.jsxs)("g", { strokeWidth: 2, fill: "none", fillRule: "evenodd", children: [
    (0, import_jsx_runtime19.jsx)("circle", { strokeOpacity: 0.25, cx: 8, cy: 8, r: 7, stroke: "var(--color-text-1)" }),
    (0, import_jsx_runtime19.jsx)("path", { strokeLinecap: "round", d: "M15 8c0-4.5-4.5-7-7-7", stroke: "var(--color-text-1)", children: (0, import_jsx_runtime19.jsx)(
      "animateTransform",
      {
        attributeName: "transform",
        type: "rotate",
        from: "0 8 8",
        to: "360 8 8",
        dur: "1s",
        repeatCount: "indefinite"
      }
    ) })
  ] }) });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs
var DefaultSvgDefs = () => {
  return null;
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useEditorComponents.mjs
var EditorComponentsContext = (0, import_react19.createContext)({});
function EditorComponentsProvider({ overrides, children }) {
  return (0, import_jsx_runtime20.jsx)(
    EditorComponentsContext.Provider,
    {
      value: (0, import_react19.useMemo)(
        () => ({
          Background: DefaultBackground,
          SvgDefs: DefaultSvgDefs,
          Brush: DefaultBrush,
          ZoomBrush: DefaultBrush,
          CollaboratorBrush: DefaultBrush,
          Cursor: DefaultCursor,
          CollaboratorCursor: DefaultCursor,
          CollaboratorHint: DefaultCollaboratorHint,
          CollaboratorShapeIndicator: ShapeIndicator,
          Grid: DefaultGrid,
          Scribble: DefaultScribble,
          SnapLine: DefaultSnapLine,
          Handles: DefaultHandles,
          Handle: DefaultHandle,
          CollaboratorScribble: DefaultScribble,
          ErrorFallback: DefaultErrorFallback,
          ShapeErrorFallback: DefaultShapeErrorFallback,
          ShapeIndicatorErrorFallback: DefaultShapeIndicatorErrorFallback,
          Spinner: DefaultSpinner,
          SelectionBackground: DefaultSelectionBackground,
          SelectionForeground: DefaultSelectionForeground,
          HoveredShapeIndicator: DefaultHoveredShapeIndicator,
          ...overrides
        }),
        [overrides]
      ),
      children
    }
  );
}
function useEditorComponents() {
  return (0, import_react19.useContext)(EditorComponentsContext);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs
var import_react20 = __toESM(require_react(), 1);
var IGNORED_TAGS = ["textarea", "input"];
function useFixSafariDoubleTapZoomPencilEvents(ref) {
  const editor = useEditor();
  (0, import_react20.useEffect)(() => {
    const elm = ref.current;
    if (!elm)
      return;
    const handleEvent = (e) => {
      if (e instanceof PointerEvent && e.pointerType === "pen") {
        ;
        e.isKilled = true;
        const { target } = e;
        if (IGNORED_TAGS.includes(target.tagName?.toLocaleLowerCase()) || editor.isIn("select.editing_shape")) {
          return;
        }
        preventDefault(e);
      }
    };
    elm.addEventListener("touchstart", handleEvent);
    elm.addEventListener("touchend", handleEvent);
    return () => {
      elm.removeEventListener("touchstart", handleEvent);
      elm.addEventListener("touchend", handleEvent);
    };
  }, [editor, ref]);
}

// node_modules/.deno/@use-gesture+core@10.3.1/node_modules/@use-gesture/core/dist/maths-0ab39ae9.esm.js
function clamp2(v, min4, max3) {
  return Math.max(min4, Math.min(v, max3));
}
var V = {
  toVector(v, fallback) {
    if (v === void 0)
      v = fallback;
    return Array.isArray(v) ? v : [v, v];
  },
  add(v1, v2) {
    return [v1[0] + v2[0], v1[1] + v2[1]];
  },
  sub(v1, v2) {
    return [v1[0] - v2[0], v1[1] - v2[1]];
  },
  addTo(v1, v2) {
    v1[0] += v2[0];
    v1[1] += v2[1];
  },
  subTo(v1, v2) {
    v1[0] -= v2[0];
    v1[1] -= v2[1];
  }
};
function rubberband(distance, dimension, constant) {
  if (dimension === 0 || Math.abs(dimension) === Infinity)
    return Math.pow(distance, constant * 5);
  return distance * dimension * constant / (dimension + constant * distance);
}
function rubberbandIfOutOfBounds(position, min4, max3, constant = 0.15) {
  if (constant === 0)
    return clamp2(position, min4, max3);
  if (position < min4)
    return -rubberband(min4 - position, max3 - min4, constant) + min4;
  if (position > max3)
    return +rubberband(position - max3, max3 - min4, constant) + max3;
  return position;
}
function computeRubberband(bounds, [Vx, Vy], [Rx, Ry]) {
  const [[X0, X1], [Y0, Y1]] = bounds;
  return [rubberbandIfOutOfBounds(Vx, X0, X1, Rx), rubberbandIfOutOfBounds(Vy, Y0, Y1, Ry)];
}

// node_modules/.deno/@use-gesture+core@10.3.1/node_modules/@use-gesture/core/dist/actions-fe213e88.esm.js
function _toPrimitive(input, hint) {
  if (typeof input !== "object" || input === null)
    return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== void 0) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object")
      return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function ownKeys(e, r) {
  var t2 = Object.keys(e);
  if (Object.getOwnPropertySymbols) {
    var o = Object.getOwnPropertySymbols(e);
    r && (o = o.filter(function(r2) {
      return Object.getOwnPropertyDescriptor(e, r2).enumerable;
    })), t2.push.apply(t2, o);
  }
  return t2;
}
function _objectSpread2(e) {
  for (var r = 1; r < arguments.length; r++) {
    var t2 = null != arguments[r] ? arguments[r] : {};
    r % 2 ? ownKeys(Object(t2), true).forEach(function(r2) {
      _defineProperty(e, r2, t2[r2]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t2)) : ownKeys(Object(t2)).forEach(function(r2) {
      Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t2, r2));
    });
  }
  return e;
}
var EVENT_TYPE_MAP = {
  pointer: {
    start: "down",
    change: "move",
    end: "up"
  },
  mouse: {
    start: "down",
    change: "move",
    end: "up"
  },
  touch: {
    start: "start",
    change: "move",
    end: "end"
  },
  gesture: {
    start: "start",
    change: "change",
    end: "end"
  }
};
function capitalize(string2) {
  if (!string2)
    return "";
  return string2[0].toUpperCase() + string2.slice(1);
}
var actionsWithoutCaptureSupported = ["enter", "leave"];
function hasCapture(capture = false, actionKey) {
  return capture && !actionsWithoutCaptureSupported.includes(actionKey);
}
function toHandlerProp(device, action = "", capture = false) {
  const deviceProps = EVENT_TYPE_MAP[device];
  const actionKey = deviceProps ? deviceProps[action] || action : action;
  return "on" + capitalize(device) + capitalize(actionKey) + (hasCapture(capture, actionKey) ? "Capture" : "");
}
var pointerCaptureEvents = ["gotpointercapture", "lostpointercapture"];
function parseProp(prop) {
  let eventKey = prop.substring(2).toLowerCase();
  const passive = !!~eventKey.indexOf("passive");
  if (passive)
    eventKey = eventKey.replace("passive", "");
  const captureKey = pointerCaptureEvents.includes(eventKey) ? "capturecapture" : "capture";
  const capture = !!~eventKey.indexOf(captureKey);
  if (capture)
    eventKey = eventKey.replace("capture", "");
  return {
    device: eventKey,
    capture,
    passive
  };
}
function toDomEventType(device, action = "") {
  const deviceProps = EVENT_TYPE_MAP[device];
  const actionKey = deviceProps ? deviceProps[action] || action : action;
  return device + actionKey;
}
function isTouch(event) {
  return "touches" in event;
}
function getPointerType(event) {
  if (isTouch(event))
    return "touch";
  if ("pointerType" in event)
    return event.pointerType;
  return "mouse";
}
function getCurrentTargetTouchList(event) {
  return Array.from(event.touches).filter((e) => {
    var _event$currentTarget, _event$currentTarget$;
    return e.target === event.currentTarget || ((_event$currentTarget = event.currentTarget) === null || _event$currentTarget === void 0 || (_event$currentTarget$ = _event$currentTarget.contains) === null || _event$currentTarget$ === void 0 ? void 0 : _event$currentTarget$.call(_event$currentTarget, e.target));
  });
}
function distanceAngle(P1, P2) {
  try {
    const dx = P2.clientX - P1.clientX;
    const dy = P2.clientY - P1.clientY;
    const cx = (P2.clientX + P1.clientX) / 2;
    const cy = (P2.clientY + P1.clientY) / 2;
    const distance = Math.hypot(dx, dy);
    const angle = -(Math.atan2(dx, dy) * 180) / Math.PI;
    const origin = [cx, cy];
    return {
      angle,
      distance,
      origin
    };
  } catch (_unused) {
  }
  return null;
}
function touchIds(event) {
  return getCurrentTargetTouchList(event).map((touch) => touch.identifier);
}
function touchDistanceAngle(event, ids) {
  const [P1, P2] = Array.from(event.touches).filter((touch) => ids.includes(touch.identifier));
  return distanceAngle(P1, P2);
}
var LINE_HEIGHT = 40;
var PAGE_HEIGHT = 800;
function wheelValues(event) {
  let {
    deltaX,
    deltaY,
    deltaMode
  } = event;
  if (deltaMode === 1) {
    deltaX *= LINE_HEIGHT;
    deltaY *= LINE_HEIGHT;
  } else if (deltaMode === 2) {
    deltaX *= PAGE_HEIGHT;
    deltaY *= PAGE_HEIGHT;
  }
  return [deltaX, deltaY];
}
function getEventDetails(event) {
  const payload = {};
  if ("buttons" in event)
    payload.buttons = event.buttons;
  if ("shiftKey" in event) {
    const {
      shiftKey,
      altKey: altKey2,
      metaKey,
      ctrlKey
    } = event;
    Object.assign(payload, {
      shiftKey,
      altKey: altKey2,
      metaKey,
      ctrlKey
    });
  }
  return payload;
}
function call(v, ...args) {
  if (typeof v === "function") {
    return v(...args);
  } else {
    return v;
  }
}
function noop3() {
}
function chain(...fns) {
  if (fns.length === 0)
    return noop3;
  if (fns.length === 1)
    return fns[0];
  return function() {
    let result;
    for (const fn of fns) {
      result = fn.apply(this, arguments) || result;
    }
    return result;
  };
}
function assignDefault(value, fallback) {
  return Object.assign({}, fallback, value || {});
}
var BEFORE_LAST_KINEMATICS_DELAY = 32;
var Engine = class {
  constructor(ctrl, args, key) {
    this.ctrl = ctrl;
    this.args = args;
    this.key = key;
    if (!this.state) {
      this.state = {};
      this.computeValues([0, 0]);
      this.computeInitial();
      if (this.init)
        this.init();
      this.reset();
    }
  }
  get state() {
    return this.ctrl.state[this.key];
  }
  set state(state) {
    this.ctrl.state[this.key] = state;
  }
  get shared() {
    return this.ctrl.state.shared;
  }
  get eventStore() {
    return this.ctrl.gestureEventStores[this.key];
  }
  get timeoutStore() {
    return this.ctrl.gestureTimeoutStores[this.key];
  }
  get config() {
    return this.ctrl.config[this.key];
  }
  get sharedConfig() {
    return this.ctrl.config.shared;
  }
  get handler() {
    return this.ctrl.handlers[this.key];
  }
  reset() {
    const {
      state,
      shared,
      ingKey,
      args
    } = this;
    shared[ingKey] = state._active = state.active = state._blocked = state._force = false;
    state._step = [false, false];
    state.intentional = false;
    state._movement = [0, 0];
    state._distance = [0, 0];
    state._direction = [0, 0];
    state._delta = [0, 0];
    state._bounds = [[-Infinity, Infinity], [-Infinity, Infinity]];
    state.args = args;
    state.axis = void 0;
    state.memo = void 0;
    state.elapsedTime = state.timeDelta = 0;
    state.direction = [0, 0];
    state.distance = [0, 0];
    state.overflow = [0, 0];
    state._movementBound = [false, false];
    state.velocity = [0, 0];
    state.movement = [0, 0];
    state.delta = [0, 0];
    state.timeStamp = 0;
  }
  start(event) {
    const state = this.state;
    const config = this.config;
    if (!state._active) {
      this.reset();
      this.computeInitial();
      state._active = true;
      state.target = event.target;
      state.currentTarget = event.currentTarget;
      state.lastOffset = config.from ? call(config.from, state) : state.offset;
      state.offset = state.lastOffset;
      state.startTime = state.timeStamp = event.timeStamp;
    }
  }
  computeValues(values) {
    const state = this.state;
    state._values = values;
    state.values = this.config.transform(values);
  }
  computeInitial() {
    const state = this.state;
    state._initial = state._values;
    state.initial = state.values;
  }
  compute(event) {
    const {
      state,
      config,
      shared
    } = this;
    state.args = this.args;
    let dt = 0;
    if (event) {
      state.event = event;
      if (config.preventDefault && event.cancelable)
        state.event.preventDefault();
      state.type = event.type;
      shared.touches = this.ctrl.pointerIds.size || this.ctrl.touchIds.size;
      shared.locked = !!document.pointerLockElement;
      Object.assign(shared, getEventDetails(event));
      shared.down = shared.pressed = shared.buttons % 2 === 1 || shared.touches > 0;
      dt = event.timeStamp - state.timeStamp;
      state.timeStamp = event.timeStamp;
      state.elapsedTime = state.timeStamp - state.startTime;
    }
    if (state._active) {
      const _absoluteDelta = state._delta.map(Math.abs);
      V.addTo(state._distance, _absoluteDelta);
    }
    if (this.axisIntent)
      this.axisIntent(event);
    const [_m0, _m1] = state._movement;
    const [t0, t1] = config.threshold;
    const {
      _step,
      values
    } = state;
    if (config.hasCustomTransform) {
      if (_step[0] === false)
        _step[0] = Math.abs(_m0) >= t0 && values[0];
      if (_step[1] === false)
        _step[1] = Math.abs(_m1) >= t1 && values[1];
    } else {
      if (_step[0] === false)
        _step[0] = Math.abs(_m0) >= t0 && Math.sign(_m0) * t0;
      if (_step[1] === false)
        _step[1] = Math.abs(_m1) >= t1 && Math.sign(_m1) * t1;
    }
    state.intentional = _step[0] !== false || _step[1] !== false;
    if (!state.intentional)
      return;
    const movement = [0, 0];
    if (config.hasCustomTransform) {
      const [v0, v1] = values;
      movement[0] = _step[0] !== false ? v0 - _step[0] : 0;
      movement[1] = _step[1] !== false ? v1 - _step[1] : 0;
    } else {
      movement[0] = _step[0] !== false ? _m0 - _step[0] : 0;
      movement[1] = _step[1] !== false ? _m1 - _step[1] : 0;
    }
    if (this.restrictToAxis && !state._blocked)
      this.restrictToAxis(movement);
    const previousOffset = state.offset;
    const gestureIsActive = state._active && !state._blocked || state.active;
    if (gestureIsActive) {
      state.first = state._active && !state.active;
      state.last = !state._active && state.active;
      state.active = shared[this.ingKey] = state._active;
      if (event) {
        if (state.first) {
          if ("bounds" in config)
            state._bounds = call(config.bounds, state);
          if (this.setup)
            this.setup();
        }
        state.movement = movement;
        this.computeOffset();
      }
    }
    const [ox, oy] = state.offset;
    const [[x0, x1], [y0, y1]] = state._bounds;
    state.overflow = [ox < x0 ? -1 : ox > x1 ? 1 : 0, oy < y0 ? -1 : oy > y1 ? 1 : 0];
    state._movementBound[0] = state.overflow[0] ? state._movementBound[0] === false ? state._movement[0] : state._movementBound[0] : false;
    state._movementBound[1] = state.overflow[1] ? state._movementBound[1] === false ? state._movement[1] : state._movementBound[1] : false;
    const rubberband2 = state._active ? config.rubberband || [0, 0] : [0, 0];
    state.offset = computeRubberband(state._bounds, state.offset, rubberband2);
    state.delta = V.sub(state.offset, previousOffset);
    this.computeMovement();
    if (gestureIsActive && (!state.last || dt > BEFORE_LAST_KINEMATICS_DELAY)) {
      state.delta = V.sub(state.offset, previousOffset);
      const absoluteDelta = state.delta.map(Math.abs);
      V.addTo(state.distance, absoluteDelta);
      state.direction = state.delta.map(Math.sign);
      state._direction = state._delta.map(Math.sign);
      if (!state.first && dt > 0) {
        state.velocity = [absoluteDelta[0] / dt, absoluteDelta[1] / dt];
        state.timeDelta = dt;
      }
    }
  }
  emit() {
    const state = this.state;
    const shared = this.shared;
    const config = this.config;
    if (!state._active)
      this.clean();
    if ((state._blocked || !state.intentional) && !state._force && !config.triggerAllEvents)
      return;
    const memo32 = this.handler(_objectSpread2(_objectSpread2(_objectSpread2({}, shared), state), {}, {
      [this.aliasKey]: state.values
    }));
    if (memo32 !== void 0)
      state.memo = memo32;
  }
  clean() {
    this.eventStore.clean();
    this.timeoutStore.clean();
  }
};
function selectAxis([dx, dy], threshold) {
  const absDx = Math.abs(dx);
  const absDy = Math.abs(dy);
  if (absDx > absDy && absDx > threshold) {
    return "x";
  }
  if (absDy > absDx && absDy > threshold) {
    return "y";
  }
  return void 0;
}
var CoordinatesEngine = class extends Engine {
  constructor(...args) {
    super(...args);
    _defineProperty(this, "aliasKey", "xy");
  }
  reset() {
    super.reset();
    this.state.axis = void 0;
  }
  init() {
    this.state.offset = [0, 0];
    this.state.lastOffset = [0, 0];
  }
  computeOffset() {
    this.state.offset = V.add(this.state.lastOffset, this.state.movement);
  }
  computeMovement() {
    this.state.movement = V.sub(this.state.offset, this.state.lastOffset);
  }
  axisIntent(event) {
    const state = this.state;
    const config = this.config;
    if (!state.axis && event) {
      const threshold = typeof config.axisThreshold === "object" ? config.axisThreshold[getPointerType(event)] : config.axisThreshold;
      state.axis = selectAxis(state._movement, threshold);
    }
    state._blocked = (config.lockDirection || !!config.axis) && !state.axis || !!config.axis && config.axis !== state.axis;
  }
  restrictToAxis(v) {
    if (this.config.axis || this.config.lockDirection) {
      switch (this.state.axis) {
        case "x":
          v[1] = 0;
          break;
        case "y":
          v[0] = 0;
          break;
      }
    }
  }
};
var identity = (v) => v;
var DEFAULT_RUBBERBAND = 0.15;
var commonConfigResolver = {
  enabled(value = true) {
    return value;
  },
  eventOptions(value, _k, config) {
    return _objectSpread2(_objectSpread2({}, config.shared.eventOptions), value);
  },
  preventDefault(value = false) {
    return value;
  },
  triggerAllEvents(value = false) {
    return value;
  },
  rubberband(value = 0) {
    switch (value) {
      case true:
        return [DEFAULT_RUBBERBAND, DEFAULT_RUBBERBAND];
      case false:
        return [0, 0];
      default:
        return V.toVector(value);
    }
  },
  from(value) {
    if (typeof value === "function")
      return value;
    if (value != null)
      return V.toVector(value);
  },
  transform(value, _k, config) {
    const transform = value || config.shared.transform;
    this.hasCustomTransform = !!transform;
    if (true) {
      const originalTransform = transform || identity;
      return (v) => {
        const r = originalTransform(v);
        if (!isFinite(r[0]) || !isFinite(r[1])) {
          console.warn(`[@use-gesture]: config.transform() must produce a valid result, but it was: [${r[0]},${[1]}]`);
        }
        return r;
      };
    }
    return transform || identity;
  },
  threshold(value) {
    return V.toVector(value, 0);
  }
};
if (true) {
  Object.assign(commonConfigResolver, {
    domTarget(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`domTarget\` option has been renamed to \`target\`.`);
      }
      return NaN;
    },
    lockDirection(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`lockDirection\` option has been merged with \`axis\`. Use it as in \`{ axis: 'lock' }\``);
      }
      return NaN;
    },
    initial(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`initial\` option has been renamed to \`from\`.`);
      }
      return NaN;
    }
  });
}
var DEFAULT_AXIS_THRESHOLD = 0;
var coordinatesConfigResolver = _objectSpread2(_objectSpread2({}, commonConfigResolver), {}, {
  axis(_v, _k, {
    axis
  }) {
    this.lockDirection = axis === "lock";
    if (!this.lockDirection)
      return axis;
  },
  axisThreshold(value = DEFAULT_AXIS_THRESHOLD) {
    return value;
  },
  bounds(value = {}) {
    if (typeof value === "function") {
      return (state) => coordinatesConfigResolver.bounds(value(state));
    }
    if ("current" in value) {
      return () => value.current;
    }
    if (typeof HTMLElement === "function" && value instanceof HTMLElement) {
      return value;
    }
    const {
      left = -Infinity,
      right = Infinity,
      top = -Infinity,
      bottom = Infinity
    } = value;
    return [[left, right], [top, bottom]];
  }
});
var isBrowser = typeof window !== "undefined" && window.document && window.document.createElement;
function supportsTouchEvents() {
  return isBrowser && "ontouchstart" in window;
}
function isTouchScreen() {
  return supportsTouchEvents() || isBrowser && window.navigator.maxTouchPoints > 1;
}
function supportsPointerEvents() {
  return isBrowser && "onpointerdown" in window;
}
function supportsPointerLock() {
  return isBrowser && "exitPointerLock" in window.document;
}
function supportsGestureEvents() {
  try {
    return "constructor" in GestureEvent;
  } catch (e) {
    return false;
  }
}
var SUPPORT = {
  isBrowser,
  gesture: supportsGestureEvents(),
  touch: supportsTouchEvents(),
  touchscreen: isTouchScreen(),
  pointer: supportsPointerEvents(),
  pointerLock: supportsPointerLock()
};
var DEFAULT_PREVENT_SCROLL_DELAY = 250;
var DEFAULT_DRAG_DELAY = 180;
var DEFAULT_SWIPE_VELOCITY = 0.5;
var DEFAULT_SWIPE_DISTANCE = 50;
var DEFAULT_SWIPE_DURATION = 250;
var DEFAULT_KEYBOARD_DISPLACEMENT = 10;
var DEFAULT_DRAG_AXIS_THRESHOLD = {
  mouse: 0,
  touch: 0,
  pen: 8
};
var dragConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
  device(_v, _k, {
    pointer: {
      touch = false,
      lock = false,
      mouse = false
    } = {}
  }) {
    this.pointerLock = lock && SUPPORT.pointerLock;
    if (SUPPORT.touch && touch)
      return "touch";
    if (this.pointerLock)
      return "mouse";
    if (SUPPORT.pointer && !mouse)
      return "pointer";
    if (SUPPORT.touch)
      return "touch";
    return "mouse";
  },
  preventScrollAxis(value, _k, {
    preventScroll
  }) {
    this.preventScrollDelay = typeof preventScroll === "number" ? preventScroll : preventScroll || preventScroll === void 0 && value ? DEFAULT_PREVENT_SCROLL_DELAY : void 0;
    if (!SUPPORT.touchscreen || preventScroll === false)
      return void 0;
    return value ? value : preventScroll !== void 0 ? "y" : void 0;
  },
  pointerCapture(_v, _k, {
    pointer: {
      capture = true,
      buttons = 1,
      keys = true
    } = {}
  }) {
    this.pointerButtons = buttons;
    this.keys = keys;
    return !this.pointerLock && this.device === "pointer" && capture;
  },
  threshold(value, _k, {
    filterTaps = false,
    tapsThreshold = 3,
    axis = void 0
  }) {
    const threshold = V.toVector(value, filterTaps ? tapsThreshold : axis ? 1 : 0);
    this.filterTaps = filterTaps;
    this.tapsThreshold = tapsThreshold;
    return threshold;
  },
  swipe({
    velocity = DEFAULT_SWIPE_VELOCITY,
    distance = DEFAULT_SWIPE_DISTANCE,
    duration = DEFAULT_SWIPE_DURATION
  } = {}) {
    return {
      velocity: this.transform(V.toVector(velocity)),
      distance: this.transform(V.toVector(distance)),
      duration
    };
  },
  delay(value = 0) {
    switch (value) {
      case true:
        return DEFAULT_DRAG_DELAY;
      case false:
        return 0;
      default:
        return value;
    }
  },
  axisThreshold(value) {
    if (!value)
      return DEFAULT_DRAG_AXIS_THRESHOLD;
    return _objectSpread2(_objectSpread2({}, DEFAULT_DRAG_AXIS_THRESHOLD), value);
  },
  keyboardDisplacement(value = DEFAULT_KEYBOARD_DISPLACEMENT) {
    return value;
  }
});
if (true) {
  Object.assign(dragConfigResolver, {
    useTouch(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`useTouch\` option has been renamed to \`pointer.touch\`. Use it as in \`{ pointer: { touch: true } }\`.`);
      }
      return NaN;
    },
    experimental_preventWindowScrollY(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`experimental_preventWindowScrollY\` option has been renamed to \`preventScroll\`.`);
      }
      return NaN;
    },
    swipeVelocity(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`swipeVelocity\` option has been renamed to \`swipe.velocity\`. Use it as in \`{ swipe: { velocity: 0.5 } }\`.`);
      }
      return NaN;
    },
    swipeDistance(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`swipeDistance\` option has been renamed to \`swipe.distance\`. Use it as in \`{ swipe: { distance: 50 } }\`.`);
      }
      return NaN;
    },
    swipeDuration(value) {
      if (value !== void 0) {
        throw Error(`[@use-gesture]: \`swipeDuration\` option has been renamed to \`swipe.duration\`. Use it as in \`{ swipe: { duration: 250 } }\`.`);
      }
      return NaN;
    }
  });
}
function clampStateInternalMovementToBounds(state) {
  const [ox, oy] = state.overflow;
  const [dx, dy] = state._delta;
  const [dirx, diry] = state._direction;
  if (ox < 0 && dx > 0 && dirx < 0 || ox > 0 && dx < 0 && dirx > 0) {
    state._movement[0] = state._movementBound[0];
  }
  if (oy < 0 && dy > 0 && diry < 0 || oy > 0 && dy < 0 && diry > 0) {
    state._movement[1] = state._movementBound[1];
  }
}
var SCALE_ANGLE_RATIO_INTENT_DEG = 30;
var PINCH_WHEEL_RATIO = 100;
var PinchEngine = class extends Engine {
  constructor(...args) {
    super(...args);
    _defineProperty(this, "ingKey", "pinching");
    _defineProperty(this, "aliasKey", "da");
  }
  init() {
    this.state.offset = [1, 0];
    this.state.lastOffset = [1, 0];
    this.state._pointerEvents = /* @__PURE__ */ new Map();
  }
  reset() {
    super.reset();
    const state = this.state;
    state._touchIds = [];
    state.canceled = false;
    state.cancel = this.cancel.bind(this);
    state.turns = 0;
  }
  computeOffset() {
    const {
      type,
      movement,
      lastOffset
    } = this.state;
    if (type === "wheel") {
      this.state.offset = V.add(movement, lastOffset);
    } else {
      this.state.offset = [(1 + movement[0]) * lastOffset[0], movement[1] + lastOffset[1]];
    }
  }
  computeMovement() {
    const {
      offset: offset2,
      lastOffset
    } = this.state;
    this.state.movement = [offset2[0] / lastOffset[0], offset2[1] - lastOffset[1]];
  }
  axisIntent() {
    const state = this.state;
    const [_m0, _m1] = state._movement;
    if (!state.axis) {
      const axisMovementDifference = Math.abs(_m0) * SCALE_ANGLE_RATIO_INTENT_DEG - Math.abs(_m1);
      if (axisMovementDifference < 0)
        state.axis = "angle";
      else if (axisMovementDifference > 0)
        state.axis = "scale";
    }
  }
  restrictToAxis(v) {
    if (this.config.lockDirection) {
      if (this.state.axis === "scale")
        v[1] = 0;
      else if (this.state.axis === "angle")
        v[0] = 0;
    }
  }
  cancel() {
    const state = this.state;
    if (state.canceled)
      return;
    setTimeout(() => {
      state.canceled = true;
      state._active = false;
      this.compute();
      this.emit();
    }, 0);
  }
  touchStart(event) {
    this.ctrl.setEventIds(event);
    const state = this.state;
    const ctrlTouchIds = this.ctrl.touchIds;
    if (state._active) {
      if (state._touchIds.every((id) => ctrlTouchIds.has(id)))
        return;
    }
    if (ctrlTouchIds.size < 2)
      return;
    this.start(event);
    state._touchIds = Array.from(ctrlTouchIds).slice(0, 2);
    const payload = touchDistanceAngle(event, state._touchIds);
    if (!payload)
      return;
    this.pinchStart(event, payload);
  }
  pointerStart(event) {
    if (event.buttons != null && event.buttons % 2 !== 1)
      return;
    this.ctrl.setEventIds(event);
    event.target.setPointerCapture(event.pointerId);
    const state = this.state;
    const _pointerEvents = state._pointerEvents;
    const ctrlPointerIds = this.ctrl.pointerIds;
    if (state._active) {
      if (Array.from(_pointerEvents.keys()).every((id) => ctrlPointerIds.has(id)))
        return;
    }
    if (_pointerEvents.size < 2) {
      _pointerEvents.set(event.pointerId, event);
    }
    if (state._pointerEvents.size < 2)
      return;
    this.start(event);
    const payload = distanceAngle(...Array.from(_pointerEvents.values()));
    if (!payload)
      return;
    this.pinchStart(event, payload);
  }
  pinchStart(event, payload) {
    const state = this.state;
    state.origin = payload.origin;
    this.computeValues([payload.distance, payload.angle]);
    this.computeInitial();
    this.compute(event);
    this.emit();
  }
  touchMove(event) {
    if (!this.state._active)
      return;
    const payload = touchDistanceAngle(event, this.state._touchIds);
    if (!payload)
      return;
    this.pinchMove(event, payload);
  }
  pointerMove(event) {
    const _pointerEvents = this.state._pointerEvents;
    if (_pointerEvents.has(event.pointerId)) {
      _pointerEvents.set(event.pointerId, event);
    }
    if (!this.state._active)
      return;
    const payload = distanceAngle(...Array.from(_pointerEvents.values()));
    if (!payload)
      return;
    this.pinchMove(event, payload);
  }
  pinchMove(event, payload) {
    const state = this.state;
    const prev_a = state._values[1];
    const delta_a = payload.angle - prev_a;
    let delta_turns = 0;
    if (Math.abs(delta_a) > 270)
      delta_turns += Math.sign(delta_a);
    this.computeValues([payload.distance, payload.angle - 360 * delta_turns]);
    state.origin = payload.origin;
    state.turns = delta_turns;
    state._movement = [state._values[0] / state._initial[0] - 1, state._values[1] - state._initial[1]];
    this.compute(event);
    this.emit();
  }
  touchEnd(event) {
    this.ctrl.setEventIds(event);
    if (!this.state._active)
      return;
    if (this.state._touchIds.some((id) => !this.ctrl.touchIds.has(id))) {
      this.state._active = false;
      this.compute(event);
      this.emit();
    }
  }
  pointerEnd(event) {
    const state = this.state;
    this.ctrl.setEventIds(event);
    try {
      event.target.releasePointerCapture(event.pointerId);
    } catch (_unused) {
    }
    if (state._pointerEvents.has(event.pointerId)) {
      state._pointerEvents.delete(event.pointerId);
    }
    if (!state._active)
      return;
    if (state._pointerEvents.size < 2) {
      state._active = false;
      this.compute(event);
      this.emit();
    }
  }
  gestureStart(event) {
    if (event.cancelable)
      event.preventDefault();
    const state = this.state;
    if (state._active)
      return;
    this.start(event);
    this.computeValues([event.scale, event.rotation]);
    state.origin = [event.clientX, event.clientY];
    this.compute(event);
    this.emit();
  }
  gestureMove(event) {
    if (event.cancelable)
      event.preventDefault();
    if (!this.state._active)
      return;
    const state = this.state;
    this.computeValues([event.scale, event.rotation]);
    state.origin = [event.clientX, event.clientY];
    const _previousMovement = state._movement;
    state._movement = [event.scale - 1, event.rotation];
    state._delta = V.sub(state._movement, _previousMovement);
    this.compute(event);
    this.emit();
  }
  gestureEnd(event) {
    if (!this.state._active)
      return;
    this.state._active = false;
    this.compute(event);
    this.emit();
  }
  wheel(event) {
    const modifierKey = this.config.modifierKey;
    if (modifierKey && (Array.isArray(modifierKey) ? !modifierKey.find((k) => event[k]) : !event[modifierKey]))
      return;
    if (!this.state._active)
      this.wheelStart(event);
    else
      this.wheelChange(event);
    this.timeoutStore.add("wheelEnd", this.wheelEnd.bind(this));
  }
  wheelStart(event) {
    this.start(event);
    this.wheelChange(event);
  }
  wheelChange(event) {
    const isR3f = "uv" in event;
    if (!isR3f) {
      if (event.cancelable) {
        event.preventDefault();
      }
      if (!event.defaultPrevented) {
        console.warn(`[@use-gesture]: To properly support zoom on trackpads, try using the \`target\` option.

This message will only appear in development mode.`);
      }
    }
    const state = this.state;
    state._delta = [-wheelValues(event)[1] / PINCH_WHEEL_RATIO * state.offset[0], 0];
    V.addTo(state._movement, state._delta);
    clampStateInternalMovementToBounds(state);
    this.state.origin = [event.clientX, event.clientY];
    this.compute(event);
    this.emit();
  }
  wheelEnd() {
    if (!this.state._active)
      return;
    this.state._active = false;
    this.compute();
    this.emit();
  }
  bind(bindFunction) {
    const device = this.config.device;
    if (!!device) {
      bindFunction(device, "start", this[device + "Start"].bind(this));
      bindFunction(device, "change", this[device + "Move"].bind(this));
      bindFunction(device, "end", this[device + "End"].bind(this));
      bindFunction(device, "cancel", this[device + "End"].bind(this));
      bindFunction("lostPointerCapture", "", this[device + "End"].bind(this));
    }
    if (this.config.pinchOnWheel) {
      bindFunction("wheel", "", this.wheel.bind(this), {
        passive: false
      });
    }
  }
};
var pinchConfigResolver = _objectSpread2(_objectSpread2({}, commonConfigResolver), {}, {
  device(_v, _k, {
    shared,
    pointer: {
      touch = false
    } = {}
  }) {
    const sharedConfig = shared;
    if (sharedConfig.target && !SUPPORT.touch && SUPPORT.gesture)
      return "gesture";
    if (SUPPORT.touch && touch)
      return "touch";
    if (SUPPORT.touchscreen) {
      if (SUPPORT.pointer)
        return "pointer";
      if (SUPPORT.touch)
        return "touch";
    }
  },
  bounds(_v, _k, {
    scaleBounds = {},
    angleBounds = {}
  }) {
    const _scaleBounds = (state) => {
      const D = assignDefault(call(scaleBounds, state), {
        min: -Infinity,
        max: Infinity
      });
      return [D.min, D.max];
    };
    const _angleBounds = (state) => {
      const A = assignDefault(call(angleBounds, state), {
        min: -Infinity,
        max: Infinity
      });
      return [A.min, A.max];
    };
    if (typeof scaleBounds !== "function" && typeof angleBounds !== "function")
      return [_scaleBounds(), _angleBounds()];
    return (state) => [_scaleBounds(state), _angleBounds(state)];
  },
  threshold(value, _k, config) {
    this.lockDirection = config.axis === "lock";
    const threshold = V.toVector(value, this.lockDirection ? [0.1, 3] : 0);
    return threshold;
  },
  modifierKey(value) {
    if (value === void 0)
      return "ctrlKey";
    return value;
  },
  pinchOnWheel(value = true) {
    return value;
  }
});
var moveConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
  mouseOnly: (value = true) => value
});
var WheelEngine = class extends CoordinatesEngine {
  constructor(...args) {
    super(...args);
    _defineProperty(this, "ingKey", "wheeling");
  }
  wheel(event) {
    if (!this.state._active)
      this.start(event);
    this.wheelChange(event);
    this.timeoutStore.add("wheelEnd", this.wheelEnd.bind(this));
  }
  wheelChange(event) {
    const state = this.state;
    state._delta = wheelValues(event);
    V.addTo(state._movement, state._delta);
    clampStateInternalMovementToBounds(state);
    this.compute(event);
    this.emit();
  }
  wheelEnd() {
    if (!this.state._active)
      return;
    this.state._active = false;
    this.compute();
    this.emit();
  }
  bind(bindFunction) {
    bindFunction("wheel", "", this.wheel.bind(this));
  }
};
var wheelConfigResolver = coordinatesConfigResolver;
var hoverConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
  mouseOnly: (value = true) => value
});
var EngineMap = /* @__PURE__ */ new Map();
var ConfigResolverMap = /* @__PURE__ */ new Map();
function registerAction(action) {
  EngineMap.set(action.key, action.engine);
  ConfigResolverMap.set(action.key, action.resolver);
}
var pinchAction = {
  key: "pinch",
  engine: PinchEngine,
  resolver: pinchConfigResolver
};
var wheelAction = {
  key: "wheel",
  engine: WheelEngine,
  resolver: wheelConfigResolver
};

// node_modules/.deno/@use-gesture+react@10.3.1/node_modules/@use-gesture/react/dist/use-gesture-react.esm.js
var import_react21 = __toESM(require_react());

// node_modules/.deno/@use-gesture+core@10.3.1/node_modules/@use-gesture/core/dist/use-gesture-core.esm.js
function _objectWithoutPropertiesLoose(source, excluded) {
  if (source == null)
    return {};
  var target = {};
  var sourceKeys = Object.keys(source);
  var key, i;
  for (i = 0; i < sourceKeys.length; i++) {
    key = sourceKeys[i];
    if (excluded.indexOf(key) >= 0)
      continue;
    target[key] = source[key];
  }
  return target;
}
function _objectWithoutProperties(source, excluded) {
  if (source == null)
    return {};
  var target = _objectWithoutPropertiesLoose(source, excluded);
  var key, i;
  if (Object.getOwnPropertySymbols) {
    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
    for (i = 0; i < sourceSymbolKeys.length; i++) {
      key = sourceSymbolKeys[i];
      if (excluded.indexOf(key) >= 0)
        continue;
      if (!Object.prototype.propertyIsEnumerable.call(source, key))
        continue;
      target[key] = source[key];
    }
  }
  return target;
}
var sharedConfigResolver = {
  target(value) {
    if (value) {
      return () => "current" in value ? value.current : value;
    }
    return void 0;
  },
  enabled(value = true) {
    return value;
  },
  window(value = SUPPORT.isBrowser ? window : void 0) {
    return value;
  },
  eventOptions({
    passive = true,
    capture = false
  } = {}) {
    return {
      passive,
      capture
    };
  },
  transform(value) {
    return value;
  }
};
var _excluded = ["target", "eventOptions", "window", "enabled", "transform"];
function resolveWith(config = {}, resolvers) {
  const result = {};
  for (const [key, resolver] of Object.entries(resolvers)) {
    switch (typeof resolver) {
      case "function":
        if (true) {
          const r = resolver.call(result, config[key], key, config);
          if (!Number.isNaN(r))
            result[key] = r;
        } else {
          result[key] = resolver.call(result, config[key], key, config);
        }
        break;
      case "object":
        result[key] = resolveWith(config[key], resolver);
        break;
      case "boolean":
        if (resolver)
          result[key] = config[key];
        break;
    }
  }
  return result;
}
function parse(newConfig, gestureKey, _config = {}) {
  const _ref = newConfig, {
    target,
    eventOptions,
    window: window3,
    enabled,
    transform
  } = _ref, rest = _objectWithoutProperties(_ref, _excluded);
  _config.shared = resolveWith({
    target,
    eventOptions,
    window: window3,
    enabled,
    transform
  }, sharedConfigResolver);
  if (gestureKey) {
    const resolver = ConfigResolverMap.get(gestureKey);
    _config[gestureKey] = resolveWith(_objectSpread2({
      shared: _config.shared
    }, rest), resolver);
  } else {
    for (const key in rest) {
      const resolver = ConfigResolverMap.get(key);
      if (resolver) {
        _config[key] = resolveWith(_objectSpread2({
          shared: _config.shared
        }, rest[key]), resolver);
      } else if (true) {
        if (!["drag", "pinch", "scroll", "wheel", "move", "hover"].includes(key)) {
          if (key === "domTarget") {
            throw Error(`[@use-gesture]: \`domTarget\` option has been renamed to \`target\`.`);
          }
          console.warn(`[@use-gesture]: Unknown config key \`${key}\` was used. Please read the documentation for further information.`);
        }
      }
    }
  }
  return _config;
}
var EventStore = class {
  constructor(ctrl, gestureKey) {
    _defineProperty(this, "_listeners", /* @__PURE__ */ new Set());
    this._ctrl = ctrl;
    this._gestureKey = gestureKey;
  }
  add(element, device, action, handler, options) {
    const listeners = this._listeners;
    const type = toDomEventType(device, action);
    const _options = this._gestureKey ? this._ctrl.config[this._gestureKey].eventOptions : {};
    const eventOptions = _objectSpread2(_objectSpread2({}, _options), options);
    element.addEventListener(type, handler, eventOptions);
    const remove2 = () => {
      element.removeEventListener(type, handler, eventOptions);
      listeners.delete(remove2);
    };
    listeners.add(remove2);
    return remove2;
  }
  clean() {
    this._listeners.forEach((remove2) => remove2());
    this._listeners.clear();
  }
};
var TimeoutStore = class {
  constructor() {
    _defineProperty(this, "_timeouts", /* @__PURE__ */ new Map());
  }
  add(key, callback, ms = 140, ...args) {
    this.remove(key);
    this._timeouts.set(key, window.setTimeout(callback, ms, ...args));
  }
  remove(key) {
    const timeout = this._timeouts.get(key);
    if (timeout)
      window.clearTimeout(timeout);
  }
  clean() {
    this._timeouts.forEach((timeout) => void window.clearTimeout(timeout));
    this._timeouts.clear();
  }
};
var Controller = class {
  constructor(handlers) {
    _defineProperty(this, "gestures", /* @__PURE__ */ new Set());
    _defineProperty(this, "_targetEventStore", new EventStore(this));
    _defineProperty(this, "gestureEventStores", {});
    _defineProperty(this, "gestureTimeoutStores", {});
    _defineProperty(this, "handlers", {});
    _defineProperty(this, "config", {});
    _defineProperty(this, "pointerIds", /* @__PURE__ */ new Set());
    _defineProperty(this, "touchIds", /* @__PURE__ */ new Set());
    _defineProperty(this, "state", {
      shared: {
        shiftKey: false,
        metaKey: false,
        ctrlKey: false,
        altKey: false
      }
    });
    resolveGestures(this, handlers);
  }
  setEventIds(event) {
    if (isTouch(event)) {
      this.touchIds = new Set(touchIds(event));
      return this.touchIds;
    } else if ("pointerId" in event) {
      if (event.type === "pointerup" || event.type === "pointercancel")
        this.pointerIds.delete(event.pointerId);
      else if (event.type === "pointerdown")
        this.pointerIds.add(event.pointerId);
      return this.pointerIds;
    }
  }
  applyHandlers(handlers, nativeHandlers) {
    this.handlers = handlers;
    this.nativeHandlers = nativeHandlers;
  }
  applyConfig(config, gestureKey) {
    this.config = parse(config, gestureKey, this.config);
  }
  clean() {
    this._targetEventStore.clean();
    for (const key of this.gestures) {
      this.gestureEventStores[key].clean();
      this.gestureTimeoutStores[key].clean();
    }
  }
  effect() {
    if (this.config.shared.target)
      this.bind();
    return () => this._targetEventStore.clean();
  }
  bind(...args) {
    const sharedConfig = this.config.shared;
    const props = {};
    let target;
    if (sharedConfig.target) {
      target = sharedConfig.target();
      if (!target)
        return;
    }
    if (sharedConfig.enabled) {
      for (const gestureKey of this.gestures) {
        const gestureConfig = this.config[gestureKey];
        const bindFunction = bindToProps(props, gestureConfig.eventOptions, !!target);
        if (gestureConfig.enabled) {
          const Engine2 = EngineMap.get(gestureKey);
          new Engine2(this, args, gestureKey).bind(bindFunction);
        }
      }
      const nativeBindFunction = bindToProps(props, sharedConfig.eventOptions, !!target);
      for (const eventKey in this.nativeHandlers) {
        nativeBindFunction(eventKey, "", (event) => this.nativeHandlers[eventKey](_objectSpread2(_objectSpread2({}, this.state.shared), {}, {
          event,
          args
        })), void 0, true);
      }
    }
    for (const handlerProp in props) {
      props[handlerProp] = chain(...props[handlerProp]);
    }
    if (!target)
      return props;
    for (const handlerProp in props) {
      const {
        device,
        capture,
        passive
      } = parseProp(handlerProp);
      this._targetEventStore.add(target, device, "", props[handlerProp], {
        capture,
        passive
      });
    }
  }
};
function setupGesture(ctrl, gestureKey) {
  ctrl.gestures.add(gestureKey);
  ctrl.gestureEventStores[gestureKey] = new EventStore(ctrl, gestureKey);
  ctrl.gestureTimeoutStores[gestureKey] = new TimeoutStore();
}
function resolveGestures(ctrl, internalHandlers) {
  if (internalHandlers.drag)
    setupGesture(ctrl, "drag");
  if (internalHandlers.wheel)
    setupGesture(ctrl, "wheel");
  if (internalHandlers.scroll)
    setupGesture(ctrl, "scroll");
  if (internalHandlers.move)
    setupGesture(ctrl, "move");
  if (internalHandlers.pinch)
    setupGesture(ctrl, "pinch");
  if (internalHandlers.hover)
    setupGesture(ctrl, "hover");
}
var bindToProps = (props, eventOptions, withPassiveOption) => (device, action, handler, options = {}, isNative = false) => {
  var _options$capture, _options$passive;
  const capture = (_options$capture = options.capture) !== null && _options$capture !== void 0 ? _options$capture : eventOptions.capture;
  const passive = (_options$passive = options.passive) !== null && _options$passive !== void 0 ? _options$passive : eventOptions.passive;
  let handlerProp = isNative ? device : toHandlerProp(device, action, capture);
  if (withPassiveOption && passive)
    handlerProp += "Passive";
  props[handlerProp] = props[handlerProp] || [];
  props[handlerProp].push(handler);
};
var RE_NOT_NATIVE = /^on(Drag|Wheel|Scroll|Move|Pinch|Hover)/;
function sortHandlers(_handlers2) {
  const native = {};
  const handlers = {};
  const actions = /* @__PURE__ */ new Set();
  for (let key in _handlers2) {
    if (RE_NOT_NATIVE.test(key)) {
      actions.add(RegExp.lastMatch);
      handlers[key] = _handlers2[key];
    } else {
      native[key] = _handlers2[key];
    }
  }
  return [handlers, native, actions];
}
function registerGesture(actions, handlers, handlerKey, key, internalHandlers, config) {
  if (!actions.has(handlerKey))
    return;
  if (!EngineMap.has(key)) {
    if (true) {
      console.warn(`[@use-gesture]: You've created a custom handler that that uses the \`${key}\` gesture but isn't properly configured.

Please add \`${key}Action\` when creating your handler.`);
    }
    return;
  }
  const startKey = handlerKey + "Start";
  const endKey = handlerKey + "End";
  const fn = (state) => {
    let memo32 = void 0;
    if (state.first && startKey in handlers)
      handlers[startKey](state);
    if (handlerKey in handlers)
      memo32 = handlers[handlerKey](state);
    if (state.last && endKey in handlers)
      handlers[endKey](state);
    return memo32;
  };
  internalHandlers[key] = fn;
  config[key] = config[key] || {};
}
function parseMergedHandlers(mergedHandlers, mergedConfig) {
  const [handlers, nativeHandlers, actions] = sortHandlers(mergedHandlers);
  const internalHandlers = {};
  registerGesture(actions, handlers, "onDrag", "drag", internalHandlers, mergedConfig);
  registerGesture(actions, handlers, "onWheel", "wheel", internalHandlers, mergedConfig);
  registerGesture(actions, handlers, "onScroll", "scroll", internalHandlers, mergedConfig);
  registerGesture(actions, handlers, "onPinch", "pinch", internalHandlers, mergedConfig);
  registerGesture(actions, handlers, "onMove", "move", internalHandlers, mergedConfig);
  registerGesture(actions, handlers, "onHover", "hover", internalHandlers, mergedConfig);
  return {
    handlers: internalHandlers,
    config: mergedConfig,
    nativeHandlers
  };
}

// node_modules/.deno/@use-gesture+react@10.3.1/node_modules/@use-gesture/react/dist/use-gesture-react.esm.js
function useRecognizers(handlers, config = {}, gestureKey, nativeHandlers) {
  const ctrl = import_react21.default.useMemo(() => new Controller(handlers), []);
  ctrl.applyHandlers(handlers, nativeHandlers);
  ctrl.applyConfig(config, gestureKey);
  import_react21.default.useEffect(ctrl.effect.bind(ctrl));
  import_react21.default.useEffect(() => {
    return ctrl.clean.bind(ctrl);
  }, []);
  if (config.target === void 0) {
    return ctrl.bind.bind(ctrl);
  }
  return void 0;
}
function createUseGesture(actions) {
  actions.forEach(registerAction);
  return function useGesture2(_handlers2, _config) {
    const {
      handlers,
      nativeHandlers,
      config
    } = parseMergedHandlers(_handlers2, _config || {});
    return useRecognizers(handlers, config, void 0, nativeHandlers);
  };
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useGestureEvents.mjs
var React8 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/normalizeWheel.mjs
var MAX_ZOOM_STEP = 10;
var IS_DARWIN = /Mac|iPod|iPhone|iPad/.test(
  typeof window === "undefined" ? "node" : window.navigator.platform
);
function normalizeWheel(event) {
  let { deltaY, deltaX } = event;
  let deltaZ = 0;
  if (event.ctrlKey || event.altKey || event.metaKey) {
    const signY = Math.sign(event.deltaY);
    const absDeltaY = Math.abs(event.deltaY);
    let dy = deltaY;
    if (absDeltaY > MAX_ZOOM_STEP) {
      dy = MAX_ZOOM_STEP * signY;
    }
    deltaZ = dy / 100;
  } else {
    if (event.shiftKey && !IS_DARWIN) {
      deltaX = deltaY;
      deltaY = 0;
    }
  }
  return { x: -deltaX, y: -deltaY, z: -deltaZ };
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useGestureEvents.mjs
var useGesture = createUseGesture([wheelAction, pinchAction]);
var lastWheelTime = void 0;
var isWheelEndEvent = (time) => {
  if (lastWheelTime === void 0) {
    lastWheelTime = time;
    return false;
  }
  if (time - lastWheelTime > 120 && time - lastWheelTime < 160) {
    lastWheelTime = time;
    return true;
  }
  lastWheelTime = time;
  return false;
};
function useGestureEvents(ref) {
  const editor = useEditor();
  const events = React8.useMemo(() => {
    let pinchState = "not sure";
    const onWheel = ({ event }) => {
      if (!editor.instanceState.isFocused) {
        return;
      }
      pinchState = "not sure";
      if (isWheelEndEvent(Date.now())) {
        return;
      }
      if (editor.editingShapeId) {
        const shape = editor.getShape(editor.editingShapeId);
        if (shape) {
          const util = editor.getShapeUtil(shape);
          if (util.canScroll(shape)) {
            const bounds = editor.getShapePageBounds(editor.editingShapeId);
            if (bounds?.containsPoint(editor.inputs.currentPagePoint)) {
              return;
            }
          }
        }
      }
      preventDefault(event);
      const delta = normalizeWheel(event);
      if (delta.x === 0 && delta.y === 0)
        return;
      const info = {
        type: "wheel",
        name: "wheel",
        delta,
        shiftKey: event.shiftKey,
        altKey: event.altKey,
        ctrlKey: event.metaKey || event.ctrlKey
      };
      editor.dispatch(info);
    };
    let initDistanceBetweenFingers = 1;
    let initZoom = 1;
    let currZoom = 1;
    let currDistanceBetweenFingers = 0;
    const initPointBetweenFingers = new Vec2d();
    const prevPointBetweenFingers = new Vec2d();
    const onPinchStart = (gesture) => {
      const elm = ref.current;
      pinchState = "not sure";
      const { event, origin, da } = gesture;
      if (event instanceof WheelEvent)
        return;
      if (!(event.target === elm || elm?.contains(event.target)))
        return;
      prevPointBetweenFingers.x = origin[0];
      prevPointBetweenFingers.y = origin[1];
      initPointBetweenFingers.x = origin[0];
      initPointBetweenFingers.y = origin[1];
      initDistanceBetweenFingers = da[0];
      initZoom = editor.zoomLevel;
      editor.dispatch({
        type: "pinch",
        name: "pinch_start",
        point: { x: origin[0], y: origin[1], z: editor.zoomLevel },
        delta: { x: 0, y: 0 },
        shiftKey: event.shiftKey,
        altKey: event.altKey,
        ctrlKey: event.metaKey || event.ctrlKey
      });
    };
    const updatePinchState = (isSafariTrackpadPinch) => {
      if (isSafariTrackpadPinch) {
        pinchState = "zooming";
      }
      if (pinchState === "zooming") {
        return;
      }
      const touchDistance = Math.abs(currDistanceBetweenFingers - initDistanceBetweenFingers);
      const originDistance = Vec2d.Dist(initPointBetweenFingers, prevPointBetweenFingers);
      switch (pinchState) {
        case "not sure": {
          if (touchDistance > 24) {
            pinchState = "zooming";
          } else if (originDistance > 16) {
            pinchState = "panning";
          }
          break;
        }
        case "panning": {
          if (touchDistance > 64) {
            pinchState = "zooming";
          }
          break;
        }
      }
    };
    const onPinch = (gesture) => {
      const elm = ref.current;
      const { event, origin, offset: offset2, da } = gesture;
      if (event instanceof WheelEvent)
        return;
      if (!(event.target === elm || elm?.contains(event.target)))
        return;
      const isSafariTrackpadPinch = gesture.type === "gesturechange" || gesture.type === "gestureend";
      currDistanceBetweenFingers = da[0];
      const dx = origin[0] - prevPointBetweenFingers.x;
      const dy = origin[1] - prevPointBetweenFingers.y;
      prevPointBetweenFingers.x = origin[0];
      prevPointBetweenFingers.y = origin[1];
      updatePinchState(isSafariTrackpadPinch);
      switch (pinchState) {
        case "zooming": {
          currZoom = offset2[0];
          editor.dispatch({
            type: "pinch",
            name: "pinch",
            point: { x: origin[0], y: origin[1], z: currZoom },
            delta: { x: dx, y: dy },
            shiftKey: event.shiftKey,
            altKey: event.altKey,
            ctrlKey: event.metaKey || event.ctrlKey
          });
          break;
        }
        case "panning": {
          editor.dispatch({
            type: "pinch",
            name: "pinch",
            point: { x: origin[0], y: origin[1], z: initZoom },
            delta: { x: dx, y: dy },
            shiftKey: event.shiftKey,
            altKey: event.altKey,
            ctrlKey: event.metaKey || event.ctrlKey
          });
          break;
        }
      }
    };
    const onPinchEnd = (gesture) => {
      const elm = ref.current;
      const { event, origin, offset: offset2 } = gesture;
      if (event instanceof WheelEvent)
        return;
      if (!(event.target === elm || elm?.contains(event.target)))
        return;
      const scale = offset2[0];
      pinchState = "not sure";
      requestAnimationFrame(() => {
        editor.dispatch({
          type: "pinch",
          name: "pinch_end",
          point: { x: origin[0], y: origin[1], z: scale },
          delta: { x: origin[0], y: origin[1] },
          shiftKey: event.shiftKey,
          altKey: event.altKey,
          ctrlKey: event.metaKey || event.ctrlKey
        });
      });
    };
    return {
      onWheel,
      onPinchStart,
      onPinchEnd,
      onPinch
    };
  }, [editor, ref]);
  useGesture(events, {
    target: ref,
    eventOptions: { passive: false },
    pinch: {
      from: () => [editor.zoomLevel, 0],
      // Return the camera z to use when pinch starts
      scaleBounds: () => {
        return { from: editor.zoomLevel, max: 8, min: 0.05 };
      }
    }
  });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useHandleEvents.mjs
var React9 = __toESM(require_react(), 1);
function getHandle(editor, id, handleId) {
  const shape = editor.getShape(id);
  const handles = editor.getShapeHandles(shape);
  return { shape, handle: handles.find((h) => h.id === handleId) };
}
function useHandleEvents(id, handleId) {
  const editor = useEditor();
  return React9.useMemo(() => {
    const onPointerDown = (e) => {
      if (e.isKilled)
        return;
      const target = loopToHtmlElement(e.currentTarget);
      setPointerCapture(target, e);
      const { shape, handle } = getHandle(editor, id, handleId);
      if (!handle)
        return;
      editor.dispatch({
        type: "pointer",
        target: "handle",
        handle,
        shape,
        name: "pointer_down",
        ...getPointerInfo(e)
      });
    };
    let lastX, lastY;
    const onPointerMove = (e) => {
      if (e.isKilled)
        return;
      if (e.clientX === lastX && e.clientY === lastY)
        return;
      lastX = e.clientX;
      lastY = e.clientY;
      const { shape, handle } = getHandle(editor, id, handleId);
      if (!handle)
        return;
      editor.dispatch({
        type: "pointer",
        target: "handle",
        handle,
        shape,
        name: "pointer_move",
        ...getPointerInfo(e)
      });
    };
    const onPointerUp = (e) => {
      if (e.isKilled)
        return;
      const target = loopToHtmlElement(e.currentTarget);
      releasePointerCapture(target, e);
      const { shape, handle } = getHandle(editor, id, handleId);
      if (!handle)
        return;
      editor.dispatch({
        type: "pointer",
        target: "handle",
        handle,
        shape,
        name: "pointer_up",
        ...getPointerInfo(e)
      });
    };
    return {
      onPointerDown,
      onPointerMove,
      onPointerUp
    };
  }, [editor, id, handleId]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useScreenBounds.mjs
var import_lodash2 = __toESM(require_lodash2(), 1);
var import_react23 = __toESM(require_react(), 1);
function useScreenBounds() {
  const editor = useEditor();
  (0, import_react23.useLayoutEffect)(() => {
    const updateBounds = (0, import_lodash2.default)(
      () => {
        editor.updateViewportScreenBounds();
      },
      200,
      {
        trailing: true
      }
    );
    editor.updateViewportScreenBounds();
    const interval = setInterval(updateBounds, 1e3);
    window.addEventListener("resize", updateBounds);
    window.addEventListener("scroll", updateBounds);
    return () => {
      clearInterval(interval);
      window.removeEventListener("resize", updateBounds);
      window.removeEventListener("scroll", updateBounds);
    };
  }, [editor]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/Matrix2d.mjs
var Matrix2d = class _Matrix2d {
  constructor(a, b, c, d, e, f) {
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
    this.e = e;
    this.f = f;
  }
  a = 1;
  b = 0;
  c = 0;
  d = 1;
  e = 0;
  f = 0;
  equals(m) {
    return this.a === m.a && this.b === m.b && this.c === m.c && this.d === m.d && this.e === m.e && this.f === m.f;
  }
  identity() {
    this.a = 1;
    this.b = 0;
    this.c = 0;
    this.d = 1;
    this.e = 0;
    this.f = 0;
    return this;
  }
  multiply(m) {
    const m2 = m;
    const { a, b, c, d, e, f } = this;
    this.a = a * m2.a + c * m2.b;
    this.c = a * m2.c + c * m2.d;
    this.e = a * m2.e + c * m2.f + e;
    this.b = b * m2.a + d * m2.b;
    this.d = b * m2.c + d * m2.d;
    this.f = b * m2.e + d * m2.f + f;
    return this;
  }
  rotate(r, cx, cy) {
    if (r === 0)
      return this;
    if (cx === void 0)
      return this.multiply(_Matrix2d.Rotate(r));
    return this.translate(cx, cy).multiply(_Matrix2d.Rotate(r)).translate(-cx, -cy);
  }
  translate(x, y) {
    return this.multiply(_Matrix2d.Translate(x, y));
  }
  scale(x, y) {
    return this.multiply(_Matrix2d.Scale(x, y));
  }
  invert() {
    const { a, b, c, d, e, f } = this;
    const denom = a * d - b * c;
    this.a = d / denom;
    this.b = b / -denom;
    this.c = c / -denom;
    this.d = a / denom;
    this.e = (d * e - c * f) / -denom;
    this.f = (b * e - a * f) / denom;
    return this;
  }
  applyToPoint(point) {
    return _Matrix2d.applyToPoint(this, point);
  }
  applyToPoints(points) {
    return _Matrix2d.applyToPoints(this, points);
  }
  rotation() {
    return _Matrix2d.Rotation(this);
  }
  point() {
    return _Matrix2d.Point(this);
  }
  decomposed() {
    return _Matrix2d.Decompose(this);
  }
  toCssString() {
    return _Matrix2d.toCssString(this);
  }
  setTo(model2) {
    Object.assign(this, model2);
    return this;
  }
  decompose() {
    return _Matrix2d.Decompose(this);
  }
  clone() {
    return new _Matrix2d(this.a, this.b, this.c, this.d, this.e, this.f);
  }
  /* --------------------- Static --------------------- */
  static Identity() {
    return new _Matrix2d(1, 0, 0, 1, 0, 0);
  }
  static Translate(x, y) {
    return new _Matrix2d(1, 0, 0, 1, x, y);
  }
  static Rotate(r, cx, cy) {
    if (r === 0)
      return _Matrix2d.Identity();
    const cosAngle = Math.cos(r);
    const sinAngle = Math.sin(r);
    const rotationMatrix2d = new _Matrix2d(cosAngle, sinAngle, -sinAngle, cosAngle, 0, 0);
    if (cx === void 0)
      return rotationMatrix2d;
    return _Matrix2d.Compose(
      _Matrix2d.Translate(cx, cy),
      rotationMatrix2d,
      _Matrix2d.Translate(-cx, -cy)
    );
  }
  static Scale = (x, y, cx, cy) => {
    const scaleMatrix2d = new _Matrix2d(x, 0, 0, 0, y, 0);
    if (cx === void 0)
      return scaleMatrix2d;
    return _Matrix2d.Compose(
      _Matrix2d.Translate(cx, cy),
      scaleMatrix2d,
      _Matrix2d.Translate(-cx, -cy)
    );
  };
  static Multiply(m1, m2) {
    return {
      a: m1.a * m2.a + m1.c * m2.b,
      c: m1.a * m2.c + m1.c * m2.d,
      e: m1.a * m2.e + m1.c * m2.f + m1.e,
      b: m1.b * m2.a + m1.d * m2.b,
      d: m1.b * m2.c + m1.d * m2.d,
      f: m1.b * m2.e + m1.d * m2.f + m1.f
    };
  }
  static Inverse(m) {
    const denom = m.a * m.d - m.b * m.c;
    return {
      a: m.d / denom,
      b: m.b / -denom,
      c: m.c / -denom,
      d: m.a / denom,
      e: (m.d * m.e - m.c * m.f) / -denom,
      f: (m.b * m.e - m.a * m.f) / denom
    };
  }
  static Absolute(m) {
    const denom = m.a * m.d - m.b * m.c;
    return {
      a: m.d / denom,
      b: m.b / -denom,
      c: m.c / -denom,
      d: m.a / denom,
      e: (m.d * m.e - m.c * m.f) / denom,
      f: (m.b * m.e - m.a * m.f) / -denom
    };
  }
  static Compose(...matrices) {
    const matrix = _Matrix2d.Identity();
    for (let i = 0, n = matrices.length; i < n; i++) {
      matrix.multiply(matrices[i]);
    }
    return matrix;
  }
  static Point(m) {
    return new Vec2d(m.e, m.f);
  }
  static Rotation(m) {
    let rotation;
    if (m.a !== 0 || m.c !== 0) {
      const hypotAc = Math.hypot(m.a, m.c);
      rotation = Math.acos(m.a / hypotAc) * (m.c > 0 ? -1 : 1);
    } else if (m.b !== 0 || m.d !== 0) {
      const hypotBd = Math.hypot(m.b, m.d);
      rotation = TAU + Math.acos(m.b / hypotBd) * (m.d > 0 ? -1 : 1);
    } else {
      rotation = 0;
    }
    return clampRadians(rotation);
  }
  static Decompose(m) {
    let scaleX, scaleY, rotation;
    if (m.a !== 0 || m.c !== 0) {
      const hypotAc = Math.hypot(m.a, m.c);
      scaleX = hypotAc;
      scaleY = (m.a * m.d - m.b * m.c) / hypotAc;
      rotation = Math.acos(m.a / hypotAc) * (m.c > 0 ? -1 : 1);
    } else if (m.b !== 0 || m.d !== 0) {
      const hypotBd = Math.hypot(m.b, m.d);
      scaleX = (m.a * m.d - m.b * m.c) / hypotBd;
      scaleY = hypotBd;
      rotation = TAU + Math.acos(m.b / hypotBd) * (m.d > 0 ? -1 : 1);
    } else {
      scaleX = 0;
      scaleY = 0;
      rotation = 0;
    }
    return {
      x: m.e,
      y: m.f,
      scaleX,
      scaleY,
      rotation: clampRadians(rotation)
    };
  }
  static Smooth(m, precision = 1e10) {
    m.a = Math.round(m.a * precision) / precision;
    m.b = Math.round(m.b * precision) / precision;
    m.c = Math.round(m.c * precision) / precision;
    m.d = Math.round(m.d * precision) / precision;
    m.e = Math.round(m.e * precision) / precision;
    m.f = Math.round(m.f * precision) / precision;
    return m;
  }
  static toCssString(m) {
    return `matrix(${toDomPrecision(m.a)}, ${toDomPrecision(m.b)}, ${toDomPrecision(
      m.c
    )}, ${toDomPrecision(m.d)}, ${toDomPrecision(m.e)}, ${toDomPrecision(m.f)})`;
  }
  static applyToPoint(m, point) {
    return new Vec2d(
      m.a * point.x + m.c * point.y + m.e,
      m.b * point.x + m.d * point.y + m.f,
      point.z
    );
  }
  static applyToXY(m, x, y) {
    return [m.a * x + m.c * y + m.e, m.b * x + m.d * y + m.f];
  }
  static applyToPoints(m, points) {
    return points.map(
      (point) => new Vec2d(m.a * point.x + m.c * point.y + m.e, m.b * point.x + m.d * point.y + m.f, point.z)
    );
  }
  static applyToBounds(m, box) {
    return new Box2d(m.e + box.minX, m.f + box.minY, box.width, box.height);
  }
  static From(m) {
    return new _Matrix2d(m.a, m.b, m.c, m.d, m.e, m.f);
  }
  static Cast(m) {
    return m instanceof _Matrix2d ? m : _Matrix2d.From(m);
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/GeometryDebuggingView.mjs
var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
var import_react24 = __toESM(require_react(), 1);
function useTick(isEnabled = true) {
  const [_, setTick] = (0, import_react24.useState)(0);
  const editor = useEditor();
  (0, import_react24.useEffect)(() => {
    if (!isEnabled)
      return;
    const update = () => setTick((tick2) => tick2 + 1);
    editor.on("tick", update);
    return () => {
      editor.off("tick", update);
    };
  }, [editor, isEnabled]);
}
var GeometryDebuggingView = track(function GeometryDebuggingView2({
  showStroke = true,
  showVertices = true,
  showClosestPointOnOutline = true
}) {
  const editor = useEditor();
  useTick(showClosestPointOnOutline);
  const {
    zoomLevel,
    renderingShapes,
    inputs: { currentPagePoint }
  } = editor;
  return (0, import_jsx_runtime21.jsx)(
    "svg",
    {
      style: {
        position: "absolute",
        pointerEvents: "none",
        zIndex: 999999999,
        top: 0,
        left: 0,
        overflow: "visible"
      },
      children: renderingShapes.map((result) => {
        const shape = editor.getShape(result.id);
        if (shape.type === "group")
          return null;
        const geometry = editor.getShapeGeometry(shape);
        const pageTransform = editor.getShapePageTransform(shape);
        const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint);
        const nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace);
        const distanceToPoint = geometry.distanceToPoint(pointInShapeSpace, true);
        const dist = Math.abs(distanceToPoint) * zoomLevel;
        const hitInside = distanceToPoint < 0;
        const { vertices } = geometry;
        return (0, import_jsx_runtime21.jsxs)(
          "g",
          {
            transform: pageTransform.toCssString(),
            strokeLinecap: "round",
            strokeLinejoin: "round",
            children: [
              showStroke && (0, import_jsx_runtime21.jsx)(
                "path",
                {
                  stroke: "red",
                  strokeWidth: "2",
                  fill: "none",
                  opacity: "1",
                  d: geometry.toSimpleSvgPath()
                }
              ),
              showVertices && vertices.map((v, i) => (0, import_jsx_runtime21.jsx)(
                "circle",
                {
                  cx: v.x,
                  cy: v.y,
                  r: "2",
                  fill: `hsl(${modulate(i, [0, vertices.length - 1], [120, 200])}, 100%, 50%)`,
                  stroke: "black",
                  strokeWidth: "1"
                },
                `v${i}`
              )),
              showClosestPointOnOutline && dist < 150 && (0, import_jsx_runtime21.jsx)(
                "line",
                {
                  x1: nearestPointOnShape.x,
                  y1: nearestPointOnShape.y,
                  x2: pointInShapeSpace.x,
                  y2: pointInShapeSpace.y,
                  opacity: 1 - dist / 150,
                  stroke: hitInside ? "goldenrod" : "dodgerblue",
                  strokeWidth: "2"
                }
              )
            ]
          },
          result.id + "_outline"
        );
      })
    }
  );
});

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/LiveCollaborators.mjs
var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
var import_react27 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/usePeerIds.mjs
var import_react25 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/uniq.mjs
var import_lodash3 = __toESM(require_lodash3(), 1);
function uniq(array2) {
  return (0, import_lodash3.default)(array2);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/usePeerIds.mjs
function usePeerIds() {
  const editor = useEditor();
  const $presences = (0, import_react25.useMemo)(() => {
    return editor.store.query.records("instance_presence", () => ({
      userId: { neq: editor.user.id }
    }));
  }, [editor]);
  const $userIds = useComputed(
    "userIds",
    () => uniq($presences.value.map((p) => p.userId)).sort(),
    { isEqual: (a, b) => a.join(",") === b.join?.(",") },
    [$presences]
  );
  return useValue($userIds);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/usePresence.mjs
var import_react26 = __toESM(require_react(), 1);
function usePresence(userId) {
  const editor = useEditor();
  const $presences = (0, import_react26.useMemo)(() => {
    return editor.store.query.records("instance_presence", () => ({
      userId: { eq: userId }
    }));
  }, [editor, userId]);
  const latestPresence = useValue(
    `latestPresence:${userId}`,
    () => {
      return $presences.value.slice().sort((a, b) => b.lastActivityTimestamp - a.lastActivityTimestamp)[0];
    },
    []
  );
  return latestPresence ?? null;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/LiveCollaborators.mjs
var LiveCollaborators = track(function Collaborators() {
  const peerIds = usePeerIds();
  return (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children: peerIds.map((id) => (0, import_jsx_runtime22.jsx)(CollaboratorGuard, { collaboratorId: id }, id)) });
});
var CollaboratorGuard = track(function CollaboratorGuard2({
  collaboratorId
}) {
  const editor = useEditor();
  const presence = usePresence(collaboratorId);
  const collaboratorState = useCollaboratorState(presence);
  if (!(presence && presence.currentPageId === editor.currentPageId)) {
    return null;
  }
  switch (collaboratorState) {
    case "inactive": {
      const { followingUserId, highlightedUserIds } = editor.instanceState;
      if (!(followingUserId === presence.userId || highlightedUserIds.includes(presence.userId))) {
        return null;
      }
      break;
    }
    case "idle": {
      const { highlightedUserIds } = editor.instanceState;
      if (presence.followingUserId === editor.user.id && !(presence.chatMessage || highlightedUserIds.includes(presence.userId))) {
        return null;
      }
      break;
    }
    case "active": {
      break;
    }
  }
  return (0, import_jsx_runtime22.jsx)(Collaborator, { latestPresence: presence });
});
var Collaborator = track(function Collaborator2({
  latestPresence
}) {
  const editor = useEditor();
  const {
    CollaboratorBrush,
    CollaboratorScribble,
    CollaboratorCursor,
    CollaboratorHint: CollaboratorHint2,
    CollaboratorShapeIndicator
  } = useEditorComponents();
  const { viewportPageBounds, zoomLevel } = editor;
  const { userId, chatMessage, brush, scribble, selectedShapeIds, userName, cursor, color } = latestPresence;
  const isCursorInViewport = !(cursor.x < viewportPageBounds.minX - 12 / zoomLevel || cursor.y < viewportPageBounds.minY - 16 / zoomLevel || cursor.x > viewportPageBounds.maxX - 12 / zoomLevel || cursor.y > viewportPageBounds.maxY - 16 / zoomLevel);
  return (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
    brush && CollaboratorBrush ? (0, import_jsx_runtime22.jsx)(
      CollaboratorBrush,
      {
        className: "tl-collaborator__brush",
        brush,
        color,
        opacity: 0.1
      },
      userId + "_brush"
    ) : null,
    isCursorInViewport && CollaboratorCursor ? (0, import_jsx_runtime22.jsx)(
      CollaboratorCursor,
      {
        className: "tl-collaborator__cursor",
        point: cursor,
        color,
        zoom: zoomLevel,
        name: userName !== "New User" ? userName : null,
        chatMessage
      },
      userId + "_cursor"
    ) : CollaboratorHint2 ? (0, import_jsx_runtime22.jsx)(
      CollaboratorHint2,
      {
        className: "tl-collaborator__cursor-hint",
        point: cursor,
        color,
        zoom: zoomLevel,
        viewport: viewportPageBounds
      },
      userId + "_cursor_hint"
    ) : null,
    scribble && CollaboratorScribble ? (0, import_jsx_runtime22.jsx)(
      CollaboratorScribble,
      {
        className: "tl-collaborator__scribble",
        scribble,
        color,
        zoom: zoomLevel,
        opacity: scribble.color === "laser" ? 0.5 : 0.1
      },
      userId + "_scribble"
    ) : null,
    CollaboratorShapeIndicator && selectedShapeIds.map((shapeId) => (0, import_jsx_runtime22.jsx)(
      CollaboratorShapeIndicator,
      {
        className: "tl-collaborator__shape-indicator",
        id: shapeId,
        color,
        opacity: 0.5
      },
      userId + "_" + shapeId
    ))
  ] });
});
function getStateFromElapsedTime(elapsed) {
  return elapsed > COLLABORATOR_INACTIVE_TIMEOUT ? "inactive" : elapsed > COLLABORATOR_IDLE_TIMEOUT ? "idle" : "active";
}
function useCollaboratorState(latestPresence) {
  const rLastActivityTimestamp = (0, import_react27.useRef)(latestPresence?.lastActivityTimestamp ?? -1);
  const [state, setState] = (0, import_react27.useState)(
    () => getStateFromElapsedTime(Date.now() - rLastActivityTimestamp.current)
  );
  (0, import_react27.useEffect)(() => {
    const interval = setInterval(() => {
      setState(getStateFromElapsedTime(Date.now() - rLastActivityTimestamp.current));
    }, COLLABORATOR_CHECK_INTERVAL);
    return () => clearInterval(interval);
  }, []);
  if (latestPresence) {
    rLastActivityTimestamp.current = latestPresence.lastActivityTimestamp;
  }
  return state;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/Shape.mjs
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
var React11 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDPRMultiple.mjs
var React10 = __toESM(require_react(), 1);
function gcd(a, b) {
  return b === 0 ? a : gcd(b, a % b);
}
function nearestMultiple(float) {
  const decimal = float.toString().split(".")[1];
  if (!decimal)
    return 1;
  const denominator = Math.pow(10, decimal.length);
  const numerator = parseInt(decimal, 10);
  return denominator / gcd(numerator, denominator);
}
function useDPRMultiple() {
  const editor = useEditor();
  const container = useContainer();
  React10.useEffect(() => {
    return react("useDPRMultiple", () => {
      const dpr = editor.instanceState.devicePixelRatio;
      container.style.setProperty("--tl-dpr-multiple", nearestMultiple(dpr).toString());
    });
  }, [editor, container]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/Shape.mjs
var Shape = track(function Shape2({
  id,
  shape,
  util,
  index: index2,
  backgroundIndex,
  opacity,
  isCulled
}) {
  const editor = useEditor();
  const { ShapeErrorFallback } = useEditorComponents();
  const containerRef = React11.useRef(null);
  const backgroundContainerRef = React11.useRef(null);
  const setProperty = React11.useCallback((property, value) => {
    containerRef.current?.style.setProperty(property, value);
    backgroundContainerRef.current?.style.setProperty(property, value);
  }, []);
  useQuickReactor(
    "set shape container transform position",
    () => {
      const shape2 = editor.getShape(id);
      if (!shape2)
        return;
      const pageTransform = editor.getShapePageTransform(id);
      const transform = Matrix2d.toCssString(pageTransform);
      setProperty("transform", transform);
    },
    [editor, setProperty]
  );
  useQuickReactor(
    "set shape container clip path",
    () => {
      const shape2 = editor.getShape(id);
      if (!shape2)
        return null;
      const clipPath = editor.getShapeClipPath(id);
      setProperty("clip-path", clipPath ?? "none");
    },
    [editor, setProperty]
  );
  useQuickReactor(
    "set shape height and width",
    () => {
      const shape2 = editor.getShape(id);
      if (!shape2)
        return null;
      const bounds = editor.getShapeGeometry(shape2).bounds;
      const dpr = Math.floor(editor.instanceState.devicePixelRatio * 100) / 100;
      const dprMultiple = nearestMultiple(dpr);
      const widthRemainder = bounds.w % dprMultiple;
      const width = widthRemainder === 0 ? bounds.w : bounds.w + (dprMultiple - widthRemainder);
      const heightRemainder = bounds.h % dprMultiple;
      const height = heightRemainder === 0 ? bounds.h : bounds.h + (dprMultiple - heightRemainder);
      setProperty("width", Math.max(width, dprMultiple) + "px");
      setProperty("height", Math.max(height, dprMultiple) + "px");
    },
    [editor]
  );
  React11.useLayoutEffect(() => {
    setProperty("opacity", opacity + "");
    containerRef.current?.style.setProperty("z-index", index2 + "");
    backgroundContainerRef.current?.style.setProperty("z-index", backgroundIndex + "");
  }, [opacity, index2, backgroundIndex, setProperty]);
  const annotateError2 = React11.useCallback(
    (error) => {
      editor.annotateError(error, { origin: "react.shape", willCrashApp: false });
    },
    [editor]
  );
  if (!shape)
    return null;
  return (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
    util.backgroundComponent && (0, import_jsx_runtime23.jsx)(
      "div",
      {
        ref: backgroundContainerRef,
        className: "tl-shape tl-shape-background",
        "data-shape-type": shape.type,
        draggable: false,
        children: !isCulled && (0, import_jsx_runtime23.jsx)(OptionalErrorBoundary, { fallback: ShapeErrorFallback, onError: annotateError2, children: (0, import_jsx_runtime23.jsx)(InnerShapeBackground, { shape, util }) })
      }
    ),
    (0, import_jsx_runtime23.jsx)("div", { ref: containerRef, className: "tl-shape", "data-shape-type": shape.type, draggable: false, children: isCulled ? (0, import_jsx_runtime23.jsx)(CulledShape, { shape }) : (0, import_jsx_runtime23.jsx)(OptionalErrorBoundary, { fallback: ShapeErrorFallback, onError: annotateError2, children: (0, import_jsx_runtime23.jsx)(InnerShape, { shape, util }) }) })
  ] });
});
var InnerShape = React11.memo(
  function InnerShape2({ shape, util }) {
    return useStateTracking("InnerShape:" + shape.type, () => util.component(shape));
  },
  (prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta
);
var InnerShapeBackground = React11.memo(
  function InnerShapeBackground2({
    shape,
    util
  }) {
    return useStateTracking("InnerShape:" + shape.type, () => util.backgroundComponent?.(shape));
  },
  (prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta
);
var CulledShape = React11.memo(
  function CulledShape2({ shape }) {
    const editor = useEditor();
    const bounds = editor.getShapeGeometry(shape).bounds;
    return (0, import_jsx_runtime23.jsx)(
      "div",
      {
        className: "tl-shape__culled",
        style: {
          transform: `translate(${toDomPrecision(bounds.minX)}px, ${toDomPrecision(
            bounds.minY
          )}px)`,
          width: Math.max(1, toDomPrecision(bounds.width)),
          height: Math.max(1, toDomPrecision(bounds.height))
        }
      }
    );
  },
  () => true
);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/Canvas.mjs
function Canvas({ className }) {
  const editor = useEditor();
  const { Background, SvgDefs } = useEditorComponents();
  const rCanvas = import_react28.default.useRef(null);
  const rHtmlLayer = import_react28.default.useRef(null);
  const rHtmlLayer2 = import_react28.default.useRef(null);
  useScreenBounds();
  useDocumentEvents();
  useCoarsePointer();
  useGestureEvents(rCanvas);
  useFixSafariDoubleTapZoomPencilEvents(rCanvas);
  useQuickReactor(
    "position layers",
    () => {
      const htmlElm = rHtmlLayer.current;
      if (!htmlElm)
        return;
      const htmlElm2 = rHtmlLayer2.current;
      if (!htmlElm2)
        return;
      const { x, y, z } = editor.camera;
      const offset2 = z >= 1 ? modulate(z, [1, 8], [0.125, 0.5], true) : modulate(z, [0.1, 1], [-2, 0.125], true);
      const transform = `scale(${toDomPrecision(z)}) translate(${toDomPrecision(
        x + offset2
      )}px,${toDomPrecision(y + offset2)}px)`;
      htmlElm.style.setProperty("transform", transform);
      htmlElm2.style.setProperty("transform", transform);
    },
    [editor]
  );
  const events = useCanvasEvents();
  const shapeSvgDefs = useValue(
    "shapeSvgDefs",
    () => {
      const shapeSvgDefsByKey = /* @__PURE__ */ new Map();
      for (const util of objectMapValues(editor.shapeUtils)) {
        if (!util)
          return;
        const defs = util.getCanvasSvgDefs();
        for (const { key, component: Component2 } of defs) {
          if (shapeSvgDefsByKey.has(key))
            continue;
          shapeSvgDefsByKey.set(key, (0, import_jsx_runtime24.jsx)(Component2, {}, key));
        }
      }
      return [...shapeSvgDefsByKey.values()];
    },
    [editor]
  );
  const hideShapes = useValue("debug_shapes", () => debugFlags.hideShapes.value, [debugFlags]);
  const debugSvg = useValue("debug_svg", () => debugFlags.debugSvg.value, [debugFlags]);
  const debugGeometry = useValue("debug_geometry", () => debugFlags.debugGeometry.value, [
    debugFlags
  ]);
  return (0, import_jsx_runtime24.jsxs)(
    "div",
    {
      ref: rCanvas,
      draggable: false,
      className: (0, import_classnames9.default)("tl-canvas", className),
      "data-testid": "canvas",
      ...events,
      children: [
        Background && (0, import_jsx_runtime24.jsx)(Background, {}),
        (0, import_jsx_runtime24.jsx)(GridWrapper, {}),
        (0, import_jsx_runtime24.jsx)(UiLogger, {}),
        (0, import_jsx_runtime24.jsx)("svg", { className: "tl-svg-context", children: (0, import_jsx_runtime24.jsxs)("defs", { children: [
          shapeSvgDefs,
          Cursor && (0, import_jsx_runtime24.jsx)(Cursor, {}),
          (0, import_jsx_runtime24.jsx)(CollaboratorHint, {}),
          (0, import_jsx_runtime24.jsx)(ArrowheadDot, {}),
          (0, import_jsx_runtime24.jsx)(ArrowheadCross, {}),
          SvgDefs && (0, import_jsx_runtime24.jsx)(SvgDefs, {})
        ] }) }),
        (0, import_jsx_runtime24.jsxs)("div", { ref: rHtmlLayer, className: "tl-html-layer tl-shapes", draggable: false, children: [
          (0, import_jsx_runtime24.jsx)(SelectionBackgroundWrapper, {}),
          hideShapes ? null : debugSvg ? (0, import_jsx_runtime24.jsx)(ShapesWithSVGs, {}) : (0, import_jsx_runtime24.jsx)(ShapesToDisplay, {})
        ] }),
        (0, import_jsx_runtime24.jsx)("div", { className: "tl-fixed-layer tl-overlays", children: (0, import_jsx_runtime24.jsxs)("div", { ref: rHtmlLayer2, className: "tl-html-layer", children: [
          debugGeometry ? (0, import_jsx_runtime24.jsx)(GeometryDebuggingView, {}) : null,
          (0, import_jsx_runtime24.jsx)(HandlesWrapper, {}),
          (0, import_jsx_runtime24.jsx)(BrushWrapper, {}),
          (0, import_jsx_runtime24.jsx)(ScribbleWrapper, {}),
          (0, import_jsx_runtime24.jsx)(ZoomBrushWrapper, {}),
          (0, import_jsx_runtime24.jsx)(SelectedIdIndicators, {}),
          (0, import_jsx_runtime24.jsx)(HoveredShapeIndicator, {}),
          (0, import_jsx_runtime24.jsx)(HintedShapeIndicator, {}),
          (0, import_jsx_runtime24.jsx)(SnapLinesWrapper, {}),
          (0, import_jsx_runtime24.jsx)(SelectionForegroundWrapper, {}),
          (0, import_jsx_runtime24.jsx)(LiveCollaborators, {})
        ] }) })
      ]
    }
  );
}
function GridWrapper() {
  const editor = useEditor();
  const gridSize = useValue("gridSize", () => editor.documentSettings.gridSize, [editor]);
  const { x, y, z } = useValue("camera", () => editor.camera, [editor]);
  const isGridMode = useValue("isGridMode", () => editor.instanceState.isGridMode, [editor]);
  const { Grid } = useEditorComponents();
  if (!(Grid && isGridMode))
    return null;
  return (0, import_jsx_runtime24.jsx)(Grid, { x, y, z, size: gridSize });
}
function ScribbleWrapper() {
  const editor = useEditor();
  const scribble = useValue("scribble", () => editor.instanceState.scribble, [editor]);
  const zoomLevel = useValue("zoomLevel", () => editor.zoomLevel, [editor]);
  const { Scribble } = useEditorComponents();
  if (!(Scribble && scribble))
    return null;
  return (0, import_jsx_runtime24.jsx)(Scribble, { className: "tl-user-scribble", scribble, zoom: zoomLevel });
}
function BrushWrapper() {
  const editor = useEditor();
  const brush = useValue("brush", () => editor.instanceState.brush, [editor]);
  const { Brush } = useEditorComponents();
  if (!(Brush && brush))
    return null;
  return (0, import_jsx_runtime24.jsx)(Brush, { className: "tl-user-brush", brush });
}
function ZoomBrushWrapper() {
  const editor = useEditor();
  const zoomBrush = useValue("zoomBrush", () => editor.instanceState.zoomBrush, [editor]);
  const { ZoomBrush } = useEditorComponents();
  if (!(ZoomBrush && zoomBrush))
    return null;
  return (0, import_jsx_runtime24.jsx)(ZoomBrush, { className: "tl-user-brush", brush: zoomBrush });
}
function SnapLinesWrapper() {
  const editor = useEditor();
  const lines = useValue("snapLines", () => editor.snaps.lines, [editor]);
  const zoomLevel = useValue("zoomLevel", () => editor.zoomLevel, [editor]);
  const { SnapLine } = useEditorComponents();
  if (!(SnapLine && lines.length > 0))
    return null;
  return (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: lines.map((line) => (0, import_jsx_runtime24.jsx)(SnapLine, { className: "tl-user-snapline", line, zoom: zoomLevel }, line.id)) });
}
var MIN_HANDLE_DISTANCE = 48;
function HandlesWrapper() {
  const editor = useEditor();
  const { Handles } = useEditorComponents();
  const zoomLevel = useValue("zoomLevel", () => editor.zoomLevel, [editor]);
  const isCoarse = useValue("coarse pointer", () => editor.instanceState.isCoarsePointer, [editor]);
  const onlySelectedShape = useValue("onlySelectedShape", () => editor.onlySelectedShape, [editor]);
  const isChangingStyle = useValue("isChangingStyle", () => editor.instanceState.isChangingStyle, [
    editor
  ]);
  const isReadonly = useValue("isChangingStyle", () => editor.instanceState.isReadonly, [editor]);
  const handles = useValue(
    "handles",
    () => editor.onlySelectedShape ? editor.getShapeHandles(editor.onlySelectedShape) : void 0,
    [editor]
  );
  const transform = useValue(
    "transform",
    () => editor.onlySelectedShape ? editor.getShapePageTransform(editor.onlySelectedShape) : void 0,
    [editor]
  );
  if (!Handles || !onlySelectedShape || isChangingStyle || isReadonly)
    return null;
  if (!handles)
    return null;
  if (!transform)
    return null;
  const handlesToDisplay = [];
  for (let i = 0, handle = handles[i]; i < handles.length; i++, handle = handles[i]) {
    if (handle.type !== "vertex") {
      const prev = handles[i - 1];
      const next = handles[i + 1];
      if (prev && next) {
        if (Math.hypot(prev.y - next.y, prev.x - next.x) < MIN_HANDLE_DISTANCE / zoomLevel) {
          continue;
        }
      }
    }
    handlesToDisplay.push(handle);
  }
  handlesToDisplay.sort((a) => a.type === "vertex" ? 1 : -1);
  return (0, import_jsx_runtime24.jsx)(Handles, { children: (0, import_jsx_runtime24.jsx)("g", { transform: Matrix2d.toCssString(transform), children: handlesToDisplay.map((handle) => {
    return (0, import_jsx_runtime24.jsx)(
      HandleWrapper,
      {
        shapeId: onlySelectedShape.id,
        handle,
        zoom: zoomLevel,
        isCoarse
      },
      handle.id
    );
  }) }) });
}
function HandleWrapper({
  shapeId,
  handle,
  zoom,
  isCoarse
}) {
  const events = useHandleEvents(shapeId, handle.id);
  const { Handle } = useEditorComponents();
  if (!Handle)
    return null;
  return (0, import_jsx_runtime24.jsx)("g", { "aria-label": "handle", transform: `translate(${handle.x}, ${handle.y})`, ...events, children: (0, import_jsx_runtime24.jsx)(Handle, { shapeId, handle, zoom, isCoarse }) });
}
function ShapesWithSVGs() {
  const editor = useEditor();
  const renderingShapes = useValue("rendering shapes", () => editor.renderingShapes, [editor]);
  return (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: renderingShapes.map((result) => (0, import_jsx_runtime24.jsxs)(import_react28.default.Fragment, { children: [
    (0, import_jsx_runtime24.jsx)(Shape, { ...result }),
    (0, import_jsx_runtime24.jsx)(DebugSvgCopy, { id: result.id })
  ] }, result.id + "_fragment")) });
}
function ShapesToDisplay() {
  const editor = useEditor();
  const renderingShapes = useValue("rendering shapes", () => editor.renderingShapes, [editor]);
  return (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: renderingShapes.map((result) => (0, import_jsx_runtime24.jsx)(Shape, { ...result }, result.id + "_shape")) });
}
function SelectedIdIndicators() {
  const editor = useEditor();
  const selectedShapeIds = useValue(
    "selectedShapeIds",
    () => editor.currentPageState.selectedShapeIds,
    [editor]
  );
  const shouldDisplay = useValue(
    "should display selected ids",
    () => {
      return editor.isInAny(
        "select.idle",
        "select.brushing",
        "select.scribble_brushing",
        "select.editing_shape",
        "select.pointing_shape",
        "select.pointing_selection",
        "select.pointing_handle"
      ) && !editor.instanceState.isChangingStyle;
    },
    [editor]
  );
  if (!shouldDisplay)
    return null;
  return (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: selectedShapeIds.map((id) => (0, import_jsx_runtime24.jsx)(ShapeIndicator, { className: "tl-user-indicator__selected", id }, id + "_indicator")) });
}
var HoveredShapeIndicator = function HoveredShapeIndicator2() {
  const editor = useEditor();
  const { HoveredShapeIndicator: HoveredShapeIndicator3 } = useEditorComponents();
  const isCoarsePointer = useValue("coarse pointer", () => editor.instanceState.isCoarsePointer, [
    editor
  ]);
  const isHoveringCanvas = useValue(
    "hovering canvas",
    () => editor.instanceState.isHoveringCanvas,
    [editor]
  );
  const hoveredShapeId = useValue("hovered id", () => editor.currentPageState.hoveredShapeId, [
    editor
  ]);
  if (isCoarsePointer || !isHoveringCanvas || !hoveredShapeId || !HoveredShapeIndicator3)
    return null;
  return (0, import_jsx_runtime24.jsx)(HoveredShapeIndicator3, { shapeId: hoveredShapeId });
};
var HintedShapeIndicator = track(function HintedShapeIndicator2() {
  const editor = useEditor();
  const ids = dedupe(editor.hintingShapeIds);
  if (!ids.length)
    return null;
  return (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: ids.map((id) => (0, import_jsx_runtime24.jsx)(ShapeIndicator, { className: "tl-user-indicator__hint", id }, id + "_hinting")) });
});
function Cursor() {
  return (0, import_jsx_runtime24.jsxs)("g", { id: "cursor", children: [
    (0, import_jsx_runtime24.jsxs)("g", { fill: "rgba(0,0,0,.2)", transform: "translate(-11,-11)", children: [
      (0, import_jsx_runtime24.jsx)("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }),
      (0, import_jsx_runtime24.jsx)("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" })
    ] }),
    (0, import_jsx_runtime24.jsxs)("g", { fill: "white", transform: "translate(-12,-12)", children: [
      (0, import_jsx_runtime24.jsx)("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }),
      (0, import_jsx_runtime24.jsx)("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" })
    ] }),
    (0, import_jsx_runtime24.jsxs)("g", { fill: "currentColor", transform: "translate(-12,-12)", children: [
      (0, import_jsx_runtime24.jsx)("path", { d: "m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z" }),
      (0, import_jsx_runtime24.jsx)("path", { d: "m13 10.814v11.188l2.969-2.866.428-.139h4.768z" })
    ] })
  ] });
}
function CollaboratorHint() {
  return (0, import_jsx_runtime24.jsx)("path", { id: "cursor_hint", fill: "currentColor", d: "M -2,-5 2,0 -2,5 Z" });
}
function ArrowheadDot() {
  return (0, import_jsx_runtime24.jsx)("marker", { id: "arrowhead-dot", className: "tl-arrow-hint", refX: "3.0", refY: "3.0", orient: "0", children: (0, import_jsx_runtime24.jsx)("circle", { cx: "3", cy: "3", r: "2", strokeDasharray: "100%" }) });
}
function ArrowheadCross() {
  return (0, import_jsx_runtime24.jsxs)("marker", { id: "arrowhead-cross", className: "tl-arrow-hint", refX: "3.0", refY: "3.0", orient: "auto", children: [
    (0, import_jsx_runtime24.jsx)("line", { x1: "1.5", y1: "1.5", x2: "4.5", y2: "4.5", strokeDasharray: "100%" }),
    (0, import_jsx_runtime24.jsx)("line", { x1: "1.5", y1: "4.5", x2: "4.5", y2: "1.5", strokeDasharray: "100%" })
  ] });
}
var DebugSvgCopy = track(function DupSvg({ id }) {
  const editor = useEditor();
  const shape = editor.getShape(id);
  const [html, setHtml] = import_react28.default.useState("");
  const isInRoot = shape?.parentId === editor.currentPageId;
  import_react28.default.useEffect(() => {
    if (!isInRoot)
      return;
    let latest = null;
    const unsubscribe = react("shape to svg", async () => {
      const renderId = Math.random();
      latest = renderId;
      const bb = editor.getShapePageBounds(id);
      const el = await editor.getSvg([id], { padding: 0 });
      if (el && bb && latest === renderId) {
        el.style.setProperty("overflow", "visible");
        el.setAttribute("preserveAspectRatio", "xMidYMin slice");
        el.style.setProperty("transform", `translate(${bb.x}px, ${bb.y + bb.h + 12}px)`);
        el.style.setProperty("border", "1px solid black");
        setHtml(el?.outerHTML);
      }
    });
    return () => {
      latest = null;
      unsubscribe();
    };
  }, [editor, id, isInRoot]);
  if (!isInRoot)
    return null;
  return (0, import_jsx_runtime24.jsx)("div", { style: { paddingTop: 12, position: "absolute" }, children: (0, import_jsx_runtime24.jsx)("div", { style: { display: "flex" }, dangerouslySetInnerHTML: { __html: html } }) });
});
function UiLogger() {
  const uiLog = useValue("debugging ui log", () => debugFlags.logMessages.value, [debugFlags]);
  if (!uiLog.length)
    return null;
  return (0, import_jsx_runtime24.jsx)("div", { className: "debug__ui-logger", children: uiLog.map((message, messageIndex) => {
    const text = typeof message === "string" ? message : JSON.stringify(message);
    return (0, import_jsx_runtime24.jsx)("div", { className: "debug__ui-logger__line", children: text }, messageIndex);
  }) });
}
function SelectionForegroundWrapper() {
  const editor = useEditor();
  const selectionRotation = useValue("selection rotation", () => editor.selectionRotation, [editor]);
  const selectionBounds = useValue("selection bounds", () => editor.selectionRotatedPageBounds, [
    editor
  ]);
  const { SelectionForeground } = useEditorComponents();
  if (!selectionBounds || !SelectionForeground)
    return null;
  return (0, import_jsx_runtime24.jsx)(SelectionForeground, { bounds: selectionBounds, rotation: selectionRotation });
}
function SelectionBackgroundWrapper() {
  const editor = useEditor();
  const selectionRotation = useValue("selection rotation", () => editor.selectionRotation, [editor]);
  const selectionBounds = useValue("selection bounds", () => editor.selectionRotatedPageBounds, [
    editor
  ]);
  const { SelectionBackground } = useEditorComponents();
  if (!selectionBounds || !SelectionBackground)
    return null;
  return (0, import_jsx_runtime24.jsx)(SelectionBackground, { bounds: selectionBounds, rotation: selectionRotation });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/uniqueId.mjs
function uniqueId() {
  return nanoid();
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/config/TLUserPreferences.mjs
var USER_DATA_KEY = "TLDRAW_USER_DATA_v3";
var userTypeValidator = validation_exports.object({
  id: validation_exports.string,
  name: validation_exports.string.nullable().optional(),
  locale: validation_exports.string.nullable().optional(),
  color: validation_exports.string.nullable().optional(),
  isDarkMode: validation_exports.boolean.nullable().optional(),
  animationSpeed: validation_exports.number.nullable().optional(),
  isSnapMode: validation_exports.boolean.nullable().optional()
});
var Versions13 = {
  AddAnimationSpeed: 1,
  AddIsSnapMode: 2,
  MakeFieldsNullable: 3
};
var userMigrations = defineMigrations({
  currentVersion: Versions13.MakeFieldsNullable,
  migrators: {
    [Versions13.AddAnimationSpeed]: {
      up: (user) => {
        return {
          ...user,
          animationSpeed: 1
        };
      },
      down: ({ animationSpeed: _, ...user }) => {
        return user;
      }
    },
    [Versions13.AddIsSnapMode]: {
      up: (user) => {
        return { ...user, isSnapMode: false };
      },
      down: ({ isSnapMode: _, ...user }) => {
        return user;
      }
    },
    [Versions13.MakeFieldsNullable]: {
      up: (user) => {
        return user;
      },
      down: (user) => {
        return {
          id: user.id,
          name: user.name ?? defaultUserPreferences.name,
          locale: user.locale ?? defaultUserPreferences.locale,
          color: user.color ?? defaultUserPreferences.color,
          isDarkMode: user.isDarkMode ?? defaultUserPreferences.isDarkMode,
          animationSpeed: user.animationSpeed ?? defaultUserPreferences.animationSpeed,
          isSnapMode: user.isSnapMode ?? defaultUserPreferences.isSnapMode
        };
      }
    }
  }
});
var USER_COLORS = [
  "#FF802B",
  "#EC5E41",
  "#F2555A",
  "#F04F88",
  "#E34BA9",
  "#BD54C6",
  "#9D5BD2",
  "#7B66DC",
  "#02B1CC",
  "#11B3A3",
  "#39B178",
  "#55B467"
];
function getRandomColor() {
  return USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)];
}
function userPrefersDarkUI() {
  if (typeof window === "undefined") {
    return false;
  }
  return window.matchMedia?.("(prefers-color-scheme: dark)")?.matches ?? false;
}
function userPrefersReducedMotion() {
  if (typeof window === "undefined") {
    return false;
  }
  return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;
}
var defaultUserPreferences = Object.freeze({
  name: "New User",
  locale: getDefaultTranslationLocale(),
  color: getRandomColor(),
  isDarkMode: false,
  animationSpeed: userPrefersReducedMotion() ? 0 : 1,
  isSnapMode: false
});
function getFreshUserPreferences() {
  return {
    id: uniqueId()
  };
}
function migrateUserPreferences(userData) {
  if (userData === null || typeof userData !== "object") {
    return getFreshUserPreferences();
  }
  if (!("version" in userData) || !("user" in userData) || typeof userData.version !== "number") {
    return getFreshUserPreferences();
  }
  const migrationResult = migrate({
    value: userData.user,
    fromVersion: userData.version,
    toVersion: userMigrations.currentVersion ?? 0,
    migrations: userMigrations
  });
  if (migrationResult.type === "error") {
    return getFreshUserPreferences();
  }
  try {
    userTypeValidator.validate(migrationResult.value);
  } catch (e) {
    return getFreshUserPreferences();
  }
  return migrationResult.value;
}
function loadUserPreferences() {
  const userData = typeof window === "undefined" ? null : JSON.parse(window?.localStorage?.getItem(USER_DATA_KEY) || "null") ?? null;
  return migrateUserPreferences(userData);
}
var globalUserPreferences = atom("globalUserData", loadUserPreferences());
function storeUserPreferences() {
  if (typeof window !== "undefined" && window.localStorage) {
    window.localStorage.setItem(
      USER_DATA_KEY,
      JSON.stringify({
        version: userMigrations.currentVersion,
        user: globalUserPreferences.value
      })
    );
  }
}
function setUserPreferences(user) {
  userTypeValidator.validate(user);
  globalUserPreferences.set(user);
  storeUserPreferences();
  broadcastUserPreferencesChange();
}
var isTest2 = typeof process !== "undefined" && false;
var channel = typeof BroadcastChannel !== "undefined" && !isTest2 ? new BroadcastChannel("tldraw-user-sync") : null;
channel?.addEventListener("message", (e) => {
  const data = e.data;
  if (data?.type === broadcastEventKey && data?.origin !== broadcastOrigin) {
    globalUserPreferences.set(migrateUserPreferences(data.data));
  }
});
var broadcastOrigin = uniqueId();
var broadcastEventKey = "tldraw-user-preferences-change";
function broadcastUserPreferencesChange() {
  channel?.postMessage({
    type: broadcastEventKey,
    origin: broadcastOrigin,
    data: {
      user: globalUserPreferences.value,
      version: userMigrations.currentVersion
    }
  });
}
function getUserPreferences() {
  return globalUserPreferences.value;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/config/createTLUser.mjs
function createTLUser(opts = {}) {
  return {
    derivePresenceState: opts.derivePresenceState ?? (() => computed("presence", () => null)),
    userPreferences: opts.userPreferences ?? computed("userPreferences", () => getUserPreferences()),
    setUserPreferences: opts.setUserPreferences ?? setUserPreferences
  };
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs
var import_eventemitter3 = __toESM(require_eventemitter3(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/SVGContainer.mjs
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
function SVGContainer({ children, className = "", ...rest }) {
  return (0, import_jsx_runtime25.jsx)("svg", { ...rest, className: `tl-svg-container ${className}`, children });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Geometry2d.mjs
var Geometry2d = class {
  isFilled = false;
  isClosed = true;
  isLabel = false;
  isSnappable = true;
  constructor(opts) {
    this.isFilled = opts.isFilled;
    this.isClosed = opts.isClosed;
    this.isSnappable = opts.isSnappable ?? false;
    this.isLabel = opts.isLabel ?? false;
  }
  hitTestPoint(point, margin = 0, hitInside = false) {
    return this.distanceToPoint(point, hitInside) <= margin;
  }
  distanceToPoint(point, hitInside = false) {
    const dist = point.dist(this.nearestPoint(point));
    if (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {
      return -dist;
    }
    return dist;
  }
  distanceToLineSegment(A, B) {
    const point = this.nearestPointOnLineSegment(A, B);
    const dist = Vec2d.DistanceToLineSegment(A, B, point);
    return this.isClosed && this.isFilled && pointInPolygon(point, this.vertices) ? -dist : dist;
  }
  hitTestLineSegment(A, B, distance = 0) {
    return this.distanceToLineSegment(A, B) <= distance;
  }
  nearestPointOnLineSegment(A, B) {
    let distance = Infinity;
    let nearest;
    for (let i = 0; i < this.vertices.length; i++) {
      const point = this.vertices[i];
      const d = Vec2d.DistanceToLineSegment(A, B, point);
      if (d < distance) {
        distance = d;
        nearest = point;
      }
    }
    if (!nearest)
      throw Error("nearest point not found");
    return nearest;
  }
  isPointInBounds(point, margin = 0) {
    const { bounds } = this;
    return !(point.x < bounds.minX - margin || point.y < bounds.minY - margin || point.x > bounds.maxX + margin || point.y > bounds.maxY + margin);
  }
  _vertices;
  get vertices() {
    if (!this._vertices) {
      this._vertices = this.getVertices();
    }
    return this._vertices;
  }
  getBounds() {
    return Box2d.FromPoints(this.vertices);
  }
  _bounds;
  get bounds() {
    if (!this._bounds) {
      this._bounds = this.getBounds();
    }
    return this._bounds;
  }
  _snapPoints;
  get snapPoints() {
    if (!this._snapPoints) {
      this._snapPoints = this.bounds.snapPoints;
    }
    return this._snapPoints;
  }
  get center() {
    return this.bounds.center;
  }
  _area;
  get area() {
    if (!this._area) {
      this._area = this.getArea();
    }
    return this._area;
  }
  getArea() {
    if (!this.isClosed) {
      return 0;
    }
    const { vertices } = this;
    let area = 0;
    for (let i = 0, n = vertices.length; i < n; i++) {
      const curr = vertices[i];
      const next = vertices[(i + 1) % n];
      area += curr.x * next.y - next.x * curr.y;
    }
    return area / 2;
  }
  toSimpleSvgPath() {
    let path = "";
    const { vertices } = this;
    const n = vertices.length;
    if (n === 0)
      return path;
    path += `M${vertices[0].x},${vertices[0].y}`;
    for (let i = 1; i < n; i++) {
      path += `L${vertices[i].x},${vertices[i].y}`;
    }
    if (this.isClosed) {
      path += "Z";
    }
    return path;
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Group2d.mjs
var Group2d = class extends Geometry2d {
  children;
  constructor(config) {
    super({ ...config, isClosed: true, isFilled: false });
    const { children } = config;
    if (children.length === 0)
      throw Error("Group2d must have at least one child");
    this.children = children;
  }
  getVertices() {
    return this.children.filter((c) => !c.isLabel).flatMap((c) => c.vertices);
  }
  nearestPoint(point) {
    let d = Infinity;
    let p;
    const { children } = this;
    if (children.length === 0) {
      throw Error("no children");
    }
    for (const child of children) {
      const nearest = child.nearestPoint(point);
      const dist = nearest.dist(point);
      if (dist < d) {
        d = dist;
        p = nearest;
      }
    }
    if (!p)
      throw Error("nearest point not found");
    return p;
  }
  distanceToPoint(point, hitInside = false) {
    return Math.min(...this.children.map((c, i) => c.distanceToPoint(point, hitInside || i > 0)));
  }
  hitTestPoint(point, margin, hitInside) {
    return !!this.children.filter((c) => !c.isLabel).find((c) => c.hitTestPoint(point, margin, hitInside));
  }
  hitTestLineSegment(A, B, zoom) {
    return !!this.children.filter((c) => !c.isLabel).find((c) => c.hitTestLineSegment(A, B, zoom));
  }
  getArea() {
    return this.children[0].area;
  }
  toSimpleSvgPath() {
    let path = "";
    for (const child of this.children) {
      path += child.toSimpleSvgPath();
    }
    const corners = Box2d.FromPoints(this.vertices).corners;
    for (let i = 0, n = corners.length; i < n; i++) {
      const corner = corners[i];
      const prevCorner = corners[(i - 1 + n) % n];
      const prevDist = corner.dist(prevCorner);
      const nextCorner = corners[(i + 1) % n];
      const nextDist = corner.dist(nextCorner);
      const A = corner.clone().lrp(prevCorner, 4 / prevDist);
      const B = corner;
      const C = corner.clone().lrp(nextCorner, 4 / nextDist);
      path += `M${A.x},${A.y} L${B.x},${B.y} L${C.x},${C.y} `;
    }
    return path;
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/intersect.mjs
function intersectLineSegmentLineSegment(a1, a2, b1, b2) {
  const ABx = a1.x - b1.x;
  const ABy = a1.y - b1.y;
  const BVx = b2.x - b1.x;
  const BVy = b2.y - b1.y;
  const AVx = a2.x - a1.x;
  const AVy = a2.y - a1.y;
  const ua_t = BVx * ABy - BVy * ABx;
  const ub_t = AVx * ABy - AVy * ABx;
  const u_b = BVy * AVx - BVx * AVy;
  if (ua_t === 0 || ub_t === 0)
    return null;
  if (u_b === 0)
    return null;
  if (u_b !== 0) {
    const ua = ua_t / u_b;
    const ub = ub_t / u_b;
    if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
      return Vec2d.AddXY(a1, ua * AVx, ua * AVy);
    }
  }
  return null;
}
function intersectLineSegmentCircle(a1, a2, c, r) {
  const a = (a2.x - a1.x) * (a2.x - a1.x) + (a2.y - a1.y) * (a2.y - a1.y);
  const b = 2 * ((a2.x - a1.x) * (a1.x - c.x) + (a2.y - a1.y) * (a1.y - c.y));
  const cc = c.x * c.x + c.y * c.y + a1.x * a1.x + a1.y * a1.y - 2 * (c.x * a1.x + c.y * a1.y) - r * r;
  const deter = b * b - 4 * a * cc;
  if (deter < 0)
    return null;
  if (deter === 0)
    return null;
  const e = Math.sqrt(deter);
  const u1 = (-b + e) / (2 * a);
  const u2 = (-b - e) / (2 * a);
  if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {
    return null;
  }
  const result = [];
  if (0 <= u1 && u1 <= 1)
    result.push(Vec2d.Lrp(a1, a2, u1));
  if (0 <= u2 && u2 <= 1)
    result.push(Vec2d.Lrp(a1, a2, u2));
  if (result.length === 0)
    return null;
  return result;
}
function intersectLineSegmentPolyline(a1, a2, points) {
  const result = [];
  let segmentIntersection;
  for (let i = 0, n = points.length - 1; i < n; i++) {
    segmentIntersection = intersectLineSegmentLineSegment(a1, a2, points[i], points[i + 1]);
    if (segmentIntersection)
      result.push(segmentIntersection);
  }
  if (result.length === 0)
    return null;
  return result;
}
function intersectLineSegmentPolygon(a1, a2, points) {
  const result = [];
  let segmentIntersection;
  for (let i = 1, n = points.length; i < n + 1; i++) {
    segmentIntersection = intersectLineSegmentLineSegment(
      a1,
      a2,
      points[i - 1],
      points[i % points.length]
    );
    if (segmentIntersection)
      result.push(segmentIntersection);
  }
  if (result.length === 0)
    return null;
  return result;
}
function intersectCircleCircle(c1, r1, c2, r2) {
  let dx = c2.x - c1.x;
  let dy = c2.y - c1.y;
  const d = Math.sqrt(dx * dx + dy * dy), x = (d * d - r2 * r2 + r1 * r1) / (2 * d), y = Math.sqrt(r1 * r1 - x * x);
  dx /= d;
  dy /= d;
  return [
    new Vec2d(c1.x + dx * x - dy * y, c1.y + dy * x + dx * y),
    new Vec2d(c1.x + dx * x + dy * y, c1.y + dy * x - dx * y)
  ];
}
function intersectCirclePolygon(c, r, points) {
  const result = [];
  let a, b, int;
  for (let i = 0, n = points.length; i < n; i++) {
    a = points[i];
    b = points[(i + 1) % points.length];
    int = intersectLineSegmentCircle(a, b, c, r);
    if (int)
      result.push(...int);
  }
  if (result.length === 0)
    return null;
  return result;
}
function intersectCirclePolyline(c, r, points) {
  const result = [];
  let a, b, int;
  for (let i = 1, n = points.length; i < n; i++) {
    a = points[i - 1];
    b = points[i];
    int = intersectLineSegmentCircle(a, b, c, r);
    if (int)
      result.push(...int);
  }
  if (result.length === 0)
    return null;
  return result;
}
function ccw(A, B, C) {
  return (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x);
}
function linesIntersect(A, B, C, D) {
  return ccw(A, C, D) !== ccw(B, C, D) && ccw(A, B, C) !== ccw(A, B, D);
}
function intersectPolygonPolygon(polygonA, polygonB) {
  const result = [];
  let a, b, c, d;
  for (let i = 0, n = polygonA.length; i < n; i++) {
    a = polygonA[i];
    if (pointInPolygon(a, polygonB)) {
      result.push(a);
    }
  }
  for (let i = 0, n = polygonB.length; i < n; i++) {
    a = polygonB[i];
    if (pointInPolygon(a, polygonA)) {
      result.push(a);
    }
  }
  for (let i = 0, n = polygonA.length; i < n; i++) {
    a = polygonA[i];
    b = polygonA[(i + 1) % polygonA.length];
    for (let j = 0, m = polygonB.length; j < m; j++) {
      c = polygonB[j];
      d = polygonB[(j + 1) % polygonB.length];
      const intersection = intersectLineSegmentLineSegment(a, b, c, d);
      if (intersection !== null) {
        result.push(intersection);
      }
    }
  }
  if (result.length === 0)
    return null;
  return orderClockwise(result);
}
function orderClockwise(points) {
  const C = Vec2d.Average(points);
  return points.sort((A, B) => Vec2d.Angle(C, A) - Vec2d.Angle(C, B));
}
function polygonsIntersect(a, b) {
  let a0, a1, b0, b1;
  for (let i = 0, n = a.length; i < n; i++) {
    a0 = a[i];
    a1 = a[(i + 1) % n];
    for (let j = 0, m = b.length; j < m; j++) {
      b0 = b[j];
      b1 = b[(j + 1) % m];
      if (linesIntersect(a0, a1, b0, b1))
        return true;
    }
  }
  return false;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Edge2d.mjs
var Edge2d = class extends Geometry2d {
  start;
  end;
  d;
  u;
  ul;
  constructor(config) {
    super({ ...config, isClosed: false, isFilled: false });
    const { start, end } = config;
    this.start = start;
    this.end = end;
    this.d = start.clone().sub(end);
    this.u = this.d.clone().uni();
    this.ul = this.u.len();
  }
  _length;
  get length() {
    if (!this._length) {
      return this.d.len();
    }
    return this._length;
  }
  midPoint() {
    return this.start.lrp(this.end, 0.5);
  }
  getVertices() {
    return [this.start, this.end];
  }
  nearestPoint(point) {
    const { start, end, u, ul: l } = this;
    if (l === 0)
      return start;
    const k = Vec2d.Sub(point, start).dpr(u) / l;
    const cx = start.x + u.x * k;
    if (cx < Math.min(start.x, end.x))
      return start.x < end.x ? start : end;
    if (cx > Math.max(start.x, end.x))
      return start.x > end.x ? start : end;
    const cy = start.y + u.y * k;
    if (cy < Math.min(start.y, end.y))
      return start.y < end.y ? start : end;
    if (cy > Math.max(start.y, end.y))
      return start.y > end.y ? start : end;
    return new Vec2d(cx, cy);
  }
  hitTestLineSegment(A, B, _zoom) {
    return linesIntersect(A, B, this.start, this.end);
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Polyline2d.mjs
var Polyline2d = class extends Geometry2d {
  points;
  constructor(config) {
    super({ isClosed: false, isFilled: false, ...config });
    const { points } = config;
    this.points = points;
  }
  _segments;
  get segments() {
    if (!this._segments) {
      this._segments = [];
      const { vertices } = this;
      for (let i = 0, n = vertices.length - 1; i < n; i++) {
        const start = vertices[i];
        const end = vertices[i + 1];
        this._segments.push(new Edge2d({ start, end }));
      }
      if (this.isClosed) {
        this._segments.push(new Edge2d({ start: vertices[vertices.length - 1], end: vertices[0] }));
      }
    }
    return this._segments;
  }
  _length;
  get length() {
    if (!this._length) {
      this._length = this.segments.reduce((acc, segment) => acc + segment.length, 0);
    }
    return this._length;
  }
  getVertices() {
    return this.points;
  }
  nearestPoint(A) {
    const { segments } = this;
    let nearest = this.points[0];
    let dist = Infinity;
    let p;
    let d;
    for (let i = 0; i < segments.length; i++) {
      p = segments[i].nearestPoint(A);
      d = p.dist(A);
      if (d < dist) {
        nearest = p;
        dist = d;
      }
    }
    return nearest;
  }
  hitTestLineSegment(A, B, zoom) {
    return this.segments.some((edge) => edge.hitTestLineSegment(A, B, zoom));
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Polygon2d.mjs
var Polygon2d = class extends Polyline2d {
  constructor(config) {
    super({ ...config });
    this.isClosed = true;
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Rectangle2d.mjs
var Rectangle2d = class extends Polygon2d {
  x;
  y;
  w;
  h;
  constructor(config) {
    const { x = 0, y = 0, width, height } = config;
    super({
      ...config,
      points: [
        new Vec2d(x, y),
        new Vec2d(x + width, y),
        new Vec2d(x + width, y + height),
        new Vec2d(x, y + height)
      ]
    });
    this.x = x;
    this.y = y;
    this.w = width;
    this.h = height;
  }
  getBounds() {
    return new Box2d(this.x, this.y, this.w, this.h);
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/ShapeUtil.mjs
var ShapeUtil = class {
  constructor(editor) {
    this.editor = editor;
  }
  static props;
  static migrations;
  /**
   * The type of the shape util, which should match the shape's type.
   *
   * @public
   */
  static type;
  /**
   * Whether the shape can be snapped to by another shape.
   *
   * @public
   */
  canSnap = () => true;
  /**
   * Whether the shape can be scrolled while editing.
   *
   * @public
   */
  canScroll = () => false;
  /**
   * Whether the shape should unmount when not visible in the editor. Consider keeping this to false if the shape's `component` has local state.
   *
   * @public
   */
  canUnmount = () => true;
  /**
   * Whether the shape can be bound to by an arrow.
   *
   * @param _otherShape - The other shape attempting to bind to this shape.
   * @public
   */
  canBind = (_shape, _otherShape) => true;
  /**
   * Whether the shape can be double clicked to edit.
   *
   * @public
   */
  canEdit = () => false;
  /**
   * Whether the shape can be resized.
   *
   * @public
   */
  canResize = () => true;
  /**
   * Whether the shape can be edited in read-only mode.
   *
   * @public
   */
  canEditInReadOnly = () => false;
  /**
   * Whether the shape can be cropped.
   *
   * @public
   */
  canCrop = () => false;
  /**
   * Does this shape provide a background for its children? If this is true,
   * then any children with a `renderBackground` method will have their
   * backgrounds rendered _above_ this shape. Otherwise, the children's
   * backgrounds will be rendered above either the next ancestor that provides
   * a background, or the canvas background.
   *
   * @internal
   */
  providesBackgroundForChildren(shape) {
    return false;
  }
  /**
   * Whether the shape should hide its resize handles when selected.
   *
   * @public
   */
  hideResizeHandles = () => false;
  /**
   * Whether the shape should hide its resize handles when selected.
   *
   * @public
   */
  hideRotateHandle = () => false;
  /**
   * Whether the shape should hide its selection bounds background when selected.
   *
   * @public
   */
  hideSelectionBoundsBg = () => false;
  /**
   * Whether the shape should hide its selection bounds foreground when selected.
   *
   * @public
   */
  hideSelectionBoundsFg = () => false;
  /**
   * Whether the shape's aspect ratio is locked.
   *
   * @public
   */
  isAspectRatioLocked = () => false;
  /**
   * Get an array of outline segments for the shape. For most shapes,
   * this will be a single segment that includes the entire outline.
   * For shapes with handles, this might be segments of the outline
   * between each handle.
   *
   * @example
   *
   * ```ts
   * util.getOutlineSegments(myShape)
   * ```
   *
   * @param shape - The shape.
   * @public
   */
  getOutlineSegments(shape) {
    return [this.editor.getShapeGeometry(shape).vertices];
  }
  /**
   * Get whether the shape can receive children of a given type.
   *
   * @param type - The shape type.
   * @public
   */
  canReceiveNewChildrenOfType(shape, type) {
    return false;
  }
  /**
   * Get whether the shape can receive children of a given type.
   *
   * @param shape - The shape type.
   * @param shapes - The shapes that are being dropped.
   * @public
   */
  canDropShapes(shape, shapes) {
    return false;
  }
  /** @internal */
  expandSelectionOutlinePx(shape) {
    return 0;
  }
  /**
   * Return elements to be added to the \<defs\> section of the canvases SVG context. This can be
   * used to define SVG content (e.g. patterns & masks) that can be referred to by ID from svg
   * elements returned by `component`.
   *
   * Each def should have a unique `key`. If multiple defs from different shapes all have the same
   * key, only one will be used.
   */
  getCanvasSvgDefs() {
    return [];
  }
  //  Events
  /**
   * A callback called just before a shape is created. This method provides a last chance to modify
   * the created shape.
   *
   * @example
   *
   * ```ts
   * onBeforeCreate = (next) => {
   * 	return { ...next, x: next.x + 1 }
   * }
   * ```
   *
   * @param next - The next shape.
   * @returns The next shape or void.
   * @public
   */
  onBeforeCreate;
  /**
   * A callback called just before a shape is updated. This method provides a last chance to modify
   * the updated shape.
   *
   * @example
   *
   * ```ts
   * onBeforeUpdate = (prev, next) => {
   * 	if (prev.x === next.x) {
   * 		return { ...next, x: next.x + 1 }
   * 	}
   * }
   * ```
   *
   * @param prev - The previous shape.
   * @param next - The next shape.
   * @returns The next shape or void.
   * @public
   */
  onBeforeUpdate;
  /**
   * A callback called when some other shapes are dragged over this one.
   *
   * @example
   *
   * ```ts
   * onDragShapesOver = (shape, shapes) => {
   * 	return { shouldHint: true }
   * }
   * ```
   *
   * @param shape - The shape.
   * @param shapes - The shapes that are being dragged over this one.
   * @returns An object specifying whether the shape should hint that it can receive the dragged shapes.
   * @public
   */
  onDragShapesOver;
  /**
   * A callback called when some other shapes are dragged out of this one.
   *
   * @param shape - The shape.
   * @param shapes - The shapes that are being dragged out.
   * @public
   */
  onDragShapesOut;
  /**
   * A callback called when some other shapes are dropped over this one.
   *
   * @param shape - The shape.
   * @param shapes - The shapes that are being dropped over this one.
   * @public
   */
  onDropShapesOver;
  /**
   * A callback called when a shape starts being resized.
   *
   * @param shape - The shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onResizeStart;
  /**
   * A callback called when a shape changes from a resize.
   *
   * @param shape - The shape at the start of the resize.
   * @param info - Info about the resize.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onResize;
  /**
   * A callback called when a shape finishes resizing.
   *
   * @param initial - The shape at the start of the resize.
   * @param current - The current shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onResizeEnd;
  /**
   * A callback called when a shape starts being translated.
   *
   * @param shape - The shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onTranslateStart;
  /**
   * A callback called when a shape changes from a translation.
   *
   * @param initial - The shape at the start of the translation.
   * @param current - The current shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onTranslate;
  /**
   * A callback called when a shape finishes translating.
   *
   * @param initial - The shape at the start of the translation.
   * @param current - The current shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onTranslateEnd;
  /**
   * A callback called when a shape starts being rotated.
   *
   * @param shape - The shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onRotateStart;
  /**
   * A callback called when a shape changes from a rotation.
   *
   * @param initial - The shape at the start of the rotation.
   * @param current - The current shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onRotate;
  /**
   * A callback called when a shape finishes rotating.
   *
   * @param initial - The shape at the start of the rotation.
   * @param current - The current shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onRotateEnd;
  /**
   * A callback called when a shape's handle changes.
   *
   * @param shape - The shape.
   * @param info - An object containing the handle and whether the handle is 'precise' or not.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onHandleChange;
  /**
   * Not currently used.
   *
   * @internal
   */
  onBindingChange;
  /**
   * A callback called when a shape's children change.
   *
   * @param shape - The shape.
   * @returns An array of shape updates, or void.
   * @public
   */
  onChildrenChange;
  /**
   * A callback called when a shape's handle is double clicked.
   *
   * @param shape - The shape.
   * @param handle - The handle that is double-clicked.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onDoubleClickHandle;
  /**
   * A callback called when a shape's edge is double clicked.
   *
   * @param shape - The shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onDoubleClickEdge;
  /**
   * A callback called when a shape is double clicked.
   *
   * @param shape - The shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onDoubleClick;
  /**
   * A callback called when a shape is clicked.
   *
   * @param shape - The shape.
   * @returns A change to apply to the shape, or void.
   * @public
   */
  onClick;
  /**
   * A callback called when a shape finishes being editing.
   *
   * @param shape - The shape.
   * @public
   */
  onEditEnd;
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs
function getPerfectDashProps(totalLength, strokeWidth, opts = {}) {
  const {
    closed = false,
    snap = 1,
    start = "outset",
    end = "outset",
    lengthRatio = 2,
    style = "dashed"
  } = opts;
  let dashLength = 0;
  let dashCount = 0;
  let ratio = 1;
  let gapLength = 0;
  let strokeDashoffset = 0;
  switch (style) {
    case "dashed": {
      ratio = 1;
      dashLength = Math.min(strokeWidth * lengthRatio, totalLength / 4);
      break;
    }
    case "dotted": {
      ratio = 100;
      dashLength = strokeWidth / ratio;
      break;
    }
    default: {
      return {
        strokeDasharray: "none",
        strokeDashoffset: "none"
      };
    }
  }
  if (!closed) {
    if (start === "outset") {
      totalLength += dashLength / 2;
      strokeDashoffset += dashLength / 2;
    } else if (start === "skip") {
      totalLength -= dashLength;
      strokeDashoffset -= dashLength;
    }
    if (end === "outset") {
      totalLength += dashLength / 2;
    } else if (end === "skip") {
      totalLength -= dashLength;
    }
  }
  dashCount = Math.floor(totalLength / dashLength / (2 * ratio));
  dashCount -= dashCount % snap;
  if (dashCount < 3 && style === "dashed") {
    if (totalLength / strokeWidth < 5) {
      dashLength = totalLength;
      dashCount = 1;
      gapLength = 0;
    } else {
      dashLength = totalLength * 0.333;
      gapLength = totalLength * 0.333;
    }
  } else {
    dashCount = Math.max(dashCount, 3);
    dashLength = totalLength / dashCount / (2 * ratio);
    if (closed) {
      strokeDashoffset = dashLength / 2;
      gapLength = (totalLength - dashCount * dashLength) / dashCount;
    } else {
      gapLength = (totalLength - dashCount * dashLength) / Math.max(1, dashCount - 1);
    }
  }
  return {
    strokeDasharray: [dashLength, gapLength].join(" "),
    strokeDashoffset: strokeDashoffset.toString()
  };
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs
function DashedOutlineBox({ bounds, className }) {
  const editor = useEditor();
  const zoomLevel = useValue("zoom level", () => editor.zoomLevel, [editor]);
  return (0, import_jsx_runtime26.jsx)("g", { className, pointerEvents: "none", strokeLinecap: "round", strokeLinejoin: "round", children: bounds.sides.map((side, i) => {
    const { strokeDasharray, strokeDashoffset } = getPerfectDashProps(
      side[0].dist(side[1]),
      1 / zoomLevel,
      {
        style: "dashed",
        lengthRatio: 4
      }
    );
    return (0, import_jsx_runtime26.jsx)(
      "line",
      {
        x1: side[0].x,
        y1: side[0].y,
        x2: side[1].x,
        y2: side[1].y,
        strokeDasharray,
        strokeDashoffset
      },
      i
    );
  }) });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs
var GroupShapeUtil = class extends ShapeUtil {
  static type = "group";
  static props = groupShapeProps;
  static migrations = groupShapeMigrations;
  hideSelectionBoundsFg = () => true;
  canBind = () => false;
  getDefaultProps() {
    return {};
  }
  getGeometry(shape) {
    const children = this.editor.getSortedChildIdsForParent(shape.id);
    if (children.length === 0) {
      return new Rectangle2d({ width: 1, height: 1, isFilled: false });
    }
    return new Group2d({
      children: children.map((childId) => {
        const shape2 = this.editor.getShape(childId);
        const geometry = this.editor.getShapeGeometry(childId);
        const points = this.editor.getShapeLocalTransform(shape2).applyToPoints(geometry.vertices);
        if (geometry.isClosed) {
          return new Polygon2d({
            points,
            isFilled: true
          });
        }
        return new Polyline2d({
          points
        });
      })
    });
  }
  component(shape) {
    const isErasing = this.editor.erasingShapeIds.includes(shape.id);
    const { hintingShapeIds } = this.editor.currentPageState;
    const isHintingOtherGroup = hintingShapeIds.length > 0 && hintingShapeIds.some(
      (id) => id !== shape.id && this.editor.isShapeOfType(this.editor.getShape(id), "group")
    );
    const isFocused = this.editor.currentPageState.focusedGroupId !== shape.id;
    if (!isErasing && // always show the outline while we're erasing the group
    // show the outline while the group is focused unless something outside of the group is being hinted
    // this happens dropping shapes from a group onto some outside group
    (isFocused || isHintingOtherGroup)) {
      return null;
    }
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    return (0, import_jsx_runtime27.jsx)(SVGContainer, { id: shape.id, children: (0, import_jsx_runtime27.jsx)(DashedOutlineBox, { className: "tl-group", bounds }) });
  }
  indicator(shape) {
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    return (0, import_jsx_runtime27.jsx)(DashedOutlineBox, { className: "", bounds });
  }
  onChildrenChange = (group) => {
    const children = this.editor.getSortedChildIdsForParent(group.id);
    if (children.length === 0) {
      if (this.editor.currentPageState.focusedGroupId === group.id) {
        this.editor.popFocusedGroupId();
      }
      this.editor.deleteShapes([group.id]);
      return;
    } else if (children.length === 1) {
      if (this.editor.currentPageState.focusedGroupId === group.id) {
        this.editor.popFocusedGroupId();
      }
      this.editor.reparentShapes(children, group.parentId);
      this.editor.deleteShapes([group.id]);
      return;
    }
  };
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/config/defaultShapes.mjs
var coreShapes = [
  // created by grouping interactions, probably the corest core shape that we have
  GroupShapeUtil
];
var coreShapeTypes = new Set(coreShapes.map((s) => s.type));
function checkShapesAndAddCore(customShapes) {
  const shapes = [...coreShapes];
  const addedCustomShapeTypes = /* @__PURE__ */ new Set();
  for (const customShape of customShapes) {
    if (coreShapeTypes.has(customShape.type)) {
      throw new Error(
        `Shape type "${customShape.type}" is a core shapes type and cannot be overridden`
      );
    }
    if (addedCustomShapeTypes.has(customShape.type)) {
      throw new Error(`Shape type "${customShape.type}" is defined more than once`);
    }
    shapes.push(customShape);
    addedCustomShapeTypes.add(customShape.type);
  }
  return shapes;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/SharedStylesMap.mjs
function sharedStyleEquals(a, b) {
  if (!b)
    return false;
  switch (a.type) {
    case "mixed":
      return b.type === "mixed";
    case "shared":
      return b.type === "shared" && a.value === b.value;
    default:
      throw exhaustiveSwitchError(a);
  }
}
var ReadonlySharedStyleMap = class {
  /** @internal */
  map;
  constructor(entries) {
    this.map = new Map(entries);
  }
  get(prop) {
    return this.map.get(prop);
  }
  getAsKnownValue(prop) {
    const value = this.get(prop);
    if (!value)
      return void 0;
    if (value.type === "mixed")
      return void 0;
    return value.value;
  }
  get size() {
    return this.map.size;
  }
  equals(other) {
    if (this.size !== other.size)
      return false;
    const checkedKeys = /* @__PURE__ */ new Set();
    for (const [styleProp, value] of this) {
      if (!sharedStyleEquals(value, other.get(styleProp)))
        return false;
      checkedKeys.add(styleProp);
    }
    for (const [styleProp, value] of other) {
      if (checkedKeys.has(styleProp))
        continue;
      if (!sharedStyleEquals(value, this.get(styleProp)))
        return false;
    }
    return true;
  }
  keys() {
    return this.map.keys();
  }
  values() {
    return this.map.values();
  }
  entries() {
    return this.map.entries();
  }
  [Symbol.iterator]() {
    return this.map[Symbol.iterator]();
  }
};
var SharedStyleMap = class extends ReadonlySharedStyleMap {
  set(prop, value) {
    this.map.set(prop, value);
  }
  applyValue(prop, value) {
    const existingValue = this.get(prop);
    if (!existingValue) {
      this.set(prop, { type: "shared", value });
      return;
    }
    switch (existingValue.type) {
      case "mixed":
        return;
      case "shared":
        if (existingValue.value !== value) {
          this.set(prop, { type: "mixed" });
        }
        return;
      default:
        exhaustiveSwitchError(existingValue, "type");
    }
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/WeakMapCache.mjs
var WeakMapCache = class {
  items = /* @__PURE__ */ new WeakMap();
  get(item, cb) {
    if (!this.items.has(item)) {
      this.items.set(item, cb(item));
    }
    return this.items.get(item);
  }
  access(item) {
    return this.items.get(item);
  }
  set(item, value) {
    this.items.set(item, value);
  }
  has(item) {
    return this.items.has(item);
  }
  invalidate(item) {
    this.items.delete(item);
  }
  bust() {
    this.items = /* @__PURE__ */ new WeakMap();
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/assets.mjs
function dataUrlToFile(url, filename, mimeType) {
  return fetch(url).then(function(res) {
    return res.arrayBuffer();
  }).then(function(buf) {
    return new File([buf], filename, { type: mimeType });
  });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/getIncrementedName.mjs
function getIncrementedName(name, others) {
  let result = name;
  const set = new Set(others);
  while (set.has(result)) {
    result = /^.*(\d+)$/.exec(result)?.[1] ? result.replace(/(\d+)(?=\D?)$/, (m) => {
      return (+m + 1).toString();
    }) : `${result} 1`;
  }
  return result;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/reordering/dgreensp/dgreensp.mjs
var DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var INTEGER_ZERO = "a0";
var SMALLEST_INTEGER = "A00000000000000000000000000";
function getIntegerLength(head) {
  if (head >= "a" && head <= "z") {
    return head.charCodeAt(0) - "a".charCodeAt(0) + 2;
  } else if (head >= "A" && head <= "Z") {
    return "Z".charCodeAt(0) - head.charCodeAt(0) + 2;
  } else {
    throw new Error("Invalid index key head: " + head);
  }
}
function validateInteger(int) {
  if (int.length !== getIntegerLength(int.charAt(0))) {
    throw new Error("invalid integer part of index key: " + int);
  }
}
function isNotUndefined(n) {
  if (n === void 0)
    throw Error("n is undefined");
}
function incrementInteger(x) {
  validateInteger(x);
  const [head, ...digs] = x.split("");
  let carry = true;
  for (let i = digs.length - 1; carry && i >= 0; i--) {
    const d = DIGITS.indexOf(digs[i]) + 1;
    if (d === DIGITS.length) {
      digs[i] = "0";
    } else {
      digs[i] = DIGITS.charAt(d);
      carry = false;
    }
  }
  if (carry) {
    if (head === "Z")
      return "a0";
    if (head === "z")
      return void 0;
    const h = String.fromCharCode(head.charCodeAt(0) + 1);
    if (h > "a") {
      digs.push("0");
    } else {
      digs.pop();
    }
    return h + digs.join("");
  } else {
    return head + digs.join("");
  }
}
function decrementInteger(x) {
  validateInteger(x);
  const [head, ...digs] = x.split("");
  let borrow = true;
  for (let i = digs.length - 1; borrow && i >= 0; i--) {
    const d = DIGITS.indexOf(digs[i]) - 1;
    if (d === -1) {
      digs[i] = DIGITS.slice(-1);
    } else {
      digs[i] = DIGITS.charAt(d);
      borrow = false;
    }
  }
  if (borrow) {
    if (head === "a")
      return "Z" + DIGITS.slice(-1);
    if (head === "A")
      return void 0;
    const h = String.fromCharCode(head.charCodeAt(0) - 1);
    if (h < "Z") {
      digs.push(DIGITS.slice(-1));
    } else {
      digs.pop();
    }
    return h + digs.join("");
  } else {
    return head + digs.join("");
  }
}
function midpoint(a, b) {
  if (b !== void 0 && a >= b) {
    throw new Error(a + " >= " + b);
  }
  if (a.slice(-1) === "0" || b && b.slice(-1) === "0") {
    throw new Error("trailing zero");
  }
  if (b) {
    let n = 0;
    while ((a.charAt(n) || "0") === b.charAt(n)) {
      n++;
    }
    if (n > 0) {
      return b.slice(0, n) + midpoint(a.slice(n), b.slice(n));
    }
  }
  const digitA = a ? DIGITS.indexOf(a.charAt(0)) : 0;
  const digitB = b !== void 0 ? DIGITS.indexOf(b.charAt(0)) : DIGITS.length;
  if (digitB - digitA > 1) {
    const midDigit = Math.round(0.5 * (digitA + digitB));
    return DIGITS.charAt(midDigit);
  } else {
    if (b && b.length > 1) {
      return b.slice(0, 1);
    } else {
      return DIGITS.charAt(digitA) + midpoint(a.slice(1), void 0);
    }
  }
}
function getIntegerPart(index2) {
  const integerPartLength = getIntegerLength(index2.charAt(0));
  if (integerPartLength > index2.length) {
    throw new Error("invalid index: " + index2);
  }
  return index2.slice(0, integerPartLength);
}
function validateOrder(index2) {
  if (index2 === SMALLEST_INTEGER) {
    throw new Error("invalid index: " + index2);
  }
  const i = getIntegerPart(index2);
  const f = index2.slice(i.length);
  if (f.slice(-1) === "0") {
    throw new Error("invalid index: " + index2);
  }
}
function generateKeyBetween(a, b) {
  if (a !== void 0)
    validateOrder(a);
  if (b !== void 0)
    validateOrder(b);
  if (a !== void 0 && b !== void 0 && a >= b) {
    throw new Error(a + " >= " + b);
  }
  if (a === void 0 && b === void 0) {
    return INTEGER_ZERO;
  }
  if (a === void 0) {
    if (b === void 0)
      throw Error("b is undefined");
    const ib2 = getIntegerPart(b);
    const fb2 = b.slice(ib2.length);
    if (ib2 === SMALLEST_INTEGER) {
      return ib2 + midpoint("", fb2);
    }
    if (ib2 < b) {
      return ib2;
    }
    const ibl = decrementInteger(ib2);
    isNotUndefined(ibl);
    return ibl;
  }
  if (b === void 0) {
    const ia2 = getIntegerPart(a);
    const fa2 = a.slice(ia2.length);
    const i2 = incrementInteger(ia2);
    return i2 === void 0 ? ia2 + midpoint(fa2, void 0) : i2;
  }
  const ia = getIntegerPart(a);
  const fa = a.slice(ia.length);
  const ib = getIntegerPart(b);
  const fb = b.slice(ib.length);
  if (ia === ib) {
    return ia + midpoint(fa, fb);
  }
  const i = incrementInteger(ia);
  isNotUndefined(i);
  return i < b ? i : ia + midpoint(fa, void 0);
}
function generateNKeysBetween(a, b, n) {
  if (n === 0)
    return [];
  if (n === 1)
    return [generateKeyBetween(a, b)];
  if (b === void 0) {
    let c2 = generateKeyBetween(a, b);
    const result = [c2];
    for (let i = 0; i < n - 1; i++) {
      c2 = generateKeyBetween(c2, b);
      result.push(c2);
    }
    return result;
  }
  if (a === void 0) {
    let c2 = generateKeyBetween(a, b);
    const result = [c2];
    for (let i = 0; i < n - 1; i++) {
      c2 = generateKeyBetween(a, c2);
      result.push(c2);
    }
    result.reverse();
    return result;
  }
  const mid = Math.floor(n / 2);
  const c = generateKeyBetween(a, b);
  return [...generateNKeysBetween(a, c, mid), c, ...generateNKeysBetween(c, b, n - mid - 1)];
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/reordering/reordering.mjs
function getIndicesBetween(below, above, n) {
  return generateNKeysBetween(below, above, n);
}
function getIndicesAbove(below, n) {
  return generateNKeysBetween(below, void 0, n);
}
function getIndicesBelow(above, n) {
  return generateNKeysBetween(void 0, above, n);
}
function getIndexBetween(below, above) {
  return generateNKeysBetween(below, above, 1)[0];
}
function getIndexAbove(below) {
  return generateNKeysBetween(below, void 0, 1)[0];
}
function getIndexBelow(above) {
  return generateNKeysBetween(void 0, above, 1)[0];
}
function getIndices(n, start = "a1") {
  return [start, ...generateNKeysBetween(start, void 0, n)];
}
function sortByIndex2(a, b) {
  if (a.index < b.index) {
    return -1;
  } else if (a.index > b.index) {
    return 1;
  }
  return 0;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/reorderShapes.mjs
function getReorderingShapesChanges(editor, operation, ids) {
  if (ids.length === 0)
    return [];
  const parents = /* @__PURE__ */ new Map();
  for (const shape of compact(ids.map((id) => editor.getShape(id)))) {
    const { parentId } = shape;
    if (!parents.has(parentId)) {
      parents.set(parentId, {
        children: compact(
          editor.getSortedChildIdsForParent(parentId).map((id) => editor.getShape(id))
        ),
        moving: /* @__PURE__ */ new Set()
      });
    }
    parents.get(parentId).moving.add(shape);
  }
  const changes = [];
  switch (operation) {
    case "toBack": {
      parents.forEach(({ moving, children }) => reorderToBack(moving, children, changes));
      break;
    }
    case "toFront": {
      parents.forEach(({ moving, children }) => reorderToFront(moving, children, changes));
      break;
    }
    case "forward": {
      parents.forEach(({ moving, children }) => reorderForward(moving, children, changes));
      break;
    }
    case "backward": {
      parents.forEach(({ moving, children }) => reorderBackward(moving, children, changes));
      break;
    }
  }
  return changes;
}
function reorderToBack(moving, children, changes) {
  const len = children.length;
  if (moving.size === len)
    return;
  let below;
  let above;
  for (let i = 0; i < len; i++) {
    const shape = children[i];
    if (moving.has(shape)) {
      below = shape.index;
      moving.delete(shape);
    } else {
      above = shape.index;
      break;
    }
  }
  if (moving.size === 0) {
    return;
  } else {
    const indices = getIndicesBetween(below, above, moving.size);
    changes.push(
      ...Array.from(moving.values()).sort(sortByIndex2).map((shape, i) => ({ ...shape, index: indices[i] }))
    );
  }
}
function reorderToFront(moving, children, changes) {
  const len = children.length;
  if (moving.size === len)
    return;
  let below;
  let above;
  for (let i = len - 1; i > -1; i--) {
    const shape = children[i];
    if (moving.has(shape)) {
      above = shape.index;
      moving.delete(shape);
    } else {
      below = shape.index;
      break;
    }
  }
  if (moving.size === 0) {
    return;
  } else {
    const indices = getIndicesBetween(below, above, moving.size);
    changes.push(
      ...Array.from(moving.values()).sort(sortByIndex2).map((shape, i) => ({ ...shape, index: indices[i] }))
    );
  }
}
function reorderForward(moving, children, changes) {
  const len = children.length;
  if (moving.size === len)
    return;
  let state = { name: "skipping" };
  for (let i = 0; i < len; i++) {
    const isMoving = moving.has(children[i]);
    switch (state.name) {
      case "skipping": {
        if (!isMoving)
          continue;
        state = { name: "selecting", selectIndex: i };
        break;
      }
      case "selecting": {
        if (isMoving)
          continue;
        const { selectIndex } = state;
        getIndicesBetween(children[i].index, children[i + 1]?.index, i - selectIndex).forEach(
          (index2, k) => changes.push({ ...children[selectIndex + k], index: index2 })
        );
        state = { name: "skipping" };
        break;
      }
    }
  }
}
function reorderBackward(moving, children, changes) {
  const len = children.length;
  if (moving.size === len)
    return;
  let state = { name: "skipping" };
  for (let i = len - 1; i > -1; i--) {
    const isMoving = moving.has(children[i]);
    switch (state.name) {
      case "skipping": {
        if (!isMoving)
          continue;
        state = { name: "selecting", selectIndex: i };
        break;
      }
      case "selecting": {
        if (isMoving)
          continue;
        getIndicesBetween(children[i - 1]?.index, children[i].index, state.selectIndex - i).forEach(
          (index2, k) => {
            changes.push({ ...children[i + k + 1], index: index2 });
          }
        );
        state = { name: "skipping" };
        break;
      }
    }
  }
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/rotation.mjs
function getRotationSnapshot({ editor }) {
  const {
    selectionRotation,
    selectionRotatedPageBounds: selectionBounds,
    inputs: { originPagePoint },
    selectedShapes
  } = editor;
  if (!selectionBounds) {
    return null;
  }
  const selectionPageCenter = selectionBounds.center.clone().rotWith(selectionBounds.point, selectionRotation);
  return {
    selectionPageCenter,
    initialCursorAngle: selectionPageCenter.angle(originPagePoint),
    initialSelectionRotation: selectionRotation,
    shapeSnapshots: selectedShapes.map((shape) => ({
      shape: structuredClone2(shape),
      initialPagePoint: editor.getShapePageTransform(shape.id).point()
    }))
  };
}
function applyRotationToSnapshotShapes({
  delta,
  editor,
  snapshot,
  stage
}) {
  const { selectionPageCenter, shapeSnapshots } = snapshot;
  editor.updateShapes(
    shapeSnapshots.map(({ shape, initialPagePoint }) => {
      const parentTransform = isShapeId(shape.parentId) ? editor.getShapePageTransform(shape.parentId) : Matrix2d.Identity();
      const newPagePoint = Vec2d.RotWith(initialPagePoint, selectionPageCenter, delta);
      const newLocalPoint = Matrix2d.applyToPoint(
        // use the current parent transform in case it has moved/resized since the start
        // (e.g. if rotating a shape at the edge of a group)
        Matrix2d.Inverse(parentTransform),
        newPagePoint
      );
      const newRotation = canonicalizeRotation(shape.rotation + delta);
      return {
        id: shape.id,
        type: shape.type,
        x: newLocalPoint.x,
        y: newLocalPoint.y,
        rotation: newRotation
      };
    })
  );
  const changes = [];
  shapeSnapshots.forEach(({ shape }) => {
    const current = editor.getShape(shape.id);
    if (!current)
      return;
    const util = editor.getShapeUtil(shape);
    if (stage === "start" || stage === "one-off") {
      const changeStart = util.onRotateStart?.(shape);
      if (changeStart)
        changes.push(changeStart);
    }
    const changeUpdate = util.onRotate?.(shape, current);
    if (changeUpdate)
      changes.push(changeUpdate);
    if (stage === "end" || stage === "one-off") {
      const changeEnd = util.onRotateEnd?.(shape, current);
      if (changeEnd)
        changes.push(changeEnd);
    }
  });
  if (changes.length > 0) {
    editor.updateShapes(changes);
  }
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/derivations/arrowBindingsIndex.mjs
var arrowBindingsIndex = (editor) => {
  const { store } = editor;
  const shapeHistory = store.query.filterHistory("shape");
  const arrowQuery = store.query.records("shape", () => ({ type: { eq: "arrow" } }));
  function fromScratch() {
    const allArrows = arrowQuery.value;
    const bindings2Arrows = {};
    for (const arrow3 of allArrows) {
      const { start, end } = arrow3.props;
      if (start.type === "binding") {
        const arrows = bindings2Arrows[start.boundShapeId];
        if (arrows)
          arrows.push({ arrowId: arrow3.id, handleId: "start" });
        else
          bindings2Arrows[start.boundShapeId] = [{ arrowId: arrow3.id, handleId: "start" }];
      }
      if (end.type === "binding") {
        const arrows = bindings2Arrows[end.boundShapeId];
        if (arrows)
          arrows.push({ arrowId: arrow3.id, handleId: "end" });
        else
          bindings2Arrows[end.boundShapeId] = [{ arrowId: arrow3.id, handleId: "end" }];
      }
    }
    return bindings2Arrows;
  }
  return computed("arrowBindingsIndex", (_lastValue, lastComputedEpoch) => {
    if (isUninitialized(_lastValue)) {
      return fromScratch();
    }
    const lastValue = _lastValue;
    const diff = shapeHistory.getDiffSince(lastComputedEpoch);
    if (diff === RESET_VALUE) {
      return fromScratch();
    }
    let nextValue = void 0;
    function ensureNewArray(boundShapeId) {
      if (!nextValue) {
        nextValue = { ...lastValue };
      }
      if (!nextValue[boundShapeId]) {
        nextValue[boundShapeId] = [];
      } else if (nextValue[boundShapeId] === lastValue[boundShapeId]) {
        nextValue[boundShapeId] = [...nextValue[boundShapeId]];
      }
    }
    function removingBinding(boundShapeId, arrowId, handleId) {
      ensureNewArray(boundShapeId);
      nextValue[boundShapeId] = nextValue[boundShapeId].filter(
        (binding) => binding.arrowId !== arrowId || binding.handleId !== handleId
      );
      if (nextValue[boundShapeId].length === 0) {
        delete nextValue[boundShapeId];
      }
    }
    function addBinding(boundShapeId, arrowId, handleId) {
      ensureNewArray(boundShapeId);
      nextValue[boundShapeId].push({ arrowId, handleId });
    }
    for (const changes of diff) {
      for (const newShape of Object.values(changes.added)) {
        if (editor.isShapeOfType(newShape, "arrow")) {
          const { start, end } = newShape.props;
          if (start.type === "binding") {
            addBinding(start.boundShapeId, newShape.id, "start");
          }
          if (end.type === "binding") {
            addBinding(end.boundShapeId, newShape.id, "end");
          }
        }
      }
      for (const [prev, next] of Object.values(changes.updated)) {
        if (!editor.isShapeOfType(prev, "arrow") || !editor.isShapeOfType(next, "arrow"))
          continue;
        for (const handle of ["start", "end"]) {
          const prevTerminal = prev.props[handle];
          const nextTerminal = next.props[handle];
          if (prevTerminal.type === "binding" && nextTerminal.type === "point") {
            removingBinding(prevTerminal.boundShapeId, prev.id, handle);
          } else if (prevTerminal.type === "point" && nextTerminal.type === "binding") {
            addBinding(nextTerminal.boundShapeId, next.id, handle);
          } else if (prevTerminal.type === "binding" && nextTerminal.type === "binding" && prevTerminal.boundShapeId !== nextTerminal.boundShapeId) {
            removingBinding(prevTerminal.boundShapeId, prev.id, handle);
            addBinding(nextTerminal.boundShapeId, next.id, handle);
          }
        }
      }
      for (const prev of Object.values(changes.removed)) {
        if (editor.isShapeOfType(prev, "arrow")) {
          const { start, end } = prev.props;
          if (start.type === "binding") {
            removingBinding(start.boundShapeId, prev.id, "start");
          }
          if (end.type === "binding") {
            removingBinding(end.boundShapeId, prev.id, "end");
          }
        }
      }
    }
    return nextValue ?? lastValue;
  });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/derivations/parentsToChildren.mjs
var parentsToChildren = (store) => {
  const shapeIdsQuery = store.query.ids("shape");
  function fromScratch() {
    const result = {};
    const shapeIds = shapeIdsQuery.value;
    const shapes = Array(shapeIds.size);
    shapeIds.forEach((id) => shapes.push(store.get(id)));
    shapes.sort(sortByIndex2);
    shapes.forEach((shape) => {
      if (!result[shape.parentId]) {
        result[shape.parentId] = [];
      }
      result[shape.parentId].push(shape.id);
    });
    return result;
  }
  return computed(
    "parentsToChildrenWithIndexes",
    (lastValue, lastComputedEpoch) => {
      if (isUninitialized(lastValue)) {
        return fromScratch();
      }
      const diff = store.history.getDiffSince(lastComputedEpoch);
      if (diff === RESET_VALUE) {
        return fromScratch();
      }
      if (diff.length === 0)
        return lastValue;
      let newValue = null;
      const ensureNewArray = (parentId) => {
        if (!newValue) {
          newValue = { ...lastValue };
        }
        if (!newValue[parentId]) {
          newValue[parentId] = [];
        } else if (newValue[parentId] === lastValue[parentId]) {
          newValue[parentId] = [...newValue[parentId]];
        }
      };
      const toSort = /* @__PURE__ */ new Set();
      let changes;
      for (let i = 0, n = diff.length; i < n; i++) {
        changes = diff[i];
        for (const record of Object.values(changes.added)) {
          if (!isShape(record))
            continue;
          ensureNewArray(record.parentId);
          newValue[record.parentId].push(record.id);
          toSort.add(newValue[record.parentId]);
        }
        for (const [from, to] of Object.values(changes.updated)) {
          if (!isShape(to))
            continue;
          if (!isShape(from))
            continue;
          if (from.parentId !== to.parentId) {
            ensureNewArray(from.parentId);
            ensureNewArray(to.parentId);
            newValue[from.parentId].splice(newValue[from.parentId].indexOf(to.id), 1);
            newValue[to.parentId].push(to.id);
            toSort.add(newValue[to.parentId]);
          } else if (from.index !== to.index) {
            ensureNewArray(to.parentId);
            const idx = newValue[to.parentId].indexOf(to.id);
            newValue[to.parentId][idx] = to.id;
            toSort.add(newValue[to.parentId]);
          }
        }
        for (const record of Object.values(changes.removed)) {
          if (!isShape(record))
            continue;
          ensureNewArray(record.parentId);
          newValue[record.parentId].splice(newValue[record.parentId].indexOf(record.id), 1);
        }
      }
      for (const arr of toSort) {
        const shapesInArr = compact(arr.map((id) => store.get(id)));
        shapesInArr.sort(sortByIndex2);
        arr.splice(0, arr.length, ...shapesInArr.map((shape) => shape.id));
      }
      return newValue ?? lastValue;
    }
  );
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs
var isShapeInPage = (store, pageId, shape) => {
  while (!isPageId(shape.parentId)) {
    const parent = store.get(shape.parentId);
    if (!parent)
      return false;
    shape = parent;
  }
  return shape.parentId === pageId;
};
var deriveShapeIdsInCurrentPage = (store, getCurrentPageId) => {
  const shapesIndex = store.query.ids("shape");
  let lastPageId = null;
  function fromScratch() {
    const currentPageId = getCurrentPageId();
    lastPageId = currentPageId;
    return new Set(
      [...shapesIndex.value].filter((id) => isShapeInPage(store, currentPageId, store.get(id)))
    );
  }
  return computed("_shapeIdsInCurrentPage", (prevValue, lastComputedEpoch) => {
    if (isUninitialized(prevValue)) {
      return fromScratch();
    }
    const currentPageId = getCurrentPageId();
    if (currentPageId !== lastPageId) {
      return fromScratch();
    }
    const diff = store.history.getDiffSince(lastComputedEpoch);
    if (diff === RESET_VALUE) {
      return fromScratch();
    }
    const builder = new IncrementalSetConstructor(
      prevValue
    );
    for (const changes of diff) {
      for (const record of Object.values(changes.added)) {
        if (isShape(record) && isShapeInPage(store, currentPageId, record)) {
          builder.add(record.id);
        }
      }
      for (const [_from, to] of Object.values(changes.updated)) {
        if (isShape(to)) {
          if (isShapeInPage(store, currentPageId, to)) {
            builder.add(to.id);
          } else {
            builder.remove(to.id);
          }
        }
      }
      for (const id of Object.keys(changes.removed)) {
        if (isShapeId(id)) {
          builder.remove(id);
        }
      }
    }
    const result = builder.get();
    if (!result) {
      return prevValue;
    }
    return withDiff(result.value, result.diff);
  });
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/ClickManager.mjs
var MAX_CLICK_DISTANCE = 40;
var ClickManager = class {
  constructor(editor) {
    this.editor = editor;
  }
  _clickId = "";
  _clickTimeout;
  _clickScreenPoint;
  _previousScreenPoint;
  _getClickTimeout = (state, id = uniqueId()) => {
    this._clickId = id;
    clearTimeout(this._clickTimeout);
    this._clickTimeout = setTimeout(
      () => {
        if (this._clickState === state && this._clickId === id) {
          switch (this._clickState) {
            case "pendingTriple": {
              this.editor.dispatch({
                ...this.lastPointerInfo,
                type: "click",
                name: "double_click",
                phase: "settle"
              });
              break;
            }
            case "pendingQuadruple": {
              this.editor.dispatch({
                ...this.lastPointerInfo,
                type: "click",
                name: "triple_click",
                phase: "settle"
              });
              break;
            }
            case "pendingOverflow": {
              this.editor.dispatch({
                ...this.lastPointerInfo,
                type: "click",
                name: "quadruple_click",
                phase: "settle"
              });
              break;
            }
            default: {
            }
          }
          this._clickState = "idle";
        }
      },
      state === "idle" || state === "pendingDouble" ? DOUBLE_CLICK_DURATION : MULTI_CLICK_DURATION
    );
  };
  /**
   * The current click state.
   *
   * @internal
   */
  _clickState = "idle";
  /**
   * The current click state.
   *
   * @public
   */
  get clickState() {
    return this._clickState;
  }
  lastPointerInfo = {};
  /**
   * Start the double click timeout.
   *
   * @param info - The event info.
   */
  transformPointerDownEvent = (info) => {
    if (!this._clickState)
      return info;
    this._clickScreenPoint = Vec2d.From(info.point);
    if (this._previousScreenPoint && this._previousScreenPoint.dist(this._clickScreenPoint) > MAX_CLICK_DISTANCE) {
      this._clickState = "idle";
    }
    this._previousScreenPoint = this._clickScreenPoint;
    this.lastPointerInfo = info;
    switch (this._clickState) {
      case "idle": {
        this._clickState = "pendingDouble";
        this._clickTimeout = this._getClickTimeout(this._clickState);
        return info;
      }
      case "pendingDouble": {
        this._clickState = "pendingTriple";
        this._clickTimeout = this._getClickTimeout(this._clickState);
        return {
          ...info,
          type: "click",
          name: "double_click",
          phase: "down"
        };
      }
      case "pendingTriple": {
        this._clickState = "pendingQuadruple";
        this._clickTimeout = this._getClickTimeout(this._clickState);
        return {
          ...info,
          type: "click",
          name: "triple_click",
          phase: "down"
        };
      }
      case "pendingQuadruple": {
        this._clickState = "pendingOverflow";
        this._clickTimeout = this._getClickTimeout(this._clickState);
        return {
          ...info,
          type: "click",
          name: "quadruple_click",
          phase: "down"
        };
      }
      case "pendingOverflow": {
        this._clickState = "overflow";
        this._clickTimeout = this._getClickTimeout(this._clickState);
        return info;
      }
      default: {
        this._clickTimeout = this._getClickTimeout(this._clickState);
        return info;
      }
    }
  };
  /**
   * Emit click_up events on pointer up.
   *
   * @param info - The event info.
   */
  transformPointerUpEvent = (info) => {
    if (!this._clickState)
      return info;
    this._clickScreenPoint = Vec2d.From(info.point);
    switch (this._clickState) {
      case "pendingTriple": {
        return {
          ...this.lastPointerInfo,
          type: "click",
          name: "double_click",
          phase: "up"
        };
      }
      case "pendingQuadruple": {
        return {
          ...this.lastPointerInfo,
          type: "click",
          name: "triple_click",
          phase: "up"
        };
      }
      case "pendingOverflow": {
        return {
          ...this.lastPointerInfo,
          type: "click",
          name: "quadruple_click",
          phase: "up"
        };
      }
      default: {
        return info;
      }
    }
  };
  /**
   * Cancel the double click timeout.
   *
   * @internal
   */
  cancelDoubleClickTimeout = () => {
    this._clickTimeout = clearTimeout(this._clickTimeout);
    this._clickState = "idle";
  };
  /**
   * Handle a move event, possibly cancelling the click timeout.
   *
   * @internal
   */
  handleMove = () => {
    if (this._clickState !== "idle" && this._clickScreenPoint && this._clickScreenPoint.dist(this.editor.inputs.currentScreenPoint) > (this.editor.instanceState.isCoarsePointer ? COARSE_DRAG_DISTANCE : DRAG_DISTANCE)) {
      this.cancelDoubleClickTimeout();
    }
  };
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/EnvironmentManager.mjs
var EnvironmentManager = class {
  constructor(editor) {
    this.editor = editor;
    if (typeof window !== "undefined" && "navigator" in window) {
      this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
      this.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i);
      this.isChromeForIos = /crios.*safari/i.test(navigator.userAgent);
      this.isFirefox = /firefox/i.test(navigator.userAgent);
      this.isAndroid = /android/i.test(navigator.userAgent);
    } else {
      this.isSafari = false;
      this.isIos = false;
      this.isChromeForIos = false;
      this.isFirefox = false;
      this.isAndroid = false;
    }
  }
  /**
   * Whether the editor is running in Safari.
   *
   * @public
   */
  isSafari;
  /**
   * Whether the editor is running on iOS.
   *
   * @public
   */
  isIos;
  /**
   * Whether the editor is running on iOS.
   *
   * @public
   */
  isChromeForIos;
  /**
   * Whether the editor is running on Firefox.
   *
   * @public
   */
  isFirefox;
  /**
   * Whether the editor is running on Android.
   *
   * @public
   */
  isAndroid;
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/Stack.mjs
function stack2(items) {
  if (items) {
    let result = EMPTY_STACK_ITEM;
    while (items.length) {
      result = result.push(items.pop());
    }
    return result;
  }
  return EMPTY_STACK_ITEM;
}
var EmptyStackItem = class {
  length = 0;
  head = null;
  tail = this;
  push(head) {
    return new StackItem(head, this);
  }
  toArray() {
    return EMPTY_ARRAY;
  }
  [Symbol.iterator]() {
    return {
      next() {
        return { value: void 0, done: true };
      }
    };
  }
};
var EMPTY_STACK_ITEM = new EmptyStackItem();
var StackItem = class _StackItem {
  constructor(head, tail) {
    this.head = head;
    this.tail = tail;
    this.length = tail.length + 1;
  }
  length;
  push(head) {
    return new _StackItem(head, this);
  }
  toArray() {
    return Array.from(this);
  }
  [Symbol.iterator]() {
    let stack22 = this;
    return {
      next() {
        if (stack22.length) {
          const value = stack22.head;
          stack22 = stack22.tail;
          return { value, done: false };
        } else {
          return { value: void 0, done: true };
        }
      }
    };
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/HistoryManager.mjs
var HistoryManager = class {
  // A flag for whether the user is in a batch operation
  constructor(ctx, annotateError2) {
    this.ctx = ctx;
    this.annotateError = annotateError2;
  }
  _undos = atom("HistoryManager.undos", stack2());
  // Updated by each action that includes and undo
  _redos = atom("HistoryManager.redos", stack2());
  // Updated when a user undoes
  _batchDepth = 0;
  onBatchComplete = () => void 0;
  _commands = {};
  get numUndos() {
    return this._undos.value.length;
  }
  get numRedos() {
    return this._redos.value.length;
  }
  createCommand = (name, constructor, handle) => {
    if (this._commands[name]) {
      throw new Error(`Duplicate command: ${name}`);
    }
    this._commands[name] = handle;
    const exec = (...args) => {
      if (!this._batchDepth) {
        this.batch(() => exec(...args));
        return this.ctx;
      }
      const result = constructor(...args);
      if (!result) {
        return this.ctx;
      }
      const { data, ephemeral, squashing, preservesRedoStack } = result;
      this.ignoringUpdates((undos, redos) => {
        handle.do(data);
        return { undos, redos };
      });
      if (!ephemeral) {
        const prev = this._undos.value.head;
        if (squashing && prev && prev.type === "command" && prev.name === name && prev.preservesRedoStack === preservesRedoStack) {
          this._undos.update(
            (undos) => undos.tail.push({
              ...prev,
              id: uniqueId(),
              data: devFreeze(handle.squash(prev.data, data))
            })
          );
        } else {
          this._undos.update(
            (undos) => undos.push({
              type: "command",
              name,
              data: devFreeze(data),
              id: uniqueId(),
              preservesRedoStack
            })
          );
        }
        if (!result.preservesRedoStack) {
          this._redos.set(stack2());
        }
        this.ctx.emit("change-history", { reason: "push" });
      }
      return this.ctx;
    };
    return exec;
  };
  batch = (fn) => {
    try {
      this._batchDepth++;
      if (this._batchDepth === 1) {
        transact(() => {
          const mostRecentActionId = this._undos.value.head?.id;
          fn();
          if (mostRecentActionId !== this._undos.value.head?.id) {
            this.onBatchComplete();
          }
        });
      } else {
        fn();
      }
    } catch (error) {
      this.annotateError(error);
      throw error;
    } finally {
      this._batchDepth--;
    }
    return this;
  };
  ignoringUpdates = (fn) => {
    let undos = this._undos.value;
    let redos = this._redos.value;
    this._undos.set(stack2());
    this._redos.set(stack2());
    try {
      ;
      ({ undos, redos } = transact(() => fn(undos, redos)));
    } finally {
      this._undos.set(undos);
      this._redos.set(redos);
    }
  };
  // History
  _undo = ({
    pushToRedoStack,
    toMark = void 0
  }) => {
    this.ignoringUpdates((undos, redos) => {
      if (undos.length === 0) {
        return { undos, redos };
      }
      while (undos.head?.type === "STOP") {
        const mark = undos.head;
        undos = undos.tail;
        if (pushToRedoStack) {
          redos = redos.push(mark);
        }
        if (mark.id === toMark) {
          this.ctx.emit(
            "change-history",
            pushToRedoStack ? { reason: "undo" } : { reason: "bail", markId: toMark }
          );
          return { undos, redos };
        }
      }
      if (undos.length === 0) {
        this.ctx.emit(
          "change-history",
          pushToRedoStack ? { reason: "undo" } : { reason: "bail", markId: toMark }
        );
        return { undos, redos };
      }
      while (undos.head) {
        const command = undos.head;
        undos = undos.tail;
        if (pushToRedoStack) {
          redos = redos.push(command);
        }
        if (command.type === "STOP") {
          if (command.onUndo && (!toMark || command.id === toMark)) {
            this.ctx.emit(
              "change-history",
              pushToRedoStack ? { reason: "undo" } : { reason: "bail", markId: toMark }
            );
            return { undos, redos };
          }
        } else {
          const handler = this._commands[command.name];
          handler.undo(command.data);
        }
      }
      this.ctx.emit(
        "change-history",
        pushToRedoStack ? { reason: "undo" } : { reason: "bail", markId: toMark }
      );
      return { undos, redos };
    });
    return this;
  };
  undo = () => {
    this._undo({ pushToRedoStack: true });
    return this;
  };
  redo = () => {
    this.ignoringUpdates((undos, redos) => {
      if (redos.length === 0) {
        return { undos, redos };
      }
      while (redos.head?.type === "STOP") {
        undos = undos.push(redos.head);
        redos = redos.tail;
      }
      if (redos.length === 0) {
        this.ctx.emit("change-history", { reason: "redo" });
        return { undos, redos };
      }
      while (redos.head) {
        const command = redos.head;
        undos = undos.push(redos.head);
        redos = redos.tail;
        if (command.type === "STOP") {
          if (command.onRedo) {
            break;
          }
        } else {
          const handler = this._commands[command.name];
          if (handler.redo) {
            handler.redo(command.data);
          } else {
            handler.do(command.data);
          }
        }
      }
      this.ctx.emit("change-history", { reason: "redo" });
      return { undos, redos };
    });
    return this;
  };
  bail = () => {
    this._undo({ pushToRedoStack: false });
    return this;
  };
  bailToMark = (id) => {
    this._undo({ pushToRedoStack: false, toMark: id });
    return this;
  };
  mark = (id = uniqueId(), onUndo = true, onRedo = true) => {
    const mostRecent = this._undos.value.head;
    if (mostRecent && mostRecent.type === "STOP") {
      if (mostRecent.id === id && mostRecent.onUndo === onUndo && mostRecent.onRedo === onRedo) {
        return mostRecent.id;
      }
    }
    this._undos.update((undos) => undos.push({ type: "STOP", id, onUndo, onRedo }));
    this.ctx.emit("mark-history", { id });
    return id;
  };
  clear() {
    this._undos.set(stack2());
    this._redos.set(stack2());
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/SideEffectManager.mjs
var SideEffectManager = class {
  constructor(editor) {
    this.editor = editor;
    editor.store.onBeforeCreate = (record, source) => {
      const handlers = this._beforeCreateHandlers[record.typeName];
      if (handlers) {
        let r = record;
        for (const handler of handlers) {
          r = handler(r, source);
        }
        return r;
      }
      return record;
    };
    editor.store.onAfterCreate = (record, source) => {
      const handlers = this._afterCreateHandlers[record.typeName];
      if (handlers) {
        for (const handler of handlers) {
          handler(record, source);
        }
      }
    };
    editor.store.onBeforeChange = (prev, next, source) => {
      const handlers = this._beforeChangeHandlers[next.typeName];
      if (handlers) {
        let r = next;
        for (const handler of handlers) {
          r = handler(prev, r, source);
        }
        return r;
      }
      return next;
    };
    let updateDepth = 0;
    editor.store.onAfterChange = (prev, next, source) => {
      updateDepth++;
      if (updateDepth > 1e3) {
        console.error("[CleanupManager.onAfterChange] Maximum update depth exceeded, bailing out.");
      } else {
        const handlers = this._afterChangeHandlers[next.typeName];
        if (handlers) {
          for (const handler of handlers) {
            handler(prev, next, source);
          }
        }
      }
      updateDepth--;
    };
    editor.store.onBeforeDelete = (record, source) => {
      const handlers = this._beforeDeleteHandlers[record.typeName];
      if (handlers) {
        for (const handler of handlers) {
          if (handler(record, source) === false) {
            return false;
          }
        }
      }
    };
    editor.store.onAfterDelete = (record, source) => {
      const handlers = this._afterDeleteHandlers[record.typeName];
      if (handlers) {
        for (const handler of handlers) {
          handler(record, source);
        }
      }
    };
    editor.history.onBatchComplete = () => {
      this._batchCompleteHandlers.forEach((fn) => fn());
    };
  }
  _beforeCreateHandlers = {};
  _afterCreateHandlers = {};
  _beforeChangeHandlers = {};
  _afterChangeHandlers = {};
  _beforeDeleteHandlers = {};
  _afterDeleteHandlers = {};
  _batchCompleteHandlers = [];
  registerBeforeCreateHandler(typeName, handler) {
    const handlers = this._beforeCreateHandlers[typeName];
    if (!handlers)
      this._beforeCreateHandlers[typeName] = [];
    this._beforeCreateHandlers[typeName].push(handler);
    return () => remove(this._beforeCreateHandlers[typeName], handler);
  }
  registerAfterCreateHandler(typeName, handler) {
    const handlers = this._afterCreateHandlers[typeName];
    if (!handlers)
      this._afterCreateHandlers[typeName] = [];
    this._afterCreateHandlers[typeName].push(handler);
    return () => remove(this._afterCreateHandlers[typeName], handler);
  }
  registerBeforeChangeHandler(typeName, handler) {
    const handlers = this._beforeChangeHandlers[typeName];
    if (!handlers)
      this._beforeChangeHandlers[typeName] = [];
    this._beforeChangeHandlers[typeName].push(handler);
    return () => remove(this._beforeChangeHandlers[typeName], handler);
  }
  registerAfterChangeHandler(typeName, handler) {
    const handlers = this._afterChangeHandlers[typeName];
    if (!handlers)
      this._afterChangeHandlers[typeName] = [];
    this._afterChangeHandlers[typeName].push(handler);
    return () => remove(this._afterChangeHandlers[typeName], handler);
  }
  registerBeforeDeleteHandler(typeName, handler) {
    const handlers = this._beforeDeleteHandlers[typeName];
    if (!handlers)
      this._beforeDeleteHandlers[typeName] = [];
    this._beforeDeleteHandlers[typeName].push(handler);
    return () => remove(this._beforeDeleteHandlers[typeName], handler);
  }
  registerAfterDeleteHandler(typeName, handler) {
    const handlers = this._afterDeleteHandlers[typeName];
    if (!handlers)
      this._afterDeleteHandlers[typeName] = [];
    this._afterDeleteHandlers[typeName].push(handler);
    return () => remove(this._afterDeleteHandlers[typeName], handler);
  }
  /**
   * Register a handler to be called when a store completes a batch.
   *
   * @example
   * ```ts
   * let count = 0
   *
   * editor.cleanup.registerBatchCompleteHandler(() => count++)
   *
   * editor.selectAll()
   * expect(count).toBe(1)
   *
   * editor.batch(() => {
   *	editor.selectNone()
   * 	editor.selectAll()
   * })
   *
   * expect(count).toBe(2)
   * ```
   *
   * @param handler - The handler to call
   *
   * @public
   */
  registerBatchCompleteHandler(handler) {
    this._batchCompleteHandlers.push(handler);
    return () => remove(this._batchCompleteHandlers, handler);
  }
};
function remove(array2, item) {
  const index2 = array2.indexOf(item);
  if (index2 >= 0) {
    array2.splice(index2, 1);
  }
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/SnapManager.mjs
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp(target, key, result);
  return result;
};
var round = (x) => {
  const decimalPlacesTolerance = 8;
  return Math.round(x * 10 ** decimalPlacesTolerance) / 10 ** decimalPlacesTolerance;
};
function findAdjacentGaps(gaps, shapeId, gapLength, direction, intersection) {
  const matches = gaps.filter(
    (gap) => (direction === "forward" ? gap.startNode.id === shapeId : gap.endNode.id === shapeId) && round(gap.length) === round(gapLength) && rangeIntersection(
      gap.breadthIntersection[0],
      gap.breadthIntersection[1],
      intersection[0],
      intersection[1]
    )
  );
  if (matches.length === 0)
    return [];
  const nextNodes = /* @__PURE__ */ new Set();
  matches.forEach((match) => {
    const node = direction === "forward" ? match.endNode.id : match.startNode.id;
    if (!nextNodes.has(node)) {
      nextNodes.add(node);
      const foundGaps = findAdjacentGaps(
        gaps,
        node,
        gapLength,
        direction,
        rangeIntersection(
          match.breadthIntersection[0],
          match.breadthIntersection[1],
          intersection[0],
          intersection[1]
        )
      );
      matches.push(...foundGaps);
    }
  });
  return matches;
}
function dedupeGapSnaps(snaps) {
  snaps.sort((a, b) => b.gaps.length - a.gaps.length);
  for (let i = snaps.length - 1; i > 0; i--) {
    const snap = snaps[i];
    for (let j = i - 1; j >= 0; j--) {
      const otherSnap = snaps[j];
      if (otherSnap.direction === snap.direction && snap.gaps.every(
        (gap) => otherSnap.gaps.some(
          (otherGap) => round(gap.startEdge[0].x) === round(otherGap.startEdge[0].x) && round(gap.startEdge[0].y) === round(otherGap.startEdge[0].y) && round(gap.startEdge[1].x) === round(otherGap.startEdge[1].x) && round(gap.startEdge[1].y) === round(otherGap.startEdge[1].y)
        ) && otherSnap.gaps.some(
          (otherGap) => round(gap.endEdge[0].x) === round(otherGap.endEdge[0].x) && round(gap.endEdge[0].y) === round(otherGap.endEdge[0].y) && round(gap.endEdge[1].x) === round(otherGap.endEdge[1].x) && round(gap.endEdge[1].y) === round(otherGap.endEdge[1].y)
        )
      )) {
        snaps.splice(i, 1);
        break;
      }
    }
  }
}
var SnapManager = class {
  constructor(editor) {
    this.editor = editor;
  }
  _snapLines = atom("snapLines", void 0);
  get lines() {
    return this._snapLines.value ?? EMPTY_ARRAY;
  }
  clear() {
    if (this.lines.length) {
      this._snapLines.set(void 0);
    }
  }
  setLines(lines) {
    this._snapLines.set(lines);
  }
  get snapPointsCache() {
    const { editor } = this;
    return editor.store.createComputedCache("snapPoints", (shape) => {
      const pageTransfrorm = editor.getShapePageTransform(shape.id);
      if (!pageTransfrorm)
        return void 0;
      const snapPoints = this.editor.getShapeGeometry(shape).snapPoints;
      return snapPoints.map((point, i) => {
        const { x, y } = Matrix2d.applyToPoint(pageTransfrorm, point);
        return { x, y, id: `${shape.id}:${i}` };
      });
    });
  }
  get snapThreshold() {
    return 8 / this.editor.zoomLevel;
  }
  get snappableShapes() {
    const { editor } = this;
    const { selectedShapeIds, renderingBounds } = editor;
    const snappableShapes = [];
    const collectSnappableShapesFromParent = (parentId) => {
      const sortedChildIds = editor.getSortedChildIdsForParent(parentId);
      for (const childId of sortedChildIds) {
        if (selectedShapeIds.includes(childId))
          continue;
        const childShape = editor.getShape(childId);
        if (!childShape)
          continue;
        const util = editor.getShapeUtil(childShape);
        if (!util.canSnap(childShape))
          continue;
        const pageBounds = editor.getShapePageBounds(childId);
        if (!(pageBounds && renderingBounds.includes(pageBounds)))
          continue;
        if (editor.isShapeOfType(childShape, "group")) {
          collectSnappableShapesFromParent(childId);
          continue;
        }
        snappableShapes.push({
          id: childId,
          pageBounds,
          isClosed: editor.getShapeGeometry(childShape).isClosed
        });
      }
    };
    collectSnappableShapesFromParent(this.currentCommonAncestor ?? editor.currentPageId);
    return snappableShapes;
  }
  get currentCommonAncestor() {
    return this.editor.findCommonAncestor(this.editor.selectedShapes);
  }
  get snappablePoints() {
    const { snappableShapes, snapPointsCache } = this;
    const result = [];
    snappableShapes.forEach((shape) => {
      const snapPoints = snapPointsCache.get(shape.id);
      if (snapPoints) {
        result.push(...snapPoints);
      }
    });
    return result;
  }
  get visibleGaps() {
    const horizontal = [];
    const vertical = [];
    let startNode, endNode;
    const sortedShapesOnCurrentPageHorizontal = this.snappableShapes.sort((a, b) => {
      return a.pageBounds.minX - b.pageBounds.minX;
    });
    for (let i = 0; i < sortedShapesOnCurrentPageHorizontal.length; i++) {
      startNode = sortedShapesOnCurrentPageHorizontal[i];
      for (let j = i + 1; j < sortedShapesOnCurrentPageHorizontal.length; j++) {
        endNode = sortedShapesOnCurrentPageHorizontal[j];
        if (
          // is there space between the boxes
          startNode.pageBounds.maxX < endNode.pageBounds.minX && // and they overlap in the y axis
          rangesOverlap(
            startNode.pageBounds.minY,
            startNode.pageBounds.maxY,
            endNode.pageBounds.minY,
            endNode.pageBounds.maxY
          )
        ) {
          horizontal.push({
            startNode,
            endNode,
            startEdge: [
              new Vec2d(startNode.pageBounds.maxX, startNode.pageBounds.minY),
              new Vec2d(startNode.pageBounds.maxX, startNode.pageBounds.maxY)
            ],
            endEdge: [
              new Vec2d(endNode.pageBounds.minX, endNode.pageBounds.minY),
              new Vec2d(endNode.pageBounds.minX, endNode.pageBounds.maxY)
            ],
            length: endNode.pageBounds.minX - startNode.pageBounds.maxX,
            breadthIntersection: rangeIntersection(
              startNode.pageBounds.minY,
              startNode.pageBounds.maxY,
              endNode.pageBounds.minY,
              endNode.pageBounds.maxY
            )
          });
        }
      }
    }
    const sortedShapesOnCurrentPageVertical = sortedShapesOnCurrentPageHorizontal.sort((a, b) => {
      return a.pageBounds.minY - b.pageBounds.minY;
    });
    for (let i = 0; i < sortedShapesOnCurrentPageVertical.length; i++) {
      startNode = sortedShapesOnCurrentPageVertical[i];
      for (let j = i + 1; j < sortedShapesOnCurrentPageVertical.length; j++) {
        endNode = sortedShapesOnCurrentPageVertical[j];
        if (
          // is there space between the boxes
          startNode.pageBounds.maxY < endNode.pageBounds.minY && // do they overlap in the x axis
          rangesOverlap(
            startNode.pageBounds.minX,
            startNode.pageBounds.maxX,
            endNode.pageBounds.minX,
            endNode.pageBounds.maxX
          )
        ) {
          vertical.push({
            startNode,
            endNode,
            startEdge: [
              new Vec2d(startNode.pageBounds.minX, startNode.pageBounds.maxY),
              new Vec2d(startNode.pageBounds.maxX, startNode.pageBounds.maxY)
            ],
            endEdge: [
              new Vec2d(endNode.pageBounds.minX, endNode.pageBounds.minY),
              new Vec2d(endNode.pageBounds.maxX, endNode.pageBounds.minY)
            ],
            length: endNode.pageBounds.minY - startNode.pageBounds.maxY,
            breadthIntersection: rangeIntersection(
              startNode.pageBounds.minX,
              startNode.pageBounds.maxX,
              endNode.pageBounds.minX,
              endNode.pageBounds.maxX
            )
          });
        }
      }
    }
    return { horizontal, vertical };
  }
  snapTranslate({
    lockedAxis,
    initialSelectionPageBounds,
    initialSelectionSnapPoints,
    dragDelta
  }) {
    const { snappablePoints: visibleSnapPointsNotInSelection, snapThreshold } = this;
    const selectionPageBounds = initialSelectionPageBounds.clone().translate(dragDelta);
    const selectionSnapPoints = initialSelectionSnapPoints.map(({ x, y }, i) => ({
      id: "selection:" + i,
      x: x + dragDelta.x,
      y: y + dragDelta.y
    }));
    const otherNodeSnapPoints = visibleSnapPointsNotInSelection;
    const nearestSnapsX = [];
    const nearestSnapsY = [];
    const minOffset = new Vec2d(snapThreshold, snapThreshold);
    this.collectPointSnaps({
      minOffset,
      nearestSnapsX,
      nearestSnapsY,
      otherNodeSnapPoints,
      selectionSnapPoints
    });
    this.collectGapSnaps({
      selectionPageBounds,
      nearestSnapsX,
      nearestSnapsY,
      minOffset
    });
    const nudge = new Vec2d(
      lockedAxis === "x" ? 0 : nearestSnapsX[0]?.nudge ?? 0,
      lockedAxis === "y" ? 0 : nearestSnapsY[0]?.nudge ?? 0
    );
    minOffset.x = 0;
    minOffset.y = 0;
    nearestSnapsX.length = 0;
    nearestSnapsY.length = 0;
    selectionSnapPoints.forEach((s) => {
      s.x += nudge.x;
      s.y += nudge.y;
    });
    selectionPageBounds.translate(nudge);
    this.collectPointSnaps({
      minOffset,
      nearestSnapsX,
      nearestSnapsY,
      otherNodeSnapPoints,
      selectionSnapPoints
    });
    this.collectGapSnaps({
      selectionPageBounds,
      nearestSnapsX,
      nearestSnapsY,
      minOffset
    });
    const pointSnapsLines = this.getPointSnapLines({
      nearestSnapsX,
      nearestSnapsY
    });
    const gapSnapLines = this.getGapSnapLines({
      selectionPageBounds,
      nearestSnapsX,
      nearestSnapsY
    });
    this._snapLines.set([...gapSnapLines, ...pointSnapsLines]);
    return { nudge };
  }
  get outlinesInPageSpace() {
    return this.snappableShapes.map(({ id, isClosed }) => {
      const outline = deepCopy(this.editor.getShapeGeometry(id).vertices);
      if (isClosed)
        outline.push(outline[0]);
      const pageTransform = this.editor.getShapePageTransform(id);
      if (!pageTransform)
        throw Error("No page transform");
      return Matrix2d.applyToPoints(pageTransform, outline);
    });
  }
  getSnappingHandleDelta({
    handlePoint,
    additionalSegments
  }) {
    const { outlinesInPageSpace, snapThreshold } = this;
    let minDistance = snapThreshold;
    let nearestPoint = null;
    let C, D, nearest, distance;
    const allSegments = [...outlinesInPageSpace, ...additionalSegments];
    for (const outline of allSegments) {
      for (let i = 0; i < outline.length - 1; i++) {
        C = outline[i];
        D = outline[i + 1];
        nearest = Vec2d.NearestPointOnLineSegment(C, D, handlePoint);
        distance = Vec2d.Dist(handlePoint, nearest);
        if (isNaN(distance))
          continue;
        if (distance < minDistance) {
          minDistance = distance;
          nearestPoint = nearest;
        }
      }
    }
    if (nearestPoint) {
      this._snapLines.set([
        {
          id: uniqueId(),
          type: "points",
          points: [nearestPoint]
        }
      ]);
      return Vec2d.Sub(nearestPoint, handlePoint);
    }
    return null;
  }
  snapResize({
    initialSelectionPageBounds,
    dragDelta,
    handle: originalHandle,
    isAspectRatioLocked,
    isResizingFromCenter
  }) {
    const { snapThreshold } = this;
    const {
      box: unsnappedResizedPageBounds,
      scaleX,
      scaleY
    } = Box2d.Resize(
      initialSelectionPageBounds,
      originalHandle,
      isResizingFromCenter ? dragDelta.x * 2 : dragDelta.x,
      isResizingFromCenter ? dragDelta.y * 2 : dragDelta.y,
      isAspectRatioLocked
    );
    let handle = originalHandle;
    if (scaleX < 0) {
      handle = flipSelectionHandleX(handle);
    }
    if (scaleY < 0) {
      handle = flipSelectionHandleY(handle);
    }
    if (isResizingFromCenter) {
      unsnappedResizedPageBounds.center = initialSelectionPageBounds.center;
    }
    const isXLocked = handle === "top" || handle === "bottom";
    const isYLocked = handle === "left" || handle === "right";
    const selectionSnapPoints = getResizeSnapPointsForHandle(handle, unsnappedResizedPageBounds);
    const otherNodeSnapPoints = this.snappablePoints;
    const nearestSnapsX = [];
    const nearestSnapsY = [];
    const minOffset = new Vec2d(snapThreshold, snapThreshold);
    this.collectPointSnaps({
      minOffset,
      nearestSnapsX,
      nearestSnapsY,
      otherNodeSnapPoints,
      selectionSnapPoints
    });
    const nudge = new Vec2d(
      isXLocked ? 0 : nearestSnapsX[0]?.nudge ?? 0,
      isYLocked ? 0 : nearestSnapsY[0]?.nudge ?? 0
    );
    if (isAspectRatioLocked && isSelectionCorner(handle) && nudge.len() !== 0) {
      const primaryNudgeAxis = nearestSnapsX.length && nearestSnapsY.length ? Math.abs(nudge.x) < Math.abs(nudge.y) ? "x" : "y" : nearestSnapsX.length ? "x" : "y";
      const ratio = initialSelectionPageBounds.aspectRatio;
      if (primaryNudgeAxis === "x") {
        nearestSnapsY.length = 0;
        nudge.y = nudge.x / ratio;
        if (handle === "bottom_left" || handle === "top_right") {
          nudge.y = -nudge.y;
        }
      } else {
        nearestSnapsX.length = 0;
        nudge.x = nudge.y * ratio;
        if (handle === "bottom_left" || handle === "top_right") {
          nudge.x = -nudge.x;
        }
      }
    }
    const snappedDelta = Vec2d.Add(dragDelta, nudge);
    const { box: snappedResizedPageBounds } = Box2d.Resize(
      initialSelectionPageBounds,
      originalHandle,
      isResizingFromCenter ? snappedDelta.x * 2 : snappedDelta.x,
      isResizingFromCenter ? snappedDelta.y * 2 : snappedDelta.y,
      isAspectRatioLocked
    );
    if (isResizingFromCenter) {
      snappedResizedPageBounds.center = initialSelectionPageBounds.center;
    }
    const snappedSelectionPoints = getResizeSnapPointsForHandle("any", snappedResizedPageBounds);
    nearestSnapsX.length = 0;
    nearestSnapsY.length = 0;
    minOffset.x = 0;
    minOffset.y = 0;
    this.collectPointSnaps({
      minOffset,
      nearestSnapsX,
      nearestSnapsY,
      otherNodeSnapPoints,
      selectionSnapPoints: snappedSelectionPoints
    });
    const pointSnaps = this.getPointSnapLines({
      nearestSnapsX,
      nearestSnapsY
    });
    this._snapLines.set([...pointSnaps]);
    return { nudge };
  }
  collectPointSnaps({
    selectionSnapPoints,
    otherNodeSnapPoints,
    minOffset,
    nearestSnapsX,
    nearestSnapsY
  }) {
    for (const thisSnapPoint of selectionSnapPoints) {
      for (const otherSnapPoint of otherNodeSnapPoints) {
        const offset2 = Vec2d.Sub(thisSnapPoint, otherSnapPoint);
        const offsetX = Math.abs(offset2.x);
        const offsetY = Math.abs(offset2.y);
        if (round(offsetX) <= round(minOffset.x)) {
          if (round(offsetX) < round(minOffset.x)) {
            nearestSnapsX.length = 0;
          }
          nearestSnapsX.push({
            type: "points",
            points: { thisPoint: thisSnapPoint, otherPoint: otherSnapPoint },
            nudge: otherSnapPoint.x - thisSnapPoint.x
          });
          minOffset.x = offsetX;
        }
        if (round(offsetY) <= round(minOffset.y)) {
          if (round(offsetY) < round(minOffset.y)) {
            nearestSnapsY.length = 0;
          }
          nearestSnapsY.push({
            type: "points",
            points: { thisPoint: thisSnapPoint, otherPoint: otherSnapPoint },
            nudge: otherSnapPoint.y - thisSnapPoint.y
          });
          minOffset.y = offsetY;
        }
      }
    }
  }
  collectGapSnaps({
    selectionPageBounds,
    minOffset,
    nearestSnapsX,
    nearestSnapsY
  }) {
    const { horizontal, vertical } = this.visibleGaps;
    for (const gap of horizontal) {
      if (!rangesOverlap(
        gap.breadthIntersection[0],
        gap.breadthIntersection[1],
        selectionPageBounds.minY,
        selectionPageBounds.maxY
      )) {
        continue;
      }
      const gapMidX = gap.startEdge[0].x + gap.length / 2;
      const centerNudge = gapMidX - selectionPageBounds.center.x;
      const gapIsLargerThanSelection = gap.length > selectionPageBounds.width;
      if (gapIsLargerThanSelection && round(Math.abs(centerNudge)) <= round(minOffset.x)) {
        if (round(Math.abs(centerNudge)) < round(minOffset.x)) {
          nearestSnapsX.length = 0;
        }
        minOffset.x = Math.abs(centerNudge);
        const snap = {
          type: "gap_center",
          gap,
          nudge: centerNudge
        };
        const otherCenterSnap = nearestSnapsX.find(({ type }) => type === "gap_center");
        const gapBreadthsOverlap = otherCenterSnap && rangeIntersection(
          gap.breadthIntersection[0],
          gap.breadthIntersection[1],
          otherCenterSnap.gap.breadthIntersection[0],
          otherCenterSnap.gap.breadthIntersection[1]
        );
        if (otherCenterSnap && otherCenterSnap.gap.length > gap.length && gapBreadthsOverlap) {
          nearestSnapsX[nearestSnapsX.indexOf(otherCenterSnap)] = snap;
        } else if (!otherCenterSnap || !gapBreadthsOverlap) {
          nearestSnapsX.push(snap);
        }
      }
      const duplicationLeftX = gap.startNode.pageBounds.minX - gap.length;
      const selectionRightX = selectionPageBounds.maxX;
      const duplicationLeftNudge = duplicationLeftX - selectionRightX;
      if (round(Math.abs(duplicationLeftNudge)) <= round(minOffset.x)) {
        if (round(Math.abs(duplicationLeftNudge)) < round(minOffset.x)) {
          nearestSnapsX.length = 0;
        }
        minOffset.x = Math.abs(duplicationLeftNudge);
        nearestSnapsX.push({
          type: "gap_duplicate",
          gap,
          protrusionDirection: "left",
          nudge: duplicationLeftNudge
        });
      }
      const duplicationRightX = gap.endNode.pageBounds.maxX + gap.length;
      const selectionLeftX = selectionPageBounds.minX;
      const duplicationRightNudge = duplicationRightX - selectionLeftX;
      if (round(Math.abs(duplicationRightNudge)) <= round(minOffset.x)) {
        if (round(Math.abs(duplicationRightNudge)) < round(minOffset.x)) {
          nearestSnapsX.length = 0;
        }
        minOffset.x = Math.abs(duplicationRightNudge);
        nearestSnapsX.push({
          type: "gap_duplicate",
          gap,
          protrusionDirection: "right",
          nudge: duplicationRightNudge
        });
      }
    }
    for (const gap of vertical) {
      if (!rangesOverlap(
        gap.breadthIntersection[0],
        gap.breadthIntersection[1],
        selectionPageBounds.minX,
        selectionPageBounds.maxX
      )) {
        continue;
      }
      const gapMidY = gap.startEdge[0].y + gap.length / 2;
      const centerNudge = gapMidY - selectionPageBounds.center.y;
      const gapIsLargerThanSelection = gap.length > selectionPageBounds.height;
      if (gapIsLargerThanSelection && round(Math.abs(centerNudge)) <= round(minOffset.y)) {
        if (round(Math.abs(centerNudge)) < round(minOffset.y)) {
          nearestSnapsY.length = 0;
        }
        minOffset.y = Math.abs(centerNudge);
        const snap = {
          type: "gap_center",
          gap,
          nudge: centerNudge
        };
        const otherCenterSnap = nearestSnapsY.find(({ type }) => type === "gap_center");
        const gapBreadthsOverlap = otherCenterSnap && rangesOverlap(
          otherCenterSnap.gap.breadthIntersection[0],
          otherCenterSnap.gap.breadthIntersection[1],
          gap.breadthIntersection[0],
          gap.breadthIntersection[1]
        );
        if (otherCenterSnap && otherCenterSnap.gap.length > gap.length && gapBreadthsOverlap) {
          nearestSnapsY[nearestSnapsY.indexOf(otherCenterSnap)] = snap;
        } else if (!otherCenterSnap || !gapBreadthsOverlap) {
          nearestSnapsY.push(snap);
        }
        continue;
      }
      const duplicationTopY = gap.startNode.pageBounds.minY - gap.length;
      const selectionBottomY = selectionPageBounds.maxY;
      const duplicationTopNudge = duplicationTopY - selectionBottomY;
      if (round(Math.abs(duplicationTopNudge)) <= round(minOffset.y)) {
        if (round(Math.abs(duplicationTopNudge)) < round(minOffset.y)) {
          nearestSnapsY.length = 0;
        }
        minOffset.y = Math.abs(duplicationTopNudge);
        nearestSnapsY.push({
          type: "gap_duplicate",
          gap,
          protrusionDirection: "top",
          nudge: duplicationTopNudge
        });
      }
      const duplicationBottomY = gap.endNode.pageBounds.maxY + gap.length;
      const selectionTopY = selectionPageBounds.minY;
      const duplicationBottomNudge = duplicationBottomY - selectionTopY;
      if (round(Math.abs(duplicationBottomNudge)) <= round(minOffset.y)) {
        if (round(Math.abs(duplicationBottomNudge)) < round(minOffset.y)) {
          nearestSnapsY.length = 0;
        }
        minOffset.y = Math.abs(duplicationBottomNudge);
        nearestSnapsY.push({
          type: "gap_duplicate",
          gap,
          protrusionDirection: "bottom",
          nudge: duplicationBottomNudge
        });
      }
    }
  }
  getPointSnapLines({
    nearestSnapsX,
    nearestSnapsY
  }) {
    const snapGroupsX = {};
    const snapGroupsY = {};
    if (nearestSnapsX.length > 0) {
      for (const snap of nearestSnapsX) {
        if (snap.type === "points") {
          const key = round(snap.points.otherPoint.x);
          if (!snapGroupsX[key]) {
            snapGroupsX[key] = [];
          }
          snapGroupsX[key].push(snap.points);
        }
      }
    }
    if (nearestSnapsY.length > 0) {
      for (const snap of nearestSnapsY) {
        if (snap.type === "points") {
          const key = round(snap.points.otherPoint.y);
          if (!snapGroupsY[key]) {
            snapGroupsY[key] = [];
          }
          snapGroupsY[key].push(snap.points);
        }
      }
    }
    return Object.values(snapGroupsX).concat(Object.values(snapGroupsY)).map((snapGroup) => ({
      id: uniqueId(),
      type: "points",
      points: dedupe(
        snapGroup.map((snap) => Vec2d.From(snap.otherPoint)).concat(snapGroup.map((snap) => Vec2d.From(snap.thisPoint))),
        (a, b) => a.equals(b)
      )
    }));
  }
  getGapSnapLines({
    selectionPageBounds,
    nearestSnapsX,
    nearestSnapsY
  }) {
    const { vertical, horizontal } = this.visibleGaps;
    const selectionSides = {
      top: selectionPageBounds.sides[0],
      right: selectionPageBounds.sides[1],
      // need bottom and left to be sorted asc, which .sides is not.
      bottom: [selectionPageBounds.corners[3], selectionPageBounds.corners[2]],
      left: [selectionPageBounds.corners[0], selectionPageBounds.corners[3]]
    };
    const result = [];
    if (nearestSnapsX.length > 0) {
      for (const snap of nearestSnapsX) {
        if (snap.type === "points")
          continue;
        const {
          gap: { breadthIntersection, startEdge, startNode, endNode, length, endEdge }
        } = snap;
        switch (snap.type) {
          case "gap_center": {
            const newGapsLength = (length - selectionPageBounds.width) / 2;
            const gapBreadthIntersection = rangeIntersection(
              breadthIntersection[0],
              breadthIntersection[1],
              selectionPageBounds.minY,
              selectionPageBounds.maxY
            );
            result.push({
              type: "gaps",
              direction: "horizontal",
              id: uniqueId(),
              gaps: [
                ...findAdjacentGaps(
                  horizontal,
                  startNode.id,
                  newGapsLength,
                  "backward",
                  gapBreadthIntersection
                ),
                {
                  startEdge,
                  endEdge: selectionSides.left
                },
                {
                  startEdge: selectionSides.right,
                  endEdge
                },
                ...findAdjacentGaps(
                  horizontal,
                  endNode.id,
                  newGapsLength,
                  "forward",
                  gapBreadthIntersection
                )
              ]
            });
            break;
          }
          case "gap_duplicate": {
            const gapBreadthIntersection = rangeIntersection(
              breadthIntersection[0],
              breadthIntersection[1],
              selectionPageBounds.minY,
              selectionPageBounds.maxY
            );
            result.push({
              type: "gaps",
              direction: "horizontal",
              id: uniqueId(),
              gaps: snap.protrusionDirection === "left" ? [
                {
                  startEdge: selectionSides.right,
                  endEdge: startEdge.map(
                    (v) => v.clone().addXY(-startNode.pageBounds.width, 0)
                  )
                },
                { startEdge, endEdge },
                ...findAdjacentGaps(
                  horizontal,
                  endNode.id,
                  length,
                  "forward",
                  gapBreadthIntersection
                )
              ] : [
                ...findAdjacentGaps(
                  horizontal,
                  startNode.id,
                  length,
                  "backward",
                  gapBreadthIntersection
                ),
                { startEdge, endEdge },
                {
                  startEdge: endEdge.map(
                    (v) => v.clone().addXY(snap.gap.endNode.pageBounds.width, 0)
                  ),
                  endEdge: selectionSides.left
                }
              ]
            });
            break;
          }
        }
      }
    }
    if (nearestSnapsY.length > 0) {
      for (const snap of nearestSnapsY) {
        if (snap.type === "points")
          continue;
        const {
          gap: { breadthIntersection, startEdge, startNode, endNode, length, endEdge }
        } = snap;
        switch (snap.type) {
          case "gap_center": {
            const newGapsLength = (length - selectionPageBounds.height) / 2;
            const gapBreadthIntersection = rangeIntersection(
              breadthIntersection[0],
              breadthIntersection[1],
              selectionPageBounds.minX,
              selectionPageBounds.maxX
            );
            result.push({
              type: "gaps",
              direction: "vertical",
              id: uniqueId(),
              gaps: [
                ...findAdjacentGaps(
                  vertical,
                  startNode.id,
                  newGapsLength,
                  "backward",
                  gapBreadthIntersection
                ),
                {
                  startEdge,
                  endEdge: selectionSides.top
                },
                {
                  startEdge: selectionSides.bottom,
                  endEdge
                },
                ...findAdjacentGaps(
                  vertical,
                  snap.gap.endNode.id,
                  newGapsLength,
                  "forward",
                  gapBreadthIntersection
                )
              ]
            });
            break;
          }
          case "gap_duplicate":
            {
              const gapBreadthIntersection = rangeIntersection(
                breadthIntersection[0],
                breadthIntersection[1],
                selectionPageBounds.minX,
                selectionPageBounds.maxX
              );
              result.push({
                type: "gaps",
                direction: "vertical",
                id: uniqueId(),
                gaps: snap.protrusionDirection === "top" ? [
                  {
                    startEdge: selectionSides.bottom,
                    endEdge: startEdge.map(
                      (v) => v.clone().addXY(0, -startNode.pageBounds.height)
                    )
                  },
                  { startEdge, endEdge },
                  ...findAdjacentGaps(
                    vertical,
                    endNode.id,
                    length,
                    "forward",
                    gapBreadthIntersection
                  )
                ] : [
                  ...findAdjacentGaps(
                    vertical,
                    startNode.id,
                    length,
                    "backward",
                    gapBreadthIntersection
                  ),
                  { startEdge, endEdge },
                  {
                    startEdge: endEdge.map(
                      (v) => v.clone().addXY(0, endNode.pageBounds.height)
                    ),
                    endEdge: selectionSides.top
                  }
                ]
              });
            }
            break;
        }
      }
    }
    dedupeGapSnaps(result);
    return result;
  }
};
__decorateClass([
  computed
], SnapManager.prototype, "snapPointsCache", 1);
__decorateClass([
  computed
], SnapManager.prototype, "snapThreshold", 1);
__decorateClass([
  computed
], SnapManager.prototype, "snappableShapes", 1);
__decorateClass([
  computed
], SnapManager.prototype, "currentCommonAncestor", 1);
__decorateClass([
  computed
], SnapManager.prototype, "snappablePoints", 1);
__decorateClass([
  computed
], SnapManager.prototype, "visibleGaps", 1);
__decorateClass([
  computed
], SnapManager.prototype, "outlinesInPageSpace", 1);
function getResizeSnapPointsForHandle(handle, selectionPageBounds) {
  const { minX, maxX, minY, maxY } = selectionPageBounds;
  const result = [];
  switch (handle) {
    case "top":
    case "left":
    case "top_left":
    case "any":
      result.push({
        id: "top_left",
        handle: "top_left",
        x: minX,
        y: minY
      });
  }
  switch (handle) {
    case "top":
    case "right":
    case "top_right":
    case "any":
      result.push({
        id: "top_right",
        handle: "top_right",
        x: maxX,
        y: minY
      });
  }
  switch (handle) {
    case "bottom":
    case "right":
    case "bottom_right":
    case "any":
      result.push({
        id: "bottom_right",
        handle: "bottom_right",
        x: maxX,
        y: maxY
      });
  }
  switch (handle) {
    case "bottom":
    case "left":
    case "bottom_left":
    case "any":
      result.push({
        id: "bottom_left",
        handle: "bottom_left",
        x: minX,
        y: maxY
      });
  }
  return result;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/TextManager.mjs
var fixNewLines = /\r?\n|\r/g;
function normalizeTextForDom(text) {
  return text.replace(fixNewLines, "\n").split("\n").map((x) => x || " ").join("\n");
}
var textAlignmentsForLtr = {
  start: "left",
  "start-legacy": "left",
  middle: "center",
  "middle-legacy": "center",
  end: "right",
  "end-legacy": "right"
};
var spaceCharacterRegex = /\s/;
var TextManager = class {
  constructor(editor) {
    this.editor = editor;
  }
  getTextElement() {
    const oldElm = document.querySelector(".tl-text-measure");
    oldElm?.remove();
    const elm = document.createElement("div");
    this.editor.getContainer().appendChild(elm);
    elm.id = `__textMeasure_${uniqueId()}`;
    elm.classList.add("tl-text");
    elm.classList.add("tl-text-measure");
    elm.tabIndex = -1;
    return elm;
  }
  measureText = (textToMeasure, opts) => {
    const elm = this.getTextElement();
    elm.setAttribute("dir", "ltr");
    elm.style.setProperty("font-family", opts.fontFamily);
    elm.style.setProperty("font-style", opts.fontStyle);
    elm.style.setProperty("font-weight", opts.fontWeight);
    elm.style.setProperty("font-size", opts.fontSize + "px");
    elm.style.setProperty("line-height", opts.lineHeight * opts.fontSize + "px");
    elm.style.setProperty("max-width", opts.maxWidth === null ? null : opts.maxWidth + "px");
    elm.style.setProperty("min-width", opts.minWidth ?? null);
    elm.style.setProperty("padding", opts.padding);
    elm.textContent = normalizeTextForDom(textToMeasure);
    const rect = elm.getBoundingClientRect();
    return {
      x: 0,
      y: 0,
      w: rect.width,
      h: rect.height
    };
  };
  /**
   * Given an html element, measure the position of each span of unbroken
   * word/white-space characters within any text nodes it contains.
   */
  measureElementTextNodeSpans(element, { shouldTruncateToFirstLine = false } = {}) {
    const spans = [];
    const elmBounds = element.getBoundingClientRect();
    const offsetX = -elmBounds.left;
    const offsetY = -elmBounds.top;
    const range = new Range();
    const textNode = element.childNodes[0];
    let idx = 0;
    let currentSpan = null;
    let prevCharWasSpaceCharacter = null;
    let prevCharTop = 0;
    let didTruncate = false;
    for (const childNode of element.childNodes) {
      if (childNode.nodeType !== Node.TEXT_NODE)
        continue;
      for (const char of childNode.textContent ?? "") {
        range.setStart(textNode, idx);
        range.setEnd(textNode, idx + char.length);
        const rects = range.getClientRects();
        const rect = rects[rects.length - 1];
        const top = rect.top + offsetY;
        const left = rect.left + offsetX;
        const right = rect.right + offsetX;
        const isSpaceCharacter = spaceCharacterRegex.test(char);
        if (
          // If we're at a word boundary...
          isSpaceCharacter !== prevCharWasSpaceCharacter || // ...or we're on a different line...
          top !== prevCharTop || // ...or we're at the start of the text and haven't created a span yet...
          !currentSpan
        ) {
          if (currentSpan) {
            if (shouldTruncateToFirstLine && top !== prevCharTop) {
              didTruncate = true;
              break;
            }
            spans.push(currentSpan);
          }
          currentSpan = {
            box: { x: left, y: top, w: rect.width, h: rect.height },
            text: char
          };
        } else {
          currentSpan.box.w = right - currentSpan.box.x;
          currentSpan.text += char;
        }
        prevCharWasSpaceCharacter = isSpaceCharacter;
        prevCharTop = top;
        idx += char.length;
      }
    }
    if (currentSpan) {
      spans.push(currentSpan);
    }
    return { spans, didTruncate };
  }
  /**
   * Measure text into individual spans. Spans are created by rendering the
   * text, then dividing it up according to line breaks and word boundaries.
   *
   * It works by having the browser render the text, then measuring the
   * position of each character. You can use this to replicate the text-layout
   * algorithm of the current browser in e.g. an SVG export.
   */
  measureTextSpans(textToMeasure, opts) {
    if (textToMeasure === "")
      return [];
    const shouldTruncateToFirstLine = opts.overflow === "truncate-ellipsis" || opts.overflow === "truncate-clip";
    const element = this.getTextElement();
    const elementWidth = Math.ceil(opts.width - opts.padding * 2);
    element.style.setProperty("width", `${elementWidth}px`);
    element.style.setProperty("height", "min-content");
    element.style.setProperty("dir", "ltr");
    element.style.setProperty("font-size", `${opts.fontSize}px`);
    element.style.setProperty("font-family", opts.fontFamily);
    element.style.setProperty("font-weight", opts.fontWeight);
    element.style.setProperty("line-height", `${opts.lineHeight * opts.fontSize}px`);
    element.style.setProperty("text-align", textAlignmentsForLtr[opts.textAlign]);
    if (shouldTruncateToFirstLine) {
      element.style.setProperty("overflow-wrap", "anywhere");
      element.style.setProperty("word-break", "break-all");
    }
    textToMeasure = normalizeTextForDom(textToMeasure);
    element.textContent = textToMeasure;
    const { spans, didTruncate } = this.measureElementTextNodeSpans(element, {
      shouldTruncateToFirstLine
    });
    if (opts.overflow === "truncate-ellipsis" && didTruncate) {
      element.textContent = "…";
      const ellipsisWidth = Math.ceil(this.measureElementTextNodeSpans(element).spans[0].box.w);
      element.style.setProperty("width", `${elementWidth - ellipsisWidth}px`);
      element.textContent = textToMeasure;
      const truncatedSpans = this.measureElementTextNodeSpans(element, {
        shouldTruncateToFirstLine: true
      }).spans;
      const lastSpan = truncatedSpans[truncatedSpans.length - 1];
      truncatedSpans.push({
        text: "…",
        box: {
          x: Math.min(lastSpan.box.x + lastSpan.box.w, opts.width - opts.padding - ellipsisWidth),
          y: lastSpan.box.y,
          w: ellipsisWidth,
          h: lastSpan.box.h
        }
      });
      return truncatedSpans;
    }
    element.remove();
    return spans;
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/TickManager.mjs
var TickManager = class {
  constructor(editor) {
    this.editor = editor;
    this.editor.disposables.add(this.dispose);
    this.start();
  }
  raf;
  isPaused = true;
  last = 0;
  t = 0;
  start = () => {
    this.isPaused = false;
    cancelAnimationFrame(this.raf);
    this.raf = requestAnimationFrame(this.tick);
    this.last = Date.now();
  };
  tick = () => {
    if (this.isPaused) {
      return;
    }
    const now = Date.now();
    const elapsed = now - this.last;
    this.last = now;
    this.t += elapsed;
    this.editor.emit("frame", elapsed);
    if (this.t < 16) {
      this.raf = requestAnimationFrame(this.tick);
      return;
    }
    this.t -= 16;
    this.updatePointerVelocity(elapsed);
    this.editor.emit("tick", elapsed);
    this.raf = requestAnimationFrame(this.tick);
  };
  // Clear the listener
  dispose = () => {
    this.isPaused = true;
    cancelAnimationFrame(this.raf);
  };
  prevPoint = new Vec2d();
  updatePointerVelocity = (elapsed) => {
    const {
      prevPoint,
      editor: {
        inputs: { currentScreenPoint, pointerVelocity }
      }
    } = this;
    if (elapsed === 0)
      return;
    const delta = Vec2d.Sub(currentScreenPoint, prevPoint);
    this.prevPoint = currentScreenPoint.clone();
    const length = delta.len();
    const direction = length ? delta.div(length) : new Vec2d(0, 0);
    const next = pointerVelocity.clone().lrp(direction.mul(length / elapsed), 0.5);
    if (Math.abs(next.x) < 0.01)
      next.x = 0;
    if (Math.abs(next.y) < 0.01)
      next.y = 0;
    if (!pointerVelocity.equals(next)) {
      this.editor.inputs.pointerVelocity = next;
    }
  };
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/managers/UserPreferencesManager.mjs
var __defProp2 = Object.defineProperty;
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
var __decorateClass2 = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc2(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp2(target, key, result);
  return result;
};
var UserPreferencesManager = class {
  constructor(user, inferDarkMode) {
    this.user = user;
    this.inferDarkMode = inferDarkMode;
  }
  updateUserPreferences = (userPreferences) => {
    this.user.setUserPreferences({
      ...this.user.userPreferences.value,
      ...userPreferences
    });
  };
  get userPreferences() {
    return {
      id: this.id,
      name: this.name,
      locale: this.locale,
      color: this.color,
      isDarkMode: this.isDarkMode,
      animationSpeed: this.animationSpeed,
      isSnapMode: this.isSnapMode
    };
  }
  get isDarkMode() {
    return this.user.userPreferences.value.isDarkMode ?? (this.inferDarkMode ? userPrefersDarkUI() : false);
  }
  get animationSpeed() {
    return this.user.userPreferences.value.animationSpeed ?? defaultUserPreferences.animationSpeed;
  }
  get id() {
    return this.user.userPreferences.value.id;
  }
  get name() {
    return this.user.userPreferences.value.name ?? defaultUserPreferences.name;
  }
  get locale() {
    return this.user.userPreferences.value.locale ?? defaultUserPreferences.locale;
  }
  get color() {
    return this.user.userPreferences.value.color ?? defaultUserPreferences.color;
  }
  get isSnapMode() {
    return this.user.userPreferences.value.isSnapMode ?? defaultUserPreferences.isSnapMode;
  }
};
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "userPreferences", 1);
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "isDarkMode", 1);
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "animationSpeed", 1);
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "id", 1);
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "name", 1);
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "locale", 1);
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "color", 1);
__decorateClass2([
  computed
], UserPreferencesManager.prototype, "isSnapMode", 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/shared/arrow/shared.mjs
function getIsArrowStraight(shape) {
  return Math.abs(shape.props.bend) < 8;
}
function getBoundShapeInfoForTerminal(editor, terminal) {
  if (terminal.type === "point") {
    return;
  }
  const shape = editor.getShape(terminal.boundShapeId);
  const transform = editor.getShapePageTransform(shape);
  const geometry = editor.getShapeGeometry(shape);
  const outline = geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices;
  return {
    shape,
    transform,
    isClosed: geometry.isClosed,
    isExact: terminal.isExact,
    didIntersect: false,
    outline
  };
}
function getArrowTerminalInArrowSpace(editor, arrowPageTransform, terminal) {
  if (terminal.type === "point") {
    return Vec2d.From(terminal);
  }
  const boundShape = editor.getShape(terminal.boundShapeId);
  if (!boundShape) {
    return new Vec2d(0, 0);
  } else {
    const { point, size: size2 } = editor.getShapeGeometry(boundShape).bounds;
    const shapePoint = Vec2d.Add(point, Vec2d.MulV(terminal.normalizedAnchor, size2));
    const pagePoint = Matrix2d.applyToPoint(editor.getShapePageTransform(boundShape), shapePoint);
    const arrowPoint = Matrix2d.applyToPoint(Matrix2d.Inverse(arrowPageTransform), pagePoint);
    return arrowPoint;
  }
}
function getArrowTerminalsInArrowSpace(editor, shape) {
  const arrowPageTransform = editor.getShapePageTransform(shape);
  const start = getArrowTerminalInArrowSpace(editor, arrowPageTransform, shape.props.start);
  const end = getArrowTerminalInArrowSpace(editor, arrowPageTransform, shape.props.end);
  return { start, end };
}
var MIN_ARROW_LENGTH = 32;
var BOUND_ARROW_OFFSET = 10;
var WAY_TOO_BIG_ARROW_BEND_FACTOR = 10;
var STROKE_SIZES = {
  s: 2,
  m: 3.5,
  l: 5,
  xl: 10
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/shared/arrow/straight-arrow.mjs
function getStraightArrowInfo(editor, shape) {
  const { start, end, arrowheadStart, arrowheadEnd } = shape.props;
  const terminalsInArrowSpace = getArrowTerminalsInArrowSpace(editor, shape);
  const a = terminalsInArrowSpace.start.clone();
  const b = terminalsInArrowSpace.end.clone();
  const c = Vec2d.Med(a, b);
  const uAB = Vec2d.Sub(b, a).uni();
  const startShapeInfo = getBoundShapeInfoForTerminal(editor, start);
  const endShapeInfo = getBoundShapeInfoForTerminal(editor, end);
  const arrowPageTransform = editor.getShapePageTransform(shape);
  updateArrowheadPointWithBoundShape(
    b,
    // <-- will be mutated
    terminalsInArrowSpace.start,
    arrowPageTransform,
    endShapeInfo
  );
  updateArrowheadPointWithBoundShape(
    a,
    // <-- will be mutated
    terminalsInArrowSpace.end,
    arrowPageTransform,
    startShapeInfo
  );
  let offsetA = 0;
  let offsetB = 0;
  const isSelfIntersection = startShapeInfo && endShapeInfo && startShapeInfo.shape === endShapeInfo.shape;
  if (startShapeInfo && endShapeInfo && !isSelfIntersection && !startShapeInfo.isExact && !endShapeInfo.isExact) {
    if (endShapeInfo.didIntersect && !startShapeInfo.didIntersect) {
      if (startShapeInfo.isClosed) {
        a.setTo(b.clone().add(uAB.clone().mul(MIN_ARROW_LENGTH)));
      }
    } else if (!endShapeInfo.didIntersect) {
      if (endShapeInfo.isClosed) {
        b.setTo(a.clone().sub(uAB.clone().mul(MIN_ARROW_LENGTH)));
      }
    }
  }
  const u = Vec2d.Sub(b, a).uni();
  const didFlip = !Vec2d.Equals(u, uAB);
  if (!isSelfIntersection) {
    if (startShapeInfo && arrowheadStart !== "none" && !startShapeInfo.isExact) {
      offsetA = BOUND_ARROW_OFFSET + STROKE_SIZES[shape.props.size] / 2 + ("size" in startShapeInfo.shape.props ? STROKE_SIZES[startShapeInfo.shape.props.size] / 2 : 0);
    }
    if (endShapeInfo && arrowheadEnd !== "none" && !endShapeInfo.isExact) {
      offsetB = BOUND_ARROW_OFFSET + STROKE_SIZES[shape.props.size] / 2 + ("size" in endShapeInfo.shape.props ? STROKE_SIZES[endShapeInfo.shape.props.size] / 2 : 0);
    }
  }
  const tA = a.clone().add(u.clone().mul(offsetA * (didFlip ? -1 : 1)));
  const tB = b.clone().sub(u.clone().mul(offsetB * (didFlip ? -1 : 1)));
  const distAB = Vec2d.Dist(tA, tB);
  if (distAB < MIN_ARROW_LENGTH) {
    if (offsetA !== 0 && offsetB !== 0) {
      offsetA *= -1.5;
      offsetB *= -1.5;
    } else if (offsetA !== 0) {
      offsetA *= -2;
    } else if (offsetB !== 0) {
      offsetB *= -2;
    } else {
      if (distAB < 10) {
        if (startShapeInfo)
          offsetA = -(10 - distAB);
        else if (endShapeInfo)
          offsetB = -(10 - distAB);
      }
    }
  }
  a.add(u.clone().mul(offsetA * (didFlip ? -1 : 1)));
  b.sub(u.clone().mul(offsetB * (didFlip ? -1 : 1)));
  if (didFlip) {
    if (startShapeInfo && endShapeInfo) {
      b.setTo(Vec2d.Add(a, u.clone().mul(-MIN_ARROW_LENGTH)));
    }
    c.setTo(Vec2d.Med(terminalsInArrowSpace.start, terminalsInArrowSpace.end));
  } else {
    c.setTo(Vec2d.Med(a, b));
  }
  const length = Vec2d.Dist(a, b);
  return {
    isStraight: true,
    start: {
      handle: terminalsInArrowSpace.start,
      point: a,
      arrowhead: shape.props.arrowheadStart
    },
    end: {
      handle: terminalsInArrowSpace.end,
      point: b,
      arrowhead: shape.props.arrowheadEnd
    },
    middle: c,
    isValid: length > 0,
    length
  };
}
function updateArrowheadPointWithBoundShape(point, opposite, arrowPageTransform, targetShapeInfo) {
  if (targetShapeInfo === void 0) {
    return;
  }
  if (targetShapeInfo.isExact) {
    return;
  }
  const pageFrom = Matrix2d.applyToPoint(arrowPageTransform, opposite);
  const pageTo = Matrix2d.applyToPoint(arrowPageTransform, point);
  const targetFrom = Matrix2d.applyToPoint(Matrix2d.Inverse(targetShapeInfo.transform), pageFrom);
  const targetTo = Matrix2d.applyToPoint(Matrix2d.Inverse(targetShapeInfo.transform), pageTo);
  const isClosed = targetShapeInfo.isClosed;
  const fn = isClosed ? intersectLineSegmentPolygon : intersectLineSegmentPolyline;
  const intersection = fn(targetFrom, targetTo, targetShapeInfo.outline);
  let targetInt;
  if (intersection !== null) {
    targetInt = intersection.sort((p1, p2) => Vec2d.Dist(p1, targetFrom) - Vec2d.Dist(p2, targetFrom))[0] ?? (isClosed ? void 0 : targetTo);
  }
  if (targetInt === void 0) {
    return;
  }
  const pageInt = Matrix2d.applyToPoint(targetShapeInfo.transform, targetInt);
  const arrowInt = Matrix2d.applyToPoint(Matrix2d.Inverse(arrowPageTransform), pageInt);
  point.setTo(arrowInt);
  targetShapeInfo.didIntersect = true;
}
function getStraightArrowHandlePath(info) {
  return getArrowPath(info.start.handle, info.end.handle);
}
function getSolidStraightArrowPath(info) {
  return getArrowPath(info.start.point, info.end.point);
}
function getArrowPath(start, end) {
  return `M${start.x},${start.y}L${end.x},${end.y}`;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/shared/arrow/curved-arrow.mjs
function getCurvedArrowInfo(editor, shape, extraBend = 0) {
  const { arrowheadEnd, arrowheadStart } = shape.props;
  const bend = shape.props.bend + extraBend;
  if (Math.abs(bend) > Math.abs(shape.props.bend * WAY_TOO_BIG_ARROW_BEND_FACTOR)) {
    return getStraightArrowInfo(editor, shape);
  }
  const terminalsInArrowSpace = getArrowTerminalsInArrowSpace(editor, shape);
  const med = Vec2d.Med(terminalsInArrowSpace.start, terminalsInArrowSpace.end);
  const u = Vec2d.Sub(terminalsInArrowSpace.end, terminalsInArrowSpace.start).uni();
  const middle = Vec2d.Add(med, u.per().mul(-bend));
  const startShapeInfo = getBoundShapeInfoForTerminal(editor, shape.props.start);
  const endShapeInfo = getBoundShapeInfoForTerminal(editor, shape.props.end);
  const a = terminalsInArrowSpace.start.clone();
  const b = terminalsInArrowSpace.end.clone();
  const c = middle.clone();
  const isClockwise = shape.props.bend < 0;
  const distFn = isClockwise ? clockwiseAngleDist : counterClockwiseAngleDist;
  const handleArc = getArcInfo(a, b, c);
  const handle_aCA = Vec2d.Angle(handleArc.center, a);
  const handle_aCB = Vec2d.Angle(handleArc.center, b);
  const handle_dAB = distFn(handle_aCA, handle_aCB);
  if (handleArc.length === 0 || handleArc.size === 0 || !isSafeFloat(handleArc.length) || !isSafeFloat(handleArc.size)) {
    return getStraightArrowInfo(editor, shape);
  }
  const tempA = a.clone();
  const tempB = b.clone();
  const tempC = c.clone();
  const arrowPageTransform = editor.getShapePageTransform(shape);
  let offsetA = 0;
  let offsetB = 0;
  if (startShapeInfo && !startShapeInfo.isExact) {
    const startInPageSpace = Matrix2d.applyToPoint(arrowPageTransform, tempA);
    const centerInPageSpace = Matrix2d.applyToPoint(arrowPageTransform, handleArc.center);
    const endInPageSpace = Matrix2d.applyToPoint(arrowPageTransform, tempB);
    const inverseTransform = Matrix2d.Inverse(startShapeInfo.transform);
    const startInStartShapeLocalSpace = Matrix2d.applyToPoint(inverseTransform, startInPageSpace);
    const centerInStartShapeLocalSpace = Matrix2d.applyToPoint(inverseTransform, centerInPageSpace);
    const endInStartShapeLocalSpace = Matrix2d.applyToPoint(inverseTransform, endInPageSpace);
    const { isClosed } = startShapeInfo;
    const fn = isClosed ? intersectCirclePolygon : intersectCirclePolyline;
    let point;
    let intersections = fn(centerInStartShapeLocalSpace, handleArc.radius, startShapeInfo.outline);
    if (intersections) {
      const angleToStart = centerInStartShapeLocalSpace.angle(startInStartShapeLocalSpace);
      const angleToEnd = centerInStartShapeLocalSpace.angle(endInStartShapeLocalSpace);
      const dAB2 = distFn(angleToStart, angleToEnd);
      intersections = intersections.filter(
        (pt) => distFn(angleToStart, centerInStartShapeLocalSpace.angle(pt)) <= dAB2
      );
      const targetDist = dAB2 * 0.25;
      intersections.sort(
        isClosed ? (p0, p1) => Math.abs(distFn(angleToStart, centerInStartShapeLocalSpace.angle(p0)) - targetDist) < Math.abs(distFn(angleToStart, centerInStartShapeLocalSpace.angle(p1)) - targetDist) ? -1 : 1 : (p0, p1) => distFn(angleToStart, centerInStartShapeLocalSpace.angle(p0)) < distFn(angleToStart, centerInStartShapeLocalSpace.angle(p1)) ? -1 : 1
      );
      point = intersections[0] ?? (isClosed ? void 0 : startInStartShapeLocalSpace);
    } else {
      point = isClosed ? void 0 : startInStartShapeLocalSpace;
    }
    if (point) {
      tempA.setTo(
        editor.getPointInShapeSpace(shape, Matrix2d.applyToPoint(startShapeInfo.transform, point))
      );
      startShapeInfo.didIntersect = true;
      if (arrowheadStart !== "none") {
        offsetA = BOUND_ARROW_OFFSET + STROKE_SIZES[shape.props.size] / 2 + ("size" in startShapeInfo.shape.props ? STROKE_SIZES[startShapeInfo.shape.props.size] / 2 : 0);
      }
    }
  }
  if (endShapeInfo && !endShapeInfo.isExact) {
    const startInPageSpace = Matrix2d.applyToPoint(arrowPageTransform, tempA);
    const endInPageSpace = Matrix2d.applyToPoint(arrowPageTransform, tempB);
    const centerInPageSpace = Matrix2d.applyToPoint(arrowPageTransform, handleArc.center);
    const inverseTransform = Matrix2d.Inverse(endShapeInfo.transform);
    const startInEndShapeLocalSpace = Matrix2d.applyToPoint(inverseTransform, startInPageSpace);
    const centerInEndShapeLocalSpace = Matrix2d.applyToPoint(inverseTransform, centerInPageSpace);
    const endInEndShapeLocalSpace = Matrix2d.applyToPoint(inverseTransform, endInPageSpace);
    const isClosed = endShapeInfo.isClosed;
    const fn = isClosed ? intersectCirclePolygon : intersectCirclePolyline;
    let point;
    let intersections = fn(centerInEndShapeLocalSpace, handleArc.radius, endShapeInfo.outline);
    if (intersections) {
      const angleToStart = centerInEndShapeLocalSpace.angle(startInEndShapeLocalSpace);
      const angleToEnd = centerInEndShapeLocalSpace.angle(endInEndShapeLocalSpace);
      const dAB2 = distFn(angleToStart, angleToEnd);
      const targetDist = dAB2 * 0.75;
      intersections = intersections.filter(
        (pt) => distFn(angleToStart, centerInEndShapeLocalSpace.angle(pt)) <= dAB2
      );
      intersections.sort(
        isClosed ? (p0, p1) => Math.abs(distFn(angleToStart, centerInEndShapeLocalSpace.angle(p0)) - targetDist) < Math.abs(distFn(angleToStart, centerInEndShapeLocalSpace.angle(p1)) - targetDist) ? -1 : 1 : (p0, p1) => distFn(angleToStart, centerInEndShapeLocalSpace.angle(p0)) < distFn(angleToStart, centerInEndShapeLocalSpace.angle(p1)) ? -1 : 1
      );
      if (intersections[0]) {
        point = intersections[0];
      } else {
        point = isClosed ? void 0 : endInEndShapeLocalSpace;
      }
    } else {
      point = isClosed ? void 0 : endInEndShapeLocalSpace;
    }
    if (point) {
      tempB.setTo(
        editor.getPointInShapeSpace(shape, Matrix2d.applyToPoint(endShapeInfo.transform, point))
      );
      endShapeInfo.didIntersect = true;
      if (arrowheadEnd !== "none") {
        offsetB = BOUND_ARROW_OFFSET + STROKE_SIZES[shape.props.size] / 2 + ("size" in endShapeInfo.shape.props ? STROKE_SIZES[endShapeInfo.shape.props.size] / 2 : 0);
      }
    }
  }
  let aCA = Vec2d.Angle(handleArc.center, tempA);
  let aCB = Vec2d.Angle(handleArc.center, tempB);
  let dAB = distFn(aCA, aCB);
  let lAB = dAB * handleArc.radius;
  const tA = tempA.clone();
  const tB = tempB.clone();
  if (offsetA !== 0) {
    const n = offsetA / lAB * (isClockwise ? 1 : -1);
    const u2 = Vec2d.FromAngle(aCA + dAB * n);
    tA.setTo(handleArc.center).add(u2.mul(handleArc.radius));
  }
  if (offsetB !== 0) {
    const n = offsetB / lAB * (isClockwise ? -1 : 1);
    const u2 = Vec2d.FromAngle(aCB + dAB * n);
    tB.setTo(handleArc.center).add(u2.mul(handleArc.radius));
  }
  const distAB = Vec2d.Dist(tA, tB);
  if (distAB < MIN_ARROW_LENGTH) {
    if (offsetA !== 0 && offsetB !== 0) {
      offsetA *= -1.5;
      offsetB *= -1.5;
    } else if (offsetA !== 0) {
      offsetA *= -2;
    } else if (offsetB !== 0) {
      offsetB *= -2;
    } else {
      if (distAB < 10) {
        if (startShapeInfo)
          offsetA = -(10 - distAB);
        else if (endShapeInfo)
          offsetB = -(10 - distAB);
      }
    }
  }
  if (offsetA !== 0) {
    const n = offsetA / lAB * (isClockwise ? 1 : -1);
    const u2 = Vec2d.FromAngle(aCA + dAB * n);
    tempA.setTo(handleArc.center).add(u2.mul(handleArc.radius));
  }
  if (offsetB !== 0) {
    const n = offsetB / lAB * (isClockwise ? -1 : 1);
    const u2 = Vec2d.FromAngle(aCB + dAB * n);
    tempB.setTo(handleArc.center).add(u2.mul(handleArc.radius));
  }
  if (startShapeInfo && endShapeInfo && !startShapeInfo.isExact && !endShapeInfo.isExact) {
    aCA = Vec2d.Angle(handleArc.center, tempA);
    aCB = Vec2d.Angle(handleArc.center, tempB);
    dAB = distFn(aCA, aCB);
    lAB = dAB * handleArc.radius;
    if (startShapeInfo.shape === endShapeInfo.shape) {
      if (lAB < 100) {
        tempA.setTo(a);
        tempB.setTo(b);
        tempC.setTo(c);
      }
    } else {
      if (startShapeInfo && !startShapeInfo.didIntersect) {
        tempA.setTo(a);
      }
      if (endShapeInfo && !endShapeInfo.didIntersect || distFn(handle_aCA, aCA) > distFn(handle_aCA, aCB)) {
        const n = Math.min(0.9, MIN_ARROW_LENGTH / lAB) * (isClockwise ? 1 : -1);
        const u2 = Vec2d.FromAngle(aCA + dAB * n);
        tempB.setTo(handleArc.center).add(u2.mul(handleArc.radius));
      }
    }
  }
  placeCenterHandle(
    handleArc.center,
    handleArc.radius,
    tempA,
    tempB,
    tempC,
    handle_dAB,
    isClockwise
  );
  if (tempA.equals(tempB)) {
    tempA.setTo(tempC.clone().addXY(1, 1));
    tempB.setTo(tempC.clone().subXY(1, 1));
  }
  a.setTo(tempA);
  b.setTo(tempB);
  c.setTo(tempC);
  const bodyArc = getArcInfo(a, b, c);
  return {
    isStraight: false,
    start: {
      point: a,
      handle: terminalsInArrowSpace.start,
      arrowhead: shape.props.arrowheadStart
    },
    end: {
      point: b,
      handle: terminalsInArrowSpace.end,
      arrowhead: shape.props.arrowheadEnd
    },
    middle: c,
    handleArc,
    bodyArc,
    isValid: bodyArc.length !== 0 && isFinite(bodyArc.center.x) && isFinite(bodyArc.center.y)
  };
}
function getCurvedArrowHandlePath(info) {
  const {
    start,
    end,
    handleArc: { radius, largeArcFlag, sweepFlag }
  } = info;
  return `M${start.handle.x},${start.handle.y} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.handle.x},${end.handle.y}`;
}
function getSolidCurvedArrowPath(info) {
  const {
    start,
    end,
    bodyArc: { radius, largeArcFlag, sweepFlag }
  } = info;
  return `M${start.point.x},${start.point.y} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.point.x},${end.point.y}`;
}
function getArcInfo(a, b, c) {
  const u = -2 * (a.x * (b.y - c.y) - a.y * (b.x - c.x) + b.x * c.y - c.x * b.y);
  const center = {
    x: ((a.x * a.x + a.y * a.y) * (c.y - b.y) + (b.x * b.x + b.y * b.y) * (a.y - c.y) + (c.x * c.x + c.y * c.y) * (b.y - a.y)) / u,
    y: ((a.x * a.x + a.y * a.y) * (b.x - c.x) + (b.x * b.x + b.y * b.y) * (c.x - a.x) + (c.x * c.x + c.y * c.y) * (a.x - b.x)) / u
  };
  const radius = Vec2d.Dist(center, a);
  const sweepFlag = +Vec2d.Clockwise(a, c, b);
  const ab = Math.hypot(a.y - b.y, a.x - b.x);
  const bc = Math.hypot(b.y - c.y, b.x - c.x);
  const ca = Math.hypot(c.y - a.y, c.x - a.x);
  const theta = Math.acos((bc * bc + ca * ca - ab * ab) / (2 * bc * ca)) * 2;
  const largeArcFlag = +(PI > theta);
  const size2 = (PI2 - theta) * (sweepFlag ? 1 : -1);
  const length = size2 * radius;
  return {
    center,
    radius,
    size: size2,
    length,
    largeArcFlag,
    sweepFlag
  };
}
function placeCenterHandle(center, radius, tempA, tempB, tempC, originalArcLength, isClockwise) {
  const aCA = Vec2d.Angle(center, tempA);
  const aCB = Vec2d.Angle(center, tempB);
  let dAB = clockwiseAngleDist(aCA, aCB);
  if (!isClockwise)
    dAB = PI2 - dAB;
  const n = 0.5 * (isClockwise ? 1 : -1);
  const u = Vec2d.FromAngle(aCA + dAB * n);
  tempC.setTo(center).add(u.mul(radius));
  if (dAB > originalArcLength) {
    tempC.rotWith(center, PI);
    const t2 = tempB.clone();
    tempB.setTo(tempA);
    tempA.setTo(t2);
  }
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/types/event-types.mjs
var EVENT_NAME_MAP = {
  wheel: "onWheel",
  pointer_down: "onPointerDown",
  pointer_move: "onPointerMove",
  pointer_up: "onPointerUp",
  right_click: "onRightClick",
  middle_click: "onMiddleClick",
  key_down: "onKeyDown",
  key_up: "onKeyUp",
  key_repeat: "onKeyRepeat",
  cancel: "onCancel",
  complete: "onComplete",
  interrupt: "onInterrupt",
  double_click: "onDoubleClick",
  triple_click: "onTripleClick",
  quadruple_click: "onQuadrupleClick"
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/tools/StateNode.mjs
var __defProp3 = Object.defineProperty;
var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
var __decorateClass3 = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc3(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp3(target, key, result);
  return result;
};
var StateNode = class {
  constructor(editor, parent) {
    this.editor = editor;
    const { id, children, initial } = this.constructor;
    this.id = id;
    this.current = atom("toolState" + this.id, void 0);
    this.path = computed("toolPath" + this.id, () => {
      const current = this.current.value;
      return this.id + (current ? `.${current.path.value}` : "");
    });
    this.parent = parent ?? {};
    if (this.parent) {
      if (children && initial) {
        this.type = "branch";
        this.initial = initial;
        this.children = Object.fromEntries(
          children().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])
        );
        this.current.set(this.children[this.initial]);
      } else {
        this.type = "leaf";
      }
    } else {
      this.type = "root";
      if (children && initial) {
        this.initial = initial;
        this.children = Object.fromEntries(
          children().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])
        );
        this.current.set(this.children[this.initial]);
      }
    }
  }
  path;
  static id;
  static initial;
  static children;
  id;
  current;
  type;
  shapeType;
  initial;
  children;
  parent;
  isActive = false;
  transition = (id, info) => {
    const path = id.split(".");
    let currState = this;
    for (let i = 0; i < path.length; i++) {
      const id2 = path[i];
      const prevChildState = currState.current.value;
      const nextChildState = currState.children?.[id2];
      if (!nextChildState) {
        throw Error(`${currState.id} - no child state exists with the id ${id2}.`);
      }
      if (prevChildState?.id !== nextChildState.id) {
        prevChildState?.exit(info, id2);
        currState.current.set(nextChildState);
        nextChildState.enter(info, prevChildState?.id || "initial");
        if (!nextChildState.isActive)
          break;
      }
      currState = nextChildState;
    }
    return this;
  };
  handleEvent = (info) => {
    const cbName = EVENT_NAME_MAP[info.name];
    const x = this.current.value;
    this[cbName]?.(info);
    if (this.current.value === x && this.isActive) {
      x?.handleEvent(info);
    }
  };
  enter = (info, from) => {
    this.isActive = true;
    this.onEnter?.(info, from);
    if (this.children && this.initial && this.isActive) {
      const initial = this.children[this.initial];
      this.current.set(initial);
      initial.enter(info, from);
    }
  };
  exit = (info, from) => {
    this.isActive = false;
    this.onExit?.(info, from);
    if (!this.isActive) {
      this.current.value?.exit(info, from);
    }
  };
  /**
   * This is a hack / escape hatch that will tell the editor to
   * report a different state as active (in `currentToolId`) when
   * this state is active. This is usually used when a tool transitions
   * to a child of a different state for a certain interaction and then
   * returns to the original tool when that interaction completes; and
   * where we would want to show the original tool as active in the UI.
   *
   * @public
   */
  _currentToolIdMask = atom("curent tool id mask", void 0);
  get currentToolIdMask() {
    return this._currentToolIdMask.value;
  }
  set currentToolIdMask(id) {
    this._currentToolIdMask.set(id);
  }
  onWheel;
  onPointerDown;
  onPointerMove;
  onPointerUp;
  onDoubleClick;
  onTripleClick;
  onQuadrupleClick;
  onRightClick;
  onMiddleClick;
  onKeyDown;
  onKeyUp;
  onKeyRepeat;
  onCancel;
  onComplete;
  onInterrupt;
  onEnter;
  onExit;
};
__decorateClass3([
  computed
], StateNode.prototype, "currentToolIdMask", 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/tools/RootState.mjs
var RootState = class extends StateNode {
  static id = "root";
  static initial = "";
  static children = () => [];
  onKeyDown = (info) => {
    switch (info.code) {
      case "KeyZ": {
        if (!(info.shiftKey || info.ctrlKey)) {
          const currentTool = this.current.value;
          if (currentTool && currentTool.current.value?.id === "idle") {
            if (this.children["zoom"]) {
              this.editor.setCurrentTool("zoom", { ...info, onInteractionEnd: currentTool.id });
            }
          }
        }
        break;
      }
    }
  };
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs
var __defProp4 = Object.defineProperty;
var __getOwnPropDesc4 = Object.getOwnPropertyDescriptor;
var __decorateClass4 = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc4(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp4(target, key, result);
  return result;
};
var Editor = class extends import_eventemitter3.EventEmitter {
  constructor({
    store,
    user,
    shapeUtils,
    tools,
    getContainer,
    initialState: initialState2,
    inferDarkMode
  }) {
    super();
    this.store = store;
    this.snaps = new SnapManager(this);
    this.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false);
    this.getContainer = getContainer ?? (() => document.body);
    this.textMeasure = new TextManager(this);
    class NewRoot extends RootState {
      static initial = initialState2 ?? "";
    }
    this.root = new NewRoot(this);
    this.root.children = {};
    const allShapeUtils = checkShapesAndAddCore(shapeUtils);
    const shapeTypesInSchema = new Set(
      Object.keys(store.schema.types.shape.migrations.subTypeMigrations)
    );
    for (const shapeUtil of allShapeUtils) {
      if (!shapeTypesInSchema.has(shapeUtil.type)) {
        throw Error(
          `Editor and store have different shapes: "${shapeUtil.type}" was passed into the editor but not the schema`
        );
      }
      shapeTypesInSchema.delete(shapeUtil.type);
    }
    if (shapeTypesInSchema.size > 0) {
      throw Error(
        `Editor and store have different shapes: "${[...shapeTypesInSchema][0]}" is present in the store schema but not provided to the editor`
      );
    }
    const _shapeUtils = {};
    const _styleProps = {};
    const allStylesById = /* @__PURE__ */ new Map();
    for (const Util of allShapeUtils) {
      const util = new Util(this);
      _shapeUtils[Util.type] = util;
      const propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {});
      _styleProps[Util.type] = propKeysByStyle;
      for (const style of propKeysByStyle.keys()) {
        if (!allStylesById.has(style.id)) {
          allStylesById.set(style.id, style);
        } else if (allStylesById.get(style.id) !== style) {
          throw Error(
            `Multiple style props with id "${style.id}" in use. Style prop IDs must be unique.`
          );
        }
      }
    }
    this.shapeUtils = _shapeUtils;
    this.styleProps = _styleProps;
    for (const Tool of [...tools]) {
      if (hasOwnProperty(this.root.children, Tool.id)) {
        throw Error(`Can't override tool with id "${Tool.id}"`);
      }
      this.root.children[Tool.id] = new Tool(this, this.root);
    }
    this.environment = new EnvironmentManager(this);
    const invalidParents = /* @__PURE__ */ new Set();
    const reparentArrow = (arrowId) => {
      const arrow3 = this.getShape(arrowId);
      if (!arrow3)
        return;
      const { start, end } = arrow3.props;
      const startShape = start.type === "binding" ? this.getShape(start.boundShapeId) : void 0;
      const endShape = end.type === "binding" ? this.getShape(end.boundShapeId) : void 0;
      const parentPageId = this.getAncestorPageId(arrow3);
      if (!parentPageId)
        return;
      let nextParentId;
      if (startShape && endShape) {
        nextParentId = this.findCommonAncestor([startShape, endShape]) ?? parentPageId;
      } else if (startShape || endShape) {
        nextParentId = parentPageId;
      } else {
        return;
      }
      if (nextParentId && nextParentId !== arrow3.parentId) {
        this.reparentShapes([arrowId], nextParentId);
      }
      const reparentedArrow = this.getShape(arrowId);
      if (!reparentedArrow)
        throw Error("no reparented arrow");
      const startSibling = this.getShapeNearestSibling(reparentedArrow, startShape);
      const endSibling = this.getShapeNearestSibling(reparentedArrow, endShape);
      let highestSibling;
      if (startSibling && endSibling) {
        highestSibling = startSibling.index > endSibling.index ? startSibling : endSibling;
      } else if (startSibling && !endSibling) {
        highestSibling = startSibling;
      } else if (endSibling && !startSibling) {
        highestSibling = endSibling;
      } else {
        return;
      }
      let finalIndex;
      const higherSiblings = this.getSortedChildIdsForParent(highestSibling.parentId).map((id) => this.getShape(id)).filter((sibling) => sibling.index > highestSibling.index);
      if (higherSiblings.length) {
        const nextHighestNonArrowSibling = higherSiblings.find(
          (sibling) => sibling.type !== "arrow"
        );
        if (
          // ...then, if we're above the last shape we want to be above...
          reparentedArrow.index > highestSibling.index && // ...but below the next non-arrow sibling...
          (!nextHighestNonArrowSibling || reparentedArrow.index < nextHighestNonArrowSibling.index)
        ) {
          return;
        }
        finalIndex = getIndexBetween(highestSibling.index, higherSiblings[0].index);
      } else {
        finalIndex = getIndexAbove(highestSibling.index);
      }
      if (finalIndex !== reparentedArrow.index) {
        this.updateShapes([{ id: arrowId, type: "arrow", index: finalIndex }]);
      }
    };
    const unbindArrowTerminal = (arrow3, handleId) => {
      const { x, y } = getArrowTerminalsInArrowSpace(this, arrow3)[handleId];
      this.store.put([{ ...arrow3, props: { ...arrow3.props, [handleId]: { type: "point", x, y } } }]);
    };
    const arrowDidUpdate = (arrow3) => {
      for (const handle of ["start", "end"]) {
        const terminal = arrow3.props[handle];
        if (terminal.type !== "binding")
          continue;
        const boundShape = this.getShape(terminal.boundShapeId);
        const isShapeInSamePageAsArrow = this.getAncestorPageId(arrow3) === this.getAncestorPageId(boundShape);
        if (!boundShape || !isShapeInSamePageAsArrow) {
          unbindArrowTerminal(arrow3, handle);
        }
      }
      reparentArrow(arrow3.id);
    };
    const cleanupInstancePageState = (prevPageState, shapesNoLongerInPage) => {
      let nextPageState = null;
      const selectedShapeIds = prevPageState.selectedShapeIds.filter(
        (id) => !shapesNoLongerInPage.has(id)
      );
      if (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {
        if (!nextPageState)
          nextPageState = { ...prevPageState };
        nextPageState.selectedShapeIds = selectedShapeIds;
      }
      const erasingShapeIds = prevPageState.erasingShapeIds.filter(
        (id) => !shapesNoLongerInPage.has(id)
      );
      if (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {
        if (!nextPageState)
          nextPageState = { ...prevPageState };
        nextPageState.erasingShapeIds = erasingShapeIds;
      }
      if (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {
        if (!nextPageState)
          nextPageState = { ...prevPageState };
        nextPageState.hoveredShapeId = null;
      }
      if (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {
        if (!nextPageState)
          nextPageState = { ...prevPageState };
        nextPageState.editingShapeId = null;
      }
      const hintingShapeIds = prevPageState.hintingShapeIds.filter(
        (id) => !shapesNoLongerInPage.has(id)
      );
      if (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {
        if (!nextPageState)
          nextPageState = { ...prevPageState };
        nextPageState.hintingShapeIds = hintingShapeIds;
      }
      if (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {
        if (!nextPageState)
          nextPageState = { ...prevPageState };
        nextPageState.focusedGroupId = null;
      }
      return nextPageState;
    };
    this.sideEffects = new SideEffectManager(this);
    this.sideEffects.registerBatchCompleteHandler(() => {
      for (const parentId of invalidParents) {
        invalidParents.delete(parentId);
        const parent = this.getShape(parentId);
        if (!parent)
          continue;
        const util = this.getShapeUtil(parent);
        const changes = util.onChildrenChange?.(parent);
        if (changes?.length) {
          this.updateShapes(changes, { squashing: true });
        }
      }
      this.emit("update");
    });
    this.sideEffects.registerBeforeDeleteHandler("shape", (record) => {
      if (record.parentId && isShapeId(record.parentId)) {
        invalidParents.add(record.parentId);
      }
      const bindings = this._arrowBindingsIndex.value[record.id];
      if (bindings?.length) {
        for (const { arrowId, handleId } of bindings) {
          const arrow3 = this.getShape(arrowId);
          if (!arrow3)
            continue;
          unbindArrowTerminal(arrow3, handleId);
        }
      }
      const deletedIds = /* @__PURE__ */ new Set([record.id]);
      const updates = compact(
        this.pageStates.map((pageState) => {
          return cleanupInstancePageState(pageState, deletedIds);
        })
      );
      if (updates.length) {
        this.store.put(updates);
      }
    });
    this.sideEffects.registerBeforeDeleteHandler("page", (record) => {
      if (this.instanceState.currentPageId !== record.id)
        return;
      const backupPageId = this.pages.find((p) => p.id !== record.id)?.id;
      if (!backupPageId)
        return;
      this.store.put([{ ...this.instanceState, currentPageId: backupPageId }]);
      const cameraId = CameraRecordType.createId(record.id);
      const instance_PageStateId = InstancePageStateRecordType.createId(record.id);
      this.store.remove([cameraId, instance_PageStateId]);
    });
    this.sideEffects.registerAfterChangeHandler("shape", (prev, next) => {
      if (this.isShapeOfType(next, "arrow")) {
        arrowDidUpdate(next);
      }
      if (prev.parentId !== next.parentId) {
        const reparentBoundArrows = (id) => {
          const boundArrows = this._arrowBindingsIndex.value[id];
          if (boundArrows?.length) {
            for (const arrow3 of boundArrows) {
              reparentArrow(arrow3.arrowId);
            }
          }
        };
        reparentBoundArrows(next.id);
        this.visitDescendants(next.id, reparentBoundArrows);
      }
      if (prev.parentId !== next.parentId && isPageId(next.parentId)) {
        const allMovingIds = /* @__PURE__ */ new Set([prev.id]);
        this.visitDescendants(prev.id, (id) => {
          allMovingIds.add(id);
        });
        for (const instancePageState of this.pageStates) {
          if (instancePageState.pageId === next.parentId)
            continue;
          const nextPageState = cleanupInstancePageState(instancePageState, allMovingIds);
          if (nextPageState) {
            this.store.put([nextPageState]);
          }
        }
      }
      if (prev.parentId && isShapeId(prev.parentId)) {
        invalidParents.add(prev.parentId);
      }
      if (next.parentId !== prev.parentId && isShapeId(next.parentId)) {
        invalidParents.add(next.parentId);
      }
    });
    this.sideEffects.registerAfterChangeHandler("instance_page_state", (prev, next) => {
      if (prev?.selectedShapeIds !== next?.selectedShapeIds) {
        const filtered = next.selectedShapeIds.filter((id) => {
          let parentId = this.getShape(id)?.parentId;
          while (isShapeId(parentId)) {
            if (next.selectedShapeIds.includes(parentId)) {
              return false;
            }
            parentId = this.getShape(parentId)?.parentId;
          }
          return true;
        });
        let nextFocusedGroupId = null;
        if (filtered.length > 0) {
          const commonGroupAncestor = this.findCommonAncestor(
            compact(filtered.map((id) => this.getShape(id))),
            (shape) => this.isShapeOfType(shape, "group")
          );
          if (commonGroupAncestor) {
            nextFocusedGroupId = commonGroupAncestor;
          }
        } else {
          if (next?.focusedGroupId) {
            nextFocusedGroupId = next.focusedGroupId;
          }
        }
        if (filtered.length !== next.selectedShapeIds.length || nextFocusedGroupId !== next.focusedGroupId) {
          this.store.put([
            { ...next, selectedShapeIds: filtered, focusedGroupId: nextFocusedGroupId ?? null }
          ]);
        }
      }
    });
    this.sideEffects.registerAfterCreateHandler("shape", (record) => {
      if (this.isShapeOfType(record, "arrow")) {
        arrowDidUpdate(record);
      }
    });
    this.sideEffects.registerAfterCreateHandler("page", (record) => {
      const cameraId = CameraRecordType.createId(record.id);
      const _pageStateId = InstancePageStateRecordType.createId(record.id);
      if (!this.store.has(cameraId)) {
        this.store.put([CameraRecordType.create({ id: cameraId })]);
      }
      if (!this.store.has(_pageStateId)) {
        this.store.put([
          InstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id })
        ]);
      }
    });
    this._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () => this.currentPageId);
    this._parentIdsToChildIds = parentsToChildren(this.store);
    this.disposables.add(
      this.store.listen((changes) => {
        this.emit("change", changes);
      })
    );
    this.store.ensureStoreIsUsable();
    this._setInstancePageState(
      {
        editingShapeId: null,
        hoveredShapeId: null,
        erasingShapeIds: []
      },
      { ephemeral: true }
    );
    if (initialState2 && this.root.children[initialState2] === void 0) {
      throw Error(`No state found for initialState "${initialState2}".`);
    }
    this.root.enter(void 0, "initial");
    if (this.instanceState.followingUserId) {
      this.stopFollowingUser();
    }
    this.updateRenderingBounds();
    requestAnimationFrame(() => {
      this._tickManager.start();
    });
  }
  /**
   * The editor's store
   *
   * @public
   */
  store;
  /**
   * The root state of the statechart.
   *
   * @public
   */
  root;
  /**
   * A set of functions to call when the app is disposed.
   *
   * @public
   */
  disposables = /* @__PURE__ */ new Set();
  /** @internal */
  _tickManager = new TickManager(this);
  /**
   * A manager for the app's snapping feature.
   *
   * @public
   */
  snaps;
  /**
   * A manager for the user and their preferences.
   *
   * @public
   */
  user;
  /**
   * A helper for measuring text.
   *
   * @public
   */
  textMeasure;
  /**
   * A manager for the editor's environment.
   *
   * @public
   */
  environment;
  /**
   * The current HTML element containing the editor.
   *
   * @example
   * ```ts
   * const container = editor.getContainer()
   * ```
   *
   * @public
   */
  getContainer;
  /**
   * A manager for side effects and correct state enforcement.
   *
   * @public
   */
  sideEffects;
  /**
   * Dispose the editor.
   *
   * @public
   */
  dispose() {
    this.disposables.forEach((dispose) => dispose());
    this.disposables.clear();
  }
  /* ------------------- Shape Utils ------------------ */
  /**
   * A map of shape utility classes (TLShapeUtils) by shape type.
   *
   * @public
   */
  shapeUtils;
  styleProps;
  getShapeUtil(arg) {
    const type = typeof arg === "string" ? arg : arg.type;
    const shapeUtil = getOwnProperty(this.shapeUtils, type);
    assert(shapeUtil, `No shape util found for type "${type}"`);
    return shapeUtil;
  }
  /* --------------------- History -------------------- */
  /**
   * A manager for the app's history.
   *
   * @readonly
   */
  history = new HistoryManager(
    this,
    // () => this._complete(),
    (error) => {
      this.annotateError(error, { origin: "history.batch", willCrashApp: true });
      this.crash(error);
    }
  );
  /**
   * Undo to the last mark.
   *
   * @example
   * ```ts
   * editor.undo()
   * ```
   *
   * @public
   */
  undo() {
    this.history.undo();
    return this;
  }
  get canUndo() {
    return this.history.numUndos > 0;
  }
  /**
   * Redo to the next mark.
   *
   * @example
   * ```ts
   * editor.redo()
   * ```
   *
   * @public
   */
  redo() {
    this.history.redo();
    return this;
  }
  get canRedo() {
    return this.history.numRedos > 0;
  }
  /**
   * Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
   * any redos.
   *
   * @example
   * ```ts
   * editor.mark()
   * editor.mark('flip shapes')
   * ```
   *
   * @param markId - The mark's id, usually the reason for adding the mark.
   * @param onUndo - (optional) Whether to stop at the mark when undoing.
   * @param onRedo - (optional) Whether to stop at the mark when redoing.
   *
   * @public
   */
  mark(markId, onUndo, onRedo) {
    this.history.mark(markId, onUndo, onRedo);
    return this;
  }
  /**
   * Clear all marks in the undo stack back to the next mark.
   *
   * @example
   * ```ts
   * editor.bail()
   * ```
   *
   * @public
   */
  bail() {
    this.history.bail();
    return this;
  }
  /**
   * Clear all marks in the undo stack back to the mark with the provided mark id.
   *
   * @example
   * ```ts
   * editor.bailToMark('dragging')
   * ```
   *
   * @public
   */
  bailToMark(id) {
    this.history.bailToMark(id);
    return this;
  }
  /**
   * Run a function in a batch, which will be undone/redone as a single action.
   *
   * @example
   * ```ts
   * editor.batch(() => {
   * 	editor.selectAll()
   * 	editor.deleteShapes(editor.selectedShapeIds)
   * 	editor.createShapes(myShapes)
   * 	editor.selectNone()
   * })
   *
   * editor.undo() // will undo all of the above
   * ```
   *
   * @public
   */
  batch(fn) {
    this.history.batch(fn);
    return this;
  }
  get _arrowBindingsIndex() {
    return arrowBindingsIndex(this);
  }
  /**
   * Get all arrows bound to a shape.
   *
   * @param shapeId - The id of the shape.
   *
   * @public
   */
  getArrowsBoundTo(shapeId) {
    return this._arrowBindingsIndex.value[shapeId] || EMPTY_ARRAY;
  }
  get arrowInfoCache() {
    return this.store.createComputedCache("arrow infoCache", (shape) => {
      return getIsArrowStraight(shape) ? getStraightArrowInfo(this, shape) : getCurvedArrowInfo(this, shape);
    });
  }
  /**
   * Get cached info about an arrow.
   *
   * @example
   * ```ts
   * const arrowInfo = editor.getArrowInfo(myArrow)
   * ```
   *
   * @param shape - The shape (or shape id) of the arrow to get the info for.
   *
   * @public
   */
  getArrowInfo(shape) {
    const id = typeof shape === "string" ? shape : shape.id;
    return this.arrowInfoCache.get(id);
  }
  /* --------------------- Errors --------------------- */
  /** @internal */
  annotateError(error, {
    origin,
    willCrashApp,
    tags,
    extras
  }) {
    const defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp);
    annotateError(error, {
      tags: { ...defaultAnnotations.tags, ...tags },
      extras: { ...defaultAnnotations.extras, ...extras }
    });
    if (willCrashApp) {
      this.store.markAsPossiblyCorrupted();
    }
    return this;
  }
  /** @internal */
  createErrorAnnotations(origin, willCrashApp) {
    try {
      return {
        tags: {
          origin,
          willCrashApp
        },
        extras: {
          activeStateNode: this.root.path.value,
          selectedShapes: this.selectedShapes,
          editingShape: this.editingShapeId ? this.getShape(this.editingShapeId) : void 0,
          inputs: this.inputs
        }
      };
    } catch {
      return {
        tags: {
          origin,
          willCrashApp
        },
        extras: {}
      };
    }
  }
  /** @internal */
  _crashingError = null;
  /**
   * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,
   * we're in a transaction that's about to be rolled back due to the same error we're currently
   * reporting.
   *
   * Instead, to listen to changes to this value, you need to listen to app's `crash` event.
   *
   * @internal
   */
  get crashingError() {
    return this._crashingError;
  }
  /** @internal */
  crash(error) {
    this._crashingError = error;
    this.store.markAsPossiblyCorrupted();
    this.emit("crash", { error });
    return this;
  }
  /* ------------------- Statechart ------------------- */
  /**
   * Get whether a certain tool (or other state node) is currently active.
   *
   * @example
   * ```ts
   * editor.isIn('select')
   * editor.isIn('select.brushing')
   * ```
   *
   * @param path - The path of active states, separated by periods.
   *
   * @public
   */
  isIn(path) {
    const ids = path.split(".").reverse();
    let state = this.root;
    while (ids.length > 0) {
      const id = ids.pop();
      if (!id)
        return true;
      const current = state.current.value;
      if (current?.id === id) {
        if (ids.length === 0)
          return true;
        state = current;
        continue;
      } else
        return false;
    }
    return false;
  }
  /**
   * Get whether the state node is in any of the given active paths.
   *
   * @example
   * ```ts
   * state.isInAny('select', 'erase')
   * state.isInAny('select.brushing', 'erase.idle')
   * ```
   *
   * @public
   */
  isInAny(...paths) {
    return paths.some((path) => this.isIn(path));
  }
  /**
   * Set the selected tool.
   *
   * @example
   * ```ts
   * editor.setCurrentTool('hand')
   * editor.setCurrentTool('hand', { date: Date.now() })
   * ```
   *
   * @param id - The id of the tool to select.
   * @param info - Arbitrary data to pass along into the transition.
   *
   * @public
   */
  setCurrentTool(id, info = {}) {
    this.root.transition(id, info);
    return this;
  }
  get currentTool() {
    return this.root.current.value;
  }
  get currentToolId() {
    const { currentTool } = this;
    if (!currentTool)
      return "";
    return currentTool.currentToolIdMask ?? currentTool.id;
  }
  /**
   * Get a descendant by its path.
   *
   * @example
   * ```ts
   * state.getStateDescendant('select')
   * state.getStateDescendant('select.brushing')
   * ```
   *
   * @param path - The descendant's path of state ids, separated by periods.
   *
   * @public
   */
  getStateDescendant(path) {
    const ids = path.split(".").reverse();
    let state = this.root;
    while (ids.length > 0) {
      const id = ids.pop();
      if (!id)
        return state;
      const childState = state.children?.[id];
      if (!childState)
        return void 0;
      state = childState;
    }
    return state;
  }
  get documentSettings() {
    return this.store.get(TLDOCUMENT_ID);
  }
  /**
   * Update the global document settings that apply to all users.
   *
   * @public
   **/
  updateDocumentSettings(settings) {
    this.store.put([{ ...this.documentSettings, ...settings }]);
    return this;
  }
  get instanceState() {
    return this.store.get(TLINSTANCE_ID);
  }
  /**
   * Update the instance's state.
   *
   * @param partial - A partial object to update the instance state with.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  updateInstanceState(partial, historyOptions) {
    this._updateInstanceState(partial, { ephemeral: true, squashing: true, ...historyOptions });
    if (partial.isChangingStyle !== void 0) {
      clearTimeout(this._isChangingStyleTimeout);
      if (partial.isChangingStyle === true) {
        this._isChangingStyleTimeout = setTimeout(() => {
          this.updateInstanceState({ isChangingStyle: false });
        }, 2e3);
      }
    }
    return this;
  }
  /** @internal */
  _updateInstanceState = this.history.createCommand(
    "updateInstanceState",
    (partial, historyOptions) => {
      const prev = this.store.get(this.instanceState.id);
      const next = { ...prev, ...partial };
      return {
        data: { prev, next },
        ephemeral: false,
        squashing: false,
        ...historyOptions
      };
    },
    {
      do: ({ next }) => {
        this.store.put([next]);
      },
      undo: ({ prev }) => {
        this.store.put([prev]);
      },
      squash({ prev }, { next }) {
        return { prev, next };
      }
    }
  );
  /** @internal */
  _isChangingStyleTimeout = -1;
  get openMenus() {
    return this.instanceState.openMenus;
  }
  /**
   * Add an open menu.
   *
   * @example
   * ```ts
   * editor.addOpenMenu('menu-id')
   * ```
   *
   * @public
   */
  addOpenMenu(id) {
    const menus = new Set(this.openMenus);
    if (!menus.has(id)) {
      menus.add(id);
      this.updateInstanceState({ openMenus: [...menus] });
    }
    return this;
  }
  /**
   * Delete an open menu.
   *
   * @example
   * ```ts
   * editor.deleteOpenMenu('menu-id')
   * ```
   *
   * @public
   */
  deleteOpenMenu(id) {
    const menus = new Set(this.openMenus);
    if (menus.has(id)) {
      menus.delete(id);
      this.updateInstanceState({ openMenus: [...menus] });
    }
    return this;
  }
  get isMenuOpen() {
    return this.openMenus.length > 0;
  }
  /* --------------------- Cursor --------------------- */
  /**
   * Set the cursor.
   *
   * @param type - The cursor type.
   * @param rotation - The cursor rotation.
   *
   * @public
   */
  setCursor = (cursor) => {
    this.updateInstanceState(
      { cursor: { ...this.instanceState.cursor, ...cursor } },
      { ephemeral: true }
    );
    return this;
  };
  get pageStates() {
    return this._pageStates.value;
  }
  get _pageStates() {
    return this.store.query.records("instance_page_state");
  }
  get currentPageState() {
    return this.store.get(this._currentPageStateId);
  }
  get _currentPageStateId() {
    return InstancePageStateRecordType.createId(this.currentPageId);
  }
  /**
   * Update this instance's page state.
   *
   * @example
   * ```ts
   * editor.updateInstancePageState({ id: 'page1', editingShapeId: 'shape:123' })
   * editor.updateInstancePageState({ id: 'page1', editingShapeId: 'shape:123' }, { ephemeral: true })
   * ```
   *
   * @param partial - The partial of the page state object containing the changes.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  updateCurrentPageState(partial, historyOptions) {
    this._setInstancePageState(partial, historyOptions);
    return this;
  }
  /** @internal */
  _setInstancePageState = this.history.createCommand(
    "setInstancePageState",
    (partial, historyOptions) => {
      const prev = this.store.get(partial.id ?? this.currentPageState.id);
      return { data: { prev, partial }, ...historyOptions };
    },
    {
      do: ({ prev, partial }) => {
        this.store.update(prev.id, (state) => ({ ...state, ...partial }));
      },
      undo: ({ prev }) => {
        this.store.update(prev.id, () => prev);
      }
    }
  );
  get selectedShapeIds() {
    return this.currentPageState.selectedShapeIds;
  }
  get selectedShapes() {
    const { selectedShapeIds } = this.currentPageState;
    return compact(selectedShapeIds.map((id) => this.store.get(id)));
  }
  /**
   * Select one or more shapes.
   *
   * @example
   * ```ts
   * editor.setSelectedShapes(['id1'])
   * editor.setSelectedShapes(['id1', 'id2'])
   * ```
   *
   * @param ids - The ids to select.
   * @param historyOptions - The history options for the change.
   *
   * @public
   */
  setSelectedShapes(shapes, historyOptions) {
    const ids = shapes.map((shape) => typeof shape === "string" ? shape : shape.id);
    this._setSelectedShapes(ids, historyOptions);
    return this;
  }
  /** @internal */
  _setSelectedShapes = this.history.createCommand(
    "setSelectedShapes",
    (ids, historyOptions) => {
      const { selectedShapeIds: prevSelectedShapeIds } = this.currentPageState;
      const prevSet = new Set(prevSelectedShapeIds);
      if (ids.length === prevSet.size && ids.every((id) => prevSet.has(id)))
        return null;
      return {
        data: { selectedShapeIds: ids, prevSelectedShapeIds },
        preservesRedoStack: true,
        ...historyOptions
      };
    },
    {
      do: ({ selectedShapeIds }) => {
        this.store.put([{ ...this.currentPageState, selectedShapeIds }]);
      },
      undo: ({ prevSelectedShapeIds }) => {
        this.store.put([
          {
            ...this.currentPageState,
            selectedShapeIds: prevSelectedShapeIds
          }
        ]);
      },
      squash({ prevSelectedShapeIds }, { selectedShapeIds }) {
        return {
          selectedShapeIds,
          prevSelectedShapeIds
        };
      }
    }
  );
  /**
   * Determine whether or not any of a shape's ancestors are selected.
   *
   * @param id - The id of the shape to check.
   *
   * @public
   */
  isAncestorSelected(shape) {
    const id = typeof shape === "string" ? shape : shape?.id ?? null;
    const _shape = this.getShape(id);
    if (!_shape)
      return false;
    const { selectedShapeIds } = this;
    return !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id));
  }
  /**
   * Select one or more shapes.
   *
   * @example
   * ```ts
   * editor.select('id1')
   * editor.select('id1', 'id2')
   * ```
   *
   * @param ids - The ids to select.
   *
   * @public
   */
  select(...shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
    this.setSelectedShapes(ids);
    return this;
  }
  /**
   * Remove a shape from the existing set of selected shapes.
   *
   * @example
   * ```ts
   * editor.deselect(shape.id)
   * ```
   *
   * @public
   */
  deselect(...shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
    const { selectedShapeIds } = this;
    if (selectedShapeIds.length > 0 && ids.length > 0) {
      this.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)));
    }
    return this;
  }
  /**
   * Select all direct children of the current page.
   *
   * @example
   * ```ts
   * editor.selectAll()
   * ```
   *
   * @public
   */
  selectAll() {
    const ids = this.getSortedChildIdsForParent(this.currentPageId);
    if (ids.length <= 0)
      return this;
    this.setSelectedShapes(this._getUnlockedShapeIds(ids));
    return this;
  }
  /**
   * Clear the selection.
   *
   * @example
   * ```ts
   * editor.selectNone()
   * ```
   *
   * @public
   */
  selectNone() {
    if (this.selectedShapeIds.length > 0) {
      this.setSelectedShapes([]);
    }
    return this;
  }
  get onlySelectedShape() {
    const { selectedShapes } = this;
    return selectedShapes.length === 1 ? selectedShapes[0] : null;
  }
  get selectionPageBounds() {
    const {
      currentPageState: { selectedShapeIds }
    } = this;
    if (selectedShapeIds.length === 0)
      return null;
    return Box2d.Common(compact(selectedShapeIds.map((id) => this.getShapePageBounds(id))));
  }
  get selectionRotation() {
    const { selectedShapeIds } = this;
    if (selectedShapeIds.length === 0) {
      return 0;
    }
    if (selectedShapeIds.length === 1) {
      return this.getShapePageTransform(this.selectedShapeIds[0]).rotation();
    }
    const allRotations = selectedShapeIds.map((id) => this.getShapePageTransform(id).rotation());
    if (allRotations.every((rotation) => Math.abs(rotation - allRotations[0]) < Math.PI / 180)) {
      return this.getShapePageTransform(selectedShapeIds[0]).rotation();
    }
    return 0;
  }
  get selectionRotatedPageBounds() {
    const { selectedShapeIds } = this;
    if (selectedShapeIds.length === 0) {
      return void 0;
    }
    const { selectionRotation } = this;
    if (selectionRotation === 0) {
      return this.selectionPageBounds;
    }
    if (selectedShapeIds.length === 1) {
      const bounds = this.getShapeGeometry(selectedShapeIds[0]).bounds.clone();
      const pageTransform = this.getShapePageTransform(selectedShapeIds[0]);
      bounds.point = pageTransform.applyToPoint(bounds.point);
      return bounds;
    }
    const boxFromRotatedVertices = Box2d.FromPoints(
      this.selectedShapeIds.flatMap((id) => {
        const pageTransform = this.getShapePageTransform(id);
        if (!pageTransform)
          return [];
        return pageTransform.applyToPoints(this.getShapeGeometry(id).vertices);
      }).map((p) => Vec2d.Rot(p, -selectionRotation))
    );
    boxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation);
    return boxFromRotatedVertices;
  }
  get focusedGroupId() {
    return this.currentPageState.focusedGroupId ?? this.currentPageId;
  }
  get focusedGroup() {
    const { focusedGroupId } = this;
    return focusedGroupId ? this.getShape(focusedGroupId) : void 0;
  }
  /**
   * Set the current focused group shape.
   *
   * @param shape - The group shape id (or group shape's id) to set as the focused group shape.
   *
   * @public
   */
  setFocusedGroup(shape) {
    const id = typeof shape === "string" ? shape : shape?.id ?? null;
    if (id !== null) {
      const shape2 = this.getShape(id);
      if (!shape2) {
        throw Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`);
      }
      if (!this.isShapeOfType(shape2, "group")) {
        throw Error(
          `Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape2.type}`
        );
      }
    }
    if (id === this.focusedGroupId)
      return this;
    this._setFocusedGroupId(id);
    return this;
  }
  /** @internal */
  _setFocusedGroupId = this.history.createCommand(
    "setFocusedGroupId",
    (next) => {
      const prev = this.currentPageState.focusedGroupId;
      if (prev === next)
        return;
      return {
        data: {
          prev,
          next
        },
        preservesRedoStack: true,
        squashing: true
      };
    },
    {
      do: ({ next }) => {
        this.store.update(this.currentPageState.id, (s) => ({ ...s, focusedGroupId: next }));
      },
      undo: ({ prev }) => {
        this.store.update(this.currentPageState.id, (s) => ({ ...s, focusedGroupId: prev }));
      },
      squash({ prev }, { next }) {
        return { prev, next };
      }
    }
  );
  /**
   * Exit the current focused group, moving up to the next parent group if there is one.
   *
   * @public
   */
  popFocusedGroupId() {
    const { focusedGroup } = this;
    if (focusedGroup) {
      const match = this.findShapeAncestor(
        focusedGroup,
        (shape) => this.isShapeOfType(shape, "group")
      );
      this.setFocusedGroup(match?.id ?? null);
      this.select(focusedGroup.id);
    } else {
      this.setFocusedGroup(null);
      this.selectNone();
    }
    return this;
  }
  get editingShapeId() {
    return this.currentPageState.editingShapeId;
  }
  get editingShape() {
    const { editingShapeId } = this;
    return editingShapeId ? this.getShape(editingShapeId) : void 0;
  }
  /**
   * Set the current editing shape.
   *
   * @example
   * ```ts
   * editor.setEditingShape(myShape)
   * editor.setEditingShape(myShape.id)
   * ```
   *
   * @param shape - The shape (or shape id) to set as editing.
   *
   * @public
   */
  setEditingShape(shape) {
    const id = typeof shape === "string" ? shape : shape?.id ?? null;
    if (id !== this.editingShapeId) {
      if (id) {
        const shape2 = this.getShape(id);
        if (shape2 && this.getShapeUtil(shape2).canEdit(shape2)) {
          this._setInstancePageState({ editingShapeId: id });
          return this;
        }
      }
      this._setInstancePageState({ editingShapeId: null });
    }
    return this;
  }
  get hoveredShapeId() {
    return this.currentPageState.hoveredShapeId;
  }
  get hoveredShape() {
    const { hoveredShapeId } = this;
    return hoveredShapeId ? this.getShape(hoveredShapeId) : void 0;
  }
  /**
   * Set the editor's current hovered shape.
   *
   * @example
   * ```ts
   * editor.setHoveredShape(myShape)
   * editor.setHoveredShape(myShape.id)
   * ```
   *
   * @param shapes - The shape (or shape id) to set as hovered.
   *
   * @public
   */
  setHoveredShape(shape) {
    const id = typeof shape === "string" ? shape : shape?.id ?? null;
    if (id === this.hoveredShapeId)
      return this;
    this.updateCurrentPageState({ hoveredShapeId: id }, { ephemeral: true });
    return this;
  }
  get hintingShapeIds() {
    return this.currentPageState.hintingShapeIds;
  }
  get hintingShapes() {
    const { hintingShapeIds } = this;
    return compact(hintingShapeIds.map((id) => this.getShape(id)));
  }
  /**
   * Set the editor's current hinting shapes.
   *
   * @example
   * ```ts
   * editor.setHintingShapes([myShape])
   * editor.setHintingShapes([myShape.id])
   * ```
   *
   * @param shapes - The shapes (or shape ids) to set as hinting.
   *
   * @public
   */
  setHintingShapes(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
    this.updateCurrentPageState({ hintingShapeIds: dedupe(ids) }, { ephemeral: true });
    return this;
  }
  get erasingShapeIds() {
    return this.currentPageState.erasingShapeIds;
  }
  get erasingShapes() {
    const { erasingShapeIds } = this;
    return compact(erasingShapeIds.map((id) => this.getShape(id)));
  }
  /**
   * Set the editor's current erasing shapes.
   *
   * @example
   * ```ts
   * editor.setErasingShapes([myShape])
   * editor.setErasingShapes([myShape.id])
   * ```
   *
   * @param shapes - The shapes (or shape ids) to set as hinting.
   *
   * @public
   */
  setErasingShapes(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
    ids.sort();
    const { erasingShapeIds } = this;
    if (ids.length === erasingShapeIds.length) {
      for (let i = 0; i < ids.length; i++) {
        if (ids[i] !== erasingShapeIds[i]) {
          this._setInstancePageState({ erasingShapeIds: ids }, { ephemeral: true });
          break;
        }
      }
    } else {
      this._setInstancePageState({ erasingShapeIds: ids }, { ephemeral: true });
    }
    return this;
  }
  // Cropping
  /**
   * The current cropping shape's id.
   *
   * @public
   */
  get croppingShapeId() {
    return this.currentPageState.croppingShapeId;
  }
  /**
   * Set the current cropping shape.
   *
   * @example
   * ```ts
   * editor.setCroppingShape(myShape)
   * editor.setCroppingShape(myShape.id)
   * ```
   *
   *
   * @param shape - The shape (or shape id) to set as cropping.
   *
   * @public
   */
  setCroppingShape(shape) {
    const id = typeof shape === "string" ? shape : shape?.id ?? null;
    if (id !== this.croppingShapeId) {
      if (!id) {
        this.updateCurrentPageState({ croppingShapeId: null });
      } else {
        const shape2 = this.getShape(id);
        const util = this.getShapeUtil(shape2);
        if (shape2 && util.canCrop(shape2)) {
          this.updateCurrentPageState({ croppingShapeId: id });
        }
      }
    }
    return this;
  }
  get cameraId() {
    return CameraRecordType.createId(this.currentPageId);
  }
  get camera() {
    return this.store.get(this.cameraId);
  }
  get zoomLevel() {
    return this.camera.z;
  }
  /** @internal */
  _setCamera(point) {
    const currentCamera = this.camera;
    if (currentCamera.x === point.x && currentCamera.y === point.y && currentCamera.z === point.z) {
      return this;
    }
    this.batch(() => {
      this.store.put([{ ...currentCamera, ...point }]);
      const { currentScreenPoint } = this.inputs;
      this.dispatch({
        type: "pointer",
        target: "canvas",
        name: "pointer_move",
        point: currentScreenPoint,
        pointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,
        ctrlKey: this.inputs.ctrlKey,
        altKey: this.inputs.altKey,
        shiftKey: this.inputs.shiftKey,
        button: 0,
        isPen: this.instanceState.isPenMode ?? false
      });
      this._tickCameraState();
    });
    return this;
  }
  /**
   * Set the current camera.
   *
   * @example
   * ```ts
   * editor.setCamera({ x: 0, y: 0})
   * editor.setCamera({ x: 0, y: 0, z: 1.5})
   * editor.setCamera({ x: 0, y: 0, z: 1.5}, { duration: 1000, easing: (t) => t * t })
   * ```
   *
   * @param point - The new camera position.
   * @param animation - (optional) Options for an animation.
   *
   * @public
   */
  setCamera(point, animation) {
    const x = Number.isFinite(point.x) ? point.x : 0;
    const y = Number.isFinite(point.y) ? point.y : 0;
    const z = Number.isFinite(point.z) ? point.z : this.zoomLevel;
    this.stopCameraAnimation();
    if (this.instanceState.followingUserId) {
      this.stopFollowingUser();
    }
    if (animation) {
      const { width, height } = this.viewportScreenBounds;
      return this._animateToViewport(new Box2d(-x, -y, width / z, height / z), animation);
    } else {
      this._setCamera({ x, y, z });
    }
    return this;
  }
  /**
   * Center the camera on a point (in the current page space).
   *
   * @example
   * ```ts
   * editor.centerOnPoint({ x: 100, y: 100 })
   * editor.centerOnPoint({ x: 100, y: 100 }, { duration: 200 })
   * ```
   *
   * @param point - The point in the current page space to center on.
   * @param animation - (optional) The options for an animation.
   *
   * @public
   */
  centerOnPoint(point, animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const {
      viewportPageBounds: { width: pw, height: ph },
      camera
    } = this;
    this.setCamera({ x: -(point.x - pw / 2), y: -(point.y - ph / 2), z: camera.z }, animation);
    return this;
  }
  /**
   * Move the camera to the nearest content.
   *
   * @example
   * ```ts
   * editor.zoomToContent()
   * editor.zoomToContent({ duration: 200 })
   * ```
   *
   * @param opts - (optional) The options for an animation.
   *
   * @public
   */
  zoomToContent() {
    const bounds = this.selectionPageBounds ?? this.currentPageBounds;
    if (bounds) {
      this.zoomToBounds(bounds, Math.min(1, this.zoomLevel), { duration: 220 });
    }
    return this;
  }
  /**
   * Zoom the camera to fit the current page's content in the viewport.
   *
   * @example
   * ```ts
   * editor.zoomToFit()
   * editor.zoomToFit({ duration: 200 })
   * ```
   *
   * @param animation - (optional) The options for an animation.
   *
   * @public
   */
  zoomToFit(animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const ids = [...this.currentPageShapeIds];
    if (ids.length <= 0)
      return this;
    const pageBounds = Box2d.Common(compact(ids.map((id) => this.getShapePageBounds(id))));
    this.zoomToBounds(pageBounds, void 0, animation);
    return this;
  }
  /**
   * Set the zoom back to 100%.
   *
   * @example
   * ```ts
   * editor.resetZoom()
   * editor.resetZoom(editor.viewportScreenCenter)
   * editor.resetZoom(editor.viewportScreenCenter, { duration: 200 })
   * ```
   *
   * @param point - (optional) The screen point to zoom out on. Defaults to the viewport screen center.
   * @param animation - (optional) The options for an animation.
   *
   * @public
   */
  resetZoom(point = this.viewportScreenCenter, animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const { x: cx, y: cy, z: cz } = this.camera;
    const { x, y } = point;
    this.setCamera(
      { x: cx + (x / 1 - x) - (x / cz - x), y: cy + (y / 1 - y) - (y / cz - y), z: 1 },
      animation
    );
    return this;
  }
  /**
   * Zoom the camera in.
   *
   * @example
   * ```ts
   * editor.zoomIn()
   * editor.zoomIn(editor.viewportScreenCenter, { duration: 120 })
   * editor.zoomIn(editor.inputs.currentScreenPoint, { duration: 120 })
   * ```
   *
   * @param animation - (optional) The options for an animation.
   *
   * @public
   */
  zoomIn(point = this.viewportScreenCenter, animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const { x: cx, y: cy, z: cz } = this.camera;
    let zoom = MAX_ZOOM;
    for (let i = 1; i < ZOOMS.length; i++) {
      const z1 = ZOOMS[i - 1];
      const z2 = ZOOMS[i];
      if (z2 - cz <= (z2 - z1) / 2)
        continue;
      zoom = z2;
      break;
    }
    const { x, y } = point;
    this.setCamera(
      { x: cx + (x / zoom - x) - (x / cz - x), y: cy + (y / zoom - y) - (y / cz - y), z: zoom },
      animation
    );
    return this;
  }
  /**
   * Zoom the camera out.
   *
   * @example
   * ```ts
   * editor.zoomOut()
   * editor.zoomOut(editor.viewportScreenCenter, { duration: 120 })
   * editor.zoomOut(editor.inputs.currentScreenPoint, { duration: 120 })
   * ```
   *
   * @param animation - (optional) The options for an animation.
   *
   * @public
   */
  zoomOut(point = this.viewportScreenCenter, animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const { x: cx, y: cy, z: cz } = this.camera;
    let zoom = MIN_ZOOM;
    for (let i = ZOOMS.length - 1; i > 0; i--) {
      const z1 = ZOOMS[i - 1];
      const z2 = ZOOMS[i];
      if (z2 - cz >= (z2 - z1) / 2)
        continue;
      zoom = z1;
      break;
    }
    const { x, y } = point;
    this.setCamera(
      {
        x: cx + (x / zoom - x) - (x / cz - x),
        y: cy + (y / zoom - y) - (y / cz - y),
        z: zoom
      },
      animation
    );
    return this;
  }
  /**
   * Zoom the camera to fit the current selection in the viewport.
   *
   * @example
   * ```ts
   * editor.zoomToSelection()
   * ```
   *
   * @param animation - (optional) The options for an animation.
   *
   * @public
   */
  zoomToSelection(animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const { selectionPageBounds } = this;
    if (!selectionPageBounds)
      return this;
    this.zoomToBounds(selectionPageBounds, Math.max(1, this.zoomLevel), animation);
    return this;
  }
  /**
   * Pan or pan/zoom the selected ids into view. This method tries to not change the zoom if possible.
   *
   * @param ids - The ids of the shapes to pan and zoom into view.
   * @param animation - The options for an animation.
   *
   * @public
   */
  panZoomIntoView(ids, animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    if (ids.length <= 0)
      return this;
    const selectionBounds = Box2d.Common(compact(ids.map((id) => this.getShapePageBounds(id))));
    const { viewportPageBounds } = this;
    if (viewportPageBounds.h < selectionBounds.h || viewportPageBounds.w < selectionBounds.w) {
      this.zoomToBounds(selectionBounds, this.camera.z, animation);
      return this;
    } else {
      const insetViewport = this.viewportPageBounds.clone().expandBy(-32 / this.zoomLevel);
      let offsetX = 0;
      let offsetY = 0;
      if (insetViewport.maxY < selectionBounds.maxY) {
        offsetY = insetViewport.maxY - selectionBounds.maxY;
      } else if (insetViewport.minY > selectionBounds.minY) {
        offsetY = insetViewport.minY - selectionBounds.minY;
      } else {
      }
      if (insetViewport.maxX < selectionBounds.maxX) {
        offsetX = insetViewport.maxX - selectionBounds.maxX;
      } else if (insetViewport.minX > selectionBounds.minX) {
        offsetX = insetViewport.minX - selectionBounds.minX;
      } else {
      }
      const { camera } = this;
      this.setCamera({ x: camera.x + offsetX, y: camera.y + offsetY, z: camera.z }, animation);
    }
    return this;
  }
  /**
   * Zoom the camera to fit a bounding box (in the current page space).
   *
   * @example
   * ```ts
   * editor.zoomToBounds(myBounds)
   * editor.zoomToBounds(myBounds, 1)
   * editor.zoomToBounds(myBounds, 1, { duration: 100 })
   * ```
   *
   * @param bounds - The bounding box.
   * @param targetZoom - The desired zoom level. Defaults to 0.1.
   * @param animation - (optional) The options for an animation.
   *
   * @public
   */
  zoomToBounds(bounds, targetZoom, animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const { viewportScreenBounds } = this;
    const inset = Math.min(256, viewportScreenBounds.width * 0.28);
    let zoom = clamp(
      Math.min(
        (viewportScreenBounds.width - inset) / bounds.width,
        (viewportScreenBounds.height - inset) / bounds.height
      ),
      MIN_ZOOM,
      MAX_ZOOM
    );
    if (targetZoom !== void 0) {
      zoom = Math.min(targetZoom, zoom);
    }
    this.setCamera(
      {
        x: -bounds.minX + (viewportScreenBounds.width - bounds.width * zoom) / 2 / zoom,
        y: -bounds.minY + (viewportScreenBounds.height - bounds.height * zoom) / 2 / zoom,
        z: zoom
      },
      animation
    );
    return this;
  }
  /**
   * Pan the camera.
   *
   * @example
   * ```ts
   * editor.pan({ x: 100, y: 100 })
   * editor.pan({ x: 100, y: 100 }, { duration: 1000 })
   * ```
   *
   * @param offset - The offset in the current page space.
   * @param animation - (optional) The animation options.
   */
  pan(offset2, animation) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const { x: cx, y: cy, z: cz } = this.camera;
    this.setCamera({ x: cx + offset2.x / cz, y: cy + offset2.y / cz, z: cz }, animation);
    return this;
  }
  /**
   * Stop the current camera animation, if any.
   *
   * @public
   */
  stopCameraAnimation() {
    this.emit("stop-camera-animation");
    return this;
  }
  /** @internal */
  _viewportAnimation = null;
  /** @internal */
  _animateViewport(ms) {
    if (!this._viewportAnimation)
      return;
    const cancel = () => {
      this.removeListener("tick", this._animateViewport);
      this.removeListener("stop-camera-animation", cancel);
      this._viewportAnimation = null;
    };
    this.once("stop-camera-animation", cancel);
    this._viewportAnimation.elapsed += ms;
    const { elapsed, easing, duration, start, end } = this._viewportAnimation;
    if (elapsed > duration) {
      this._setCamera({ x: -end.x, y: -end.y, z: this.viewportScreenBounds.width / end.width });
      cancel();
      return;
    }
    const remaining = duration - elapsed;
    const t2 = easing(1 - remaining / duration);
    const left = start.minX + (end.minX - start.minX) * t2;
    const top = start.minY + (end.minY - start.minY) * t2;
    const right = start.maxX + (end.maxX - start.maxX) * t2;
    this._setCamera({ x: -left, y: -top, z: this.viewportScreenBounds.width / (right - left) });
  }
  /** @internal */
  _animateToViewport(targetViewportPage, opts = {}) {
    const { duration = 0, easing = EASINGS.easeInOutCubic } = opts;
    const {
      user: { animationSpeed },
      viewportPageBounds
    } = this;
    this.stopCameraAnimation();
    if (this.instanceState.followingUserId) {
      this.stopFollowingUser();
    }
    if (duration === 0 || animationSpeed === 0) {
      return this._setCamera({
        x: -targetViewportPage.x,
        y: -targetViewportPage.y,
        z: this.viewportScreenBounds.width / targetViewportPage.width
      });
    }
    this._viewportAnimation = {
      elapsed: 0,
      duration: duration / animationSpeed,
      easing,
      start: viewportPageBounds.clone(),
      end: targetViewportPage.clone()
    };
    this.addListener("tick", this._animateViewport);
    return this;
  }
  /**
   * Slide the camera in a certain direction.
   *
   * @param opts - Options for the slide
   * @public
   */
  slideCamera(opts = {}) {
    if (!this.instanceState.canMoveCamera)
      return this;
    this.stopCameraAnimation();
    const { animationSpeed } = this.user;
    if (animationSpeed === 0)
      return this;
    const { speed, friction, direction, speedThreshold = 0.01 } = opts;
    let currentSpeed = Math.min(speed, 1);
    const cancel = () => {
      this.removeListener("tick", moveCamera);
      this.removeListener("stop-camera-animation", cancel);
    };
    this.once("stop-camera-animation", cancel);
    const moveCamera = (elapsed) => {
      const { x: cx, y: cy, z: cz } = this.camera;
      const movementVec = Vec2d.Mul(direction, currentSpeed * elapsed / cz);
      currentSpeed *= 1 - friction;
      if (currentSpeed < speedThreshold) {
        cancel();
      } else {
        this._setCamera({ x: cx + movementVec.x, y: cy + movementVec.y, z: cz });
      }
    };
    this.addListener("tick", moveCamera);
    return this;
  }
  /**
   * Animate the camera to a user's cursor position.
   * This also briefly show the user's cursor if it's not currently visible.
   *
   * @param userId - The id of the user to aniamte to.
   * @public
   */
  animateToUser(userId) {
    const presences = this.store.query.records("instance_presence", () => ({
      userId: { eq: userId }
    }));
    const presence = [...presences.value].sort((a, b) => {
      return a.lastActivityTimestamp - b.lastActivityTimestamp;
    }).pop();
    if (!presence)
      return this;
    this.batch(() => {
      if (this.instanceState.followingUserId !== null) {
        this.stopFollowingUser();
      }
      const isOnSamePage = presence.currentPageId === this.currentPageId;
      if (!isOnSamePage) {
        this.setCurrentPage(presence.currentPageId);
      }
      const options = isOnSamePage ? { duration: 500 } : void 0;
      this.centerOnPoint(presence.cursor, options);
      const { highlightedUserIds } = this.instanceState;
      this.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] });
      setTimeout(() => {
        const highlightedUserIds2 = [...this.instanceState.highlightedUserIds];
        const index2 = highlightedUserIds2.indexOf(userId);
        if (index2 < 0)
          return;
        highlightedUserIds2.splice(index2, 1);
        this.updateInstanceState({ highlightedUserIds: highlightedUserIds2 });
      }, COLLABORATOR_IDLE_TIMEOUT);
    });
    return this;
  }
  /**
   * Animate the camera to a shape.
   *
   * @public
   */
  animateToShape(shapeId, opts = DEFAULT_ANIMATION_OPTIONS) {
    if (!this.instanceState.canMoveCamera)
      return this;
    const activeArea = this.viewportScreenBounds.clone().expandBy(-32);
    const viewportAspectRatio = activeArea.width / activeArea.height;
    const shapePageBounds = this.getShapePageBounds(shapeId);
    if (!shapePageBounds)
      return this;
    const shapeAspectRatio = shapePageBounds.width / shapePageBounds.height;
    const targetViewportPage = shapePageBounds.clone();
    const z = shapePageBounds.width / activeArea.width;
    targetViewportPage.width += (activeArea.minX + activeArea.maxX) * z;
    targetViewportPage.height += (activeArea.minY + activeArea.maxY) * z;
    targetViewportPage.x -= activeArea.minX * z;
    targetViewportPage.y -= activeArea.minY * z;
    if (shapeAspectRatio > viewportAspectRatio) {
      targetViewportPage.height = shapePageBounds.width / viewportAspectRatio;
      targetViewportPage.y -= (targetViewportPage.height - shapePageBounds.height) / 2;
    } else {
      targetViewportPage.width = shapePageBounds.height * viewportAspectRatio;
      targetViewportPage.x -= (targetViewportPage.width - shapePageBounds.width) / 2;
    }
    return this._animateToViewport(targetViewportPage, opts);
  }
  // Viewport
  /** @internal */
  _willSetInitialBounds = true;
  /**
   * Update the viewport. The viewport will measure the size and screen position of its container
   * element. This should be done whenever the container's position on the screen changes.
   *
   * @example
   * ```ts
   * editor.updateViewportScreenBounds()
   * editor.updateViewportScreenBounds(true)
   * ```
   *
   * @param center - (optional) Whether to preserve the viewport page center as the viewport changes.
   *
   * @public
   */
  updateViewportScreenBounds(center = false) {
    const container = this.getContainer();
    if (!container)
      return this;
    const rect = container.getBoundingClientRect();
    const screenBounds = new Box2d(
      rect.left || rect.x,
      rect.top || rect.y,
      Math.max(rect.width, 1),
      Math.max(rect.height, 1)
    );
    const boundsAreEqual = screenBounds.equals(this.viewportScreenBounds);
    const { _willSetInitialBounds } = this;
    if (boundsAreEqual) {
      this._willSetInitialBounds = false;
    } else {
      if (_willSetInitialBounds) {
        this._willSetInitialBounds = false;
        this.updateInstanceState(
          { screenBounds: screenBounds.toJson() },
          { squashing: true, ephemeral: true }
        );
      } else {
        if (center && !this.instanceState.followingUserId) {
          const before = this.viewportPageCenter;
          this.updateInstanceState(
            { screenBounds: screenBounds.toJson() },
            { squashing: true, ephemeral: true }
          );
          this.centerOnPoint(before);
        } else {
          this.updateInstanceState(
            { screenBounds: screenBounds.toJson() },
            { squashing: true, ephemeral: true }
          );
        }
      }
    }
    this._tickCameraState();
    this.updateRenderingBounds();
    return this;
  }
  get viewportScreenBounds() {
    const { x, y, w, h } = this.instanceState.screenBounds;
    return new Box2d(x, y, w, h);
  }
  get viewportScreenCenter() {
    return this.viewportScreenBounds.center;
  }
  get viewportPageBounds() {
    const { w, h } = this.viewportScreenBounds;
    const { x: cx, y: cy, z: cz } = this.camera;
    return new Box2d(-cx, -cy, w / cz, h / cz);
  }
  get viewportPageCenter() {
    return this.viewportPageBounds.center;
  }
  /**
   * Convert a point in screen space to a point in the current page space.
   *
   * @example
   * ```ts
   * editor.screenToPage({ x: 100, y: 100 })
   * ```
   *
   * @param point - The point in screen space.
   *
   * @public
   */
  screenToPage(point) {
    const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID);
    const { x: cx, y: cy, z: cz = 1 } = this.camera;
    return {
      x: (point.x - screenBounds.x) / cz - cx,
      y: (point.y - screenBounds.y) / cz - cy,
      z: point.z ?? 0.5
    };
  }
  /**
   * Convert a point in the current page space to a point in current screen space.
   *
   * @example
   * ```ts
   * editor.pageToScreen({ x: 100, y: 100 })
   * ```
   *
   * @param point - The point in screen space.
   *
   * @public
   */
  pageToScreen(point) {
    const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID);
    const { x: cx, y: cy, z: cz = 1 } = this.camera;
    return {
      x: (point.x + cx) * cz + screenBounds.x,
      y: (point.y + cy) * cz + screenBounds.y,
      z: point.z ?? 0.5
    };
  }
  // Following
  /**
   * Start viewport-following a user.
   *
   * @param userId - The id of the user to follow.
   *
   * @public
   */
  startFollowingUser(userId) {
    const leaderPresences = this.store.query.records("instance_presence", () => ({
      userId: { eq: userId }
    }));
    const thisUserId = this.user.id;
    if (!thisUserId) {
      console.warn("You should set the userId for the current instance before following a user");
    }
    if (leaderPresences.value.some((p) => p.followingUserId === thisUserId)) {
      return this;
    }
    transact(() => {
      this.stopFollowingUser();
      this.updateInstanceState({ followingUserId: userId }, { ephemeral: true });
    });
    const cancel = () => {
      this.removeListener("frame", moveTowardsUser);
      this.removeListener("stop-following", cancel);
    };
    let isCaughtUp = false;
    const moveTowardsUser = () => {
      const leaderPresence = [...leaderPresences.value].sort((a, b) => {
        return a.lastActivityTimestamp - b.lastActivityTimestamp;
      }).pop();
      if (!leaderPresence) {
        this.stopFollowingUser();
        return;
      }
      const isOnSamePage = leaderPresence.currentPageId === this.currentPageId;
      const chaseProportion = isOnSamePage ? FOLLOW_CHASE_PROPORTION : 1;
      if (!isOnSamePage) {
        this.stopFollowingUser();
        this.setCurrentPage(leaderPresence.currentPageId);
        this.startFollowingUser(userId);
        return;
      }
      const { center, width, height } = this.viewportPageBounds;
      const leaderScreen = Box2d.From(leaderPresence.screenBounds);
      const leaderWidth = leaderScreen.width / leaderPresence.camera.z;
      const leaderHeight = leaderScreen.height / leaderPresence.camera.z;
      const leaderCenter = new Vec2d(
        leaderWidth / 2 - leaderPresence.camera.x,
        leaderHeight / 2 - leaderPresence.camera.y
      );
      const isFollowingFollower = leaderPresence.followingUserId === thisUserId;
      const desiredWidth = width + (leaderWidth - width) * chaseProportion;
      const desiredHeight = height + (leaderHeight - height) * chaseProportion;
      const ratio = !isFollowingFollower ? Math.min(width / desiredWidth, height / desiredHeight) : height / desiredHeight;
      const targetZoom = clamp(this.camera.z * ratio, MIN_ZOOM, MAX_ZOOM);
      const targetWidth = this.viewportScreenBounds.w / targetZoom;
      const targetHeight = this.viewportScreenBounds.h / targetZoom;
      const displacement = leaderCenter.sub(center);
      const targetCenter = Vec2d.Add(center, Vec2d.Mul(displacement, chaseProportion));
      const distance = Vec2d.Sub(targetCenter, center).len();
      const zoomChange = Math.abs(targetZoom - this.camera.z);
      if (distance < FOLLOW_CHASE_PAN_SNAP && zoomChange < FOLLOW_CHASE_ZOOM_SNAP) {
        isCaughtUp = true;
        return;
      }
      if (isCaughtUp && distance < FOLLOW_CHASE_PAN_UNSNAP && zoomChange < FOLLOW_CHASE_ZOOM_UNSNAP) {
        return;
      }
      isCaughtUp = false;
      this.stopCameraAnimation();
      this._setCamera({
        x: -(targetCenter.x - targetWidth / 2),
        y: -(targetCenter.y - targetHeight / 2),
        z: targetZoom
      });
    };
    this.once("stop-following", cancel);
    this.addListener("frame", moveTowardsUser);
    return this;
  }
  /**
   * Stop viewport-following a user.
   *
   * @public
   */
  stopFollowingUser() {
    this.updateInstanceState({ followingUserId: null }, { ephemeral: true });
    this.emit("stop-following");
    return this;
  }
  // Camera state
  _cameraState = atom("camera state", "idle");
  get cameraState() {
    return this._cameraState.value;
  }
  // Camera state does two things: first, it allows us to subscribe to whether
  // the camera is moving or not; and second, it allows us to update the rendering
  // shapes on the canvas. Changing the rendering shapes may cause shapes to
  // unmount / remount in the DOM, which is expensive; and computing visibility is
  // also expensive in large projects. For this reason, we use a second bounding
  // box just for rendering, and we only update after the camera stops moving.
  _cameraStateTimeoutRemaining = 0;
  _lastUpdateRenderingBoundsTimestamp = Date.now();
  _decayCameraStateTimeout = (elapsed) => {
    this._cameraStateTimeoutRemaining -= elapsed;
    if (this._cameraStateTimeoutRemaining <= 0) {
      this.off("tick", this._decayCameraStateTimeout);
      this._cameraState.set("idle");
      this.updateRenderingBounds();
    }
  };
  _tickCameraState = () => {
    this._cameraStateTimeoutRemaining = CAMERA_MOVING_TIMEOUT;
    const now = Date.now();
    if (this._cameraState.__unsafe__getWithoutCapture() === "idle") {
      this._lastUpdateRenderingBoundsTimestamp = now;
      this._cameraState.set("moving");
      this.on("tick", this._decayCameraStateTimeout);
    } else {
      if (now - this._lastUpdateRenderingBoundsTimestamp > CAMERA_MAX_RENDERING_INTERVAL) {
        this.updateRenderingBounds();
      }
    }
  };
  getUnorderedRenderingShapes(useEditorState) {
    const renderingShapes = [];
    let nextIndex = MAX_SHAPES_PER_PAGE * 2;
    let nextBackgroundIndex = MAX_SHAPES_PER_PAGE;
    const editingShapeId = this.editingShapeId;
    const selectedShapeIds = this.selectedShapeIds;
    const erasingShapeIds = this.erasingShapeIds;
    const renderingBoundsExpanded = this.renderingBoundsExpanded;
    const isCullingOffScreenShapes = Number.isFinite(this.renderingBoundsMargin);
    const addShapeById = (id, opacity, isAncestorErasing) => {
      const shape = this.getShape(id);
      if (!shape)
        return;
      opacity *= shape.opacity;
      let isCulled = false;
      let isShapeErasing = false;
      const util = this.getShapeUtil(shape);
      const maskedPageBounds = this.getShapeMaskedPageBounds(id);
      if (useEditorState) {
        isShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id);
        if (isShapeErasing) {
          opacity *= 0.32;
        }
        isCulled = isCullingOffScreenShapes && // only cull shapes that allow unmounting, i.e. not stateful components
        util.canUnmount(shape) && // never cull editingg shapes
        editingShapeId !== id && // if the shape is fully outside of its parent's clipping bounds...
        (maskedPageBounds === void 0 || // ...or if the shape is outside of the expanded viewport bounds...
        !renderingBoundsExpanded.includes(maskedPageBounds) && // ...and if it's not selected... then cull it
        !selectedShapeIds.includes(id));
      }
      renderingShapes.push({
        id,
        shape,
        util,
        index: nextIndex,
        backgroundIndex: nextBackgroundIndex,
        opacity,
        isCulled,
        maskedPageBounds
      });
      nextIndex += 1;
      nextBackgroundIndex += 1;
      const childIds = this.getSortedChildIdsForParent(id);
      if (!childIds.length)
        return;
      let backgroundIndexToRestore = null;
      if (util.providesBackgroundForChildren(shape)) {
        backgroundIndexToRestore = nextBackgroundIndex;
        nextBackgroundIndex = nextIndex;
        nextIndex += MAX_SHAPES_PER_PAGE;
      }
      for (const childId of childIds) {
        addShapeById(childId, opacity, isAncestorErasing || isShapeErasing);
      }
      if (backgroundIndexToRestore !== null) {
        nextBackgroundIndex = backgroundIndexToRestore;
      }
    };
    for (const childId of this.getSortedChildIdsForParent(this.currentPageId)) {
      addShapeById(childId, 1, false);
    }
    return renderingShapes;
  }
  get renderingShapes() {
    const renderingShapes = this.getUnorderedRenderingShapes(true);
    return renderingShapes.sort(sortById);
  }
  get renderingBounds() {
    return this._renderingBounds.value;
  }
  /** @internal */
  _renderingBounds = atom("rendering viewport", new Box2d());
  get renderingBoundsExpanded() {
    return this._renderingBoundsExpanded.value;
  }
  /** @internal */
  _renderingBoundsExpanded = atom("rendering viewport expanded", new Box2d());
  /**
   * Update the rendering bounds. This should be called when the viewport has stopped changing, such
   * as at the end of a pan, zoom, or animation.
   *
   * @example
   * ```ts
   * editor.updateRenderingBounds()
   * ```
   *
   *
   * @internal
   */
  updateRenderingBounds() {
    const { viewportPageBounds } = this;
    if (viewportPageBounds.equals(this._renderingBounds.__unsafe__getWithoutCapture()))
      return this;
    this._renderingBounds.set(viewportPageBounds.clone());
    if (Number.isFinite(this.renderingBoundsMargin)) {
      this._renderingBoundsExpanded.set(
        viewportPageBounds.clone().expandBy(this.renderingBoundsMargin / this.zoomLevel)
      );
    } else {
      this._renderingBoundsExpanded.set(viewportPageBounds);
    }
    return this;
  }
  /**
   * The distance to expand the viewport when measuring culling. A larger distance will
   * mean that shapes near to the viewport (but still outside of it) will not be culled.
   *
   * @public
   */
  renderingBoundsMargin = 100;
  get _pages() {
    return this.store.query.records("page");
  }
  get pages() {
    return this._pages.value.sort(sortByIndex2);
  }
  /**
   * The current page.
   *
   * @public
   */
  get currentPage() {
    const page = this.getPage(this.currentPageId);
    return page;
  }
  /**
   * The current page id.
   *
   * @public
   */
  get currentPageId() {
    return this.instanceState.currentPageId;
  }
  /**
   * Get a page.
   *
   * @example
   * ```ts
   * editor.getPage(myPage.id)
   * editor.getPage(myPage)
   * ```
   *
   * @param page - The page (or page id) to get.
   *
   * @public
   */
  getPage(page) {
    return this.store.get(typeof page === "string" ? page : page.id);
  }
  /* @internal */
  _currentPageShapeIds;
  /**
   * An array of all of the shapes on the current page.
   *
   * @public
   */
  get currentPageShapeIds() {
    return this._currentPageShapeIds.value;
  }
  /**
   * Get the ids of shapes on a page.
   *
   * @example
   * ```ts
   * const idsOnPage1 = editor.getCurrentPageShapeIds('page1')
   * const idsOnPage2 = editor.getCurrentPageShapeIds(myPage2)
   * ```
   *
   * @param page - The page (or page id) to get.
   *
   * @public
   **/
  getPageShapeIds(page) {
    const pageId = typeof page === "string" ? page : page.id;
    const result = this.store.query.exec("shape", { parentId: { eq: pageId } });
    return this.getShapeAndDescendantIds(result.map((s) => s.id));
  }
  /**
   * Set the current page.
   *
   * @example
   * ```ts
   * editor.setCurrentPage('page1')
   * editor.setCurrentPage(myPage1)
   * ```
   *
   * @param page - The page (or page id) to set as the current page.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  setCurrentPage(page, historyOptions) {
    const pageId = typeof page === "string" ? page : page.id;
    this._setCurrentPageId(pageId, historyOptions);
    return this;
  }
  /** @internal */
  _setCurrentPageId = this.history.createCommand(
    "setCurrentPage",
    (pageId, historyOptions) => {
      if (!this.store.has(pageId)) {
        console.error("Tried to set the current page id to a page that doesn't exist.");
        return;
      }
      this.stopFollowingUser();
      return {
        data: { toId: pageId, fromId: this.currentPageId },
        squashing: true,
        preservesRedoStack: true,
        ...historyOptions
      };
    },
    {
      do: ({ toId }) => {
        if (!this.store.has(toId)) {
          return;
        }
        if (!this.pageStates.find((p) => p.pageId === toId)) {
          const camera = CameraRecordType.create({
            id: CameraRecordType.createId(toId)
          });
          this.store.put([
            camera,
            InstancePageStateRecordType.create({
              id: InstancePageStateRecordType.createId(toId),
              pageId: toId
            })
          ]);
        }
        this.store.put([{ ...this.instanceState, currentPageId: toId }]);
        this.updateRenderingBounds();
      },
      undo: ({ fromId }) => {
        if (!this.store.has(fromId)) {
          return;
        }
        this.store.put([{ ...this.instanceState, currentPageId: fromId }]);
        this.updateRenderingBounds();
      },
      squash: ({ fromId }, { toId }) => {
        return { toId, fromId };
      }
    }
  );
  /**
   * Update a page.
   *
   * @example
   * ```ts
   * editor.updatePage({ id: 'page2', name: 'Page 2' })
   * editor.updatePage({ id: 'page2', name: 'Page 2' }, { squashing: true })
   * ```
   *
   * @param partial - The partial of the shape to update.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  updatePage(partial, historyOptions) {
    this._updatePage(partial, historyOptions);
    return this;
  }
  /** @internal */
  _updatePage = this.history.createCommand(
    "updatePage",
    (partial, historyOptions) => {
      if (this.instanceState.isReadonly)
        return null;
      const prev = this.getPage(partial.id);
      if (!prev)
        return null;
      return { data: { prev, partial }, ...historyOptions };
    },
    {
      do: ({ partial }) => {
        this.store.update(partial.id, (page) => ({ ...page, ...partial }));
      },
      undo: ({ prev, partial }) => {
        this.store.update(partial.id, () => prev);
      },
      squash(prevData, nextData) {
        return {
          prev: { ...prevData.prev, ...nextData.prev },
          partial: nextData.partial
        };
      }
    }
  );
  /**
   * Create a page.
   *
   * @example
   * ```ts
   * editor.createPage(myPage)
   * editor.createPage({ name: 'Page 2' })
   * ```
   *
   * @param page - The page (or page partial) to create.
   *
   * @public
   */
  createPage(page) {
    this._createPage(page);
    return this;
  }
  /** @internal */
  _createPage = this.history.createCommand(
    "createPage",
    (page) => {
      if (this.instanceState.isReadonly)
        return null;
      if (this.pages.length >= MAX_PAGES)
        return null;
      const { pages } = this;
      const name = getIncrementedName(
        page.name ?? "Page",
        pages.map((p) => p.name)
      );
      let index2 = page.index;
      if (!index2 || pages.some((p) => p.index === index2)) {
        index2 = getIndexAbove(pages[pages.length - 1].index);
      }
      const newPage = PageRecordType.create({
        meta: {},
        ...page,
        name,
        index: index2
      });
      const newCamera = CameraRecordType.create({
        id: CameraRecordType.createId(newPage.id)
      });
      const newTabPageState = InstancePageStateRecordType.create({
        id: InstancePageStateRecordType.createId(newPage.id),
        pageId: newPage.id
      });
      return {
        data: {
          newPage,
          newTabPageState,
          newCamera
        }
      };
    },
    {
      do: ({ newPage, newTabPageState, newCamera }) => {
        this.store.put([newPage, newCamera, newTabPageState]);
      },
      undo: ({ newPage, newTabPageState, newCamera }) => {
        if (this.pages.length === 1)
          return;
        this.store.remove([newTabPageState.id, newPage.id, newCamera.id]);
      }
    }
  );
  /**
   * Delete a page.
   *
   * @example
   * ```ts
   * editor.deletePage('page1')
   * ```
   *
   * @param id - The id of the page to delete.
   *
   * @public
   */
  deletePage(page) {
    const id = typeof page === "string" ? page : page.id;
    this._deletePage(id);
    return this;
  }
  /** @internal */
  _deletePage = this.history.createCommand(
    "delete_page",
    (id) => {
      if (this.instanceState.isReadonly)
        return null;
      const { pages } = this;
      if (pages.length === 1)
        return null;
      const deletedPage = this.getPage(id);
      const deletedPageStates = this.pageStates.filter((s) => s.pageId === id);
      if (!deletedPage)
        return null;
      if (id === this.currentPageId) {
        const index2 = pages.findIndex((page) => page.id === id);
        const next = pages[index2 - 1] ?? pages[index2 + 1];
        this.setCurrentPage(next.id);
      }
      return { data: { id, deletedPage, deletedPageStates } };
    },
    {
      do: ({ deletedPage, deletedPageStates }) => {
        const { pages } = this;
        if (pages.length === 1)
          return;
        if (deletedPage.id === this.currentPageId) {
          const index2 = pages.findIndex((page) => page.id === deletedPage.id);
          const next = pages[index2 - 1] ?? pages[index2 + 1];
          this.setCurrentPage(next.id);
        }
        this.store.remove(deletedPageStates.map((s) => s.id));
        this.store.remove([deletedPage.id]);
        this.updateRenderingBounds();
      },
      undo: ({ deletedPage, deletedPageStates }) => {
        this.store.put([deletedPage]);
        this.store.put(deletedPageStates);
        this.updateRenderingBounds();
      }
    }
  );
  /**
   * Duplicate a page.
   *
   * @param id - The id of the page to duplicate. Defaults to the current page.
   * @param createId - The id of the new page. Defaults to a new id.
   *
   * @public
   */
  duplicatePage(page, createId = PageRecordType.createId()) {
    if (this.pages.length >= MAX_PAGES)
      return this;
    const id = typeof page === "string" ? page : page.id;
    const freshPage = this.getPage(id);
    if (!freshPage)
      return this;
    const prevCamera = { ...this.camera };
    const content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id));
    this.batch(() => {
      const { pages } = this;
      const index2 = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index);
      this.createPage({ name: freshPage.name + " Copy", id: createId, index: index2 });
      this.setCurrentPage(createId);
      this.setCamera(prevCamera);
      if (content) {
        return this.putContentOntoCurrentPage(content);
      }
    });
    return this;
  }
  /**
   * Rename a page.
   *
   * @example
   * ```ts
   * editor.renamePage('page1', 'My Page')
   * ```
   *
   * @param id - The id of the page to rename.
   * @param name - The new name.
   *
   * @public
   */
  renamePage(page, name, historyOptions) {
    const id = typeof page === "string" ? page : page.id;
    if (this.instanceState.isReadonly)
      return this;
    this.updatePage({ id, name }, historyOptions);
    return this;
  }
  get _assets() {
    return this.store.query.records("asset");
  }
  /**
   * Get all assets in the editor.
   *
   * @public
   */
  get assets() {
    return this._assets.value;
  }
  /**
   * Create one or more assets.
   *
   * @example
   * ```ts
   * editor.createAssets([...myAssets])
   * ```
   *
   * @param assets - The assets to create.
   *
   * @public
   */
  createAssets(assets) {
    this._createAssets(assets);
    return this;
  }
  /** @internal */
  _createAssets = this.history.createCommand(
    "createAssets",
    (assets) => {
      if (this.instanceState.isReadonly)
        return null;
      if (assets.length <= 0)
        return null;
      return { data: { assets } };
    },
    {
      do: ({ assets }) => {
        this.store.put(assets);
      },
      undo: ({ assets }) => {
        this.store.remove(assets.map((a) => a.id));
      }
    }
  );
  /**
   * Update one or more assets.
   *
   * @example
   * ```ts
   * editor.updateAssets([{ id: 'asset1', name: 'New name' }])
   * ```
   *
   * @param assets - The assets to update.
   *
   * @public
   */
  updateAssets(assets) {
    this._updateAssets(assets);
    return this;
  }
  /** @internal */
  _updateAssets = this.history.createCommand(
    "updateAssets",
    (assets) => {
      if (this.instanceState.isReadonly)
        return;
      if (assets.length <= 0)
        return;
      const snapshots = {};
      return { data: { snapshots, assets } };
    },
    {
      do: ({ assets, snapshots }) => {
        this.store.put(
          assets.map((a) => {
            const asset = this.store.get(a.id);
            snapshots[a.id] = asset;
            return {
              ...asset,
              ...a
            };
          })
        );
      },
      undo: ({ snapshots }) => {
        this.store.put(Object.values(snapshots));
      }
    }
  );
  /**
   * Delete one or more assets.
   *
   * @example
   * ```ts
   * editor.deleteAssets(['asset1', 'asset2'])
   * ```
   *
   * @param ids - The assets to delete.
   *
   * @public
   */
  deleteAssets(assets) {
    const ids = typeof assets[0] === "string" ? assets : assets.map((a) => a.id);
    this._deleteAssets(ids);
    return this;
  }
  /** @internal */
  _deleteAssets = this.history.createCommand(
    "deleteAssets",
    (ids) => {
      if (this.instanceState.isReadonly)
        return;
      if (ids.length <= 0)
        return;
      const prev = compact(ids.map((id) => this.store.get(id)));
      return { data: { ids, prev } };
    },
    {
      do: ({ ids }) => {
        this.store.remove(ids);
      },
      undo: ({ prev }) => {
        this.store.put(prev);
      }
    }
  );
  /**
   * Get an asset by its id.
   *
   * @example
   * ```ts
   * editor.getAsset('asset1')
   * ```
   *
   * @param asset - The asset (or asset id) to get.
   *
   * @public
   */
  getAsset(asset) {
    return this.store.get(typeof asset === "string" ? asset : asset.id);
  }
  get _shapeGeometryCache() {
    return this.store.createComputedCache(
      "bounds",
      (shape) => this.getShapeUtil(shape).getGeometry(shape),
      (a, b) => a.props === b.props
    );
  }
  /**
   * Get the geometry of a shape.
   *
   * @example
   * ```ts
   * editor.getShapeGeometry(myShape)
   * editor.getShapeGeometry(myShapeId)
   * ```
   *
   * @param shape - The shape (or shape id) to get the geometry for.
   *
   * @public
   */
  getShapeGeometry(shape) {
    return this._shapeGeometryCache.get(typeof shape === "string" ? shape : shape.id);
  }
  get _shapeOutlineSegmentsCache() {
    return this.store.createComputedCache("outline-segments", (shape) => {
      return this.getShapeUtil(shape).getOutlineSegments(shape);
    });
  }
  /**
   * Get the local outline segments of a shape.
   *
   * @example
   * ```ts
   * editor.getShapeOutlineSegments(myShape)
   * editor.getShapeOutlineSegments(myShapeId)
   * ```
   *
   * @param shape - The shape (or shape id) to get the outline segments for.
   *
   * @public
   */
  getShapeOutlineSegments(shape) {
    return this._shapeOutlineSegmentsCache.get(typeof shape === "string" ? shape : shape.id) ?? EMPTY_ARRAY;
  }
  get _shapeHandlesCache() {
    return this.store.createComputedCache("handles", (shape) => {
      return this.getShapeUtil(shape).getHandles?.(shape);
    });
  }
  /**
   * Get the handles (if any) for a shape.
   *
   * @example
   * ```ts
   * editor.getShapeHandles(myShape)
   * editor.getShapeHandles(myShapeId)
   * ```
   *
   * @param shape - The shape (or shape id) to get the handles for.
   * @public
   */
  getShapeHandles(shape) {
    return this._shapeHandlesCache.get(typeof shape === "string" ? shape : shape.id);
  }
  /**
   * Get the local transform for a shape as a matrix model. This transform reflects both its
   * translation (x, y) from from either its parent's top left corner, if the shape's parent is
   * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the
   * shape's rotation.
   *
   * @example
   * ```ts
   * editor.getShapeLocalTransform(myShape)
   * ```
   *
   * @param shape - The shape to get the local transform for.
   *
   * @public
   */
  getShapeLocalTransform(shape) {
    const id = typeof shape === "string" ? shape : shape.id;
    const freshShape = this.getShape(id);
    if (!freshShape)
      throw Error("Editor.getTransform: shape not found");
    return Matrix2d.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation);
  }
  get _shapePageTransformCache() {
    return this.store.createComputedCache("pageTransformCache", (shape) => {
      if (isPageId(shape.parentId)) {
        return this.getShapeLocalTransform(shape);
      }
      const parentTransform = this._shapePageTransformCache.get(shape.parentId) ?? Matrix2d.Identity();
      return Matrix2d.Compose(parentTransform, this.getShapeLocalTransform(shape));
    });
  }
  /**
   * Get the local transform of a shape's parent as a matrix model.
   *
   * @example
   * ```ts
   * editor.getShapeParentTransform(myShape)
   * ```
   *
   * @param shape - The shape (or shape id) to get the parent transform for.
   *
   * @public
   */
  getShapeParentTransform(shape) {
    const id = typeof shape === "string" ? shape : shape.id;
    const freshShape = this.getShape(id);
    if (!freshShape || isPageId(freshShape.parentId))
      return Matrix2d.Identity();
    return this._shapePageTransformCache.get(freshShape.parentId) ?? Matrix2d.Identity();
  }
  /**
   * Get the transform of a shape in the current page space.
   *
   * @example
   * ```ts
   * editor.getShapePageTransform(myShape)
   * editor.getShapePageTransform(myShapeId)
   * ```
   *
   * @param shape - The shape (or shape id) to get the page transform for.
   *
   * @public
   */
  getShapePageTransform(shape) {
    const id = typeof shape === "string" ? shape : this.getShape(shape).id;
    return this._shapePageTransformCache.get(id) ?? Matrix2d.Identity();
  }
  get _shapePageBoundsCache() {
    return this.store.createComputedCache("pageBoundsCache", (shape) => {
      const pageTransform = this._shapePageTransformCache.get(shape.id);
      if (!pageTransform)
        return new Box2d();
      const result = Box2d.FromPoints(
        Matrix2d.applyToPoints(pageTransform, this.getShapeGeometry(shape).vertices)
      );
      return result;
    });
  }
  /**
   * Get the bounds of a shape in the current page space.
   *
   * @example
   * ```ts
   * editor.getShapePageBounds(myShape)
   * editor.getShapePageBounds(myShapeId)
   * ```
   *
   * @param shape - The shape (or shape id) to get the bounds for.
   *
   * @public
   */
  getShapePageBounds(shape) {
    return this._shapePageBoundsCache.get(typeof shape === "string" ? shape : shape.id);
  }
  get _shapeClipPathCache() {
    return this.store.createComputedCache("clipPathCache", (shape) => {
      const pageMask = this._shapeMaskCache.get(shape.id);
      if (!pageMask)
        return void 0;
      const pageTransform = this._shapePageTransformCache.get(shape.id);
      if (!pageTransform)
        return void 0;
      if (pageMask.length === 0) {
        return `polygon(0px 0px, 0px 0px, 0px 0px)`;
      }
      const localMask = Matrix2d.applyToPoints(Matrix2d.Inverse(pageTransform), pageMask);
      return `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(",")})`;
    });
  }
  /**
   * Get the clip path for a shape.
   *
   * @example
   * ```ts
   * const clipPath = editor.getShapeClipPath(shape)
   * const clipPath = editor.getShapeClipPath(shape.id)
   * ```
   *
   * @param shape - The shape (or shape id) to get the clip path for.
   *
   * @returns The clip path or undefined.
   *
   * @public
   */
  getShapeClipPath(shape) {
    return this._shapeClipPathCache.get(typeof shape === "string" ? shape : shape.id);
  }
  get _shapeMaskCache() {
    return this.store.createComputedCache("pageMaskCache", (shape) => {
      if (isPageId(shape.parentId)) {
        return void 0;
      }
      const frameAncestors = this.getShapeAncestors(shape.id).filter(
        (shape2) => this.isShapeOfType(shape2, "frame")
      );
      if (frameAncestors.length === 0)
        return void 0;
      const pageMask = frameAncestors.map(
        (s) => (
          // Apply the frame transform to the frame outline to get the frame outline in the current page space
          this._shapePageTransformCache.get(s.id).applyToPoints(this.getShapeGeometry(s).vertices)
        )
      ).reduce((acc, b) => {
        if (!(b && acc))
          return void 0;
        const intersection = intersectPolygonPolygon(acc, b);
        if (intersection) {
          return intersection.map(Vec2d.Cast);
        }
        return [];
      });
      return pageMask;
    });
  }
  /**
   * Get the mask (in the current page space) for a shape.
   *
   * @example
   * ```ts
   * const pageMask = editor.getShapeMask(shape.id)
   * ```
   *
   * @param id - The id of the shape to get the mask for.
   *
   * @returns The mask for the shape.
   *
   * @public
   */
  getShapeMask(shape) {
    return this._shapeMaskCache.get(typeof shape === "string" ? shape : shape.id);
  }
  /**
   * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the
   * shape were the child of a frame and was half way out of the frame, the bounds would be the half
   * of the shape that was in the frame.
   *
   * @example
   * ```ts
   * editor.getShapeMaskedPageBounds(myShape)
   * editor.getShapeMaskedPageBounds(myShapeId)
   * ```
   *
   * @param shape - The shape to get the masked bounds for.
   *
   * @public
   */
  getShapeMaskedPageBounds(shape) {
    if (typeof shape !== "string")
      shape = shape.id;
    const pageBounds = this._shapePageBoundsCache.get(shape);
    if (!pageBounds)
      return;
    const pageMask = this._shapeMaskCache.get(shape);
    if (pageMask) {
      const intersection = intersectPolygonPolygon(pageMask, pageBounds.corners);
      if (!intersection)
        return;
      return Box2d.FromPoints(intersection);
    }
    return pageBounds;
  }
  /**
   * Get the ancestors of a shape.
   *
   * @example
   * ```ts
   * const ancestors = editor.getShapeAncestors(myShape)
   * const ancestors = editor.getShapeAncestors(myShapeId)
   * ```
   *
   * @param shape - The shape (or shape id) to get the ancestors for.
   *
   * @public
   */
  getShapeAncestors(shape, acc = []) {
    const id = typeof shape === "string" ? shape : shape.id;
    const freshShape = this.getShape(id);
    if (!freshShape)
      return acc;
    const parentId = freshShape.parentId;
    if (isPageId(parentId)) {
      acc.reverse();
      return acc;
    }
    const parent = this.store.get(parentId);
    if (!parent)
      return acc;
    acc.push(parent);
    return this.getShapeAncestors(parent, acc);
  }
  /**
   * Find the first ancestor matching the given predicate
   *
   * @example
   * ```ts
   * const ancestor = editor.findShapeAncestor(myShape)
   * const ancestor = editor.findShapeAncestor(myShape.id)
   * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')
   * ```
   *
   * @param shape - The shape to check the ancestors for.
   *
   * @public
   */
  findShapeAncestor(shape, predicate) {
    const id = typeof shape === "string" ? shape : shape.id;
    const freshShape = this.getShape(id);
    if (!freshShape)
      return;
    const parentId = freshShape.parentId;
    if (isPageId(parentId))
      return;
    const parent = this.getShape(parentId);
    if (!parent)
      return;
    return predicate(parent) ? parent : this.findShapeAncestor(parent, predicate);
  }
  /**
   * Returns true if the the given shape has the given ancestor.
   *
   * @param shape - The shape.
   * @param ancestorId - The id of the ancestor.
   *
   * @public
   */
  hasAncestor(shape, ancestorId) {
    const id = typeof shape === "string" ? shape : shape?.id;
    const freshShape = id && this.getShape(id);
    if (!freshShape)
      return false;
    if (freshShape.parentId === ancestorId)
      return true;
    return this.hasAncestor(this.getShapeParent(freshShape), ancestorId);
  }
  /**
   * Get the common ancestor of two or more shapes that matches a predicate.
   *
   * @param shapes - The shapes (or shape ids) to check.
   * @param predicate - The predicate to match.
   */
  findCommonAncestor(shapes, predicate) {
    if (shapes.length === 0) {
      return;
    }
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    const freshShapes = compact(ids.map((id) => this.getShape(id)));
    if (freshShapes.length === 1) {
      const parentId = freshShapes[0].parentId;
      if (isPageId(parentId)) {
        return;
      }
      return predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId;
    }
    const [nodeA, ...others] = freshShapes;
    let ancestor = this.getShapeParent(nodeA);
    while (ancestor) {
      if (predicate && !predicate(ancestor)) {
        ancestor = this.getShapeParent(ancestor);
        continue;
      }
      if (others.every((shape) => this.hasAncestor(shape, ancestor.id))) {
        return ancestor.id;
      }
      ancestor = this.getShapeParent(ancestor);
    }
    return void 0;
  }
  isShapeOrAncestorLocked(arg) {
    const shape = typeof arg === "string" ? this.getShape(arg) : arg;
    if (shape === void 0)
      return false;
    if (shape.isLocked)
      return true;
    return this.isShapeOrAncestorLocked(this.getShapeParent(shape));
  }
  get currentPageBounds() {
    let commonBounds;
    this.currentPageShapeIds.forEach((shapeId) => {
      const bounds = this.getShapeMaskedPageBounds(shapeId);
      if (!bounds)
        return;
      if (!commonBounds) {
        commonBounds = bounds.clone();
      } else {
        commonBounds = commonBounds.expand(bounds);
      }
    });
    return commonBounds;
  }
  /**
   * Get the top-most selected shape at the given point, ignoring groups.
   *
   * @param point - The point to check.
   *
   * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.
   */
  getSelectedShapeAtPoint(point) {
    const { selectedShapeIds } = this;
    return this.currentPageShapesSorted.filter((shape) => shape.type !== "group" && selectedShapeIds.includes(shape.id)).reverse().find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }));
  }
  /**
   * Get the shape at the current point.
   *
   * @param point - The point to check.
   * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.
   *
   * @returns The shape at the given point, or undefined if there is no shape at the point.
   */
  getShapeAtPoint(point, opts = {}) {
    const { viewportPageBounds, zoomLevel } = this;
    const {
      filter: filter2,
      margin = 0,
      hitLabels = false,
      hitInside = false,
      hitFrameInside = false
    } = opts;
    let inHollowSmallestArea = Infinity;
    let inHollowSmallestAreaHit = null;
    let inMarginClosestToEdgeDistance = Infinity;
    let inMarginClosestToEdgeHit = null;
    const shapesToCheck = (opts.renderingOnly ? this.currentPageRenderingShapesSorted : this.currentPageShapesSorted).filter((shape) => {
      if (this.isShapeOfType(shape, "group"))
        return false;
      const pageMask = this.getShapeMask(shape);
      if (pageMask && !pointInPolygon(point, pageMask))
        return false;
      if (filter2)
        return filter2(shape);
      return true;
    });
    for (let i = shapesToCheck.length - 1; i >= 0; i--) {
      const shape = shapesToCheck[i];
      const geometry = this.getShapeGeometry(shape);
      const isGroup = geometry instanceof Group2d;
      const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
      if (this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") {
        if (shape.props.text.trim()) {
          for (const childGeometry of geometry.children) {
            if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
              return shape;
            }
          }
        }
      }
      if (this.isShapeOfType(shape, "frame")) {
        const distance2 = geometry.distanceToPoint(pointInShapeSpace, hitInside);
        if (Math.abs(distance2) <= margin) {
          return inMarginClosestToEdgeHit || shape;
        }
        if (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {
          return inMarginClosestToEdgeHit || inHollowSmallestAreaHit || (hitFrameInside ? shape : void 0);
        }
        continue;
      }
      let distance;
      if (isGroup) {
        let minDistance = Infinity;
        for (const childGeometry of geometry.children) {
          if (childGeometry.isLabel && !hitLabels)
            continue;
          const tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside);
          if (tDistance < minDistance) {
            minDistance = tDistance;
          }
        }
        distance = minDistance;
      } else {
        if (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {
          distance = geometry.distanceToPoint(pointInShapeSpace, hitInside);
        } else {
          if (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {
            distance = geometry.distanceToPoint(pointInShapeSpace, hitInside);
          } else {
            distance = Infinity;
          }
        }
      }
      if (geometry.isClosed) {
        if (distance <= margin) {
          if (geometry.isFilled || isGroup && geometry.children[0].isFilled) {
            return inMarginClosestToEdgeHit || shape;
          } else {
            if (this.getShapePageBounds(shape).contains(viewportPageBounds))
              continue;
            if (Math.abs(distance) < margin) {
              if (Math.abs(distance) < inMarginClosestToEdgeDistance) {
                inMarginClosestToEdgeDistance = Math.abs(distance);
                inMarginClosestToEdgeHit = shape;
              }
            } else if (!inMarginClosestToEdgeHit) {
              const { area } = geometry;
              if (area < inHollowSmallestArea) {
                inHollowSmallestArea = area;
                inHollowSmallestAreaHit = shape;
              }
            }
          }
        }
      } else {
        if (distance < HIT_TEST_MARGIN / zoomLevel) {
          return shape;
        }
      }
    }
    return inMarginClosestToEdgeHit || inHollowSmallestAreaHit || void 0;
  }
  /**
   * Get the shapes, if any, at a given page point.
   *
   * @example
   * ```ts
   * editor.getShapesAtPoint({ x: 100, y: 100 })
   * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true })
   * ```
   *
   * @param point - The page point to test.
   *
   * @public
   */
  getShapesAtPoint(point, opts = {}) {
    return this.currentPageShapes.filter((shape) => this.isPointInShape(shape, point, opts));
  }
  /**
   * Test whether a point (in the current page space) will will a shape. This method takes into account masks,
   * such as when a shape is the child of a frame and is partially clipped by the frame.
   *
   * @example
   * ```ts
   * editor.isPointInShape({ x: 100, y: 100 }, myShape)
   * ```
   *
   * @param shape - The shape to test against.
   * @param point - The page point to test (in the current page space).
   * @param hitInside - Whether to count as a hit if the point is inside of a closed shape.
   *
   * @public
   */
  isPointInShape(shape, point, opts = {}) {
    const { hitInside = false, margin = 0 } = opts;
    const id = typeof shape === "string" ? shape : shape.id;
    const pageMask = this.getShapeMask(id);
    if (pageMask && !pointInPolygon(point, pageMask))
      return false;
    return this.getShapeGeometry(id).hitTestPoint(
      this.getPointInShapeSpace(shape, point),
      margin,
      hitInside
    );
  }
  /**
   * Convert a point in the current page space to a point in the local space of a shape. For example, if a
   * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at
   * `{ x: 10, y: 10 }` in the shape's local space.
   *
   * @example
   * ```ts
   * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })
   * ```
   *
   * @param shape - The shape to get the point in the local space of.
   * @param point - The page point to get in the local space of the shape.
   *
   * @public
   */
  getPointInShapeSpace(shape, point) {
    const id = typeof shape === "string" ? shape : shape.id;
    return this._shapePageTransformCache.get(id).clone().invert().applyToPoint(point);
  }
  /**
   * Convert a delta in the current page space to a point in the local space of a shape's parent.
   *
   * @example
   * ```ts
   * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })
   * ```
   *
   * @param shape - The shape to get the point in the local space of.
   * @param point - The page point to get in the local space of the shape.
   *
   * @public
   */
  getPointInParentSpace(shape, point) {
    const id = typeof shape === "string" ? shape : shape.id;
    const freshShape = this.getShape(id);
    if (!freshShape)
      return new Vec2d(0, 0);
    if (isPageId(freshShape.parentId))
      return Vec2d.From(point);
    const parentTransform = this.getShapePageTransform(freshShape.parentId);
    if (!parentTransform)
      return Vec2d.From(point);
    return parentTransform.clone().invert().applyToPoint(point);
  }
  get currentPageShapes() {
    return Array.from(this.currentPageShapeIds, (id) => this.store.get(id));
  }
  get currentPageShapesSorted() {
    const shapes = new Set(this.currentPageShapes.sort(sortByIndex2));
    const results = [];
    function pushShapeWithDescendants(shape) {
      results.push(shape);
      shapes.delete(shape);
      shapes.forEach((otherShape) => {
        if (otherShape.parentId === shape.id) {
          pushShapeWithDescendants(otherShape);
        }
      });
    }
    shapes.forEach((shape) => {
      const parent = this.getShape(shape.parentId);
      if (!isShape(parent)) {
        pushShapeWithDescendants(shape);
      }
    });
    return results;
  }
  get currentPageRenderingShapesSorted() {
    return this.renderingShapes.filter(({ isCulled }) => !isCulled).sort((a, b) => a.index - b.index).map(({ shape }) => shape);
  }
  isShapeOfType(arg, type) {
    const shape = typeof arg === "string" ? this.getShape(arg) : arg;
    return shape.type === type;
  }
  /**
   * Get a shape by its id.
   *
   * @example
   * ```ts
   * editor.getShape('box1')
   * ```
   *
   * @param id - The id of the shape to get.
   *
   * @public
   */
  getShape(shape) {
    const id = typeof shape === "string" ? shape : shape.id;
    if (!isShapeId(id))
      return void 0;
    return this.store.get(id);
  }
  /**
   * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of
   * the page.
   *
   * @example
   * ```ts
   * editor.getShapeParent(myShape)
   * ```
   *
   * @public
   */
  getShapeParent(shape) {
    const id = typeof shape === "string" ? shape : shape?.id;
    if (!id)
      return void 0;
    const freshShape = this.getShape(id);
    if (freshShape === void 0 || !isShapeId(freshShape.parentId))
      return void 0;
    return this.store.get(freshShape.parentId);
  }
  /**
   * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an
   * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns
   * undefined.
   *
   * @internal
   */
  getShapeNearestSibling(siblingShape, targetShape) {
    if (!targetShape) {
      return void 0;
    }
    if (targetShape.parentId === siblingShape.parentId) {
      return targetShape;
    }
    const ancestor = this.findShapeAncestor(
      targetShape,
      (ancestor2) => ancestor2.parentId === siblingShape.parentId
    );
    return ancestor;
  }
  /**
   * Get whether the given shape is the descendant of the given page.
   *
   * @example
   * ```ts
   * editor.isShapeInPage(myShape)
   * editor.isShapeInPage(myShape, 'page1')
   * ```
   *
   * @param shape - The shape to check.
   * @param pageId - The id of the page to check against. Defaults to the current page.
   *
   * @public
   */
  isShapeInPage(shape, pageId = this.currentPageId) {
    const id = typeof shape === "string" ? shape : shape.id;
    const shapeToCheck = this.getShape(id);
    if (!shapeToCheck)
      return false;
    let shapeIsInPage = false;
    if (shapeToCheck.parentId === pageId) {
      shapeIsInPage = true;
    } else {
      let parent = this.getShape(shapeToCheck.parentId);
      isInPageSearch:
        while (parent) {
          if (parent.parentId === pageId) {
            shapeIsInPage = true;
            break isInPageSearch;
          }
          parent = this.getShape(parent.parentId);
        }
    }
    return shapeIsInPage;
  }
  /**
   * Get the id of the containing page for a given shape.
   *
   * @param shape - The shape to get the page id for.
   *
   * @returns The id of the page that contains the shape, or undefined if the shape is undefined.
   *
   * @public
   */
  getAncestorPageId(shape) {
    const id = typeof shape === "string" ? shape : shape?.id;
    const _shape = id && this.getShape(id);
    if (!_shape)
      return void 0;
    if (isPageId(_shape.parentId)) {
      return _shape.parentId;
    } else {
      return this.getAncestorPageId(this.getShape(_shape.parentId));
    }
  }
  // Parents and children
  /**
   * A cache of parents to children.
   *
   * @internal
   */
  _parentIdsToChildIds;
  /**
   * Reparent shapes to a new parent. This operation preserves the shape's current page positions /
   * rotations.
   *
   * @example
   * ```ts
   * editor.reparentShapes([box1, box2], 'frame1')
   * editor.reparentShapes([box1.id, box2.id], 'frame1')
   * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)
   * ```
   *
   * @param shapes - The shapes (or shape ids) of the shapes to reparent.
   * @param parentId - The id of the new parent shape.
   * @param insertIndex - (optional) The index to insert the children.
   *
   * @public
   */
  reparentShapes(shapes, parentId, insertIndex) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    const changes = [];
    const parentTransform = isPageId(parentId) ? Matrix2d.Identity() : this.getShapePageTransform(parentId);
    const parentPageRotation = parentTransform.rotation();
    let indices = [];
    const sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)));
    if (insertIndex) {
      const sibWithInsertIndex = sibs.find((s) => s.index === insertIndex);
      if (sibWithInsertIndex) {
        const sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1];
        if (sibAbove) {
          indices = getIndicesBetween(insertIndex, sibAbove.index, ids.length);
        } else {
          indices = getIndicesAbove(insertIndex, ids.length);
        }
      } else {
        const sibAbove = sibs.sort(sortByIndex2).find((s) => s.index > insertIndex);
        if (sibAbove) {
          indices = getIndicesBetween(insertIndex, sibAbove.index, ids.length);
        } else {
          indices = getIndicesAbove(insertIndex, ids.length);
        }
      }
    } else {
      const sib = sibs.length && sibs[sibs.length - 1];
      indices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length);
    }
    const invertedParentTransform = parentTransform.clone().invert();
    const shapesToReparent = compact(ids.map((id) => this.getShape(id)));
    const lockedShapes = shapesToReparent.filter((shape) => shape.isLocked);
    if (lockedShapes.length) {
      this.updateShapes(lockedShapes.map(({ id, type }) => ({ id, type, isLocked: false })));
    }
    for (let i = 0; i < shapesToReparent.length; i++) {
      const shape = shapesToReparent[i];
      const pageTransform = this.getShapePageTransform(shape);
      if (!pageTransform)
        continue;
      const pagePoint = pageTransform.point();
      if (!pagePoint)
        continue;
      const newPoint = invertedParentTransform.applyToPoint(pagePoint);
      const newRotation = pageTransform.rotation() - parentPageRotation;
      changes.push({
        id: shape.id,
        type: shape.type,
        parentId,
        x: newPoint.x,
        y: newPoint.y,
        rotation: newRotation,
        index: indices[i],
        isLocked: shape.isLocked
        // this will re-lock locked shapes
      });
    }
    this.updateShapes(changes);
    return this;
  }
  /**
   * Get the index above the highest child of a given parent.
   *
   * @param parentId - The id of the parent.
   *
   * @returns The index.
   *
   * @public
   */
  getHighestIndexForParent(parent) {
    const parentId = typeof parent === "string" ? parent : parent.id;
    const children = this._parentIdsToChildIds.value[parentId];
    if (!children || children.length === 0) {
      return "a1";
    }
    const shape = this.getShape(children[children.length - 1]);
    return getIndexAbove(shape.index);
  }
  /**
   * A cache of children for each parent.
   *
   * @internal
   */
  _childIdsCache = new WeakMapCache();
  /**
   * Get an array of all the children of a shape.
   *
   * @example
   * ```ts
   * editor.getSortedChildIdsForParent('frame1')
   * ```
   *
   * @param parentId - The id of the parent shape.
   *
   * @public
   */
  getSortedChildIdsForParent(parent) {
    const parentId = typeof parent === "string" ? parent : parent.id;
    const ids = this._parentIdsToChildIds.value[parentId];
    if (!ids)
      return EMPTY_ARRAY;
    return this._childIdsCache.get(ids, () => ids);
  }
  /**
   * Run a visitor function for all descendants of a shape.
   *
   * @example
   * ```ts
   * editor.visitDescendants('frame1', myCallback)
   * ```
   *
   * @param parentId - The id of the parent shape.
   * @param visitor - The visitor function.
   *
   * @public
   */
  visitDescendants(parent, visitor) {
    const parentId = typeof parent === "string" ? parent : parent.id;
    const children = this.getSortedChildIdsForParent(parentId);
    for (const id of children) {
      if (visitor(id) === false)
        continue;
      this.visitDescendants(id, visitor);
    }
    return this;
  }
  /**
   * Get the shape ids of all descendants of the given shapes (including the shapes themselves).
   *
   * @param ids - The ids of the shapes to get descendants of.
   *
   * @returns The decscendant ids.
   *
   * @public
   */
  getShapeAndDescendantIds(ids) {
    const idsToInclude = /* @__PURE__ */ new Set();
    const idsToCheck = [...ids];
    while (idsToCheck.length > 0) {
      const id = idsToCheck.pop();
      if (!id)
        break;
      if (idsToInclude.has(id))
        continue;
      idsToInclude.add(id);
      for (const childId of this.getSortedChildIdsForParent(id)) {
        idsToCheck.push(childId);
      }
    }
    return idsToInclude;
  }
  /**
   * Get the shape that some shapes should be dropped on at a given point.
   *
   * @param point - The point to find the parent for.
   * @param droppingShapes - The shapes that are being dropped.
   *
   * @returns The shape to drop on.
   *
   * @public
   */
  getDroppingOverShape(point, droppingShapes = []) {
    const { currentPageShapesSorted } = this;
    for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
      const shape = currentPageShapesSorted[i];
      if (
        // only allow shapes that can receive children
        !this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) || // don't allow dropping a shape on itself or one of it's children
        droppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))
      ) {
        continue;
      }
      const maskedPageBounds = this.getShapeMaskedPageBounds(shape.id);
      if (maskedPageBounds && maskedPageBounds.containsPoint(point) && this.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)) {
        return shape;
      }
    }
  }
  /**
   * Get the shape that should be selected when you click on a given shape, assuming there is
   * nothing already selected. It will not return anything higher than or including the current
   * focus layer.
   *
   * @param shape - The shape to get the outermost selectable shape for.
   * @param filter - A function to filter the selectable shapes.
   *
   * @returns The outermost selectable shape.
   *
   * @public
   */
  getOutermostSelectableShape(shape, filter2) {
    const id = typeof shape === "string" ? shape : shape.id;
    const freshShape = this.getShape(id);
    let match = freshShape;
    let node = freshShape;
    const { focusedGroup } = this;
    while (node) {
      if (this.isShapeOfType(node, "group") && focusedGroup?.id !== node.id && !this.hasAncestor(focusedGroup, node.id) && (filter2?.(node) ?? true)) {
        match = node;
      } else if (focusedGroup?.id === node.id) {
        break;
      }
      node = this.getShapeParent(node);
    }
    return match;
  }
  /* -------------------- Commands -------------------- */
  /**
   * Rotate shapes by a delta in radians.
   * Note: Currently, this assumes that the shapes are your currently selected shapes.
   *
   * @example
   * ```ts
   * editor.rotateShapesBy(editor.selectedShapeIds, Math.PI)
   * editor.rotateShapesBy(editor.selectedShapeIds, Math.PI / 2)
   * ```
   *
   * @param shapes - The shapes (or shape ids) of the shapes to move.
   * @param delta - The delta in radians to apply to the selection rotation.
   */
  rotateShapesBy(shapes, delta) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (ids.length <= 0)
      return this;
    const snapshot = getRotationSnapshot({ editor: this });
    if (!snapshot)
      return this;
    applyRotationToSnapshotShapes({ delta, snapshot, editor: this, stage: "one-off" });
    return this;
  }
  /**
   * Move shapes by a delta.
   *
   * @example
   * ```ts
   * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })
   * editor.nudgeShapes(editor.selectedShapes, { x: 8, y: 8 }, { squashing: true })
   * ```
   *
   * @param shapes - The shapes (or shape ids) to move.
   * @param direction - The direction in which to move the shapes.
   * @param historyOptions - (optional) The history options for the change.
   */
  nudgeShapes(shapes, offset2, historyOptions) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (ids.length <= 0)
      return this;
    const changes = [];
    for (const id of ids) {
      const shape = this.getShape(id);
      if (!shape) {
        throw Error(`Could not find a shape with the id ${id}.`);
      }
      const localDelta = Vec2d.Cast(offset2);
      const parentTransform = this.getShapeParentTransform(shape);
      if (parentTransform)
        localDelta.rot(-parentTransform.rotation());
      const translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape);
      changes.push(
        translateStartChanges ? {
          ...translateStartChanges,
          x: shape.x + localDelta.x,
          y: shape.y + localDelta.y
        } : {
          id,
          x: shape.x + localDelta.x,
          y: shape.y + localDelta.y,
          type: shape.type
        }
      );
    }
    this.updateShapes(changes, {
      squashing: true,
      ...historyOptions
    });
    return this;
  }
  /**
   * Duplicate shapes.
   *
   * @example
   * ```ts
   * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })
   * editor.duplicateShapes(editor.selectedShapes, { x: 8, y: 8 })
   * ```
   *
   * @param shapes - The shapes (or shape ids) to duplicate.
   * @param offset - (optional) The offset (in pixels) to apply to the duplicated shapes.
   *
   * @public
   */
  duplicateShapes(shapes, offset2) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (ids.length <= 0)
      return this;
    const initialIds = new Set(ids);
    const idsToCreate = [];
    const idsToCheck = [...ids];
    while (idsToCheck.length > 0) {
      const id = idsToCheck.pop();
      if (!id)
        break;
      idsToCreate.push(id);
      this.getSortedChildIdsForParent(id).forEach((childId) => idsToCheck.push(childId));
    }
    idsToCreate.reverse();
    const idsMap = new Map(idsToCreate.map((id) => [id, createShapeId()]));
    const shapesToCreate = compact(
      idsToCreate.map((id) => {
        const shape = this.getShape(id);
        if (!shape) {
          return null;
        }
        const createId = idsMap.get(id);
        let ox = 0;
        let oy = 0;
        if (offset2 && initialIds.has(id)) {
          const parentTransform = this.getShapeParentTransform(shape);
          const vec = new Vec2d(offset2.x, offset2.y).rot(-parentTransform.rotation());
          ox = vec.x;
          oy = vec.y;
        }
        const parentId = shape.parentId ?? this.currentPageId;
        const siblings = this.getSortedChildIdsForParent(parentId);
        const currentIndex = siblings.indexOf(shape.id);
        const siblingAboveId = siblings[currentIndex + 1];
        const siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : null;
        const index2 = siblingAbove ? getIndexBetween(shape.index, siblingAbove.index) : getIndexAbove(shape.index);
        let newShape = deepCopy(shape);
        if (this.isShapeOfType(shape, "arrow") && this.isShapeOfType(newShape, "arrow")) {
          const info = this.getArrowInfo(shape);
          let newStartShapeId = void 0;
          let newEndShapeId = void 0;
          if (shape.props.start.type === "binding") {
            newStartShapeId = idsMap.get(shape.props.start.boundShapeId);
            if (!newStartShapeId) {
              if (info?.isValid) {
                const { x, y } = info.start.point;
                newShape.props.start = {
                  type: "point",
                  x,
                  y
                };
              } else {
                const { start } = getArrowTerminalsInArrowSpace(this, shape);
                newShape.props.start = {
                  type: "point",
                  x: start.x,
                  y: start.y
                };
              }
            }
          }
          if (shape.props.end.type === "binding") {
            newEndShapeId = idsMap.get(shape.props.end.boundShapeId);
            if (!newEndShapeId) {
              if (info?.isValid) {
                const { x, y } = info.end.point;
                newShape.props.end = {
                  type: "point",
                  x,
                  y
                };
              } else {
                const { end } = getArrowTerminalsInArrowSpace(this, shape);
                newShape.props.start = {
                  type: "point",
                  x: end.x,
                  y: end.y
                };
              }
            }
          }
          const infoAfter = getIsArrowStraight(newShape) ? getStraightArrowInfo(this, newShape) : getCurvedArrowInfo(this, newShape);
          if (info?.isValid && infoAfter?.isValid && !getIsArrowStraight(shape)) {
            const mpA = Vec2d.Med(info.start.handle, info.end.handle);
            const distA = Vec2d.Dist(info.middle, mpA);
            const distB = Vec2d.Dist(infoAfter.middle, mpA);
            if (newShape.props.bend < 0) {
              newShape.props.bend += distB - distA;
            } else {
              newShape.props.bend -= distB - distA;
            }
          }
          if (newShape.props.start.type === "binding" && newStartShapeId) {
            newShape.props.start.boundShapeId = newStartShapeId;
          }
          if (newShape.props.end.type === "binding" && newEndShapeId) {
            newShape.props.end.boundShapeId = newEndShapeId;
          }
        }
        newShape = { ...newShape, id: createId, x: shape.x + ox, y: shape.y + oy, index: index2 };
        return newShape;
      })
    );
    shapesToCreate.forEach((shape) => {
      if (isShapeId(shape.parentId)) {
        if (idsMap.has(shape.parentId)) {
          shape.parentId = idsMap.get(shape.parentId);
        }
      }
    });
    this.history.batch(() => {
      const maxShapesReached = shapesToCreate.length + this.currentPageShapeIds.size > MAX_SHAPES_PER_PAGE;
      if (maxShapesReached) {
        alertMaxShapes(this);
      }
      const newShapes = maxShapesReached ? shapesToCreate.slice(0, MAX_SHAPES_PER_PAGE - this.currentPageShapeIds.size) : shapesToCreate;
      const ids2 = newShapes.map((s) => s.id);
      this.createShapes(newShapes);
      this.setSelectedShapes(ids2);
      if (offset2 !== void 0) {
        const { viewportPageBounds, selectionPageBounds } = this;
        if (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {
          this.centerOnPoint(selectionPageBounds.center, {
            duration: ANIMATION_MEDIUM_MS
          });
        }
      }
    });
    return this;
  }
  /**
   * Move shapes to page.
   *
   * @example
   * ```ts
   * editor.moveShapesToPage(['box1', 'box2'], 'page1')
   * ```
   *
   * @param shapes - The shapes (or shape ids) of the shapes to move.
   * @param pageId - The id of the page where the shapes will be moved.
   *
   * @public
   */
  moveShapesToPage(shapes, pageId) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (ids.length === 0)
      return this;
    if (this.instanceState.isReadonly)
      return this;
    const { currentPageId } = this;
    if (pageId === currentPageId)
      return this;
    if (!this.store.has(pageId))
      return this;
    const content = this.getContentFromCurrentPage(ids);
    if (!content)
      return this;
    if (this.getPageShapeIds(pageId).size + content.shapes.length > MAX_SHAPES_PER_PAGE) {
      alertMaxShapes(this, pageId);
      return this;
    }
    const fromPageZ = this.camera.z;
    this.history.batch(() => {
      this.deleteShapes(ids);
      this.setCurrentPage(pageId);
      this.setFocusedGroup(null);
      this.selectNone();
      this.putContentOntoCurrentPage(content, {
        select: true,
        preserveIds: true,
        preservePosition: true
      });
      this.setCamera({ ...this.camera, z: fromPageZ });
      this.centerOnPoint(this.selectionRotatedPageBounds.center);
    });
    return this;
  }
  /**
   * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.
   *
   * @param shapes - The shapes (or shape ids) to toggle.
   *
   * @public
   */
  toggleLock(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (this.instanceState.isReadonly || ids.length === 0)
      return this;
    let allLocked = true, allUnlocked = true;
    const shapesToToggle = [];
    for (const id of ids) {
      const shape = this.getShape(id);
      if (shape) {
        shapesToToggle.push(shape);
        if (shape.isLocked) {
          allUnlocked = false;
        } else {
          allLocked = false;
        }
      }
    }
    this.batch(() => {
      if (allUnlocked) {
        this.updateShapes(
          shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
        );
        this.setSelectedShapes([]);
      } else if (allLocked) {
        this.updateShapes(
          shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))
        );
      } else {
        this.updateShapes(
          shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
        );
      }
    });
    return this;
  }
  /**
   * Send shapes to the back of the page's object list.
   *
   * @example
   * ```ts
   * editor.sendToBack(['id1', 'id2'])
   * editor.sendToBack(box1, box2)
   * ```
   *
   * @param shapes - The shapes (or shape ids) to move.
   *
   * @public
   */
  sendToBack(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    const changes = getReorderingShapesChanges(this, "toBack", ids);
    if (changes)
      this.updateShapes(changes);
    return this;
  }
  /**
   * Send shapes backward in the page's object list.
   *
   * @example
   * ```ts
   * editor.sendBackward(['id1', 'id2'])
   * editor.sendBackward([box1, box2])
   * ```
   *
   * @param shapes - The shapes (or shape ids) to move.
   *
   * @public
   */
  sendBackward(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    const changes = getReorderingShapesChanges(this, "backward", ids);
    if (changes)
      this.updateShapes(changes);
    return this;
  }
  /**
   * Bring shapes forward in the page's object list.
   *
   * @example
   * ```ts
   * editor.bringForward(['id1', 'id2'])
   * editor.bringForward(box1,  box2)
   * ```
   *
   * @param shapes - The shapes (or shape ids) to move.
   *
   * @public
   */
  bringForward(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    const changes = getReorderingShapesChanges(this, "forward", ids);
    if (changes)
      this.updateShapes(changes);
    return this;
  }
  /**
   * Bring shapes to the front of the page's object list.
   *
   * @example
   * ```ts
   * editor.bringToFront(['id1', 'id2'])
   * editor.bringToFront([box1, box2])
   * ```
   *
   * @param shapes - The shapes (or shape ids) to move.
   *
   * @public
   */
  bringToFront(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    const changes = getReorderingShapesChanges(this, "toFront", ids);
    if (changes)
      this.updateShapes(changes);
    return this;
  }
  /**
   * Flip shape positions.
   *
   * @example
   * ```ts
   * editor.flipShapes([box1, box2], 'horizontal', 32)
   * editor.flipShapes(editor.selectedShapeIds, 'horizontal', 32)
   * ```
   *
   * @param shapes - The ids of the shapes to flip.
   * @param operation - Whether to flip horizontally or vertically.
   *
   * @public
   */
  flipShapes(shapes, operation) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (this.instanceState.isReadonly)
      return this;
    let shapesToFlip = compact(ids.map((id) => this.getShape(id)));
    if (!shapesToFlip.length)
      return this;
    shapesToFlip = compact(
      shapesToFlip.map((shape) => {
        if (this.isShapeOfType(shape, "group")) {
          return this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id));
        }
        return shape;
      }).flat()
    );
    const scaleOriginPage = Box2d.Common(
      compact(shapesToFlip.map((id) => this.getShapePageBounds(id)))
    ).center;
    this.batch(() => {
      for (const shape of shapesToFlip) {
        const bounds = this.getShapeGeometry(shape).bounds;
        const initialPageTransform = this.getShapePageTransform(shape.id);
        if (!initialPageTransform)
          continue;
        this.resizeShape(
          shape.id,
          { x: operation === "horizontal" ? -1 : 1, y: operation === "vertical" ? -1 : 1 },
          {
            initialBounds: bounds,
            initialPageTransform,
            initialShape: shape,
            mode: "scale_shape",
            scaleOrigin: scaleOriginPage,
            scaleAxisRotation: 0
          }
        );
      }
    });
    return this;
  }
  /**
   * Stack shape.
   *
   * @example
   * ```ts
   * editor.stackShapes([box1, box2], 'horizontal', 32)
   * editor.stackShapes(editor.selectedShapeIds, 'horizontal', 32)
   * ```
   *
   * @param shapes - The shapes (or shape ids) to stack.
   * @param operation - Whether to stack horizontally or vertically.
   * @param gap - The gap to leave between shapes.
   *
   * @public
   */
  stackShapes(shapes, operation, gap) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (this.instanceState.isReadonly)
      return this;
    const shapesToStack = compact(
      ids.map((id) => this.getShape(id)).filter((shape) => {
        if (!shape)
          return false;
        if (this.isShapeOfType(shape, "arrow")) {
          if (shape.props.start.type === "binding" || shape.props.end.type === "binding") {
            return false;
          }
        }
        return true;
      })
    );
    const len = shapesToStack.length;
    if (gap === 0 && len < 3 || len < 2)
      return this;
    const pageBounds = Object.fromEntries(
      shapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)])
    );
    let val;
    let min4;
    let max3;
    let dim;
    if (operation === "horizontal") {
      val = "x";
      min4 = "minX";
      max3 = "maxX";
      dim = "width";
    } else {
      val = "y";
      min4 = "minY";
      max3 = "maxY";
      dim = "height";
    }
    let shapeGap;
    if (gap === 0) {
      const gaps = [];
      shapesToStack.sort((a, b) => pageBounds[a.id][min4] - pageBounds[b.id][min4]);
      for (let i = 0; i < len - 1; i++) {
        const shape = shapesToStack[i];
        const nextShape = shapesToStack[i + 1];
        const bounds = pageBounds[shape.id];
        const nextBounds = pageBounds[nextShape.id];
        const gap2 = nextBounds[min4] - bounds[max3];
        const current = gaps.find((g) => g.gap === gap2);
        if (current) {
          current.count++;
        } else {
          gaps.push({ gap: gap2, count: 1 });
        }
      }
      let maxCount = 0;
      gaps.forEach((g) => {
        if (g.count > maxCount) {
          maxCount = g.count;
          shapeGap = g.gap;
        }
      });
      if (maxCount === 1) {
        shapeGap = Math.max(0, gaps.reduce((a, c) => a + c.gap * c.count, 0) / (len - 1));
      }
    } else {
      shapeGap = gap;
    }
    const changes = [];
    let v = pageBounds[shapesToStack[0].id][max3];
    shapesToStack.forEach((shape, i) => {
      if (i === 0)
        return;
      const delta = { x: 0, y: 0 };
      delta[val] = v + shapeGap - pageBounds[shape.id][val];
      const parent = this.getShapeParent(shape);
      const localDelta = parent ? Vec2d.Rot(delta, -this.getShapePageTransform(parent).decompose().rotation) : delta;
      const translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape);
      changes.push(
        translateStartChanges ? {
          ...translateStartChanges,
          [val]: shape[val] + localDelta[val]
        } : {
          id: shape.id,
          type: shape.type,
          [val]: shape[val] + localDelta[val]
        }
      );
      v += pageBounds[shape.id][dim] + shapeGap;
    });
    this.updateShapes(changes);
    return this;
  }
  /**
   * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).
   *
   * @example
   * ```ts
   * editor.packShapes([box1, box2], 32)
   * editor.packShapes(editor.selectedShapeIds, 32)
   * ```
   *
   *
   * @param shapes - The shapes (or shape ids) to pack.
   * @param gap - The padding to apply to the packed shapes. Defaults to 16.
   */
  packShapes(shapes, gap) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (this.instanceState.isReadonly)
      return this;
    if (ids.length < 2)
      return this;
    const shapesToPack = compact(
      ids.map((id) => this.getShape(id)).filter((shape2) => {
        if (!shape2)
          return false;
        if (this.isShapeOfType(shape2, "arrow")) {
          if (shape2.props.start.type === "binding" || shape2.props.end.type === "binding") {
            return false;
          }
        }
        return true;
      })
    );
    const shapePageBounds = {};
    const nextShapePageBounds = {};
    let shape, bounds, area = 0;
    for (let i = 0; i < shapesToPack.length; i++) {
      shape = shapesToPack[i];
      bounds = this.getShapePageBounds(shape);
      shapePageBounds[shape.id] = bounds;
      nextShapePageBounds[shape.id] = bounds.clone();
      area += bounds.width * bounds.height;
    }
    const commonBounds = Box2d.Common(compact(Object.values(shapePageBounds)));
    const maxWidth2 = commonBounds.width;
    shapesToPack.sort((a, b) => shapePageBounds[b.id].height - shapePageBounds[a.id].height);
    const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth2);
    const spaces = [new Box2d(commonBounds.x, commonBounds.y, startWidth, Infinity)];
    let width = 0;
    let height = 0;
    let space;
    let last2;
    for (let i = 0; i < shapesToPack.length; i++) {
      shape = shapesToPack[i];
      bounds = nextShapePageBounds[shape.id];
      for (let i2 = spaces.length - 1; i2 >= 0; i2--) {
        space = spaces[i2];
        if (bounds.width > space.width || bounds.height > space.height)
          continue;
        bounds.x = space.x;
        bounds.y = space.y;
        height = Math.max(height, bounds.maxY);
        width = Math.max(width, bounds.maxX);
        if (bounds.width === space.width && bounds.height === space.height) {
          last2 = spaces.pop();
          if (i2 < spaces.length)
            spaces[i2] = last2;
        } else if (bounds.height === space.height) {
          space.x += bounds.width + gap;
          space.width -= bounds.width + gap;
        } else if (bounds.width === space.width) {
          space.y += bounds.height + gap;
          space.height -= bounds.height + gap;
        } else {
          spaces.push(
            new Box2d(
              space.x + (bounds.width + gap),
              space.y,
              space.width - (bounds.width + gap),
              bounds.height
            )
          );
          space.y += bounds.height + gap;
          space.height -= bounds.height + gap;
        }
        break;
      }
    }
    const commonAfter = Box2d.Common(Object.values(nextShapePageBounds));
    const centerDelta = Vec2d.Sub(commonBounds.center, commonAfter.center);
    let nextBounds;
    const changes = [];
    for (let i = 0; i < shapesToPack.length; i++) {
      shape = shapesToPack[i];
      bounds = shapePageBounds[shape.id];
      nextBounds = nextShapePageBounds[shape.id];
      const delta = Vec2d.Sub(nextBounds.point, bounds.point).add(centerDelta);
      const parentTransform = this.getShapeParentTransform(shape);
      if (parentTransform)
        delta.rot(-parentTransform.rotation());
      const change = {
        id: shape.id,
        type: shape.type,
        x: shape.x + delta.x,
        y: shape.y + delta.y
      };
      const translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({
        ...shape,
        ...change
      });
      if (translateStartChange) {
        changes.push({ ...change, ...translateStartChange });
      } else {
        changes.push(change);
      }
    }
    if (changes.length) {
      this.updateShapes(changes);
    }
    return this;
  }
  /**
   * Align shape positions.
   *
   * @example
   * ```ts
   * editor.alignShapes([box1, box2], 'left')
   * editor.alignShapes(editor.selectedShapeIds, 'left')
   * ```
   *
   * @param shapes - The shapes (or shape ids) to align.
   * @param operation - The align operation to apply.
   *
   * @public
   */
  alignShapes(shapes, operation) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (this.instanceState.isReadonly)
      return this;
    if (ids.length < 2)
      return this;
    const shapesToAlign = compact(ids.map((id) => this.getShape(id)));
    const shapePageBounds = Object.fromEntries(
      shapesToAlign.map((shape) => [shape.id, this.getShapePageBounds(shape)])
    );
    const commonBounds = Box2d.Common(compact(Object.values(shapePageBounds)));
    const changes = [];
    shapesToAlign.forEach((shape) => {
      const pageBounds = shapePageBounds[shape.id];
      if (!pageBounds)
        return;
      const delta = { x: 0, y: 0 };
      switch (operation) {
        case "top": {
          delta.y = commonBounds.minY - pageBounds.minY;
          break;
        }
        case "center-vertical": {
          delta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2;
          break;
        }
        case "bottom": {
          delta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height;
          break;
        }
        case "left": {
          delta.x = commonBounds.minX - pageBounds.minX;
          break;
        }
        case "center-horizontal": {
          delta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2;
          break;
        }
        case "right": {
          delta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width;
          break;
        }
      }
      const parent = this.getShapeParent(shape);
      const localDelta = parent ? Vec2d.Rot(delta, -this.getShapePageTransform(parent).decompose().rotation) : delta;
      const translateChanges = this.getShapeUtil(shape).onTranslateStart?.(shape);
      changes.push(
        translateChanges ? {
          ...translateChanges,
          x: shape.x + localDelta.x,
          y: shape.y + localDelta.y
        } : {
          id: shape.id,
          type: shape.type,
          x: shape.x + localDelta.x,
          y: shape.y + localDelta.y
        }
      );
    });
    this.updateShapes(changes);
    return this;
  }
  /**
   * Distribute shape positions.
   *
   * @example
   * ```ts
   * editor.distributeShapes([box1, box2], 'horizontal')
   * editor.distributeShapes(editor.selectedShapeIds, 'horizontal')
   * ```
   *
   * @param shapes - The shapes (or shape ids) to distribute.
   * @param operation - Whether to distribute shapes horizontally or vertically.
   *
   * @public
   */
  distributeShapes(shapes, operation) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (this.instanceState.isReadonly)
      return this;
    if (ids.length < 3)
      return this;
    const len = ids.length;
    const shapesToDistribute = compact(ids.map((id) => this.getShape(id)));
    const pageBounds = Object.fromEntries(
      shapesToDistribute.map((shape) => [shape.id, this.getShapePageBounds(shape)])
    );
    let val;
    let min4;
    let max3;
    let mid;
    let dim;
    if (operation === "horizontal") {
      val = "x";
      min4 = "minX";
      max3 = "maxX";
      mid = "midX";
      dim = "width";
    } else {
      val = "y";
      min4 = "minY";
      max3 = "maxY";
      mid = "midY";
      dim = "height";
    }
    const changes = [];
    const first = shapesToDistribute.sort(
      (a, b) => pageBounds[a.id][min4] - pageBounds[b.id][min4]
    )[0];
    const last2 = shapesToDistribute.sort((a, b) => pageBounds[b.id][max3] - pageBounds[a.id][max3])[0];
    const midFirst = pageBounds[first.id][mid];
    const step = (pageBounds[last2.id][mid] - midFirst) / (len - 1);
    const v = midFirst + step;
    shapesToDistribute.filter((shape) => shape !== first && shape !== last2).sort((a, b) => pageBounds[a.id][mid] - pageBounds[b.id][mid]).forEach((shape, i) => {
      const delta = { x: 0, y: 0 };
      delta[val] = v + step * i - pageBounds[shape.id][dim] / 2 - pageBounds[shape.id][val];
      const parent = this.getShapeParent(shape);
      const localDelta = parent ? Vec2d.Rot(delta, -this.getShapePageTransform(parent).rotation()) : delta;
      const translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape);
      changes.push(
        translateStartChanges ? {
          ...translateStartChanges,
          [val]: shape[val] + localDelta[val]
        } : {
          id: shape.id,
          type: shape.type,
          [val]: shape[val] + localDelta[val]
        }
      );
    });
    this.updateShapes(changes);
    return this;
  }
  /**
   * Stretch shape sizes and positions to fill their common bounding box.
   *
   * @example
   * ```ts
   * editor.stretchShapes([box1, box2], 'horizontal')
   * editor.stretchShapes(editor.selectedShapeIds, 'horizontal')
   * ```
   *
   * @param shapes - The shapes (or shape ids) to stretch.
   * @param operation - Whether to stretch shapes horizontally or vertically.
   *
   * @public
   */
  stretchShapes(shapes, operation) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (this.instanceState.isReadonly)
      return this;
    if (ids.length < 2)
      return this;
    const shapesToStretch = compact(ids.map((id) => this.getShape(id)));
    const shapeBounds = Object.fromEntries(ids.map((id) => [id, this.getShapeGeometry(id).bounds]));
    const shapePageBounds = Object.fromEntries(ids.map((id) => [id, this.getShapePageBounds(id)]));
    const commonBounds = Box2d.Common(compact(Object.values(shapePageBounds)));
    switch (operation) {
      case "vertical": {
        this.batch(() => {
          for (const shape of shapesToStretch) {
            const pageRotation = this.getShapePageTransform(shape).rotation();
            if (pageRotation % PI2)
              continue;
            const bounds = shapeBounds[shape.id];
            const pageBounds = shapePageBounds[shape.id];
            const localOffset = new Vec2d(0, commonBounds.minY - pageBounds.minY);
            const parentTransform = this.getShapeParentTransform(shape);
            if (parentTransform)
              localOffset.rot(-parentTransform.rotation());
            const { x, y } = Vec2d.Add(localOffset, shape);
            this.updateShapes([{ id: shape.id, type: shape.type, x, y }], { squashing: true });
            const scale = new Vec2d(1, commonBounds.height / pageBounds.height);
            this.resizeShape(shape.id, scale, {
              initialBounds: bounds,
              scaleOrigin: new Vec2d(pageBounds.center.x, commonBounds.minY),
              scaleAxisRotation: 0
            });
          }
        });
        break;
      }
      case "horizontal": {
        this.batch(() => {
          for (const shape of shapesToStretch) {
            const bounds = shapeBounds[shape.id];
            const pageBounds = shapePageBounds[shape.id];
            const pageRotation = this.getShapePageTransform(shape).rotation();
            if (pageRotation % PI2)
              continue;
            const localOffset = new Vec2d(commonBounds.minX - pageBounds.minX, 0);
            const parentTransform = this.getShapeParentTransform(shape);
            if (parentTransform)
              localOffset.rot(-parentTransform.rotation());
            const { x, y } = Vec2d.Add(localOffset, shape);
            this.updateShapes([{ id: shape.id, type: shape.type, x, y }], { squashing: true });
            const scale = new Vec2d(commonBounds.width / pageBounds.width, 1);
            this.resizeShape(shape.id, scale, {
              initialBounds: bounds,
              scaleOrigin: new Vec2d(commonBounds.minX, pageBounds.center.y),
              scaleAxisRotation: 0
            });
          }
        });
        break;
      }
    }
    return this;
  }
  /**
   * Resize a shape.
   *
   * @param id - The id of the shape to resize.
   * @param scale - The scale factor to apply to the shape.
   * @param options - Additional options.
   *
   * @public
   */
  resizeShape(shape, scale, options = {}) {
    const id = typeof shape === "string" ? shape : shape.id;
    if (this.instanceState.isReadonly)
      return this;
    if (!Number.isFinite(scale.x))
      scale = new Vec2d(1, scale.y);
    if (!Number.isFinite(scale.y))
      scale = new Vec2d(scale.x, 1);
    const initialShape = options.initialShape ?? this.getShape(id);
    if (!initialShape)
      return this;
    const scaleOrigin = options.scaleOrigin ?? this.getShapePageBounds(id)?.center;
    if (!scaleOrigin)
      return this;
    const pageTransform = options.initialPageTransform ? Matrix2d.Cast(options.initialPageTransform) : this.getShapePageTransform(id);
    if (!pageTransform)
      return this;
    const pageRotation = pageTransform.rotation();
    if (pageRotation == null)
      return this;
    const scaleAxisRotation = options.scaleAxisRotation ?? pageRotation;
    const initialBounds = options.initialBounds ?? this.getShapeGeometry(id).bounds;
    if (!initialBounds)
      return this;
    if (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {
      return this._resizeUnalignedShape(id, scale, {
        ...options,
        initialBounds,
        scaleOrigin,
        scaleAxisRotation,
        initialPageTransform: pageTransform,
        initialShape
      });
    }
    const util = this.getShapeUtil(initialShape);
    if (util.isAspectRatioLocked(initialShape)) {
      if (Math.abs(scale.x) > Math.abs(scale.y)) {
        scale = new Vec2d(scale.x, Math.sign(scale.y) * Math.abs(scale.x));
      } else {
        scale = new Vec2d(Math.sign(scale.x) * Math.abs(scale.y), scale.y);
      }
    }
    if (util.onResize && util.canResize(initialShape)) {
      const newPagePoint = this._scalePagePoint(
        Matrix2d.applyToPoint(pageTransform, new Vec2d(0, 0)),
        scaleOrigin,
        scale,
        scaleAxisRotation
      );
      const newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint);
      const myScale = new Vec2d(scale.x, scale.y);
      const areWidthAndHeightAlignedWithCorrectAxis = approximately(
        (pageRotation - scaleAxisRotation) % Math.PI,
        0
      );
      myScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y;
      myScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x;
      const initialPagePoint = Matrix2d.applyToPoint(pageTransform, new Vec2d());
      const { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint);
      this.updateShapes(
        [
          {
            id,
            type: initialShape.type,
            x: newLocalPoint.x,
            y: newLocalPoint.y,
            ...util.onResize(
              { ...initialShape, x, y },
              {
                newPoint: newLocalPoint,
                handle: options.dragHandle ?? "bottom_right",
                // don't set isSingle to true for children
                mode: options.mode ?? "scale_shape",
                scaleX: myScale.x,
                scaleY: myScale.y,
                initialBounds,
                initialShape
              }
            )
          }
        ],
        { squashing: true }
      );
    } else {
      const initialPageCenter = Matrix2d.applyToPoint(pageTransform, initialBounds.center);
      const newPageCenter = this._scalePagePoint(
        initialPageCenter,
        scaleOrigin,
        scale,
        scaleAxisRotation
      );
      const initialPageCenterInParentSpace = this.getPointInParentSpace(
        initialShape.id,
        initialPageCenter
      );
      const newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter);
      const delta = Vec2d.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace);
      this.updateShapes(
        [
          {
            id,
            type: initialShape.type,
            x: initialShape.x + delta.x,
            y: initialShape.y + delta.y
          }
        ],
        { squashing: true }
      );
    }
    return this;
  }
  /** @internal */
  _scalePagePoint(point, scaleOrigin, scale, scaleAxisRotation) {
    const relativePoint = Vec2d.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin);
    const newRelativePagePoint = Vec2d.MulV(relativePoint, scale);
    const destination = Vec2d.Add(newRelativePagePoint, scaleOrigin).rotWith(
      scaleOrigin,
      scaleAxisRotation
    );
    return destination;
  }
  /** @internal */
  _resizeUnalignedShape(id, scale, options) {
    const { type } = options.initialShape;
    const shapeScale = new Vec2d(scale.x, scale.y);
    if (Math.abs(scale.x) > Math.abs(scale.y)) {
      shapeScale.x = Math.sign(scale.x) * Math.abs(scale.y);
    } else {
      shapeScale.y = Math.sign(scale.y) * Math.abs(scale.x);
    }
    this.resizeShape(id, shapeScale, {
      initialShape: options.initialShape,
      initialBounds: options.initialBounds
    });
    if (Math.sign(scale.x) * Math.sign(scale.y) < 0) {
      let { rotation } = Matrix2d.Decompose(options.initialPageTransform);
      rotation -= 2 * rotation;
      this.updateShapes([{ id, type, rotation }], { squashing: true });
    }
    const preScaleShapePageCenter = Matrix2d.applyToPoint(
      options.initialPageTransform,
      options.initialBounds.center
    );
    const postScaleShapePageCenter = this._scalePagePoint(
      preScaleShapePageCenter,
      options.scaleOrigin,
      scale,
      options.scaleAxisRotation
    );
    const pageBounds = this.getShapePageBounds(id);
    const pageTransform = this.getShapePageTransform(id);
    const currentPageCenter = pageBounds.center;
    const shapePageTransformOrigin = pageTransform.point();
    if (!currentPageCenter || !shapePageTransformOrigin)
      return this;
    const pageDelta = Vec2d.Sub(postScaleShapePageCenter, currentPageCenter);
    const postScaleShapePagePoint = Vec2d.Add(shapePageTransformOrigin, pageDelta);
    const { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint);
    this.updateShapes([{ id, type, x, y }], { squashing: true });
    return this;
  }
  /**
   * Get the initial meta value for a shape.
   *
   * @example
   * ```ts
   * editor.getInitialMetaForShape = (shape) => {
   *   if (shape.type === 'note') {
   *     return { createdBy: myCurrentUser.id }
   *   }
   * }
   * ```
   *
   * @param shape - The shape to get the initial meta for.
   *
   * @public
   */
  getInitialMetaForShape(_shape) {
    return {};
  }
  /**
   * Create a single shape.
   *
   * @example
   * ```ts
   * editor.createShape(myShape)
   * editor.createShape({ id: 'box1', type: 'text', props: { text: "ok" } })
   * ```
   *
   * @param shape - The shape (or shape partial) to create.
   *
   * @public
   */
  createShape(shape) {
    this._createShapes([shape]);
    return this;
  }
  /**
   * Create shapes.
   *
   * @example
   * ```ts
   * editor.createShapes([myShape])
   * editor.createShapes([{ id: 'box1', type: 'text', props: { text: "ok" } }])
   * ```
   *
   * @param shapes - The shapes (or shape partials) to create.
   * @param select - Whether to select the created shapes. Defaults to false.
   *
   * @public
   */
  createShapes(shapes) {
    if (!Array.isArray(shapes)) {
      throw Error("Editor.createShapes: must provide an array of shapes or shape partials");
    }
    this._createShapes(shapes);
    return this;
  }
  /** @internal */
  _createShapes = this.history.createCommand(
    "createShapes",
    (partials) => {
      if (this.instanceState.isReadonly)
        return null;
      if (partials.length <= 0)
        return null;
      const { currentPageShapeIds } = this;
      const maxShapesReached = partials.length + currentPageShapeIds.size > MAX_SHAPES_PER_PAGE;
      if (maxShapesReached) {
        alertMaxShapes(this);
        return;
      }
      if (partials.length === 0)
        return null;
      return {
        data: {
          currentPageId: this.currentPageId,
          partials: partials.map(
            (p) => p.id ? p : { ...p, id: createShapeId() }
          )
        }
      };
    },
    {
      do: ({ partials }) => {
        const { focusedGroupId } = this;
        const { currentPageShapesSorted } = this;
        partials = partials.map((partial) => {
          if (!partial.parentId || !(this.store.has(partial.parentId) || partials.some((p) => p.id === partial.parentId))) {
            let parentId = this.focusedGroupId;
            for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
              const parent = currentPageShapesSorted[i];
              if (
                // parent.type === 'frame'
                this.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) && this.isPointInShape(
                  parent,
                  // If no parent is provided, then we can treat the
                  // shape's provided x/y as being in the page's space.
                  { x: partial.x ?? 0, y: partial.y ?? 0 },
                  {
                    margin: 0,
                    hitInside: true
                  }
                )
              ) {
                parentId = parent.id;
                break;
              }
            }
            const prevParentId = partial.parentId;
            if (parentId === partial.id) {
              parentId = focusedGroupId;
            }
            if (parentId !== prevParentId) {
              partial = { ...partial };
              partial.parentId = parentId;
              if (isShapeId(parentId)) {
                const point = this.getPointInShapeSpace(this.getShape(parentId), {
                  x: partial.x ?? 0,
                  y: partial.y ?? 0
                });
                partial.x = point.x;
                partial.y = point.y;
                partial.rotation = -this.getShapePageTransform(parentId).rotation() + (partial.rotation ?? 0);
              }
            }
          }
          return partial;
        });
        const parentIndices = /* @__PURE__ */ new Map();
        const shapeRecordsToCreate = [];
        for (const partial of partials) {
          const util = this.getShapeUtil(partial);
          let index2 = partial.index;
          if (!index2) {
            const parentId = partial.parentId ?? focusedGroupId;
            if (!parentIndices.has(parentId)) {
              parentIndices.set(parentId, this.getHighestIndexForParent(parentId));
            }
            index2 = parentIndices.get(parentId);
            parentIndices.set(parentId, getIndexAbove(index2));
          }
          const initialProps = util.getDefaultProps();
          for (const [style, propKey] of this.styleProps[partial.type]) {
            ;
            initialProps[propKey] = this.getStyleForNextShape(style);
          }
          let shapeRecordToCreate = this.store.schema.types.shape.create({
            ...partial,
            index: index2,
            opacity: partial.opacity ?? this.instanceState.opacityForNextShape,
            parentId: partial.parentId ?? focusedGroupId,
            props: "props" in partial ? { ...initialProps, ...partial.props } : initialProps
          });
          if (shapeRecordToCreate.index === void 0) {
            throw Error("no index!");
          }
          const next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate);
          if (next) {
            shapeRecordToCreate = next;
          }
          shapeRecordsToCreate.push(shapeRecordToCreate);
        }
        shapeRecordsToCreate.forEach((shape) => {
          shape.meta = {
            ...this.getInitialMetaForShape(shape),
            ...shape.meta
          };
        });
        this.store.put(shapeRecordsToCreate);
      },
      undo: ({ partials }) => {
        this.store.remove(partials.map((p) => p.id));
      }
    }
  );
  animatingShapes = /* @__PURE__ */ new Map();
  /**
   * Animate a shape.
   *
   * @example
   * ```ts
   * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })
   * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { duration: 100, ease: t => t*t })
   * ```
   *
   * @param partial - The shape partial to update.
   * @param options - (optional) The animation's options.
   *
   * @public
   */
  animateShape(partial, animationOptions) {
    return this.animateShapes([partial], animationOptions);
  }
  /**
   * Animate shapes.
   *
   * @example
   * ```ts
   * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])
   * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { duration: 100, ease: t => t*t })
   * ```
   *
   * @param partials - The shape partials to update.
   * @param options - (optional) The animation's options.
   *
   * @public
   */
  animateShapes(partials, animationOptions = {}) {
    const { duration = 500, easing = EASINGS.linear } = animationOptions;
    const animationId = uniqueId();
    let remaining = duration;
    let t2;
    const animations = [];
    partials.forEach((partial) => {
      if (!partial)
        return;
      const result = {
        partial,
        values: []
      };
      const shape = this.getShape(partial.id);
      if (!shape)
        return;
      for (const key of ["x", "y", "rotation"]) {
        if (partial[key] !== void 0 && shape[key] !== partial[key]) {
          result.values.push({ prop: key, from: shape[key], to: partial[key] });
        }
      }
      animations.push(result);
      this.animatingShapes.set(shape.id, animationId);
    });
    let value;
    const handleTick = (elapsed) => {
      remaining -= elapsed;
      if (remaining < 0) {
        const { animatingShapes: animatingShapes2 } = this;
        const partialsToUpdate = partials.filter(
          (p) => p && animatingShapes2.get(p.id) === animationId
        );
        if (partialsToUpdate.length) {
          this.updateShapes(partialsToUpdate, { squashing: false });
        }
        this.removeListener("tick", handleTick);
        return;
      }
      t2 = easing(1 - remaining / duration);
      const { animatingShapes } = this;
      try {
        const tPartials = [];
        for (let i = 0; i < animations.length; i++) {
          value = animations[i];
          if (animatingShapes.get(value.partial.id) === animationId) {
            tPartials.push({
              id: value.partial.id,
              type: value.partial.type,
              ...value.values.reduce((acc, { prop, from, to }) => {
                acc[prop] = from + (to - from) * t2;
                return acc;
              }, {})
            });
          }
        }
        this._updateShapes(tPartials, { squashing: true });
      } catch (e) {
      }
    };
    this.addListener("tick", handleTick);
    return this;
  }
  /**
   * Create a group containing the provided shapes.
   *
   * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.
   * @param groupId - (optional) The id of the group to create.
   *
   * @public
   */
  groupShapes(shapes, groupId = createShapeId()) {
    if (!Array.isArray(shapes)) {
      throw Error("Editor.groupShapes: must provide an array of shapes or shape ids");
    }
    if (this.instanceState.isReadonly)
      return this;
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (ids.length <= 1)
      return this;
    const shapesToGroup = compact(this._getUnlockedShapeIds(ids).map((id) => this.getShape(id)));
    const sortedShapeIds = shapesToGroup.sort(sortByIndex2).map((s) => s.id);
    const pageBounds = Box2d.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))));
    const { x, y } = pageBounds.point;
    const parentId = this.findCommonAncestor(shapesToGroup) ?? this.currentPageId;
    if (this.currentToolId !== "select")
      return this;
    if (!this.isIn("select.idle")) {
      this.cancel();
    }
    const shapesWithRootParent = shapesToGroup.filter((shape) => shape.parentId === parentId).sort(sortByIndex2);
    const highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index;
    this.batch(() => {
      this.createShapes([
        {
          id: groupId,
          type: "group",
          parentId,
          index: highestIndex,
          x,
          y,
          opacity: 1,
          props: {}
        }
      ]);
      this.reparentShapes(sortedShapeIds, groupId);
      this.select(groupId);
    });
    return this;
  }
  ungroupShapes(_ids) {
    const ids = typeof _ids[0] === "string" ? _ids : _ids.map((s) => s.id);
    if (this.instanceState.isReadonly)
      return this;
    if (ids.length === 0)
      return this;
    if (this.currentToolId !== "select")
      return this;
    if (!this.isIn("select.idle")) {
      this.cancel();
    }
    const idsToSelect = /* @__PURE__ */ new Set();
    const shapes = compact(ids.map((id) => this.getShape(id)));
    const groups = [];
    shapes.forEach((shape) => {
      if (this.isShapeOfType(shape, "group")) {
        groups.push(shape);
      } else {
        idsToSelect.add(shape.id);
      }
    });
    if (groups.length === 0)
      return this;
    this.batch(() => {
      let group;
      for (let i = 0, n = groups.length; i < n; i++) {
        group = groups[i];
        const childIds = this.getSortedChildIdsForParent(group.id);
        for (let j = 0, n2 = childIds.length; j < n2; j++) {
          idsToSelect.add(childIds[j]);
        }
        this.reparentShapes(childIds, group.parentId, group.index);
      }
      this.deleteShapes(groups.map((group2) => group2.id));
      this.select(...idsToSelect);
    });
    return this;
  }
  /**
   * Update a shape using a partial of the shape.
   *
   * @example
   * ```ts
   * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })
   * ```
   *
   * @param partial - The shape partial to update.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  updateShape(partial, historyOptions) {
    this.updateShapes([partial], historyOptions);
    return this;
  }
  /**
   * Update shapes using partials of each shape.
   *
   * @example
   * ```ts
   * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])
   * ```
   *
   * @param partials - The shape partials to update.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  updateShapes(partials, historyOptions) {
    let compactedPartials = compact(partials);
    if (this.animatingShapes.size > 0) {
      compactedPartials.forEach((p) => this.animatingShapes.delete(p.id));
    }
    compactedPartials = compactedPartials.filter((p) => {
      const shape = this.getShape(p.id);
      if (!shape)
        return false;
      if (this.isShapeOrAncestorLocked(shape) && !Object.hasOwn(p, "isLocked"))
        return false;
      return true;
    });
    this._updateShapes(compactedPartials, historyOptions);
    return this;
  }
  /** @internal */
  _updateShapes = this.history.createCommand(
    "updateShapes",
    (_partials, historyOptions) => {
      if (this.instanceState.isReadonly)
        return null;
      const partials = compact(_partials);
      const snapshots = Object.fromEntries(
        compact(partials.map(({ id }) => this.getShape(id))).map((shape) => {
          return [shape.id, shape];
        })
      );
      if (partials.length <= 0)
        return null;
      const updated = compact(
        partials.map((partial) => {
          const prev = snapshots[partial.id];
          if (!prev)
            return null;
          let newRecord = null;
          for (const [k, v] of Object.entries(partial)) {
            if (v === void 0)
              continue;
            switch (k) {
              case "id":
              case "type":
                continue;
              default: {
                if (v !== prev[k]) {
                  if (!newRecord) {
                    newRecord = { ...prev };
                  }
                  if (k === "props") {
                    const nextProps = { ...prev.props };
                    for (const [propKey, propValue] of Object.entries(v)) {
                      if (propValue !== void 0) {
                        nextProps[propKey] = propValue;
                      }
                    }
                    newRecord.props = nextProps;
                  } else if (k === "meta") {
                    const nextMeta = { ...prev.meta };
                    for (const [metaKey, metaValue] of Object.entries(v)) {
                      if (metaValue !== void 0) {
                        nextMeta[metaKey] = metaValue;
                      }
                    }
                    newRecord.meta = nextMeta;
                  } else {
                    ;
                    newRecord[k] = v;
                  }
                }
              }
            }
          }
          return newRecord ?? prev;
        })
      );
      const updates = Object.fromEntries(updated.map((shape) => [shape.id, shape]));
      return { data: { snapshots, updates }, ...historyOptions };
    },
    {
      do: ({ updates }) => {
        const result = Object.values(updates);
        for (let i = 0; i < result.length; i++) {
          const shape = result[i];
          const current = this.store.get(shape.id);
          if (!current)
            continue;
          const next = this.getShapeUtil(shape).onBeforeUpdate?.(current, shape);
          if (next) {
            result[i] = next;
          }
        }
        this.store.put(result);
      },
      undo: ({ snapshots }) => {
        this.store.put(Object.values(snapshots));
      },
      squash(prevData, nextData) {
        return {
          // keep the oldest snapshots
          snapshots: { ...nextData.snapshots, ...prevData.snapshots },
          // keep the newest updates
          updates: { ...prevData.updates, ...nextData.updates }
        };
      }
    }
  );
  /** @internal */
  _getUnlockedShapeIds(ids) {
    return ids.filter((id) => !this.getShape(id)?.isLocked);
  }
  deleteShapes(_ids) {
    if (!Array.isArray(_ids)) {
      throw Error("Editor.deleteShapes: must provide an array of shapes or shapeIds");
    }
    this._deleteShapes(
      this._getUnlockedShapeIds(
        typeof _ids[0] === "string" ? _ids : _ids.map((s) => s.id)
      )
    );
    return this;
  }
  deleteShape(_id) {
    this.deleteShapes([typeof _id === "string" ? _id : _id.id]);
    return this;
  }
  /** @internal */
  _deleteShapes = this.history.createCommand(
    "delete_shapes",
    (ids) => {
      if (this.instanceState.isReadonly)
        return null;
      if (ids.length === 0)
        return null;
      const prevSelectedShapeIds = [...this.currentPageState.selectedShapeIds];
      const allIds = new Set(ids);
      for (const id of ids) {
        this.visitDescendants(id, (childId) => {
          allIds.add(childId);
        });
      }
      const deletedIds = [...allIds];
      const arrowBindings = this._arrowBindingsIndex.value;
      const snapshots = compact(
        deletedIds.flatMap((id) => {
          const shape = this.getShape(id);
          const bindings = arrowBindings[id];
          if (bindings && bindings.length > 0) {
            return bindings.map(({ arrowId }) => this.getShape(arrowId)).concat(shape);
          }
          return shape;
        })
      );
      const postSelectedShapeIds = prevSelectedShapeIds.filter((id) => !allIds.has(id));
      return { data: { deletedIds, snapshots, prevSelectedShapeIds, postSelectedShapeIds } };
    },
    {
      do: ({ deletedIds, postSelectedShapeIds }) => {
        this.store.remove(deletedIds);
        this.store.update(this.currentPageState.id, (state) => ({
          ...state,
          selectedShapeIds: postSelectedShapeIds
        }));
      },
      undo: ({ snapshots, prevSelectedShapeIds }) => {
        this.store.put(snapshots);
        this.store.update(this.currentPageState.id, (state) => ({
          ...state,
          selectedShapeIds: prevSelectedShapeIds
        }));
      }
    }
  );
  /* --------------------- Styles --------------------- */
  /**
   * Get all the current styles among the users selected shapes
   *
   * @internal
   */
  _extractSharedStyles(shape, sharedStyleMap) {
    if (this.isShapeOfType(shape, "group")) {
      const childIds = this._parentIdsToChildIds.value[shape.id];
      if (!childIds)
        return;
      for (let i = 0, n = childIds.length; i < n; i++) {
        this._extractSharedStyles(this.getShape(childIds[i]), sharedStyleMap);
      }
    } else {
      for (const [style, propKey] of this.styleProps[shape.type]) {
        sharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey));
      }
    }
  }
  /**
   * A derived map containing all current styles among the user's selected shapes.
   *
   * @internal
   */
  _selectionSharedStyles = computed(
    "_selectionSharedStyles",
    () => {
      const { selectedShapes } = this;
      const sharedStyles = new SharedStyleMap();
      for (const selectedShape of selectedShapes) {
        this._extractSharedStyles(selectedShape, sharedStyles);
      }
      return sharedStyles;
    }
  );
  /** @internal */
  getStyleForNextShape(style) {
    const value = this.instanceState.stylesForNextShape[style.id];
    return value === void 0 ? style.defaultValue : value;
  }
  getShapeStyleIfExists(shape, style) {
    const styleKey = this.styleProps[shape.type].get(style);
    if (styleKey === void 0)
      return void 0;
    return getOwnProperty(shape.props, styleKey);
  }
  get sharedStyles() {
    if (this.isIn("select") && this.selectedShapeIds.length > 0) {
      return this._selectionSharedStyles.value;
    }
    const currentTool = this.root.current.value;
    const styles = new SharedStyleMap();
    if (currentTool.shapeType) {
      for (const style of this.styleProps[currentTool.shapeType].keys()) {
        styles.applyValue(style, this.getStyleForNextShape(style));
      }
    }
    return styles;
  }
  get sharedOpacity() {
    if (this.isIn("select") && this.selectedShapeIds.length > 0) {
      const shapesToCheck = [];
      const addShape = (shapeId) => {
        const shape = this.getShape(shapeId);
        if (!shape)
          return;
        if (this.isShapeOfType(shape, "group")) {
          for (const childId of this.getSortedChildIdsForParent(shape.id)) {
            addShape(childId);
          }
        } else {
          shapesToCheck.push(shape);
        }
      };
      for (const shapeId of this.selectedShapeIds) {
        addShape(shapeId);
      }
      let opacity = null;
      for (const shape of shapesToCheck) {
        if (opacity === null) {
          opacity = shape.opacity;
        } else if (opacity !== shape.opacity) {
          return { type: "mixed" };
        }
      }
      if (opacity !== null)
        return { type: "shared", value: opacity };
    }
    return { type: "shared", value: this.instanceState.opacityForNextShape };
  }
  /**
   * Set the opacity for the next shapes. This will effect subsequently created shapes.
   *
   * @example
   * ```ts
   * editor.setOpacityForNextShapes(0.5)
   * editor.setOpacityForNextShapes(0.5, { squashing: true })
   * ```
   *
   * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.
   * @param historyOptions - The history options for the change.
   */
  setOpacityForNextShapes(opacity, historyOptions) {
    this.updateInstanceState({ opacityForNextShape: opacity }, historyOptions);
    return this;
  }
  /**
   * Set the current opacity. This will effect any selected shapes.
   *
   * @example
   * ```ts
   * editor.setOpacityForSelectedShapes(0.5)
   * editor.setOpacityForSelectedShapes(0.5, { squashing: true })
   * ```
   *
   * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.
   * @param historyOptions - The history options for the change.
   */
  setOpacityForSelectedShapes(opacity, historyOptions) {
    const { selectedShapes } = this;
    if (selectedShapes.length > 0) {
      const shapesToUpdate = [];
      const addShapeById = (shape) => {
        if (this.isShapeOfType(shape, "group")) {
          const childIds = this.getSortedChildIdsForParent(shape);
          for (const childId of childIds) {
            addShapeById(this.getShape(childId));
          }
        } else {
          shapesToUpdate.push(shape);
        }
      };
      for (const id of selectedShapes) {
        addShapeById(id);
      }
      this.updateShapes(
        shapesToUpdate.map((shape) => {
          return {
            id: shape.id,
            type: shape.type,
            opacity
          };
        }),
        historyOptions
      );
    }
    return this;
  }
  /**
   * Set the value of a {@link @tldraw/tlschema#StyleProp} for the selected shapes.
   *
   * @example
   * ```ts
   * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')
   * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red', { ephemeral: true })
   * ```
   *
   * @param style - The style to set.
   * @param value - The value to set.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  setStyleForNextShapes(style, value, historyOptions) {
    const {
      instanceState: { stylesForNextShape }
    } = this;
    this.updateInstanceState(
      { stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },
      historyOptions
    );
    return this;
  }
  /**
   * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.
   *
   * @example
   * ```ts
   * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')
   * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red', { ephemeral: true })
   * ```
   *
   * @param style - The style to set.
   * @param value - The value to set.
   * @param historyOptions - (optional) The history options for the change.
   *
   * @public
   */
  setStyleForSelectedShapes(style, value, historyOptions) {
    const { selectedShapes } = this;
    if (selectedShapes.length > 0) {
      const updates = [];
      const addShapeById = (shape) => {
        if (this.isShapeOfType(shape, "group")) {
          const childIds = this.getSortedChildIdsForParent(shape.id);
          for (const childId of childIds) {
            addShapeById(this.getShape(childId));
          }
        } else {
          const util = this.getShapeUtil(shape);
          const stylePropKey = this.styleProps[shape.type].get(style);
          if (stylePropKey) {
            const shapePartial = {
              id: shape.id,
              type: shape.type,
              props: { [stylePropKey]: value }
            };
            updates.push({
              util,
              originalShape: shape,
              updatePartial: shapePartial
            });
          }
        }
      };
      for (const shape of selectedShapes) {
        addShapeById(shape);
      }
      this.updateShapes(
        updates.map(({ updatePartial }) => updatePartial),
        historyOptions
      );
    }
    return this;
  }
  /* --------------------- Content -------------------- */
  /** @internal */
  externalAssetContentHandlers = {
    file: null,
    url: null
  };
  /**
   * Register an external content handler. This handler will be called when the editor receives
   * external content of the provided type. For example, the 'image' type handler will be called
   * when a user drops an image onto the canvas.
   *
   * @example
   * ```ts
   * editor.registerExternalAssetHandler('text', myHandler)
   * ```
   *
   * @param type - The type of external content.
   * @param handler - The handler to use for this content type.
   *
   * @public
   */
  registerExternalAssetHandler(type, handler) {
    this.externalAssetContentHandlers[type] = handler;
    return this;
  }
  /**
   * Get an asset for an external asset content type.
   *
   * @example
   * ```ts
   * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })
   * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })
   * ```
   *
   * @param info - Info about the external content.
   * @returns The asset.
   */
  async getAssetForExternalContent(info) {
    return await this.externalAssetContentHandlers[info.type]?.(info);
  }
  /** @internal */
  externalContentHandlers = {
    text: null,
    files: null,
    embed: null,
    "svg-text": null,
    url: null
  };
  /**
   * Register an external content handler. This handler will be called when the editor receives
   * external content of the provided type. For example, the 'image' type handler will be called
   * when a user drops an image onto the canvas.
   *
   * @example
   * ```ts
   * editor.registerExternalContentHandler('text', myHandler)
   * ```
   *
   * @param type - The type of external content.
   * @param handler - The handler to use for this content type.
   *
   * @public
   */
  registerExternalContentHandler(type, handler) {
    this.externalContentHandlers[type] = handler;
    return this;
  }
  /**
   * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.
   *
   * @param info - Info about the external content.
   */
  async putExternalContent(info) {
    return this.externalContentHandlers[info.type]?.(info);
  }
  /**
   * Get content that can be exported for the given shape ids.
   *
   * @param shapes - The shapes (or shape ids) to get content for.
   *
   * @returns The exported content.
   *
   * @public
   */
  getContentFromCurrentPage(shapes) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (!ids)
      return;
    if (ids.length === 0)
      return;
    const pageTransforms = {};
    let shapesForContent = dedupe(
      ids.map((id) => this.getShape(id)).sort(sortByIndex2).flatMap((shape) => {
        const allShapes = [shape];
        this.visitDescendants(shape.id, (descendant) => {
          allShapes.push(this.getShape(descendant));
        });
        return allShapes;
      })
    );
    shapesForContent = shapesForContent.map((shape) => {
      pageTransforms[shape.id] = this.getShapePageTransform(shape.id);
      shape = structuredClone2(shape);
      if (this.isShapeOfType(shape, "arrow")) {
        const startBindingId = shape.props.start.type === "binding" ? shape.props.start.boundShapeId : void 0;
        const endBindingId = shape.props.end.type === "binding" ? shape.props.end.boundShapeId : void 0;
        const info = this.getArrowInfo(shape);
        if (shape.props.start.type === "binding") {
          if (!shapesForContent.some((s) => s.id === startBindingId)) {
            if (info?.isValid) {
              const { x, y } = info.start.point;
              shape.props.start = {
                type: "point",
                x,
                y
              };
            } else {
              const { start } = getArrowTerminalsInArrowSpace(this, shape);
              shape.props.start = {
                type: "point",
                x: start.x,
                y: start.y
              };
            }
          }
        }
        if (shape.props.end.type === "binding") {
          if (!shapesForContent.some((s) => s.id === endBindingId)) {
            if (info?.isValid) {
              const { x, y } = info.end.point;
              shape.props.end = {
                type: "point",
                x,
                y
              };
            } else {
              const { end } = getArrowTerminalsInArrowSpace(this, shape);
              shape.props.end = {
                type: "point",
                x: end.x,
                y: end.y
              };
            }
          }
        }
        const infoAfter = getIsArrowStraight(shape) ? getStraightArrowInfo(this, shape) : getCurvedArrowInfo(this, shape);
        if (info?.isValid && infoAfter?.isValid && !getIsArrowStraight(shape)) {
          const mpA = Vec2d.Med(info.start.handle, info.end.handle);
          const distA = Vec2d.Dist(info.middle, mpA);
          const distB = Vec2d.Dist(infoAfter.middle, mpA);
          if (shape.props.bend < 0) {
            shape.props.bend += distB - distA;
          } else {
            shape.props.bend -= distB - distA;
          }
        }
        return shape;
      }
      return shape;
    });
    const rootShapeIds = [];
    shapesForContent.forEach((shape) => {
      if (shapesForContent.find((s) => s.id === shape.parentId) === void 0) {
        const pageTransform = this.getShapePageTransform(shape.id);
        const pagePoint = pageTransform.point();
        const pageRotation = pageTransform.rotation();
        shape.x = pagePoint.x;
        shape.y = pagePoint.y;
        shape.rotation = pageRotation;
        shape.parentId = this.currentPageId;
        rootShapeIds.push(shape.id);
      }
    });
    const assetsSet = /* @__PURE__ */ new Set();
    shapesForContent.forEach((shape) => {
      if ("assetId" in shape.props) {
        if (shape.props.assetId !== null) {
          assetsSet.add(shape.props.assetId);
        }
      }
    });
    return {
      shapes: shapesForContent,
      rootShapeIds,
      schema: this.store.schema.serialize(),
      assets: compact(Array.from(assetsSet).map((id) => this.getAsset(id)))
    };
  }
  /**
   * Place content into the editor.
   *
   * @param content - The content.
   * @param options - Options for placing the content.
   *
   * @public
   */
  putContentOntoCurrentPage(content, options = {}) {
    if (this.instanceState.isReadonly)
      return this;
    if (!content.schema) {
      throw Error("Could not put content:\ncontent is missing a schema.");
    }
    const { select = false, preserveIds = false, preservePosition = false } = options;
    let { point = void 0 } = options;
    const { currentPageId } = this;
    const { assets, shapes, rootShapeIds } = content;
    const idMap = new Map(shapes.map((shape) => [shape.id, createShapeId()]));
    let pasteParentId = this.currentPageId;
    let lowestDepth = Infinity;
    let lowestAncestors = [];
    for (const shape of this.selectedShapes) {
      if (lowestDepth === 0)
        break;
      const isFrame = this.isShapeOfType(shape, "frame");
      const ancestors = this.getShapeAncestors(shape);
      if (isFrame)
        ancestors.push(shape);
      const depth = isFrame ? ancestors.length + 1 : ancestors.length;
      if (depth < lowestDepth) {
        lowestDepth = depth;
        lowestAncestors = ancestors;
        pasteParentId = isFrame ? shape.id : shape.parentId;
      } else if (depth === lowestDepth) {
        if (lowestAncestors.length !== ancestors.length) {
          throw Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`);
        }
        if (lowestAncestors.length === 0) {
          pasteParentId = currentPageId;
          break;
        } else {
          pasteParentId = currentPageId;
          for (let i = 0; i < lowestAncestors.length; i++) {
            if (ancestors[i] !== lowestAncestors[i])
              break;
            pasteParentId = ancestors[i].id;
          }
        }
      }
    }
    let isDuplicating = false;
    if (!isPageId(pasteParentId)) {
      const parent = this.getShape(pasteParentId);
      if (parent) {
        if (!this.viewportPageBounds.includes(this.getShapePageBounds(parent))) {
          pasteParentId = currentPageId;
        } else {
          if (rootShapeIds.length === 1) {
            const rootShape = shapes.find((s) => s.id === rootShapeIds[0]);
            if (this.isShapeOfType(parent, "frame") && this.isShapeOfType(rootShape, "frame") && rootShape.props.w === parent?.props.w && rootShape.props.h === parent?.props.h) {
              isDuplicating = true;
            }
          }
        }
      } else {
        pasteParentId = currentPageId;
      }
    }
    if (!isDuplicating) {
      isDuplicating = idMap.has(pasteParentId);
    }
    if (isDuplicating) {
      pasteParentId = this.getShape(pasteParentId).parentId;
    }
    let index2 = this.getHighestIndexForParent(pasteParentId);
    const rootShapes = [];
    const newShapes = shapes.map((shape) => {
      let newShape;
      if (preserveIds) {
        newShape = deepCopy(shape);
        idMap.set(shape.id, shape.id);
      } else {
        const id = idMap.get(shape.id);
        newShape = deepCopy({ ...shape, id });
      }
      if (rootShapeIds.includes(shape.id)) {
        newShape.parentId = currentPageId;
        rootShapes.push(newShape);
      }
      if (idMap.has(newShape.parentId)) {
        newShape.parentId = idMap.get(shape.parentId);
      } else {
        rootShapeIds.push(newShape.id);
        newShape.index = index2;
        index2 = getIndexAbove(index2);
      }
      if (this.isShapeOfType(newShape, "arrow")) {
        if (newShape.props.start.type === "binding") {
          const mappedId = idMap.get(newShape.props.start.boundShapeId);
          newShape.props.start = mappedId ? { ...newShape.props.start, boundShapeId: mappedId } : (
            // this shouldn't happen, if you copy an arrow but not it's bound shape it should
            // convert the binding to a point at the time of copying
            {
              type: "point",
              x: 0,
              y: 0
            }
          );
        }
        if (newShape.props.end.type === "binding") {
          const mappedId = idMap.get(newShape.props.end.boundShapeId);
          newShape.props.end = mappedId ? { ...newShape.props.end, boundShapeId: mappedId } : (
            // this shouldn't happen, if you copy an arrow but not it's bound shape it should
            // convert the binding to a point at the time of copying
            {
              type: "point",
              x: 0,
              y: 0
            }
          );
        }
      }
      return newShape;
    });
    if (newShapes.length + this.currentPageShapeIds.size > MAX_SHAPES_PER_PAGE) {
      alertMaxShapes(this);
      return this;
    }
    let assetsToCreate = [];
    if (assets) {
      for (let i = 0; i < assets.length; i++) {
        const asset = assets[i];
        const result = this.store.schema.migratePersistedRecord(asset, content.schema);
        if (result.type === "success") {
          assets[i] = result.value;
        } else {
          throw Error(
            `Could not put content:
could not migrate content for asset:
${asset.id}
${asset.type}
reason:${result.reason}`
          );
        }
      }
      const assetsToUpdate = [];
      assetsToCreate = assets.filter((asset) => !this.store.has(asset.id)).map((asset) => {
        if (asset.type === "image" || asset.type === "video") {
          if (asset.props.src && asset.props.src?.startsWith("data:image")) {
            assetsToUpdate.push(structuredClone2(asset));
            asset.props.src = null;
          } else {
            assetsToUpdate.push(structuredClone2(asset));
          }
        }
        return asset;
      });
      Promise.allSettled(
        assetsToUpdate.map(async (asset) => {
          const file = await dataUrlToFile(
            asset.props.src,
            asset.props.name,
            asset.props.mimeType ?? "image/png"
          );
          const newAsset = await this.getAssetForExternalContent({ type: "file", file });
          if (!newAsset) {
            return null;
          }
          return [asset, newAsset];
        })
      ).then((assets2) => {
        this.updateAssets(
          compact(
            assets2.map(
              (result) => result.status === "fulfilled" && result.value ? { ...result.value[1], id: result.value[0].id } : void 0
            )
          )
        );
      });
    }
    for (let i = 0; i < newShapes.length; i++) {
      const shape = newShapes[i];
      const result = this.store.schema.migratePersistedRecord(shape, content.schema);
      if (result.type === "success") {
        newShapes[i] = result.value;
      } else {
        throw Error(
          `Could not put content:
could not migrate content for shape:
${shape.id}, ${shape.type}
reason:${result.reason}`
        );
      }
    }
    this.batch(() => {
      if (assetsToCreate.length > 0) {
        this.createAssets(assetsToCreate);
      }
      this.createShapes(newShapes);
      if (select) {
        this.select(...rootShapes.map((s) => s.id));
      }
      if (pasteParentId !== currentPageId) {
        this.reparentShapes(
          rootShapes.map((s) => s.id),
          pasteParentId
        );
      }
      const newCreatedShapes = newShapes.map((s) => this.getShape(s.id));
      const bounds = Box2d.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)));
      if (point === void 0) {
        if (!isPageId(pasteParentId)) {
          const shape = this.getShape(pasteParentId);
          point = Matrix2d.applyToPoint(
            this.getShapePageTransform(shape),
            this.getShapeGeometry(shape).bounds.center
          );
        } else {
          const { viewportPageBounds } = this;
          if (preservePosition || viewportPageBounds.includes(Box2d.From(bounds))) {
            point = bounds.center;
          } else {
            point = viewportPageBounds.center;
          }
        }
      }
      if (rootShapes.length === 1) {
        const onlyRoot = rootShapes[0];
        if (this.isShapeOfType(onlyRoot, "frame")) {
          while (this.getShapesAtPoint(point).some(
            (shape) => this.isShapeOfType(shape, "frame") && shape.props.w === onlyRoot.props.w && shape.props.h === onlyRoot.props.h
          )) {
            point.x += bounds.w + 16;
          }
        }
      }
      const pageCenter = Box2d.Common(
        compact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))
      ).center;
      const offset2 = Vec2d.Sub(point, pageCenter);
      this.updateShapes(
        rootShapes.map(({ id }) => {
          const s = this.getShape(id);
          const localRotation = this.getShapeParentTransform(id).decompose().rotation;
          const localDelta = Vec2d.Rot(offset2, -localRotation);
          return { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y };
        })
      );
    });
    return this;
  }
  /**
   * Get an exported SVG of the given shapes.
   *
   * @param ids - The shapes (or shape ids) to export.
   * @param opts - Options for the export.
   *
   * @returns The SVG element.
   *
   * @public
   */
  async getSvg(shapes, opts = {}) {
    const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
    if (ids.length === 0)
      return;
    if (!window.document)
      throw Error("No document");
    const {
      scale = 1,
      background = false,
      padding = SVG_PADDING,
      preserveAspectRatio = false
    } = opts;
    const theme = getDefaultColorTheme({ isDarkMode: this.user.isDarkMode });
    const shapeIdsToInclude = this.getShapeAndDescendantIds(ids);
    const renderingShapes = this.getUnorderedRenderingShapes(false).filter(
      ({ id }) => shapeIdsToInclude.has(id)
    );
    let bbox = null;
    for (const { maskedPageBounds } of renderingShapes) {
      if (!maskedPageBounds)
        continue;
      if (bbox) {
        bbox.union(maskedPageBounds);
      } else {
        bbox = maskedPageBounds.clone();
      }
    }
    if (!bbox)
      return;
    const singleFrameShapeId = ids.length === 1 && this.isShapeOfType(this.getShape(ids[0]), "frame") ? ids[0] : null;
    if (!singleFrameShapeId) {
      bbox.expandBy(padding);
    }
    const w = bbox.width * scale;
    const h = bbox.height * scale;
    const svg = window.document.createElementNS("http://www.w3.org/2000/svg", "svg");
    if (preserveAspectRatio) {
      svg.setAttribute("preserveAspectRatio", preserveAspectRatio);
    }
    svg.setAttribute("direction", "ltr");
    svg.setAttribute("width", w + "");
    svg.setAttribute("height", h + "");
    svg.setAttribute("viewBox", `${bbox.minX} ${bbox.minY} ${bbox.width} ${bbox.height}`);
    svg.setAttribute("stroke-linecap", "round");
    svg.setAttribute("stroke-linejoin", "round");
    if (background) {
      if (singleFrameShapeId) {
        svg.style.setProperty("background", theme.solid);
      } else {
        svg.style.setProperty("background-color", theme.background);
      }
    } else {
      svg.style.setProperty("background-color", "transparent");
    }
    try {
      document.body.focus?.();
    } catch (e) {
    }
    const defs = window.document.createElementNS("http://www.w3.org/2000/svg", "defs");
    svg.append(defs);
    const exportDefPromisesById = /* @__PURE__ */ new Map();
    const exportContext = {
      addExportDef: (def) => {
        if (exportDefPromisesById.has(def.key))
          return;
        const promise = (async () => {
          const elements = await def.getElement();
          if (!elements)
            return;
          const comment = document.createComment(`def: ${def.key}`);
          defs.appendChild(comment);
          for (const element of Array.isArray(elements) ? elements : [elements]) {
            defs.appendChild(element);
          }
        })();
        exportDefPromisesById.set(def.key, promise);
      }
    };
    const unorderedShapeElements = (await Promise.all(
      renderingShapes.map(async ({ id, opacity, index: index2, backgroundIndex }) => {
        if (id === singleFrameShapeId)
          return [];
        const shape = this.getShape(id);
        if (this.isShapeOfType(shape, "group"))
          return [];
        const util = this.getShapeUtil(shape);
        let shapeSvgElement = await util.toSvg?.(shape, exportContext);
        let backgroundSvgElement = await util.toBackgroundSvg?.(shape, exportContext);
        if (shapeSvgElement) {
          const outerElement = document.createElementNS("http://www.w3.org/2000/svg", "g");
          outerElement.appendChild(shapeSvgElement);
          shapeSvgElement = outerElement;
        }
        if (backgroundSvgElement) {
          const outerElement = document.createElementNS("http://www.w3.org/2000/svg", "g");
          outerElement.appendChild(backgroundSvgElement);
          backgroundSvgElement = outerElement;
        }
        if (!shapeSvgElement && !backgroundSvgElement) {
          const bounds = this.getShapePageBounds(shape);
          const elm = window.document.createElementNS("http://www.w3.org/2000/svg", "rect");
          elm.setAttribute("width", bounds.width + "");
          elm.setAttribute("height", bounds.height + "");
          elm.setAttribute("fill", theme.solid);
          elm.setAttribute("stroke", theme.grey.pattern);
          elm.setAttribute("stroke-width", "1");
          shapeSvgElement = elm;
        }
        let pageTransform = this.getShapePageTransform(shape).toCssString();
        if ("scale" in shape.props) {
          if (shape.props.scale !== 1) {
            pageTransform = `${pageTransform} scale(${shape.props.scale}, ${shape.props.scale})`;
          }
        }
        shapeSvgElement?.setAttribute("transform", pageTransform);
        backgroundSvgElement?.setAttribute("transform", pageTransform);
        shapeSvgElement?.setAttribute("opacity", opacity + "");
        backgroundSvgElement?.setAttribute("opacity", opacity + "");
        const pageMask = this.getShapeMask(shape.id);
        if (pageMask) {
          const clipPathEl = document.createElementNS("http://www.w3.org/2000/svg", "clipPath");
          defs.appendChild(clipPathEl);
          const id2 = uniqueId();
          clipPathEl.id = id2;
          const mask = document.createElementNS("http://www.w3.org/2000/svg", "path");
          mask.setAttribute("d", `M${pageMask.map(({ x, y }) => `${x},${y}`).join("L")}Z`);
          clipPathEl.appendChild(mask);
          if (shapeSvgElement) {
            const outerElement = document.createElementNS("http://www.w3.org/2000/svg", "g");
            outerElement.setAttribute("clip-path", `url(#${id2})`);
            outerElement.appendChild(shapeSvgElement);
            shapeSvgElement = outerElement;
          }
          if (backgroundSvgElement) {
            const outerElement = document.createElementNS("http://www.w3.org/2000/svg", "g");
            outerElement.setAttribute("clip-path", `url(#${id2})`);
            outerElement.appendChild(backgroundSvgElement);
            backgroundSvgElement = outerElement;
          }
        }
        const elements = [];
        if (shapeSvgElement) {
          elements.push({ zIndex: index2, element: shapeSvgElement });
        }
        if (backgroundSvgElement) {
          elements.push({ zIndex: backgroundIndex, element: backgroundSvgElement });
        }
        return elements;
      })
    )).flat();
    await Promise.all(exportDefPromisesById.values());
    for (const { element } of unorderedShapeElements.sort((a, b) => a.zIndex - b.zIndex)) {
      svg.appendChild(element);
    }
    return svg;
  }
  /* --------------------- Events --------------------- */
  /**
   * The app's current input state.
   *
   * @public
   */
  inputs = {
    /** The most recent pointer down's position in the current page space. */
    originPagePoint: new Vec2d(),
    /** The most recent pointer down's position in screen space. */
    originScreenPoint: new Vec2d(),
    /** The previous pointer position in the current page space. */
    previousPagePoint: new Vec2d(),
    /** The previous pointer position in screen space. */
    previousScreenPoint: new Vec2d(),
    /** The most recent pointer position in the current page space. */
    currentPagePoint: new Vec2d(),
    /** The most recent pointer position in screen space. */
    currentScreenPoint: new Vec2d(),
    /** A set containing the currently pressed keys. */
    keys: /* @__PURE__ */ new Set(),
    /** A set containing the currently pressed buttons. */
    buttons: /* @__PURE__ */ new Set(),
    /** Whether the input is from a pe. */
    isPen: false,
    /** Whether the shift key is currently pressed. */
    shiftKey: false,
    /** Whether the control or command key is currently pressed. */
    ctrlKey: false,
    /** Whether the alt or option key is currently pressed. */
    altKey: false,
    /** Whether the user is dragging. */
    isDragging: false,
    /** Whether the user is pointing. */
    isPointing: false,
    /** Whether the user is pinching. */
    isPinching: false,
    /** Whether the user is editing. */
    isEditing: false,
    /** Whether the user is panning. */
    isPanning: false,
    /** Velocity of mouse pointer, in pixels per millisecond */
    pointerVelocity: new Vec2d()
  };
  /**
   * Update the input points from a pointer or pinch event.
   *
   * @param info - The event info.
   */
  _updateInputsFromEvent(info) {
    const { previousScreenPoint, previousPagePoint, currentScreenPoint, currentPagePoint } = this.inputs;
    const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID);
    const { x: sx, y: sy, z: sz } = info.point;
    const { x: cx, y: cy, z: cz } = this.camera;
    previousScreenPoint.setTo(currentScreenPoint);
    previousPagePoint.setTo(currentPagePoint);
    currentScreenPoint.set(sx, sy);
    currentPagePoint.set(
      (sx - screenBounds.x) / cz - cx,
      (sy - screenBounds.y) / cz - cy,
      sz ?? 0.5
    );
    this.inputs.isPen = info.type === "pointer" && info.isPen;
    if (info.name === "pointer_down") {
      this.inputs.pointerVelocity.set(0, 0);
    }
    this.store.put([
      {
        id: TLPOINTER_ID,
        typeName: "pointer",
        x: currentPagePoint.x,
        y: currentPagePoint.y,
        lastActivityTimestamp: (
          // If our pointer moved only because we're following some other user, then don't
          // update our last activity timestamp; otherwise, update it to the current timestamp.
          info.type === "pointer" && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE ? this.store.get(TLPOINTER_ID)?.lastActivityTimestamp ?? Date.now() : Date.now()
        ),
        meta: {}
      }
    ]);
  }
  /**
   * Dispatch a cancel event.
   *
   * @example
   * ```ts
   * editor.cancel()
   * ```
   *
   * @public
   */
  cancel() {
    this.dispatch({ type: "misc", name: "cancel" });
    return this;
  }
  /**
   * Dispatch an interrupt event.
   *
   * @example
   * ```ts
   * editor.interrupt()
   * ```
   *
   * @public
   */
  interrupt() {
    this.dispatch({ type: "misc", name: "interrupt" });
    return this;
  }
  /**
   * Dispatch a complete event.
   *
   * @example
   * ```ts
   * editor.complete()
   * ```
   *
   * @public
   */
  complete() {
    this.dispatch({ type: "misc", name: "complete" });
    return this;
  }
  /**
   * A manager for recording multiple click events.
   *
   * @internal
   */
  _clickManager = new ClickManager(this);
  /**
   * Prevent a double click event from firing the next time the user clicks
   *
   * @public
   */
  cancelDoubleClick() {
    this._clickManager.cancelDoubleClickTimeout();
  }
  /**
   * The previous cursor. Used for restoring the cursor after pan events.
   *
   * @internal
   */
  _prevCursor = "default";
  /** @internal */
  _shiftKeyTimeout = -1;
  /** @internal */
  _setShiftKeyTimeout = () => {
    this.inputs.shiftKey = false;
    this.dispatch({
      type: "keyboard",
      name: "key_up",
      key: "Shift",
      shiftKey: this.inputs.shiftKey,
      ctrlKey: this.inputs.ctrlKey,
      altKey: this.inputs.altKey,
      code: "ShiftLeft"
    });
  };
  /** @internal */
  _altKeyTimeout = -1;
  /** @internal */
  _setAltKeyTimeout = () => {
    this.inputs.altKey = false;
    this.dispatch({
      type: "keyboard",
      name: "key_up",
      key: "Alt",
      shiftKey: this.inputs.shiftKey,
      ctrlKey: this.inputs.ctrlKey,
      altKey: this.inputs.altKey,
      code: "AltLeft"
    });
  };
  /** @internal */
  _ctrlKeyTimeout = -1;
  /** @internal */
  _setCtrlKeyTimeout = () => {
    this.inputs.ctrlKey = false;
    this.dispatch({
      type: "keyboard",
      name: "key_up",
      key: "Ctrl",
      shiftKey: this.inputs.shiftKey,
      ctrlKey: this.inputs.ctrlKey,
      altKey: this.inputs.altKey,
      code: "ControlLeft"
    });
  };
  /** @internal */
  _restoreToolId = "select";
  /** @internal */
  _pinchStart = 1;
  /** @internal */
  _didPinch = false;
  /** @internal */
  _selectedShapeIdsAtPointerDown = [];
  /** @internal */
  capturedPointerId = null;
  /**
   * Dispatch an event to the editor.
   *
   * @example
   * ```ts
   * editor.dispatch(myPointerEvent)
   * ```
   *
   * @param info - The event info.
   *
   * @public
   */
  dispatch = (info) => {
    if (this.crashingError)
      return this;
    const { inputs } = this;
    const { type } = info;
    this.batch(() => {
      if (info.type === "misc") {
        if (info.name === "cancel" || info.name === "complete") {
          this.inputs.isDragging = false;
          if (this.inputs.isPanning) {
            this.inputs.isPanning = false;
            this.updateInstanceState({
              cursor: {
                type: this._prevCursor,
                rotation: 0
              }
            });
          }
        }
        this.root.handleEvent(info);
        return;
      }
      if (info.shiftKey) {
        clearInterval(this._shiftKeyTimeout);
        this._shiftKeyTimeout = -1;
        inputs.shiftKey = true;
      } else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {
        this._shiftKeyTimeout = setTimeout(this._setShiftKeyTimeout, 150);
      }
      if (info.altKey) {
        clearInterval(this._altKeyTimeout);
        this._altKeyTimeout = -1;
        inputs.altKey = true;
      } else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {
        this._altKeyTimeout = setTimeout(this._setAltKeyTimeout, 150);
      }
      if (info.ctrlKey) {
        clearInterval(this._ctrlKeyTimeout);
        this._ctrlKeyTimeout = -1;
        inputs.ctrlKey = true;
      } else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {
        this._ctrlKeyTimeout = setTimeout(this._setCtrlKeyTimeout, 150);
      }
      const { originPagePoint, originScreenPoint, currentPagePoint, currentScreenPoint } = inputs;
      if (!inputs.isPointing) {
        inputs.isDragging = false;
      }
      switch (type) {
        case "pinch": {
          if (!this.instanceState.canMoveCamera)
            return;
          this._updateInputsFromEvent(info);
          switch (info.name) {
            case "pinch_start": {
              if (inputs.isPinching)
                return;
              if (!inputs.isEditing) {
                this._pinchStart = this.camera.z;
                if (!this._selectedShapeIdsAtPointerDown.length) {
                  this._selectedShapeIdsAtPointerDown = this.selectedShapeIds;
                }
                this._didPinch = true;
                inputs.isPinching = true;
                this.interrupt();
              }
              return;
            }
            case "pinch": {
              if (!inputs.isPinching)
                return;
              const {
                point: { x, y, z = 1 },
                delta: { x: dx, y: dy }
              } = info;
              const {
                camera: { x: cx, y: cy, z: cz }
              } = this;
              const zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, z));
              this.setCamera({
                x: cx + dx / cz - x / cz + x / zoom,
                y: cy + dy / cz - y / cz + y / zoom,
                z: zoom
              });
              return;
            }
            case "pinch_end": {
              if (!inputs.isPinching)
                return this;
              inputs.isPinching = false;
              const { _selectedShapeIdsAtPointerDown } = this;
              this.setSelectedShapes(this._selectedShapeIdsAtPointerDown, { squashing: true });
              this._selectedShapeIdsAtPointerDown = [];
              if (this._didPinch) {
                this._didPinch = false;
                requestAnimationFrame(() => {
                  if (!this._didPinch) {
                    this.setSelectedShapes(_selectedShapeIdsAtPointerDown, { squashing: true });
                  }
                });
              }
              return;
            }
          }
        }
        case "wheel": {
          if (!this.instanceState.canMoveCamera)
            return;
          if (this.isMenuOpen) {
          } else {
            if (inputs.ctrlKey) {
              const { x, y } = this.inputs.currentScreenPoint;
              const { x: cx, y: cy, z: cz } = this.camera;
              const zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, cz + (info.delta.z ?? 0) * cz));
              this.setCamera({
                x: cx + (x / zoom - x) - (x / cz - x),
                y: cy + (y / zoom - y) - (y / cz - y),
                z: zoom
              });
              return;
            }
            this.pan(info.delta);
            if (!inputs.isDragging && inputs.isPointing && originPagePoint.dist(currentPagePoint) > (this.instanceState.isCoarsePointer ? COARSE_DRAG_DISTANCE : DRAG_DISTANCE) / this.zoomLevel) {
              inputs.isDragging = true;
            }
          }
          break;
        }
        case "pointer": {
          if (inputs.isPinching)
            return;
          this._updateInputsFromEvent(info);
          const { isPen } = info;
          switch (info.name) {
            case "pointer_down": {
              this._selectedShapeIdsAtPointerDown = this.selectedShapeIds;
              if (info.button === 0) {
                this.capturedPointerId = info.pointerId;
              }
              inputs.buttons.add(info.button);
              inputs.isPointing = true;
              inputs.isDragging = false;
              if (this.instanceState.isPenMode) {
                if (!isPen) {
                  return;
                }
              } else {
                if (isPen) {
                  this.updateInstanceState({ isPenMode: true });
                }
              }
              if (info.button === 5) {
                this._restoreToolId = this.currentToolId;
                this.complete();
                this.setCurrentTool("eraser");
              } else if (info.button === 1) {
                if (!this.inputs.isPanning) {
                  this._prevCursor = this.instanceState.cursor.type;
                }
                this.inputs.isPanning = true;
              }
              if (this.inputs.isPanning) {
                this.stopCameraAnimation();
                this.updateInstanceState({
                  cursor: {
                    type: "grabbing",
                    rotation: 0
                  }
                });
                return this;
              }
              originScreenPoint.setTo(currentScreenPoint);
              originPagePoint.setTo(currentPagePoint);
              break;
            }
            case "pointer_move": {
              if (!isPen && this.instanceState.isPenMode) {
                return;
              }
              if (this.inputs.isPanning && this.inputs.isPointing) {
                const { currentScreenPoint: currentScreenPoint2, previousScreenPoint } = this.inputs;
                this.pan(Vec2d.Sub(currentScreenPoint2, previousScreenPoint));
                return;
              }
              if (!inputs.isDragging && inputs.isPointing && originPagePoint.dist(currentPagePoint) > (this.instanceState.isCoarsePointer ? COARSE_DRAG_DISTANCE : DRAG_DISTANCE) / this.zoomLevel) {
                inputs.isDragging = true;
              }
              break;
            }
            case "pointer_up": {
              inputs.buttons.delete(info.button);
              inputs.isPointing = false;
              inputs.isDragging = false;
              if (this.isMenuOpen) {
                return;
              }
              if (!isPen && this.instanceState.isPenMode) {
                return;
              }
              if (this.capturedPointerId === info.pointerId) {
                this.capturedPointerId = null;
                info.button = 0;
              }
              if (inputs.isPanning) {
                if (info.button === 1) {
                  if (!this.inputs.keys.has(" ")) {
                    inputs.isPanning = false;
                    this.slideCamera({
                      speed: Math.min(2, this.inputs.pointerVelocity.len()),
                      direction: this.inputs.pointerVelocity,
                      friction: CAMERA_SLIDE_FRICTION
                    });
                    this.updateInstanceState({
                      cursor: { type: this._prevCursor, rotation: 0 }
                    });
                  } else {
                    this.slideCamera({
                      speed: Math.min(2, this.inputs.pointerVelocity.len()),
                      direction: this.inputs.pointerVelocity,
                      friction: CAMERA_SLIDE_FRICTION
                    });
                    this.updateInstanceState({
                      cursor: {
                        type: "grab",
                        rotation: 0
                      }
                    });
                  }
                } else if (info.button === 0) {
                  this.slideCamera({
                    speed: Math.min(2, this.inputs.pointerVelocity.len()),
                    direction: this.inputs.pointerVelocity,
                    friction: CAMERA_SLIDE_FRICTION
                  });
                  this.updateInstanceState({
                    cursor: {
                      type: "grab",
                      rotation: 0
                    }
                  });
                }
              } else {
                if (info.button === 5) {
                  this.complete();
                  this.setCurrentTool(this._restoreToolId);
                }
              }
              break;
            }
          }
          break;
        }
        case "keyboard": {
          if (info.key === "ShiftRight")
            info.key = "ShiftLeft";
          if (info.key === "AltRight")
            info.key = "AltLeft";
          if (info.code === "ControlRight")
            info.code = "ControlLeft";
          switch (info.name) {
            case "key_down": {
              inputs.keys.add(info.code);
              if (!info.ctrlKey && info.code === "Space") {
                if (!this.inputs.isPanning) {
                  this._prevCursor = this.instanceState.cursor.type;
                }
                this.inputs.isPanning = true;
                this.updateInstanceState({
                  cursor: { type: this.inputs.isPointing ? "grabbing" : "grab", rotation: 0 }
                });
              }
              break;
            }
            case "key_up": {
              inputs.keys.delete(info.code);
              if (info.code === "Space" && !this.inputs.buttons.has(1)) {
                this.inputs.isPanning = false;
                this.updateInstanceState({
                  cursor: { type: this._prevCursor, rotation: 0 }
                });
              }
              break;
            }
            case "key_repeat": {
              break;
            }
          }
          break;
        }
      }
      if (info.type === "pointer") {
        if (info.button === 1) {
          info.name = "middle_click";
        } else if (info.button === 2) {
          info.name = "right_click";
        }
        if (info.isPen === this.instanceState.isPenMode) {
          switch (info.name) {
            case "pointer_down": {
              const otherEvent = this._clickManager.transformPointerDownEvent(info);
              if (info.name !== otherEvent.name) {
                this.root.handleEvent(info);
                this.emit("event", info);
                this.root.handleEvent(otherEvent);
                this.emit("event", otherEvent);
                return;
              }
              break;
            }
            case "pointer_up": {
              const otherEvent = this._clickManager.transformPointerUpEvent(info);
              if (info.name !== otherEvent.name) {
                this.root.handleEvent(info);
                this.emit("event", info);
                this.root.handleEvent(otherEvent);
                this.emit("event", otherEvent);
                return;
              }
              break;
            }
            case "pointer_move": {
              this._clickManager.handleMove();
              break;
            }
          }
        }
      }
      this.root.handleEvent(info);
      this.emit("event", info);
    });
    return this;
  };
};
__decorateClass4([
  computed
], Editor.prototype, "canUndo", 1);
__decorateClass4([
  computed
], Editor.prototype, "canRedo", 1);
__decorateClass4([
  computed
], Editor.prototype, "_arrowBindingsIndex", 1);
__decorateClass4([
  computed
], Editor.prototype, "arrowInfoCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "currentTool", 1);
__decorateClass4([
  computed
], Editor.prototype, "currentToolId", 1);
__decorateClass4([
  computed
], Editor.prototype, "documentSettings", 1);
__decorateClass4([
  computed
], Editor.prototype, "instanceState", 1);
__decorateClass4([
  computed
], Editor.prototype, "openMenus", 1);
__decorateClass4([
  computed
], Editor.prototype, "isMenuOpen", 1);
__decorateClass4([
  computed
], Editor.prototype, "pageStates", 1);
__decorateClass4([
  computed
], Editor.prototype, "_pageStates", 1);
__decorateClass4([
  computed
], Editor.prototype, "currentPageState", 1);
__decorateClass4([
  computed
], Editor.prototype, "_currentPageStateId", 1);
__decorateClass4([
  computed
], Editor.prototype, "selectedShapeIds", 1);
__decorateClass4([
  computed
], Editor.prototype, "selectedShapes", 1);
__decorateClass4([
  computed
], Editor.prototype, "onlySelectedShape", 1);
__decorateClass4([
  computed
], Editor.prototype, "selectionPageBounds", 1);
__decorateClass4([
  computed
], Editor.prototype, "selectionRotation", 1);
__decorateClass4([
  computed
], Editor.prototype, "selectionRotatedPageBounds", 1);
__decorateClass4([
  computed
], Editor.prototype, "focusedGroupId", 1);
__decorateClass4([
  computed
], Editor.prototype, "focusedGroup", 1);
__decorateClass4([
  computed
], Editor.prototype, "editingShapeId", 1);
__decorateClass4([
  computed
], Editor.prototype, "editingShape", 1);
__decorateClass4([
  computed
], Editor.prototype, "hoveredShapeId", 1);
__decorateClass4([
  computed
], Editor.prototype, "hoveredShape", 1);
__decorateClass4([
  computed
], Editor.prototype, "hintingShapeIds", 1);
__decorateClass4([
  computed
], Editor.prototype, "hintingShapes", 1);
__decorateClass4([
  computed
], Editor.prototype, "erasingShapeIds", 1);
__decorateClass4([
  computed
], Editor.prototype, "erasingShapes", 1);
__decorateClass4([
  computed
], Editor.prototype, "cameraId", 1);
__decorateClass4([
  computed
], Editor.prototype, "camera", 1);
__decorateClass4([
  computed
], Editor.prototype, "zoomLevel", 1);
__decorateClass4([
  computed
], Editor.prototype, "viewportScreenBounds", 1);
__decorateClass4([
  computed
], Editor.prototype, "viewportScreenCenter", 1);
__decorateClass4([
  computed
], Editor.prototype, "viewportPageBounds", 1);
__decorateClass4([
  computed
], Editor.prototype, "viewportPageCenter", 1);
__decorateClass4([
  computed
], Editor.prototype, "cameraState", 1);
__decorateClass4([
  computed
], Editor.prototype, "renderingShapes", 1);
__decorateClass4([
  computed
], Editor.prototype, "renderingBounds", 1);
__decorateClass4([
  computed
], Editor.prototype, "renderingBoundsExpanded", 1);
__decorateClass4([
  computed
], Editor.prototype, "_pages", 1);
__decorateClass4([
  computed
], Editor.prototype, "pages", 1);
__decorateClass4([
  computed
], Editor.prototype, "_assets", 1);
__decorateClass4([
  computed
], Editor.prototype, "_shapeGeometryCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "_shapeOutlineSegmentsCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "_shapeHandlesCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "_shapePageTransformCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "_shapePageBoundsCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "_shapeClipPathCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "_shapeMaskCache", 1);
__decorateClass4([
  computed
], Editor.prototype, "currentPageBounds", 1);
__decorateClass4([
  computed
], Editor.prototype, "currentPageShapes", 1);
__decorateClass4([
  computed
], Editor.prototype, "currentPageShapesSorted", 1);
__decorateClass4([
  computed
], Editor.prototype, "currentPageRenderingShapesSorted", 1);
__decorateClass4([
  computed({ isEqual: (a, b) => a.equals(b) })
], Editor.prototype, "sharedStyles", 1);
__decorateClass4([
  computed
], Editor.prototype, "sharedOpacity", 1);
function alertMaxShapes(editor, pageId = editor.currentPageId) {
  const name = editor.getPage(pageId).name;
  editor.emit("max-shapes", { name, pageId, count: MAX_SHAPES_PER_PAGE });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useIsDarkMode.mjs
function useIsDarkMode() {
  const editor = useEditor();
  return useValue("isDarkMode", () => editor.user.isDarkMode, [editor]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useCursor.mjs
var DEFAULT_SVG = `<path d="m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" fill="white"/><path d="m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" fill="white"/><path d="m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z" fill="black"/><path d="m13 10.814v11.188l2.969-2.866.428-.139h4.768z" fill="black"/>`;
var POINTER_SVG = `<path d="m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z" fill="white"/><g stroke="black" stroke-linecap="round" stroke-width=".75"><path d="m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z" stroke-linejoin="round"/><path d="m21.5664 21.7344v-3.459"/><path d="m19.5508 21.7461-.016-3.473"/><path d="m17.5547 18.3047.021 3.426"/></g>`;
var CROSS_SVG = `<path d="m25 16h-6.01v-6h-2.98v6h-6.01v3h6.01v6h2.98v-6h6.01z" fill="white"/><path d="m23.9902 17.0103h-6v-6.01h-.98v6.01h-6v.98h6v6.01h.98v-6.01h6z" fill="%23231f1f"/>`;
var MOVE_SVG = `<path d="m19 14h1v1h-1zm1 6h-1v-1h1zm-5-5h-1v-1h1zm0 5h-1v-1h1zm2-10.987-7.985 7.988 5.222 5.221 2.763 2.763 7.984-7.985z" fill="white"/><g fill="black"><path d="m23.5664 16.9971-2.557-2.809v1.829h-4.009-4.001v-1.829l-2.571 2.809 2.572 2.808-.001-1.808h4.001 4.009l-.001 1.808z"/><path d="m17.9873 17h.013v-4.001l1.807.001-2.807-2.571-2.809 2.57h1.809v4.001h.008v4.002l-1.828-.001 2.807 2.577 2.805-2.576h-1.805z"/></g>`;
var CORNER_SVG = `<path d='m19.7432 17.0869-4.072 4.068 2.829 2.828-8.473-.013-.013-8.47 2.841 2.842 4.075-4.068 1.414-1.415-2.844-2.842h8.486v8.484l-2.83-2.827z' fill='%23fff'/><path d='m18.6826 16.7334-4.427 4.424 1.828 1.828-5.056-.016-.014-5.054 1.842 1.841 4.428-4.422 2.474-2.475-1.844-1.843h5.073v5.071l-1.83-1.828z' fill='%23000'/>`;
var EDGE_SVG = `<path d='m9 17.9907v.005l5.997 5.996.001-3.999h1.999 2.02v4l5.98-6.001-5.98-5.999.001 4.019-2.021.002h-2l.001-4.022zm1.411.003 3.587-3.588-.001 2.587h3.5 2.521v-2.585l3.565 3.586-3.564 3.585-.001-2.585h-2.521l-3.499-.001-.001 2.586z' fill='%23fff'/><path d='m17.4971 18.9932h2.521v2.586l3.565-3.586-3.565-3.585v2.605h-2.521-3.5v-2.607l-3.586 3.587 3.586 3.586v-2.587z' fill='%23000'/>`;
var ROTATE_CORNER_SVG = `<path d="M22.4789 9.45728L25.9935 12.9942L22.4789 16.5283V14.1032C18.126 14.1502 14.6071 17.6737 14.5675 22.0283H17.05L13.513 25.543L9.97889 22.0283H12.5674C12.6071 16.5691 17.0214 12.1503 22.4789 12.1031L22.4789 9.45728Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M21.4789 7.03223L27.4035 12.9945L21.4789 18.9521V15.1868C18.4798 15.6549 16.1113 18.0273 15.649 21.0284H19.475L13.5128 26.953L7.55519 21.0284H11.6189C12.1243 15.8155 16.2679 11.6677 21.4789 11.1559L21.4789 7.03223ZM22.4789 12.1031C17.0214 12.1503 12.6071 16.5691 12.5674 22.0284H9.97889L13.513 25.543L17.05 22.0284H14.5675C14.5705 21.6896 14.5947 21.3558 14.6386 21.0284C15.1157 17.4741 17.9266 14.6592 21.4789 14.1761C21.8063 14.1316 22.1401 14.1069 22.4789 14.1032V16.5284L25.9935 12.9942L22.4789 9.45729L22.4789 12.1031Z" fill="white"/>`;
var TEXT_SVG = `<path fill="white" d="M7.94 0a5.25 5.25 0 0 0-3.47 1.17A5.27 5.27 0 0 0 1 0H0v3h1c1.41 0 1.85.7 2 1v3.94H2v3h1v3c-.13.3-.57 1-2 1H0v3h1a5.27 5.27 0 0 0 3.47-1.17c.98.8 2.21 1.21 3.47 1.17h1v-3h-1c-1.41 0-1.85-.7-2-1v-3H7v-3H6V4c.13-.3.57-1 2-1h1V0H7.94z"/><path fill="black" d="M7.94 2V1a4 4 0 0 0-3.47 1.64A4 4 0 0 0 1 1v1c1.3-.17 2.56.6 3 1.84v5.1H3v1h1v4.16c-.45 1.24-1.7 2-3 1.84v1a4.05 4.05 0 0 0 3.47-1.63 4.05 4.05 0 0 0 3.47 1.63v-1A2.82 2.82 0 0 1 5 14.1V9.93h1v-1H5V3.85A2.81 2.81 0 0 1 7.94 2z"/>`;
var GRABBING_SVG = `<path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042' fill='white'/><g stroke='black' stroke-width='.75'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042z' stroke-linejoin='round'/><path d='m20.5664 19.7344v-3.459' stroke-linecap='round'/><path d='m18.5508 19.7461-.016-3.473' stroke-linecap='round'/><path d='m16.5547 16.3047.021 3.426' stroke-linecap='round'/></g>`;
var GRAB_SVG = `<path d="m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121" fill="white"/><g stroke="black" stroke-linecap="round" stroke-width=".75"><path d="m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121" stroke-linejoin="round"/><path d="m20.5664 21.7344v-3.459"/><path d="m18.5508 21.7461-.016-3.473"/><path d="m16.5547 18.3047.021 3.426"/></g>`;
var ZOOM_IN_SVG = `<path d="m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5" fill="white"/><path d="m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z" stroke="black"/><g fill="black"><path d="m18 14h-2v-2h-2v2h-2v1.98h2v2.02h2v-2.02h2z"/><path d="m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z"/></g>`;
var ZOOM_OUT_SVG = `<path d="m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5" fill="white"/><path d="m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z" stroke="black"/><g fill="black"><path d="m18 16h-5.98v-1.98h5.98z"/><path d="m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z"/></g>`;
function getCursorCss(svg, r, tr, f, color, hotspotX = 16, hotspotY = 16) {
  const a = (-tr - r) * (PI / 180);
  const s = Math.sin(a);
  const c = Math.cos(a);
  const dx = 1 * c - 1 * s;
  const dy = 1 * s + 1 * c;
  return `url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: ${color};'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='${dx}' dy='${dy}' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(${r + tr} 16 16)${f ? ` scale(-1,-1) translate(0, -32)` : ""}' filter='url(%23shadow)'>` + svg.replaceAll(`"`, `'`) + `</g></svg>") ${hotspotX} ${hotspotY}, pointer`;
}
var CURSORS = {
  none: () => "none",
  default: (r, f, c) => getCursorCss(DEFAULT_SVG, r, 0, f, c, 12, 8),
  pointer: (r, f, c) => getCursorCss(POINTER_SVG, r, 0, f, c, 14, 10),
  cross: (r, f, c) => getCursorCss(CROSS_SVG, r, 0, f, c),
  move: (r, f, c) => getCursorCss(MOVE_SVG, r, 0, f, c),
  grab: (r, f, c) => getCursorCss(GRAB_SVG, r, 0, f, c),
  grabbing: (r, f, c) => getCursorCss(GRABBING_SVG, r, 0, f, c),
  text: (r, f, c) => getCursorCss(TEXT_SVG, r, 0, f, c, 4, 10),
  "ew-resize": (r, f, c) => getCursorCss(EDGE_SVG, r, 0, f, c),
  "ns-resize": (r, f, c) => getCursorCss(EDGE_SVG, r, 90, f, c),
  "nesw-resize": (r, f, c) => getCursorCss(CORNER_SVG, r, 0, f, c),
  "nwse-resize": (r, f, c) => getCursorCss(CORNER_SVG, r, 90, f, c),
  "nwse-rotate": (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 0, f, c),
  "nesw-rotate": (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 90, f, c),
  "senw-rotate": (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 180, f, c),
  "swne-rotate": (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 270, f, c),
  "zoom-in": (r, f, c) => getCursorCss(ZOOM_IN_SVG, r, 0, f, c),
  "zoom-out": (r, f, c) => getCursorCss(ZOOM_OUT_SVG, r, 0, f, c)
};
function getCursor(cursor, rotation = 0, color = "black") {
  return CURSORS[cursor](radiansToDegrees(rotation), false, color);
}
var STATIC_CURSORS = ["default", "pointer", "cross", "move", "grab", "grabbing", "text"];
function useCursor() {
  const editor = useEditor();
  const container = useContainer();
  const isDarkMode = useIsDarkMode();
  useQuickReactor(
    "useCursor",
    () => {
      const { type, rotation } = editor.instanceState.cursor;
      if (STATIC_CURSORS.includes(type)) {
        container.style.setProperty("--tl-cursor", `var(--tl-cursor-${type})`);
        return;
      }
      container.style.setProperty(
        "--tl-cursor",
        getCursor(type, rotation, isDarkMode ? "white" : "black")
      );
    },
    [editor, container, isDarkMode]
  );
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDarkMode.mjs
var import_react29 = __toESM(require_react(), 1);
function useDarkMode() {
  const editor = useEditor();
  const container = useContainer();
  const isDarkMode = useIsDarkMode();
  const forceSrgb = useValue(debugFlags.forceSrgb);
  import_react29.default.useEffect(() => {
    if (isDarkMode) {
      container.setAttribute("data-color-mode", "dark");
      container.classList.remove("tl-theme__light");
      container.classList.add("tl-theme__dark");
    } else {
      container.setAttribute("data-color-mode", "light");
      container.classList.remove("tl-theme__dark");
      container.classList.add("tl-theme__light");
    }
    if (forceSrgb) {
      container.classList.add("tl-theme__force-sRGB");
    } else {
      container.classList.remove("tl-theme__force-sRGB");
    }
  }, [editor, container, forceSrgb, isDarkMode]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useEvent.mjs
var import_react30 = __toESM(require_react(), 1);
function useEvent(handler) {
  const handlerRef = (0, import_react30.useRef)();
  (0, import_react30.useLayoutEffect)(() => {
    handlerRef.current = handler;
  });
  (0, import_react30.useDebugValue)(handler);
  return (0, import_react30.useCallback)((...args) => {
    const fn = handlerRef.current;
    assert(fn, "fn does not exist");
    return fn(...args);
  }, []);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useFocusEvents.mjs
var import_react31 = __toESM(require_react(), 1);
function useFocusEvents(autoFocus) {
  const editor = useEditor();
  const container = useContainer();
  (0, import_react31.useLayoutEffect)(() => {
    if (autoFocus) {
      if (!editor.instanceState.isFocused) {
        editor.updateInstanceState({ isFocused: true });
      }
      editor.getContainer().focus();
    } else {
      if (editor.instanceState.isFocused) {
        editor.updateInstanceState({ isFocused: false });
      }
    }
  }, [editor, container, autoFocus]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useForceUpdate.mjs
var import_react32 = __toESM(require_react(), 1);
function useForceUpdate() {
  const [_, ss] = (0, import_react32.useState)(0);
  (0, import_react32.useEffect)(() => ss((s) => s + 1), []);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useLocalStore.mjs
var import_react34 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/config/TLSessionStateSnapshot.mjs
var tabIdKey = "TLDRAW_TAB_ID_v2";
var window2 = globalThis.window;
function iOS() {
  if (!window2)
    return false;
  return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(
    window2.navigator.platform
  ) || // iPad on iOS 13 detection
  window2.navigator.userAgent.includes("Mac") && "ontouchend" in document;
}
var TAB_ID = window2?.[tabIdKey] ?? window2?.sessionStorage[tabIdKey] ?? `TLDRAW_INSTANCE_STATE_V1_` + uniqueId();
if (window2) {
  window2[tabIdKey] = TAB_ID;
  if (iOS()) {
    window2.sessionStorage[tabIdKey] = TAB_ID;
  } else {
    delete window2.sessionStorage[tabIdKey];
  }
}
window2?.addEventListener("beforeunload", () => {
  window2.sessionStorage[tabIdKey] = TAB_ID;
});
var Versions14 = {
  Initial: 0
};
var CURRENT_SESSION_STATE_SNAPSHOT_VERSION = Versions14.Initial;
var sessionStateSnapshotValidator = validation_exports.object({
  version: validation_exports.number,
  currentPageId: pageIdValidator,
  isFocusMode: validation_exports.boolean,
  exportBackground: validation_exports.boolean,
  isDebugMode: validation_exports.boolean,
  isToolLocked: validation_exports.boolean,
  isGridMode: validation_exports.boolean,
  pageStates: validation_exports.arrayOf(
    validation_exports.object({
      pageId: pageIdValidator,
      camera: validation_exports.object({
        x: validation_exports.number,
        y: validation_exports.number,
        z: validation_exports.number
      }),
      selectedShapeIds: validation_exports.arrayOf(shapeIdValidator),
      focusedGroupId: shapeIdValidator.nullable()
    })
  )
});
var sessionStateSnapshotMigrations = defineMigrations({
  currentVersion: CURRENT_SESSION_STATE_SNAPSHOT_VERSION
});
function migrateAndValidateSessionStateSnapshot(state) {
  if (!state || typeof state !== "object") {
    console.warn("Invalid instance state");
    return null;
  }
  if (!("version" in state) || typeof state.version !== "number") {
    console.warn("No version in instance state");
    return null;
  }
  const result = migrate({
    value: state,
    fromVersion: state.version,
    toVersion: CURRENT_SESSION_STATE_SNAPSHOT_VERSION,
    migrations: sessionStateSnapshotMigrations
  });
  if (result.type === "error") {
    console.warn(result.reason);
    return null;
  }
  const value = { ...result.value, version: CURRENT_SESSION_STATE_SNAPSHOT_VERSION };
  try {
    sessionStateSnapshotValidator.validate(value);
  } catch (e) {
    console.warn(e);
    return null;
  }
  return value;
}
function createSessionStateSnapshotSignal(store) {
  const $allPageIds = store.query.ids("page");
  return computed("sessionStateSnapshot", () => {
    const instanceState = store.get(TLINSTANCE_ID);
    if (!instanceState)
      return null;
    const allPageIds = [...$allPageIds.value];
    return {
      version: CURRENT_SESSION_STATE_SNAPSHOT_VERSION,
      currentPageId: instanceState.currentPageId,
      exportBackground: instanceState.exportBackground,
      isFocusMode: instanceState.isFocusMode,
      isDebugMode: instanceState.isDebugMode,
      isToolLocked: instanceState.isToolLocked,
      isGridMode: instanceState.isGridMode,
      pageStates: allPageIds.map((id) => {
        const ps = store.get(InstancePageStateRecordType.createId(id));
        const camera = store.get(CameraRecordType.createId(id));
        return {
          pageId: id,
          camera: {
            x: camera?.x ?? 0,
            y: camera?.y ?? 0,
            z: camera?.z ?? 1
          },
          selectedShapeIds: ps?.selectedShapeIds ?? [],
          focusedGroupId: ps?.focusedGroupId ?? null
        };
      })
    };
  });
}
function loadSessionStateSnapshotIntoStore(store, snapshot) {
  const res = migrateAndValidateSessionStateSnapshot(snapshot);
  if (!res)
    return;
  const allPageStatesAndCameras = store.allRecords().filter((r) => r.typeName === "instance_page_state" || r.typeName === "camera");
  const removeDiff = {
    added: {},
    updated: {},
    removed: {
      ...objectMapFromEntries(allPageStatesAndCameras.map((r) => [r.id, r]))
    }
  };
  if (store.has(TLINSTANCE_ID)) {
    removeDiff.removed[TLINSTANCE_ID] = store.get(TLINSTANCE_ID);
  }
  const addDiff = {
    removed: {},
    updated: {},
    added: {
      [TLINSTANCE_ID]: store.schema.types.instance.create({
        id: TLINSTANCE_ID,
        currentPageId: res.currentPageId,
        isDebugMode: res.isDebugMode,
        isFocusMode: res.isFocusMode,
        isToolLocked: res.isToolLocked,
        isGridMode: res.isGridMode,
        exportBackground: res.exportBackground
      })
    }
  };
  for (const ps of res.pageStates) {
    const cameraId = CameraRecordType.createId(ps.pageId);
    const pageStateId = InstancePageStateRecordType.createId(ps.pageId);
    addDiff.added[cameraId] = CameraRecordType.create({
      id: CameraRecordType.createId(ps.pageId),
      x: ps.camera.x,
      y: ps.camera.y,
      z: ps.camera.z
    });
    addDiff.added[pageStateId] = InstancePageStateRecordType.create({
      id: InstancePageStateRecordType.createId(ps.pageId),
      pageId: ps.pageId,
      selectedShapeIds: ps.selectedShapeIds,
      focusedGroupId: ps.focusedGroupId
    });
  }
  transact(() => {
    store.applyDiff(squashRecordDiffs([removeDiff, addDiff]));
    store.ensureStoreIsUsable();
  });
}
function extractSessionStateFromLegacySnapshot(store) {
  const instanceRecords = [];
  for (const record of Object.values(store)) {
    if (record.typeName?.match(/^(instance.*|pointer|camera)$/)) {
      instanceRecords.push(record);
    }
  }
  const oldInstance = instanceRecords.filter(
    (r) => r.typeName === "instance" && r.id !== TLINSTANCE_ID
  )[0];
  if (!oldInstance)
    return null;
  const result = {
    version: CURRENT_SESSION_STATE_SNAPSHOT_VERSION,
    currentPageId: oldInstance.currentPageId,
    exportBackground: !!oldInstance.exportBackground,
    isFocusMode: !!oldInstance.isFocusMode,
    isDebugMode: !!oldInstance.isDebugMode,
    isToolLocked: !!oldInstance.isToolLocked,
    isGridMode: false,
    pageStates: instanceRecords.filter((r) => r.typeName === "instance_page_state" && r.instanceId === oldInstance.id).map((ps) => {
      const camera = store[ps.cameraId] ?? { x: 0, y: 0, z: 1 };
      return {
        pageId: ps.pageId,
        camera: {
          x: camera.x,
          y: camera.y,
          z: camera.z
        },
        selectedShapeIds: ps.selectedShapeIds,
        focusedGroupId: ps.focusedGroupId
      };
    })
  };
  try {
    sessionStateSnapshotValidator.validate(result);
    return result;
  } catch (e) {
    return null;
  }
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/sync/alerts.mjs
function showCantWriteToIndexDbAlert() {
  window.alert(
    `Oops! We could not save changes to your browser's storage. We now need to reload the page and try again.

Keep seeing this message?
• If you're using tldraw in a private or "incognito" window, try loading tldraw in a regular window or in a different browser.
• If your hard disk is full, try clearing up some space and then reload the page.`
  );
}
function showCantReadFromIndexDbAlert() {
  window.alert(
    `Oops! We could not access your browser's storage—and the app won't work correctly without that. We now need to reload the page and try again.

Keep seeing this message?
• If you're using tldraw in a private or "incognito" window, try loading tldraw in a regular window or in a different browser.`
  );
}

// node_modules/.deno/idb@7.1.1/node_modules/idb/build/wrap-idb-value.js
var instanceOfAny = (object2, constructors) => constructors.some((c) => object2 instanceof c);
var idbProxyableTypes;
var cursorAdvanceMethods;
function getIdbProxyableTypes() {
  return idbProxyableTypes || (idbProxyableTypes = [
    IDBDatabase,
    IDBObjectStore,
    IDBIndex,
    IDBCursor,
    IDBTransaction
  ]);
}
function getCursorAdvanceMethods() {
  return cursorAdvanceMethods || (cursorAdvanceMethods = [
    IDBCursor.prototype.advance,
    IDBCursor.prototype.continue,
    IDBCursor.prototype.continuePrimaryKey
  ]);
}
var cursorRequestMap = /* @__PURE__ */ new WeakMap();
var transactionDoneMap = /* @__PURE__ */ new WeakMap();
var transactionStoreNamesMap = /* @__PURE__ */ new WeakMap();
var transformCache = /* @__PURE__ */ new WeakMap();
var reverseTransformCache = /* @__PURE__ */ new WeakMap();
function promisifyRequest(request) {
  const promise = new Promise((resolve, reject) => {
    const unlisten = () => {
      request.removeEventListener("success", success);
      request.removeEventListener("error", error);
    };
    const success = () => {
      resolve(wrap(request.result));
      unlisten();
    };
    const error = () => {
      reject(request.error);
      unlisten();
    };
    request.addEventListener("success", success);
    request.addEventListener("error", error);
  });
  promise.then((value) => {
    if (value instanceof IDBCursor) {
      cursorRequestMap.set(value, request);
    }
  }).catch(() => {
  });
  reverseTransformCache.set(promise, request);
  return promise;
}
function cacheDonePromiseForTransaction(tx) {
  if (transactionDoneMap.has(tx))
    return;
  const done = new Promise((resolve, reject) => {
    const unlisten = () => {
      tx.removeEventListener("complete", complete);
      tx.removeEventListener("error", error);
      tx.removeEventListener("abort", error);
    };
    const complete = () => {
      resolve();
      unlisten();
    };
    const error = () => {
      reject(tx.error || new DOMException("AbortError", "AbortError"));
      unlisten();
    };
    tx.addEventListener("complete", complete);
    tx.addEventListener("error", error);
    tx.addEventListener("abort", error);
  });
  transactionDoneMap.set(tx, done);
}
var idbProxyTraps = {
  get(target, prop, receiver) {
    if (target instanceof IDBTransaction) {
      if (prop === "done")
        return transactionDoneMap.get(target);
      if (prop === "objectStoreNames") {
        return target.objectStoreNames || transactionStoreNamesMap.get(target);
      }
      if (prop === "store") {
        return receiver.objectStoreNames[1] ? void 0 : receiver.objectStore(receiver.objectStoreNames[0]);
      }
    }
    return wrap(target[prop]);
  },
  set(target, prop, value) {
    target[prop] = value;
    return true;
  },
  has(target, prop) {
    if (target instanceof IDBTransaction && (prop === "done" || prop === "store")) {
      return true;
    }
    return prop in target;
  }
};
function replaceTraps(callback) {
  idbProxyTraps = callback(idbProxyTraps);
}
function wrapFunction(func) {
  if (func === IDBDatabase.prototype.transaction && !("objectStoreNames" in IDBTransaction.prototype)) {
    return function(storeNames, ...args) {
      const tx = func.call(unwrap(this), storeNames, ...args);
      transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);
      return wrap(tx);
    };
  }
  if (getCursorAdvanceMethods().includes(func)) {
    return function(...args) {
      func.apply(unwrap(this), args);
      return wrap(cursorRequestMap.get(this));
    };
  }
  return function(...args) {
    return wrap(func.apply(unwrap(this), args));
  };
}
function transformCachableValue(value) {
  if (typeof value === "function")
    return wrapFunction(value);
  if (value instanceof IDBTransaction)
    cacheDonePromiseForTransaction(value);
  if (instanceOfAny(value, getIdbProxyableTypes()))
    return new Proxy(value, idbProxyTraps);
  return value;
}
function wrap(value) {
  if (value instanceof IDBRequest)
    return promisifyRequest(value);
  if (transformCache.has(value))
    return transformCache.get(value);
  const newValue = transformCachableValue(value);
  if (newValue !== value) {
    transformCache.set(value, newValue);
    reverseTransformCache.set(newValue, value);
  }
  return newValue;
}
var unwrap = (value) => reverseTransformCache.get(value);

// node_modules/.deno/idb@7.1.1/node_modules/idb/build/index.js
function openDB(name, version2, { blocked, upgrade, blocking, terminated } = {}) {
  const request = indexedDB.open(name, version2);
  const openPromise = wrap(request);
  if (upgrade) {
    request.addEventListener("upgradeneeded", (event) => {
      upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
    });
  }
  if (blocked) {
    request.addEventListener("blocked", (event) => blocked(
      // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
      event.oldVersion,
      event.newVersion,
      event
    ));
  }
  openPromise.then((db) => {
    if (terminated)
      db.addEventListener("close", () => terminated());
    if (blocking) {
      db.addEventListener("versionchange", (event) => blocking(event.oldVersion, event.newVersion, event));
    }
  }).catch(() => {
  });
  return openPromise;
}
function deleteDB(name, { blocked } = {}) {
  const request = indexedDB.deleteDatabase(name);
  if (blocked) {
    request.addEventListener("blocked", (event) => blocked(
      // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
      event.oldVersion,
      event
    ));
  }
  return wrap(request).then(() => void 0);
}
var readMethods = ["get", "getKey", "getAll", "getAllKeys", "count"];
var writeMethods = ["put", "add", "delete", "clear"];
var cachedMethods = /* @__PURE__ */ new Map();
function getMethod(target, prop) {
  if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === "string")) {
    return;
  }
  if (cachedMethods.get(prop))
    return cachedMethods.get(prop);
  const targetFuncName = prop.replace(/FromIndex$/, "");
  const useIndex = prop !== targetFuncName;
  const isWrite = writeMethods.includes(targetFuncName);
  if (
    // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
    !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))
  ) {
    return;
  }
  const method = async function(storeName, ...args) {
    const tx = this.transaction(storeName, isWrite ? "readwrite" : "readonly");
    let target2 = tx.store;
    if (useIndex)
      target2 = target2.index(args.shift());
    return (await Promise.all([
      target2[targetFuncName](...args),
      isWrite && tx.done
    ]))[0];
  };
  cachedMethods.set(prop, method);
  return method;
}
replaceTraps((oldTraps) => ({
  ...oldTraps,
  get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
  has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
}));

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/sync/indexedDb.mjs
var STORE_PREFIX = "TLDRAW_DOCUMENT_v2";
var dbNameIndexKey = "TLDRAW_DB_NAME_INDEX_v2";
var Table = {
  Records: "records",
  Schema: "schema",
  SessionState: "session_state"
};
async function withDb(storeId, cb) {
  addDbName(storeId);
  const db = await openDB(storeId, 3, {
    upgrade(database) {
      if (!database.objectStoreNames.contains(Table.Records)) {
        database.createObjectStore(Table.Records);
      }
      if (!database.objectStoreNames.contains(Table.Schema)) {
        database.createObjectStore(Table.Schema);
      }
      if (!database.objectStoreNames.contains(Table.SessionState)) {
        database.createObjectStore(Table.SessionState);
      }
    }
  });
  try {
    return await cb(db);
  } finally {
    db.close();
  }
}
async function loadDataFromStore({
  persistenceKey,
  sessionId,
  didCancel
}) {
  const storeId = STORE_PREFIX + persistenceKey;
  if (!getAllIndexDbNames().includes(storeId))
    return void 0;
  await pruneSessionState({ persistenceKey, didCancel });
  return await withDb(storeId, async (db) => {
    if (didCancel?.())
      return void 0;
    const tx = db.transaction([Table.Records, Table.Schema, Table.SessionState], "readonly");
    const recordsStore = tx.objectStore(Table.Records);
    const schemaStore = tx.objectStore(Table.Schema);
    const sessionStateStore = tx.objectStore(Table.SessionState);
    let sessionStateSnapshot = sessionId ? (await sessionStateStore.get(sessionId))?.snapshot : null;
    if (!sessionStateSnapshot) {
      const all = await sessionStateStore.getAll();
      sessionStateSnapshot = all.sort((a, b) => a.updatedAt - b.updatedAt).pop()?.snapshot;
    }
    const result = {
      records: await recordsStore.getAll(),
      schema: await schemaStore.get(Table.Schema),
      sessionStateSnapshot
    };
    if (didCancel?.()) {
      tx.abort();
      return void 0;
    }
    await tx.done;
    return result;
  });
}
async function storeChangesInIndexedDb({
  persistenceKey,
  schema,
  changes,
  sessionId,
  sessionStateSnapshot,
  didCancel
}) {
  const storeId = STORE_PREFIX + persistenceKey;
  await withDb(storeId, async (db) => {
    const tx = db.transaction([Table.Records, Table.Schema, Table.SessionState], "readwrite");
    const recordsStore = tx.objectStore(Table.Records);
    const schemaStore = tx.objectStore(Table.Schema);
    const sessionStateStore = tx.objectStore(Table.SessionState);
    for (const [id, record] of Object.entries(changes.added)) {
      await recordsStore.put(record, id);
    }
    for (const [_prev, updated] of Object.values(changes.updated)) {
      await recordsStore.put(updated, updated.id);
    }
    for (const id of Object.keys(changes.removed)) {
      await recordsStore.delete(id);
    }
    schemaStore.put(schema.serialize(), Table.Schema);
    if (sessionStateSnapshot && sessionId) {
      sessionStateStore.put(
        {
          snapshot: sessionStateSnapshot,
          updatedAt: Date.now(),
          id: sessionId
        },
        sessionId
      );
    } else if (sessionStateSnapshot || sessionId) {
      console.error("sessionStateSnapshot and instanceId must be provided together");
    }
    if (didCancel?.())
      return tx.abort();
    await tx.done;
  });
}
async function storeSnapshotInIndexedDb({
  persistenceKey,
  schema,
  snapshot,
  sessionId,
  sessionStateSnapshot,
  didCancel
}) {
  const storeId = STORE_PREFIX + persistenceKey;
  await withDb(storeId, async (db) => {
    const tx = db.transaction([Table.Records, Table.Schema, Table.SessionState], "readwrite");
    const recordsStore = tx.objectStore(Table.Records);
    const schemaStore = tx.objectStore(Table.Schema);
    const sessionStateStore = tx.objectStore(Table.SessionState);
    await recordsStore.clear();
    for (const [id, record] of Object.entries(snapshot)) {
      await recordsStore.put(record, id);
    }
    schemaStore.put(schema.serialize(), Table.Schema);
    if (sessionStateSnapshot && sessionId) {
      sessionStateStore.put(
        {
          snapshot: sessionStateSnapshot,
          updatedAt: Date.now(),
          id: sessionId
        },
        sessionId
      );
    } else if (sessionStateSnapshot || sessionId) {
      console.error("sessionStateSnapshot and instanceId must be provided together");
    }
    if (didCancel?.())
      return tx.abort();
    await tx.done;
  });
}
async function pruneSessionState({
  persistenceKey,
  didCancel
}) {
  await withDb(STORE_PREFIX + persistenceKey, async (db) => {
    const tx = db.transaction([Table.SessionState], "readwrite");
    const sessionStateStore = tx.objectStore(Table.SessionState);
    const all = (await sessionStateStore.getAll()).sort((a, b) => a.updatedAt - b.updatedAt);
    if (all.length < 10) {
      await tx.done;
      return;
    }
    const toDelete = all.slice(0, all.length - 10);
    for (const { id } of toDelete) {
      await sessionStateStore.delete(id);
    }
    if (didCancel?.())
      return tx.abort();
    await tx.done;
  });
}
function getAllIndexDbNames() {
  const result = JSON.parse(window?.localStorage.getItem(dbNameIndexKey) || "[]") ?? [];
  if (!Array.isArray(result)) {
    return [];
  }
  return result;
}
function addDbName(name) {
  const all = new Set(getAllIndexDbNames());
  all.add(name);
  window?.localStorage.setItem(dbNameIndexKey, JSON.stringify([...all]));
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs
var PERSIST_THROTTLE_MS = 350;
var PERSIST_RETRY_THROTTLE_MS = 1e4;
var UPDATE_INSTANCE_STATE = Symbol("UPDATE_INSTANCE_STATE");
var msg = (msg2) => msg2;
var BroadcastChannelMock = class {
  onmessage;
  constructor(_name) {
  }
  postMessage(_msg) {
  }
  close() {
  }
};
var BC = typeof BroadcastChannel === "undefined" ? BroadcastChannelMock : BroadcastChannel;
var TLLocalSyncClient = class {
  constructor(store, {
    persistenceKey,
    sessionId = TAB_ID,
    onLoad,
    onLoadError
  }, channel2 = new BC(`tldraw-tab-sync-${persistenceKey}`)) {
    this.store = store;
    this.channel = channel2;
    if (typeof window !== "undefined") {
      ;
      window.tlsync = this;
    }
    this.persistenceKey = persistenceKey;
    this.sessionId = sessionId;
    this.serializedSchema = this.store.schema.serialize();
    this.$sessionStateSnapshot = createSessionStateSnapshotSignal(this.store);
    this.disposables.add(
      // Set up a subscription to changes from the store: When
      // the store changes (and if the change was made by the user)
      // then immediately send the diff to other tabs via postMessage
      // and schedule a persist.
      store.listen(
        ({ changes }) => {
          this.diffQueue.push(changes);
          this.channel.postMessage(
            msg({
              type: "diff",
              storeId: this.store.id,
              changes,
              schema: this.serializedSchema
            })
          );
          this.schedulePersist();
        },
        { source: "user", scope: "document" }
      )
    );
    this.disposables.add(
      store.listen(
        () => {
          this.diffQueue.push(UPDATE_INSTANCE_STATE);
          this.schedulePersist();
        },
        { scope: "session" }
      )
    );
    this.connect(onLoad, onLoadError);
    this.documentTypes = new Set(
      Object.values(this.store.schema.types).filter((t2) => t2.scope === "document").map((t2) => t2.typeName)
    );
  }
  disposables = /* @__PURE__ */ new Set();
  diffQueue = [];
  didDispose = false;
  shouldDoFullDBWrite = true;
  isReloading = false;
  persistenceKey;
  sessionId;
  serializedSchema;
  isDebugging = false;
  documentTypes;
  $sessionStateSnapshot;
  initTime = Date.now();
  debug(...args) {
    if (this.isDebugging) {
      console.debug(...args);
    }
  }
  async connect(onLoad, onLoadError) {
    this.debug("connecting");
    let data;
    try {
      data = await loadDataFromStore({
        persistenceKey: this.persistenceKey,
        sessionId: this.sessionId,
        didCancel: () => this.didDispose
      });
    } catch (error) {
      onLoadError(error);
      showCantReadFromIndexDbAlert();
      if (typeof window !== "undefined") {
        window.location.reload();
      }
      return;
    }
    this.debug("loaded data from store", data, "didDispose", this.didDispose);
    if (this.didDispose)
      return;
    try {
      if (data) {
        const documentSnapshot = Object.fromEntries(data.records.map((r) => [r.id, r]));
        const sessionStateSnapshot = data.sessionStateSnapshot ?? extractSessionStateFromLegacySnapshot(documentSnapshot);
        const migrationResult = this.store.schema.migrateStoreSnapshot({
          store: documentSnapshot,
          schema: data.schema ?? this.store.schema.serializeEarliestVersion()
        });
        if (migrationResult.type === "error") {
          console.error("failed to migrate store", migrationResult);
          onLoadError(new Error(`Failed to migrate store: ${migrationResult.reason}`));
          return;
        }
        this.store.mergeRemoteChanges(() => {
          this.store.put(
            Object.values(migrationResult.value).filter((r) => this.documentTypes.has(r.typeName)),
            "initialize"
          );
        });
        if (sessionStateSnapshot) {
          loadSessionStateSnapshotIntoStore(this.store, sessionStateSnapshot);
        }
      }
      this.channel.onmessage = ({ data: data2 }) => {
        this.debug("got message", data2);
        const msg2 = data2;
        const comparison = compareSchemas(
          this.serializedSchema,
          msg2.schema ?? this.store.schema.serializeEarliestVersion()
        );
        if (comparison === -1) {
          const timeSinceInit = Date.now() - this.initTime;
          if (timeSinceInit < 5e3) {
            onLoadError(new Error("Schema mismatch, please close other tabs and reload the page"));
            return;
          }
          this.debug("reloading");
          this.isReloading = true;
          window?.location?.reload?.();
          return;
        } else if (comparison === 1) {
          this.debug("telling them to reload");
          this.channel.postMessage({ type: "announce", schema: this.serializedSchema });
          this.shouldDoFullDBWrite = true;
          this.persistIfNeeded();
          return;
        }
        if (msg2.type === "diff") {
          this.debug("applying diff");
          transact(() => {
            this.store.mergeRemoteChanges(() => {
              this.store.applyDiff(msg2.changes);
              this.store.ensureStoreIsUsable();
            });
          });
        }
      };
      this.channel.postMessage({ type: "announce", schema: this.serializedSchema });
      this.disposables.add(() => {
        this.channel.close();
      });
      onLoad(this);
    } catch (e) {
      this.debug("error loading data from store", e);
      if (this.didDispose)
        return;
      onLoadError(e);
      return;
    }
  }
  close() {
    this.debug("closing");
    this.didDispose = true;
    this.disposables.forEach((d) => d());
  }
  isPersisting = false;
  didLastWriteError = false;
  scheduledPersistTimeout = null;
  /**
   * Schedule a persist. Persists don't happen immediately: they are throttled to avoid writing too
   * often, and will retry if failed.
   *
   * @internal
   */
  schedulePersist() {
    this.debug("schedulePersist", this.scheduledPersistTimeout);
    if (this.scheduledPersistTimeout)
      return;
    this.scheduledPersistTimeout = setTimeout(
      () => {
        this.scheduledPersistTimeout = null;
        this.persistIfNeeded();
      },
      this.didLastWriteError ? PERSIST_RETRY_THROTTLE_MS : PERSIST_THROTTLE_MS
    );
  }
  /**
   * Persist to IndexedDB only under certain circumstances:
   *
   * - If we're not already persisting
   * - If we're not reloading the page
   * - And we have something to persist (a full db write scheduled or changes in the diff queue)
   *
   * @internal
   */
  persistIfNeeded() {
    this.debug("persistIfNeeded", {
      isPersisting: this.isPersisting,
      isReloading: this.isReloading,
      shouldDoFullDBWrite: this.shouldDoFullDBWrite,
      diffQueueLength: this.diffQueue.length,
      storeIsPossiblyCorrupt: this.store.isPossiblyCorrupted()
    });
    if (this.scheduledPersistTimeout) {
      clearTimeout(this.scheduledPersistTimeout);
      this.scheduledPersistTimeout = null;
    }
    if (this.isPersisting)
      return;
    if (this.isReloading)
      return;
    if (this.store.isPossiblyCorrupted())
      return;
    if (this.shouldDoFullDBWrite || this.diffQueue.length > 0) {
      this.doPersist();
    }
  }
  /**
   * Actually persist to IndexedDB. If the write fails, then we'll retry with a full db write after
   * a short delay.
   */
  async doPersist() {
    assert(!this.isPersisting, "persist already in progress");
    this.isPersisting = true;
    this.debug("doPersist start");
    const diffQueue = this.diffQueue;
    this.diffQueue = [];
    try {
      if (this.shouldDoFullDBWrite) {
        this.shouldDoFullDBWrite = false;
        await storeSnapshotInIndexedDb({
          persistenceKey: this.persistenceKey,
          schema: this.store.schema,
          snapshot: this.store.serialize(),
          didCancel: () => this.didDispose,
          sessionId: this.sessionId,
          sessionStateSnapshot: this.$sessionStateSnapshot.value
        });
      } else {
        const diffs = squashRecordDiffs(
          diffQueue.filter((d) => d !== UPDATE_INSTANCE_STATE)
        );
        await storeChangesInIndexedDb({
          persistenceKey: this.persistenceKey,
          changes: diffs,
          schema: this.store.schema,
          didCancel: () => this.didDispose,
          sessionId: this.sessionId,
          sessionStateSnapshot: this.$sessionStateSnapshot.value
        });
      }
      this.didLastWriteError = false;
    } catch (e) {
      this.shouldDoFullDBWrite = true;
      this.didLastWriteError = true;
      console.error("failed to store changes in indexed db", e);
      showCantWriteToIndexDbAlert();
      if (typeof window !== "undefined") {
        window.location.reload();
      }
    }
    this.isPersisting = false;
    this.debug("doPersist end");
    this.schedulePersist();
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useTLStore.mjs
var import_react33 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/config/createTLStore.mjs
function createTLStore({ initialData, defaultName = "", ...rest }) {
  const schema = "schema" in rest && rest.schema ? (
    // we have a schema
    rest.schema
  ) : (
    // we need a schema
    createTLSchema({
      shapes: currentPageShapesToShapeMap(
        checkShapesAndAddCore("shapeUtils" in rest && rest.shapeUtils ? rest.shapeUtils : [])
      )
    })
  );
  return new Store({
    schema,
    initialData,
    props: {
      defaultName
    }
  });
}
function currentPageShapesToShapeMap(shapeUtils) {
  return Object.fromEntries(
    shapeUtils.map((s) => [
      s.type,
      {
        props: s.props,
        migrations: s.migrations
      }
    ])
  );
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useTLStore.mjs
function useTLStore(opts) {
  const [store, setStore] = (0, import_react33.useState)(() => {
    const store2 = createTLStore(opts);
    if (opts.snapshot) {
      store2.loadSnapshot(opts.snapshot);
    }
    return store2;
  });
  const ref = (0, import_react33.useRef)(opts);
  (0, import_react33.useEffect)(() => void (ref.current = opts));
  if (
    // shallow equality check
    Object.keys(ref.current).some(
      (key) => ref.current[key] !== opts[key]
    )
  ) {
    const newStore = createTLStore(opts);
    if (opts.snapshot) {
      newStore.loadSnapshot(opts.snapshot);
    }
    setStore(newStore);
    return newStore;
  }
  return store;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useLocalStore.mjs
function useLocalStore({
  persistenceKey,
  sessionId,
  ...rest
}) {
  const [state, setState] = (0, import_react34.useState)(
    null
  );
  const store = useTLStore(rest);
  (0, import_react34.useEffect)(() => {
    const id = uniqueId();
    if (!persistenceKey) {
      setState({
        id,
        storeWithStatus: { status: "not-synced", store }
      });
      return;
    }
    setState({
      id,
      storeWithStatus: { status: "loading" }
    });
    const setStoreWithStatus = (storeWithStatus) => {
      setState((prev) => {
        if (prev?.id === id) {
          return { id, storeWithStatus };
        }
        return prev;
      });
    };
    const client = new TLLocalSyncClient(store, {
      sessionId,
      persistenceKey,
      onLoad() {
        setStoreWithStatus({ store, status: "synced-local" });
      },
      onLoadError(err) {
        setStoreWithStatus({ status: "error", error: err });
      }
    });
    return () => {
      setState((prevState) => prevState?.id === id ? null : prevState);
      client.close();
    };
  }, [persistenceKey, store, sessionId]);
  return state?.storeWithStatus ?? { status: "loading" };
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useSafariFocusOutFix.mjs
var React14 = __toESM(require_react(), 1);
var isMobileSafari = false;
if (typeof window !== "undefined") {
  const ua = window.navigator.userAgent;
  const iOS2 = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
  const webkit = !!ua.match(/WebKit/i);
  isMobileSafari = iOS2 && webkit && !ua.match(/CriOS/i);
}
function useSafariFocusOutFix() {
  const editor = useEditor();
  React14.useEffect(() => {
    if (!isMobileSafari)
      return;
    function handleFocusOut(e) {
      if (e.target instanceof HTMLInputElement && e.target.type === "text" || e.target instanceof HTMLTextAreaElement) {
        editor.complete();
      }
    }
    document.addEventListener("focusout", handleFocusOut);
    return () => document.removeEventListener("focusout", handleFocusOut);
  }, [editor]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useZoomCss.mjs
var React15 = __toESM(require_react(), 1);
function useZoomCss() {
  const editor = useEditor();
  const container = useContainer();
  React15.useEffect(() => {
    const setScale = (s) => container.style.setProperty("--tl-zoom", s.toString());
    const setScaleDebounced = debounce(setScale, 100);
    const scheduler = new EffectScheduler("useZoomCss", () => {
      const numShapes = editor.currentPageShapeIds.size;
      if (numShapes < 300) {
        setScale(editor.zoomLevel);
      } else {
        setScaleDebounced(editor.zoomLevel);
      }
    });
    scheduler.attach();
    scheduler.execute();
    return () => {
      scheduler.detach();
    };
  }, [editor, container]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/TldrawEditor.mjs
var EMPTY_SHAPE_UTILS_ARRAY = [];
var EMPTY_TOOLS_ARRAY = [];
var TldrawEditor = (0, import_react35.memo)(function TldrawEditor2({
  store,
  components,
  className,
  user: _user,
  ...rest
}) {
  const [container, rContainer] = import_react35.default.useState(null);
  const user = (0, import_react35.useMemo)(() => _user ?? createTLUser(), [_user]);
  const ErrorFallback = components?.ErrorFallback === void 0 ? DefaultErrorFallback : components?.ErrorFallback;
  const withDefaults = {
    ...rest,
    shapeUtils: rest.shapeUtils ?? EMPTY_SHAPE_UTILS_ARRAY,
    tools: rest.tools ?? EMPTY_TOOLS_ARRAY
  };
  return (0, import_jsx_runtime28.jsx)(
    "div",
    {
      ref: rContainer,
      draggable: false,
      className: (0, import_classnames10.default)("tl-container tl-theme__light", className),
      onPointerDown: stopEventPropagation,
      tabIndex: -1,
      children: (0, import_jsx_runtime28.jsx)(
        OptionalErrorBoundary,
        {
          fallback: ErrorFallback,
          onError: (error) => annotateError(error, { tags: { origin: "react.tldraw-before-app" } }),
          children: container && (0, import_jsx_runtime28.jsx)(ContainerProvider, { container, children: (0, import_jsx_runtime28.jsx)(EditorComponentsProvider, { overrides: components, children: store ? store instanceof Store ? (
            // Store is ready to go, whether externally synced or not
            (0, import_jsx_runtime28.jsx)(TldrawEditorWithReadyStore, { ...withDefaults, store, user })
          ) : (
            // Store is a synced store, so handle syncing stages internally
            (0, import_jsx_runtime28.jsx)(TldrawEditorWithLoadingStore, { ...withDefaults, store, user })
          ) : (
            // We have no store (it's undefined) so create one and possibly sync it
            (0, import_jsx_runtime28.jsx)(TldrawEditorWithOwnStore, { ...withDefaults, store, user })
          ) }) })
        }
      )
    }
  );
});
function TldrawEditorWithOwnStore(props) {
  const { defaultName, snapshot, initialData, shapeUtils, persistenceKey, sessionId, user } = props;
  const syncedStore = useLocalStore({
    shapeUtils,
    initialData,
    persistenceKey,
    sessionId,
    defaultName,
    snapshot
  });
  return (0, import_jsx_runtime28.jsx)(TldrawEditorWithLoadingStore, { ...props, store: syncedStore, user });
}
var TldrawEditorWithLoadingStore = (0, import_react35.memo)(function TldrawEditorBeforeLoading({
  store,
  user,
  ...rest
}) {
  const container = useContainer();
  (0, import_react35.useLayoutEffect)(() => {
    if (user.userPreferences.value.isDarkMode) {
      container.classList.remove("tl-theme__light");
      container.classList.add("tl-theme__dark");
    }
  }, [container, user.userPreferences.value.isDarkMode]);
  switch (store.status) {
    case "error": {
      throw store.error;
    }
    case "loading": {
      return (0, import_jsx_runtime28.jsx)(LoadingScreen, { children: "Connecting..." });
    }
    case "not-synced": {
      break;
    }
    case "synced-local": {
      break;
    }
    case "synced-remote": {
      break;
    }
  }
  return (0, import_jsx_runtime28.jsx)(TldrawEditorWithReadyStore, { ...rest, store: store.store, user });
});
function TldrawEditorWithReadyStore({
  onMount,
  children,
  store,
  tools,
  shapeUtils,
  user,
  initialState: initialState2,
  autoFocus = true,
  inferDarkMode
}) {
  const { ErrorFallback } = useEditorComponents();
  const container = useContainer();
  const [editor, setEditor] = (0, import_react35.useState)(null);
  (0, import_react35.useLayoutEffect)(() => {
    const editor2 = new Editor({
      store,
      shapeUtils,
      tools,
      getContainer: () => container,
      user,
      initialState: initialState2,
      inferDarkMode
    });
    window.app = editor2;
    window.editor = editor2;
    setEditor(editor2);
    return () => {
      editor2.dispose();
    };
  }, [container, shapeUtils, tools, store, user, initialState2, inferDarkMode]);
  const crashingError = (0, import_react35.useSyncExternalStore)(
    (0, import_react35.useCallback)(
      (onStoreChange) => {
        if (editor) {
          editor.on("crash", onStoreChange);
          return () => editor.off("crash", onStoreChange);
        }
        return () => {
        };
      },
      [editor]
    ),
    () => editor?.crashingError ?? null
  );
  if (!editor) {
    return null;
  }
  return (
    // the top-level tldraw component also renders an error boundary almost
    // identical to this one. the reason we have two is because this one has
    // access to `App`, which means that here we can enrich errors with data
    // from app for reporting, and also still attempt to render the user's
    // document in the event of an error to reassure them that their work is
    // not lost.
    (0, import_jsx_runtime28.jsx)(OptionalErrorBoundary, {
      fallback: ErrorFallback,
      onError: (error) => editor.annotateError(error, { origin: "react.tldraw", willCrashApp: true }),
      children: crashingError ? (0, import_jsx_runtime28.jsx)(Crash, { crashingError }) : (0, import_jsx_runtime28.jsx)(EditorContext.Provider, { value: editor, children: (0, import_jsx_runtime28.jsx)(Layout, { autoFocus, onMount, children }) })
    })
  );
}
function Layout({
  children,
  onMount,
  autoFocus
}) {
  useZoomCss();
  useCursor();
  useDarkMode();
  useSafariFocusOutFix();
  useForceUpdate();
  useFocusEvents(autoFocus);
  useOnMount(onMount);
  useDPRMultiple();
  const editor = useEditor();
  editor.updateViewportScreenBounds();
  return children ?? (0, import_jsx_runtime28.jsx)(Canvas, {});
}
function Crash({ crashingError }) {
  throw crashingError;
}
function LoadingScreen({ children }) {
  const { Spinner: Spinner2 } = useEditorComponents();
  return (0, import_jsx_runtime28.jsxs)("div", { className: "tl-loading", children: [
    Spinner2 ? (0, import_jsx_runtime28.jsx)(Spinner2, {}) : null,
    children
  ] });
}
function ErrorScreen({ children }) {
  return (0, import_jsx_runtime28.jsx)("div", { className: "tl-loading", children });
}
function useOnMount(onMount) {
  const editor = useEditor();
  const onMountEvent = useEvent((editor2) => {
    const teardown = onMount?.(editor2);
    editor2.emit("mount");
    window.tldrawReady = true;
    return teardown;
  });
  import_react35.default.useLayoutEffect(() => {
    if (editor)
      return onMountEvent?.(editor);
  }, [editor, onMountEvent]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/HTMLContainer.mjs
var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
function HTMLContainer({ children, className = "", ...rest }) {
  return (0, import_jsx_runtime29.jsx)("div", { ...rest, className: `tl-html-container ${className}`, children });
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/components/PositionedOnCanvas.mjs
var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
var import_classnames11 = __toESM(require_classnames(), 1);
var import_react36 = __toESM(require_react(), 1);
var PositionedOnCanvas = track(function PositionedOnCanvas2({
  x: offsetX = 0,
  y: offsetY = 0,
  rotation = 0,
  ...rest
}) {
  const editor = useEditor();
  const rContainer = (0, import_react36.useRef)(null);
  (0, import_react36.useLayoutEffect)(() => {
    const { x, y, z } = editor.camera;
    const elm = rContainer.current;
    if (!elm)
      return;
    if (x === void 0)
      return;
    elm.style.transform = `translate(${x}px, ${y}px) scale(${z}) rotate(${rotation}rad) translate(${offsetX}px, ${offsetY}px)`;
  }, [editor.camera, offsetX, offsetY, rotation]);
  return (0, import_jsx_runtime30.jsx)("div", { ref: rContainer, ...rest, className: (0, import_classnames11.default)("tl-positioned", rest.className) });
});

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/shared/resizeBox.mjs
function resizeBox(shape, info, opts = {}) {
  const { newPoint, handle, scaleX, scaleY } = info;
  const { minWidth = 1, maxWidth: maxWidth2 = Infinity, minHeight = 1, maxHeight: maxHeight2 = Infinity } = opts;
  let w = shape.props.w * scaleX;
  let h = shape.props.h * scaleY;
  const offset2 = new Vec2d(0, 0);
  if (w > 0) {
    if (w < minWidth) {
      switch (handle) {
        case "top_left":
        case "left":
        case "bottom_left": {
          offset2.x = w - minWidth;
          break;
        }
        case "top":
        case "bottom": {
          offset2.x = (w - minWidth) / 2;
          break;
        }
        default: {
          offset2.x = 0;
        }
      }
      w = minWidth;
    }
  } else {
    offset2.x = w;
    w = -w;
    if (w < minWidth) {
      switch (handle) {
        case "top_left":
        case "left":
        case "bottom_left": {
          offset2.x = -w;
          break;
        }
        default: {
          offset2.x = -minWidth;
        }
      }
      w = minWidth;
    }
  }
  if (h > 0) {
    if (h < minHeight) {
      switch (handle) {
        case "top_left":
        case "top":
        case "top_right": {
          offset2.y = h - minHeight;
          break;
        }
        case "right":
        case "left": {
          offset2.y = (h - minHeight) / 2;
          break;
        }
        default: {
          offset2.y = 0;
        }
      }
      h = minHeight;
    }
  } else {
    offset2.y = h;
    h = -h;
    if (h < minHeight) {
      switch (handle) {
        case "top_left":
        case "top":
        case "top_right": {
          offset2.y = -h;
          break;
        }
        default: {
          offset2.y = -minHeight;
        }
      }
      h = minHeight;
    }
  }
  const { x, y } = offset2.rot(shape.rotation).add(newPoint);
  return {
    x,
    y,
    props: {
      w: Math.min(maxWidth2, w),
      h: Math.min(maxHeight2, h)
    }
  };
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs
var BaseBoxShapeUtil = class extends ShapeUtil {
  getGeometry(shape) {
    return new Rectangle2d({
      width: shape.props.w,
      height: shape.props.h,
      isFilled: true
    });
  }
  onResize = (shape, info) => {
    return resizeBox(shape, info);
  };
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/shapes/shared/arrow/arrowheads.mjs
function getArrowPoints(info, side, strokeWidth) {
  const PT = side === "end" ? info.end.point : info.start.point;
  const PB = side === "end" ? info.start.point : info.end.point;
  const compareLength = info.isStraight ? Vec2d.Dist(PB, PT) : Math.abs(info.bodyArc.length);
  const length = Math.max(Math.min(compareLength / 5, strokeWidth * 3), strokeWidth);
  let P0;
  if (info.isStraight) {
    P0 = Vec2d.Nudge(PT, PB, length);
  } else {
    const ints = intersectCircleCircle(PT, length, info.handleArc.center, info.handleArc.radius);
    P0 = side === "end" ? info.handleArc.sweepFlag ? ints[0] : ints[1] : info.handleArc.sweepFlag ? ints[1] : ints[0];
  }
  return {
    point: PT,
    int: P0
  };
}
function getArrowhead({ point, int }) {
  const PL = Vec2d.RotWith(int, point, PI / 6);
  const PR = Vec2d.RotWith(int, point, -PI / 6);
  return `M ${PL.x} ${PL.y} L ${point.x} ${point.y} L ${PR.x} ${PR.y}`;
}
function getTriangleHead({ point, int }) {
  const PL = Vec2d.RotWith(int, point, PI / 6);
  const PR = Vec2d.RotWith(int, point, -PI / 6);
  return `M ${PL.x} ${PL.y} L ${point.x} ${point.y} L ${PR.x} ${PR.y} Z`;
}
function getInvertedTriangleHead({ point, int }) {
  const d = Vec2d.Sub(int, point).div(2);
  const PL = Vec2d.Add(point, Vec2d.Rot(d, TAU));
  const PR = Vec2d.Sub(point, Vec2d.Rot(d, TAU));
  return `M ${PL.x} ${PL.y} L ${int.x} ${int.y} L ${PR.x} ${PR.y} Z`;
}
function getDotHead({ point, int }) {
  const A = Vec2d.Lrp(point, int, 0.45);
  const r = Vec2d.Dist(A, point);
  return `M ${A.x - r},${A.y}
  a ${r},${r} 0 1,0 ${r * 2},0
  a ${r},${r} 0 1,0 -${r * 2},0 `;
}
function getDiamondHead({ point, int }) {
  const PB = Vec2d.Lrp(point, int, 0.75);
  const PL = Vec2d.RotWith(PB, point, PI / 4);
  const PR = Vec2d.RotWith(PB, point, -PI / 4);
  const PQ = Vec2d.Lrp(PL, PR, 0.5);
  PQ.add(Vec2d.Sub(PQ, point));
  return `M ${PQ.x} ${PQ.y} L ${PL.x} ${PL.y} ${point.x} ${point.y} L ${PR.x} ${PR.y} Z`;
}
function getSquareHead({ int, point }) {
  const PB = Vec2d.Lrp(point, int, 0.85);
  const d = Vec2d.Sub(PB, point).div(2);
  const PL1 = Vec2d.Add(point, Vec2d.Rot(d, TAU));
  const PR1 = Vec2d.Sub(point, Vec2d.Rot(d, TAU));
  const PL2 = Vec2d.Add(PB, Vec2d.Rot(d, TAU));
  const PR2 = Vec2d.Sub(PB, Vec2d.Rot(d, TAU));
  return `M ${PL1.x} ${PL1.y} L ${PL2.x} ${PL2.y} L ${PR2.x} ${PR2.y} L ${PR1.x} ${PR1.y} Z`;
}
function getBarHead({ int, point }) {
  const d = Vec2d.Sub(int, point).div(2);
  const PL = Vec2d.Add(point, Vec2d.Rot(d, TAU));
  const PR = Vec2d.Sub(point, Vec2d.Rot(d, TAU));
  return `M ${PL.x} ${PL.y} L ${PR.x} ${PR.y}`;
}
function getArrowheadPathForType(info, side, strokeWidth) {
  const type = side === "end" ? info.end.arrowhead : info.start.arrowhead;
  if (type === "none")
    return;
  const points = getArrowPoints(info, side, strokeWidth);
  if (!points)
    return;
  switch (type) {
    case "bar":
      return getBarHead(points);
    case "square":
      return getSquareHead(points);
    case "diamond":
      return getDiamondHead(points);
    case "dot":
      return getDotHead(points);
    case "inverted":
      return getInvertedTriangleHead(points);
    case "arrow":
      return getArrowhead(points);
    case "triangle":
      return getTriangleHead(points);
  }
  return "";
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Idle.mjs
var Idle = class extends StateNode {
  static id = "idle";
  onPointerDown = (info) => {
    this.parent.transition("pointing", info);
  };
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs
var Pointing = class extends StateNode {
  static id = "pointing";
  markId = "";
  wasFocusedOnEnter = false;
  onEnter = () => {
    const { isMenuOpen } = this.editor;
    this.wasFocusedOnEnter = !isMenuOpen;
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      const { originPagePoint } = this.editor.inputs;
      const shapeType = this.parent.shapeType;
      const id = createShapeId();
      this.markId = `creating:${id}`;
      this.editor.mark(this.markId);
      this.editor.createShapes([
        {
          id,
          type: shapeType,
          x: originPagePoint.x,
          y: originPagePoint.y,
          props: {
            w: 1,
            h: 1
          }
        }
      ]).select(id);
      this.editor.setCurrentTool("select.resizing", {
        ...info,
        target: "selection",
        handle: "bottom_right",
        isCreating: true,
        creationCursorOffset: { x: 1, y: 1 },
        onInteractionEnd: this.parent.id
      });
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  onInterrupt = () => {
    this.cancel();
  };
  complete() {
    const { originPagePoint } = this.editor.inputs;
    if (!this.wasFocusedOnEnter) {
      return;
    }
    this.editor.mark(this.markId);
    const shapeType = this.parent.shapeType;
    const id = createShapeId();
    this.editor.mark(this.markId);
    this.editor.createShapes([
      {
        id,
        type: shapeType,
        x: originPagePoint.x,
        y: originPagePoint.y
      }
    ]);
    const shape = this.editor.getShape(id);
    const { w, h } = this.editor.getShapeUtil(shape).getDefaultProps();
    const delta = new Vec2d(w / 2, h / 2);
    const parentTransform = this.editor.getShapeParentTransform(shape);
    if (parentTransform)
      delta.rot(-parentTransform.rotation());
    this.editor.updateShapes([
      {
        id,
        type: shapeType,
        x: shape.x - delta.x,
        y: shape.y - delta.y
      }
    ]);
    this.editor.setSelectedShapes([id]);
    if (this.editor.instanceState.isToolLocked) {
      this.parent.transition("idle", {});
    } else {
      this.editor.setCurrentTool("select.idle");
    }
  }
  cancel() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs
var BaseBoxShapeTool = class extends StateNode {
  static id = "box";
  static initial = "idle";
  static children = () => [Idle, Pointing];
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useIsCropping.mjs
function useIsCropping(shapeId) {
  const editor = useEditor();
  return useValue("isCropping", () => editor.croppingShapeId === shapeId, [editor, shapeId]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useIsEditing.mjs
function useIsEditing(shapeId) {
  const editor = useEditor();
  return useValue("isEditing", () => editor.editingShapeId === shapeId, [editor, shapeId]);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/hooks/useSelectionEvents.mjs
var import_react37 = __toESM(require_react(), 1);
function useSelectionEvents(handle) {
  const editor = useEditor();
  const events = (0, import_react37.useMemo)(
    function selectionEvents() {
      const onPointerDown = (e) => {
        if (e.isKilled)
          return;
        if (e.button === 2) {
          editor.dispatch({
            type: "pointer",
            target: "selection",
            handle,
            name: "right_click",
            ...getPointerInfo(e)
          });
          return;
        }
        if (e.button !== 0)
          return;
        const elm = loopToHtmlElement(e.currentTarget);
        function releaseCapture() {
          elm.removeEventListener("pointerup", releaseCapture);
          releasePointerCapture(elm, e);
        }
        setPointerCapture(elm, e);
        elm.addEventListener("pointerup", releaseCapture);
        editor.dispatch({
          name: "pointer_down",
          type: "pointer",
          target: "selection",
          handle,
          ...getPointerInfo(e)
        });
        stopEventPropagation(e);
      };
      let lastX, lastY;
      function onPointerMove(e) {
        if (e.isKilled)
          return;
        if (e.button !== 0)
          return;
        if (e.clientX === lastX && e.clientY === lastY)
          return;
        lastX = e.clientX;
        lastY = e.clientY;
        editor.dispatch({
          name: "pointer_move",
          type: "pointer",
          target: "selection",
          handle,
          ...getPointerInfo(e)
        });
      }
      const onPointerUp = (e) => {
        if (e.isKilled)
          return;
        if (e.button !== 0)
          return;
        editor.dispatch({
          name: "pointer_up",
          type: "pointer",
          target: "selection",
          handle,
          ...getPointerInfo(e)
        });
      };
      return {
        onPointerDown,
        onPointerMove,
        onPointerUp
      };
    },
    [editor, handle]
  );
  return events;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/geometry-constants.mjs
var SPACING = 20;
var MIN_COUNT = 8;
function getVerticesCountForLength(length, spacing = SPACING) {
  return Math.max(MIN_COUNT, Math.ceil(length / spacing));
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Arc2d.mjs
var Arc2d = class extends Geometry2d {
  _center;
  radius;
  start;
  end;
  measure;
  length;
  angleStart;
  angleEnd;
  constructor(config) {
    super({ ...config, isFilled: false, isClosed: false });
    const { center, radius, sweepFlag, largeArcFlag, start, end } = config;
    if (start.equals(end))
      throw Error(`Arc must have different start and end points.`);
    this.angleStart = Vec2d.Angle(center, start);
    this.angleEnd = Vec2d.Angle(center, end);
    this.measure = getArcMeasure(this.angleStart, this.angleEnd, sweepFlag, largeArcFlag);
    this.length = this.measure * radius;
    this.start = start;
    this.end = end;
    this._center = center;
    this.radius = radius;
  }
  nearestPoint(point) {
    const { _center, measure, radius, angleEnd, angleStart, start: A, end: B } = this;
    const t2 = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point));
    if (t2 <= 0)
      return A;
    if (t2 >= 1)
      return B;
    const P = _center.clone().add(point.clone().sub(_center).uni().mul(radius));
    let distance = Infinity;
    let nearest;
    for (const pt of [A, B, P]) {
      if (point.dist(pt) < distance) {
        nearest = pt;
        distance = point.dist(pt);
      }
    }
    if (!nearest)
      throw Error("nearest point not found");
    return nearest;
  }
  hitTestLineSegment(A, B, _zoom) {
    const { _center, radius, measure, angleStart, angleEnd } = this;
    const intersection = intersectLineSegmentCircle(A, B, _center, radius);
    if (intersection === null)
      return false;
    return intersection.some((p) => {
      const result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p));
      return result >= 0 && result <= 1;
    });
  }
  getVertices() {
    const { _center, measure, length, radius, angleStart } = this;
    const vertices = [];
    for (let i = 0, n = getVerticesCountForLength(Math.abs(length)); i < n + 1; i++) {
      const t2 = i / n * measure;
      const angle = angleStart + t2;
      vertices.push(_center.clone().add(new Vec2d(Math.cos(angle), Math.sin(angle)).mul(radius)));
    }
    return vertices;
  }
};
function getPointInArcT(mAB, A, B, P) {
  let mAP;
  if (Math.abs(mAB) > PI) {
    mAP = shortAngleDist(A, P);
    const mPB = shortAngleDist(P, B);
    if (Math.abs(mAP) < Math.abs(mPB)) {
      return mAP / mAB;
    } else {
      return (mAB - mPB) / mAB;
    }
  } else {
    mAP = shortAngleDist(A, P);
    return mAP / mAB;
  }
}
function getArcMeasure(A, B, sweepFlag, largeArcFlag) {
  const m = 2 * ((B - A) % PI2) % PI2 - (B - A) % PI2;
  if (!largeArcFlag)
    return m;
  return (PI2 - Math.abs(m)) * (sweepFlag ? 1 : -1);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Circle2d.mjs
var Circle2d = class extends Geometry2d {
  constructor(config) {
    super({ isClosed: true, ...config });
    this.config = config;
    const { x = 0, y = 0, radius } = config;
    this.x = x;
    this.y = y;
    this._center = new Vec2d(radius + x, radius + y);
    this.radius = radius;
  }
  _center;
  radius;
  x;
  y;
  getBounds() {
    return new Box2d(this.x, this.y, this.radius * 2, this.radius * 2);
  }
  getVertices() {
    const { _center, radius } = this;
    const perimeter = PI2 * radius;
    const vertices = [];
    for (let i = 0, n = getVerticesCountForLength(perimeter); i < n; i++) {
      const angle = i / n * PI2;
      vertices.push(_center.clone().add(Vec2d.FromAngle(angle).mul(radius)));
    }
    return vertices;
  }
  nearestPoint(point) {
    const { _center, radius } = this;
    if (_center.equals(point))
      return Vec2d.AddXY(_center, radius, 0);
    return _center.clone().add(point.clone().sub(_center).uni().mul(radius));
  }
  hitTestLineSegment(A, B, _zoom) {
    const { _center, radius } = this;
    return intersectLineSegmentCircle(A, B, _center, radius) !== null;
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs
var CubicBezier2d = class extends Polyline2d {
  a;
  b;
  c;
  d;
  constructor(config) {
    const { start: a, cp1: b, cp2: c, end: d } = config;
    super({ ...config, points: [a, d] });
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
  }
  getVertices() {
    const vertices = [];
    const { a, b, c, d } = this;
    for (let i = 0, n = 10; i <= n; i++) {
      const t2 = i / n;
      vertices.push(
        new Vec2d(
          (1 - t2) * (1 - t2) * (1 - t2) * a.x + 3 * ((1 - t2) * (1 - t2)) * t2 * b.x + 3 * (1 - t2) * (t2 * t2) * c.x + t2 * t2 * t2 * d.x,
          (1 - t2) * (1 - t2) * (1 - t2) * a.y + 3 * ((1 - t2) * (1 - t2)) * t2 * b.y + 3 * (1 - t2) * (t2 * t2) * c.y + t2 * t2 * t2 * d.y
        )
      );
    }
    return vertices;
  }
  midPoint() {
    return getAtT(this, 0.5);
  }
  nearestPoint(A) {
    let nearest;
    let dist = Infinity;
    for (const edge of this.segments) {
      const p = edge.nearestPoint(A);
      const d = p.dist(A);
      if (d < dist) {
        nearest = p;
        dist = d;
      }
    }
    if (!nearest)
      throw Error("nearest point not found");
    return nearest;
  }
};
function getAtT(segment, t2) {
  const { a, b, c, d } = segment;
  return new Vec2d(
    (1 - t2) * (1 - t2) * (1 - t2) * a.x + 3 * ((1 - t2) * (1 - t2)) * t2 * b.x + 3 * (1 - t2) * (t2 * t2) * c.x + t2 * t2 * t2 * d.x,
    (1 - t2) * (1 - t2) * (1 - t2) * a.y + 3 * ((1 - t2) * (1 - t2)) * t2 * b.y + 3 * (1 - t2) * (t2 * t2) * c.y + t2 * t2 * t2 * d.y
  );
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs
var CubicSpline2d = class extends Geometry2d {
  points;
  constructor(config) {
    super({ ...config, isClosed: false, isFilled: false });
    const { points } = config;
    this.points = points;
  }
  _segments;
  get segments() {
    if (!this._segments) {
      this._segments = [];
      const { points } = this;
      const len = points.length;
      const last2 = len - 2;
      const k = 1.25;
      for (let i = 0; i < len - 1; i++) {
        const p0 = i === 0 ? points[0] : points[i - 1];
        const p1 = points[i];
        const p2 = points[i + 1];
        const p3 = i === last2 ? p2 : points[i + 2];
        const start = p1, cp1 = i === 0 ? p0 : new Vec2d(p1.x + (p2.x - p0.x) / 6 * k, p1.y + (p2.y - p0.y) / 6 * k), cp2 = i === last2 ? p2 : new Vec2d(p2.x - (p3.x - p1.x) / 6 * k, p2.y - (p3.y - p1.y) / 6 * k), end = p2;
        this._segments.push(new CubicBezier2d({ start, cp1, cp2, end }));
      }
    }
    return this._segments;
  }
  _length;
  get length() {
    if (!this._length) {
      this._length = this.segments.reduce((acc, segment) => acc + segment.length, 0);
    }
    return this._length;
  }
  getVertices() {
    const vertices = this.segments.reduce((acc, segment) => {
      return acc.concat(segment.vertices);
    }, []);
    vertices.push(this.points[this.points.length - 1]);
    return vertices;
  }
  nearestPoint(A) {
    let nearest;
    let dist = Infinity;
    for (const segment of this.segments) {
      const p = segment.nearestPoint(A);
      const d = p.dist(A);
      if (d < dist) {
        nearest = p;
        dist = d;
      }
    }
    if (!nearest)
      throw Error("nearest point not found");
    return nearest;
  }
  hitTestLineSegment(A, B, zoom) {
    return this.segments.some((segment) => segment.hitTestLineSegment(A, B, zoom));
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Ellipse2d.mjs
var Ellipse2d = class extends Geometry2d {
  constructor(config) {
    super({ ...config, isClosed: true });
    this.config = config;
    const { width, height } = config;
    this.w = width;
    this.h = height;
  }
  w;
  h;
  _edges;
  get edges() {
    if (!this._edges) {
      const { vertices } = this;
      this._edges = [];
      for (let i = 0, n = vertices.length; i < n; i++) {
        const start = vertices[i];
        const end = vertices[(i + 1) % n];
        this._edges.push(new Edge2d({ start, end }));
      }
    }
    return this._edges;
  }
  getVertices() {
    const w = Math.max(1, this.w);
    const h = Math.max(1, this.h);
    const cx = w / 2;
    const cy = h / 2;
    const q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2);
    const p = PI * (cx + cy) * (1 + 3 * q / (10 + Math.sqrt(4 - 3 * q)));
    const len = getVerticesCountForLength(p);
    const step = PI2 / len;
    const a = Math.cos(step);
    const b = Math.sin(step);
    let sin = 0;
    let cos = 1;
    let ts = 0;
    let tc = 1;
    const vertices = Array(len);
    for (let i = 0; i < len; i++) {
      vertices[i] = new Vec2d(cx + cx * cos, cy + cy * sin);
      ts = b * cos + a * sin;
      tc = a * cos - b * sin;
      sin = ts;
      cos = tc;
    }
    return vertices;
  }
  nearestPoint(A) {
    let nearest;
    let dist = Infinity;
    for (const edge of this.edges) {
      const p = edge.nearestPoint(A);
      const d = p.dist(A);
      if (d < dist) {
        nearest = p;
        dist = d;
      }
    }
    if (!nearest)
      throw Error("nearest point not found");
    return nearest;
  }
  hitTestLineSegment(A, B, zoom) {
    return this.edges.some((edge) => edge.hitTestLineSegment(A, B, zoom));
  }
  getBounds() {
    return new Box2d(0, 0, this.w, this.h);
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/primitives/geometry/Stadium2d.mjs
var Stadium2d = class extends Ellipse2d {
  constructor(config) {
    super({ ...config });
    this.config = config;
  }
  getVertices() {
    const w = Math.max(1, this.w);
    const h = Math.max(1, this.h);
    const cx = w / 2;
    const cy = h / 2;
    const len = 10;
    const points = Array(len * 2 - 2);
    if (h > w) {
      for (let i = 0; i < len - 1; i++) {
        const t1 = -PI + PI * i / (len - 2);
        const t2 = PI * i / (len - 2);
        points[i] = new Vec2d(cx + cx * Math.cos(t1), cx + cx * Math.sin(t1));
        points[i + (len - 1)] = new Vec2d(cx + cx * Math.cos(t2), h - cx + cx * Math.sin(t2));
      }
    } else {
      for (let i = 0; i < len - 1; i++) {
        const t1 = -TAU + PI * i / (len - 2);
        const t2 = TAU + PI * -i / (len - 2);
        points[i] = new Vec2d(w - cy + cy * Math.cos(t1), h - cy + cy * Math.sin(t1));
        points[i + (len - 1)] = new Vec2d(cy - cy * Math.cos(t2), h - cy + cy * Math.sin(t2));
      }
    }
    return points;
  }
};

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/sync/hardReset.mjs
async function hardReset({ shouldReload = true } = {}) {
  sessionStorage.clear();
  await Promise.all(getAllIndexDbNames().map((db) => deleteDB(db)));
  localStorage.clear();
  if (shouldReload) {
    window.location.reload();
  }
}
if (typeof window !== "undefined") {
  if (true) {
    ;
    window.hardReset = hardReset;
  }
  ;
  window.__tldraw__hardReset = hardReset;
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/lib/utils/window-open.mjs
function openWindow(url, target = "_blank") {
  runtime.openWindow(url, target);
}

// node_modules/.deno/@tldraw+editor@2.0.0-alpha.17/node_modules/@tldraw/editor/dist-esm/index.mjs
var import_at = __toESM(require_at2(), 1);
var import_flat = __toESM(require_flat2(), 1);
var import_flat_map = __toESM(require_flat_map2(), 1);
var import_at2 = __toESM(require_at4(), 1);
var import_replace_all = __toESM(require_replace_all2(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs
var React17 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useAssetUrls.mjs
var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
var import_react38 = __toESM(require_react(), 1);
var AssetUrlsContext = (0, import_react38.createContext)(null);
function AssetUrlsProvider({
  assetUrls,
  children
}) {
  return (0, import_jsx_runtime31.jsx)(AssetUrlsContext.Provider, { value: assetUrls, children });
}
function useAssetUrls() {
  const assetUrls = (0, import_react38.useContext)(AssetUrlsContext);
  if (!assetUrls) {
    throw new Error("useAssetUrls must be used within an AssetUrlsProvider");
  }
  return assetUrls;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs
var DEFAULT_TRANSLATION = {
  "action.convert-to-bookmark": "Convert to Bookmark",
  "action.convert-to-embed": "Convert to Embed",
  "action.open-embed-link": "Open link",
  "action.align-bottom": "Align bottom",
  "action.align-center-horizontal": "Align horizontally",
  "action.align-center-vertical": "Align vertically",
  "action.align-center-horizontal.short": "Align H",
  "action.align-center-vertical.short": "Align V",
  "action.align-left": "Align left",
  "action.align-right": "Align right",
  "action.align-top": "Align top",
  "action.back-to-content": "Back to content",
  "action.bring-forward": "Bring forward",
  "action.bring-to-front": "Bring to front",
  "action.copy-as-json.short": "JSON",
  "action.copy-as-json": "Copy as JSON",
  "action.copy-as-png.short": "PNG",
  "action.copy-as-png": "Copy as PNG",
  "action.copy-as-svg.short": "SVG",
  "action.copy-as-svg": "Copy as SVG",
  "action.copy": "Copy",
  "action.cut": "Cut",
  "action.delete": "Delete",
  "action.unlock-all": "Unlock all",
  "action.distribute-horizontal": "Distribute horizontally",
  "action.distribute-vertical": "Distribute vertically",
  "action.distribute-horizontal.short": "Distribute H",
  "action.distribute-vertical.short": "Distribute V",
  "action.duplicate": "Duplicate",
  "action.edit-link": "Edit link",
  "action.exit-pen-mode": "Exit pen mode",
  "action.export-as-json.short": "JSON",
  "action.export-as-json": "Export as JSON",
  "action.export-as-png.short": "PNG",
  "action.export-as-png": "Export as PNG",
  "action.export-as-svg.short": "SVG",
  "action.export-as-svg": "Export as SVG",
  "action.flip-horizontal": "Flip horizontally",
  "action.flip-vertical": "Flip vertically",
  "action.flip-horizontal.short": "Flip H",
  "action.flip-vertical.short": "Flip V",
  "action.fork-project": "Fork this project",
  "action.group": "Group",
  "action.insert-embed": "Insert embed",
  "action.insert-media": "Upload media",
  "action.leave-shared-project": "Leave shared project",
  "action.new-project": "New project",
  "action.new-shared-project": "New shared project",
  "action.open-cursor-chat": "Cursor chat",
  "action.open-file": "Open file",
  "action.pack": "Pack",
  "action.paste": "Paste",
  "action.print": "Print",
  "action.redo": "Redo",
  "action.rotate-ccw": "Rotate counterclockwise",
  "action.rotate-cw": "Rotate clockwise",
  "action.save-copy": "Save a copy",
  "action.select-all": "Select all",
  "action.select-none": "Select none",
  "action.send-backward": "Send backward",
  "action.send-to-back": "Send to back",
  "action.share-project": "Share this project",
  "action.stack-horizontal": "Stack horizontally",
  "action.stack-vertical": "Stack vertically",
  "action.stack-horizontal.short": "Stack H",
  "action.stack-vertical.short": "Stack V",
  "action.stop-following": "Stop following",
  "action.stretch-horizontal": "Stretch horizontally",
  "action.stretch-vertical": "Stretch vertically",
  "action.stretch-horizontal.short": "Stretch H",
  "action.stretch-vertical.short": "Stretch V",
  "action.toggle-auto-size": "Toggle auto size",
  "action.toggle-dark-mode.menu": "Dark mode",
  "action.toggle-dark-mode": "Toggle dark mode",
  "action.toggle-reduce-motion.menu": "Reduce motion",
  "action.toggle-reduce-motion": "Toggle reduce motion",
  "action.toggle-debug-mode.menu": "Debug mode",
  "action.toggle-debug-mode": "Toggle debug mode",
  "action.toggle-focus-mode.menu": "Focus mode",
  "action.toggle-focus-mode": "Toggle focus mode",
  "action.toggle-grid.menu": "Show grid",
  "action.toggle-grid": "Toggle grid",
  "action.toggle-lock": "Toggle locked",
  "action.toggle-snap-mode.menu": "Always snap",
  "action.toggle-snap-mode": "Toggle always snap",
  "action.toggle-tool-lock.menu": "Tool lock",
  "action.toggle-tool-lock": "Toggle tool lock",
  "action.toggle-transparent.context-menu": "Transparent",
  "action.toggle-transparent.menu": "Transparent",
  "action.toggle-transparent": "Toggle transparent background",
  "action.undo": "Undo",
  "action.ungroup": "Ungroup",
  "action.zoom-in": "Zoom in",
  "action.zoom-out": "Zoom out",
  "action.zoom-to-100": "Zoom to 100%",
  "action.zoom-to-fit": "Zoom to fit",
  "action.zoom-to-selection": "Zoom to selection",
  "color-style.black": "Black",
  "color-style.blue": "Blue",
  "color-style.green": "Green",
  "color-style.grey": "Grey",
  "color-style.light-blue": "Light blue",
  "color-style.light-green": "Light green",
  "color-style.light-red": "Light red",
  "color-style.light-violet": "Light violet",
  "color-style.orange": "Orange",
  "color-style.red": "Red",
  "color-style.violet": "Violet",
  "color-style.yellow": "Yellow",
  "fill-style.none": "None",
  "fill-style.semi": "Semi",
  "fill-style.solid": "Solid",
  "fill-style.pattern": "Pattern",
  "dash-style.dashed": "Dashed",
  "dash-style.dotted": "Dotted",
  "dash-style.draw": "Draw",
  "dash-style.solid": "Solid",
  "size-style.s": "Small",
  "size-style.m": "Medium",
  "size-style.l": "Large",
  "size-style.xl": "Extra large",
  "opacity-style.0.1": "10%",
  "opacity-style.0.25": "25%",
  "opacity-style.0.5": "50%",
  "opacity-style.0.75": "75%",
  "opacity-style.1": "100%",
  "font-style.draw": "Draw",
  "font-style.sans": "Sans",
  "font-style.serif": "Serif",
  "font-style.mono": "Mono",
  "align-style.start": "Start",
  "align-style.middle": "Middle",
  "align-style.end": "End",
  "align-style.justify": "Justify",
  "geo-style.arrow-down": "Arrow down",
  "geo-style.arrow-left": "Arrow left",
  "geo-style.arrow-right": "Arrow right",
  "geo-style.arrow-up": "Arrow up",
  "geo-style.diamond": "Diamond",
  "geo-style.ellipse": "Ellipse",
  "geo-style.hexagon": "Hexagon",
  "geo-style.octagon": "Octagon",
  "geo-style.oval": "Oval",
  "geo-style.cloud": "Cloud",
  "geo-style.pentagon": "Pentagon",
  "geo-style.rectangle": "Rectangle",
  "geo-style.rhombus-2": "Rhombus 2",
  "geo-style.rhombus": "Rhombus",
  "geo-style.star": "Star",
  "geo-style.trapezoid": "Trapezoid",
  "geo-style.triangle": "Triangle",
  "geo-style.x-box": "X box",
  "geo-style.check-box": "Check box",
  "arrowheadStart-style.none": "None",
  "arrowheadStart-style.arrow": "Arrow",
  "arrowheadStart-style.bar": "Bar",
  "arrowheadStart-style.diamond": "Diamond",
  "arrowheadStart-style.dot": "Dot",
  "arrowheadStart-style.inverted": "Inverted",
  "arrowheadStart-style.pipe": "Pipe",
  "arrowheadStart-style.square": "Square",
  "arrowheadStart-style.triangle": "Triangle",
  "arrowheadEnd-style.none": "None",
  "arrowheadEnd-style.arrow": "Arrow",
  "arrowheadEnd-style.bar": "Bar",
  "arrowheadEnd-style.diamond": "Diamond",
  "arrowheadEnd-style.dot": "Dot",
  "arrowheadEnd-style.inverted": "Inverted",
  "arrowheadEnd-style.pipe": "Pipe",
  "arrowheadEnd-style.square": "Square",
  "arrowheadEnd-style.triangle": "Triangle",
  "spline-style.line": "Line",
  "spline-style.cubic": "Cubic",
  "tool.select": "Select",
  "tool.hand": "Hand",
  "tool.draw": "Draw",
  "tool.eraser": "Eraser",
  "tool.arrow-down": "Arrow down",
  "tool.arrow-left": "Arrow left",
  "tool.arrow-right": "Arrow right",
  "tool.arrow-up": "Arrow up",
  "tool.arrow": "Arrow",
  "tool.cloud": "Cloud",
  "tool.diamond": "Diamond",
  "tool.ellipse": "Ellipse",
  "tool.hexagon": "Hexagon",
  "tool.highlight": "Highlight",
  "tool.line": "Line",
  "tool.octagon": "Octagon",
  "tool.oval": "Oval",
  "tool.pentagon": "Pentagon",
  "tool.rectangle": "Rectangle",
  "tool.rhombus": "Rhombus",
  "tool.star": "Star",
  "tool.trapezoid": "Trapezoid",
  "tool.triangle": "Triangle",
  "tool.x-box": "X box",
  "tool.check-box": "Check box",
  "tool.asset": "Asset",
  "tool.frame": "Frame",
  "tool.note": "Note",
  "tool.laser": "Laser",
  "tool.embed": "Embed",
  "tool.text": "Text",
  "menu.title": "Menu",
  "menu.copy-as": "Copy as",
  "menu.edit": "Edit",
  "menu.export-as": "Export as",
  "menu.file": "File",
  "menu.language": "Language",
  "menu.preferences": "Preferences",
  "menu.view": "View",
  "context-menu.arrange": "Arrange",
  "context-menu.copy-as": "Copy as",
  "context-menu.export-as": "Export as",
  "context-menu.move-to-page": "Move to page",
  "context-menu.reorder": "Reorder",
  "page-menu.title": "Pages",
  "page-menu.create-new-page": "Create new page",
  "page-menu.max-page-count-reached": "Max pages reached",
  "page-menu.new-page-initial-name": "Page 1",
  "page-menu.edit-start": "Edit",
  "page-menu.edit-done": "Done",
  "page-menu.go-to-page": "Go to page",
  "page-menu.submenu.rename": "Rename",
  "page-menu.submenu.duplicate-page": "Duplicate",
  "page-menu.submenu.title": "Menu",
  "page-menu.submenu.move-down": "Move down",
  "page-menu.submenu.move-up": "Move up",
  "page-menu.submenu.delete": "Delete",
  "share-menu.title": "Share",
  "share-menu.save-note": "Download this project to your computer as a .tldr file.",
  "share-menu.fork-note": "Create a new shared project based on this snapshot.",
  "share-menu.share-project": "Share this project",
  "share-menu.default-project-name": "Shared Project",
  "share-menu.copy-link": "Copy share link",
  "share-menu.readonly-link": "Read-only",
  "share-menu.create-snapshot-link": "Copy snapshot link",
  "share-menu.snapshot-link-note": "Capture and share this project as a read-only snapshot link.",
  "share-menu.copy-readonly-link": "Copy read-only link",
  "share-menu.offline-note": "Create a new shared project based on your current project.",
  "share-menu.copy-link-note": "Anyone with the link will be able to view and edit this project.",
  "share-menu.copy-readonly-link-note": "Anyone with the link will be able to view (but not edit) this project.",
  "share-menu.project-too-large": "Sorry, this project can't be shared because it's too large. We're working on it!",
  "share-menu.upload-failed": "Sorry, we couldn't upload your project at the moment. Please try again or let us know if the problem persists.",
  "status.offline": "Offline",
  "status.online": "Online",
  "people-menu.title": "People",
  "people-menu.change-name": "Change name",
  "people-menu.change-color": "Change color",
  "people-menu.follow": "Following",
  "people-menu.following": "Following",
  "people-menu.leading": "Following You",
  "people-menu.user": "(You)",
  "people-menu.invite": "Invite others",
  "help-menu.title": "Help and resources",
  "help-menu.about": "About",
  "help-menu.discord": "Discord",
  "help-menu.github": "GitHub",
  "help-menu.keyboard-shortcuts": "Keyboard shortcuts",
  "help-menu.twitter": "Twitter",
  "actions-menu.title": "Actions",
  "edit-link-dialog.title": "Edit link",
  "edit-link-dialog.invalid-url": "A link must be a valid URL.",
  "edit-link-dialog.detail": "Links will open in a new tab.",
  "edit-link-dialog.url": "URL",
  "edit-link-dialog.clear": "Clear",
  "edit-link-dialog.save": "Continue",
  "edit-link-dialog.cancel": "Cancel",
  "embed-dialog.title": "Insert embed",
  "embed-dialog.back": "Back",
  "embed-dialog.create": "Create",
  "embed-dialog.cancel": "Cancel",
  "embed-dialog.url": "URL",
  "embed-dialog.instruction": "Paste in the site's URL to create the embed.",
  "embed-dialog.invalid-url": "We could not create an embed from that URL.",
  "edit-pages-dialog.move-down": "Move down",
  "edit-pages-dialog.move-up": "Move up",
  "shortcuts-dialog.title": "Keyboard shortcuts",
  "shortcuts-dialog.edit": "Edit",
  "shortcuts-dialog.file": "File",
  "shortcuts-dialog.preferences": "Preferences",
  "shortcuts-dialog.tools": "Tools",
  "shortcuts-dialog.transform": "Transform",
  "shortcuts-dialog.view": "View",
  "shortcuts-dialog.collaboration": "Collaboration",
  "home-project-dialog.title": "Home project",
  "home-project-dialog.description": "This is your local home project. It's just for you!",
  "rename-project-dialog.title": "Rename project",
  "rename-project-dialog.cancel": "Cancel",
  "rename-project-dialog.rename": "Rename",
  "home-project-dialog.ok": "Ok",
  "style-panel.title": "Styles",
  "style-panel.align": "Align",
  "style-panel.vertical-align": "Vertical align",
  "style-panel.position": "Position",
  "style-panel.arrowheads": "Arrowheads",
  "style-panel.arrowhead-start": "Start",
  "style-panel.arrowhead-end": "End",
  "style-panel.color": "Color",
  "style-panel.dash": "Dash",
  "style-panel.fill": "Fill",
  "style-panel.font": "Font",
  "style-panel.geo": "Shape",
  "style-panel.mixed": "Mixed",
  "style-panel.opacity": "Opacity",
  "style-panel.size": "Size",
  "style-panel.spline": "Spline",
  "tool-panel.drawing": "Drawing",
  "tool-panel.shapes": "Shapes",
  "tool-panel.more": "More",
  "debug-panel.more": "More",
  "navigation-zone.toggle-minimap": "Toggle minimap",
  "navigation-zone.zoom": "Zoom",
  "focus-mode.toggle-focus-mode": "Toggle focus mode",
  "toast.close": "Close",
  "file-system.file-open-error.title": "Could not open file",
  "file-system.file-open-error.not-a-tldraw-file": "The file you tried to open doesn't look like a tldraw file.",
  "file-system.file-open-error.file-format-version-too-new": "The file you tried to open is from a newer version of tldraw. Please reload the page and try again.",
  "file-system.file-open-error.generic-corrupted-file": "The file you tried to open is corrupted.",
  "file-system.confirm-open.title": "Overwrite current project?",
  "file-system.confirm-open.description": "Opening a file will replace your current project and any unsaved changes will be lost. Are you sure you want to continue?",
  "file-system.confirm-open.cancel": "Cancel",
  "file-system.confirm-open.open": "Open file",
  "file-system.confirm-open.dont-show-again": "Don't ask again",
  "file-system.confirm-clear.title": "Clear current project?",
  "file-system.confirm-clear.description": "Creating a new project will clear your current project and any unsaved changes will be lost. Are you sure you want to continue?",
  "file-system.confirm-clear.cancel": "Cancel",
  "file-system.confirm-clear.continue": "Continue",
  "file-system.confirm-clear.dont-show-again": "Don't ask again",
  "file-system.shared-document-file-open-error.title": "Could not open file",
  "file-system.shared-document-file-open-error.description": "Opening files from shared projects is not supported.",
  "sharing.confirm-leave.title": "Leave current project?",
  "sharing.confirm-leave.description": "Are you sure you want to leave this shared project? You can return to it by navigating to its URL.",
  "sharing.confirm-leave.cancel": "Cancel",
  "sharing.confirm-leave.leave": "Leave",
  "sharing.confirm-leave.dont-show-again": "Don't ask again",
  "toast.error.export-fail.title": "Failed export",
  "toast.error.export-fail.desc": "Failed to export image",
  "toast.error.copy-fail.title": "Failed copy",
  "toast.error.copy-fail.desc": "Failed to copy image",
  "context.pages.new-page": "New page",
  "vscode.file-open.desc": "We've updated this document to work with the current version of tldraw. If you'd like to keep the original version (which will work on old.tldraw.com), click below to create a backup.",
  "vscode.file-open.open": "Continue",
  "vscode.file-open.backup": "Backup",
  "vscode.file-open.backup-saved": "Backup saved",
  "vscode.file-open.backup-failed": "Backup failed: this is not a .tldr file.",
  "vscode.file-open.dont-show-again": "Don't ask again",
  "cursor-chat.type-to-chat": "Type to chat..."
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useTranslation/translations.mjs
var EN_TRANSLATION = {
  locale: "en",
  label: "English",
  messages: DEFAULT_TRANSLATION
};
async function fetchTranslation(locale, assetUrls) {
  const mainRes = await fetch(assetUrls.translations.en);
  if (!mainRes.ok) {
    console.warn(`No main translations found.`);
    return EN_TRANSLATION;
  }
  if (locale === "en") {
    return EN_TRANSLATION;
  }
  const language = LANGUAGES.find((t2) => t2.locale === locale);
  if (!language) {
    console.warn(`No translation found for locale ${locale}`);
    return EN_TRANSLATION;
  }
  const res = await fetch(assetUrls.translations[language.locale]);
  const messages = await res.json();
  if (!messages) {
    console.warn(`No messages found for locale ${locale}`);
    return EN_TRANSLATION;
  }
  const missing = [];
  for (const key in EN_TRANSLATION.messages) {
    if (!messages[key]) {
      missing.push(key);
    }
  }
  if (missing.length > 0 && true) {
    console.warn(`Language ${locale}: missing messages for keys:
${missing.join("\n")}`);
  }
  return {
    locale,
    label: language.label,
    messages: { ...EN_TRANSLATION.messages, ...messages }
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs
var TranslationsContext = React17.createContext(
  {}
);
var useCurrentTranslation = () => React17.useContext(TranslationsContext);
var TranslationProvider = track(function TranslationProvider2({
  overrides,
  children
}) {
  const editor = useEditor();
  const locale = editor.user.locale;
  const getAssetUrl = useAssetUrls();
  const [currentTranslation, setCurrentTranslation] = React17.useState(() => {
    if (overrides && overrides["en"]) {
      return {
        locale: "en",
        label: "English",
        messages: { ...DEFAULT_TRANSLATION, ...overrides["en"] }
      };
    }
    return {
      locale: "en",
      label: "English",
      messages: DEFAULT_TRANSLATION
    };
  });
  React17.useEffect(() => {
    let isCancelled = false;
    async function loadTranslation() {
      const translation = await fetchTranslation(locale, getAssetUrl);
      if (translation && !isCancelled) {
        if (overrides && overrides[locale]) {
          setCurrentTranslation({
            ...translation,
            messages: { ...translation.messages, ...overrides[locale] }
          });
        } else {
          setCurrentTranslation(translation);
        }
      }
    }
    loadTranslation();
    return () => {
      isCancelled = true;
    };
  }, [getAssetUrl, locale, overrides]);
  return (0, import_jsx_runtime32.jsx)(TranslationsContext.Provider, { value: currentTranslation, children });
});
function useTranslation() {
  const translation = useCurrentTranslation();
  return React17.useCallback(
    function msg2(id) {
      return translation.messages[id] ?? id;
    },
    [translation]
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/Spinner.mjs
var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
function Spinner(props) {
  return (0, import_jsx_runtime33.jsx)("svg", { width: 16, height: 16, viewBox: "0 0 16 16", ...props, children: (0, import_jsx_runtime33.jsxs)("g", { strokeWidth: 2, fill: "none", fillRule: "evenodd", children: [
    (0, import_jsx_runtime33.jsx)("circle", { strokeOpacity: 0.25, cx: 8, cy: 8, r: 7, stroke: "currentColor" }),
    (0, import_jsx_runtime33.jsx)("path", { strokeLinecap: "round", d: "M15 8c0-4.5-4.5-7-7-7", stroke: "currentColor", children: (0, import_jsx_runtime33.jsx)(
      "animateTransform",
      {
        attributeName: "transform",
        type: "rotate",
        from: "0 8 8",
        to: "360 8 8",
        dur: "1s",
        repeatCount: "indefinite"
      }
    ) })
  ] }) });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Icon.mjs
var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
var import_classnames12 = __toESM(require_classnames(), 1);
var import_react39 = __toESM(require_react(), 1);
var Icon = (0, import_react39.memo)(function Icon2({
  small,
  invertIcon,
  icon,
  color,
  className,
  ...props
}) {
  const assetUrls = useAssetUrls();
  const asset = assetUrls.icons[icon];
  const ref = (0, import_react39.useRef)(null);
  (0, import_react39.useLayoutEffect)(() => {
    if (ref?.current) {
      ref.current.style.webkitMask = `url(${asset}) center 100% / 100% no-repeat`;
    }
  }, [ref, asset]);
  return (0, import_jsx_runtime34.jsx)(
    "div",
    {
      ...props,
      ref,
      className: (0, import_classnames12.default)("tlui-icon", { "tlui-icon__small": small }, className),
      style: {
        color,
        mask: `url(${asset}) center 100% / 100% no-repeat`,
        transform: invertIcon ? "scale(-1, 1)" : void 0
      }
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Kbd.mjs
var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/shared.mjs
var isDarwin = typeof window === "undefined" ? false : window.navigator.userAgent.toLowerCase().indexOf("mac") > -1;
var cmdKey = isDarwin ? "⌘" : "Ctrl";
var altKey = isDarwin ? "⌥" : "Alt";
function kbd(str) {
  return str.split(",")[0].split("").map((sub) => {
    const subStr = sub.replace(/\$/g, cmdKey).replace(/\?/g, altKey).replace(/!/g, "⇧");
    return subStr[0].toUpperCase() + subStr.slice(1);
  });
}
function kbdStr(str) {
  return "— " + str.split(",")[0].split("").map((sub) => {
    const subStr = sub.replace(/\$/g, cmdKey).replace(/\?/g, altKey).replace(/!/g, "⇧");
    return subStr[0].toUpperCase() + subStr.slice(1);
  }).join(" ");
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Kbd.mjs
function Kbd({ children }) {
  return (0, import_jsx_runtime35.jsx)("kbd", { className: "tlui-kbd", children: kbd(children).map((k, i) => (0, import_jsx_runtime35.jsx)("span", { children: k }, i)) });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Button.mjs
var Button = React18.forwardRef(function Button2({
  label,
  icon,
  invertIcon,
  iconLeft,
  smallIcon,
  kbd: kbd2,
  isChecked = false,
  type = "normal",
  children,
  spinner,
  ...props
}, ref) {
  const msg2 = useTranslation();
  const labelStr = label ? msg2(label) : "";
  return (0, import_jsx_runtime36.jsxs)(
    "button",
    {
      ref,
      draggable: false,
      type: "button",
      ...props,
      title: props.title ?? labelStr,
      className: (0, import_classnames13.default)("tlui-button", `tlui-button__${type}`, props.className),
      children: [
        iconLeft && (0, import_jsx_runtime36.jsx)(Icon, { icon: iconLeft, className: "tlui-icon-left", small: true }),
        children,
        label && (0, import_jsx_runtime36.jsxs)("span", { draggable: false, children: [
          labelStr,
          isChecked && (0, import_jsx_runtime36.jsx)(Icon, { icon: "check" })
        ] }),
        kbd2 && (0, import_jsx_runtime36.jsx)(Kbd, { children: kbd2 }),
        icon && !spinner && (0, import_jsx_runtime36.jsx)(Icon, { icon, small: !!label || smallIcon, invertIcon }),
        spinner && (0, import_jsx_runtime36.jsx)(Spinner, {})
      ]
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Dialog.mjs
function Header({ className, children }) {
  return (0, import_jsx_runtime37.jsx)("div", { className: (0, import_classnames14.default)("tlui-dialog__header", className), children });
}
function Title({ className, children }) {
  return (0, import_jsx_runtime37.jsx)(DialogTitle, { dir: "ltr", className: (0, import_classnames14.default)("tlui-dialog__header__title", className), children });
}
function CloseButton() {
  return (0, import_jsx_runtime37.jsx)("div", { className: "tlui-dialog__header__close", children: (0, import_jsx_runtime37.jsx)(DialogClose, { "data-testid": "dialog.close", dir: "ltr", asChild: true, children: (0, import_jsx_runtime37.jsx)(Button, { "aria-label": "Close", onTouchEnd: (e) => e.target.click(), children: (0, import_jsx_runtime37.jsx)(Icon, { small: true, icon: "cross-2" }) }) }) });
}
function Body({
  className,
  children,
  style
}) {
  return (0, import_jsx_runtime37.jsx)("div", { className: (0, import_classnames14.default)("tlui-dialog__body", className), style, children });
}
function Footer({ className, children }) {
  return (0, import_jsx_runtime37.jsx)("div", { className: (0, import_classnames14.default)("tlui-dialog__footer", className), children });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/DropdownMenu.mjs
var DropdownMenu_exports = {};
__export(DropdownMenu_exports, {
  CheckboxItem: () => CheckboxItem3,
  Content: () => Content3,
  Group: () => Group3,
  Indicator: () => Indicator,
  Item: () => Item,
  RadioItem: () => RadioItem2,
  Root: () => Root4,
  Sub: () => Sub3,
  SubContent: () => SubContent3,
  SubTrigger: () => SubTrigger3,
  Trigger: () => Trigger2
});
var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useMenuIsOpen.mjs
var import_react40 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useEventsProvider.mjs
var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
var React19 = __toESM(require_react(), 1);
var defaultEventHandler = () => void 0;
var EventsContext = React19.createContext({});
function UiEventsProvider({ onEvent, children }) {
  return (0, import_jsx_runtime38.jsx)(EventsContext.Provider, { value: onEvent ?? defaultEventHandler, children });
}
function useUiEvents() {
  const eventHandler2 = React19.useContext(EventsContext);
  return eventHandler2 ?? defaultEventHandler;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useMenuIsOpen.mjs
function useMenuIsOpen(id, cb) {
  const editor = useEditor();
  const rIsOpen = (0, import_react40.useRef)(false);
  const trackEvent = useUiEvents();
  const onOpenChange = (0, import_react40.useCallback)(
    (isOpen2) => {
      rIsOpen.current = isOpen2;
      editor.batch(() => {
        if (isOpen2) {
          editor.complete();
          editor.addOpenMenu(id);
        } else {
          editor.updateInstanceState({
            openMenus: editor.openMenus.filter((m) => !m.startsWith(id))
          });
        }
        cb?.(isOpen2);
      });
    },
    [editor, id, cb]
  );
  (0, import_react40.useEffect)(() => {
    if (rIsOpen.current) {
      trackEvent("open-menu", { source: "unknown", id });
      editor.addOpenMenu(id);
    }
    return () => {
      if (rIsOpen.current) {
        editor.deleteOpenMenu(id);
        editor.openMenus.forEach((menuId) => {
          if (menuId.startsWith(id)) {
            trackEvent("close-menu", { source: "unknown", id });
            editor.deleteOpenMenu(menuId);
          }
        });
        rIsOpen.current = false;
      }
    };
  }, [editor, id, trackEvent]);
  const isOpen = useValue("is menu open", () => editor.openMenus.includes(id), [editor, id]);
  return [isOpen, onOpenChange];
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/DropdownMenu.mjs
function Root4({
  id,
  children,
  modal = false
}) {
  const [open, onOpenChange] = useMenuIsOpen(id);
  return (0, import_jsx_runtime39.jsx)(Root22, { open, dir: "ltr", modal, onOpenChange, children });
}
function Trigger2({
  children,
  "data-testid": testId
}) {
  return (0, import_jsx_runtime39.jsx)(
    Trigger,
    {
      dir: "ltr",
      "data-testid": testId,
      asChild: true,
      onTouchEnd: (e) => preventDefault(e),
      children
    }
  );
}
function Content3({
  side = "bottom",
  align = "start",
  sideOffset = 8,
  alignOffset = 8,
  children
}) {
  const container = useContainer();
  return (0, import_jsx_runtime39.jsx)(Portal22, { dir: "ltr", container, children: (0, import_jsx_runtime39.jsx)(
    Content22,
    {
      className: "tlui-menu",
      align,
      sideOffset,
      side,
      alignOffset,
      collisionPadding: 4,
      children
    }
  ) });
}
function Sub3({ id, children }) {
  const [open, onOpenChange] = useMenuIsOpen(id);
  return (0, import_jsx_runtime39.jsx)(Sub2, { open, onOpenChange, children });
}
function SubTrigger3({
  label,
  "data-testid": testId,
  "data-direction": dataDirection
}) {
  return (0, import_jsx_runtime39.jsx)(SubTrigger2, { dir: "ltr", "data-direction": dataDirection, "data-testid": testId, asChild: true, children: (0, import_jsx_runtime39.jsx)(
    Button,
    {
      className: "tlui-menu__button tlui-menu__submenu__trigger",
      label,
      icon: "chevron-right"
    }
  ) });
}
function SubContent3({
  alignOffset = 0,
  sideOffset = 5,
  children
}) {
  const container = useContainer();
  return (0, import_jsx_runtime39.jsx)(Portal22, { container, dir: "ltr", children: (0, import_jsx_runtime39.jsx)(
    SubContent2,
    {
      className: "tlui-menu tlui-menu__submenu__content",
      alignOffset,
      sideOffset,
      collisionPadding: 4,
      children
    }
  ) });
}
function Group3({
  children,
  size: size2 = "medium"
}) {
  return (0, import_jsx_runtime39.jsx)(Group2, { dir: "ltr", className: "tlui-menu__group", "data-size": size2, children });
}
function Indicator() {
  return (0, import_jsx_runtime39.jsx)(ItemIndicator2, { dir: "ltr", asChild: true, children: (0, import_jsx_runtime39.jsx)(Icon, { icon: "check" }) });
}
function Item({ noClose, ...props }) {
  return (0, import_jsx_runtime39.jsx)(
    Item22,
    {
      dir: "ltr",
      asChild: true,
      onClick: noClose || props.isChecked !== void 0 ? preventDefault : void 0,
      children: (0, import_jsx_runtime39.jsx)(Button, { className: "tlui-menu__button", ...props })
    }
  );
}
function CheckboxItem3({ children, onSelect, ...rest }) {
  return (0, import_jsx_runtime39.jsxs)(
    CheckboxItem2,
    {
      dir: "ltr",
      className: "tlui-button tlui-menu__button tlui-menu__checkbox-item",
      onSelect: (e) => {
        onSelect?.(e);
        preventDefault(e);
      },
      ...rest,
      children: [
        (0, import_jsx_runtime39.jsx)(
          "div",
          {
            className: "tlui-menu__checkbox-item__check",
            style: {
              transformOrigin: "75% center",
              transform: `scale(${rest.checked ? 1 : 0.5})`,
              opacity: rest.checked ? 1 : 0.5
            },
            children: (0, import_jsx_runtime39.jsx)(Icon, { small: true, icon: rest.checked ? "check" : "checkbox-empty" })
          }
        ),
        children
      ]
    }
  );
}
function RadioItem2({ children, onSelect, ...rest }) {
  return (0, import_jsx_runtime39.jsxs)(
    CheckboxItem2,
    {
      dir: "ltr",
      className: "tlui-button tlui-menu__button tlui-menu__checkbox-item",
      onSelect: (e) => {
        onSelect?.(e);
        preventDefault(e);
      },
      ...rest,
      children: [
        (0, import_jsx_runtime39.jsx)(ItemIndicator2, { dir: "ltr", className: "tlui-menu__checkbox-item__check", children: (0, import_jsx_runtime39.jsx)(Icon, { icon: "check" }) }),
        children
      ]
    }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/Tldraw.mjs
var import_jsx_runtime129 = __toESM(require_jsx_runtime(), 1);
var import_react112 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/TldrawHandles.mjs
var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
var TldrawHandles = ({ children }) => {
  const editor = useEditor();
  const shouldDisplayHandles = useValue(
    "shouldDisplayHandles",
    () => editor.isInAny("select.idle", "select.pointing_handle"),
    [editor]
  );
  if (!shouldDisplayHandles)
    return null;
  return (0, import_jsx_runtime40.jsx)("svg", { className: "tl-user-handles tl-overlays__item", children });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/TldrawHoveredShapeIndicator.mjs
var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
var TldrawHoveredShapeIndicator = ({ shapeId }) => {
  const editor = useEditor();
  const showHoveredShapeIndicator = useValue(
    "show hovered",
    () => {
      if (editor.isIn("select.editing_shape")) {
        return editor.hoveredShapeId !== editor.editingShapeId;
      }
      return editor.isInAny("select.idle");
    },
    [editor]
  );
  if (!showHoveredShapeIndicator)
    return null;
  return (0, import_jsx_runtime41.jsx)(ShapeIndicator, { className: "tl-user-indicator__hovered", id: shapeId });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/TldrawScribble.mjs
var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
var import_classnames15 = __toESM(require_classnames(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs
var { PI: PI3 } = Math;
var FIXED_PI = PI3 + 1e-4;
function getStrokeOutlinePoints(strokePoints, options = {}) {
  const { size: size2 = 16, smoothing = 0.5, start = {}, end = {}, last: isComplete = false } = options;
  const { cap: capStart = true } = start;
  const { cap: capEnd = true } = end;
  if (strokePoints.length === 0 || size2 <= 0) {
    return [];
  }
  const firstStrokePoint = strokePoints[0];
  const lastStrokePoint = strokePoints[strokePoints.length - 1];
  const totalLength = lastStrokePoint.runningLength;
  const taperStart = start.taper === false ? 0 : start.taper === true ? Math.max(size2, totalLength) : start.taper;
  const taperEnd = end.taper === false ? 0 : end.taper === true ? Math.max(size2, totalLength) : end.taper;
  const minDistance = Math.pow(size2 * smoothing, 2);
  const leftPts = [];
  const rightPts = [];
  let prevVector = strokePoints[0].vector;
  let pl = strokePoints[0].point;
  let pr = pl;
  let tl = pl;
  let tr = pr;
  let isPrevPointSharpCorner = false;
  let strokePoint;
  for (let i = 0; i < strokePoints.length; i++) {
    strokePoint = strokePoints[i];
    const { point, vector } = strokePoints[i];
    const prevDpr = strokePoint.vector.dpr(prevVector);
    const nextVector = (i < strokePoints.length - 1 ? strokePoints[i + 1] : strokePoints[i]).vector;
    const nextDpr = i < strokePoints.length - 1 ? nextVector.dpr(strokePoint.vector) : 1;
    const isPointSharpCorner = prevDpr < 0 && !isPrevPointSharpCorner;
    const isNextPointSharpCorner = nextDpr !== null && nextDpr < 0.2;
    if (isPointSharpCorner || isNextPointSharpCorner) {
      if (nextDpr > -0.62 && totalLength - strokePoint.runningLength > strokePoint.radius) {
        const offset22 = prevVector.clone().mul(strokePoint.radius);
        const cpr = prevVector.clone().cpr(nextVector);
        if (cpr < 0) {
          tl = Vec2d.Add(point, offset22);
          tr = Vec2d.Sub(point, offset22);
        } else {
          tl = Vec2d.Sub(point, offset22);
          tr = Vec2d.Add(point, offset22);
        }
        leftPts.push(tl);
        rightPts.push(tr);
      } else {
        const offset22 = prevVector.clone().mul(strokePoint.radius).per();
        const start2 = Vec2d.Sub(strokePoint.input, offset22);
        for (let step = 1 / 13, t2 = 0; t2 < 1; t2 += step) {
          tl = Vec2d.RotWith(start2, strokePoint.input, FIXED_PI * t2);
          leftPts.push(tl);
          tr = Vec2d.RotWith(start2, strokePoint.input, FIXED_PI + FIXED_PI * -t2);
          rightPts.push(tr);
        }
      }
      pl = tl;
      pr = tr;
      if (isNextPointSharpCorner) {
        isPrevPointSharpCorner = true;
      }
      continue;
    }
    isPrevPointSharpCorner = false;
    if (strokePoint === firstStrokePoint || strokePoint === lastStrokePoint) {
      const offset22 = Vec2d.Per(vector).mul(strokePoint.radius);
      leftPts.push(Vec2d.Sub(point, offset22));
      rightPts.push(Vec2d.Add(point, offset22));
      continue;
    }
    const offset2 = Vec2d.Lrp(nextVector, vector, nextDpr).per().mul(strokePoint.radius);
    tl = Vec2d.Sub(point, offset2);
    if (i <= 1 || Vec2d.Dist2(pl, tl) > minDistance) {
      leftPts.push(tl);
      pl = tl;
    }
    tr = Vec2d.Add(point, offset2);
    if (i <= 1 || Vec2d.Dist2(pr, tr) > minDistance) {
      rightPts.push(tr);
      pr = tr;
    }
    prevVector = vector;
    continue;
  }
  const firstPoint = firstStrokePoint.point;
  const lastPoint = strokePoints.length > 1 ? strokePoints[strokePoints.length - 1].point : Vec2d.AddXY(firstStrokePoint.point, 1, 1);
  if (strokePoints.length === 1) {
    if (!(taperStart || taperEnd) || isComplete) {
      const start2 = Vec2d.Add(
        firstPoint,
        Vec2d.Sub(firstPoint, lastPoint).uni().per().mul(-firstStrokePoint.radius)
      );
      const dotPts = [];
      for (let step = 1 / 13, t2 = step; t2 <= 1; t2 += step) {
        dotPts.push(Vec2d.RotWith(start2, firstPoint, FIXED_PI * 2 * t2));
      }
      return dotPts;
    }
  }
  const startCap = [];
  if (taperStart || taperEnd && strokePoints.length === 1) {
  } else if (capStart) {
    for (let step = 1 / 8, t2 = step; t2 <= 1; t2 += step) {
      const pt = Vec2d.RotWith(rightPts[0], firstPoint, FIXED_PI * t2);
      startCap.push(pt);
    }
  } else {
    const cornersVector = Vec2d.Sub(leftPts[0], rightPts[0]);
    const offsetA = Vec2d.Mul(cornersVector, 0.5);
    const offsetB = Vec2d.Mul(cornersVector, 0.51);
    startCap.push(
      Vec2d.Sub(firstPoint, offsetA),
      Vec2d.Sub(firstPoint, offsetB),
      Vec2d.Add(firstPoint, offsetB),
      Vec2d.Add(firstPoint, offsetA)
    );
  }
  const endCap = [];
  const direction = lastStrokePoint.vector.clone().per().neg();
  if (taperEnd || taperStart && strokePoints.length === 1) {
    endCap.push(lastPoint);
  } else if (capEnd) {
    const start2 = Vec2d.Add(lastPoint, Vec2d.Mul(direction, lastStrokePoint.radius));
    for (let step = 1 / 29, t2 = step; t2 < 1; t2 += step) {
      endCap.push(Vec2d.RotWith(start2, lastPoint, FIXED_PI * 3 * t2));
    }
  } else {
    endCap.push(
      Vec2d.Add(lastPoint, Vec2d.Mul(direction, lastStrokePoint.radius)),
      Vec2d.Add(lastPoint, Vec2d.Mul(direction, lastStrokePoint.radius * 0.99)),
      Vec2d.Sub(lastPoint, Vec2d.Mul(direction, lastStrokePoint.radius * 0.99)),
      Vec2d.Sub(lastPoint, Vec2d.Mul(direction, lastStrokePoint.radius))
    );
  }
  return leftPts.concat(endCap, rightPts.reverse(), startCap);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs
var MIN_START_PRESSURE = 0.025;
var MIN_END_PRESSURE = 0.01;
function getStrokePoints(rawInputPoints, options = {}) {
  const { streamline = 0.5, size: size2 = 16, simulatePressure = false } = options;
  if (rawInputPoints.length === 0)
    return [];
  const t2 = 0.15 + (1 - streamline) * 0.85;
  let pts = rawInputPoints.map(Vec2d.From);
  let pointsRemovedFromNearEnd = 0;
  if (!simulatePressure) {
    let pt2 = pts[0];
    while (pt2) {
      if (pt2.z >= MIN_START_PRESSURE)
        break;
      pts.shift();
      pt2 = pts[0];
    }
  }
  if (!simulatePressure) {
    let pt2 = pts[pts.length - 1];
    while (pt2) {
      if (pt2.z >= MIN_END_PRESSURE)
        break;
      pts.pop();
      pt2 = pts[pts.length - 1];
    }
  }
  if (pts.length === 0)
    return [
      {
        point: Vec2d.From(rawInputPoints[0]),
        input: Vec2d.From(rawInputPoints[0]),
        pressure: simulatePressure ? 0.5 : 0.15,
        vector: new Vec2d(1, 1),
        distance: 0,
        runningLength: 0,
        radius: 1
      }
    ];
  let pt = pts[1];
  while (pt) {
    if (Vec2d.Dist(pt, pts[0]) > size2 / 3)
      break;
    pts[0].z = Math.max(pts[0].z, pt.z);
    pts.splice(1, 1);
    pt = pts[1];
  }
  const last2 = pts.pop();
  pt = pts[pts.length - 1];
  while (pt) {
    if (Vec2d.Dist(pt, last2) > size2 / 3)
      break;
    pts.pop();
    pt = pts[pts.length - 1];
    pointsRemovedFromNearEnd++;
  }
  pts.push(last2);
  const isComplete = options.last || !options.simulatePressure || pts.length > 1 && Vec2d.Dist(pts[pts.length - 1], pts[pts.length - 2]) < size2 || pointsRemovedFromNearEnd > 0;
  if (pts.length === 2 && options.simulatePressure) {
    const last22 = pts[1];
    pts = pts.slice(0, -1);
    for (let i = 1; i < 5; i++) {
      const next = Vec2d.Lrp(pts[0], last22, i / 4);
      next.z = (pts[0].z + (last22.z - pts[0].z)) * i / 4;
      pts.push(next);
    }
  }
  const strokePoints = [
    {
      point: pts[0],
      input: pts[0],
      pressure: simulatePressure ? 0.5 : pts[0].z,
      vector: new Vec2d(1, 1),
      distance: 0,
      runningLength: 0,
      radius: 1
    }
  ];
  let totalLength = 0;
  let prev = strokePoints[0];
  let point, distance;
  if (isComplete && streamline > 0) {
    pts.push(pts[pts.length - 1].clone());
  }
  for (let i = 1, n = pts.length; i < n; i++) {
    point = !t2 || options.last && i === n - 1 ? pts[i].clone() : pts[i].clone().lrp(prev.point, 1 - t2);
    if (prev.point.equals(point))
      continue;
    distance = Vec2d.Dist(point, prev.point);
    totalLength += distance;
    if (i < 4 && totalLength < size2) {
      continue;
    }
    prev = {
      input: pts[i],
      // The adjusted point
      point,
      // The input pressure (or .5 if not specified)
      pressure: simulatePressure ? 0.5 : pts[i].z,
      // The vector from the current point to the previous point
      vector: Vec2d.Sub(prev.point, point).uni(),
      // The distance between the current point and the previous point
      distance,
      // The total distance so far
      runningLength: totalLength,
      // The stroke point's radius
      radius: 1
    };
    strokePoints.push(prev);
  }
  if (strokePoints[1]?.vector) {
    strokePoints[0].vector = strokePoints[1].vector.clone();
  }
  if (totalLength < 1) {
    const maxPressureAmongPoints = Math.max(0.5, ...strokePoints.map((s) => s.pressure));
    strokePoints.forEach((s) => s.pressure = maxPressureAmongPoints);
  }
  return strokePoints;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs
var { min } = Math;
var RATE_OF_PRESSURE_CHANGE = 0.275;
function setStrokePointRadii(strokePoints, options) {
  const {
    size: size2 = 16,
    thinning = 0.5,
    simulatePressure = true,
    easing = (t2) => t2,
    start = {},
    end = {}
  } = options;
  const { easing: taperStartEase = EASINGS.easeOutQuad } = start;
  const { easing: taperEndEase = EASINGS.easeOutCubic } = end;
  const totalLength = strokePoints[strokePoints.length - 1].runningLength;
  let firstRadius;
  let prevPressure = strokePoints[0].pressure;
  let strokePoint;
  if (!simulatePressure && totalLength < size2) {
    const max3 = strokePoints.reduce((max22, curr) => Math.max(max22, curr.pressure), 0.5);
    strokePoints.forEach((sp) => {
      sp.pressure = max3;
      sp.radius = size2 * easing(0.5 - thinning * (0.5 - sp.pressure));
    });
    return strokePoints;
  } else {
    let p;
    for (let i = 0, n = strokePoints.length; i < n; i++) {
      strokePoint = strokePoints[i];
      if (strokePoint.runningLength > size2 * 5)
        break;
      const sp = min(1, strokePoint.distance / size2);
      if (simulatePressure) {
        const rp = min(1, 1 - sp);
        p = min(1, prevPressure + (rp - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE));
      } else {
        p = min(1, prevPressure + (strokePoint.pressure - prevPressure) * 0.5);
      }
      prevPressure = prevPressure + (p - prevPressure) * 0.5;
    }
    for (let i = 0; i < strokePoints.length; i++) {
      strokePoint = strokePoints[i];
      if (thinning) {
        let { pressure } = strokePoint;
        const sp = min(1, strokePoint.distance / size2);
        if (simulatePressure) {
          const rp = min(1, 1 - sp);
          pressure = min(1, prevPressure + (rp - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE));
        } else {
          pressure = min(
            1,
            prevPressure + (pressure - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE)
          );
        }
        strokePoint.radius = size2 * easing(0.5 - thinning * (0.5 - pressure));
        prevPressure = pressure;
      } else {
        strokePoint.radius = size2 / 2;
      }
      if (firstRadius === void 0) {
        firstRadius = strokePoint.radius;
      }
    }
  }
  const taperStart = start.taper === false ? 0 : start.taper === true ? Math.max(size2, totalLength) : start.taper;
  const taperEnd = end.taper === false ? 0 : end.taper === true ? Math.max(size2, totalLength) : end.taper;
  if (taperStart || taperEnd) {
    for (let i = 0; i < strokePoints.length; i++) {
      strokePoint = strokePoints[i];
      const { runningLength } = strokePoint;
      const ts = runningLength < taperStart ? taperStartEase(runningLength / taperStart) : 1;
      const te = totalLength - runningLength < taperEnd ? taperEndEase((totalLength - runningLength) / taperEnd) : 1;
      strokePoint.radius = Math.max(0.01, strokePoint.radius * Math.min(ts, te));
    }
  }
  return strokePoints;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/freehand/getStroke.mjs
function getStroke(points, options = {}) {
  return getStrokeOutlinePoints(
    setStrokePointRadii(getStrokePoints(points, options), options),
    options
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/TldrawScribble.mjs
var TldrawScribble = ({
  scribble,
  zoom,
  color,
  opacity,
  className
}) => {
  if (!scribble.points.length)
    return null;
  const stroke = getStroke(scribble.points, {
    size: scribble.size / zoom,
    start: { taper: true, easing: EASINGS.linear },
    last: scribble.state === "stopping",
    simulatePressure: false,
    streamline: 0.32
  });
  let d;
  if (stroke.length < 4) {
    const r = scribble.size / zoom / 2;
    const { x, y } = scribble.points[scribble.points.length - 1];
    d = `M ${x - r},${y} a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 ${-r * 2},0`;
  } else {
    d = getSvgPathFromPoints(stroke);
  }
  return (0, import_jsx_runtime42.jsx)("svg", { className: className ? (0, import_classnames15.default)("tl-overlays__item", className) : className, children: (0, import_jsx_runtime42.jsx)(
    "path",
    {
      className: "tl-scribble",
      d,
      fill: color ?? `var(--color-${scribble.color})`,
      opacity: opacity ?? scribble.opacity
    }
  ) });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/TldrawSelectionBackground.mjs
var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
var TldrawSelectionBackground = ({ bounds, rotation }) => {
  const editor = useEditor();
  const shouldDisplay = useValue(
    "should display",
    () => editor.isInAny(
      "select.idle",
      "select.brushing",
      "select.scribble_brushing",
      "select.pointing_shape",
      "select.pointing_selection",
      "text.resizing"
    ),
    [editor]
  );
  if (!shouldDisplay)
    return null;
  return (0, import_jsx_runtime43.jsx)(DefaultSelectionBackground, { bounds, rotation });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/TldrawSelectionForeground.mjs
var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
var import_classnames17 = __toESM(require_classnames(), 1);
var import_react41 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useReadonly.mjs
function useReadonly() {
  const editor = useEditor();
  return useValue("isReadonlyMode", () => editor.instanceState.isReadonly, [editor]);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/CropHandles.mjs
var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
var import_classnames16 = __toESM(require_classnames(), 1);
function CropHandles({ size: size2, width, height, hideAlternateHandles }) {
  const cropStrokeWidth = toDomPrecision(size2 / 3);
  const offset2 = cropStrokeWidth / 2;
  return (0, import_jsx_runtime44.jsxs)("svg", { className: "tl-overlays__item", children: [
    (0, import_jsx_runtime44.jsx)(
      "polyline",
      {
        className: "tl-corner-crop-handle",
        points: `
						${toDomPrecision(0 - offset2)},${toDomPrecision(size2)} 
						${toDomPrecision(0 - offset2)},${toDomPrecision(0 - offset2)} 
						${toDomPrecision(size2)},${toDomPrecision(0 - offset2)}`,
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.top_left",
        "aria-label": "top_left handle"
      }
    ),
    (0, import_jsx_runtime44.jsx)(
      "line",
      {
        className: (0, import_classnames16.default)("tl-corner-crop-edge-handle", {
          "tl-hidden": hideAlternateHandles
        }),
        x1: toDomPrecision(width / 2 - size2),
        y1: toDomPrecision(0 - offset2),
        x2: toDomPrecision(width / 2 + size2),
        y2: toDomPrecision(0 - offset2),
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.top",
        "aria-label": "top handle"
      }
    ),
    (0, import_jsx_runtime44.jsx)(
      "polyline",
      {
        className: (0, import_classnames16.default)("tl-corner-crop-handle", {
          "tl-hidden": hideAlternateHandles
        }),
        points: `
						${toDomPrecision(width - size2)},${toDomPrecision(0 - offset2)} 
						${toDomPrecision(width + offset2)},${toDomPrecision(0 - offset2)} 
						${toDomPrecision(width + offset2)},${toDomPrecision(size2)}`,
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.top_right",
        "aria-label": "top_right handle"
      }
    ),
    (0, import_jsx_runtime44.jsx)(
      "line",
      {
        className: (0, import_classnames16.default)("tl-corner-crop-edge-handle", {
          "tl-hidden": hideAlternateHandles
        }),
        x1: toDomPrecision(width + offset2),
        y1: toDomPrecision(height / 2 - size2),
        x2: toDomPrecision(width + offset2),
        y2: toDomPrecision(height / 2 + size2),
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.right",
        "aria-label": "right handle"
      }
    ),
    (0, import_jsx_runtime44.jsx)(
      "polyline",
      {
        className: "tl-corner-crop-handle",
        points: `
						${toDomPrecision(width + offset2)},${toDomPrecision(height - size2)} 
						${toDomPrecision(width + offset2)},${toDomPrecision(height + offset2)}
						${toDomPrecision(width - size2)},${toDomPrecision(height + offset2)}`,
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.bottom_right",
        "aria-label": "bottom_right handle"
      }
    ),
    (0, import_jsx_runtime44.jsx)(
      "line",
      {
        className: (0, import_classnames16.default)("tl-corner-crop-edge-handle", {
          "tl-hidden": hideAlternateHandles
        }),
        x1: toDomPrecision(width / 2 - size2),
        y1: toDomPrecision(height + offset2),
        x2: toDomPrecision(width / 2 + size2),
        y2: toDomPrecision(height + offset2),
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.bottom",
        "aria-label": "bottom handle"
      }
    ),
    (0, import_jsx_runtime44.jsx)(
      "polyline",
      {
        className: (0, import_classnames16.default)("tl-corner-crop-handle", {
          "tl-hidden": hideAlternateHandles
        }),
        points: `
						${toDomPrecision(0 + size2)},${toDomPrecision(height + offset2)} 
						${toDomPrecision(0 - offset2)},${toDomPrecision(height + offset2)}
						${toDomPrecision(0 - offset2)},${toDomPrecision(height - size2)}`,
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.bottom_left",
        "aria-label": "bottom_left handle"
      }
    ),
    (0, import_jsx_runtime44.jsx)(
      "line",
      {
        className: (0, import_classnames16.default)("tl-corner-crop-edge-handle", {
          "tl-hidden": hideAlternateHandles
        }),
        x1: toDomPrecision(0 - offset2),
        y1: toDomPrecision(height / 2 - size2),
        x2: toDomPrecision(0 - offset2),
        y2: toDomPrecision(height / 2 + size2),
        strokeWidth: cropStrokeWidth,
        "data-testid": "selection.crop.left",
        "aria-label": "left handle"
      }
    )
  ] });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/canvas/TldrawSelectionForeground.mjs
var IS_FIREFOX = typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().indexOf("firefox") > -1;
var TldrawSelectionForeground = track(
  function TldrawSelectionForeground2({ bounds, rotation }) {
    const editor = useEditor();
    const rSvg = (0, import_react41.useRef)(null);
    const isReadonlyMode = useReadonly();
    const topEvents = useSelectionEvents("top");
    const rightEvents = useSelectionEvents("right");
    const bottomEvents = useSelectionEvents("bottom");
    const leftEvents = useSelectionEvents("left");
    const topLeftEvents = useSelectionEvents("top_left");
    const topRightEvents = useSelectionEvents("top_right");
    const bottomRightEvents = useSelectionEvents("bottom_right");
    const bottomLeftEvents = useSelectionEvents("bottom_left");
    const isDefaultCursor = !editor.isMenuOpen && editor.instanceState.cursor.type === "default";
    const isCoarsePointer = editor.instanceState.isCoarsePointer;
    const shapes = editor.selectedShapes;
    const onlyShape = editor.onlySelectedShape;
    const isLockedShape = onlyShape && editor.isShapeOrAncestorLocked(onlyShape);
    const expandOutlineBy = onlyShape ? editor.getShapeUtil(onlyShape).expandSelectionOutlinePx(onlyShape) : 0;
    useTransform(rSvg, bounds?.x, bounds?.y, 1, editor.selectionRotation, {
      x: -expandOutlineBy,
      y: -expandOutlineBy
    });
    if (!bounds)
      return null;
    bounds = bounds.clone().expandBy(expandOutlineBy).zeroFix();
    const zoom = editor.zoomLevel;
    const isChangingStyle = editor.instanceState.isChangingStyle;
    const width = bounds.width;
    const height = bounds.height;
    const size2 = 8 / zoom;
    const isTinyX = width < size2 * 2;
    const isTinyY = height < size2 * 2;
    const isSmallX = width < size2 * 4;
    const isSmallY = height < size2 * 4;
    const isSmallCropX = width < size2 * 5;
    const isSmallCropY = height < size2 * 5;
    const mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1;
    const targetSize = 6 / zoom * mobileHandleMultiplier;
    const targetSizeX = (isSmallX ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75);
    const targetSizeY = (isSmallY ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75);
    const showSelectionBounds = (onlyShape ? !editor.getShapeUtil(onlyShape).hideSelectionBoundsFg(onlyShape) : true) && !isChangingStyle;
    let shouldDisplayBox = showSelectionBounds && editor.isInAny(
      "select.idle",
      "select.brushing",
      "select.scribble_brushing",
      "select.pointing_canvas",
      "select.pointing_selection",
      "select.pointing_shape",
      "select.crop.idle",
      "select.crop.pointing_crop",
      "select.pointing_resize_handle",
      "select.pointing_crop_handle"
    ) || showSelectionBounds && editor.isIn("select.resizing") && onlyShape && editor.isShapeOfType(onlyShape, "text");
    if (onlyShape && shouldDisplayBox) {
      if (IS_FIREFOX && editor.isShapeOfType(onlyShape, "embed")) {
        shouldDisplayBox = false;
      }
    }
    const showCropHandles = editor.isInAny(
      "select.pointing_crop_handle",
      "select.crop.idle",
      "select.crop.pointing_crop"
    ) && !isChangingStyle && !isReadonlyMode;
    const shouldDisplayControls = editor.isInAny(
      "select.idle",
      "select.pointing_selection",
      "select.pointing_shape",
      "select.crop.idle"
    ) && !isChangingStyle && !isReadonlyMode;
    const showCornerRotateHandles = !isCoarsePointer && !(isTinyX || isTinyY) && (shouldDisplayControls || showCropHandles) && (onlyShape ? !editor.getShapeUtil(onlyShape).hideRotateHandle(onlyShape) : true) && !isLockedShape;
    const showMobileRotateHandle = isCoarsePointer && (!isSmallX || !isSmallY) && (shouldDisplayControls || showCropHandles) && (onlyShape ? !editor.getShapeUtil(onlyShape).hideRotateHandle(onlyShape) : true) && !isLockedShape;
    const showResizeHandles = shouldDisplayControls && (onlyShape ? editor.getShapeUtil(onlyShape).canResize(onlyShape) && !editor.getShapeUtil(onlyShape).hideResizeHandles(onlyShape) : true) && !showCropHandles && !isLockedShape;
    const hideAlternateCornerHandles = isTinyX || isTinyY;
    const showOnlyOneHandle = isTinyX && isTinyY;
    const hideAlternateCropHandles = isSmallCropX || isSmallCropY;
    const showHandles = showResizeHandles || showCropHandles;
    const hideRotateCornerHandles = !showCornerRotateHandles;
    const hideMobileRotateHandle = !shouldDisplayControls || !showMobileRotateHandle;
    const hideTopLeftCorner = !shouldDisplayControls || !showHandles;
    const hideTopRightCorner = !shouldDisplayControls || !showHandles || hideAlternateCornerHandles;
    const hideBottomLeftCorner = !shouldDisplayControls || !showHandles || hideAlternateCornerHandles;
    const hideBottomRightCorner = !shouldDisplayControls || !showHandles || showOnlyOneHandle && !showCropHandles;
    let hideEdgeTargetsDueToCoarsePointer = isCoarsePointer;
    if (hideEdgeTargetsDueToCoarsePointer && shapes.every((shape) => editor.getShapeUtil(shape).isAspectRatioLocked(shape))) {
      hideEdgeTargetsDueToCoarsePointer = false;
    }
    let hideEdgeTargets = true;
    if (showCropHandles) {
      hideEdgeTargets = hideAlternateCropHandles;
    } else if (showResizeHandles) {
      hideEdgeTargets = hideAlternateCornerHandles || showOnlyOneHandle || hideEdgeTargetsDueToCoarsePointer;
    }
    const textHandleHeight = Math.min(24 / zoom, height - targetSizeY * 3);
    const showTextResizeHandles = shouldDisplayControls && isCoarsePointer && onlyShape && editor.isShapeOfType(onlyShape, "text") && textHandleHeight * zoom >= 4;
    return (0, import_jsx_runtime45.jsxs)(
      "svg",
      {
        ref: rSvg,
        className: "tl-overlays__item tl-selection__fg",
        "data-testid": "selection-foreground",
        children: [
          shouldDisplayBox && (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-selection__fg__outline"),
              width: toDomPrecision(width),
              height: toDomPrecision(height)
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            RotateCornerHandle,
            {
              "data-testid": "selection.rotate.top-left",
              cx: 0,
              cy: 0,
              targetSize,
              corner: "top_left_rotate",
              cursor: isDefaultCursor ? getCursor("nwse-rotate", rotation) : void 0,
              isHidden: hideRotateCornerHandles
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            RotateCornerHandle,
            {
              "data-testid": "selection.rotate.top-right",
              cx: width + targetSize * 3,
              cy: 0,
              targetSize,
              corner: "top_right_rotate",
              cursor: isDefaultCursor ? getCursor("nesw-rotate", rotation) : void 0,
              isHidden: hideRotateCornerHandles
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            RotateCornerHandle,
            {
              "data-testid": "selection.rotate.bottom-left",
              cx: 0,
              cy: height + targetSize * 3,
              targetSize,
              corner: "bottom_left_rotate",
              cursor: isDefaultCursor ? getCursor("swne-rotate", rotation) : void 0,
              isHidden: hideRotateCornerHandles
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            RotateCornerHandle,
            {
              "data-testid": "selection.rotate.bottom-right",
              cx: width + targetSize * 3,
              cy: height + targetSize * 3,
              targetSize,
              corner: "bottom_right_rotate",
              cursor: isDefaultCursor ? getCursor("senw-rotate", rotation) : void 0,
              isHidden: hideRotateCornerHandles
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            MobileRotateHandle,
            {
              "data-testid": "selection.rotate.mobile",
              cx: isSmallX ? -targetSize * 1.5 : width / 2,
              cy: isSmallX ? height / 2 : -targetSize * 1.5,
              size: size2,
              isHidden: hideMobileRotateHandle
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideEdgeTargets
              }),
              "data-testid": "selection.resize.top",
              "aria-label": "top target",
              pointerEvents: "all",
              x: 0,
              y: toDomPrecision(0 - (isSmallY ? targetSizeY * 2 : targetSizeY)),
              width: toDomPrecision(width),
              height: toDomPrecision(Math.max(1, targetSizeY * 2)),
              style: isDefaultCursor ? { cursor: getCursor("ns-resize", rotation) } : void 0,
              ...topEvents
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideEdgeTargets
              }),
              "data-testid": "selection.resize.right",
              "aria-label": "right target",
              pointerEvents: "all",
              x: toDomPrecision(width - (isSmallX ? 0 : targetSizeX)),
              y: 0,
              height: toDomPrecision(height),
              width: toDomPrecision(Math.max(1, targetSizeX * 2)),
              style: isDefaultCursor ? { cursor: getCursor("ew-resize", rotation) } : void 0,
              ...rightEvents
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideEdgeTargets
              }),
              "data-testid": "selection.resize.bottom",
              "aria-label": "bottom target",
              pointerEvents: "all",
              x: 0,
              y: toDomPrecision(height - (isSmallY ? 0 : targetSizeY)),
              width: toDomPrecision(width),
              height: toDomPrecision(Math.max(1, targetSizeY * 2)),
              style: isDefaultCursor ? { cursor: getCursor("ns-resize", rotation) } : void 0,
              ...bottomEvents
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideEdgeTargets
              }),
              "data-testid": "selection.resize.left",
              "aria-label": "left target",
              pointerEvents: "all",
              x: toDomPrecision(0 - (isSmallX ? targetSizeX * 2 : targetSizeX)),
              y: 0,
              height: toDomPrecision(height),
              width: toDomPrecision(Math.max(1, targetSizeX * 2)),
              style: isDefaultCursor ? { cursor: getCursor("ew-resize", rotation) } : void 0,
              ...leftEvents
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideTopLeftCorner
              }),
              "data-testid": "selection.target.top-left",
              "aria-label": "top-left target",
              pointerEvents: "all",
              x: toDomPrecision(0 - (isSmallX ? targetSizeX * 2 : targetSizeX * 1.5)),
              y: toDomPrecision(0 - (isSmallY ? targetSizeY * 2 : targetSizeY * 1.5)),
              width: toDomPrecision(targetSizeX * 3),
              height: toDomPrecision(targetSizeY * 3),
              style: isDefaultCursor ? { cursor: getCursor("nwse-resize", rotation) } : void 0,
              ...topLeftEvents
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideTopRightCorner
              }),
              "data-testid": "selection.target.top-right",
              "aria-label": "top-right target",
              pointerEvents: "all",
              x: toDomPrecision(width - (isSmallX ? 0 : targetSizeX * 1.5)),
              y: toDomPrecision(0 - (isSmallY ? targetSizeY * 2 : targetSizeY * 1.5)),
              width: toDomPrecision(targetSizeX * 3),
              height: toDomPrecision(targetSizeY * 3),
              style: isDefaultCursor ? { cursor: getCursor("nesw-resize", rotation) } : void 0,
              ...topRightEvents
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideBottomRightCorner
              }),
              "data-testid": "selection.target.bottom-right",
              "aria-label": "bottom-right target",
              pointerEvents: "all",
              x: toDomPrecision(width - (isSmallX ? targetSizeX : targetSizeX * 1.5)),
              y: toDomPrecision(height - (isSmallY ? targetSizeY : targetSizeY * 1.5)),
              width: toDomPrecision(targetSizeX * 3),
              height: toDomPrecision(targetSizeY * 3),
              style: isDefaultCursor ? { cursor: getCursor("nwse-resize", rotation) } : void 0,
              ...bottomRightEvents
            }
          ),
          (0, import_jsx_runtime45.jsx)(
            "rect",
            {
              className: (0, import_classnames17.default)("tl-transparent", {
                "tl-hidden": hideBottomLeftCorner
              }),
              "data-testid": "selection.target.bottom-left",
              "aria-label": "bottom-left target",
              pointerEvents: "all",
              x: toDomPrecision(0 - (isSmallX ? targetSizeX * 3 : targetSizeX * 1.5)),
              y: toDomPrecision(height - (isSmallY ? 0 : targetSizeY * 1.5)),
              width: toDomPrecision(targetSizeX * 3),
              height: toDomPrecision(targetSizeY * 3),
              style: isDefaultCursor ? { cursor: getCursor("nesw-resize", rotation) } : void 0,
              ...bottomLeftEvents
            }
          ),
          showResizeHandles && (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
            (0, import_jsx_runtime45.jsx)(
              "rect",
              {
                "data-testid": "selection.resize.top-left",
                className: (0, import_classnames17.default)("tl-corner-handle", {
                  "tl-hidden": hideTopLeftCorner
                }),
                "aria-label": "top_left handle",
                x: toDomPrecision(0 - size2 / 2),
                y: toDomPrecision(0 - size2 / 2),
                width: toDomPrecision(size2),
                height: toDomPrecision(size2)
              }
            ),
            (0, import_jsx_runtime45.jsx)(
              "rect",
              {
                "data-testid": "selection.resize.top-right",
                className: (0, import_classnames17.default)("tl-corner-handle", {
                  "tl-hidden": hideTopRightCorner
                }),
                "aria-label": "top_right handle",
                x: toDomPrecision(width - size2 / 2),
                y: toDomPrecision(0 - size2 / 2),
                width: toDomPrecision(size2),
                height: toDomPrecision(size2)
              }
            ),
            (0, import_jsx_runtime45.jsx)(
              "rect",
              {
                "data-testid": "selection.resize.bottom-right",
                className: (0, import_classnames17.default)("tl-corner-handle", {
                  "tl-hidden": hideBottomRightCorner
                }),
                "aria-label": "bottom_right handle",
                x: toDomPrecision(width - size2 / 2),
                y: toDomPrecision(height - size2 / 2),
                width: toDomPrecision(size2),
                height: toDomPrecision(size2)
              }
            ),
            (0, import_jsx_runtime45.jsx)(
              "rect",
              {
                "data-testid": "selection.resize.bottom-left",
                className: (0, import_classnames17.default)("tl-corner-handle", {
                  "tl-hidden": hideBottomLeftCorner
                }),
                "aria-label": "bottom_left handle",
                x: toDomPrecision(0 - size2 / 2),
                y: toDomPrecision(height - size2 / 2),
                width: toDomPrecision(size2),
                height: toDomPrecision(size2)
              }
            )
          ] }),
          showTextResizeHandles && (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
            (0, import_jsx_runtime45.jsx)(
              "rect",
              {
                "data-testid": "selection.text-resize.left.handle",
                className: "tl-text-handle",
                "aria-label": "bottom_left handle",
                x: toDomPrecision(0 - size2 / 4),
                y: toDomPrecision(height / 2 - textHandleHeight / 2),
                rx: size2 / 4,
                width: toDomPrecision(size2 / 2),
                height: toDomPrecision(textHandleHeight)
              }
            ),
            (0, import_jsx_runtime45.jsx)(
              "rect",
              {
                "data-testid": "selection.text-resize.right.handle",
                className: "tl-text-handle",
                "aria-label": "bottom_left handle",
                rx: size2 / 4,
                x: toDomPrecision(width - size2 / 4),
                y: toDomPrecision(height / 2 - textHandleHeight / 2),
                width: toDomPrecision(size2 / 2),
                height: toDomPrecision(textHandleHeight)
              }
            )
          ] }),
          showCropHandles && (0, import_jsx_runtime45.jsx)(
            CropHandles,
            {
              ...{
                size: size2,
                width,
                height,
                hideAlternateHandles: hideAlternateCropHandles
              }
            }
          )
        ]
      }
    );
  }
);
var RotateCornerHandle = function RotateCornerHandle2({
  cx,
  cy,
  targetSize,
  corner,
  cursor,
  isHidden,
  "data-testid": testId
}) {
  const events = useSelectionEvents(corner);
  return (0, import_jsx_runtime45.jsx)(
    "rect",
    {
      className: (0, import_classnames17.default)("tl-transparent", "tl-rotate-corner", { "tl-hidden": isHidden }),
      "data-testid": testId,
      "aria-label": `${corner} target`,
      pointerEvents: "all",
      x: toDomPrecision(cx - targetSize * 3),
      y: toDomPrecision(cy - targetSize * 3),
      width: toDomPrecision(Math.max(1, targetSize * 3)),
      height: toDomPrecision(Math.max(1, targetSize * 3)),
      cursor,
      ...events
    }
  );
};
var SQUARE_ROOT_PI = Math.sqrt(Math.PI);
var MobileRotateHandle = function RotateHandle({
  cx,
  cy,
  size: size2,
  isHidden,
  "data-testid": testId
}) {
  const events = useSelectionEvents("mobile_rotate");
  const editor = useEditor();
  const zoom = useValue("zoom level", () => editor.zoomLevel, [editor]);
  const bgRadius = Math.max(14 * (1 / zoom), 20 / Math.max(1, zoom));
  return (0, import_jsx_runtime45.jsxs)("g", { children: [
    (0, import_jsx_runtime45.jsx)(
      "circle",
      {
        "data-testid": testId,
        pointerEvents: "all",
        className: (0, import_classnames17.default)("tl-transparent", "tl-mobile-rotate__bg", { "tl-hidden": isHidden }),
        cx,
        cy,
        r: bgRadius,
        ...events
      }
    ),
    (0, import_jsx_runtime45.jsx)(
      "circle",
      {
        className: (0, import_classnames17.default)("tl-mobile-rotate__fg", { "tl-hidden": isHidden }),
        cx,
        cy,
        r: size2 / SQUARE_ROOT_PI
      }
    )
  ] });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/default-shape-constants.mjs
var TEXT_PROPS = {
  lineHeight: 1.35,
  fontWeight: "normal",
  fontVariant: "normal",
  fontStyle: "normal",
  padding: "0px"
};
var STROKE_SIZES2 = {
  s: 2,
  m: 3.5,
  l: 5,
  xl: 10
};
var FONT_SIZES = {
  s: 18,
  m: 24,
  l: 36,
  xl: 44
};
var LABEL_FONT_SIZES = {
  s: 18,
  m: 22,
  l: 26,
  xl: 32
};
var ARROW_LABEL_FONT_SIZES = {
  s: 18,
  m: 20,
  l: 24,
  xl: 28
};
var FONT_FAMILIES = {
  draw: "var(--tl-font-draw)",
  sans: "var(--tl-font-sans)",
  serif: "var(--tl-font-serif)",
  mono: "var(--tl-font-mono)"
};

// node_modules/.deno/canvas-size@1.2.6/node_modules/canvas-size/dist/canvas-size.esm.js
function _iterableToArrayLimit(arr, i) {
  var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];
  if (null != _i) {
    var _s, _e, _x, _r, _arr = [], _n = true, _d = false;
    try {
      if (_x = (_i = _i.call(arr)).next, 0 === i) {
        if (Object(_i) !== _i)
          return;
        _n = false;
      } else
        for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = true)
          ;
    } catch (err) {
      _d = true, _e = err;
    } finally {
      try {
        if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r))
          return;
      } finally {
        if (_d)
          throw _e;
      }
    }
    return _arr;
  }
}
function ownKeys2(object2, enumerableOnly) {
  var keys = Object.keys(object2);
  if (Object.getOwnPropertySymbols) {
    var symbols = Object.getOwnPropertySymbols(object2);
    enumerableOnly && (symbols = symbols.filter(function(sym) {
      return Object.getOwnPropertyDescriptor(object2, sym).enumerable;
    })), keys.push.apply(keys, symbols);
  }
  return keys;
}
function _objectSpread22(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = null != arguments[i] ? arguments[i] : {};
    i % 2 ? ownKeys2(Object(source), true).forEach(function(key) {
      _defineProperty2(target, key, source[key]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys2(Object(source)).forEach(function(key) {
      Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
    });
  }
  return target;
}
function _defineProperty2(obj, key, value) {
  key = _toPropertyKey2(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function _objectWithoutPropertiesLoose2(source, excluded) {
  if (source == null)
    return {};
  var target = {};
  var sourceKeys = Object.keys(source);
  var key, i;
  for (i = 0; i < sourceKeys.length; i++) {
    key = sourceKeys[i];
    if (excluded.indexOf(key) >= 0)
      continue;
    target[key] = source[key];
  }
  return target;
}
function _objectWithoutProperties2(source, excluded) {
  if (source == null)
    return {};
  var target = _objectWithoutPropertiesLoose2(source, excluded);
  var key, i;
  if (Object.getOwnPropertySymbols) {
    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
    for (i = 0; i < sourceSymbolKeys.length; i++) {
      key = sourceSymbolKeys[i];
      if (excluded.indexOf(key) >= 0)
        continue;
      if (!Object.prototype.propertyIsEnumerable.call(source, key))
        continue;
      target[key] = source[key];
    }
  }
  return target;
}
function _slicedToArray(arr, i) {
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr))
    return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
  if (Array.isArray(arr))
    return arr;
}
function _iterableToArray(iter) {
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null)
    return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
  if (!o)
    return;
  if (typeof o === "string")
    return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor)
    n = o.constructor.name;
  if (n === "Map" || n === "Set")
    return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
    return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length)
    len = arr.length;
  for (var i = 0, arr2 = new Array(len); i < len; i++)
    arr2[i] = arr[i];
  return arr2;
}
function _nonIterableSpread() {
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _nonIterableRest() {
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _toPrimitive2(input, hint) {
  if (typeof input !== "object" || input === null)
    return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== void 0) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object")
      return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey2(arg) {
  var key = _toPrimitive2(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}
function canvasTest(settings) {
  var size2 = settings.sizes.shift();
  var width = Math.max(Math.ceil(size2[0]), 1);
  var height = Math.max(Math.ceil(size2[1]), 1);
  var fill = [width - 1, height - 1, 1, 1];
  var job = Date.now();
  var isWorker = typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope;
  var cropCvs, testCvs;
  if (isWorker) {
    cropCvs = new OffscreenCanvas(1, 1);
    testCvs = new OffscreenCanvas(width, height);
  } else {
    cropCvs = document.createElement("canvas");
    cropCvs.width = 1;
    cropCvs.height = 1;
    testCvs = document.createElement("canvas");
    testCvs.width = width;
    testCvs.height = height;
  }
  var cropCtx = cropCvs.getContext("2d");
  var testCtx = testCvs.getContext("2d");
  if (testCtx) {
    testCtx.fillRect.apply(testCtx, fill);
    cropCtx.drawImage(testCvs, width - 1, height - 1, 1, 1, 0, 0, 1, 1);
  }
  var isTestPass = cropCtx && cropCtx.getImageData(0, 0, 1, 1).data[3] !== 0;
  var benchmark = Date.now() - job;
  [cropCvs, testCvs].forEach(function(cvs) {
    cvs.height = 0;
    cvs.width = 0;
  });
  if (isWorker) {
    postMessage({
      width,
      height,
      benchmark,
      isTestPass
    });
    if (!isTestPass && settings.sizes.length) {
      canvasTest(settings);
    }
  } else if (isTestPass) {
    settings.onSuccess(width, height, benchmark);
  } else {
    settings.onError(width, height, benchmark);
    if (settings.sizes.length) {
      canvasTest(settings);
    }
  }
  return isTestPass;
}
var testSizes = {
  area: [16384, 14188, 11402, 11180, 10836, 8192, 4096, 1],
  height: [8388607, 65535, 32767, 16384, 8192, 4096, 1],
  width: [4194303, 65535, 32767, 16384, 8192, 4096, 1]
};
var _excluded2 = ["onError", "onSuccess"];
var defaults = {
  max: null,
  min: 1,
  sizes: [],
  step: 1024,
  usePromise: false,
  useWorker: false,
  onError: Function.prototype,
  onSuccess: Function.prototype
};
var workerJobs = {};
function createSizesArray(settings) {
  var isArea = settings.width === settings.height;
  var isWidth = settings.height === 1;
  var isHeight = settings.width === 1;
  var sizes = [];
  if (!settings.width || !settings.height) {
    settings.sizes.forEach(function(testSize2) {
      var width2 = isArea || isWidth ? testSize2 : 1;
      var height2 = isArea || isHeight ? testSize2 : 1;
      sizes.push([width2, height2]);
    });
  } else {
    var testMin = settings.min || defaults.min;
    var testStep = settings.step || defaults.step;
    var testSize = Math.max(settings.width, settings.height);
    while (testSize >= testMin) {
      var width = isArea || isWidth ? testSize : 1;
      var height = isArea || isHeight ? testSize : 1;
      sizes.push([width, height]);
      testSize -= testStep;
    }
  }
  return sizes;
}
function handleMethod(settings) {
  var hasCanvasSupport = window && "HTMLCanvasElement" in window;
  var hasOffscreenCanvasSupport = window && "OffscreenCanvas" in window;
  var jobID = Date.now();
  var _onError = settings.onError, _onSuccess = settings.onSuccess, settingsWithoutCallbacks = _objectWithoutProperties2(settings, _excluded2);
  var worker = null;
  if (!hasCanvasSupport) {
    return false;
  }
  if (settings.useWorker && hasOffscreenCanvasSupport) {
    var js = "\n            var canvasTest = ".concat(canvasTest.toString(), ";\n            onmessage = function(e) {\n                canvasTest(e.data);\n            };\n        ");
    var blob = new Blob([js], {
      type: "application/javascript"
    });
    var blobURL = URL.createObjectURL(blob);
    worker = new Worker(blobURL);
    URL.revokeObjectURL(blobURL);
    worker.onmessage = function(e) {
      var _e$data = e.data, width = _e$data.width, height = _e$data.height, benchmark = _e$data.benchmark, isTestPass = _e$data.isTestPass;
      if (isTestPass) {
        workerJobs[jobID].onSuccess(width, height, benchmark);
        delete workerJobs[jobID];
      } else {
        workerJobs[jobID].onError(width, height, benchmark);
      }
    };
  }
  if (settings.usePromise) {
    return new Promise(function(resolve, reject) {
      var promiseSettings = _objectSpread22(_objectSpread22({}, settings), {}, {
        onError: function onError2(width, height, benchmark) {
          var isLastTest;
          if (settings.sizes.length === 0) {
            isLastTest = true;
          } else {
            var _settings$sizes$slice = settings.sizes.slice(-1), _settings$sizes$slice2 = _slicedToArray(_settings$sizes$slice, 1), _settings$sizes$slice3 = _slicedToArray(_settings$sizes$slice2[0], 2), lastWidth = _settings$sizes$slice3[0], lastHeight = _settings$sizes$slice3[1];
            isLastTest = width === lastWidth && height === lastHeight;
          }
          _onError(width, height, benchmark);
          if (isLastTest) {
            reject({
              width,
              height,
              benchmark
            });
          }
        },
        onSuccess: function onSuccess2(width, height, benchmark) {
          _onSuccess(width, height, benchmark);
          resolve({
            width,
            height,
            benchmark
          });
        }
      });
      if (worker) {
        var onError = promiseSettings.onError, onSuccess = promiseSettings.onSuccess;
        workerJobs[jobID] = {
          onError,
          onSuccess
        };
        worker.postMessage(settingsWithoutCallbacks);
      } else {
        canvasTest(promiseSettings);
      }
    });
  } else {
    if (worker) {
      workerJobs[jobID] = {
        onError: _onError,
        onSuccess: _onSuccess
      };
      worker.postMessage(settingsWithoutCallbacks);
    } else {
      return canvasTest(settings);
    }
  }
}
var canvasSize = {
  maxArea: function maxArea() {
    var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
    var sizes = createSizesArray({
      width: options.max,
      height: options.max,
      min: options.min,
      step: options.step,
      sizes: _toConsumableArray(testSizes.area)
    });
    var settings = _objectSpread22(_objectSpread22(_objectSpread22({}, defaults), options), {}, {
      sizes
    });
    return handleMethod(settings);
  },
  maxHeight: function maxHeight() {
    var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
    var sizes = createSizesArray({
      width: 1,
      height: options.max,
      min: options.min,
      step: options.step,
      sizes: _toConsumableArray(testSizes.height)
    });
    var settings = _objectSpread22(_objectSpread22(_objectSpread22({}, defaults), options), {}, {
      sizes
    });
    return handleMethod(settings);
  },
  maxWidth: function maxWidth() {
    var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
    var sizes = createSizesArray({
      width: options.max,
      height: 1,
      min: options.min,
      step: options.step,
      sizes: _toConsumableArray(testSizes.width)
    });
    var settings = _objectSpread22(_objectSpread22(_objectSpread22({}, defaults), options), {}, {
      sizes
    });
    return handleMethod(settings);
  },
  test: function test() {
    var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
    var settings = _objectSpread22(_objectSpread22({}, defaults), options);
    settings.sizes = _toConsumableArray(settings.sizes);
    if (settings.width && settings.height) {
      settings.sizes = [[settings.width, settings.height]];
    }
    return handleMethod(settings);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/getBrowserCanvasMaxSize.mjs
var maxSizePromise = null;
function getBrowserCanvasMaxSize() {
  if (!maxSizePromise) {
    maxSizePromise = calculateBrowserCanvasMaxSize();
  }
  return maxSizePromise;
}
async function calculateBrowserCanvasMaxSize() {
  const maxWidth2 = await canvasSize.maxWidth({ usePromise: true });
  const maxHeight2 = await canvasSize.maxHeight({ usePromise: true });
  const maxArea2 = await canvasSize.maxArea({ usePromise: true });
  return {
    maxWidth: maxWidth2.width,
    maxHeight: maxHeight2.height,
    maxArea: maxArea2.width * maxArea2.height
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/is-gif-animated.mjs
function getDataBlocksLength(buffer, offset2) {
  let length = 0;
  while (buffer[offset2 + length]) {
    length += buffer[offset2 + length] + 1;
  }
  return length + 1;
}
function isGIF(buffer) {
  const enc = new TextDecoder("ascii");
  const header = enc.decode(buffer.slice(0, 3));
  return header === "GIF";
}
function isAnimated(buffer) {
  const view = new Uint8Array(buffer);
  let hasColorTable, colorTableSize;
  let offset2 = 0;
  let imagesCount = 0;
  if (!isGIF(buffer)) {
    return false;
  }
  hasColorTable = view[10] & 128;
  colorTableSize = view[10] & 7;
  offset2 += 6;
  offset2 += 7;
  offset2 += hasColorTable ? 3 * Math.pow(2, colorTableSize + 1) : 0;
  while (imagesCount < 2 && offset2 < view.length) {
    switch (view[offset2]) {
      case 44:
        imagesCount += 1;
        hasColorTable = view[offset2 + 9] & 128;
        colorTableSize = view[offset2 + 9] & 7;
        offset2 += 10;
        offset2 += hasColorTable ? 3 * Math.pow(2, colorTableSize + 1) : 0;
        offset2 += getDataBlocksLength(view, offset2 + 1) + 1;
        break;
      case 33:
        offset2 += 2;
        offset2 += getDataBlocksLength(view, offset2);
        break;
      case 59:
        offset2 = view.length;
        break;
      default:
        offset2 = view.length;
        break;
    }
  }
  return imagesCount > 1;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/assets.mjs
function containBoxSize(originalSize, containBoxSize2) {
  const overByXScale = originalSize.w / containBoxSize2.w;
  const overByYScale = originalSize.h / containBoxSize2.h;
  if (overByXScale <= 1 && overByYScale <= 1) {
    return originalSize;
  } else if (overByXScale > overByYScale) {
    return {
      w: originalSize.w / overByXScale,
      h: originalSize.h / overByXScale
    };
  } else {
    return {
      w: originalSize.w / overByYScale,
      h: originalSize.h / overByYScale
    };
  }
}
async function getResizedImageDataUrl(dataURLForImage, width, height) {
  return await new Promise((resolve) => {
    const img = new Image();
    img.onload = async () => {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      if (!ctx)
        return;
      const canvasSizes = await getBrowserCanvasMaxSize();
      let desiredWidth = width * 2;
      let desiredHeight = height * 2;
      const aspectRatio = img.width / img.height;
      if (desiredWidth > canvasSizes.maxWidth) {
        desiredWidth = canvasSizes.maxWidth;
        desiredHeight = desiredWidth / aspectRatio;
      }
      if (desiredHeight > canvasSizes.maxHeight) {
        desiredHeight = canvasSizes.maxHeight;
        desiredWidth = desiredHeight * aspectRatio;
      }
      if (desiredWidth * desiredHeight > canvasSizes.maxArea) {
        const ratio = Math.sqrt(canvasSizes.maxArea / (desiredWidth * desiredHeight));
        desiredWidth *= ratio;
        desiredHeight *= ratio;
      }
      canvas.width = desiredWidth;
      canvas.height = desiredHeight;
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      const newDataURL = canvas.toDataURL();
      resolve(newDataURL);
    };
    img.crossOrigin = "anonymous";
    img.src = dataURLForImage;
  });
}
var DEFAULT_ACCEPTED_IMG_TYPE = ["image/jpeg", "image/png", "image/gif", "image/svg+xml"];
var DEFAULT_ACCEPTED_VID_TYPE = ["video/mp4", "video/quicktime"];
async function isGifAnimated(file) {
  return await new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onerror = () => reject(reader.error);
    reader.onload = () => {
      resolve(reader.result ? isAnimated(reader.result) : false);
    };
    reader.readAsArrayBuffer(file);
  });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/embeds.mjs
function escapeStringRegexp(string2) {
  if (typeof string2 !== "string") {
    throw new TypeError("Expected a string");
  }
  return string2.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
}
function matchEmbedUrl(url) {
  const host = new URL(url).host.replace("www.", "");
  for (const localEmbedDef of EMBED_DEFINITIONS) {
    if (checkHostnames(localEmbedDef.hostnames, host)) {
      const originalUrl = localEmbedDef.fromEmbedUrl(url);
      if (originalUrl) {
        return {
          definition: localEmbedDef,
          url: originalUrl,
          embedUrl: url
        };
      }
    }
  }
}
var globlikeRegExp = (input) => {
  return input.split("*").map((str) => escapeStringRegexp(str)).join(".+");
};
var checkHostnames = (hostnames, targetHostname) => {
  return !!hostnames.find((hostname) => {
    const re = new RegExp(globlikeRegExp(hostname));
    return targetHostname.match(re);
  });
};
function matchUrl(url) {
  const host = new URL(url).host.replace("www.", "");
  for (const localEmbedDef of EMBED_DEFINITIONS) {
    if (checkHostnames(localEmbedDef.hostnames, host)) {
      const embedUrl = localEmbedDef.toEmbedUrl(url);
      if (embedUrl) {
        return {
          definition: localEmbedDef,
          embedUrl,
          url
        };
      }
    }
  }
}
function getEmbedInfoUnsafely(inputUrl) {
  const result = matchUrl(inputUrl) ?? matchEmbedUrl(inputUrl);
  return result;
}
function getEmbedInfo(inputUrl) {
  try {
    return getEmbedInfoUnsafely(inputUrl);
  } catch (e) {
    console.error(e);
  }
  return void 0;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs
var INDENT = "  ";
var TextHelpers = class _TextHelpers {
  static insertTextFirefox(field, text) {
    field.setRangeText(
      text,
      field.selectionStart || 0,
      field.selectionEnd || 0,
      "end"
      // Without this, the cursor is either at the beginning or text remains selected
    );
    field.dispatchEvent(
      new InputEvent("input", {
        data: text,
        inputType: "insertText",
        isComposing: false
        // TODO: fix @types/jsdom, this shouldn't be required
      })
    );
  }
  /**
   * Inserts text at the cursor’s position, replacing any selection, with **undo** support and by
   * firing the input event.
   */
  static insert(field, text) {
    const document2 = field.ownerDocument;
    const initialFocus = document2.activeElement;
    if (initialFocus !== field) {
      field.focus();
    }
    if (!document2.execCommand("insertText", false, text)) {
      _TextHelpers.insertTextFirefox(field, text);
    }
    if (initialFocus === document2.body) {
      field.blur();
    } else if (initialFocus instanceof HTMLElement && initialFocus !== field) {
      initialFocus.focus();
    }
  }
  /**
   * Replaces the entire content, equivalent to field.value = text but with **undo** support and by
   * firing the input event.
   */
  static set(field, text) {
    field.select();
    _TextHelpers.insert(field, text);
  }
  /** Get the selected text in a field or an empty string if nothing is selected. */
  static getSelection(field) {
    const { selectionStart, selectionEnd } = field;
    return field.value.slice(
      selectionStart ? selectionStart : void 0,
      selectionEnd ? selectionEnd : void 0
    );
  }
  /**
   * Adds the wrappingText before and after field’s selection (or cursor). If endWrappingText is
   * provided, it will be used instead of wrappingText at on the right.
   */
  static wrapSelection(field, wrap2, wrapEnd) {
    const { selectionStart, selectionEnd } = field;
    const selection = _TextHelpers.getSelection(field);
    _TextHelpers.insert(field, wrap2 + selection + (wrapEnd ?? wrap2));
    field.selectionStart = (selectionStart || 0) + wrap2.length;
    field.selectionEnd = (selectionEnd || 0) + wrap2.length;
  }
  /** Finds and replaces strings and regex in the field’s value. */
  static replace(field, searchValue, replacer) {
    let drift = 0;
    field.value.replace(searchValue, (...args) => {
      const matchStart = drift + args[args.length - 2];
      const matchLength = args[0].length;
      field.selectionStart = matchStart;
      field.selectionEnd = matchStart + matchLength;
      const replacement = typeof replacer === "string" ? replacer : replacer(...args);
      _TextHelpers.insert(field, replacement);
      field.selectionStart = matchStart;
      drift += replacement.length - matchLength;
      return replacement;
    });
  }
  static findLineEnd(value, currentEnd) {
    const lastLineStart = value.lastIndexOf("\n", currentEnd - 1) + 1;
    if (value.charAt(lastLineStart) !== "	") {
      return currentEnd;
    }
    return lastLineStart + 1;
  }
  static indent(element) {
    const { selectionStart, selectionEnd, value } = element;
    const selectedContrast = value.slice(selectionStart, selectionEnd);
    const lineBreakCount = /\n/g.exec(selectedContrast)?.length;
    if (lineBreakCount && lineBreakCount > 0) {
      const firstLineStart = value.lastIndexOf("\n", selectionStart - 1) + 1;
      const newSelection = element.value.slice(firstLineStart, selectionEnd - 1);
      const indentedText = newSelection.replace(
        /^|\n/g,
        // Match all line starts
        `$&${INDENT}`
      );
      const replacementsCount = indentedText.length - newSelection.length;
      element.setSelectionRange(firstLineStart, selectionEnd - 1);
      _TextHelpers.insert(element, indentedText);
      element.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount);
    } else {
      _TextHelpers.insert(element, INDENT);
    }
  }
  // The first line should always be unindented
  // The last line should only be unindented if the selection includes any characters after \n
  static unindent(element) {
    const { selectionStart, selectionEnd, value } = element;
    const firstLineStart = value.lastIndexOf("\n", selectionStart - 1) + 1;
    const minimumSelectionEnd = _TextHelpers.findLineEnd(value, selectionEnd);
    const newSelection = element.value.slice(firstLineStart, minimumSelectionEnd);
    const indentedText = newSelection.replace(/(^|\n)(\t| {1,2})/g, "$1");
    const replacementsCount = newSelection.length - indentedText.length;
    element.setSelectionRange(firstLineStart, minimumSelectionEnd);
    _TextHelpers.insert(element, indentedText);
    const firstLineIndentation = /\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart));
    const difference = firstLineIndentation ? firstLineIndentation[0].length : 0;
    const newSelectionStart = selectionStart - difference;
    element.setSelectionRange(
      selectionStart - difference,
      Math.max(newSelectionStart, selectionEnd - replacementsCount)
    );
  }
  static indentCE(element) {
    const selection = window.getSelection();
    const value = element.innerText;
    const selectionStart = getCaretIndex(element) ?? 0;
    const selectionEnd = getCaretIndex(element) ?? 0;
    const selectedContrast = value.slice(selectionStart, selectionEnd);
    const lineBreakCount = /\n/g.exec(selectedContrast)?.length;
    if (lineBreakCount && lineBreakCount > 0) {
      const firstLineStart = value.lastIndexOf("\n", selectionStart - 1) + 1;
      const newSelection = value.slice(firstLineStart, selectionEnd - 1);
      const indentedText = newSelection.replace(
        /^|\n/g,
        // Match all line starts
        `$&${INDENT}`
      );
      const replacementsCount = indentedText.length - newSelection.length;
      if (selection) {
        selection.setBaseAndExtent(
          element,
          selectionStart + 1,
          element,
          selectionEnd + replacementsCount
        );
      }
    } else {
      const selection2 = window.getSelection();
      element.innerText = value.slice(0, selectionStart) + INDENT + value.slice(selectionStart);
      selection2?.setBaseAndExtent(element, selectionStart + 1, element, selectionStart + 2);
    }
  }
  static unindentCE(element) {
    const selection = window.getSelection();
    const value = element.innerText;
    const selectionStart = getCaretIndex(element) ?? 0;
    const selectionEnd = getCaretIndex(element) ?? 0;
    const firstLineStart = value.lastIndexOf("\n", selectionStart - 1) + 1;
    const minimumSelectionEnd = _TextHelpers.findLineEnd(value, selectionEnd);
    const newSelection = value.slice(firstLineStart, minimumSelectionEnd);
    const indentedText = newSelection.replace(/(^|\n)(\t| {1,2})/g, "$1");
    const replacementsCount = newSelection.length - indentedText.length;
    if (selection) {
      selection.setBaseAndExtent(element, firstLineStart, element, minimumSelectionEnd);
      const firstLineIndentation = /\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart));
      const difference = firstLineIndentation ? firstLineIndentation[0].length : 0;
      const newSelectionStart = selectionStart - difference;
      selection.setBaseAndExtent(
        element,
        selectionStart - difference,
        element,
        Math.max(newSelectionStart, selectionEnd - replacementsCount)
      );
    }
  }
  static fixNewLines = /\r?\n|\r/g;
  static normalizeText(text) {
    return text.replace(_TextHelpers.fixNewLines, "\n");
  }
  static normalizeTextForDom(text) {
    return text.replace(_TextHelpers.fixNewLines, "\n").split("\n").map((x) => x || " ").join("\n");
  }
};
function getCaretIndex(element) {
  if (typeof window.getSelection === "undefined")
    return;
  const selection = window.getSelection();
  if (!selection)
    return;
  let position = 0;
  if (selection.rangeCount !== 0) {
    const range = selection.getRangeAt(0);
    const preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(element);
    preCaretRange.setEnd(range.endContainer, range.endOffset);
    position = preCaretRange.toString().length;
  }
  return position;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/text.mjs
var rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
function isRightToLeftLanguage(text) {
  return rtlRegex.test(text);
}
function replaceTabsWithSpaces(text) {
  return text.replace(/\t/g, INDENT);
}
function stripCommonMinimumIndentation(text) {
  const lines = text.split("\n");
  while (lines[0].trim().length === 0) {
    lines.shift();
  }
  let minIndentation = Infinity;
  for (const line of lines) {
    if (line.trim().length > 0) {
      const indentation = line.length - line.trimStart().length;
      minIndentation = Math.min(minIndentation, indentation);
    }
  }
  return lines.map((line) => line.slice(minIndentation)).join("\n");
}
function stripTrailingWhitespace(text) {
  return text.replace(/[ \t]+$/gm, "").replace(/\n+$/, "");
}
function cleanupText(text) {
  return stripTrailingWhitespace(stripCommonMinimumIndentation(replaceTabsWithSpaces(text)));
}
var truncateStringWithEllipsis = (str, maxLength) => {
  return str.length <= maxLength ? str : str.substring(0, maxLength - 3) + "...";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/defaultExternalContentHandlers.mjs
function registerDefaultExternalContentHandlers(editor, {
  maxImageDimension,
  maxAssetSize,
  acceptedImageMimeTypes,
  acceptedVideoMimeTypes
}) {
  editor.registerExternalAssetHandler("file", async ({ file }) => {
    return await new Promise((resolve, reject) => {
      if (!acceptedImageMimeTypes.includes(file.type) && !acceptedVideoMimeTypes.includes(file.type)) {
        console.warn(`File type not allowed: ${file.type}`);
        reject();
      }
      if (file.size > maxAssetSize) {
        console.warn(
          `File size too big: ${(file.size / 1024).toFixed()}kb > ${(maxAssetSize / 1024).toFixed()}kb`
        );
        reject();
      }
      const reader = new FileReader();
      reader.onerror = () => reject(reader.error);
      reader.onload = async () => {
        let dataUrl = reader.result;
        if (file.type === "video/quicktime" && dataUrl.includes("video/quicktime")) {
          dataUrl = dataUrl.replace("video/quicktime", "video/mp4");
        }
        const isImageType = acceptedImageMimeTypes.includes(file.type);
        let size2;
        let isAnimated2;
        if (isImageType) {
          size2 = await MediaHelpers.getImageSizeFromSrc(dataUrl);
          isAnimated2 = file.type === "image/gif" && await isGifAnimated(file);
        } else {
          isAnimated2 = true;
          size2 = await MediaHelpers.getVideoSizeFromSrc(dataUrl);
        }
        if (isFinite(maxImageDimension)) {
          const resizedSize = containBoxSize(size2, { w: maxImageDimension, h: maxImageDimension });
          if (size2 !== resizedSize && (file.type === "image/jpeg" || file.type === "image/png")) {
            dataUrl = await getResizedImageDataUrl(dataUrl, size2.w, size2.h);
          }
          size2 = resizedSize;
        }
        const assetId = AssetRecordType.createId(getHashForString(dataUrl));
        const asset = AssetRecordType.create({
          id: assetId,
          type: isImageType ? "image" : "video",
          typeName: "asset",
          props: {
            name: file.name,
            src: dataUrl,
            w: size2.w,
            h: size2.h,
            mimeType: file.type,
            isAnimated: isAnimated2
          }
        });
        resolve(asset);
      };
      reader.readAsDataURL(file);
    });
  });
  editor.registerExternalAssetHandler("url", async ({ url }) => {
    let meta;
    try {
      const resp = await fetch(url, { method: "GET", mode: "no-cors" });
      const html = await resp.text();
      const doc = new DOMParser().parseFromString(html, "text/html");
      meta = {
        image: doc.head.querySelector('meta[property="og:image"]')?.getAttribute("content") ?? "",
        title: doc.head.querySelector('meta[property="og:title"]')?.getAttribute("content") ?? truncateStringWithEllipsis(url, 32),
        description: doc.head.querySelector('meta[property="og:description"]')?.getAttribute("content") ?? ""
      };
    } catch (error) {
      console.error(error);
      meta = { image: "", title: truncateStringWithEllipsis(url, 32), description: "" };
    }
    return {
      id: AssetRecordType.createId(getHashForString(url)),
      typeName: "asset",
      type: "bookmark",
      props: {
        src: url,
        description: meta.description,
        image: meta.image,
        title: meta.title
      },
      meta: {}
    };
  });
  editor.registerExternalContentHandler("svg-text", async ({ point, text }) => {
    const position = point ?? (editor.inputs.shiftKey ? editor.inputs.currentPagePoint : editor.viewportPageCenter);
    const svg = new DOMParser().parseFromString(text, "image/svg+xml").querySelector("svg");
    if (!svg) {
      throw new Error("No <svg/> element present");
    }
    let width = parseFloat(svg.getAttribute("width") || "0");
    let height = parseFloat(svg.getAttribute("height") || "0");
    if (!(width && height)) {
      document.body.appendChild(svg);
      const box = svg.getBoundingClientRect();
      document.body.removeChild(svg);
      width = box.width;
      height = box.height;
    }
    const asset = await editor.getAssetForExternalContent({
      type: "file",
      file: new File([text], "asset.svg", { type: "image/svg+xml" })
    });
    if (!asset)
      throw Error("Could not create an asset");
    createShapesForAssets(editor, [asset], position);
  });
  editor.registerExternalContentHandler("embed", ({ point, url, embed }) => {
    const position = point ?? (editor.inputs.shiftKey ? editor.inputs.currentPagePoint : editor.viewportPageCenter);
    const { width, height } = embed;
    const id = createShapeId();
    const shapePartial = {
      id,
      type: "embed",
      x: position.x - (width || 450) / 2,
      y: position.y - (height || 450) / 2,
      props: {
        w: width,
        h: height,
        url
      }
    };
    editor.createShapes([shapePartial]).select(id);
  });
  editor.registerExternalContentHandler("files", async ({ point, files }) => {
    const position = point ?? (editor.inputs.shiftKey ? editor.inputs.currentPagePoint : editor.viewportPageCenter);
    const pagePoint = new Vec2d(position.x, position.y);
    const assets = [];
    await Promise.all(
      files.map(async (file, i) => {
        if (file.size > maxAssetSize) {
          console.warn(
            `File size too big: ${(file.size / 1024).toFixed()}kb > ${(maxAssetSize / 1024).toFixed()}kb`
          );
          return null;
        }
        if (!file.type) {
          throw new Error("No mime type");
        }
        if (!acceptedImageMimeTypes.concat(acceptedVideoMimeTypes).includes(file.type)) {
          console.warn(`${file.name} not loaded - Extension not allowed.`);
          return null;
        }
        try {
          const asset = await editor.getAssetForExternalContent({ type: "file", file });
          if (!asset) {
            throw Error("Could not create an asset");
          }
          assets[i] = asset;
        } catch (error) {
          console.error(error);
          return null;
        }
      })
    );
    createShapesForAssets(editor, compact(assets), pagePoint);
  });
  editor.registerExternalContentHandler("text", async ({ point, text }) => {
    const p = point ?? (editor.inputs.shiftKey ? editor.inputs.currentPagePoint : editor.viewportPageCenter);
    const defaultProps = editor.getShapeUtil("text").getDefaultProps();
    const textToPaste = cleanupText(text);
    let w;
    let h;
    let autoSize;
    let align = "middle";
    const isMultiLine = textToPaste.split("\n").length > 1;
    const isRtl = isRightToLeftLanguage(textToPaste);
    if (isMultiLine) {
      align = isMultiLine ? isRtl ? "end" : "start" : "middle";
    }
    const rawSize = editor.textMeasure.measureText(textToPaste, {
      ...TEXT_PROPS,
      fontFamily: FONT_FAMILIES[defaultProps.font],
      fontSize: FONT_SIZES[defaultProps.size],
      maxWidth: null
    });
    const minWidth = Math.min(
      isMultiLine ? editor.viewportPageBounds.width * 0.9 : 920,
      Math.max(200, editor.viewportPageBounds.width * 0.9)
    );
    if (rawSize.w > minWidth) {
      const shrunkSize = editor.textMeasure.measureText(textToPaste, {
        ...TEXT_PROPS,
        fontFamily: FONT_FAMILIES[defaultProps.font],
        fontSize: FONT_SIZES[defaultProps.size],
        maxWidth: minWidth
      });
      w = shrunkSize.w;
      h = shrunkSize.h;
      autoSize = false;
      align = isRtl ? "end" : "start";
    } else {
      w = rawSize.w;
      h = rawSize.h;
      autoSize = true;
    }
    if (p.y - h / 2 < editor.viewportPageBounds.minY + 40) {
      p.y = editor.viewportPageBounds.minY + 40 + h / 2;
    }
    editor.createShapes([
      {
        id: createShapeId(),
        type: "text",
        x: p.x - w / 2,
        y: p.y - h / 2,
        props: {
          text: textToPaste,
          // if the text has more than one line, align it to the left
          align,
          autoSize,
          w
        }
      }
    ]);
  });
  editor.registerExternalContentHandler("url", async ({ point, url }) => {
    const embedInfo = getEmbedInfo(url);
    if (embedInfo) {
      return editor.putExternalContent({
        type: "embed",
        url: embedInfo.url,
        point,
        embed: embedInfo.definition
      });
    }
    const position = point ?? (editor.inputs.shiftKey ? editor.inputs.currentPagePoint : editor.viewportPageCenter);
    const assetId = AssetRecordType.createId(getHashForString(url));
    let asset = editor.getAsset(assetId);
    let shouldAlsoCreateAsset = false;
    if (!asset) {
      shouldAlsoCreateAsset = true;
      const bookmarkAsset = await editor.getAssetForExternalContent({ type: "url", url });
      if (!bookmarkAsset)
        throw Error("Could not create an asset");
      asset = bookmarkAsset;
    }
    editor.batch(() => {
      if (shouldAlsoCreateAsset) {
        editor.createAssets([asset]);
      }
      createShapesForAssets(editor, [asset], position);
    });
  });
}
async function createShapesForAssets(editor, assets, position) {
  if (!assets.length)
    return;
  const currentPoint = Vec2d.From(position);
  const partials = [];
  for (const asset of assets) {
    switch (asset.type) {
      case "bookmark": {
        partials.push({
          id: createShapeId(),
          type: "bookmark",
          x: currentPoint.x - 150,
          y: currentPoint.y - 160,
          opacity: 1,
          props: {
            assetId: asset.id,
            url: asset.props.src
          }
        });
        currentPoint.x += 300;
        break;
      }
      case "image": {
        partials.push({
          id: createShapeId(),
          type: "image",
          x: currentPoint.x - asset.props.w / 2,
          y: currentPoint.y - asset.props.h / 2,
          opacity: 1,
          props: {
            assetId: asset.id,
            w: asset.props.w,
            h: asset.props.h
          }
        });
        currentPoint.x += asset.props.w;
        break;
      }
      case "video": {
        partials.push({
          id: createShapeId(),
          type: "video",
          x: currentPoint.x - asset.props.w / 2,
          y: currentPoint.y - asset.props.h / 2,
          opacity: 1,
          props: {
            assetId: asset.id,
            w: asset.props.w,
            h: asset.props.h
          }
        });
        currentPoint.x += asset.props.w;
      }
    }
  }
  editor.batch(() => {
    const assetsToCreate = assets.filter((asset) => !editor.getAsset(asset.id));
    if (assetsToCreate.length) {
      editor.createAssets(assetsToCreate);
    }
    editor.createShapes(partials).select(...partials.map((p) => p.id));
    const { viewportPageBounds } = editor;
    let { selectionPageBounds } = editor;
    if (selectionPageBounds) {
      const offset2 = selectionPageBounds.center.sub(position);
      editor.updateShapes(
        editor.selectedShapes.map((shape) => {
          const localRotation = editor.getShapeParentTransform(shape).decompose().rotation;
          const localDelta = Vec2d.Rot(offset2, -localRotation);
          return {
            id: shape.id,
            type: shape.type,
            x: shape.x - localDelta.x,
            y: shape.y - localDelta.y
          };
        })
      );
    }
    selectionPageBounds = editor.selectionPageBounds;
    if (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {
      editor.zoomToSelection();
    }
  });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs
var Idle2 = class extends StateNode {
  static id = "idle";
  onPointerDown = (info) => {
    this.parent.transition("pointing", info);
  };
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
  onKeyUp = (info) => {
    if (info.key === "Enter") {
      if (this.editor.instanceState.isReadonly)
        return null;
      const { onlySelectedShape } = this.editor;
      if (onlySelectedShape && this.editor.getShapeUtil(onlySelectedShape).canEdit(onlySelectedShape)) {
        this.editor.setCurrentTool("select");
        this.editor.setEditingShape(onlySelectedShape.id);
        this.editor.root.current.value.transition("editing_shape", {
          ...info,
          target: "shape",
          shape: onlySelectedShape
        });
      }
    }
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs
var Pointing2 = class extends StateNode {
  static id = "pointing";
  shape;
  markId = "";
  onEnter = () => {
    this.didTimeout = false;
    const target = this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
      filter: (targetShape) => {
        return !targetShape.isLocked && this.editor.getShapeUtil(targetShape).canBind(targetShape);
      },
      margin: 0,
      hitInside: true,
      renderingOnly: true
    });
    if (!target) {
      this.createArrowShape();
    } else {
      this.editor.setHintingShapes([target.id]);
    }
    this.startPreciseTimeout();
  };
  onExit = () => {
    this.shape = void 0;
    this.editor.setHintingShapes([]);
    this.clearPreciseTimeout();
  };
  onPointerMove = () => {
    if (this.editor.inputs.isDragging) {
      if (!this.shape) {
        this.createArrowShape();
      }
      if (!this.shape)
        throw Error(`expected shape`);
      this.updateArrowShapeEndHandle();
      this.editor.setCurrentTool("select.dragging_handle", {
        shape: this.shape,
        handle: this.editor.getShapeHandles(this.shape).find((h) => h.id === "end"),
        isCreating: true,
        onInteractionEnd: "arrow"
      });
    }
  };
  onPointerUp = () => {
    this.cancel();
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  cancel() {
    if (this.shape) {
      this.editor.bailToMark(this.markId);
    }
    this.editor.setHintingShapes([]);
    this.parent.transition("idle", {});
  }
  createArrowShape() {
    const { originPagePoint } = this.editor.inputs;
    const id = createShapeId();
    this.markId = `creating:${id}`;
    this.editor.mark(this.markId);
    this.editor.createShapes([
      {
        id,
        type: "arrow",
        x: originPagePoint.x,
        y: originPagePoint.y
      }
    ]);
    const shape = this.editor.getShape(id);
    if (!shape)
      throw Error(`expected shape`);
    const handles = this.editor.getShapeHandles(shape);
    if (!handles)
      throw Error(`expected handles for arrow`);
    const util = this.editor.getShapeUtil("arrow");
    const startHandle = handles.find((h) => h.id === "start");
    const change = util.onHandleChange?.(shape, {
      handle: { ...startHandle, x: 0, y: 0 },
      isPrecise: true
    });
    if (change) {
      const startTerminal = change.props?.start;
      if (startTerminal?.type === "binding") {
        this.editor.setHintingShapes([startTerminal.boundShapeId]);
      }
      this.editor.updateShapes([change], { squashing: true });
    }
    this.shape = this.editor.getShape(id);
    this.editor.select(id);
  }
  updateArrowShapeEndHandle() {
    const shape = this.shape;
    if (!shape)
      throw Error(`expected shape`);
    const handles = this.editor.getShapeHandles(shape);
    if (!handles)
      throw Error(`expected handles for arrow`);
    const shapeWithOutEndOffset = {
      ...shape,
      props: { ...shape.props, end: { ...shape.props.end, x: 0, y: 0 } }
    };
    {
      const util = this.editor.getShapeUtil("arrow");
      const point = this.editor.getPointInShapeSpace(shape, this.editor.inputs.currentPagePoint);
      const endHandle = handles.find((h) => h.id === "end");
      const change = util.onHandleChange?.(shapeWithOutEndOffset, {
        handle: { ...endHandle, x: point.x, y: point.y },
        isPrecise: false
        // sure about that?
      });
      if (change) {
        const endTerminal = change.props?.end;
        if (endTerminal?.type === "binding") {
          this.editor.setHintingShapes([endTerminal.boundShapeId]);
        }
        this.editor.updateShapes([change], { squashing: true });
      }
    }
    {
      const util = this.editor.getShapeUtil("arrow");
      const startHandle = handles.find((h) => h.id === "start");
      const change = util.onHandleChange?.(shapeWithOutEndOffset, {
        handle: { ...startHandle, x: 0, y: 0 },
        isPrecise: this.didTimeout
        // sure about that?
      });
      if (change) {
        this.editor.updateShapes([change], { squashing: true });
      }
    }
    this.shape = this.editor.getShape(shape.id);
  }
  preciseTimeout = -1;
  didTimeout = false;
  startPreciseTimeout() {
    this.preciseTimeout = window.setTimeout(() => {
      if (!this.isActive)
        return;
      this.didTimeout = true;
    }, 320);
  }
  clearPreciseTimeout() {
    clearTimeout(this.preciseTimeout);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/arrow/ArrowShapeTool.mjs
var ArrowShapeTool = class extends StateNode {
  static id = "arrow";
  static initial = "idle";
  static children = () => [Idle2, Pointing2];
  shapeType = "arrow";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs
var Drawing = class extends StateNode {
  static id = "drawing";
  info = {};
  initialShape;
  shapeType = this.parent.id === "highlight" ? "highlight" : "draw";
  util = this.editor.getShapeUtil(this.shapeType);
  isPen = false;
  segmentMode = "free";
  didJustShiftClickToExtendPreviousShapeLine = false;
  pagePointWhereCurrentSegmentChanged = {};
  pagePointWhereNextSegmentChanged = null;
  lastRecordedPoint = {};
  mergeNextPoint = false;
  currentLineLength = 0;
  canDraw = false;
  markId = null;
  onEnter = (info) => {
    this.markId = null;
    this.info = info;
    this.canDraw = !this.editor.isMenuOpen;
    this.lastRecordedPoint = this.editor.inputs.currentPagePoint.clone();
    if (this.canDraw) {
      this.startShape();
    }
  };
  onPointerMove = () => {
    const {
      editor: { inputs }
    } = this;
    if (this.isPen !== inputs.isPen) {
      if (this.markId) {
        this.editor.bailToMark(this.markId);
        this.startShape();
        return;
      }
    } else {
      if (!this.canDraw && inputs.isDragging) {
        this.startShape();
        this.canDraw = true;
      }
    }
    if (this.canDraw) {
      if (inputs.isPen) {
        if (Vec2d.Dist(inputs.currentPagePoint, this.lastRecordedPoint) >= 1 / this.editor.zoomLevel) {
          this.lastRecordedPoint = inputs.currentPagePoint.clone();
          this.mergeNextPoint = false;
        } else {
          this.mergeNextPoint = true;
        }
      } else {
        this.mergeNextPoint = false;
      }
      this.updateShapes();
    }
  };
  onKeyDown = (info) => {
    if (info.key === "Shift") {
      switch (this.segmentMode) {
        case "free": {
          this.segmentMode = "starting_straight";
          this.pagePointWhereNextSegmentChanged = this.editor.inputs.currentPagePoint.clone();
          break;
        }
        case "starting_free": {
          this.segmentMode = "starting_straight";
        }
      }
    }
    this.updateShapes();
  };
  onKeyUp = (info) => {
    if (info.key === "Shift") {
      this.editor.snaps.clear();
      switch (this.segmentMode) {
        case "straight": {
          this.segmentMode = "starting_free";
          this.pagePointWhereNextSegmentChanged = this.editor.inputs.currentPagePoint.clone();
          break;
        }
        case "starting_straight": {
          this.pagePointWhereNextSegmentChanged = null;
          this.segmentMode = "free";
          break;
        }
      }
    }
    this.updateShapes();
  };
  onExit = () => {
    this.editor.snaps.clear();
    this.pagePointWhereCurrentSegmentChanged = this.editor.inputs.currentPagePoint.clone();
  };
  canClose() {
    return this.shapeType !== "highlight";
  }
  getIsClosed(segments, size2) {
    if (!this.canClose())
      return false;
    const strokeWidth = STROKE_SIZES2[size2];
    const firstPoint = segments[0].points[0];
    const lastSegment = segments[segments.length - 1];
    const lastPoint = lastSegment.points[lastSegment.points.length - 1];
    return firstPoint !== lastPoint && this.currentLineLength > strokeWidth * 4 && Vec2d.Dist(firstPoint, lastPoint) < strokeWidth * 2;
  }
  startShape() {
    const {
      inputs: { originPagePoint, isPen }
    } = this.editor;
    this.markId = "draw start " + uniqueId();
    this.editor.mark(this.markId);
    this.isPen = isPen;
    const pressure = this.isPen ? this.info.point.z * 1.25 : 0.5;
    this.segmentMode = this.editor.inputs.shiftKey ? "straight" : "free";
    this.didJustShiftClickToExtendPreviousShapeLine = false;
    this.lastRecordedPoint = originPagePoint.clone();
    if (this.initialShape) {
      const shape = this.editor.getShape(this.initialShape.id);
      if (shape && this.segmentMode === "straight") {
        this.didJustShiftClickToExtendPreviousShapeLine = true;
        const prevSegment = last(shape.props.segments);
        if (!prevSegment)
          throw Error("Expected a previous segment!");
        const prevPoint = last(prevSegment.points);
        if (!prevPoint)
          throw Error("Expected a previous point!");
        const { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed();
        const pressure2 = this.isPen ? this.info.point.z * 1.25 : 0.5;
        const newSegment = {
          type: this.segmentMode,
          points: [
            {
              x: prevPoint.x,
              y: prevPoint.y,
              z: +pressure2.toFixed(2)
            },
            {
              x,
              y,
              z: +pressure2.toFixed(2)
            }
          ]
        };
        const prevPointPageSpace = Matrix2d.applyToPoint(
          this.editor.getShapePageTransform(shape.id),
          prevPoint
        );
        this.pagePointWhereCurrentSegmentChanged = prevPointPageSpace;
        this.pagePointWhereNextSegmentChanged = null;
        const segments = [...shape.props.segments, newSegment];
        this.currentLineLength = this.getLineLength(segments);
        const shapePartial = {
          id: shape.id,
          type: this.shapeType,
          props: {
            segments
          }
        };
        if (this.canClose()) {
          ;
          shapePartial.props.isClosed = this.getIsClosed(
            segments,
            shape.props.size
          );
        }
        this.editor.updateShapes([shapePartial]);
        return;
      }
    }
    this.pagePointWhereCurrentSegmentChanged = originPagePoint.clone();
    const id = createShapeId();
    this.editor.createShapes([
      {
        id,
        type: this.shapeType,
        x: originPagePoint.x,
        y: originPagePoint.y,
        props: {
          isPen: this.isPen,
          segments: [
            {
              type: this.segmentMode,
              points: [
                {
                  x: 0,
                  y: 0,
                  z: +pressure.toFixed(2)
                }
              ]
            }
          ]
        }
      }
    ]);
    this.currentLineLength = 0;
    this.initialShape = this.editor.getShape(id);
  }
  updateShapes() {
    const { inputs } = this.editor;
    const { initialShape } = this;
    if (!initialShape)
      return;
    const {
      id,
      props: { size: size2 }
    } = initialShape;
    const shape = this.editor.getShape(id);
    if (!shape)
      return;
    const { segments } = shape.props;
    const { x, y, z } = this.editor.getPointInShapeSpace(shape, inputs.currentPagePoint).toFixed();
    const newPoint = { x, y, z: this.isPen ? +(z * 1.25).toFixed(2) : 0.5 };
    switch (this.segmentMode) {
      case "starting_straight": {
        const { pagePointWhereNextSegmentChanged } = this;
        if (pagePointWhereNextSegmentChanged === null) {
          throw Error("We should have a point where the segment changed");
        }
        const hasMovedFarEnough = Vec2d.Dist(pagePointWhereNextSegmentChanged, inputs.currentPagePoint) > DRAG_DISTANCE;
        if (hasMovedFarEnough) {
          this.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged.clone();
          this.pagePointWhereNextSegmentChanged = null;
          this.segmentMode = "straight";
          const prevSegment = last(segments);
          if (!prevSegment)
            throw Error("Expected a previous segment!");
          const prevLastPoint = last(prevSegment.points);
          if (!prevLastPoint)
            throw Error("Expected a previous last point!");
          let newSegment;
          const newLastPoint = this.editor.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged).toFixed().toJson();
          if (prevSegment.type === "straight") {
            this.currentLineLength += Vec2d.Dist(prevLastPoint, newLastPoint);
            newSegment = {
              type: "straight",
              points: [{ ...prevLastPoint }, newLastPoint]
            };
            const transform = this.editor.getShapePageTransform(shape);
            this.pagePointWhereCurrentSegmentChanged = Matrix2d.applyToPoint(
              transform,
              prevLastPoint
            );
          } else {
            newSegment = {
              type: "straight",
              points: [newLastPoint, newPoint]
            };
          }
          const shapePartial = {
            id,
            type: this.shapeType,
            props: {
              segments: [...segments, newSegment]
            }
          };
          if (this.canClose()) {
            ;
            shapePartial.props.isClosed = this.getIsClosed(
              segments,
              size2
            );
          }
          this.editor.updateShapes([shapePartial], {
            squashing: true
          });
        }
        break;
      }
      case "starting_free": {
        const { pagePointWhereNextSegmentChanged } = this;
        if (pagePointWhereNextSegmentChanged === null) {
          throw Error("We should have a point where the segment changed");
        }
        const hasMovedFarEnough = Vec2d.Dist(pagePointWhereNextSegmentChanged, inputs.currentPagePoint) > DRAG_DISTANCE;
        if (hasMovedFarEnough) {
          this.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged.clone();
          this.pagePointWhereNextSegmentChanged = null;
          this.segmentMode = "free";
          const newSegments = segments.slice();
          const prevStraightSegment = newSegments[newSegments.length - 1];
          const prevPoint = last(prevStraightSegment.points);
          if (!prevPoint) {
            throw Error("No previous point!");
          }
          const newFreeSegment = {
            type: "free",
            points: [
              ...Vec2d.PointsBetween(prevPoint, newPoint, 6).map((p) => p.toFixed().toJson())
            ]
          };
          const finalSegments = [...newSegments, newFreeSegment];
          this.currentLineLength = this.getLineLength(finalSegments);
          const shapePartial = {
            id,
            type: this.shapeType,
            props: {
              segments: finalSegments
            }
          };
          if (this.canClose()) {
            ;
            shapePartial.props.isClosed = this.getIsClosed(
              finalSegments,
              size2
            );
          }
          this.editor.updateShapes([shapePartial], { squashing: true });
        }
        break;
      }
      case "straight": {
        const newSegments = segments.slice();
        const newSegment = newSegments[newSegments.length - 1];
        const { pagePointWhereCurrentSegmentChanged } = this;
        const { currentPagePoint, ctrlKey } = this.editor.inputs;
        if (!pagePointWhereCurrentSegmentChanged)
          throw Error("We should have a point where the segment changed");
        let pagePoint;
        let shouldSnapToAngle = false;
        if (this.didJustShiftClickToExtendPreviousShapeLine) {
          if (this.editor.inputs.isDragging) {
            shouldSnapToAngle = !ctrlKey;
            this.didJustShiftClickToExtendPreviousShapeLine = false;
          } else {
          }
        } else {
          shouldSnapToAngle = !ctrlKey;
        }
        let newPoint2 = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed().toJson();
        let didSnap = false;
        let snapSegment = void 0;
        const shouldSnap = this.editor.user.isSnapMode ? !ctrlKey : ctrlKey;
        if (shouldSnap) {
          if (newSegments.length > 2) {
            let nearestPoint = void 0;
            let minDistance = 8 / this.editor.zoomLevel;
            for (let i = 0, n = segments.length - 2; i < n; i++) {
              const segment = segments[i];
              if (!segment)
                break;
              if (segment.type === "free")
                continue;
              const first = segment.points[0];
              const lastPoint = last(segment.points);
              if (!(first && lastPoint))
                continue;
              const nearestPointOnSegment = Vec2d.NearestPointOnLineSegment(
                first,
                lastPoint,
                newPoint2
              );
              const distance = Vec2d.Dist(nearestPointOnSegment, newPoint2);
              if (distance < minDistance) {
                nearestPoint = nearestPointOnSegment.toFixed().toJson();
                minDistance = distance;
                snapSegment = segment;
                break;
              }
            }
            if (nearestPoint) {
              didSnap = true;
              newPoint2 = nearestPoint;
            }
          }
        }
        if (didSnap && snapSegment) {
          const transform = this.editor.getShapePageTransform(shape);
          const first = snapSegment.points[0];
          const lastPoint = last(snapSegment.points);
          if (!lastPoint)
            throw Error("Expected a last point!");
          const A = Matrix2d.applyToPoint(transform, first);
          const B = Matrix2d.applyToPoint(transform, lastPoint);
          const snappedPoint = Matrix2d.applyToPoint(transform, newPoint2);
          this.editor.snaps.setLines([
            {
              id: uniqueId(),
              type: "points",
              points: [A, snappedPoint, B]
            }
          ]);
        } else {
          this.editor.snaps.clear();
          if (shouldSnapToAngle) {
            const currentAngle = Vec2d.Angle(pagePointWhereCurrentSegmentChanged, currentPagePoint);
            const snappedAngle = snapAngle(currentAngle, 24);
            const angleDiff = snappedAngle - currentAngle;
            pagePoint = Vec2d.RotWith(
              currentPagePoint,
              pagePointWhereCurrentSegmentChanged,
              angleDiff
            );
          } else {
            pagePoint = currentPagePoint;
          }
          newPoint2 = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson();
        }
        this.currentLineLength += Vec2d.Dist(newSegment.points[0], newPoint2);
        newSegments[newSegments.length - 1] = {
          ...newSegment,
          type: "straight",
          points: [newSegment.points[0], newPoint2]
        };
        const shapePartial = {
          id,
          type: this.shapeType,
          props: {
            segments: newSegments
          }
        };
        if (this.canClose()) {
          ;
          shapePartial.props.isClosed = this.getIsClosed(
            segments,
            size2
          );
        }
        this.editor.updateShapes([shapePartial], { squashing: true });
        break;
      }
      case "free": {
        const newSegments = segments.slice();
        const newSegment = newSegments[newSegments.length - 1];
        const newPoints = [...newSegment.points];
        if (newPoints.length && this.mergeNextPoint) {
          const { z: z2 } = newPoints[newPoints.length - 1];
          newPoints[newPoints.length - 1] = {
            x: newPoint.x,
            y: newPoint.y,
            z: z2 ? Math.max(z2, newPoint.z) : newPoint.z
          };
        } else {
          this.currentLineLength += Vec2d.Dist(newPoints[newPoints.length - 1], newPoint);
          newPoints.push(newPoint);
        }
        newSegments[newSegments.length - 1] = {
          ...newSegment,
          points: newPoints
        };
        this.currentLineLength = this.getLineLength(newSegments);
        const shapePartial = {
          id,
          type: this.shapeType,
          props: {
            segments: newSegments
          }
        };
        if (this.canClose()) {
          ;
          shapePartial.props.isClosed = this.getIsClosed(
            newSegments,
            size2
          );
        }
        this.editor.updateShapes([shapePartial], { squashing: true });
        if (newPoints.length > 500) {
          this.editor.updateShapes([{ id, type: this.shapeType, props: { isComplete: true } }]);
          const { currentPagePoint } = this.editor.inputs;
          const newShapeId = createShapeId();
          this.editor.createShapes([
            {
              id: newShapeId,
              type: this.shapeType,
              x: toFixed(currentPagePoint.x),
              y: toFixed(currentPagePoint.y),
              props: {
                isPen: this.isPen,
                segments: [
                  {
                    type: "free",
                    points: [{ x: 0, y: 0, z: this.isPen ? +(z * 1.25).toFixed() : 0.5 }]
                  }
                ]
              }
            }
          ]);
          this.initialShape = structuredClone(this.editor.getShape(newShapeId));
          this.mergeNextPoint = false;
          this.lastRecordedPoint = this.editor.inputs.currentPagePoint.clone();
          this.currentLineLength = 0;
        }
        break;
      }
    }
  }
  getLineLength(segments) {
    let length = 0;
    for (const segment of segments) {
      for (let i = 0; i < segment.points.length - 1; i++) {
        const A = segment.points[i];
        const B = segment.points[i + 1];
        length += Vec2d.Sub(B, A).len2();
      }
    }
    return Math.sqrt(length);
  }
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  onInterrupt = () => {
    if (this.editor.inputs.isDragging) {
      return;
    }
    if (this.markId) {
      this.editor.bailToMark(this.markId);
    }
    this.cancel();
  };
  complete() {
    if (!this.canDraw) {
      this.cancel();
      return;
    }
    const { initialShape } = this;
    if (!initialShape)
      return;
    this.editor.updateShapes([
      { id: initialShape.id, type: initialShape.type, props: { isComplete: true } }
    ]);
    this.parent.transition("idle", {});
  }
  cancel() {
    this.parent.transition("idle", this.info);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/draw/toolStates/Idle.mjs
var Idle3 = class extends StateNode {
  static id = "idle";
  onPointerDown = (info) => {
    this.parent.transition("drawing", info);
  };
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/draw/DrawShapeTool.mjs
var DrawShapeTool = class extends StateNode {
  static id = "draw";
  static initial = "idle";
  static children = () => [Idle3, Drawing];
  shapeType = "draw";
  onExit = () => {
    const drawingState = this.children["drawing"];
    drawingState.initialShape = void 0;
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/frame/FrameShapeTool.mjs
var FrameShapeTool = class extends BaseBoxShapeTool {
  static id = "frame";
  static initial = "idle";
  shapeType = "frame";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/toolStates/Idle.mjs
var Idle4 = class extends StateNode {
  static id = "idle";
  onPointerDown = (info) => {
    this.parent.transition("pointing", info);
  };
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
  onKeyUp = (info) => {
    if (info.key === "Enter") {
      if (this.editor.instanceState.isReadonly)
        return null;
      const { onlySelectedShape } = this.editor;
      if (onlySelectedShape && this.editor.getShapeUtil(onlySelectedShape).canEdit(onlySelectedShape)) {
        this.editor.setCurrentTool("select");
        this.editor.setEditingShape(onlySelectedShape.id);
        this.editor.root.current.value.transition("editing_shape", {
          ...info,
          target: "shape",
          shape: onlySelectedShape
        });
      }
    }
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs
var Pointing3 = class extends StateNode {
  static id = "pointing";
  markId = "";
  onPointerUp = () => {
    this.complete();
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      const { originPagePoint } = this.editor.inputs;
      const id = createShapeId();
      this.markId = `creating:${id}`;
      this.editor.mark(this.markId);
      this.editor.createShapes([
        {
          id,
          type: "geo",
          x: originPagePoint.x,
          y: originPagePoint.y,
          props: {
            w: 1,
            h: 1,
            geo: this.editor.getStyleForNextShape(GeoShapeGeoStyle)
          }
        }
      ]).select(id).setCurrentTool("select.resizing", {
        ...info,
        target: "selection",
        handle: "bottom_right",
        isCreating: true,
        creationCursorOffset: { x: 1, y: 1 },
        onInteractionEnd: "geo"
      });
    }
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  onInterrupt = () => {
    this.cancel();
  };
  complete() {
    const { originPagePoint } = this.editor.inputs;
    const id = createShapeId();
    this.markId = `creating:${id}`;
    this.editor.mark(this.markId);
    this.editor.createShapes([
      {
        id,
        type: "geo",
        x: originPagePoint.x,
        y: originPagePoint.y,
        props: {
          geo: this.editor.getStyleForNextShape(GeoShapeGeoStyle),
          w: 1,
          h: 1
        }
      }
    ]);
    const shape = this.editor.getShape(id);
    if (!shape)
      return;
    const bounds = shape.props.geo === "star" ? getStarBounds(5, 200, 200) : shape.props.geo === "cloud" ? new Box2d(0, 0, 300, 180) : new Box2d(0, 0, 200, 200);
    const delta = bounds.center;
    const parentTransform = this.editor.getShapeParentTransform(shape);
    if (parentTransform)
      delta.rot(-parentTransform.rotation());
    this.editor.select(id);
    this.editor.updateShapes([
      {
        id: shape.id,
        type: "geo",
        x: shape.x - delta.x,
        y: shape.y - delta.y,
        props: {
          geo: this.editor.getStyleForNextShape(GeoShapeGeoStyle),
          w: bounds.width,
          h: bounds.height
        }
      }
    ]);
    if (this.editor.instanceState.isToolLocked) {
      this.parent.transition("idle", {});
    } else {
      this.editor.setCurrentTool("select", {});
    }
  }
  cancel() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/GeoShapeTool.mjs
var GeoShapeTool = class extends StateNode {
  static id = "geo";
  static initial = "idle";
  static children = () => [Idle4, Pointing3];
  shapeType = "geo";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/highlight/HighlightShapeTool.mjs
var HighlightShapeTool = class extends StateNode {
  static id = "highlight";
  static initial = "idle";
  static children = () => [Idle3, Drawing];
  shapeType = "highlight";
  onExit = () => {
    const drawingState = this.children["drawing"];
    drawingState.initialShape = void 0;
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/line/toolStates/Idle.mjs
var Idle5 = class extends StateNode {
  static id = "idle";
  shapeId = "";
  onEnter = (info) => {
    this.shapeId = info.shapeId;
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
  onPointerDown = () => {
    this.parent.transition("pointing", { shapeId: this.shapeId });
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/line/toolStates/Pointing.mjs
var MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES = 2;
var Pointing4 = class extends StateNode {
  static id = "pointing";
  shape = {};
  markId;
  onEnter = (info) => {
    const { inputs } = this.editor;
    const { currentPagePoint } = inputs;
    this.markId = void 0;
    const shape = info.shapeId && this.editor.getShape(info.shapeId);
    if (shape && inputs.shiftKey) {
      this.markId = `creating:${shape.id}`;
      this.editor.mark(this.markId);
      this.shape = shape;
      const handles = this.editor.getShapeHandles(this.shape);
      if (!handles)
        return;
      const vertexHandles = handles.filter((h) => h.type === "vertex").sort(sortByIndex2);
      const endHandle = vertexHandles[vertexHandles.length - 1];
      const prevEndHandle = vertexHandles[vertexHandles.length - 2];
      const shapePagePoint = Matrix2d.applyToPoint(
        this.editor.getShapeParentTransform(this.shape),
        new Vec2d(this.shape.x, this.shape.y)
      );
      let nextEndHandleIndex, nextEndHandleId, nextEndHandle;
      const nextPoint = Vec2d.Sub(currentPagePoint, shapePagePoint);
      if (Vec2d.Dist(endHandle, prevEndHandle) < MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES || Vec2d.Dist(nextPoint, endHandle) < MINIMUM_DISTANCE_BETWEEN_SHIFT_CLICKED_HANDLES) {
        nextEndHandleIndex = endHandle.index;
        nextEndHandleId = endHandle.id;
        nextEndHandle = {
          ...endHandle,
          x: nextPoint.x + 0.1,
          y: nextPoint.y + 0.1
        };
      } else {
        nextEndHandleIndex = getIndexAbove(endHandle.index);
        nextEndHandleId = "handle:" + nextEndHandleIndex;
        nextEndHandle = {
          id: nextEndHandleId,
          type: "vertex",
          index: nextEndHandleIndex,
          x: nextPoint.x + 0.1,
          y: nextPoint.y + 0.1,
          canBind: false
        };
      }
      const nextHandles = structuredClone2(this.shape.props.handles);
      nextHandles[nextEndHandle.id] = nextEndHandle;
      this.editor.updateShapes([
        {
          id: this.shape.id,
          type: this.shape.type,
          props: {
            handles: nextHandles
          }
        }
      ]);
    } else {
      const id = createShapeId();
      this.markId = `creating:${id}`;
      this.editor.mark(this.markId);
      this.editor.createShapes([
        {
          id,
          type: "line",
          x: currentPagePoint.x,
          y: currentPagePoint.y
        }
      ]);
      this.editor.select(id);
      this.shape = this.editor.getShape(id);
    }
  };
  onPointerMove = () => {
    if (!this.shape)
      return;
    if (this.editor.inputs.isDragging) {
      const handles = this.editor.getShapeHandles(this.shape);
      console;
      if (!handles) {
        if (this.markId)
          this.editor.bailToMark(this.markId);
        throw Error("No handles found");
      }
      const lastHandle = last(handles);
      this.editor.setCurrentTool("select.dragging_handle", {
        shape: this.shape,
        isCreating: true,
        // remove the offset that we added to the handle when we created it
        handle: { ...lastHandle, x: lastHandle.x - 0.1, y: lastHandle.y - 0.1 },
        onInteractionEnd: "line"
      });
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  onInterrupt = () => {
    this.parent.transition("idle", {});
    if (this.markId)
      this.editor.bailToMark(this.markId);
    this.editor.snaps.clear();
  };
  complete() {
    this.parent.transition("idle", { shapeId: this.shape.id });
    this.editor.snaps.clear();
  }
  cancel() {
    if (this.markId)
      this.editor.bailToMark(this.markId);
    this.parent.transition("idle", { shapeId: this.shape.id });
    this.editor.snaps.clear();
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/line/LineShapeTool.mjs
var LineShapeTool = class extends StateNode {
  static id = "line";
  static initial = "idle";
  static children = () => [Idle5, Pointing4];
  shapeType = "line";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/note/toolStates/Idle.mjs
var Idle6 = class extends StateNode {
  static id = "idle";
  onPointerDown = (info) => {
    this.parent.transition("pointing", info);
  };
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/note/toolStates/Pointing.mjs
var Pointing5 = class extends StateNode {
  static id = "pointing";
  dragged = false;
  info = {};
  wasFocusedOnEnter = false;
  markId = "";
  shape = {};
  onEnter = () => {
    this.wasFocusedOnEnter = !this.editor.isMenuOpen;
    if (this.wasFocusedOnEnter) {
      this.shape = this.createShape();
    }
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      if (!this.wasFocusedOnEnter) {
        this.shape = this.createShape();
      }
      this.editor.setCurrentTool("select.translating", {
        ...info,
        target: "shape",
        shape: this.shape,
        isCreating: true,
        editAfterComplete: true,
        onInteractionEnd: "note"
      });
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  onInterrupt = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  complete() {
    if (this.wasFocusedOnEnter) {
      if (this.editor.instanceState.isToolLocked) {
        this.parent.transition("idle", {});
      } else {
        this.editor.setEditingShape(this.shape.id);
        this.editor.setCurrentTool("select.editing_shape", {
          ...this.info,
          target: "shape",
          shape: this.shape
        });
      }
    }
  }
  cancel() {
    this.editor.bailToMark(this.markId);
    this.parent.transition("idle", this.info);
  }
  createShape() {
    const {
      inputs: { originPagePoint }
    } = this.editor;
    const id = createShapeId();
    this.markId = `creating:${id}`;
    this.editor.mark(this.markId);
    this.editor.createShapes([
      {
        id,
        type: "note",
        x: originPagePoint.x,
        y: originPagePoint.y
      }
    ]).select(id);
    const shape = this.editor.getShape(id);
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    this.editor.updateShapes([
      {
        id,
        type: "note",
        x: shape.x - bounds.width / 2,
        y: shape.y - bounds.height / 2
      }
    ]);
    return this.editor.getShape(id);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/note/NoteShapeTool.mjs
var NoteShapeTool = class extends StateNode {
  static id = "note";
  static initial = "idle";
  static children = () => [Idle6, Pointing5];
  shapeType = "note";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/selection-logic/updateHoveredId.mjs
function updateHoveredId(editor) {
  const hitShape = editor.getShapeAtPoint(editor.inputs.currentPagePoint, {
    hitInside: false,
    hitLabels: false,
    margin: HIT_TEST_MARGIN / editor.zoomLevel,
    renderingOnly: true
  });
  if (!hitShape)
    return editor.setHoveredShape(null);
  let shapeToHover = void 0;
  const outermostShape = editor.getOutermostSelectableShape(hitShape);
  if (outermostShape === hitShape) {
    shapeToHover = hitShape;
  } else {
    if (outermostShape.id === editor.focusedGroupId || editor.selectedShapeIds.includes(outermostShape.id)) {
      shapeToHover = hitShape;
    } else {
      shapeToHover = outermostShape;
    }
  }
  return editor.setHoveredShape(shapeToHover.id);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/text/toolStates/Idle.mjs
var Idle7 = class extends StateNode {
  static id = "idle";
  onPointerMove = (info) => {
    switch (info.target) {
      case "shape":
      case "canvas": {
        updateHoveredId(this.editor);
      }
    }
  };
  onPointerDown = (info) => {
    this.parent.transition("pointing", info);
  };
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
  onKeyDown = (info) => {
    if (info.key === "Enter") {
      if (this.editor.instanceState.isReadonly)
        return null;
      const { onlySelectedShape } = this.editor;
      if (onlySelectedShape && this.editor.getShapeUtil(onlySelectedShape).canEdit(onlySelectedShape)) {
        this.editor.setCurrentTool("select");
        this.editor.setEditingShape(onlySelectedShape.id);
        this.editor.root.current.value.transition("editing_shape", {
          ...info,
          target: "shape",
          shape: onlySelectedShape
        });
      }
    }
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/text/toolStates/Pointing.mjs
var Pointing6 = class extends StateNode {
  static id = "pointing";
  shape;
  markId = "";
  onExit = () => {
    this.editor.setHintingShapes([]);
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      const {
        inputs: { originPagePoint }
      } = this.editor;
      const id = createShapeId();
      this.markId = `creating:${id}`;
      this.editor.mark(this.markId);
      this.editor.createShapes([
        {
          id,
          type: "text",
          x: originPagePoint.x,
          y: originPagePoint.y,
          props: {
            text: "",
            autoSize: false,
            w: 20
          }
        }
      ]);
      this.editor.select(id);
      this.shape = this.editor.getShape(id);
      if (!this.shape)
        return;
      this.editor.setCurrentTool("select.resizing", {
        ...info,
        target: "selection",
        handle: "right",
        isCreating: true,
        creationCursorOffset: { x: 1, y: 1 },
        editAfterComplete: true,
        onInteractionEnd: "text"
      });
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.cancel();
  };
  onCancel = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  complete() {
    this.editor.mark("creating text shape");
    const id = createShapeId();
    const { x, y } = this.editor.inputs.currentPagePoint;
    this.editor.createShapes([
      {
        id,
        type: "text",
        x,
        y,
        props: {
          text: "",
          autoSize: true
        }
      }
    ]).select(id);
    this.editor.setEditingShape(id);
    this.editor.setCurrentTool("select");
    this.editor.root.current.value?.transition("editing_shape", {});
  }
  cancel() {
    this.parent.transition("idle", {});
    this.editor.bailToMark(this.markId);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/text/TextShapeTool.mjs
var TextShapeTool = class extends StateNode {
  static id = "text";
  static initial = "idle";
  static children = () => [Idle7, Pointing6];
  shapeType = "text";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/defaultShapeTools.mjs
var defaultShapeTools = [
  TextShapeTool,
  DrawShapeTool,
  GeoShapeTool,
  NoteShapeTool,
  LineShapeTool,
  FrameShapeTool,
  ArrowShapeTool,
  HighlightShapeTool
];

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs
var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
var import_react45 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/ShapeFill.mjs
var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
var import_react42 = __toESM(require_react(), 1);
function useDefaultColorTheme() {
  return getDefaultColorTheme({ isDarkMode: useIsDarkMode() });
}
var ShapeFill = import_react42.default.memo(function ShapeFill2({ theme, d, color, fill }) {
  switch (fill) {
    case "none": {
      return null;
    }
    case "solid": {
      return (0, import_jsx_runtime46.jsx)("path", { fill: theme[color].semi, d });
    }
    case "semi": {
      return (0, import_jsx_runtime46.jsx)("path", { fill: theme.solid, d });
    }
    case "pattern": {
      return (0, import_jsx_runtime46.jsx)(PatternFill, { theme, color, fill, d });
    }
  }
});
var PatternFill = function PatternFill2({ d, color, theme }) {
  const editor = useEditor();
  const zoomLevel = useValue("zoomLevel", () => editor.zoomLevel, [editor]);
  const intZoom = Math.ceil(zoomLevel);
  const teenyTiny = editor.zoomLevel <= 0.18;
  return (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
    (0, import_jsx_runtime46.jsx)("path", { fill: theme[color].pattern, d }),
    (0, import_jsx_runtime46.jsx)(
      "path",
      {
        fill: teenyTiny ? theme[color].semi : `url(#${HASH_PATTERN_ZOOM_NAMES[`${intZoom}_${theme.id}`]})`,
        d
      }
    )
  ] });
};
function getShapeFillSvg({ d, color, fill, theme }) {
  if (fill === "none") {
    return;
  }
  if (fill === "pattern") {
    const gEl = document.createElementNS("http://www.w3.org/2000/svg", "g");
    const path1El = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path1El.setAttribute("d", d);
    path1El.setAttribute("fill", theme[color].pattern);
    const path2El = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path2El.setAttribute("d", d);
    path2El.setAttribute("fill", `url(#hash_pattern)`);
    gEl.appendChild(path1El);
    gEl.appendChild(path2El);
    return gEl;
  }
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
  path.setAttribute("d", d);
  switch (fill) {
    case "semi": {
      path.setAttribute("fill", theme.solid);
      break;
    }
    case "solid": {
      {
        path.setAttribute("fill", theme[color].semi);
      }
      break;
    }
  }
  return path;
}
function getSvgWithShapeFill(foregroundPath, backgroundPath) {
  if (backgroundPath) {
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    g.appendChild(backgroundPath);
    g.appendChild(foregroundPath);
    return g;
  } else {
    return foregroundPath;
  }
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/createTextSvgElementFromSpans.mjs
function correctSpacesToNbsp(input) {
  return input.replace(/\s/g, " ");
}
function createTextSvgElementFromSpans(editor, spans, opts) {
  const { padding = 0 } = opts;
  const textElm = document.createElementNS("http://www.w3.org/2000/svg", "text");
  textElm.setAttribute("font-size", opts.fontSize + "px");
  textElm.setAttribute("font-family", opts.fontFamily);
  textElm.setAttribute("font-style", opts.fontStyle);
  textElm.setAttribute("font-weight", opts.fontWeight);
  textElm.setAttribute("line-height", opts.lineHeight * opts.fontSize + "px");
  textElm.setAttribute("dominant-baseline", "mathematical");
  textElm.setAttribute("alignment-baseline", "mathematical");
  if (spans.length === 0)
    return textElm;
  const bounds = Box2d.From(spans[0].box);
  for (const { box } of spans) {
    bounds.union(box);
  }
  const offsetX = padding + (opts.offsetX ?? 0);
  const offsetY = (opts.offsetY ?? 0) + opts.fontSize / 2 + (opts.verticalTextAlign === "start" ? padding : opts.verticalTextAlign === "end" ? opts.height - padding - bounds.height : (Math.ceil(opts.height) - bounds.height) / 2);
  let currentLineTop = null;
  for (const { text, box } of spans) {
    const didBreakLine = currentLineTop !== null && box.y > currentLineTop;
    if (didBreakLine) {
      const lineBreakTspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
      lineBreakTspan.setAttribute("alignment-baseline", "mathematical");
      lineBreakTspan.setAttribute("x", offsetX + "px");
      lineBreakTspan.setAttribute("y", box.y + offsetY + "px");
      lineBreakTspan.textContent = "\n";
      textElm.appendChild(lineBreakTspan);
    }
    const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
    tspan.setAttribute("alignment-baseline", "mathematical");
    tspan.setAttribute("x", box.x + offsetX + "px");
    tspan.setAttribute("y", box.y + offsetY + "px");
    const cleanText = correctSpacesToNbsp(text);
    tspan.textContent = cleanText;
    textElm.appendChild(tspan);
    currentLineTop = box.y;
  }
  if (opts.stroke && opts.strokeWidth) {
    textElm.setAttribute("stroke", opts.stroke);
    textElm.setAttribute("stroke-width", opts.strokeWidth + "px");
  }
  if (opts.fill) {
    textElm.setAttribute("fill", opts.fill);
  }
  return textElm;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs
var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
var import_react43 = __toESM(require_react(), 1);
function getFontDefForExport(fontStyle) {
  return {
    key: `${DefaultFontStyle.id}:${fontStyle}`,
    getElement: async () => {
      const font = findFont(fontStyle);
      if (!font)
        return null;
      const url = font.$$_url;
      const fontFaceRule = font.$$_fontface;
      if (!url || !fontFaceRule)
        return null;
      const fontFile = await (await fetch(url)).blob();
      const base64FontFile = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = reject;
        reader.readAsDataURL(fontFile);
      });
      const newFontFaceRule = fontFaceRule.replace(url, base64FontFile);
      const style = document.createElementNS("http://www.w3.org/2000/svg", "style");
      style.textContent = newFontFaceRule;
      return style;
    }
  };
}
function findFont(name) {
  const fontFamily = DefaultFontFamilies[name];
  for (const font of document.fonts) {
    if (fontFamily.includes(font.family)) {
      return font;
    }
  }
  return null;
}
function getFillDefForExport(fill, theme) {
  return {
    key: `${DefaultFontStyle.id}:${fill}`,
    getElement: async () => {
      if (fill !== "pattern")
        return null;
      const t2 = 8 / 12;
      const divEl = document.createElement("div");
      divEl.innerHTML = `
				<svg>
					<defs>
						<mask id="hash_pattern_mask">
							<rect x="0" y="0" width="8" height="8" fill="white" />
							<g
								strokeLinecap="round"
								stroke="black"
							>
								<line x1="${t2 * 1}" y1="${t2 * 3}" x2="${t2 * 3}" y2="${t2 * 1}" />
								<line x1="${t2 * 5}" y1="${t2 * 7}" x2="${t2 * 7}" y2="${t2 * 5}" />
								<line x1="${t2 * 9}" y1="${t2 * 11}" x2="${t2 * 11}" y2="${t2 * 9}" />
							</g>
						</mask>
						<pattern
							id="hash_pattern"
							width="8"
							height="8"
							patternUnits="userSpaceOnUse"
						>
							<rect x="0" y="0" width="8" height="8" fill="${theme.solid}" mask="url(#hash_pattern_mask)" />
						</pattern>
					</defs>
				</svg>
			`;
      return Array.from(divEl.querySelectorAll("defs > *"));
    }
  };
}
function getFillDefForCanvas() {
  return {
    key: `${DefaultFontStyle.id}:pattern`,
    component: PatternFillDefForCanvas
  };
}
var TILE_PATTERN_SIZE = 8;
var generateImage = (dpr, currentZoom, darkMode) => {
  return new Promise((resolve, reject) => {
    const size2 = TILE_PATTERN_SIZE * currentZoom * dpr;
    const canvasEl = document.createElement("canvas");
    canvasEl.width = size2;
    canvasEl.height = size2;
    const ctx = canvasEl.getContext("2d");
    if (!ctx)
      return;
    ctx.fillStyle = darkMode ? "#212529" : "#f8f9fa";
    ctx.fillRect(0, 0, size2, size2);
    ctx.globalCompositeOperation = "destination-out";
    ctx.lineCap = "round";
    ctx.lineWidth = 1.25 * currentZoom * dpr;
    const t2 = 8 / 12;
    const s = (v) => v * currentZoom * dpr;
    ctx.beginPath();
    ctx.moveTo(s(t2 * 1), s(t2 * 3));
    ctx.lineTo(s(t2 * 3), s(t2 * 1));
    ctx.moveTo(s(t2 * 5), s(t2 * 7));
    ctx.lineTo(s(t2 * 7), s(t2 * 5));
    ctx.moveTo(s(t2 * 9), s(t2 * 11));
    ctx.lineTo(s(t2 * 11), s(t2 * 9));
    ctx.stroke();
    canvasEl.toBlob((blob) => {
      if (!blob || debugFlags.throwToBlob.value) {
        reject();
      } else {
        resolve(blob);
      }
    });
  });
};
var canvasBlob = (size2, fn) => {
  const canvas = document.createElement("canvas");
  canvas.width = size2[0];
  canvas.height = size2[1];
  const ctx = canvas.getContext("2d");
  if (!ctx)
    return "";
  fn(ctx);
  return canvas.toDataURL();
};
var getDefaultPatterns = () => {
  const defaultPatterns = [];
  for (let i = 1; i <= Math.ceil(MAX_ZOOM); i++) {
    const whitePixelBlob = canvasBlob([1, 1], (ctx) => {
      ctx.fillStyle = DefaultColorThemePalette.lightMode.black.semi;
      ctx.fillRect(0, 0, 1, 1);
    });
    const blackPixelBlob = canvasBlob([1, 1], (ctx) => {
      ctx.fillStyle = DefaultColorThemePalette.darkMode.black.semi;
      ctx.fillRect(0, 0, 1, 1);
    });
    defaultPatterns.push({
      zoom: i,
      url: whitePixelBlob,
      darkMode: false
    });
    defaultPatterns.push({
      zoom: i,
      url: blackPixelBlob,
      darkMode: true
    });
  }
  return defaultPatterns;
};
function usePattern() {
  const editor = useEditor();
  const dpr = editor.instanceState.devicePixelRatio;
  const [isReady, setIsReady] = (0, import_react43.useState)(false);
  const defaultPatterns = (0, import_react43.useMemo)(() => getDefaultPatterns(), []);
  const [backgroundUrls, setBackgroundUrls] = (0, import_react43.useState)(defaultPatterns);
  (0, import_react43.useEffect)(() => {
    const promises = [];
    for (let i = 1; i <= Math.ceil(MAX_ZOOM); i++) {
      promises.push(
        generateImage(dpr, i, false).then((blob) => ({
          zoom: i,
          url: URL.createObjectURL(blob),
          darkMode: false
        }))
      );
      promises.push(
        generateImage(dpr, i, true).then((blob) => ({
          zoom: i,
          url: URL.createObjectURL(blob),
          darkMode: true
        }))
      );
    }
    let isCancelled = false;
    Promise.all(promises).then((urls) => {
      if (isCancelled)
        return;
      setBackgroundUrls(urls);
      setIsReady(true);
    });
    return () => {
      isCancelled = true;
      setIsReady(false);
    };
  }, [dpr]);
  const defs = (0, import_jsx_runtime47.jsx)(import_jsx_runtime47.Fragment, { children: backgroundUrls.map((item) => {
    const key = item.zoom + (item.darkMode ? "_dark" : "_light");
    return (0, import_jsx_runtime47.jsx)(
      "pattern",
      {
        id: HASH_PATTERN_ZOOM_NAMES[key],
        width: TILE_PATTERN_SIZE,
        height: TILE_PATTERN_SIZE,
        patternUnits: "userSpaceOnUse",
        children: (0, import_jsx_runtime47.jsx)("image", { href: item.url, width: TILE_PATTERN_SIZE, height: TILE_PATTERN_SIZE })
      },
      key
    );
  }) });
  return { defs, isReady };
}
function PatternFillDefForCanvas() {
  const editor = useEditor();
  const containerRef = (0, import_react43.useRef)(null);
  const { defs, isReady } = usePattern();
  (0, import_react43.useEffect)(() => {
    if (isReady && editor.environment.isSafari) {
      const htmlLayer = findHtmlLayerParent(containerRef.current);
      if (htmlLayer) {
        requestAnimationFrame(() => {
          htmlLayer.style.display = "none";
          requestAnimationFrame(() => {
            htmlLayer.style.display = "";
          });
        });
      }
    }
  }, [editor, isReady]);
  return (0, import_jsx_runtime47.jsx)("g", { ref: containerRef, children: defs });
}
function findHtmlLayerParent(element) {
  if (element.classList.contains("tl-html-layer"))
    return element;
  if (element.parentElement)
    return findHtmlLayerParent(element.parentElement);
  return null;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/getPerfectDashProps.mjs
function getPerfectDashProps2(totalLength, strokeWidth, opts = {}) {
  const {
    closed = false,
    snap = 1,
    start = "outset",
    end = "outset",
    lengthRatio = 2,
    style = "dashed"
  } = opts;
  let dashLength = 0;
  let dashCount = 0;
  let ratio = 1;
  let gapLength = 0;
  let strokeDashoffset = 0;
  switch (style) {
    case "dashed": {
      ratio = 1;
      dashLength = Math.min(strokeWidth * lengthRatio, totalLength / 4);
      break;
    }
    case "dotted": {
      ratio = 100;
      dashLength = strokeWidth / ratio;
      break;
    }
    default: {
      return {
        strokeDasharray: "none",
        strokeDashoffset: "none"
      };
    }
  }
  if (!closed) {
    if (start === "outset") {
      totalLength += dashLength / 2;
      strokeDashoffset += dashLength / 2;
    } else if (start === "skip") {
      totalLength -= dashLength;
      strokeDashoffset -= dashLength;
    }
    if (end === "outset") {
      totalLength += dashLength / 2;
    } else if (end === "skip") {
      totalLength -= dashLength;
    }
  }
  dashCount = Math.floor(totalLength / dashLength / (2 * ratio));
  dashCount -= dashCount % snap;
  if (dashCount < 3 && style === "dashed") {
    if (totalLength / strokeWidth < 5) {
      dashLength = totalLength;
      dashCount = 1;
      gapLength = 0;
    } else {
      dashLength = totalLength * 0.333;
      gapLength = totalLength * 0.333;
    }
  } else {
    dashCount = Math.max(dashCount, 3);
    dashLength = totalLength / dashCount / (2 * ratio);
    if (closed) {
      strokeDashoffset = dashLength / 2;
      gapLength = (totalLength - dashCount * dashLength) / dashCount;
    } else {
      gapLength = (totalLength - dashCount * dashLength) / Math.max(1, dashCount - 1);
    }
  }
  return {
    strokeDasharray: [dashLength, gapLength].join(" "),
    strokeDashoffset: strokeDashoffset.toString()
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/arrow/components/ArrowTextLabel.mjs
var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
var React21 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/useEditableText.mjs
var import_react44 = __toESM(require_react(), 1);
function useEditableText(id, type, text) {
  const editor = useEditor();
  const rInput = (0, import_react44.useRef)(null);
  const rSkipSelectOnFocus = (0, import_react44.useRef)(false);
  const rSelectionRanges = (0, import_react44.useRef)();
  const isEditing = useValue("isEditing", () => editor.editingShapeId === id, [editor, id]);
  (0, import_react44.useEffect)(() => {
    const elm = rInput.current;
    if (elm && isEditing && document.activeElement !== elm) {
      elm.focus();
    }
  }, [isEditing]);
  const handleFocus = (0, import_react44.useCallback)(() => {
    const skipSelect = rSkipSelectOnFocus.current;
    rSkipSelectOnFocus.current = false;
    requestAnimationFrame(() => {
      const elm = rInput.current;
      if (!elm)
        return;
      const shape = editor.getShape(id);
      if (shape) {
        elm.value = shape.props.text;
        if (elm.value.length && !skipSelect) {
          elm.select();
        }
      }
    });
  }, [editor, id]);
  const handleBlur = (0, import_react44.useCallback)(() => {
    const ranges = rSelectionRanges.current;
    requestAnimationFrame(() => {
      const elm = rInput.current;
      const { editingShapeId } = editor;
      if (elm && editingShapeId) {
        if (editingShapeId === id) {
          if (ranges) {
            if (!ranges.length) {
              elm.focus();
            } else {
              rSkipSelectOnFocus.current = true;
              elm.focus();
              const selection = window.getSelection();
              if (selection) {
                ranges.forEach((range) => selection.addRange(range));
              }
            }
          } else {
            elm.focus();
          }
        }
      } else {
        window.getSelection()?.removeAllRanges();
        editor.complete();
      }
    });
  }, [editor, id]);
  const handleKeyDown = (0, import_react44.useCallback)(
    (e) => {
      if (!isEditing)
        return;
      if (e.ctrlKey || e.metaKey)
        stopEventPropagation(e);
      switch (e.key) {
        case "Enter": {
          if (e.ctrlKey || e.metaKey) {
            editor.complete();
          }
          break;
        }
        case "Tab": {
          preventDefault(e);
          if (e.shiftKey) {
            TextHelpers.unindent(e.currentTarget);
          } else {
            TextHelpers.indent(e.currentTarget);
          }
          break;
        }
      }
    },
    [editor, isEditing]
  );
  const handleChange = (0, import_react44.useCallback)(
    (e) => {
      if (!isEditing)
        return;
      let text2 = TextHelpers.normalizeText(e.currentTarget.value);
      const untabbedText = text2.replace(/\t/g, INDENT);
      if (untabbedText !== text2) {
        const selectionStart = e.currentTarget.selectionStart;
        e.currentTarget.value = untabbedText;
        e.currentTarget.selectionStart = selectionStart + (untabbedText.length - text2.length);
        e.currentTarget.selectionEnd = selectionStart + (untabbedText.length - text2.length);
        text2 = untabbedText;
      }
      editor.updateShapes([
        { id, type, props: { text: text2 } }
      ]);
    },
    [editor, id, type, isEditing]
  );
  const isEmpty = text.trim().length === 0;
  (0, import_react44.useEffect)(() => {
    if (!isEditing)
      return;
    const elm = rInput.current;
    if (elm) {
      let updateSelection2 = function() {
        const selection = window.getSelection?.();
        if (selection && selection.type !== "None") {
          const ranges = [];
          if (selection) {
            for (let i = 0; i < selection.rangeCount; i++) {
              ranges.push(selection.getRangeAt?.(i));
            }
          }
          rSelectionRanges.current = ranges;
        }
      };
      var updateSelection = updateSelection2;
      document.addEventListener("selectionchange", updateSelection2);
      return () => {
        document.removeEventListener("selectionchange", updateSelection2);
      };
    }
  }, [isEditing]);
  const handleInputPointerDown = (0, import_react44.useCallback)(
    (e) => {
      editor.dispatch({
        ...getPointerInfo(e),
        type: "pointer",
        name: "pointer_down",
        target: "shape",
        shape: editor.getShape(id)
      });
      stopEventPropagation(e);
    },
    [editor, id]
  );
  const handleDoubleClick = stopEventPropagation;
  return {
    rInput,
    isEditing,
    handleFocus,
    handleBlur,
    handleKeyDown,
    handleChange,
    handleInputPointerDown,
    handleDoubleClick,
    isEmpty
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/arrow/components/ArrowTextLabel.mjs
var ArrowTextLabel = React21.memo(function ArrowTextLabel2({
  id,
  text,
  size: size2,
  font,
  position,
  width,
  labelColor
}) {
  const {
    rInput,
    isEditing,
    handleFocus,
    handleBlur,
    handleKeyDown,
    handleChange,
    isEmpty,
    handleInputPointerDown,
    handleDoubleClick
  } = useEditableText(id, "arrow", text);
  const finalText = TextHelpers.normalizeTextForDom(text);
  const hasText = finalText.trim().length > 0;
  if (!isEditing && !hasText) {
    return null;
  }
  return (0, import_jsx_runtime48.jsx)(
    "div",
    {
      className: "tl-arrow-label",
      "data-font": font,
      "data-align": "center",
      "data-hastext": !isEmpty,
      "data-isediting": isEditing,
      style: {
        textAlign: "center",
        fontSize: ARROW_LABEL_FONT_SIZES[size2],
        lineHeight: ARROW_LABEL_FONT_SIZES[size2] * TEXT_PROPS.lineHeight + "px",
        transform: `translate(${position.x}px, ${position.y}px)`,
        color: labelColor
      },
      children: (0, import_jsx_runtime48.jsxs)("div", { className: "tl-arrow-label__inner", children: [
        (0, import_jsx_runtime48.jsx)("p", { style: { width: width ? width : "9px" }, children: text ? TextHelpers.normalizeTextForDom(text) : " " }),
        isEditing && // Consider replacing with content-editable
        (0, import_jsx_runtime48.jsx)(
          "textarea",
          {
            ref: rInput,
            className: "tl-text tl-text-input",
            name: "text",
            tabIndex: -1,
            autoComplete: "false",
            autoCapitalize: "false",
            autoCorrect: "false",
            autoSave: "false",
            autoFocus: true,
            placeholder: "",
            spellCheck: "true",
            wrap: "off",
            dir: "auto",
            datatype: "wysiwyg",
            defaultValue: text,
            onFocus: handleFocus,
            onChange: handleChange,
            onKeyDown: handleKeyDown,
            onBlur: handleBlur,
            onContextMenu: stopEventPropagation,
            onPointerDown: handleInputPointerDown,
            onDoubleClick: handleDoubleClick
          }
        )
      ] })
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs
var globalRenderIndex = 0;
var ArrowShapeUtil = class extends ShapeUtil {
  static type = "arrow";
  static props = arrowShapeProps;
  static migrations = arrowShapeMigrations;
  canEdit = () => true;
  canBind = () => false;
  canSnap = () => false;
  hideResizeHandles = () => true;
  hideRotateHandle = () => true;
  hideSelectionBoundsBg = () => true;
  hideSelectionBoundsFg = () => true;
  getDefaultProps() {
    return {
      dash: "draw",
      size: "m",
      fill: "none",
      color: "black",
      labelColor: "black",
      bend: 0,
      start: { type: "point", x: 0, y: 0 },
      end: { type: "point", x: 2, y: 0 },
      arrowheadStart: "none",
      arrowheadEnd: "arrow",
      text: "",
      font: "draw"
    };
  }
  getGeometry(shape) {
    const info = this.editor.getArrowInfo(shape);
    const bodyGeom = info.isStraight ? new Edge2d({
      start: Vec2d.From(info.start.point),
      end: Vec2d.From(info.end.point)
    }) : new Arc2d({
      center: Vec2d.Cast(info.handleArc.center),
      radius: info.handleArc.radius,
      start: Vec2d.Cast(info.start.point),
      end: Vec2d.Cast(info.end.point),
      sweepFlag: info.bodyArc.sweepFlag,
      largeArcFlag: info.bodyArc.largeArcFlag
    });
    let labelGeom;
    if (shape.props.text.trim()) {
      const bodyBounds = bodyGeom.bounds;
      const { w, h } = this.editor.textMeasure.measureText(shape.props.text, {
        ...TEXT_PROPS,
        fontFamily: FONT_FAMILIES[shape.props.font],
        fontSize: ARROW_LABEL_FONT_SIZES[shape.props.size],
        maxWidth: null
      });
      let width = w;
      let height = h;
      if (bodyBounds.width > bodyBounds.height) {
        width = Math.max(Math.min(w, 64), Math.min(bodyBounds.width - 64, w));
        const { w: squishedWidth, h: squishedHeight } = this.editor.textMeasure.measureText(
          shape.props.text,
          {
            ...TEXT_PROPS,
            fontFamily: FONT_FAMILIES[shape.props.font],
            fontSize: ARROW_LABEL_FONT_SIZES[shape.props.size],
            maxWidth: width
          }
        );
        width = squishedWidth;
        height = squishedHeight;
      }
      if (width > 16 * ARROW_LABEL_FONT_SIZES[shape.props.size]) {
        width = 16 * ARROW_LABEL_FONT_SIZES[shape.props.size];
        const { w: squishedWidth, h: squishedHeight } = this.editor.textMeasure.measureText(
          shape.props.text,
          {
            ...TEXT_PROPS,
            fontFamily: FONT_FAMILIES[shape.props.font],
            fontSize: ARROW_LABEL_FONT_SIZES[shape.props.size],
            maxWidth: width
          }
        );
        width = squishedWidth;
        height = squishedHeight;
      }
      labelGeom = new Rectangle2d({
        x: info.middle.x - width / 2 - 4.25,
        y: info.middle.y - height / 2 - 4.25,
        width: width + 8.5,
        height: height + 8.5,
        isFilled: true,
        isLabel: true
      });
    }
    return new Group2d({
      children: labelGeom ? [bodyGeom, labelGeom] : [bodyGeom],
      isSnappable: false
    });
  }
  getHandles(shape) {
    const info = this.editor.getArrowInfo(shape);
    return [
      {
        id: "start",
        type: "vertex",
        index: "a0",
        x: info.start.handle.x,
        y: info.start.handle.y,
        canBind: true
      },
      {
        id: "middle",
        type: "virtual",
        index: "a2",
        x: info.middle.x,
        y: info.middle.y,
        canBind: false
      },
      {
        id: "end",
        type: "vertex",
        index: "a3",
        x: info.end.handle.x,
        y: info.end.handle.y,
        canBind: true
      }
    ];
  }
  onHandleChange = (shape, { handle, isPrecise: isPrecise2 }) => {
    const handleId = handle.id;
    if (handleId === "middle") {
      const { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape);
      const delta = Vec2d.Sub(end, start);
      const v = Vec2d.Per(delta);
      const med = Vec2d.Med(end, start);
      const A = Vec2d.Sub(med, v);
      const B = Vec2d.Add(med, v);
      const point2 = Vec2d.NearestPointOnLineSegment(A, B, handle, false);
      let bend = Vec2d.Dist(point2, med);
      if (Vec2d.Clockwise(point2, end, med))
        bend *= -1;
      return { id: shape.id, type: shape.type, props: { bend } };
    }
    const next = deepCopy(shape);
    const pageTransform = this.editor.getShapePageTransform(next.id);
    const pointInPageSpace = pageTransform.applyToPoint(handle);
    if (this.editor.inputs.ctrlKey) {
      next.props[handleId] = {
        type: "point",
        x: handle.x,
        y: handle.y
      };
      return next;
    }
    const point = this.editor.getShapePageTransform(shape.id).applyToPoint(handle);
    const target = this.editor.getShapeAtPoint(point, {
      hitInside: true,
      hitFrameInside: true,
      margin: 0,
      filter: (targetShape) => {
        return !targetShape.isLocked && this.editor.getShapeUtil(targetShape).canBind(targetShape);
      }
    });
    if (!target) {
      next.props[handleId] = {
        type: "point",
        x: handle.x,
        y: handle.y
      };
      return next;
    }
    const targetGeometry = this.editor.getShapeGeometry(target);
    const targetBounds = Box2d.ZeroFix(targetGeometry.bounds);
    const pointInTargetSpace = this.editor.getPointInShapeSpace(target, pointInPageSpace);
    let precise3 = isPrecise2;
    if (!precise3) {
      const prevHandle = next.props[handleId];
      if (prevHandle.type === "point" || prevHandle.type === "binding" && target.id !== prevHandle.boundShapeId) {
        precise3 = this.editor.inputs.pointerVelocity.len() < 0.5;
      }
    }
    if (precise3) {
      precise3 = Vec2d.Dist(pointInTargetSpace, targetBounds.center) > Math.max(4, Math.min(Math.min(targetBounds.width, targetBounds.height) * 0.15, 16)) / this.editor.zoomLevel;
    }
    if (!isPrecise2) {
      if (!targetGeometry.isClosed) {
        precise3 = true;
      }
      const otherHandle = next.props[handleId === "start" ? "end" : "start"];
      if (otherHandle.type === "binding" && target.id === otherHandle.boundShapeId && Vec2d.Equals(otherHandle.normalizedAnchor, { x: 0.5, y: 0.5 })) {
        precise3 = true;
      }
    }
    next.props[handleId] = {
      type: "binding",
      boundShapeId: target.id,
      normalizedAnchor: precise3 ? {
        x: (pointInTargetSpace.x - targetBounds.minX) / targetBounds.width,
        y: (pointInTargetSpace.y - targetBounds.minY) / targetBounds.height
      } : { x: 0.5, y: 0.5 },
      isExact: this.editor.inputs.altKey
    };
    if (next.props.start.type === "binding" && next.props.end.type === "binding") {
      if (next.props.start.boundShapeId === next.props.end.boundShapeId) {
        if (Vec2d.Equals(next.props.start.normalizedAnchor, next.props.end.normalizedAnchor)) {
          next.props.end.normalizedAnchor.x += 0.05;
        }
      }
    }
    return next;
  };
  onTranslateStart = (shape) => {
    const startBindingId = shape.props.start.type === "binding" ? shape.props.start.boundShapeId : null;
    const endBindingId = shape.props.end.type === "binding" ? shape.props.end.boundShapeId : null;
    const { selectedShapeIds } = this.editor;
    if (startBindingId && (selectedShapeIds.includes(startBindingId) || this.editor.isAncestorSelected(startBindingId)) || endBindingId && (selectedShapeIds.includes(endBindingId) || this.editor.isAncestorSelected(endBindingId))) {
      return;
    }
    const { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape);
    return {
      id: shape.id,
      type: shape.type,
      props: {
        ...shape.props,
        start: {
          type: "point",
          x: start.x,
          y: start.y
        },
        end: {
          type: "point",
          x: end.x,
          y: end.y
        }
      }
    };
  };
  onResize = (shape, info) => {
    const { scaleX, scaleY } = info;
    const terminals = getArrowTerminalsInArrowSpace(this.editor, shape);
    const { start, end } = deepCopy(shape.props);
    let { bend } = shape.props;
    if (start.type === "point") {
      start.x = terminals.start.x * scaleX;
      start.y = terminals.start.y * scaleY;
    }
    if (end.type === "point") {
      end.x = terminals.end.x * scaleX;
      end.y = terminals.end.y * scaleY;
    }
    const mx = Math.abs(scaleX);
    const my = Math.abs(scaleY);
    if (scaleX < 0 && scaleY >= 0) {
      if (bend !== 0) {
        bend *= -1;
        bend *= Math.max(mx, my);
      }
      if (start.type === "binding") {
        start.normalizedAnchor.x = 1 - start.normalizedAnchor.x;
      }
      if (end.type === "binding") {
        end.normalizedAnchor.x = 1 - end.normalizedAnchor.x;
      }
    } else if (scaleX >= 0 && scaleY < 0) {
      if (bend !== 0) {
        bend *= -1;
        bend *= Math.max(mx, my);
      }
      if (start.type === "binding") {
        start.normalizedAnchor.y = 1 - start.normalizedAnchor.y;
      }
      if (end.type === "binding") {
        end.normalizedAnchor.y = 1 - end.normalizedAnchor.y;
      }
    } else if (scaleX >= 0 && scaleY >= 0) {
      if (bend !== 0) {
        bend *= Math.max(mx, my);
      }
    } else if (scaleX < 0 && scaleY < 0) {
      if (bend !== 0) {
        bend *= Math.max(mx, my);
      }
      if (start.type === "binding") {
        start.normalizedAnchor.x = 1 - start.normalizedAnchor.x;
        start.normalizedAnchor.y = 1 - start.normalizedAnchor.y;
      }
      if (end.type === "binding") {
        end.normalizedAnchor.x = 1 - end.normalizedAnchor.x;
        end.normalizedAnchor.y = 1 - end.normalizedAnchor.y;
      }
    }
    const next = {
      props: {
        start,
        end,
        bend
      }
    };
    return next;
  };
  onDoubleClickHandle = (shape, handle) => {
    switch (handle.id) {
      case "start": {
        return {
          id: shape.id,
          type: shape.type,
          props: {
            ...shape.props,
            arrowheadStart: shape.props.arrowheadStart === "none" ? "arrow" : "none"
          }
        };
      }
      case "end": {
        return {
          id: shape.id,
          type: shape.type,
          props: {
            ...shape.props,
            arrowheadEnd: shape.props.arrowheadEnd === "none" ? "arrow" : "none"
          }
        };
      }
    }
  };
  component(shape) {
    const theme = useDefaultColorTheme();
    const onlySelectedShape = this.editor.onlySelectedShape;
    const shouldDisplayHandles = this.editor.isInAny(
      "select.idle",
      "select.pointing_handle",
      "select.dragging_handle",
      "arrow.dragging"
    ) && !this.editor.instanceState.isReadonly;
    const info = this.editor.getArrowInfo(shape);
    const bounds = Box2d.ZeroFix(this.editor.getShapeGeometry(shape).bounds);
    const changeIndex = import_react45.default.useMemo(() => {
      return this.editor.environment.isSafari ? globalRenderIndex += 1 : 0;
    }, [shape]);
    if (!info?.isValid)
      return null;
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const as = info.start.arrowhead && getArrowheadPathForType(info, "start", strokeWidth);
    const ae = info.end.arrowhead && getArrowheadPathForType(info, "end", strokeWidth);
    const path = info.isStraight ? getSolidStraightArrowPath(info) : getSolidCurvedArrowPath(info);
    let handlePath = null;
    if (onlySelectedShape === shape && shouldDisplayHandles) {
      const sw = 2;
      const { strokeDasharray: strokeDasharray2, strokeDashoffset: strokeDashoffset2 } = getPerfectDashProps2(
        info.isStraight ? Vec2d.Dist(info.start.handle, info.end.handle) : Math.abs(info.handleArc.length),
        sw,
        {
          end: "skip",
          start: "skip",
          lengthRatio: 2.5
        }
      );
      handlePath = shape.props.start.type === "binding" || shape.props.end.type === "binding" ? (0, import_jsx_runtime49.jsx)(
        "path",
        {
          className: "tl-arrow-hint",
          d: info.isStraight ? getStraightArrowHandlePath(info) : getCurvedArrowHandlePath(info),
          strokeDasharray: strokeDasharray2,
          strokeDashoffset: strokeDashoffset2,
          strokeWidth: sw,
          markerStart: shape.props.start.type === "binding" ? shape.props.start.isExact ? "" : isPrecise(shape.props.start.normalizedAnchor) ? "url(#arrowhead-cross)" : "url(#arrowhead-dot)" : "",
          markerEnd: shape.props.end.type === "binding" ? shape.props.end.isExact ? "" : isPrecise(shape.props.end.normalizedAnchor) ? "url(#arrowhead-cross)" : "url(#arrowhead-dot)" : "",
          opacity: 0.16
        }
      ) : null;
    }
    const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
      info.isStraight ? info.length : Math.abs(info.bodyArc.length),
      strokeWidth,
      {
        style: shape.props.dash
      }
    );
    const labelGeometry = shape.props.text.trim() ? this.editor.getShapeGeometry(shape).children[1] : null;
    const maskStartArrowhead = !(info.start.arrowhead === "none" || info.start.arrowhead === "arrow");
    const maskEndArrowhead = !(info.end.arrowhead === "none" || info.end.arrowhead === "arrow");
    const maskId = (shape.id + "_clip_" + changeIndex).replace(":", "_");
    return (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
      (0, import_jsx_runtime49.jsxs)(SVGContainer, { id: shape.id, style: { minWidth: 50, minHeight: 50 }, children: [
        (0, import_jsx_runtime49.jsx)("defs", { children: (0, import_jsx_runtime49.jsxs)("mask", { id: maskId, children: [
          (0, import_jsx_runtime49.jsx)(
            "rect",
            {
              x: toDomPrecision(-100 + bounds.minX),
              y: toDomPrecision(-100 + bounds.minY),
              width: toDomPrecision(bounds.width + 200),
              height: toDomPrecision(bounds.height + 200),
              fill: "white"
            }
          ),
          labelGeometry && (0, import_jsx_runtime49.jsx)(
            "rect",
            {
              x: labelGeometry.x,
              y: labelGeometry.y,
              width: labelGeometry.w,
              height: labelGeometry.h,
              fill: "black",
              rx: 4,
              ry: 4
            }
          ),
          as && maskStartArrowhead && (0, import_jsx_runtime49.jsx)(
            "path",
            {
              d: as,
              fill: info.start.arrowhead === "arrow" ? "none" : "black",
              stroke: "none"
            }
          ),
          ae && maskEndArrowhead && (0, import_jsx_runtime49.jsx)(
            "path",
            {
              d: ae,
              fill: info.end.arrowhead === "arrow" ? "none" : "black",
              stroke: "none"
            }
          )
        ] }) }),
        (0, import_jsx_runtime49.jsxs)(
          "g",
          {
            fill: "none",
            stroke: theme[shape.props.color].solid,
            strokeWidth,
            strokeLinejoin: "round",
            strokeLinecap: "round",
            pointerEvents: "none",
            children: [
              handlePath,
              (0, import_jsx_runtime49.jsxs)("g", { mask: `url(#${maskId})`, children: [
                (0, import_jsx_runtime49.jsx)(
                  "rect",
                  {
                    x: toDomPrecision(bounds.minX - 100),
                    y: toDomPrecision(bounds.minY - 100),
                    width: toDomPrecision(bounds.width + 200),
                    height: toDomPrecision(bounds.height + 200),
                    opacity: 0
                  }
                ),
                (0, import_jsx_runtime49.jsx)(
                  "path",
                  {
                    d: path,
                    strokeDasharray,
                    strokeDashoffset
                  }
                )
              ] }),
              as && maskStartArrowhead && shape.props.fill !== "none" && (0, import_jsx_runtime49.jsx)(ShapeFill, { theme, d: as, color: shape.props.color, fill: shape.props.fill }),
              ae && maskEndArrowhead && shape.props.fill !== "none" && (0, import_jsx_runtime49.jsx)(ShapeFill, { theme, d: ae, color: shape.props.color, fill: shape.props.fill }),
              as && (0, import_jsx_runtime49.jsx)("path", { d: as }),
              ae && (0, import_jsx_runtime49.jsx)("path", { d: ae })
            ]
          }
        )
      ] }),
      (0, import_jsx_runtime49.jsx)(
        ArrowTextLabel,
        {
          id: shape.id,
          text: shape.props.text,
          font: shape.props.font,
          size: shape.props.size,
          position: info.middle,
          width: labelGeometry?.w ?? 0,
          labelColor: theme[shape.props.labelColor].solid
        }
      )
    ] });
  }
  indicator(shape) {
    const { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape);
    const info = this.editor.getArrowInfo(shape);
    const geometry = this.editor.getShapeGeometry(shape);
    const bounds = geometry.bounds;
    const labelGeometry = shape.props.text.trim() ? geometry.children[1] : null;
    const isEditing = useIsEditing(shape.id);
    if (!info)
      return null;
    if (Vec2d.Equals(start, end))
      return null;
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const as = info.start.arrowhead && getArrowheadPathForType(info, "start", strokeWidth);
    const ae = info.end.arrowhead && getArrowheadPathForType(info, "end", strokeWidth);
    const path = info.isStraight ? getSolidStraightArrowPath(info) : getSolidCurvedArrowPath(info);
    const includeMask = as && info.start.arrowhead !== "arrow" || ae && info.end.arrowhead !== "arrow" || !!labelGeometry;
    const maskId = (shape.id + "_clip").replace(":", "_");
    if (isEditing && labelGeometry) {
      return (0, import_jsx_runtime49.jsx)(
        "rect",
        {
          x: toDomPrecision(labelGeometry.x),
          y: toDomPrecision(labelGeometry.y),
          width: labelGeometry.w,
          height: labelGeometry.h,
          rx: 3.5,
          ry: 3.5
        }
      );
    }
    return (0, import_jsx_runtime49.jsxs)("g", { children: [
      includeMask && (0, import_jsx_runtime49.jsx)("defs", { children: (0, import_jsx_runtime49.jsxs)("mask", { id: maskId, children: [
        (0, import_jsx_runtime49.jsx)(
          "rect",
          {
            x: bounds.minX - 100,
            y: bounds.minY - 100,
            width: bounds.w + 200,
            height: bounds.h + 200,
            fill: "white"
          }
        ),
        labelGeometry && (0, import_jsx_runtime49.jsx)(
          "rect",
          {
            x: toDomPrecision(labelGeometry.x),
            y: toDomPrecision(labelGeometry.y),
            width: labelGeometry.w,
            height: labelGeometry.h,
            fill: "black",
            rx: 3.5,
            ry: 3.5
          }
        ),
        as && (0, import_jsx_runtime49.jsx)(
          "path",
          {
            d: as,
            fill: info.start.arrowhead === "arrow" ? "none" : "black",
            stroke: "none"
          }
        ),
        ae && (0, import_jsx_runtime49.jsx)(
          "path",
          {
            d: ae,
            fill: info.end.arrowhead === "arrow" ? "none" : "black",
            stroke: "none"
          }
        )
      ] }) }),
      (0, import_jsx_runtime49.jsxs)("g", { ...includeMask ? { mask: `url(#${maskId})` } : void 0, children: [
        includeMask && (0, import_jsx_runtime49.jsx)(
          "rect",
          {
            x: bounds.minX - 100,
            y: bounds.minY - 100,
            width: bounds.width + 200,
            height: bounds.height + 200,
            opacity: 0
          }
        ),
        (0, import_jsx_runtime49.jsx)("path", { d: path })
      ] }),
      as && (0, import_jsx_runtime49.jsx)("path", { d: as }),
      ae && (0, import_jsx_runtime49.jsx)("path", { d: ae }),
      labelGeometry && (0, import_jsx_runtime49.jsx)(
        "rect",
        {
          x: toDomPrecision(labelGeometry.x),
          y: toDomPrecision(labelGeometry.y),
          width: labelGeometry.w,
          height: labelGeometry.h,
          rx: 3.5,
          ry: 3.5
        }
      )
    ] });
  }
  onEditEnd = (shape) => {
    const {
      id,
      type,
      props: { text }
    } = shape;
    if (text.trimEnd() !== shape.props.text) {
      this.editor.updateShapes([
        {
          id,
          type,
          props: {
            text: text.trimEnd()
          }
        }
      ]);
    }
  };
  toSvg(shape, ctx) {
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    ctx.addExportDef(getFillDefForExport(shape.props.fill, theme));
    const color = theme[shape.props.color].solid;
    const info = this.editor.getArrowInfo(shape);
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    if (!info)
      return g;
    const as = info.start.arrowhead && getArrowheadPathForType(info, "start", strokeWidth);
    const ae = info.end.arrowhead && getArrowheadPathForType(info, "end", strokeWidth);
    const geometry = this.editor.getShapeGeometry(shape);
    const bounds = geometry.bounds;
    const labelGeometry = shape.props.text.trim() ? geometry.children[1] : null;
    const maskId = (shape.id + "_clip").replace(":", "_");
    if (as || ae || !!labelGeometry) {
      const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
      const mask = document.createElementNS("http://www.w3.org/2000/svg", "mask");
      mask.id = maskId;
      const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
      rect.setAttribute("x", bounds.minX - 100 + "");
      rect.setAttribute("y", bounds.minY - 100 + "");
      rect.setAttribute("width", bounds.width + 200 + "");
      rect.setAttribute("height", bounds.height + 200 + "");
      rect.setAttribute("fill", "white");
      mask.appendChild(rect);
      if (as)
        mask.appendChild(getArrowheadSvgMask(as, info.start.arrowhead));
      if (ae)
        mask.appendChild(getArrowheadSvgMask(ae, info.end.arrowhead));
      if (labelGeometry) {
        const labelMask = document.createElementNS("http://www.w3.org/2000/svg", "rect");
        labelMask.setAttribute("x", labelGeometry.x + "");
        labelMask.setAttribute("y", labelGeometry.y + "");
        labelMask.setAttribute("width", labelGeometry.w + "");
        labelMask.setAttribute("height", labelGeometry.h + "");
        labelMask.setAttribute("fill", "black");
        mask.appendChild(labelMask);
      }
      defs.appendChild(mask);
      g.appendChild(defs);
    }
    const g2 = document.createElementNS("http://www.w3.org/2000/svg", "g");
    g2.setAttribute("mask", `url(#${maskId})`);
    g.appendChild(g2);
    const rect2 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect2.setAttribute("x", "-100");
    rect2.setAttribute("y", "-100");
    rect2.setAttribute("width", bounds.width + 200 + "");
    rect2.setAttribute("height", bounds.height + 200 + "");
    rect2.setAttribute("fill", "transparent");
    rect2.setAttribute("stroke", "none");
    g2.appendChild(rect2);
    const path = getArrowSvgPath(
      info.isStraight ? getSolidStraightArrowPath(info) : getSolidCurvedArrowPath(info),
      color,
      strokeWidth
    );
    const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
      info.isStraight ? info.length : Math.abs(info.bodyArc.length),
      strokeWidth,
      {
        style: shape.props.dash
      }
    );
    path.setAttribute("stroke-dasharray", strokeDasharray);
    path.setAttribute("stroke-dashoffset", strokeDashoffset);
    g2.appendChild(path);
    if (as) {
      g.appendChild(
        getArrowheadSvgPath(
          as,
          shape.props.color,
          strokeWidth,
          shape.props.arrowheadStart === "arrow" ? "none" : shape.props.fill,
          theme
        )
      );
    }
    if (ae) {
      g.appendChild(
        getArrowheadSvgPath(
          ae,
          shape.props.color,
          strokeWidth,
          shape.props.arrowheadEnd === "arrow" ? "none" : shape.props.fill,
          theme
        )
      );
    }
    if (labelGeometry) {
      ctx.addExportDef(getFontDefForExport(shape.props.font));
      const opts = {
        fontSize: ARROW_LABEL_FONT_SIZES[shape.props.size],
        lineHeight: TEXT_PROPS.lineHeight,
        fontFamily: DefaultFontFamilies[shape.props.font],
        padding: 0,
        textAlign: "middle",
        width: labelGeometry.w - 8,
        verticalTextAlign: "middle",
        height: labelGeometry.h,
        fontStyle: "normal",
        fontWeight: "normal",
        overflow: "wrap"
      };
      const textElm = createTextSvgElementFromSpans(
        this.editor,
        this.editor.textMeasure.measureTextSpans(shape.props.text, opts),
        opts
      );
      textElm.setAttribute("fill", theme[shape.props.labelColor].solid);
      const children = Array.from(textElm.children);
      children.forEach((child) => {
        const x = parseFloat(child.getAttribute("x") || "0");
        const y = parseFloat(child.getAttribute("y") || "0");
        child.setAttribute("x", x + 4 + labelGeometry.x + "px");
        child.setAttribute("y", y + labelGeometry.y + "px");
      });
      const textBgEl = textElm.cloneNode(true);
      textBgEl.setAttribute("stroke-width", "2");
      textBgEl.setAttribute("fill", theme.background);
      textBgEl.setAttribute("stroke", theme.background);
      g.appendChild(textBgEl);
      g.appendChild(textElm);
    }
    return g;
  }
  getCanvasSvgDefs() {
    return [getFillDefForCanvas()];
  }
};
function getArrowheadSvgMask(d, arrowhead) {
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
  path.setAttribute("d", d);
  path.setAttribute("fill", arrowhead === "arrow" ? "none" : "black");
  path.setAttribute("stroke", "none");
  return path;
}
function getArrowSvgPath(d, color, strokeWidth) {
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
  path.setAttribute("d", d);
  path.setAttribute("fill", "none");
  path.setAttribute("stroke", color);
  path.setAttribute("stroke-width", strokeWidth + "");
  return path;
}
function getArrowheadSvgPath(d, color, strokeWidth, fill, theme) {
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
  path.setAttribute("d", d);
  path.setAttribute("fill", "none");
  path.setAttribute("stroke", theme[color].solid);
  path.setAttribute("stroke-width", strokeWidth + "");
  const shapeFill = getShapeFillSvg({
    d,
    fill,
    color,
    theme
  });
  if (shapeFill) {
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    g.appendChild(shapeFill);
    g.appendChild(path);
    return g;
  } else {
    return path;
  }
}
function isPrecise(normalizedAnchor) {
  return normalizedAnchor.x !== 0.5 || normalizedAnchor.y !== 0.5;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs
var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/rotated-box-shadow.mjs
var ROTATING_BOX_SHADOWS = [
  {
    offsetX: 0,
    offsetY: 2,
    blur: 4,
    spread: 0,
    color: "#00000029"
  },
  {
    offsetX: 0,
    offsetY: 3,
    blur: 6,
    spread: 0,
    color: "#0000001f"
  }
];
function getRotatedBoxShadow(rotation) {
  const cssStrings = ROTATING_BOX_SHADOWS.map((shadow) => {
    const { offsetX, offsetY, blur, spread, color } = shadow;
    const vec = new Vec2d(offsetX, offsetY);
    const { x, y } = vec.rot(-rotation);
    return `${x}px ${y}px ${blur}px ${spread}px ${color}`;
  });
  return cssStrings.join(", ");
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/HyperlinkButton.mjs
var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
var import_classnames18 = __toESM(require_classnames(), 1);
var LINK_ICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E";
function HyperlinkButton({ url, zoomLevel }) {
  return (0, import_jsx_runtime50.jsx)(
    "a",
    {
      className: (0, import_classnames18.default)("tl-hyperlink-button", {
        "tl-hyperlink-button__hidden": zoomLevel < 0.32
      }),
      href: url,
      target: "_blank",
      rel: "noopener noreferrer",
      onPointerDown: stopEventPropagation,
      onPointerUp: stopEventPropagation,
      title: url,
      draggable: false,
      children: (0, import_jsx_runtime50.jsx)(
        "div",
        {
          className: "tl-hyperlink-button__icon",
          style: {
            mask: `url("${LINK_ICON}") center 100% / 100% no-repeat`,
            WebkitMask: `url("${LINK_ICON}") center 100% / 100% no-repeat`
          }
        }
      )
    }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs
var BookmarkShapeUtil = class extends BaseBoxShapeUtil {
  static type = "bookmark";
  static props = bookmarkShapeProps;
  static migrations = bookmarkShapeMigrations;
  canResize = () => false;
  hideSelectionBoundsFg = () => true;
  getDefaultProps() {
    return {
      url: "",
      w: 300,
      h: 320,
      assetId: null
    };
  }
  component(shape) {
    const asset = shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null;
    const pageRotation = this.editor.getShapePageTransform(shape).rotation();
    const address = getHumanReadableAddress(shape);
    return (0, import_jsx_runtime51.jsx)(HTMLContainer, { children: (0, import_jsx_runtime51.jsxs)(
      "div",
      {
        className: "tl-bookmark__container",
        style: {
          boxShadow: getRotatedBoxShadow(pageRotation)
        },
        children: [
          (0, import_jsx_runtime51.jsxs)("div", { className: "tl-bookmark__image_container", children: [
            asset?.props.image ? (0, import_jsx_runtime51.jsx)(
              "img",
              {
                className: "tl-bookmark__image",
                draggable: false,
                src: asset?.props.image,
                alt: asset?.props.title || ""
              }
            ) : (0, import_jsx_runtime51.jsx)("div", { className: "tl-bookmark__placeholder" }),
            (0, import_jsx_runtime51.jsx)(HyperlinkButton, { url: shape.props.url, zoomLevel: this.editor.zoomLevel })
          ] }),
          (0, import_jsx_runtime51.jsxs)("div", { className: "tl-bookmark__copy_container", children: [
            asset?.props.title && (0, import_jsx_runtime51.jsx)("h2", { className: "tl-bookmark__heading", children: truncateStringWithEllipsis(asset?.props.title || "", 54) }),
            asset?.props.description && (0, import_jsx_runtime51.jsx)("p", { className: "tl-bookmark__description", children: truncateStringWithEllipsis(asset?.props.description || "", 128) }),
            (0, import_jsx_runtime51.jsx)(
              "a",
              {
                className: "tl-bookmark__link",
                href: shape.props.url || "",
                target: "_blank",
                rel: "noopener noreferrer",
                onPointerDown: stopEventPropagation,
                onPointerUp: stopEventPropagation,
                onClick: stopEventPropagation,
                children: truncateStringWithEllipsis(address, 45)
              }
            )
          ] })
        ]
      }
    ) });
  }
  indicator(shape) {
    return (0, import_jsx_runtime51.jsx)(
      "rect",
      {
        width: toDomPrecision(shape.props.w),
        height: toDomPrecision(shape.props.h),
        rx: "8",
        ry: "8"
      }
    );
  }
  onBeforeCreate = (shape) => {
    updateBookmarkAssetOnUrlChange(this.editor, shape);
  };
  onBeforeUpdate = (prev, shape) => {
    if (prev.props.url !== shape.props.url) {
      if (!isValidUrl(shape.props.url)) {
        return { ...shape, props: { ...shape.props, url: prev.props.url } };
      } else {
        updateBookmarkAssetOnUrlChange(this.editor, shape);
      }
    }
  };
};
var getHumanReadableAddress = (shape) => {
  try {
    const url = new URL(shape.props.url);
    const path = url.pathname.replace(/\/*$/, "");
    return `${url.hostname}${path}`;
  } catch (e) {
    return shape.props.url;
  }
};
function updateBookmarkAssetOnUrlChange(editor, shape) {
  const { url } = shape.props;
  const assetId = AssetRecordType.createId(getHashForString(url));
  if (editor.getAsset(assetId)) {
    if (shape.props.assetId !== assetId) {
      editor.updateShapes([
        {
          id: shape.id,
          type: shape.type,
          props: { assetId }
        }
      ]);
    }
  } else {
    editor.updateShapes([
      {
        id: shape.id,
        type: shape.type,
        props: { assetId: null }
      }
    ]);
    createBookmarkAssetOnUrlChange(editor, shape);
  }
}
var createBookmarkAssetOnUrlChange = debounce(async (editor, shape) => {
  const { url } = shape.props;
  const asset = await editor.getAssetForExternalContent({ type: "url", url });
  if (!asset) {
    return;
  }
  editor.batch(() => {
    editor.createAssets([asset]);
    editor.updateShapes([
      {
        id: shape.id,
        type: shape.type,
        props: { assetId: asset.id }
      }
    ]);
  });
}, 500);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs
var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/freehand/svg.mjs
function getSvgPathFromStrokePoints(points, closed = false) {
  const len = points.length;
  if (len < 2) {
    return "";
  }
  let a = points[0].point;
  let b = points[1].point;
  if (len === 2) {
    return `M${precise(a)}L${precise(b)}`;
  }
  let result = "";
  for (let i = 2, max3 = len - 1; i < max3; i++) {
    a = points[i].point;
    b = points[i + 1].point;
    result += average(a, b);
  }
  if (closed) {
    return `M${average(points[0].point, points[1].point)}Q${precise(points[1].point)}${average(
      points[1].point,
      points[2].point
    )}T${result}${average(points[len - 1].point, points[0].point)}${average(
      points[0].point,
      points[1].point
    )}Z`;
  } else {
    return `M${precise(points[0].point)}Q${precise(points[1].point)}${average(
      points[1].point,
      points[2].point
    )}${points.length > 3 ? "T" : ""}${result}L${precise(points[len - 1].point)}`;
  }
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/useForceSolid.mjs
function useForceSolid() {
  const editor = useEditor();
  return useValue("zoom", () => editor.zoomLevel < 0.35, [editor]);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/draw/getPath.mjs
var PEN_EASING = (t2) => t2 * 0.65 + SIN(t2 * PI / 2) * 0.35;
var simulatePressureSettings = (strokeWidth) => {
  return {
    size: 1 + strokeWidth,
    thinning: 0.5,
    streamline: 0.62 + (1 + strokeWidth) / 8 * 0.06,
    smoothing: 0.62,
    easing: EASINGS.easeOutSine,
    simulatePressure: true
  };
};
var realPressureSettings = (strokeWidth) => {
  return {
    size: 1 + strokeWidth * 1.2,
    thinning: 0.62,
    streamline: 0.62,
    smoothing: 0.62,
    simulatePressure: false,
    easing: PEN_EASING
  };
};
var solidSettings = (strokeWidth) => {
  return {
    size: 1 + strokeWidth,
    thinning: 0,
    streamline: 0.62 + (1 + strokeWidth) / 8 * 0.06,
    smoothing: 0.62,
    simulatePressure: false,
    easing: EASINGS.linear
  };
};
function getHighlightFreehandSettings({
  strokeWidth,
  showAsComplete
}) {
  return {
    size: 1 + strokeWidth,
    thinning: 0,
    streamline: 0.5,
    smoothing: 0.5,
    simulatePressure: false,
    easing: EASINGS.easeOutSine,
    last: showAsComplete
  };
}
function getFreehandOptions(shapeProps, strokeWidth, forceComplete, forceSolid) {
  return {
    ...forceSolid ? solidSettings(strokeWidth) : shapeProps.dash === "draw" ? shapeProps.isPen ? realPressureSettings(strokeWidth) : simulatePressureSettings(strokeWidth) : solidSettings(strokeWidth),
    last: shapeProps.isComplete || forceComplete
  };
}
function getPointsFromSegments(segments) {
  const points = [];
  for (const segment of segments) {
    if (segment.type === "free" || segment.points.length < 2) {
      points.push(...segment.points.map(Vec2d.Cast));
    } else {
      const pointsToInterpolate = Math.max(
        4,
        Math.floor(Vec2d.Dist(segment.points[0], segment.points[1]) / 16)
      );
      points.push(...Vec2d.PointsBetween(segment.points[0], segment.points[1], pointsToInterpolate));
    }
  }
  return points;
}
function getDrawShapeStrokeDashArray(shape, strokeWidth) {
  return {
    draw: "none",
    solid: `none`,
    dotted: `0.1 ${strokeWidth * 2}`,
    dashed: `${strokeWidth * 2} ${strokeWidth * 2}`
  }[shape.props.dash];
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs
var DrawShapeUtil = class extends ShapeUtil {
  static type = "draw";
  static props = drawShapeProps;
  static migrations = drawShapeMigrations;
  hideResizeHandles = (shape) => getIsDot(shape);
  hideRotateHandle = (shape) => getIsDot(shape);
  hideSelectionBoundsFg = (shape) => getIsDot(shape);
  getDefaultProps() {
    return {
      segments: [],
      color: "black",
      fill: "none",
      dash: "draw",
      size: "m",
      isComplete: false,
      isClosed: false,
      isPen: false
    };
  }
  getGeometry(shape) {
    const points = getPointsFromSegments(shape.props.segments);
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    if (shape.props.segments.length === 1) {
      const box = Box2d.FromPoints(points);
      if (box.width < strokeWidth * 2 && box.height < strokeWidth * 2) {
        return new Circle2d({
          x: -strokeWidth,
          y: -strokeWidth,
          radius: strokeWidth,
          isFilled: true
        });
      }
    }
    const strokePoints = getStrokePoints(
      points,
      getFreehandOptions(shape.props, strokeWidth, true, true)
    ).map((p) => p.point);
    if (shape.props.isClosed) {
      return new Polygon2d({
        points: strokePoints,
        isFilled: shape.props.fill !== "none"
      });
    }
    return new Polyline2d({
      points: strokePoints
    });
  }
  component(shape) {
    const theme = useDefaultColorTheme();
    const forceSolid = useForceSolid();
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const allPointsFromSegments = getPointsFromSegments(shape.props.segments);
    const showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === "straight";
    let sw = strokeWidth;
    if (!forceSolid && !shape.props.isPen && shape.props.dash === "draw" && allPointsFromSegments.length === 1) {
      sw += rng(shape.id)() * (strokeWidth / 6);
    }
    const options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid);
    const strokePoints = getStrokePoints(allPointsFromSegments, options);
    const solidStrokePath = strokePoints.length > 1 ? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed) : getDot(allPointsFromSegments[0], sw);
    if (!forceSolid && shape.props.dash === "draw" || strokePoints.length < 2) {
      setStrokePointRadii(strokePoints, options);
      const strokeOutlinePoints = getStrokeOutlinePoints(strokePoints, options);
      return (0, import_jsx_runtime52.jsxs)(SVGContainer, { id: shape.id, children: [
        (0, import_jsx_runtime52.jsx)(
          ShapeFill,
          {
            theme,
            fill: shape.props.isClosed ? shape.props.fill : "none",
            color: shape.props.color,
            d: solidStrokePath
          }
        ),
        (0, import_jsx_runtime52.jsx)(
          "path",
          {
            d: getSvgPathFromPoints(strokeOutlinePoints, true),
            strokeLinecap: "round",
            fill: theme[shape.props.color].solid
          }
        )
      ] });
    }
    return (0, import_jsx_runtime52.jsxs)(SVGContainer, { id: shape.id, children: [
      (0, import_jsx_runtime52.jsx)(
        ShapeFill,
        {
          theme,
          color: shape.props.color,
          fill: shape.props.isClosed ? shape.props.fill : "none",
          d: solidStrokePath
        }
      ),
      (0, import_jsx_runtime52.jsx)(
        "path",
        {
          d: solidStrokePath,
          strokeLinecap: "round",
          fill: "none",
          stroke: theme[shape.props.color].solid,
          strokeWidth,
          strokeDasharray: getDrawShapeStrokeDashArray(shape, strokeWidth),
          strokeDashoffset: "0"
        }
      )
    ] });
  }
  indicator(shape) {
    const forceSolid = useForceSolid();
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const allPointsFromSegments = getPointsFromSegments(shape.props.segments);
    let sw = strokeWidth;
    if (!forceSolid && !shape.props.isPen && shape.props.dash === "draw" && allPointsFromSegments.length === 1) {
      sw += rng(shape.id)() * (strokeWidth / 6);
    }
    const showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === "straight";
    const options = getFreehandOptions(shape.props, sw, showAsComplete, true);
    const strokePoints = getStrokePoints(allPointsFromSegments, options);
    const solidStrokePath = strokePoints.length > 1 ? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed) : getDot(allPointsFromSegments[0], sw);
    return (0, import_jsx_runtime52.jsx)("path", { d: solidStrokePath });
  }
  toSvg(shape, ctx) {
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    ctx.addExportDef(getFillDefForExport(shape.props.fill, theme));
    const { color } = shape.props;
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const allPointsFromSegments = getPointsFromSegments(shape.props.segments);
    const showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === "straight";
    let sw = strokeWidth;
    if (!shape.props.isPen && shape.props.dash === "draw" && allPointsFromSegments.length === 1) {
      sw += rng(shape.id)() * (strokeWidth / 6);
    }
    const options = getFreehandOptions(shape.props, sw, showAsComplete, false);
    const strokePoints = getStrokePoints(allPointsFromSegments, options);
    const solidStrokePath = strokePoints.length > 1 ? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed) : getDot(allPointsFromSegments[0], sw);
    let foregroundPath;
    if (shape.props.dash === "draw" || strokePoints.length < 2) {
      setStrokePointRadii(strokePoints, options);
      const strokeOutlinePoints = getStrokeOutlinePoints(strokePoints, options);
      const p = document.createElementNS("http://www.w3.org/2000/svg", "path");
      p.setAttribute("d", getSvgPathFromPoints(strokeOutlinePoints, true));
      p.setAttribute("fill", theme[color].solid);
      p.setAttribute("stroke-linecap", "round");
      foregroundPath = p;
    } else {
      const p = document.createElementNS("http://www.w3.org/2000/svg", "path");
      p.setAttribute("d", solidStrokePath);
      p.setAttribute("stroke", theme[color].solid);
      p.setAttribute("fill", "none");
      p.setAttribute("stroke-linecap", "round");
      p.setAttribute("stroke-width", strokeWidth.toString());
      p.setAttribute("stroke-dasharray", getDrawShapeStrokeDashArray(shape, strokeWidth));
      p.setAttribute("stroke-dashoffset", "0");
      foregroundPath = p;
    }
    const fillPath = getShapeFillSvg({
      fill: shape.props.isClosed ? shape.props.fill : "none",
      d: solidStrokePath,
      color: shape.props.color,
      theme
    });
    if (fillPath) {
      const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
      g.appendChild(fillPath);
      g.appendChild(foregroundPath);
      return g;
    }
    return foregroundPath;
  }
  getCanvasSvgDefs() {
    return [getFillDefForCanvas()];
  }
  onResize = (shape, info) => {
    const { scaleX, scaleY } = info;
    const newSegments = [];
    for (const segment of shape.props.segments) {
      newSegments.push({
        ...segment,
        points: segment.points.map(({ x, y, z }) => {
          return {
            x: toFixed(scaleX * x),
            y: toFixed(scaleY * y),
            z
          };
        })
      });
    }
    return {
      props: {
        segments: newSegments
      }
    };
  };
  expandSelectionOutlinePx(shape) {
    const multiplier = shape.props.dash === "draw" ? 1.6 : 1;
    return STROKE_SIZES2[shape.props.size] * multiplier / 2;
  }
};
function getDot(point, sw) {
  const r = (sw + 1) * 0.5;
  return `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${r * 2},0`;
}
function getIsDot(shape) {
  return shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs
var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
var import_react46 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/resizeBox.mjs
function resizeBox2(shape, info, opts = {}) {
  const { newPoint, handle, scaleX, scaleY } = info;
  const { minWidth = 1, maxWidth: maxWidth2 = Infinity, minHeight = 1, maxHeight: maxHeight2 = Infinity } = opts;
  let w = shape.props.w * scaleX;
  let h = shape.props.h * scaleY;
  const offset2 = new Vec2d(0, 0);
  if (w > 0) {
    if (w < minWidth) {
      switch (handle) {
        case "top_left":
        case "left":
        case "bottom_left": {
          offset2.x = w - minWidth;
          break;
        }
        case "top":
        case "bottom": {
          offset2.x = (w - minWidth) / 2;
          break;
        }
        default: {
          offset2.x = 0;
        }
      }
      w = minWidth;
    }
  } else {
    offset2.x = w;
    w = -w;
    if (w < minWidth) {
      switch (handle) {
        case "top_left":
        case "left":
        case "bottom_left": {
          offset2.x = -w;
          break;
        }
        default: {
          offset2.x = -minWidth;
        }
      }
      w = minWidth;
    }
  }
  if (h > 0) {
    if (h < minHeight) {
      switch (handle) {
        case "top_left":
        case "top":
        case "top_right": {
          offset2.y = h - minHeight;
          break;
        }
        case "right":
        case "left": {
          offset2.y = (h - minHeight) / 2;
          break;
        }
        default: {
          offset2.y = 0;
        }
      }
      h = minHeight;
    }
  } else {
    offset2.y = h;
    h = -h;
    if (h < minHeight) {
      switch (handle) {
        case "top_left":
        case "top":
        case "top_right": {
          offset2.y = -h;
          break;
        }
        default: {
          offset2.y = -minHeight;
        }
      }
      h = minHeight;
    }
  }
  const { x, y } = offset2.rot(shape.rotation).add(newPoint);
  return {
    x,
    y,
    props: {
      w: Math.min(maxWidth2, w),
      h: Math.min(maxHeight2, h)
    }
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs
var getSandboxPermissions = (permissions) => {
  return Object.entries(permissions).filter(([_perm, isEnabled]) => isEnabled).map(([perm]) => perm).join(" ");
};
var EmbedShapeUtil = class extends BaseBoxShapeUtil {
  static type = "embed";
  static props = embedShapeProps;
  static migrations = embedShapeMigrations;
  hideSelectionBoundsFg = (shape) => !this.canResize(shape);
  canEdit = () => true;
  canUnmount = (shape) => {
    return !!getEmbedInfo(shape.props.url)?.definition?.canUnmount;
  };
  canResize = (shape) => {
    return !!getEmbedInfo(shape.props.url)?.definition?.doesResize;
  };
  canEditInReadOnly = () => true;
  getDefaultProps() {
    return {
      w: 300,
      h: 300,
      url: ""
    };
  }
  isAspectRatioLocked = (shape) => {
    const embedInfo = getEmbedInfo(shape.props.url);
    return embedInfo?.definition.isAspectRatioLocked ?? false;
  };
  onResize = (shape, info) => {
    const isAspectRatioLocked = this.isAspectRatioLocked(shape);
    const embedInfo = getEmbedInfo(shape.props.url);
    let minWidth = embedInfo?.definition.minWidth ?? 200;
    let minHeight = embedInfo?.definition.minHeight ?? 200;
    if (isAspectRatioLocked) {
      const aspectRatio = shape.props.w / shape.props.h;
      if (aspectRatio > 1) {
        minWidth *= aspectRatio;
      } else {
        minHeight /= aspectRatio;
      }
    }
    return resizeBox2(shape, info, { minWidth, minHeight });
  };
  component(shape) {
    const { w, h, url } = shape.props;
    const isEditing = useIsEditing(shape.id);
    const embedInfo = (0, import_react46.useMemo)(() => getEmbedInfoUnsafely(url), [url]);
    const isHoveringWhileEditingSameShape = useValue(
      "is hovering",
      () => {
        const { editingShapeId, hoveredShapeId } = this.editor.currentPageState;
        if (editingShapeId && hoveredShapeId !== editingShapeId) {
          const editingShape = this.editor.getShape(editingShapeId);
          if (editingShape && this.editor.isShapeOfType(editingShape, "embed")) {
            return true;
          }
        }
        return false;
      },
      []
    );
    const pageRotation = this.editor.getShapePageTransform(shape).rotation();
    const isInteractive = isEditing || isHoveringWhileEditingSameShape;
    if (embedInfo?.definition.type === "github_gist") {
      const idFromGistUrl = embedInfo.url.split("/").pop();
      if (!idFromGistUrl)
        throw Error("No gist id!");
      return (0, import_jsx_runtime53.jsx)(HTMLContainer, { className: "tl-embed-container", id: shape.id, children: (0, import_jsx_runtime53.jsx)(
        Gist,
        {
          id: idFromGistUrl,
          width: toDomPrecision(w),
          height: toDomPrecision(h),
          isInteractive,
          pageRotation
        }
      ) });
    }
    const sandbox = getSandboxPermissions({
      ...embedShapePermissionDefaults,
      ...embedInfo?.definition.overridePermissions ?? {}
    });
    return (0, import_jsx_runtime53.jsx)(HTMLContainer, { className: "tl-embed-container", id: shape.id, children: embedInfo?.definition ? (0, import_jsx_runtime53.jsx)(
      "iframe",
      {
        className: "tl-embed",
        sandbox,
        src: embedInfo.embedUrl,
        width: toDomPrecision(w),
        height: toDomPrecision(h),
        draggable: false,
        frameBorder: "0",
        referrerPolicy: "no-referrer-when-downgrade",
        style: {
          border: 0,
          pointerEvents: isInteractive ? "auto" : "none",
          // Fix for safari <https://stackoverflow.com/a/49150908>
          zIndex: isInteractive ? "" : "-1",
          boxShadow: getRotatedBoxShadow(pageRotation),
          borderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,
          background: embedInfo?.definition.backgroundColor
        }
      }
    ) : null });
  }
  indicator(shape) {
    const embedInfo = (0, import_react46.useMemo)(() => getEmbedInfo(shape.props.url), [shape.props.url]);
    return (0, import_jsx_runtime53.jsx)(
      "rect",
      {
        width: toDomPrecision(shape.props.w),
        height: toDomPrecision(shape.props.h),
        rx: embedInfo?.definition.overrideOutlineRadius ?? 8,
        ry: embedInfo?.definition.overrideOutlineRadius ?? 8
      }
    );
  }
};
function Gist({
  id,
  file,
  isInteractive,
  width,
  height,
  style,
  pageRotation
}) {
  return (0, import_jsx_runtime53.jsx)(
    "iframe",
    {
      className: "tl-embed",
      draggable: false,
      width: toDomPrecision(width),
      height: toDomPrecision(height),
      frameBorder: "0",
      scrolling: "no",
      seamless: true,
      referrerPolicy: "no-referrer-when-downgrade",
      style: {
        ...style,
        pointerEvents: isInteractive ? "all" : "none",
        // Fix for safari <https://stackoverflow.com/a/49150908>
        zIndex: isInteractive ? "" : "-1",
        boxShadow: getRotatedBoxShadow(pageRotation)
      },
      srcDoc: `
			<html>
				<head>
					<base target="_blank">
				</head>
				<body>
					<script src=${`https://gist.github.com/${id}.js${file ? `?file=${file}` : ""}`}><\/script>
					<style type="text/css">
						* { margin: 0px; }
						table { height: 100%; background-color: red; }
						.gist { background-color: none; height: 100%;  }
						.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }
					</style>
				</body>
			</html>`
    }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs
var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/frame/components/FrameHeading.mjs
var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
var import_react48 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs
var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
var import_react47 = __toESM(require_react(), 1);
var FrameLabelInput = (0, import_react47.forwardRef)(({ id, name, isEditing }, ref) => {
  const editor = useEditor();
  const handleKeyDown = (0, import_react47.useCallback)(
    (e) => {
      if (e.key === "Enter" && !e.nativeEvent.isComposing) {
        stopEventPropagation(e);
        e.currentTarget.blur();
        editor.setEditingShape(null);
      }
    },
    [editor]
  );
  const handleBlur = (0, import_react47.useCallback)(
    (e) => {
      const shape = editor.getShape(id);
      if (!shape)
        return;
      const name2 = shape.props.name;
      const value = e.currentTarget.value.trim();
      if (name2 === value)
        return;
      editor.updateShapes(
        [
          {
            id,
            type: "frame",
            props: { name: value }
          }
        ],
        { squashing: true }
      );
    },
    [id, editor]
  );
  const handleChange = (0, import_react47.useCallback)(
    (e) => {
      const shape = editor.getShape(id);
      if (!shape)
        return;
      const name2 = shape.props.name;
      const value = e.currentTarget.value;
      if (name2 === value)
        return;
      editor.updateShapes(
        [
          {
            id,
            type: "frame",
            props: { name: value }
          }
        ],
        { squashing: true }
      );
    },
    [id, editor]
  );
  return (0, import_jsx_runtime54.jsxs)("div", { className: `tl-frame-label ${isEditing ? "tl-frame-label__editing" : ""}`, children: [
    (0, import_jsx_runtime54.jsx)(
      "input",
      {
        className: "tl-frame-name-input",
        ref,
        style: { display: isEditing ? void 0 : "none" },
        value: name,
        autoFocus: true,
        onKeyDown: handleKeyDown,
        onBlur: handleBlur,
        onChange: handleChange
      }
    ),
    defaultEmptyAs(name, "Frame") + String.fromCharCode(8203)
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/frame/components/FrameHeading.mjs
var FrameHeading = function FrameHeading2({
  id,
  name,
  width,
  height
}) {
  const editor = useEditor();
  const pageRotation = canonicalizeRotation(editor.getShapePageTransform(id).rotation());
  const isEditing = useIsEditing(id);
  const rInput = (0, import_react48.useRef)(null);
  const handlePointerDown = (0, import_react48.useCallback)(
    (e) => {
      const event = getPointerInfo(e);
      if (editor.editingShapeId === id)
        return;
      editor.dispatch({
        type: "pointer",
        name: "pointer_down",
        target: "shape",
        shape: editor.getShape(id),
        ...event
      });
      e.preventDefault();
    },
    [editor, id]
  );
  (0, import_react48.useEffect)(() => {
    const el = rInput.current;
    if (el && isEditing) {
      el.focus();
      el.select();
      requestAnimationFrame(() => {
        if (document.activeElement !== el) {
          el.focus();
          el.select();
        }
      });
    }
  }, [rInput, isEditing]);
  const offsetRotation = pageRotation + Math.PI / 4;
  const scaledRotation = (offsetRotation * (2 / Math.PI) + 4) % 4;
  const labelSide = ["top", "left", "bottom", "right"][Math.floor(scaledRotation)];
  let labelTranslate;
  switch (labelSide) {
    case "top":
      labelTranslate = ``;
      break;
    case "right":
      labelTranslate = `translate(${toDomPrecision(width)}px, 0px) rotate(90deg)`;
      break;
    case "bottom":
      labelTranslate = `translate(${toDomPrecision(width)}px, ${toDomPrecision(
        height
      )}px) rotate(180deg)`;
      break;
    case "left":
      labelTranslate = `translate(0px, ${toDomPrecision(height)}px) rotate(270deg)`;
      break;
  }
  return (0, import_jsx_runtime55.jsx)(
    "div",
    {
      className: "tl-frame-heading",
      style: {
        overflow: isEditing ? "visible" : "hidden",
        maxWidth: `calc(var(--tl-zoom) * ${labelSide === "top" || labelSide === "bottom" ? Math.ceil(width) : Math.ceil(height)}px + var(--space-5))`,
        bottom: "100%",
        transform: `${labelTranslate} scale(var(--tl-scale)) translateX(calc(-1 * var(--space-3))`
      },
      onPointerDown: handlePointerDown,
      children: (0, import_jsx_runtime55.jsx)("div", { className: "tl-frame-heading-hit-area", children: (0, import_jsx_runtime55.jsx)(FrameLabelInput, { ref: rInput, id, name, isEditing }) })
    }
  );
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs
function defaultEmptyAs(str, dflt) {
  if (str.match(/^\s*$/)) {
    return dflt;
  }
  return str;
}
var FrameShapeUtil = class extends BaseBoxShapeUtil {
  static type = "frame";
  static props = frameShapeProps;
  static migrations = frameShapeMigrations;
  canBind = () => true;
  canEdit = () => true;
  getDefaultProps() {
    return { w: 160 * 2, h: 90 * 2, name: "" };
  }
  getGeometry(shape) {
    return new Rectangle2d({
      width: shape.props.w,
      height: shape.props.h,
      isFilled: false
    });
  }
  component(shape) {
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    const theme = useDefaultColorTheme();
    return (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
      (0, import_jsx_runtime56.jsx)(SVGContainer, { children: (0, import_jsx_runtime56.jsx)(
        "rect",
        {
          className: "tl-frame__body",
          width: bounds.width,
          height: bounds.height,
          fill: theme.solid,
          stroke: theme.text
        }
      ) }),
      (0, import_jsx_runtime56.jsx)(
        FrameHeading,
        {
          id: shape.id,
          name: shape.props.name,
          width: bounds.width,
          height: bounds.height
        }
      )
    ] });
  }
  toSvg(shape) {
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect.setAttribute("width", shape.props.w.toString());
    rect.setAttribute("height", shape.props.h.toString());
    rect.setAttribute("fill", theme.solid);
    rect.setAttribute("stroke", theme.black.solid);
    rect.setAttribute("stroke-width", "1");
    rect.setAttribute("rx", "1");
    rect.setAttribute("ry", "1");
    g.appendChild(rect);
    const pageRotation = canonicalizeRotation(
      this.editor.getShapePageTransform(shape.id).rotation()
    );
    const offsetRotation = pageRotation + Math.PI / 4;
    const scaledRotation = (offsetRotation * (2 / Math.PI) + 4) % 4;
    const labelSide = ["top", "left", "bottom", "right"][Math.floor(scaledRotation)];
    let labelTranslate;
    switch (labelSide) {
      case "top":
        labelTranslate = ``;
        break;
      case "right":
        labelTranslate = `translate(${toDomPrecision(shape.props.w)}px, 0px) rotate(90deg)`;
        break;
      case "bottom":
        labelTranslate = `translate(${toDomPrecision(shape.props.w)}px, ${toDomPrecision(
          shape.props.h
        )}px) rotate(180deg)`;
        break;
      case "left":
        labelTranslate = `translate(0px, ${toDomPrecision(shape.props.h)}px) rotate(270deg)`;
        break;
      default:
        labelTranslate = ``;
    }
    const opts = {
      fontSize: 12,
      fontFamily: "Inter, sans-serif",
      textAlign: "start",
      width: shape.props.w,
      height: 32,
      padding: 0,
      lineHeight: 1,
      fontStyle: "normal",
      fontWeight: "normal",
      overflow: "truncate-ellipsis",
      verticalTextAlign: "middle"
    };
    const spans = this.editor.textMeasure.measureTextSpans(
      defaultEmptyAs(shape.props.name, "Frame") + String.fromCharCode(8203),
      opts
    );
    const firstSpan = spans[0];
    const lastSpan = last(spans);
    const labelTextWidth = lastSpan.box.w + lastSpan.box.x - firstSpan.box.x;
    const text = createTextSvgElementFromSpans(this.editor, spans, {
      offsetY: -opts.height - 2,
      ...opts
    });
    text.style.setProperty("transform", labelTranslate);
    const textBg = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    textBg.setAttribute("x", "-8px");
    textBg.setAttribute("y", -opts.height - 4 + "px");
    textBg.setAttribute("width", labelTextWidth + 16 + "px");
    textBg.setAttribute("height", `${opts.height}px`);
    textBg.setAttribute("rx", "4px");
    textBg.setAttribute("ry", "4px");
    textBg.setAttribute("fill", theme.background);
    g.appendChild(textBg);
    g.appendChild(text);
    return g;
  }
  indicator(shape) {
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    return (0, import_jsx_runtime56.jsx)(
      "rect",
      {
        width: toDomPrecision(bounds.width),
        height: toDomPrecision(bounds.height),
        className: `tl-frame-indicator`
      }
    );
  }
  canReceiveNewChildrenOfType = (shape, _type) => {
    return !shape.isLocked;
  };
  providesBackgroundForChildren() {
    return true;
  }
  canDropShapes = (shape, _shapes) => {
    return !shape.isLocked;
  };
  onDragShapesOver = (frame2, shapes) => {
    if (!shapes.every((child) => child.parentId === frame2.id)) {
      this.editor.reparentShapes(
        shapes.map((shape) => shape.id),
        frame2.id
      );
      return { shouldHint: true };
    }
    return { shouldHint: false };
  };
  onDragShapesOut = (_shape, shapes) => {
    const parent = this.editor.getShape(_shape.parentId);
    const isInGroup = parent && this.editor.isShapeOfType(parent, "group");
    if (isInGroup) {
      this.editor.reparentShapes(shapes, parent.id);
    } else {
      this.editor.reparentShapes(shapes, this.editor.currentPageId);
    }
  };
  onResizeEnd = (shape) => {
    const bounds = this.editor.getShapePageBounds(shape);
    const children = this.editor.getSortedChildIdsForParent(shape.id);
    const shapesToReparent = [];
    for (const childId of children) {
      const childBounds = this.editor.getShapePageBounds(childId);
      if (!bounds.includes(childBounds)) {
        shapesToReparent.push(childId);
      }
    }
    if (shapesToReparent.length > 0) {
      this.editor.reparentShapes(shapesToReparent, this.editor.currentPageId);
    }
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs
var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/TextLabel.mjs
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
var import_react49 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/legacyProps.mjs
function getLegacyOffsetX(align, padding, spans, totalWidth) {
  if ((align === "start-legacy" || align === "end-legacy") && spans.length !== 0) {
    const spansBounds = Box2d.From(spans[0].box);
    for (const { box } of spans) {
      spansBounds.union(box);
    }
    if (align === "start-legacy") {
      return (totalWidth - 2 * padding - spansBounds.width) / 2;
    } else if (align === "end-legacy") {
      return -(totalWidth - 2 * padding - spansBounds.width) / 2;
    }
  }
}
function isLegacyAlign(align) {
  return align === "start-legacy" || align === "middle-legacy" || align === "end-legacy";
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/TextLabel.mjs
var TextLabel = import_react49.default.memo(function TextLabel2({
  id,
  type,
  text,
  size: size2,
  labelColor,
  font,
  align,
  verticalAlign,
  wrap: wrap2,
  bounds
}) {
  const {
    rInput,
    isEmpty,
    isEditing,
    handleFocus,
    handleChange,
    handleKeyDown,
    handleBlur,
    handleInputPointerDown,
    handleDoubleClick
  } = useEditableText(id, type, text);
  const finalText = TextHelpers.normalizeTextForDom(text);
  const hasText = finalText.length > 0;
  const legacyAlign = isLegacyAlign(align);
  const theme = useDefaultColorTheme();
  if (!isEditing && !hasText) {
    return null;
  }
  return (0, import_jsx_runtime57.jsx)(
    "div",
    {
      className: "tl-text-label",
      "data-font": font,
      "data-align": align,
      "data-hastext": !isEmpty,
      "data-isediting": isEditing,
      "data-textwrap": !!wrap2,
      style: {
        justifyContent: align === "middle" || legacyAlign ? "center" : align,
        alignItems: verticalAlign === "middle" ? "center" : verticalAlign,
        ...bounds ? {
          top: bounds.minY,
          left: bounds.minX,
          width: bounds.width,
          height: bounds.height,
          position: "absolute"
        } : {}
      },
      children: (0, import_jsx_runtime57.jsxs)(
        "div",
        {
          className: "tl-text-label__inner",
          style: {
            fontSize: LABEL_FONT_SIZES[size2],
            lineHeight: LABEL_FONT_SIZES[size2] * TEXT_PROPS.lineHeight + "px",
            minHeight: TEXT_PROPS.lineHeight + 32,
            minWidth: 0,
            color: theme[labelColor].solid
          },
          children: [
            (0, import_jsx_runtime57.jsx)("div", { className: "tl-text tl-text-content", dir: "ltr", children: finalText }),
            isEditing && (0, import_jsx_runtime57.jsx)(
              "textarea",
              {
                ref: rInput,
                className: "tl-text tl-text-input",
                name: "text",
                tabIndex: -1,
                autoComplete: "false",
                autoCapitalize: "false",
                autoCorrect: "false",
                autoSave: "false",
                autoFocus: true,
                placeholder: "",
                spellCheck: "true",
                wrap: "off",
                dir: "auto",
                datatype: "wysiwyg",
                defaultValue: text,
                onFocus: handleFocus,
                onChange: handleChange,
                onKeyDown: handleKeyDown,
                onBlur: handleBlur,
                onContextMenu: stopEventPropagation,
                onPointerDown: handleInputPointerDown,
                onDoubleClick: handleDoubleClick
              }
            )
          ]
        }
      )
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/getTextLabelSvgElement.mjs
function getTextLabelSvgElement({
  bounds,
  editor,
  font,
  shape
}) {
  const padding = 16;
  const opts = {
    fontSize: LABEL_FONT_SIZES[shape.props.size],
    fontFamily: font,
    textAlign: shape.props.align,
    verticalTextAlign: shape.props.verticalAlign,
    width: Math.ceil(bounds.width),
    height: Math.ceil(bounds.height),
    padding: 16,
    lineHeight: TEXT_PROPS.lineHeight,
    fontStyle: "normal",
    fontWeight: "normal",
    overflow: "wrap",
    offsetX: 0
  };
  const spans = editor.textMeasure.measureTextSpans(shape.props.text, opts);
  const offsetX = getLegacyOffsetX(shape.props.align, padding, spans, bounds.width);
  if (offsetX) {
    opts.offsetX = offsetX;
  }
  const textElm = createTextSvgElementFromSpans(editor, spans, opts);
  return textElm;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/polygon-helpers.mjs
function precise2(A) {
  return `${toDomPrecision(A.x)},${toDomPrecision(A.y)} `;
}
function rng2(seed = "") {
  let x = 0;
  let y = 0;
  let z = 0;
  let w = 0;
  function next() {
    const t2 = x ^ x << 11;
    x = y;
    y = z;
    z = w;
    w ^= (w >>> 19 ^ t2 ^ t2 >>> 8) >>> 0;
    return w / 4294967296 * 2;
  }
  for (let k = 0; k < seed.length + 64; k++) {
    x ^= seed.charCodeAt(k) | 0;
    next();
  }
  return next;
}
function getRoundedInkyPolygonPath(points) {
  let polylineA = `M`;
  const len = points.length;
  let p0;
  let p1;
  let p2;
  for (let i = 0, n = len; i < n; i += 3) {
    p0 = points[i];
    p1 = points[i + 1];
    p2 = points[i + 2];
    polylineA += `${precise2(p0)}L${precise2(p1)}Q${precise2(p2)}`;
  }
  polylineA += `${precise2(points[0])}`;
  return polylineA;
}
function getRoundedPolygonPoints(id, outline, offset2, roundness, passes) {
  const results = [];
  const random = rng2(id);
  let p0 = outline[0];
  let p1;
  const len = outline.length;
  for (let i = 0, n = len * passes; i < n; i++) {
    p1 = Vec2d.AddXY(outline[(i + 1) % len], random() * offset2, random() * offset2);
    const delta = Vec2d.Sub(p1, p0);
    const distance = Vec2d.Len(delta);
    const vector = Vec2d.Div(delta, distance).mul(Math.min(distance / 4, roundness));
    results.push(Vec2d.Add(p0, vector), Vec2d.Add(p1, vector.neg()), p1);
    p0 = p1;
  }
  return results;
}
function getDrawLinePathData(id, outline, strokeWidth) {
  let innerPathData = `M ${precise2(outline[0])}L`;
  let outerPathData2 = `M ${precise2(outline[0])}L`;
  const offset2 = strokeWidth / 3;
  const roundness = strokeWidth * 2;
  const random = rng2(id);
  let p0 = outline[0];
  let p1;
  let s0 = outline[0];
  let s1;
  const len = outline.length;
  for (let i = 0, n = len - 1; i < n; i++) {
    p1 = outline[i + 1];
    s1 = Vec2d.AddXY(outline[i + 1], random() * offset2, random() * offset2);
    const delta = Vec2d.Sub(p1, p0);
    const distance = Vec2d.Len(delta);
    const vector = Vec2d.Div(delta, distance).mul(Math.min(distance / 4, roundness));
    const q0 = Vec2d.Add(p0, vector);
    const q1 = Vec2d.Add(p1, vector.neg());
    const sDelta = Vec2d.Sub(s1, s0);
    const sDistance = Vec2d.Len(sDelta);
    const sVector = Vec2d.Div(sDelta, sDistance).mul(Math.min(sDistance / 4, roundness));
    const sq0 = Vec2d.Add(s0, sVector);
    const sq1 = Vec2d.Add(s1, sVector.neg());
    if (i === n - 1) {
      innerPathData += `${precise2(q0)}L ${precise2(p1)}`;
      outerPathData2 += `${precise2(sq0)}L ${precise2(s1)}`;
    } else {
      innerPathData += `${precise2(q0)}L ${precise2(q1)}Q ${precise2(p1)}`;
      outerPathData2 += `${precise2(sq0)}L ${precise2(sq1)}Q ${precise2(s1)}`;
      p0 = p1;
      s0 = s1;
    }
  }
  return [innerPathData, innerPathData + outerPathData2];
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/cloudOutline.mjs
function getPillCircumference(width, height) {
  const radius = Math.min(width, height) / 2;
  const longSide = Math.max(width, height) - radius * 2;
  return Math.PI * (radius * 2) + 2 * longSide;
}
function getPillPoints(width, height, numPoints) {
  const radius = Math.min(width, height) / 2;
  const longSide = Math.max(width, height) - radius * 2;
  const circumference = Math.PI * (radius * 2) + 2 * longSide;
  const spacing = circumference / numPoints;
  const sections = width > height ? [
    {
      type: "straight",
      start: new Vec2d(radius, 0),
      delta: new Vec2d(1, 0)
    },
    {
      type: "arc",
      center: new Vec2d(width - radius, radius),
      startAngle: -PI / 2
    },
    {
      type: "straight",
      start: new Vec2d(width - radius, height),
      delta: new Vec2d(-1, 0)
    },
    {
      type: "arc",
      center: new Vec2d(radius, radius),
      startAngle: PI / 2
    }
  ] : [
    {
      type: "straight",
      start: new Vec2d(width, radius),
      delta: new Vec2d(0, 1)
    },
    {
      type: "arc",
      center: new Vec2d(radius, height - radius),
      startAngle: 0
    },
    {
      type: "straight",
      start: new Vec2d(0, height - radius),
      delta: new Vec2d(0, -1)
    },
    {
      type: "arc",
      center: new Vec2d(radius, radius),
      startAngle: PI
    }
  ];
  let sectionOffset = 0;
  const points = [];
  for (let i = 0; i < numPoints; i++) {
    const section = sections[0];
    if (section.type === "straight") {
      points.push(Vec2d.Add(section.start, Vec2d.Mul(section.delta, sectionOffset)));
    } else {
      points.push(
        getPointOnCircle(
          section.center.x,
          section.center.y,
          radius,
          section.startAngle + sectionOffset / radius
        )
      );
    }
    sectionOffset += spacing;
    let sectionLength = section.type === "straight" ? longSide : PI * radius;
    while (sectionOffset > sectionLength) {
      sectionOffset -= sectionLength;
      sections.push(sections.shift());
      sectionLength = sections[0].type === "straight" ? longSide : PI * radius;
    }
  }
  return points;
}
var switchSize = (size2, s, m, l, xl) => {
  switch (size2) {
    case "s":
      return s;
    case "m":
      return m;
    case "l":
      return l;
    case "xl":
      return xl;
  }
};
function getCloudArcs(width, height, seed, size2) {
  const getRandom = rng(seed);
  const pillCircumference = getPillCircumference(width, height);
  const numBumps = Math.max(
    Math.ceil(pillCircumference / switchSize(size2, 50, 70, 100, 130)),
    6,
    Math.ceil(pillCircumference / Math.min(width, height))
  );
  const targetBumpProtrusion = pillCircumference / numBumps * 0.2;
  const innerWidth = Math.max(width - targetBumpProtrusion * 2, 1);
  const innerHeight = Math.max(height - targetBumpProtrusion * 2, 1);
  const paddingX = (width - innerWidth) / 2;
  const paddingY = (height - innerHeight) / 2;
  const distanceBetweenPointsOnPerimeter = getPillCircumference(innerWidth, innerHeight) / numBumps;
  const bumpPoints = getPillPoints(innerWidth, innerHeight, numBumps).map((p) => {
    return p.addXY(paddingX, paddingY);
  });
  const maxWiggleX = width < 20 ? 0 : targetBumpProtrusion * 0.3;
  const maxWiggleY = height < 20 ? 0 : targetBumpProtrusion * 0.3;
  const wiggledPoints = bumpPoints.slice(0);
  for (let i = 0; i < Math.floor(numBumps / 2); i++) {
    wiggledPoints[i] = Vec2d.AddXY(
      wiggledPoints[i],
      getRandom() * maxWiggleX,
      getRandom() * maxWiggleY
    );
    wiggledPoints[numBumps - i - 1] = Vec2d.AddXY(
      wiggledPoints[numBumps - i - 1],
      getRandom() * maxWiggleX,
      getRandom() * maxWiggleY
    );
  }
  const arcs = [];
  for (let i = 0; i < wiggledPoints.length; i++) {
    const j = i === wiggledPoints.length - 1 ? 0 : i + 1;
    const leftWigglePoint = wiggledPoints[i];
    const rightWigglePoint = wiggledPoints[j];
    const leftPoint = bumpPoints[i];
    const rightPoint = bumpPoints[j];
    const midPoint = Vec2d.Average([leftPoint, rightPoint]);
    const offsetAngle = Vec2d.Angle(leftPoint, rightPoint) - Math.PI / 2;
    const distanceBetweenOriginalPoints = Vec2d.Dist(leftPoint, rightPoint);
    const curvatureOffset = distanceBetweenPointsOnPerimeter - distanceBetweenOriginalPoints;
    const distanceBetweenWigglePoints = Vec2d.Dist(leftWigglePoint, rightWigglePoint);
    const relativeSize = distanceBetweenWigglePoints / distanceBetweenOriginalPoints;
    const finalDistance = (Math.max(paddingX, paddingY) + curvatureOffset) * relativeSize;
    const arcPoint = Vec2d.Add(midPoint, Vec2d.FromAngle(offsetAngle, finalDistance));
    if (arcPoint.x < 0) {
      arcPoint.x = 0;
    } else if (arcPoint.x > width) {
      arcPoint.x = width;
    }
    if (arcPoint.y < 0) {
      arcPoint.y = 0;
    } else if (arcPoint.y > height) {
      arcPoint.y = height;
    }
    const center = getCenterOfCircleGivenThreePoints(leftWigglePoint, rightWigglePoint, arcPoint);
    const radius = Vec2d.Dist(
      center ? center : Vec2d.Average([leftWigglePoint, rightWigglePoint]),
      leftWigglePoint
    );
    arcs.push({
      leftPoint: leftWigglePoint,
      rightPoint: rightWigglePoint,
      arcPoint,
      center,
      radius
    });
  }
  return arcs;
}
function getCenterOfCircleGivenThreePoints(a, b, c) {
  const A = a.x * (b.y - c.y) - a.y * (b.x - c.x) + b.x * c.y - c.x * b.y;
  const B = (a.x * a.x + a.y * a.y) * (c.y - b.y) + (b.x * b.x + b.y * b.y) * (a.y - c.y) + (c.x * c.x + c.y * c.y) * (b.y - a.y);
  const C = (a.x * a.x + a.y * a.y) * (b.x - c.x) + (b.x * b.x + b.y * b.y) * (c.x - a.x) + (c.x * c.x + c.y * c.y) * (a.x - b.x);
  const x = -B / (2 * A);
  const y = -C / (2 * A);
  if (!Number.isFinite(x) || !Number.isFinite(y)) {
    return null;
  }
  return new Vec2d(x, y);
}
function cloudOutline(width, height, seed, size2) {
  const path = [];
  const arcs = getCloudArcs(width, height, seed, size2);
  for (const { center, radius, leftPoint, rightPoint } of arcs) {
    path.push(...pointsOnArc(leftPoint, rightPoint, center, radius, 10));
  }
  return path;
}
function cloudSvgPath(width, height, seed, size2) {
  const arcs = getCloudArcs(width, height, seed, size2);
  let path = `M${toDomPrecision(arcs[0].leftPoint.x)},${toDomPrecision(arcs[0].leftPoint.y)}`;
  for (const { leftPoint, rightPoint, radius, center } of arcs) {
    if (center === null) {
      path += ` L${toDomPrecision(rightPoint.x)},${toDomPrecision(rightPoint.y)}`;
      continue;
    }
    const arc = isLeft(leftPoint, rightPoint, center) ? "0" : "1";
    path += ` A${toDomPrecision(radius)},${toDomPrecision(radius)} 0 ${arc},1 ${toDomPrecision(
      rightPoint.x
    )},${toDomPrecision(rightPoint.y)}`;
  }
  path += " Z";
  return path;
}
function inkyCloudSvgPath(width, height, seed, size2) {
  const getRandom = rng(seed);
  const mutMultiplier = size2 === "s" ? 0.5 : size2 === "m" ? 0.7 : size2 === "l" ? 0.9 : 1.6;
  const mut = (n) => {
    return n + getRandom() * mutMultiplier * 2;
  };
  const arcs = getCloudArcs(width, height, seed, size2);
  const avgArcLength = arcs.reduce((sum, arc) => sum + Vec2d.Dist(arc.leftPoint, arc.rightPoint), 0) / arcs.length;
  const shouldMutatePoints = avgArcLength > mutMultiplier * 15;
  const mutPoint = shouldMutatePoints ? (p) => new Vec2d(mut(p.x), mut(p.y)) : (p) => p;
  let pathA = `M${toDomPrecision(arcs[0].leftPoint.x)},${toDomPrecision(arcs[0].leftPoint.y)}`;
  let leftMutPoint = mutPoint(arcs[0].leftPoint);
  let pathB = `M${toDomPrecision(leftMutPoint.x)},${toDomPrecision(leftMutPoint.y)}`;
  for (const { leftPoint, center, rightPoint, radius, arcPoint } of arcs) {
    if (center === null) {
      pathA += ` L${toDomPrecision(rightPoint.x)},${toDomPrecision(rightPoint.y)}`;
      const rightMutPoint2 = mutPoint(rightPoint);
      pathB += ` L${toDomPrecision(rightMutPoint2.x)},${toDomPrecision(rightMutPoint2.y)}`;
      leftMutPoint = rightMutPoint2;
      continue;
    }
    const arc = isLeft(leftPoint, rightPoint, center) ? "0" : "1";
    pathA += ` A${toDomPrecision(radius)},${toDomPrecision(radius)} 0 ${arc},1 ${toDomPrecision(
      rightPoint.x
    )},${toDomPrecision(rightPoint.y)}`;
    const rightMutPoint = mutPoint(rightPoint);
    const mutArcPoint = mutPoint(arcPoint);
    const mutCenter = getCenterOfCircleGivenThreePoints(leftMutPoint, rightMutPoint, mutArcPoint);
    if (!mutCenter) {
      pathB += ` L${toDomPrecision(rightMutPoint.x)},${toDomPrecision(rightMutPoint.y)}`;
      leftMutPoint = rightMutPoint;
      continue;
    }
    const mutRadius = Math.abs(Vec2d.Dist(mutCenter, leftMutPoint));
    pathB += ` A${toDomPrecision(mutRadius)},${toDomPrecision(
      mutRadius
    )} 0 ${arc},1 ${toDomPrecision(rightMutPoint.x)},${toDomPrecision(rightMutPoint.y)}`;
    leftMutPoint = rightMutPoint;
  }
  return pathA + pathB + " Z";
}
function pointsOnArc(startPoint, endPoint, center, radius, numPoints) {
  if (center === null) {
    return [Vec2d.From(startPoint), Vec2d.From(endPoint)];
  }
  const results = [];
  const startAngle = Vec2d.Angle(center, startPoint);
  const endAngle = Vec2d.Angle(center, endPoint);
  const l = clockwiseAngleDist(startAngle, endAngle);
  for (let i = 0; i < numPoints; i++) {
    const t2 = i / (numPoints - 1);
    const angle = startAngle + l * t2;
    const point = getPointOnCircle(center.x, center.y, radius, angle);
    results.push(point);
  }
  return results;
}
function isLeft(a, b, c) {
  return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) > 0;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DashStyleCloud.mjs
var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
var React24 = __toESM(require_react(), 1);
var DashStyleCloud = React24.memo(function DashStylePolygon({
  dash,
  fill,
  color,
  strokeWidth,
  w,
  h,
  id,
  size: size2
}) {
  const theme = useDefaultColorTheme();
  const innerPath = cloudSvgPath(w, h, id, size2);
  const arcs = getCloudArcs(w, h, id, size2);
  return (0, import_jsx_runtime58.jsxs)(import_jsx_runtime58.Fragment, { children: [
    (0, import_jsx_runtime58.jsx)(ShapeFill, { theme, d: innerPath, fill, color }),
    (0, import_jsx_runtime58.jsx)("g", { strokeWidth, stroke: theme[color].solid, fill: "none", pointerEvents: "all", children: arcs.map(({ leftPoint, rightPoint, center, radius }, i) => {
      const arcLength = center ? radius * canonicalizeRotation(
        canonicalizeRotation(Vec2d.Angle(center, rightPoint)) - canonicalizeRotation(Vec2d.Angle(center, leftPoint))
      ) : Vec2d.Dist(leftPoint, rightPoint);
      const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
        arcLength,
        strokeWidth,
        {
          style: dash,
          start: "outset",
          end: "outset"
        }
      );
      return (0, import_jsx_runtime58.jsx)(
        "path",
        {
          d: center ? `M${leftPoint.x},${leftPoint.y}A${radius},${radius},0,0,1,${rightPoint.x},${rightPoint.y}` : `M${leftPoint.x},${leftPoint.y}L${rightPoint.x},${rightPoint.y}`,
          strokeDasharray,
          strokeDashoffset
        },
        i
      );
    }) })
  ] });
});
function DashStyleCloudSvg({
  dash,
  fill,
  color,
  theme,
  strokeWidth,
  w,
  h,
  id,
  size: size2
}) {
  const innerPath = cloudSvgPath(w, h, id, size2);
  const arcs = getCloudArcs(w, h, id, size2);
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "g");
  strokeElement.setAttribute("stroke-width", strokeWidth.toString());
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("fill", "none");
  for (const { leftPoint, rightPoint, center, radius } of arcs) {
    const arcLength = center ? radius * canonicalizeRotation(
      canonicalizeRotation(Vec2d.Angle(center, rightPoint)) - canonicalizeRotation(Vec2d.Angle(center, leftPoint))
    ) : Vec2d.Dist(leftPoint, rightPoint);
    const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(arcLength, strokeWidth, {
      style: dash,
      start: "outset",
      end: "outset"
    });
    const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path.setAttribute(
      "d",
      center ? `M${leftPoint.x},${leftPoint.y}A${radius},${radius},0,0,1,${rightPoint.x},${rightPoint.y}` : `M${leftPoint.x},${leftPoint.y}L${rightPoint.x},${rightPoint.y}`
    );
    path.setAttribute("stroke-dasharray", strokeDasharray.toString());
    path.setAttribute("stroke-dashoffset", strokeDashoffset.toString());
    strokeElement.appendChild(path);
  }
  const fillElement = getShapeFillSvg({
    d: innerPath,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DashStyleEllipse.mjs
var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
var React25 = __toESM(require_react(), 1);
var DashStyleEllipse = React25.memo(function DashStyleEllipse2({
  w,
  h,
  strokeWidth: sw,
  dash,
  color,
  fill
}) {
  const theme = useDefaultColorTheme();
  const cx = w / 2;
  const cy = h / 2;
  const rx = Math.max(0, cx);
  const ry = Math.max(0, cy);
  const perimeter = perimeterOfEllipse(rx, ry);
  const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
    perimeter < 64 ? perimeter * 2 : perimeter,
    sw,
    {
      style: dash,
      snap: 4,
      closed: true
    }
  );
  const d = `M${cx - rx},${cy}a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`;
  return (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
    (0, import_jsx_runtime59.jsx)(ShapeFill, { theme, d, color, fill }),
    (0, import_jsx_runtime59.jsx)(
      "path",
      {
        d,
        strokeWidth: sw,
        width: toDomPrecision(w),
        height: toDomPrecision(h),
        fill: "none",
        stroke: theme[color].solid,
        strokeDasharray,
        strokeDashoffset,
        pointerEvents: "all"
      }
    )
  ] });
});
function DashStyleEllipseSvg({
  w,
  h,
  strokeWidth: sw,
  dash,
  color,
  theme,
  fill
}) {
  const cx = w / 2;
  const cy = h / 2;
  const rx = Math.max(0, cx - sw / 2);
  const ry = Math.max(0, cy - sw / 2);
  const perimeter = perimeterOfEllipse(rx, ry);
  const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
    perimeter < 64 ? perimeter * 2 : perimeter,
    sw,
    {
      style: dash,
      snap: 4,
      closed: true
    }
  );
  const d = `M${cx - rx},${cy}a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`;
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", d);
  strokeElement.setAttribute("stroke-width", sw.toString());
  strokeElement.setAttribute("width", w.toString());
  strokeElement.setAttribute("height", h.toString());
  strokeElement.setAttribute("fill", "none");
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("stroke-dasharray", strokeDasharray);
  strokeElement.setAttribute("stroke-dashoffset", strokeDashoffset);
  const fillElement = getShapeFillSvg({
    d,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DashStyleOval.mjs
var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
var React26 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/helpers.mjs
function getOvalSolidPath(w, h) {
  if (h > w) {
    const offset22 = w / 2;
    return `
    M0,${offset22}
    a${offset22},${offset22},0,1,1,${offset22 * 2},0
    L${w},${h - offset22}
    a${offset22},${offset22},0,1,1,-${offset22 * 2},0
    Z`;
  }
  const offset2 = h / 2;
  return `
    M${offset2},0
    L${w - offset2},0
    a${offset2},${offset2},0,1,1,0,${offset2 * 2}
    L${offset2},${h}
    a${offset2},${offset2},0,1,1,0,${-offset2 * 2}
    Z`;
}
function getOvalPerimeter(h, w) {
  if (h > w) {
    const offset22 = w / 2;
    return perimeterOfEllipse(offset22, offset22) + (h - offset22 * 2) * 2;
  }
  const offset2 = h / 2;
  return perimeterOfEllipse(offset2, offset2) + (w - offset2 * 2) * 2;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DashStyleOval.mjs
var DashStyleOval = React26.memo(function DashStyleOval2({
  w,
  h,
  strokeWidth: sw,
  dash,
  color,
  fill
}) {
  const theme = useDefaultColorTheme();
  const d = getOvalSolidPath(w, h);
  const perimeter = getOvalPerimeter(w, h);
  const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
    perimeter < 64 ? perimeter * 2 : perimeter,
    sw,
    {
      style: dash,
      snap: 4,
      start: "outset",
      end: "outset",
      closed: true
    }
  );
  return (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
    (0, import_jsx_runtime60.jsx)(ShapeFill, { theme, d, color, fill }),
    (0, import_jsx_runtime60.jsx)(
      "path",
      {
        d,
        strokeWidth: sw,
        width: toDomPrecision(w),
        height: toDomPrecision(h),
        fill: "none",
        stroke: theme[color].solid,
        strokeDasharray,
        strokeDashoffset,
        pointerEvents: "all"
      }
    )
  ] });
});
function DashStyleOvalSvg({
  w,
  h,
  strokeWidth: sw,
  dash,
  color,
  theme,
  fill
}) {
  const d = getOvalSolidPath(w, h);
  const perimeter = getOvalPerimeter(w, h);
  const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
    perimeter < 64 ? perimeter * 2 : perimeter,
    sw,
    {
      style: dash,
      snap: 4,
      closed: true
    }
  );
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", d);
  strokeElement.setAttribute("stroke-width", sw.toString());
  strokeElement.setAttribute("width", w.toString());
  strokeElement.setAttribute("height", h.toString());
  strokeElement.setAttribute("fill", "none");
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("stroke-dasharray", strokeDasharray);
  strokeElement.setAttribute("stroke-dashoffset", strokeDashoffset);
  const fillElement = getShapeFillSvg({
    d,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DashStylePolygon.mjs
var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
var React27 = __toESM(require_react(), 1);
var DashStylePolygon2 = React27.memo(function DashStylePolygon22({
  dash,
  fill,
  color,
  strokeWidth,
  outline,
  lines
}) {
  const theme = useDefaultColorTheme();
  const innerPath = "M" + outline[0] + "L" + outline.slice(1) + "Z";
  return (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
    (0, import_jsx_runtime61.jsx)(ShapeFill, { theme, d: innerPath, fill, color }),
    (0, import_jsx_runtime61.jsxs)("g", { strokeWidth, stroke: theme[color].solid, fill: "none", pointerEvents: "all", children: [
      Array.from(Array(outline.length)).map((_, i) => {
        const A = outline[i];
        const B = outline[(i + 1) % outline.length];
        const dist = Vec2d.Dist(A, B);
        const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(dist, strokeWidth, {
          style: dash,
          start: "outset",
          end: "outset"
        });
        return (0, import_jsx_runtime61.jsx)(
          "line",
          {
            x1: A.x,
            y1: A.y,
            x2: B.x,
            y2: B.y,
            strokeDasharray,
            strokeDashoffset
          },
          i
        );
      }),
      lines && lines.map(([A, B], i) => {
        const dist = Vec2d.Dist(A, B);
        const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(dist, strokeWidth, {
          style: dash,
          start: "skip",
          end: "outset",
          snap: dash === "dotted" ? 4 : void 0
        });
        return (0, import_jsx_runtime61.jsx)(
          "path",
          {
            d: `M${A.x},${A.y}L${B.x},${B.y}`,
            stroke: theme[color].solid,
            strokeWidth,
            fill: "none",
            strokeDasharray,
            strokeDashoffset
          },
          `line_fg_${i}`
        );
      })
    ] })
  ] });
});
function DashStylePolygonSvg({
  dash,
  fill,
  color,
  theme,
  strokeWidth,
  outline,
  lines
}) {
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "g");
  strokeElement.setAttribute("stroke-width", strokeWidth.toString());
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("fill", "none");
  Array.from(Array(outline.length)).forEach((_, i) => {
    const A = outline[i];
    const B = outline[(i + 1) % outline.length];
    const dist = Vec2d.Dist(A, B);
    const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(dist, strokeWidth, {
      style: dash
    });
    const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
    line.setAttribute("x1", A.x.toString());
    line.setAttribute("y1", A.y.toString());
    line.setAttribute("x2", B.x.toString());
    line.setAttribute("y2", B.y.toString());
    line.setAttribute("stroke-dasharray", strokeDasharray.toString());
    line.setAttribute("stroke-dashoffset", strokeDashoffset.toString());
    strokeElement.appendChild(line);
  });
  if (lines) {
    for (const [A, B] of lines) {
      const dist = Vec2d.Dist(A, B);
      const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(dist, strokeWidth, {
        style: dash,
        start: "skip",
        end: "skip",
        snap: dash === "dotted" ? 4 : 2
      });
      const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
      line.setAttribute("x1", A.x.toString());
      line.setAttribute("y1", A.y.toString());
      line.setAttribute("x2", B.x.toString());
      line.setAttribute("y2", B.y.toString());
      line.setAttribute("stroke-dasharray", strokeDasharray.toString());
      line.setAttribute("stroke-dashoffset", strokeDashoffset.toString());
      strokeElement.appendChild(line);
    }
  }
  const fillElement = getShapeFillSvg({
    d: "M" + outline[0] + "L" + outline.slice(1) + "Z",
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DrawStyleCloud.mjs
var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
var React28 = __toESM(require_react(), 1);
var DrawStyleCloud = React28.memo(function StyleCloud({
  fill,
  color,
  strokeWidth,
  w,
  h,
  id,
  size: size2
}) {
  const theme = useDefaultColorTheme();
  const path = inkyCloudSvgPath(w, h, id, size2);
  return (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
    (0, import_jsx_runtime62.jsx)(ShapeFill, { theme, d: path, fill, color }),
    (0, import_jsx_runtime62.jsx)("path", { d: path, stroke: theme[color].solid, strokeWidth, fill: "none" })
  ] });
});
function DrawStyleCloudSvg({
  fill,
  color,
  strokeWidth,
  theme,
  w,
  h,
  id,
  size: size2
}) {
  const pathData = inkyCloudSvgPath(w, h, id, size2);
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", pathData);
  strokeElement.setAttribute("stroke-width", strokeWidth.toString());
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("fill", "none");
  const fillElement = getShapeFillSvg({
    d: pathData,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DrawStyleEllipse.mjs
var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
var React29 = __toESM(require_react(), 1);
var DrawStyleEllipse = React29.memo(function DrawStyleEllipse2({
  id,
  w,
  h,
  strokeWidth: sw,
  fill,
  color
}) {
  const theme = useDefaultColorTheme();
  const innerPath = getEllipseIndicatorPath(id, w, h, sw);
  const outerPath = getEllipsePath(id, w, h, sw);
  return (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
    (0, import_jsx_runtime63.jsx)(ShapeFill, { theme, d: innerPath, color, fill }),
    (0, import_jsx_runtime63.jsx)("path", { d: outerPath, fill: theme[color].solid, strokeWidth: 0, pointerEvents: "all" })
  ] });
});
function DrawStyleEllipseSvg({
  id,
  w,
  h,
  strokeWidth: sw,
  fill,
  color,
  theme
}) {
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", getEllipsePath(id, w, h, sw));
  strokeElement.setAttribute("fill", theme[color].solid);
  const fillElement = getShapeFillSvg({
    d: getEllipseIndicatorPath(id, w, h, sw),
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}
function getEllipseStrokeOptions(strokeWidth) {
  return {
    size: 1 + strokeWidth,
    thinning: 0.25,
    end: { taper: strokeWidth },
    start: { taper: strokeWidth },
    streamline: 0,
    smoothing: 1,
    simulatePressure: false
  };
}
function getEllipseStrokePoints(id, width, height, strokeWidth) {
  const getRandom = rng(id);
  const rx = width / 2;
  const ry = height / 2;
  const perimeter = perimeterOfEllipse(rx, ry);
  const points = [];
  const start = PI2 * getRandom();
  const length = PI2 + TAU / 2 + Math.abs(getRandom()) * TAU;
  const count = Math.max(16, perimeter / 10);
  for (let i = 0; i < count; i++) {
    const t2 = i / (count - 1);
    const r = start + t2 * length;
    const c = Math.cos(r);
    const s = Math.sin(r);
    points.push(
      new Vec2d(
        rx * c + width * 0.5 + 0.05 * getRandom(),
        ry * s + height / 2 + 0.05 * getRandom(),
        Math.min(
          1,
          0.5 + Math.abs(0.5 - (getRandom() > 0 ? EASINGS.easeInOutSine(t2) : EASINGS.easeInExpo(t2))) / 2
        )
      )
    );
  }
  return getStrokePoints(points, getEllipseStrokeOptions(strokeWidth));
}
function getEllipsePath(id, width, height, strokeWidth) {
  const options = getEllipseStrokeOptions(strokeWidth);
  return getSvgPathFromPoints(
    getStrokeOutlinePoints(
      setStrokePointRadii(getEllipseStrokePoints(id, width, height, strokeWidth), options),
      options
    )
  );
}
function getEllipseIndicatorPath(id, width, height, strokeWidth) {
  return getSvgPathFromStrokePoints(getEllipseStrokePoints(id, width, height, strokeWidth));
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/DrawStylePolygon.mjs
var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
var React30 = __toESM(require_react(), 1);
var DrawStylePolygon = React30.memo(function DrawStylePolygon2({
  id,
  outline,
  lines,
  fill,
  color,
  strokeWidth
}) {
  const theme = useDefaultColorTheme();
  const polygonPoints = getRoundedPolygonPoints(id, outline, strokeWidth / 3, strokeWidth * 2, 2);
  let strokePathData = getRoundedInkyPolygonPath(polygonPoints);
  if (lines) {
    for (const [A, B] of lines) {
      strokePathData += `M${A.x},${A.y}L${B.x},${B.y}`;
    }
  }
  const innerPolygonPoints = getRoundedPolygonPoints(id, outline, 0, strokeWidth * 2, 1);
  const innerPathData = getRoundedInkyPolygonPath(innerPolygonPoints);
  return (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
    (0, import_jsx_runtime64.jsx)(ShapeFill, { d: innerPathData, fill, color, theme }),
    (0, import_jsx_runtime64.jsx)("path", { d: strokePathData, stroke: theme[color].solid, strokeWidth, fill: "none" })
  ] });
});
function DrawStylePolygonSvg({
  id,
  outline,
  lines,
  fill,
  color,
  theme,
  strokeWidth
}) {
  const polygonPoints = getRoundedPolygonPoints(id, outline, strokeWidth / 3, strokeWidth * 2, 2);
  let strokePathData = getRoundedInkyPolygonPath(polygonPoints);
  if (lines) {
    for (const [A, B] of lines) {
      strokePathData += `M${A.x},${A.y}L${B.x},${B.y}`;
    }
  }
  const innerPolygonPoints = getRoundedPolygonPoints(id, outline, 0, strokeWidth * 2, 1);
  const innerPathData = getRoundedInkyPolygonPath(innerPolygonPoints);
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", strokePathData);
  strokeElement.setAttribute("fill", "none");
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("stroke-width", strokeWidth.toString());
  const fillElement = getShapeFillSvg({
    d: innerPathData,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/SolidStyleCloud.mjs
var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
var React31 = __toESM(require_react(), 1);
var SolidStyleCloud = React31.memo(function SolidStyleCloud2({
  fill,
  color,
  strokeWidth,
  w,
  h,
  id,
  size: size2
}) {
  const theme = useDefaultColorTheme();
  const path = cloudSvgPath(w, h, id, size2);
  return (0, import_jsx_runtime65.jsxs)(import_jsx_runtime65.Fragment, { children: [
    (0, import_jsx_runtime65.jsx)(ShapeFill, { theme, d: path, fill, color }),
    (0, import_jsx_runtime65.jsx)("path", { d: path, stroke: theme[color].solid, strokeWidth, fill: "none" })
  ] });
});
function SolidStyleCloudSvg({
  fill,
  color,
  strokeWidth,
  theme,
  w,
  h,
  id,
  size: size2
}) {
  const pathData = cloudSvgPath(w, h, id, size2);
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", pathData);
  strokeElement.setAttribute("stroke-width", strokeWidth.toString());
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("fill", "none");
  const fillElement = getShapeFillSvg({
    d: pathData,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/SolidStyleEllipse.mjs
var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
var React32 = __toESM(require_react(), 1);
var SolidStyleEllipse = React32.memo(function SolidStyleEllipse2({
  w,
  h,
  strokeWidth: sw,
  fill,
  color
}) {
  const theme = useDefaultColorTheme();
  const cx = w / 2;
  const cy = h / 2;
  const rx = Math.max(0, cx);
  const ry = Math.max(0, cy);
  const d = `M${cx - rx},${cy}a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`;
  return (0, import_jsx_runtime66.jsxs)(import_jsx_runtime66.Fragment, { children: [
    (0, import_jsx_runtime66.jsx)(ShapeFill, { d, color, fill, theme }),
    (0, import_jsx_runtime66.jsx)("path", { d, stroke: theme[color].solid, strokeWidth: sw, fill: "none" })
  ] });
});
function SolidStyleEllipseSvg({
  w,
  h,
  strokeWidth: sw,
  fill,
  color,
  theme
}) {
  const cx = w / 2;
  const cy = h / 2;
  const rx = Math.max(0, cx);
  const ry = Math.max(0, cy);
  const d = `M${cx - rx},${cy}a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`;
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", d);
  strokeElement.setAttribute("stroke-width", sw.toString());
  strokeElement.setAttribute("width", w.toString());
  strokeElement.setAttribute("height", h.toString());
  strokeElement.setAttribute("fill", "none");
  strokeElement.setAttribute("stroke", theme[color].solid);
  const fillElement = getShapeFillSvg({
    d,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/SolidStyleOval.mjs
var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
var React33 = __toESM(require_react(), 1);
var SolidStyleOval = React33.memo(function SolidStyleOval2({
  w,
  h,
  strokeWidth: sw,
  fill,
  color
}) {
  const theme = useDefaultColorTheme();
  const d = getOvalIndicatorPath(w, h);
  return (0, import_jsx_runtime67.jsxs)(import_jsx_runtime67.Fragment, { children: [
    (0, import_jsx_runtime67.jsx)(ShapeFill, { d, color, fill, theme }),
    (0, import_jsx_runtime67.jsx)("path", { d, stroke: theme[color].solid, strokeWidth: sw, fill: "none" })
  ] });
});
function SolidStyleOvalSvg({
  w,
  h,
  strokeWidth: sw,
  fill,
  color,
  theme
}) {
  const d = getOvalIndicatorPath(w, h);
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", d);
  strokeElement.setAttribute("stroke-width", sw.toString());
  strokeElement.setAttribute("width", w.toString());
  strokeElement.setAttribute("height", h.toString());
  strokeElement.setAttribute("fill", "none");
  strokeElement.setAttribute("stroke", theme[color].solid);
  const fillElement = getShapeFillSvg({
    d,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}
function getOvalIndicatorPath(w, h) {
  let d;
  if (h > w) {
    const offset2 = w / 2;
    d = `
    M0,${offset2}
    a${offset2},${offset2},0,1,1,${offset2 * 2},0
    L${w},${h - offset2}
    a${offset2},${offset2},0,1,1,-${offset2 * 2},0
    Z`;
  } else {
    const offset2 = h / 2;
    d = `
    M${offset2},0
    L${w - offset2},0
    a${offset2},${offset2},0,1,1,0,${offset2 * 2}
    L${offset2},${h}
    a${offset2},${offset2},0,1,1,0,${-offset2 * 2}
    Z`;
  }
  return d;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/components/SolidStylePolygon.mjs
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
var React34 = __toESM(require_react(), 1);
var SolidStylePolygon = React34.memo(function SolidStylePolygon2({
  outline,
  lines,
  fill,
  color,
  strokeWidth
}) {
  const theme = useDefaultColorTheme();
  let path = "M" + outline[0] + "L" + outline.slice(1) + "Z";
  if (lines) {
    for (const [A, B] of lines) {
      path += `M${A.x},${A.y}L${B.x},${B.y}`;
    }
  }
  return (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
    (0, import_jsx_runtime68.jsx)(ShapeFill, { d: path, fill, color, theme }),
    (0, import_jsx_runtime68.jsx)("path", { d: path, stroke: theme[color].solid, strokeWidth, fill: "none" })
  ] });
});
function SolidStylePolygonSvg({
  outline,
  lines,
  fill,
  color,
  strokeWidth,
  theme
}) {
  const pathData = "M" + outline[0] + "L" + outline.slice(1) + "Z";
  const fillPathData = pathData;
  let strokePathData = pathData;
  if (lines) {
    for (const [A, B] of lines) {
      strokePathData += `M${A.x},${A.y}L${B.x},${B.y}`;
    }
  }
  const strokeElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  strokeElement.setAttribute("d", strokePathData);
  strokeElement.setAttribute("stroke-width", strokeWidth.toString());
  strokeElement.setAttribute("stroke", theme[color].solid);
  strokeElement.setAttribute("fill", "none");
  const fillElement = getShapeFillSvg({
    d: fillPathData,
    fill,
    color,
    theme
  });
  return getSvgWithShapeFill(strokeElement, fillElement);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs
var LABEL_PADDING = 16;
var MIN_SIZE_WITH_LABEL = 17 * 3;
var GeoShapeUtil = class extends BaseBoxShapeUtil {
  static type = "geo";
  static props = geoShapeProps;
  static migrations = geoShapeMigrations;
  canEdit = () => true;
  getDefaultProps() {
    return {
      w: 100,
      h: 100,
      geo: "rectangle",
      color: "black",
      labelColor: "black",
      fill: "none",
      dash: "draw",
      size: "m",
      font: "draw",
      text: "",
      align: "middle",
      verticalAlign: "middle",
      growY: 0,
      url: ""
    };
  }
  getGeometry(shape) {
    const w = Math.max(1, shape.props.w);
    const h = Math.max(1, shape.props.h + shape.props.growY);
    const cx = w / 2;
    const cy = h / 2;
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const isFilled = shape.props.fill !== "none";
    let body;
    switch (shape.props.geo) {
      case "cloud": {
        body = new Polygon2d({
          points: cloudOutline(w, h, shape.id, shape.props.size),
          isFilled
        });
        break;
      }
      case "triangle": {
        body = new Polygon2d({
          points: [new Vec2d(cx, 0), new Vec2d(w, h), new Vec2d(0, h)],
          isFilled
        });
        break;
      }
      case "diamond": {
        body = new Polygon2d({
          points: [new Vec2d(cx, 0), new Vec2d(w, cy), new Vec2d(cx, h), new Vec2d(0, cy)],
          isFilled
        });
        break;
      }
      case "pentagon": {
        body = new Polygon2d({
          points: getPolygonVertices(w, h, 5),
          isFilled
        });
        break;
      }
      case "hexagon": {
        body = new Polygon2d({
          points: getPolygonVertices(w, h, 6),
          isFilled
        });
        break;
      }
      case "octagon": {
        body = new Polygon2d({
          points: getPolygonVertices(w, h, 8),
          isFilled
        });
        break;
      }
      case "ellipse": {
        body = new Ellipse2d({
          width: w,
          height: h,
          isFilled
        });
        break;
      }
      case "oval": {
        body = new Stadium2d({
          width: w,
          height: h,
          isFilled
        });
        break;
      }
      case "star": {
        const sides2 = 5;
        const step = PI2 / sides2 / 2;
        const rightMostIndex = Math.floor(sides2 / 4) * 2;
        const leftMostIndex = sides2 * 2 - rightMostIndex;
        const topMostIndex = 0;
        const bottomMostIndex = Math.floor(sides2 / 2) * 2;
        const maxX = Math.cos(-TAU + rightMostIndex * step) * w / 2;
        const minX = Math.cos(-TAU + leftMostIndex * step) * w / 2;
        const minY = Math.sin(-TAU + topMostIndex * step) * h / 2;
        const maxY = Math.sin(-TAU + bottomMostIndex * step) * h / 2;
        const diffX = w - Math.abs(maxX - minX);
        const diffY = h - Math.abs(maxY - minY);
        const offsetX = w / 2 + minX - (w / 2 - maxX);
        const offsetY = h / 2 + minY - (h / 2 - maxY);
        const ratio = 1;
        const cx2 = (w - offsetX) / 2;
        const cy2 = (h - offsetY) / 2;
        const ox = (w + diffX) / 2;
        const oy = (h + diffY) / 2;
        const ix = ox * ratio / 2;
        const iy = oy * ratio / 2;
        body = new Polygon2d({
          points: Array.from(Array(sides2 * 2)).map((_, i) => {
            const theta = -TAU + i * step;
            return new Vec2d(
              cx2 + (i % 2 ? ix : ox) * Math.cos(theta),
              cy2 + (i % 2 ? iy : oy) * Math.sin(theta)
            );
          }),
          isFilled
        });
        break;
      }
      case "rhombus": {
        const offset2 = Math.min(w * 0.38, h * 0.38);
        body = new Polygon2d({
          points: [
            new Vec2d(offset2, 0),
            new Vec2d(w, 0),
            new Vec2d(w - offset2, h),
            new Vec2d(0, h)
          ],
          isFilled
        });
        break;
      }
      case "rhombus-2": {
        const offset2 = Math.min(w * 0.38, h * 0.38);
        body = new Polygon2d({
          points: [
            new Vec2d(0, 0),
            new Vec2d(w - offset2, 0),
            new Vec2d(w, h),
            new Vec2d(offset2, h)
          ],
          isFilled
        });
        break;
      }
      case "trapezoid": {
        const offset2 = Math.min(w * 0.38, h * 0.38);
        body = new Polygon2d({
          points: [
            new Vec2d(offset2, 0),
            new Vec2d(w - offset2, 0),
            new Vec2d(w, h),
            new Vec2d(0, h)
          ],
          isFilled
        });
        break;
      }
      case "arrow-right": {
        const ox = Math.min(w, h) * 0.38;
        const oy = h * 0.16;
        body = new Polygon2d({
          points: [
            new Vec2d(0, oy),
            new Vec2d(w - ox, oy),
            new Vec2d(w - ox, 0),
            new Vec2d(w, h / 2),
            new Vec2d(w - ox, h),
            new Vec2d(w - ox, h - oy),
            new Vec2d(0, h - oy)
          ],
          isFilled
        });
        break;
      }
      case "arrow-left": {
        const ox = Math.min(w, h) * 0.38;
        const oy = h * 0.16;
        body = new Polygon2d({
          points: [
            new Vec2d(ox, 0),
            new Vec2d(ox, oy),
            new Vec2d(w, oy),
            new Vec2d(w, h - oy),
            new Vec2d(ox, h - oy),
            new Vec2d(ox, h),
            new Vec2d(0, h / 2)
          ],
          isFilled
        });
        break;
      }
      case "arrow-up": {
        const ox = w * 0.16;
        const oy = Math.min(w, h) * 0.38;
        body = new Polygon2d({
          points: [
            new Vec2d(w / 2, 0),
            new Vec2d(w, oy),
            new Vec2d(w - ox, oy),
            new Vec2d(w - ox, h),
            new Vec2d(ox, h),
            new Vec2d(ox, oy),
            new Vec2d(0, oy)
          ],
          isFilled
        });
        break;
      }
      case "arrow-down": {
        const ox = w * 0.16;
        const oy = Math.min(w, h) * 0.38;
        body = new Polygon2d({
          points: [
            new Vec2d(ox, 0),
            new Vec2d(w - ox, 0),
            new Vec2d(w - ox, h - oy),
            new Vec2d(w, h - oy),
            new Vec2d(w / 2, h),
            new Vec2d(0, h - oy),
            new Vec2d(ox, h - oy)
          ],
          isFilled
        });
        break;
      }
      case "check-box":
      case "x-box":
      case "rectangle": {
        body = new Rectangle2d({
          width: w,
          height: h,
          isFilled,
          isSnappable: true
        });
        break;
      }
    }
    const labelSize = getLabelSize(this.editor, shape);
    const labelWidth = Math.min(w, Math.max(labelSize.w, Math.min(32, Math.max(1, w - 8))));
    const labelHeight = Math.min(h, Math.max(labelSize.h, Math.min(32, Math.max(1, w - 8))));
    const lines = getLines(shape.props, strokeWidth);
    const edges = lines ? lines.map((line) => new Polyline2d({ points: line })) : [];
    return new Group2d({
      children: [
        body,
        new Rectangle2d({
          x: shape.props.align === "start" ? 0 : shape.props.align === "end" ? w - labelWidth : (w - labelWidth) / 2,
          y: shape.props.verticalAlign === "start" ? 0 : shape.props.verticalAlign === "end" ? h - labelHeight : (h - labelHeight) / 2,
          width: labelWidth,
          height: labelHeight,
          isFilled: true,
          isSnappable: false,
          isLabel: true
        }),
        ...edges
      ],
      isSnappable: false
    });
  }
  onEditEnd = (shape) => {
    const {
      id,
      type,
      props: { text }
    } = shape;
    if (text.trimEnd() !== shape.props.text) {
      this.editor.updateShapes([
        {
          id,
          type,
          props: {
            text: text.trimEnd()
          }
        }
      ]);
    }
  };
  component(shape) {
    const { id, type, props } = shape;
    const strokeWidth = STROKE_SIZES2[props.size];
    const { w, color, labelColor, fill, dash, growY, font, align, verticalAlign, size: size2, text } = props;
    const getShape = () => {
      const h = props.h + growY;
      switch (props.geo) {
        case "cloud": {
          if (dash === "solid") {
            return (0, import_jsx_runtime69.jsx)(
              SolidStyleCloud,
              {
                color,
                fill,
                strokeWidth,
                w,
                h,
                id,
                size: size2
              }
            );
          } else if (dash === "dashed" || dash === "dotted") {
            return (0, import_jsx_runtime69.jsx)(
              DashStyleCloud,
              {
                color,
                fill,
                strokeWidth,
                w,
                h,
                id,
                size: size2,
                dash
              }
            );
          } else if (dash === "draw") {
            return (0, import_jsx_runtime69.jsx)(
              DrawStyleCloud,
              {
                color,
                fill,
                strokeWidth,
                w,
                h,
                id,
                size: size2
              }
            );
          }
          break;
        }
        case "ellipse": {
          if (dash === "solid") {
            return (0, import_jsx_runtime69.jsx)(SolidStyleEllipse, { strokeWidth, w, h, color, fill });
          } else if (dash === "dashed" || dash === "dotted") {
            return (0, import_jsx_runtime69.jsx)(
              DashStyleEllipse,
              {
                id,
                strokeWidth,
                w,
                h,
                dash,
                color,
                fill
              }
            );
          } else if (dash === "draw") {
            return (0, import_jsx_runtime69.jsx)(SolidStyleEllipse, { strokeWidth, w, h, color, fill });
          }
          break;
        }
        case "oval": {
          if (dash === "solid") {
            return (0, import_jsx_runtime69.jsx)(SolidStyleOval, { strokeWidth, w, h, color, fill });
          } else if (dash === "dashed" || dash === "dotted") {
            return (0, import_jsx_runtime69.jsx)(
              DashStyleOval,
              {
                id,
                strokeWidth,
                w,
                h,
                dash,
                color,
                fill
              }
            );
          } else if (dash === "draw") {
            return (0, import_jsx_runtime69.jsx)(SolidStyleOval, { strokeWidth, w, h, color, fill });
          }
          break;
        }
        default: {
          const geometry = this.editor.getShapeGeometry(shape);
          const outline = geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices;
          const lines = getLines(shape.props, strokeWidth);
          if (dash === "solid") {
            return (0, import_jsx_runtime69.jsx)(
              SolidStylePolygon,
              {
                fill,
                color,
                strokeWidth,
                outline,
                lines
              }
            );
          } else if (dash === "dashed" || dash === "dotted") {
            return (0, import_jsx_runtime69.jsx)(
              DashStylePolygon2,
              {
                dash,
                fill,
                color,
                strokeWidth,
                outline,
                lines
              }
            );
          } else if (dash === "draw") {
            return (0, import_jsx_runtime69.jsx)(
              DrawStylePolygon,
              {
                id,
                fill,
                color,
                strokeWidth,
                outline,
                lines
              }
            );
          }
        }
      }
    };
    return (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
      (0, import_jsx_runtime69.jsx)(SVGContainer, { id, children: getShape() }),
      (0, import_jsx_runtime69.jsx)(
        TextLabel,
        {
          id,
          type,
          font,
          fill,
          size: size2,
          align,
          verticalAlign,
          text,
          labelColor,
          wrap: true,
          bounds: props.geo === "cloud" ? this.getGeometry(shape).bounds : void 0
        }
      ),
      shape.props.url && (0, import_jsx_runtime69.jsx)(HyperlinkButton, { url: shape.props.url, zoomLevel: this.editor.zoomLevel })
    ] });
  }
  indicator(shape) {
    const { id, props } = shape;
    const { w, size: size2 } = props;
    const h = props.h + props.growY;
    const strokeWidth = STROKE_SIZES2[size2];
    switch (props.geo) {
      case "ellipse": {
        if (props.dash === "draw") {
          return (0, import_jsx_runtime69.jsx)("path", { d: getEllipseIndicatorPath(id, w, h, strokeWidth) });
        }
        return (0, import_jsx_runtime69.jsx)("ellipse", { cx: w / 2, cy: h / 2, rx: w / 2, ry: h / 2 });
      }
      case "oval": {
        return (0, import_jsx_runtime69.jsx)("path", { d: getOvalIndicatorPath(w, h) });
      }
      case "cloud": {
        return (0, import_jsx_runtime69.jsx)("path", { d: cloudSvgPath(w, h, id, size2) });
      }
      default: {
        const geometry = this.editor.getShapeGeometry(shape);
        const outline = geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices;
        let path;
        if (props.dash === "draw") {
          const polygonPoints = getRoundedPolygonPoints(id, outline, 0, strokeWidth * 2, 1);
          path = getRoundedInkyPolygonPath(polygonPoints);
        } else {
          path = "M" + outline[0] + "L" + outline.slice(1) + "Z";
        }
        const lines = getLines(shape.props, strokeWidth);
        if (lines) {
          for (const [A, B] of lines) {
            path += `M${A.x},${A.y}L${B.x},${B.y}`;
          }
        }
        return (0, import_jsx_runtime69.jsx)("path", { d: path });
      }
    }
  }
  toSvg(shape, ctx) {
    const { id, props } = shape;
    const strokeWidth = STROKE_SIZES2[props.size];
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    ctx.addExportDef(getFillDefForExport(shape.props.fill, theme));
    let svgElm;
    switch (props.geo) {
      case "ellipse": {
        switch (props.dash) {
          case "draw":
            svgElm = DrawStyleEllipseSvg({
              id,
              w: props.w,
              h: props.h,
              color: props.color,
              fill: props.fill,
              strokeWidth,
              theme
            });
            break;
          case "solid":
            svgElm = SolidStyleEllipseSvg({
              strokeWidth,
              w: props.w,
              h: props.h,
              color: props.color,
              fill: props.fill,
              theme
            });
            break;
          default:
            svgElm = DashStyleEllipseSvg({
              id,
              strokeWidth,
              w: props.w,
              h: props.h,
              dash: props.dash,
              color: props.color,
              fill: props.fill,
              theme
            });
            break;
        }
        break;
      }
      case "oval": {
        switch (props.dash) {
          case "draw":
            svgElm = DashStyleOvalSvg({
              id,
              strokeWidth,
              w: props.w,
              h: props.h,
              dash: props.dash,
              color: props.color,
              fill: props.fill,
              theme
            });
            break;
          case "solid":
            svgElm = SolidStyleOvalSvg({
              strokeWidth,
              w: props.w,
              h: props.h,
              color: props.color,
              fill: props.fill,
              theme
            });
            break;
          default:
            svgElm = DashStyleOvalSvg({
              id,
              strokeWidth,
              w: props.w,
              h: props.h,
              dash: props.dash,
              color: props.color,
              fill: props.fill,
              theme
            });
        }
        break;
      }
      case "cloud": {
        switch (props.dash) {
          case "draw":
            svgElm = DrawStyleCloudSvg({
              id,
              strokeWidth,
              w: props.w,
              h: props.h,
              color: props.color,
              fill: props.fill,
              size: props.size,
              theme
            });
            break;
          case "solid":
            svgElm = SolidStyleCloudSvg({
              strokeWidth,
              w: props.w,
              h: props.h,
              color: props.color,
              fill: props.fill,
              size: props.size,
              id,
              theme
            });
            break;
          default:
            svgElm = DashStyleCloudSvg({
              id,
              strokeWidth,
              w: props.w,
              h: props.h,
              dash: props.dash,
              color: props.color,
              fill: props.fill,
              theme,
              size: props.size
            });
        }
        break;
      }
      default: {
        const geometry = this.editor.getShapeGeometry(shape);
        const outline = geometry instanceof Group2d ? geometry.children[0].vertices : geometry.vertices;
        const lines = getLines(shape.props, strokeWidth);
        switch (props.dash) {
          case "draw":
            svgElm = DrawStylePolygonSvg({
              id,
              fill: props.fill,
              color: props.color,
              strokeWidth,
              outline,
              lines,
              theme
            });
            break;
          case "solid":
            svgElm = SolidStylePolygonSvg({
              fill: props.fill,
              color: props.color,
              strokeWidth,
              outline,
              lines,
              theme
            });
            break;
          default:
            svgElm = DashStylePolygonSvg({
              dash: props.dash,
              fill: props.fill,
              color: props.color,
              strokeWidth,
              outline,
              lines,
              theme
            });
            break;
        }
        break;
      }
    }
    if (props.text) {
      const bounds = this.editor.getShapeGeometry(shape).bounds;
      ctx.addExportDef(getFontDefForExport(shape.props.font));
      const rootTextElm = getTextLabelSvgElement({
        editor: this.editor,
        shape,
        font: DefaultFontFamilies[shape.props.font],
        bounds
      });
      const textElm = rootTextElm.cloneNode(true);
      textElm.setAttribute("fill", theme[shape.props.labelColor].solid);
      textElm.setAttribute("stroke", "none");
      const textBgEl = rootTextElm.cloneNode(true);
      textBgEl.setAttribute("stroke-width", "2");
      textBgEl.setAttribute("fill", theme.background);
      textBgEl.setAttribute("stroke", theme.background);
      const groupEl = document.createElementNS("http://www.w3.org/2000/svg", "g");
      groupEl.append(textBgEl);
      groupEl.append(textElm);
      if (svgElm.nodeName === "g") {
        svgElm.appendChild(groupEl);
        return svgElm;
      } else {
        const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
        g.appendChild(svgElm);
        g.appendChild(groupEl);
        return g;
      }
    }
    return svgElm;
  }
  getCanvasSvgDefs() {
    return [getFillDefForCanvas()];
  }
  onResize = (shape, { handle, newPoint, scaleX, scaleY, initialShape }) => {
    let w = initialShape.props.w * scaleX;
    let h = (initialShape.props.h + initialShape.props.growY) * scaleY;
    let overShrinkX = 0;
    let overShrinkY = 0;
    if (shape.props.text.trim()) {
      let newW = Math.max(Math.abs(w), MIN_SIZE_WITH_LABEL);
      let newH = Math.max(Math.abs(h), MIN_SIZE_WITH_LABEL);
      if (newW < MIN_SIZE_WITH_LABEL && newH === MIN_SIZE_WITH_LABEL) {
        newW = MIN_SIZE_WITH_LABEL;
      }
      if (newW === MIN_SIZE_WITH_LABEL && newH < MIN_SIZE_WITH_LABEL) {
        newH = MIN_SIZE_WITH_LABEL;
      }
      const labelSize = getLabelSize(this.editor, {
        ...shape,
        props: {
          ...shape.props,
          w: newW,
          h: newH
        }
      });
      const nextW = Math.max(Math.abs(w), labelSize.w) * Math.sign(w);
      const nextH = Math.max(Math.abs(h), labelSize.h) * Math.sign(h);
      overShrinkX = Math.abs(nextW) - Math.abs(w);
      overShrinkY = Math.abs(nextH) - Math.abs(h);
      w = nextW;
      h = nextH;
    }
    const offset2 = new Vec2d(0, 0);
    if (scaleX < 0) {
      offset2.x += w;
    }
    if (handle === "left" || handle === "top_left" || handle === "bottom_left") {
      offset2.x += scaleX < 0 ? overShrinkX : -overShrinkX;
    }
    if (scaleY < 0) {
      offset2.y += h;
    }
    if (handle === "top" || handle === "top_left" || handle === "top_right") {
      offset2.y += scaleY < 0 ? overShrinkY : -overShrinkY;
    }
    const { x, y } = offset2.rot(shape.rotation).add(newPoint);
    return {
      x,
      y,
      props: {
        w: Math.max(Math.abs(w), 1),
        h: Math.max(Math.abs(h), 1),
        growY: 0
      }
    };
  };
  onBeforeCreate = (shape) => {
    if (!shape.props.text) {
      if (shape.props.growY) {
        return {
          ...shape,
          props: {
            ...shape.props,
            growY: 0
          }
        };
      } else {
        return;
      }
    }
    const prevHeight = shape.props.h;
    const nextHeight = getLabelSize(this.editor, shape).h;
    let growY = null;
    if (nextHeight > prevHeight) {
      growY = nextHeight - prevHeight;
    } else {
      if (shape.props.growY) {
        growY = 0;
      }
    }
    if (growY !== null) {
      return {
        ...shape,
        props: {
          ...shape.props,
          growY
        }
      };
    }
  };
  onBeforeUpdate = (prev, next) => {
    const prevText = prev.props.text;
    const nextText = next.props.text;
    if (prevText === nextText && prev.props.font === next.props.font && prev.props.size === next.props.size) {
      return;
    }
    if (prevText && !nextText) {
      return {
        ...next,
        props: {
          ...next.props,
          growY: 0
        }
      };
    }
    const prevWidth = prev.props.w;
    const prevHeight = prev.props.h;
    const nextSize = getLabelSize(this.editor, next);
    const nextWidth = nextSize.w;
    const nextHeight = nextSize.h;
    if (!prevText && nextText && nextText.length === 1) {
      let w = Math.max(prevWidth, nextWidth);
      let h = Math.max(prevHeight, nextHeight);
      if (prev.props.w < MIN_SIZE_WITH_LABEL && prev.props.h < MIN_SIZE_WITH_LABEL) {
        w = Math.max(w, MIN_SIZE_WITH_LABEL);
        h = Math.max(h, MIN_SIZE_WITH_LABEL);
        w = Math.max(w, h);
        h = Math.max(w, h);
      }
      return {
        ...next,
        props: {
          ...next.props,
          w,
          h,
          growY: 0
        }
      };
    }
    let growY = null;
    if (nextHeight > prevHeight) {
      growY = nextHeight - prevHeight;
    } else {
      if (prev.props.growY) {
        growY = 0;
      }
    }
    if (growY !== null) {
      return {
        ...next,
        props: {
          ...next.props,
          growY,
          w: Math.max(next.props.w, nextWidth)
        }
      };
    }
    if (nextWidth > prev.props.w) {
      return {
        ...next,
        props: {
          ...next.props,
          w: nextWidth
        }
      };
    }
  };
  onDoubleClick = (shape) => {
    if (this.editor.inputs.altKey) {
      switch (shape.props.geo) {
        case "rectangle": {
          return {
            ...shape,
            props: {
              geo: "check-box"
            }
          };
        }
        case "check-box": {
          return {
            ...shape,
            props: {
              geo: "rectangle"
            }
          };
        }
      }
    }
    return;
  };
};
function getLabelSize(editor, shape) {
  const text = shape.props.text;
  if (!text) {
    return { w: 0, h: 0 };
  }
  const minSize = editor.textMeasure.measureText("w", {
    ...TEXT_PROPS,
    fontFamily: FONT_FAMILIES[shape.props.font],
    fontSize: LABEL_FONT_SIZES[shape.props.size],
    maxWidth: 100
  });
  const sizes = {
    s: 2,
    m: 3.5,
    l: 5,
    xl: 10
  };
  const size2 = editor.textMeasure.measureText(text, {
    ...TEXT_PROPS,
    fontFamily: FONT_FAMILIES[shape.props.font],
    fontSize: LABEL_FONT_SIZES[shape.props.size],
    minWidth: minSize.w + "px",
    maxWidth: Math.max(
      // Guard because a DOM nodes can't be less 0
      0,
      // A 'w' width that we're setting as the min-width
      Math.ceil(minSize.w + sizes[shape.props.size]),
      // The actual text size
      Math.ceil(shape.props.w - LABEL_PADDING * 2)
    )
  });
  return {
    w: size2.w + LABEL_PADDING * 2,
    h: size2.h + LABEL_PADDING * 2
  };
}
function getLines(props, sw) {
  switch (props.geo) {
    case "x-box": {
      return getXBoxLines(props.w, props.h, sw, props.dash);
    }
    case "check-box": {
      return getCheckBoxLines(props.w, props.h);
    }
    default: {
      return void 0;
    }
  }
}
function getXBoxLines(w, h, sw, dash) {
  const inset = dash === "draw" ? 0.62 : 0;
  if (dash === "dashed") {
    return [
      [new Vec2d(0, 0), new Vec2d(w / 2, h / 2)],
      [new Vec2d(w, h), new Vec2d(w / 2, h / 2)],
      [new Vec2d(0, h), new Vec2d(w / 2, h / 2)],
      [new Vec2d(w, 0), new Vec2d(w / 2, h / 2)]
    ];
  }
  const clampX = (x) => Math.max(0, Math.min(w, x));
  const clampY = (y) => Math.max(0, Math.min(h, y));
  return [
    [
      new Vec2d(clampX(sw * inset), clampY(sw * inset)),
      new Vec2d(clampX(w - sw * inset), clampY(h - sw * inset))
    ],
    [
      new Vec2d(clampX(sw * inset), clampY(h - sw * inset)),
      new Vec2d(clampX(w - sw * inset), clampY(sw * inset))
    ]
  ];
}
function getCheckBoxLines(w, h) {
  const size2 = Math.min(w, h) * 0.82;
  const ox = (w - size2) / 2;
  const oy = (h - size2) / 2;
  const clampX = (x) => Math.max(0, Math.min(w, x));
  const clampY = (y) => Math.max(0, Math.min(h, y));
  return [
    [
      new Vec2d(clampX(ox + size2 * 0.25), clampY(oy + size2 * 0.52)),
      new Vec2d(clampX(ox + size2 * 0.45), clampY(oy + size2 * 0.82))
    ],
    [
      new Vec2d(clampX(ox + size2 * 0.45), clampY(oy + size2 * 0.82)),
      new Vec2d(clampX(ox + size2 * 0.82), clampY(oy + size2 * 0.22))
    ]
  ];
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs
var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/useColorSpace.mjs
var import_react50 = __toESM(require_react(), 1);
function useColorSpace() {
  const [supportsP3, setSupportsP3] = (0, import_react50.useState)(false);
  (0, import_react50.useEffect)(() => {
    const supportsSyntax = CSS.supports("color", "color(display-p3 1 1 1)");
    const query = matchMedia("(color-gamut: p3)");
    setSupportsP3(supportsSyntax && query.matches);
    const onChange = () => setSupportsP3(supportsSyntax && query.matches);
    query.addEventListener("change", onChange);
    return () => query.removeEventListener("change", onChange);
  }, []);
  const forceSrgb = useValue(debugFlags.forceSrgb);
  return forceSrgb || !supportsP3 ? "srgb" : "p3";
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs
var OVERLAY_OPACITY = 0.35;
var UNDERLAY_OPACITY = 0.82;
var HighlightShapeUtil = class extends ShapeUtil {
  static type = "highlight";
  static props = highlightShapeProps;
  static migrations = highlightShapeMigrations;
  hideResizeHandles = (shape) => getIsDot2(shape);
  hideRotateHandle = (shape) => getIsDot2(shape);
  hideSelectionBoundsFg = (shape) => getIsDot2(shape);
  getDefaultProps() {
    return {
      segments: [],
      color: "black",
      size: "m",
      isComplete: false,
      isPen: false
    };
  }
  getGeometry(shape) {
    const strokeWidth = getStrokeWidth(shape);
    if (getIsDot2(shape)) {
      return new Circle2d({
        x: -strokeWidth / 2,
        y: -strokeWidth / 2,
        radius: strokeWidth / 2,
        isFilled: true
      });
    }
    const { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true);
    const opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true });
    setStrokePointRadii(strokePoints, opts);
    return new Polygon2d({
      points: getStrokeOutlinePoints(strokePoints, opts),
      isFilled: true
    });
  }
  component(shape) {
    return (0, import_jsx_runtime70.jsx)(
      HighlightRenderer,
      {
        strokeWidth: getStrokeWidth(shape),
        shape,
        opacity: OVERLAY_OPACITY
      }
    );
  }
  backgroundComponent(shape) {
    return (0, import_jsx_runtime70.jsx)(
      HighlightRenderer,
      {
        strokeWidth: getStrokeWidth(shape),
        shape,
        opacity: UNDERLAY_OPACITY
      }
    );
  }
  indicator(shape) {
    const forceSolid = useForceSolid();
    const strokeWidth = getStrokeWidth(shape);
    const allPointsFromSegments = getPointsFromSegments(shape.props.segments);
    let sw = strokeWidth;
    if (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {
      sw += rng(shape.id)() * (strokeWidth / 6);
    }
    const showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === "straight";
    const options = getHighlightFreehandSettings({
      strokeWidth,
      showAsComplete
    });
    const strokePoints = getStrokePoints(allPointsFromSegments, options);
    let strokePath;
    if (strokePoints.length < 2) {
      strokePath = getIndicatorDot(allPointsFromSegments[0], sw);
    } else {
      strokePath = getSvgPathFromStrokePoints(strokePoints, false);
    }
    return (0, import_jsx_runtime70.jsx)("path", { d: strokePath });
  }
  toSvg(shape) {
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    return highlighterToSvg(getStrokeWidth(shape), shape, OVERLAY_OPACITY, theme);
  }
  toBackgroundSvg(shape) {
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    return highlighterToSvg(getStrokeWidth(shape), shape, UNDERLAY_OPACITY, theme);
  }
  onResize = (shape, info) => {
    const { scaleX, scaleY } = info;
    const newSegments = [];
    for (const segment of shape.props.segments) {
      newSegments.push({
        ...segment,
        points: segment.points.map(({ x, y, z }) => {
          return {
            x: scaleX * x,
            y: scaleY * y,
            z
          };
        })
      });
    }
    return {
      props: {
        segments: newSegments
      }
    };
  };
};
function getShapeDot(point) {
  const r = 0.1;
  return `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${r * 2},0`;
}
function getIndicatorDot(point, sw) {
  const r = sw / 2;
  return `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${r * 2},0`;
}
function getHighlightStrokePoints(shape, strokeWidth, forceSolid) {
  const allPointsFromSegments = getPointsFromSegments(shape.props.segments);
  const showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === "straight";
  let sw = strokeWidth;
  if (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {
    sw += rng(shape.id)() * (strokeWidth / 6);
  }
  const options = getHighlightFreehandSettings({
    strokeWidth: sw,
    showAsComplete
  });
  const strokePoints = getStrokePoints(allPointsFromSegments, options);
  return { strokePoints, sw };
}
function getHighlightSvgPath(shape, strokeWidth, forceSolid) {
  const { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid);
  const solidStrokePath = strokePoints.length > 1 ? getSvgPathFromStrokePoints(strokePoints, false) : getShapeDot(shape.props.segments[0].points[0]);
  return { solidStrokePath, sw };
}
function HighlightRenderer({
  strokeWidth,
  shape,
  opacity
}) {
  const theme = useDefaultColorTheme();
  const forceSolid = useForceSolid();
  const { solidStrokePath, sw } = getHighlightSvgPath(shape, strokeWidth, forceSolid);
  const colorSpace = useColorSpace();
  const color = theme[shape.props.color].highlight[colorSpace];
  return (0, import_jsx_runtime70.jsx)(SVGContainer, { id: shape.id, style: { opacity }, children: (0, import_jsx_runtime70.jsx)(
    "path",
    {
      d: solidStrokePath,
      strokeLinecap: "round",
      fill: "none",
      pointerEvents: "all",
      stroke: color,
      strokeWidth: sw
    }
  ) });
}
function highlighterToSvg(strokeWidth, shape, opacity, theme) {
  const { solidStrokePath, sw } = getHighlightSvgPath(shape, strokeWidth, false);
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
  path.setAttribute("d", solidStrokePath);
  path.setAttribute("fill", "none");
  path.setAttribute("stroke", theme[shape.props.color].highlight.srgb);
  path.setAttribute("stroke-width", `${sw}`);
  path.setAttribute("opacity", `${opacity}`);
  return path;
}
function getStrokeWidth(shape) {
  return FONT_SIZES[shape.props.size] * 1.12;
}
function getIsDot2(shape) {
  return shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/image/ImageShapeUtil.mjs
var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
var import_react52 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs
var import_react51 = __toESM(require_react(), 1);
function usePrefersReducedMotion() {
  const [prefersReducedMotion, setPrefersReducedMotion] = (0, import_react51.useState)(false);
  (0, import_react51.useEffect)(() => {
    const mql = window.matchMedia("(prefers-reduced-motion: reduce)");
    const handler = () => {
      setPrefersReducedMotion(mql.matches);
    };
    handler();
    mql.addEventListener("change", handler);
    return () => mql.removeEventListener("change", handler);
  }, []);
  return prefersReducedMotion;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/image/ImageShapeUtil.mjs
var loadImage = async (url) => {
  return new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = () => resolve(image);
    image.onerror = () => reject(new Error("Failed to load image"));
    image.crossOrigin = "anonymous";
    image.src = url;
  });
};
var getStateFrame = async (url) => {
  const image = await loadImage(url);
  const canvas = document.createElement("canvas");
  canvas.width = image.width;
  canvas.height = image.height;
  const ctx = canvas.getContext("2d");
  if (!ctx)
    return;
  ctx.drawImage(image, 0, 0);
  return canvas.toDataURL();
};
async function getDataURIFromURL(url) {
  const response = await fetch(url);
  const blob = await response.blob();
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(blob);
  });
}
var ImageShapeUtil = class extends BaseBoxShapeUtil {
  static type = "image";
  static props = imageShapeProps;
  static migrations = imageShapeMigrations;
  isAspectRatioLocked = () => true;
  canCrop = () => true;
  getDefaultProps() {
    return {
      w: 100,
      h: 100,
      assetId: null,
      playing: true,
      url: "",
      crop: null
    };
  }
  component(shape) {
    const containerStyle = getContainerStyle(shape);
    const isCropping = useIsCropping(shape.id);
    const prefersReducedMotion = usePrefersReducedMotion();
    const [staticFrameSrc, setStaticFrameSrc] = (0, import_react52.useState)("");
    const asset = shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : void 0;
    if (asset?.type === "bookmark") {
      throw Error("Bookmark assets can't be rendered as images");
    }
    const isSelected = useValue(
      "onlySelectedShape",
      () => shape.id === this.editor.onlySelectedShape?.id,
      [this.editor]
    );
    const showCropPreview = isSelected && isCropping && this.editor.isInAny("select.crop", "select.cropping", "select.pointing_crop_handle");
    const reduceMotion = prefersReducedMotion && (asset?.props.mimeType?.includes("video") || asset?.props.mimeType?.includes("gif"));
    (0, import_react52.useEffect)(() => {
      if (asset?.props.src && "mimeType" in asset.props && asset?.props.mimeType === "image/gif") {
        let cancelled = false;
        const run = async () => {
          const newStaticFrame = await getStateFrame(asset.props.src);
          if (cancelled)
            return;
          if (newStaticFrame) {
            setStaticFrameSrc(newStaticFrame);
          }
        };
        run();
        return () => {
          cancelled = true;
        };
      }
    }, [prefersReducedMotion, asset?.props]);
    return (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
      asset?.props.src && showCropPreview && (0, import_jsx_runtime71.jsx)("div", { style: containerStyle, children: (0, import_jsx_runtime71.jsx)(
        "div",
        {
          className: "tl-image",
          style: {
            opacity: 0.1,
            backgroundImage: `url(${!shape.props.playing || reduceMotion ? staticFrameSrc : asset.props.src})`
          },
          draggable: false
        }
      ) }),
      (0, import_jsx_runtime71.jsx)(
        HTMLContainer,
        {
          id: shape.id,
          style: { overflow: "hidden", width: shape.props.w, height: shape.props.h },
          children: (0, import_jsx_runtime71.jsxs)("div", { className: "tl-image-container", style: containerStyle, children: [
            asset?.props.src ? (0, import_jsx_runtime71.jsx)(
              "div",
              {
                className: "tl-image",
                style: {
                  backgroundImage: `url(${!shape.props.playing || reduceMotion ? staticFrameSrc : asset.props.src})`
                },
                draggable: false
              }
            ) : null,
            asset?.props.isAnimated && !shape.props.playing && (0, import_jsx_runtime71.jsx)("div", { className: "tl-image__tg", children: "GIF" })
          ] })
        }
      ),
      "url" in shape.props && shape.props.url && (0, import_jsx_runtime71.jsx)(HyperlinkButton, { url: shape.props.url, zoomLevel: this.editor.zoomLevel })
    ] });
  }
  indicator(shape) {
    const isCropping = useIsCropping(shape.id);
    if (isCropping) {
      return null;
    }
    return (0, import_jsx_runtime71.jsx)("rect", { width: toDomPrecision(shape.props.w), height: toDomPrecision(shape.props.h) });
  }
  async toSvg(shape) {
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    const asset = shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null;
    let src = asset?.props.src || "";
    if (src && src.startsWith("http")) {
      src = await getDataURIFromURL(src) || "";
    }
    const image = document.createElementNS("http://www.w3.org/2000/svg", "image");
    image.setAttributeNS("http://www.w3.org/1999/xlink", "href", src);
    const containerStyle = getContainerStyle(shape);
    const crop = shape.props.crop;
    if (containerStyle.transform && crop) {
      const { transform, width, height } = containerStyle;
      const points = [
        new Vec2d(crop.topLeft.x * width, crop.topLeft.y * height),
        new Vec2d(crop.bottomRight.x * width, crop.topLeft.y * height),
        new Vec2d(crop.bottomRight.x * width, crop.bottomRight.y * height),
        new Vec2d(crop.topLeft.x * width, crop.bottomRight.y * height)
      ];
      const innerElement = document.createElementNS("http://www.w3.org/2000/svg", "g");
      innerElement.style.clipPath = `polygon(${points.map((p) => `${p.x}px ${p.y}px`).join(",")})`;
      image.setAttribute("width", width.toString());
      image.setAttribute("height", height.toString());
      image.style.transform = transform;
      innerElement.appendChild(image);
      g.appendChild(innerElement);
    } else {
      image.setAttribute("width", shape.props.w.toString());
      image.setAttribute("height", shape.props.h.toString());
      g.appendChild(image);
    }
    return g;
  }
  onDoubleClick = (shape) => {
    const asset = shape.props.assetId ? this.editor.getAsset(shape.props.assetId) : void 0;
    if (!asset)
      return;
    const canPlay = asset.props.src && "mimeType" in asset.props && asset.props.mimeType === "image/gif";
    if (!canPlay)
      return;
    this.editor.updateShapes([
      {
        type: "image",
        id: shape.id,
        props: {
          playing: !shape.props.playing
        }
      }
    ]);
  };
  onDoubleClickEdge = (shape) => {
    const props = shape.props;
    if (!props)
      return;
    if (this.editor.croppingShapeId !== shape.id) {
      return;
    }
    const crop = deepCopy(props.crop) || {
      topLeft: { x: 0, y: 0 },
      bottomRight: { x: 1, y: 1 }
    };
    const w = 1 / (crop.bottomRight.x - crop.topLeft.x) * shape.props.w;
    const h = 1 / (crop.bottomRight.y - crop.topLeft.y) * shape.props.h;
    const pointDelta = new Vec2d(crop.topLeft.x * w, crop.topLeft.y * h).rot(shape.rotation);
    const partial = {
      id: shape.id,
      type: shape.type,
      x: shape.x - pointDelta.x,
      y: shape.y - pointDelta.y,
      props: {
        crop: {
          topLeft: { x: 0, y: 0 },
          bottomRight: { x: 1, y: 1 }
        },
        w,
        h
      }
    };
    this.editor.updateShapes([partial]);
  };
};
function getContainerStyle(shape) {
  const crop = shape.props.crop;
  const topLeft = crop?.topLeft;
  if (!topLeft) {
    return {
      width: shape.props.w,
      height: shape.props.h
    };
  }
  const w = 1 / (crop.bottomRight.x - crop.topLeft.x) * shape.props.w;
  const h = 1 / (crop.bottomRight.y - crop.topLeft.y) * shape.props.h;
  const offsetX = -topLeft.x * w;
  const offsetY = -topLeft.y * h;
  return {
    transform: `translate(${offsetX}px, ${offsetY}px)`,
    width: w,
    height: h
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/line/LineShapeUtil.mjs
var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/line/components/svg.mjs
function getSvgPathForEdge(edge, first) {
  const { start, end } = edge;
  if (first) {
    return `M${toDomPrecision(start.x)},${toDomPrecision(start.y)} L${toDomPrecision(
      end.x
    )},${toDomPrecision(end.y)} `;
  }
  return `${toDomPrecision(end.x)},${toDomPrecision(end.y)} `;
}
function getSvgPathForBezierCurve(curve, first) {
  const { a, b, c, d } = curve;
  if (Vec2d.Equals(a, d))
    return "";
  return `${first ? `M${toDomPrecision(a.x)},${toDomPrecision(a.y)}` : ``}C${toDomPrecision(
    b.x
  )},${toDomPrecision(b.y)} ${toDomPrecision(c.x)},${toDomPrecision(c.y)} ${toDomPrecision(
    d.x
  )},${toDomPrecision(d.y)}`;
}
function getSvgPathForCubicSpline(spline, isClosed) {
  let d = spline.segments.reduce((d2, segment, i) => {
    return d2 + getSvgPathForBezierCurve(segment, i === 0);
  }, "");
  if (isClosed) {
    d += "Z";
  }
  return d;
}
function getSvgPathForPolylineSpline(spline, isClosed) {
  let d = spline.segments.reduce((d2, segment, i) => {
    return d2 + getSvgPathForEdge(segment, i === 0);
  }, "");
  if (isClosed) {
    d += "Z";
  }
  return d;
}
function getSvgPathForLineGeometry(spline, isClosed = false) {
  if (spline instanceof Polyline2d) {
    return getSvgPathForPolylineSpline(spline, isClosed);
  } else {
    return getSvgPathForCubicSpline(spline, isClosed);
  }
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/line/components/getLinePath.mjs
function getLineDrawFreehandOptions(strokeWidth) {
  return {
    size: strokeWidth,
    thinning: 0.4,
    streamline: 0,
    smoothing: 0.5,
    simulatePressure: true,
    last: true
  };
}
function getLineStrokePoints(shape, spline, strokeWidth) {
  const points = spline.vertices;
  const options = getLineDrawFreehandOptions(strokeWidth);
  return getStrokePoints(points, options);
}
function getLineDrawStrokeOutlinePoints(shape, spline, strokeWidth) {
  const options = getLineDrawFreehandOptions(strokeWidth);
  return getStrokeOutlinePoints(
    setStrokePointRadii(getLineStrokePoints(shape, spline, strokeWidth), options),
    options
  );
}
function getLineDrawPath(shape, spline, strokeWidth) {
  const stroke = getLineDrawStrokeOutlinePoints(shape, spline, strokeWidth);
  return getSvgPathFromPoints(stroke);
}
function getLineIndicatorPath(shape, spline, strokeWidth) {
  if (shape.props.dash === "draw") {
    const strokePoints = getLineStrokePoints(shape, spline, strokeWidth);
    return getSvgPathFromStrokePoints(strokePoints);
  }
  return getSvgPathForLineGeometry(spline);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/line/LineShapeUtil.mjs
var handlesCache = new WeakMapCache();
var LineShapeUtil = class extends ShapeUtil {
  static type = "line";
  static props = lineShapeProps;
  static migrations = lineShapeMigrations;
  hideResizeHandles = () => true;
  hideRotateHandle = () => true;
  hideSelectionBoundsFg = () => true;
  hideSelectionBoundsBg = () => true;
  getDefaultProps() {
    return {
      dash: "draw",
      size: "m",
      color: "black",
      spline: "line",
      handles: {
        start: {
          id: "start",
          type: "vertex",
          canBind: false,
          canSnap: true,
          index: "a1",
          x: 0,
          y: 0
        },
        end: {
          id: "end",
          type: "vertex",
          canBind: false,
          canSnap: true,
          index: "a2",
          x: 0.1,
          y: 0.1
        }
      }
    };
  }
  getGeometry(shape) {
    return getGeometryForLineShape(shape);
  }
  getHandles(shape) {
    return handlesCache.get(shape.props, () => {
      const handles = shape.props.handles;
      const spline = getGeometryForLineShape(shape);
      const sortedHandles = Object.values(handles).sort(sortByIndex2);
      const results = sortedHandles.slice();
      for (let i = 0; i < spline.segments.length; i++) {
        const segment = spline.segments[i];
        const point = segment.midPoint();
        const index2 = getIndexBetween(sortedHandles[i].index, sortedHandles[i + 1].index);
        results.push({
          id: `mid-${i}`,
          type: "create",
          index: index2,
          x: point.x,
          y: point.y
        });
      }
      return results.sort(sortByIndex2);
    });
  }
  getOutlineSegments(shape) {
    const spline = this.editor.getShapeGeometry(shape);
    return spline.segments.map((s) => s.vertices);
  }
  //   Events
  onResize = (shape, info) => {
    const { scaleX, scaleY } = info;
    const handles = deepCopy(shape.props.handles);
    Object.values(shape.props.handles).forEach(({ id, x, y }) => {
      handles[id].x = x * scaleX;
      handles[id].y = y * scaleY;
    });
    return {
      props: {
        handles
      }
    };
  };
  onHandleChange = (shape, { handle }) => {
    const next = deepCopy(shape);
    switch (handle.id) {
      case "start":
      case "end": {
        next.props.handles[handle.id] = {
          ...next.props.handles[handle.id],
          x: handle.x,
          y: handle.y
        };
        break;
      }
      default: {
        const id = "handle:" + handle.index;
        const existing = shape.props.handles[id];
        if (existing) {
          next.props.handles[id] = {
            ...existing,
            x: handle.x,
            y: handle.y
          };
        } else {
          next.props.handles[id] = {
            id,
            type: "vertex",
            canBind: false,
            index: handle.index,
            x: handle.x,
            y: handle.y
          };
        }
        break;
      }
    }
    return next;
  };
  component(shape) {
    const theme = useDefaultColorTheme();
    const spline = getGeometryForLineShape(shape);
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const { dash, color } = shape.props;
    if (shape.props.spline === "line") {
      if (dash === "solid") {
        const outline = spline.points;
        const pathData = "M" + outline[0] + "L" + outline.slice(1);
        return (0, import_jsx_runtime72.jsxs)(SVGContainer, { id: shape.id, children: [
          (0, import_jsx_runtime72.jsx)(ShapeFill, { d: pathData, fill: "none", color, theme }),
          (0, import_jsx_runtime72.jsx)("path", { d: pathData, stroke: theme[color].solid, strokeWidth, fill: "none" })
        ] });
      }
      if (dash === "dashed" || dash === "dotted") {
        const outline = spline.points;
        const pathData = "M" + outline[0] + "L" + outline.slice(1);
        return (0, import_jsx_runtime72.jsxs)(SVGContainer, { id: shape.id, children: [
          (0, import_jsx_runtime72.jsx)(ShapeFill, { d: pathData, fill: "none", color, theme }),
          (0, import_jsx_runtime72.jsx)("g", { stroke: theme[color].solid, strokeWidth, children: spline.segments.map((segment, i) => {
            const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
              segment.length,
              strokeWidth,
              {
                style: dash,
                start: i > 0 ? "outset" : "none",
                end: i < spline.segments.length - 1 ? "outset" : "none"
              }
            );
            return (0, import_jsx_runtime72.jsx)(
              "path",
              {
                strokeDasharray,
                strokeDashoffset,
                d: getSvgPathForEdge(segment, true),
                fill: "none"
              },
              i
            );
          }) })
        ] });
      }
      if (dash === "draw") {
        const outline = spline.points;
        const [innerPathData, outerPathData] = getDrawLinePathData(shape.id, outline, strokeWidth);
        return (0, import_jsx_runtime72.jsxs)(SVGContainer, { id: shape.id, children: [
          (0, import_jsx_runtime72.jsx)(ShapeFill, { d: innerPathData, fill: "none", color, theme }),
          (0, import_jsx_runtime72.jsx)(
            "path",
            {
              d: outerPathData,
              stroke: theme[color].solid,
              strokeWidth,
              fill: "none"
            }
          )
        ] });
      }
    }
    if (shape.props.spline === "cubic") {
      const splinePath = getSvgPathForLineGeometry(spline);
      if (dash === "solid") {
        return (0, import_jsx_runtime72.jsxs)(SVGContainer, { id: shape.id, children: [
          (0, import_jsx_runtime72.jsx)(ShapeFill, { d: splinePath, fill: "none", color, theme }),
          (0, import_jsx_runtime72.jsx)(
            "path",
            {
              strokeWidth,
              stroke: theme[color].solid,
              fill: "none",
              d: splinePath
            }
          )
        ] });
      }
      if (dash === "dashed" || dash === "dotted") {
        return (0, import_jsx_runtime72.jsxs)(SVGContainer, { id: shape.id, children: [
          (0, import_jsx_runtime72.jsx)(ShapeFill, { d: splinePath, fill: "none", color, theme }),
          (0, import_jsx_runtime72.jsx)("g", { stroke: theme[color].solid, strokeWidth, children: spline.segments.map((segment, i) => {
            const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
              segment.length,
              strokeWidth,
              {
                style: dash,
                start: i > 0 ? "outset" : "none",
                end: i < spline.segments.length - 1 ? "outset" : "none"
              }
            );
            return (0, import_jsx_runtime72.jsx)(
              "path",
              {
                strokeDasharray,
                strokeDashoffset,
                d: getSvgPathForBezierCurve(segment, true),
                fill: "none"
              },
              i
            );
          }) })
        ] });
      }
      if (dash === "draw") {
        return (0, import_jsx_runtime72.jsxs)(SVGContainer, { id: shape.id, children: [
          (0, import_jsx_runtime72.jsx)(ShapeFill, { d: splinePath, fill: "none", color, theme }),
          (0, import_jsx_runtime72.jsx)(
            "path",
            {
              d: getLineDrawPath(shape, spline, strokeWidth),
              strokeWidth: 1,
              stroke: theme[color].solid,
              fill: theme[color].solid
            }
          )
        ] });
      }
    }
  }
  indicator(shape) {
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    const spline = getGeometryForLineShape(shape);
    const { dash } = shape.props;
    let path;
    if (shape.props.spline === "line") {
      const outline = spline.points;
      if (dash === "solid" || dash === "dotted" || dash === "dashed") {
        path = "M" + outline[0] + "L" + outline.slice(1);
      } else {
        const [innerPathData] = getDrawLinePathData(shape.id, outline, strokeWidth);
        path = innerPathData;
      }
    } else {
      path = getLineIndicatorPath(shape, spline, strokeWidth);
    }
    return (0, import_jsx_runtime72.jsx)("path", { d: path });
  }
  toSvg(shape) {
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    const color = theme[shape.props.color].solid;
    const spline = getGeometryForLineShape(shape);
    const strokeWidth = STROKE_SIZES2[shape.props.size];
    switch (shape.props.dash) {
      case "draw": {
        let pathData;
        if (spline instanceof CubicSpline2d) {
          pathData = getLineDrawPath(shape, spline, strokeWidth);
        } else {
          const [_, outerPathData] = getDrawLinePathData(shape.id, spline.points, strokeWidth);
          pathData = outerPathData;
        }
        const p = document.createElementNS("http://www.w3.org/2000/svg", "path");
        p.setAttribute("stroke-width", strokeWidth + "px");
        p.setAttribute("stroke", color);
        p.setAttribute("fill", "none");
        p.setAttribute("d", pathData);
        return p;
      }
      case "solid": {
        let pathData;
        if (spline instanceof CubicSpline2d) {
          pathData = getSvgPathForCubicSpline(spline, false);
        } else {
          const outline = spline.points;
          pathData = "M" + outline[0] + "L" + outline.slice(1);
        }
        const p = document.createElementNS("http://www.w3.org/2000/svg", "path");
        p.setAttribute("stroke-width", strokeWidth + "px");
        p.setAttribute("stroke", color);
        p.setAttribute("fill", "none");
        p.setAttribute("d", pathData);
        return p;
      }
      default: {
        const { segments } = spline;
        const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
        g.setAttribute("stroke", color);
        g.setAttribute("stroke-width", strokeWidth.toString());
        const fn = spline instanceof CubicSpline2d ? getSvgPathForBezierCurve : getSvgPathForEdge;
        segments.forEach((segment, i) => {
          const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
          const { strokeDasharray, strokeDashoffset } = getPerfectDashProps2(
            segment.length,
            strokeWidth,
            {
              style: shape.props.dash,
              start: i > 0 ? "outset" : "none",
              end: i < segments.length - 1 ? "outset" : "none"
            }
          );
          path.setAttribute("stroke-dasharray", strokeDasharray.toString());
          path.setAttribute("stroke-dashoffset", strokeDashoffset.toString());
          path.setAttribute("d", fn(segment, true));
          path.setAttribute("fill", "none");
          g.appendChild(path);
        });
        return g;
      }
    }
  }
};
function getGeometryForLineShape(shape) {
  const { spline, handles } = shape.props;
  const handlePoints = Object.values(handles).sort(sortByIndex2).map(Vec2d.From);
  switch (spline) {
    case "cubic": {
      return new CubicSpline2d({ points: handlePoints });
    }
    case "line": {
      return new Polyline2d({ points: handlePoints });
    }
  }
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/note/NoteShapeUtil.mjs
var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
var NOTE_SIZE = 200;
var NoteShapeUtil = class extends ShapeUtil {
  static type = "note";
  static props = noteShapeProps;
  static migrations = noteShapeMigrations;
  canEdit = () => true;
  hideResizeHandles = () => true;
  hideSelectionBoundsFg = () => true;
  getDefaultProps() {
    return {
      color: "black",
      size: "m",
      text: "",
      font: "draw",
      align: "middle",
      verticalAlign: "middle",
      growY: 0,
      url: ""
    };
  }
  getHeight(shape) {
    return NOTE_SIZE + shape.props.growY;
  }
  getGeometry(shape) {
    const height = this.getHeight(shape);
    return new Rectangle2d({ width: NOTE_SIZE, height, isFilled: true });
  }
  component(shape) {
    const {
      id,
      type,
      props: { color, font, size: size2, align, text, verticalAlign }
    } = shape;
    const theme = useDefaultColorTheme();
    const adjustedColor = color === "black" ? "yellow" : color;
    return (0, import_jsx_runtime73.jsxs)(import_jsx_runtime73.Fragment, { children: [
      (0, import_jsx_runtime73.jsx)(
        "div",
        {
          style: {
            position: "absolute",
            width: NOTE_SIZE,
            height: this.getHeight(shape)
          },
          children: (0, import_jsx_runtime73.jsxs)(
            "div",
            {
              className: "tl-note__container",
              style: {
                color: theme[adjustedColor].solid,
                backgroundColor: theme[adjustedColor].solid
              },
              children: [
                (0, import_jsx_runtime73.jsx)("div", { className: "tl-note__scrim" }),
                (0, import_jsx_runtime73.jsx)(
                  TextLabel,
                  {
                    id,
                    type,
                    font,
                    size: size2,
                    align,
                    verticalAlign,
                    text,
                    labelColor: "black",
                    wrap: true
                  }
                )
              ]
            }
          )
        }
      ),
      "url" in shape.props && shape.props.url && (0, import_jsx_runtime73.jsx)(HyperlinkButton, { url: shape.props.url, zoomLevel: this.editor.zoomLevel })
    ] });
  }
  indicator(shape) {
    return (0, import_jsx_runtime73.jsx)(
      "rect",
      {
        rx: "7",
        width: toDomPrecision(NOTE_SIZE),
        height: toDomPrecision(this.getHeight(shape))
      }
    );
  }
  toSvg(shape, ctx) {
    ctx.addExportDef(getFontDefForExport(shape.props.font));
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    const adjustedColor = shape.props.color === "black" ? "yellow" : shape.props.color;
    const rect1 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect1.setAttribute("rx", "10");
    rect1.setAttribute("width", NOTE_SIZE.toString());
    rect1.setAttribute("height", bounds.height.toString());
    rect1.setAttribute("fill", theme[adjustedColor].solid);
    rect1.setAttribute("stroke", theme[adjustedColor].solid);
    rect1.setAttribute("stroke-width", "1");
    g.appendChild(rect1);
    const rect2 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect2.setAttribute("rx", "10");
    rect2.setAttribute("width", NOTE_SIZE.toString());
    rect2.setAttribute("height", bounds.height.toString());
    rect2.setAttribute("fill", theme.background);
    rect2.setAttribute("opacity", ".28");
    g.appendChild(rect2);
    const textElm = getTextLabelSvgElement({
      editor: this.editor,
      shape,
      font: DefaultFontFamilies[shape.props.font],
      bounds
    });
    textElm.setAttribute("fill", theme.text);
    textElm.setAttribute("stroke", "none");
    g.appendChild(textElm);
    return g;
  }
  onBeforeCreate = (next) => {
    return getGrowY(this.editor, next, next.props.growY);
  };
  onBeforeUpdate = (prev, next) => {
    if (prev.props.text === next.props.text && prev.props.font === next.props.font && prev.props.size === next.props.size) {
      return;
    }
    return getGrowY(this.editor, next, prev.props.growY);
  };
  onEditEnd = (shape) => {
    const {
      id,
      type,
      props: { text }
    } = shape;
    if (text.trimEnd() !== shape.props.text) {
      this.editor.updateShapes([
        {
          id,
          type,
          props: {
            text: text.trimEnd()
          }
        }
      ]);
    }
  };
};
function getGrowY(editor, shape, prevGrowY = 0) {
  const PADDING = 17;
  const nextTextSize = editor.textMeasure.measureText(shape.props.text, {
    ...TEXT_PROPS,
    fontFamily: FONT_FAMILIES[shape.props.font],
    fontSize: LABEL_FONT_SIZES[shape.props.size],
    maxWidth: NOTE_SIZE - PADDING * 2
  });
  const nextHeight = nextTextSize.h + PADDING * 2;
  let growY = null;
  if (nextHeight > NOTE_SIZE) {
    growY = nextHeight - NOTE_SIZE;
  } else {
    if (prevGrowY) {
      growY = 0;
    }
  }
  if (growY !== null) {
    return {
      ...shape,
      props: {
        ...shape.props,
        growY
      }
    };
  }
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/text/TextShapeUtil.mjs
var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/resizeScaled.mjs
function resizeScaled(shape, {
  initialBounds,
  scaleX,
  scaleY,
  newPoint
}) {
  const scaleDelta = Math.max(0.01, Math.min(Math.abs(scaleX), Math.abs(scaleY)));
  const offset2 = new Vec2d(0, 0);
  if (scaleX < 0) {
    offset2.x = -(initialBounds.width * scaleDelta);
  }
  if (scaleY < 0) {
    offset2.y = -(initialBounds.height * scaleDelta);
  }
  const { x, y } = Vec2d.Add(newPoint, offset2.rot(shape.rotation));
  return {
    x,
    y,
    props: {
      scale: scaleDelta * shape.props.scale
    }
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/text/TextShapeUtil.mjs
var sizeCache = new WeakMapCache();
var TextShapeUtil = class extends ShapeUtil {
  static type = "text";
  static props = textShapeProps;
  static migrations = textShapeMigrations;
  getDefaultProps() {
    return {
      color: "black",
      size: "m",
      w: 8,
      text: "",
      font: "draw",
      align: "middle",
      autoSize: true,
      scale: 1
    };
  }
  getMinDimensions(shape) {
    return sizeCache.get(shape.props, (props) => getTextSize(this.editor, props));
  }
  getGeometry(shape) {
    const { scale } = shape.props;
    const { width, height } = this.getMinDimensions(shape);
    return new Rectangle2d({
      width: width * scale,
      height: height * scale,
      isFilled: true
    });
  }
  canEdit = () => true;
  isAspectRatioLocked = () => true;
  component(shape) {
    const {
      id,
      type,
      props: { text, color }
    } = shape;
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    const { width, height } = this.getMinDimensions(shape);
    const {
      rInput,
      isEmpty,
      isEditing,
      handleFocus,
      handleChange,
      handleKeyDown,
      handleBlur,
      handleInputPointerDown,
      handleDoubleClick
    } = useEditableText(id, type, text);
    return (0, import_jsx_runtime74.jsx)(HTMLContainer, { id: shape.id, children: (0, import_jsx_runtime74.jsxs)(
      "div",
      {
        className: "tl-text-shape__wrapper tl-text-shadow",
        "data-font": shape.props.font,
        "data-align": shape.props.align,
        "data-hastext": !isEmpty,
        "data-isediting": isEditing,
        "data-textwrap": true,
        style: {
          fontSize: FONT_SIZES[shape.props.size],
          lineHeight: FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + "px",
          transform: `scale(${shape.props.scale})`,
          transformOrigin: "top left",
          width: Math.max(1, width),
          height: Math.max(FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight, height),
          color: theme[color].solid
        },
        children: [
          (0, import_jsx_runtime74.jsx)("div", { className: "tl-text tl-text-content", dir: "ltr", children: text }),
          isEditing ? (0, import_jsx_runtime74.jsx)(
            "textarea",
            {
              ref: rInput,
              className: "tl-text tl-text-input",
              name: "text",
              tabIndex: -1,
              autoComplete: "false",
              autoCapitalize: "false",
              autoCorrect: "false",
              autoSave: "false",
              autoFocus: isEditing,
              placeholder: "",
              spellCheck: "true",
              wrap: "off",
              dir: "ltr",
              datatype: "wysiwyg",
              defaultValue: text,
              onFocus: handleFocus,
              onChange: handleChange,
              onKeyDown: handleKeyDown,
              onBlur: handleBlur,
              onTouchEnd: stopEventPropagation,
              onContextMenu: stopEventPropagation,
              onPointerDown: handleInputPointerDown,
              onDoubleClick: handleDoubleClick
            }
          ) : null
        ]
      }
    ) });
  }
  indicator(shape) {
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    return (0, import_jsx_runtime74.jsx)("rect", { width: toDomPrecision(bounds.width), height: toDomPrecision(bounds.height) });
  }
  toSvg(shape, ctx) {
    ctx.addExportDef(getFontDefForExport(shape.props.font));
    const theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode });
    const bounds = this.editor.getShapeGeometry(shape).bounds;
    const text = shape.props.text;
    const width = bounds.width / (shape.props.scale ?? 1);
    const height = bounds.height / (shape.props.scale ?? 1);
    const opts = {
      fontSize: FONT_SIZES[shape.props.size],
      fontFamily: DefaultFontFamilies[shape.props.font],
      textAlign: shape.props.align,
      verticalTextAlign: "middle",
      width,
      height,
      padding: 0,
      // no padding?
      lineHeight: TEXT_PROPS.lineHeight,
      fontStyle: "normal",
      fontWeight: "normal",
      overflow: "wrap"
    };
    const color = theme[shape.props.color].solid;
    const groupEl = document.createElementNS("http://www.w3.org/2000/svg", "g");
    const textBgEl = createTextSvgElementFromSpans(
      this.editor,
      this.editor.textMeasure.measureTextSpans(text, opts),
      {
        ...opts,
        stroke: theme.background,
        strokeWidth: 2,
        fill: theme.background,
        padding: 0
      }
    );
    const textElm = textBgEl.cloneNode(true);
    textElm.setAttribute("fill", color);
    textElm.setAttribute("stroke", "none");
    groupEl.append(textBgEl);
    groupEl.append(textElm);
    return groupEl;
  }
  onResize = (shape, info) => {
    const { initialBounds, initialShape, scaleX, handle } = info;
    if (info.mode === "scale_shape" || handle !== "right" && handle !== "left") {
      return {
        id: shape.id,
        type: shape.type,
        ...resizeScaled(shape, info)
      };
    } else {
      const prevWidth = initialBounds.width;
      let nextWidth = prevWidth * scaleX;
      const offset2 = new Vec2d(0, 0);
      nextWidth = Math.max(1, Math.abs(nextWidth));
      if (handle === "left") {
        offset2.x = prevWidth - nextWidth;
        if (scaleX < 0) {
          offset2.x += nextWidth;
        }
      } else {
        if (scaleX < 0) {
          offset2.x -= nextWidth;
        }
      }
      const { x, y } = offset2.rot(shape.rotation).add(initialShape);
      return {
        id: shape.id,
        type: shape.type,
        x,
        y,
        props: {
          w: nextWidth / initialShape.props.scale,
          autoSize: false
        }
      };
    }
  };
  onBeforeCreate = (shape) => {
    if (!shape.props.autoSize)
      return;
    if (shape.props.text.trim())
      return;
    const bounds = this.getMinDimensions(shape);
    return {
      ...shape,
      x: shape.x - bounds.width / 2,
      y: shape.y - bounds.height / 2
    };
  };
  onEditEnd = (shape) => {
    const {
      id,
      type,
      props: { text }
    } = shape;
    const trimmedText = shape.props.text.trimEnd();
    if (trimmedText.length === 0) {
      this.editor.deleteShapes([shape.id]);
    } else {
      if (trimmedText !== shape.props.text) {
        this.editor.updateShapes([
          {
            id,
            type,
            props: {
              text: text.trimEnd()
            }
          }
        ]);
      }
    }
  };
  onBeforeUpdate = (prev, next) => {
    if (!next.props.autoSize)
      return;
    const styleDidChange = prev.props.size !== next.props.size || prev.props.align !== next.props.align || prev.props.font !== next.props.font || prev.props.scale !== 1 && next.props.scale === 1;
    const textDidChange = prev.props.text !== next.props.text;
    if (!styleDidChange && !textDidChange)
      return;
    const boundsA = this.getMinDimensions(prev);
    const boundsB = getTextSize(this.editor, next.props);
    const wA = boundsA.width * prev.props.scale;
    const hA = boundsA.height * prev.props.scale;
    const wB = boundsB.width * next.props.scale;
    const hB = boundsB.height * next.props.scale;
    let delta;
    switch (next.props.align) {
      case "middle": {
        delta = new Vec2d((wB - wA) / 2, textDidChange ? 0 : (hB - hA) / 2);
        break;
      }
      case "end": {
        delta = new Vec2d(wB - wA, textDidChange ? 0 : (hB - hA) / 2);
        break;
      }
      default: {
        if (textDidChange)
          break;
        delta = new Vec2d(0, (hB - hA) / 2);
        break;
      }
    }
    if (delta) {
      delta.rot(next.rotation);
      const { x, y } = next;
      return {
        ...next,
        x: x - delta.x,
        y: y - delta.y,
        props: { ...next.props, w: wB }
      };
    } else {
      return {
        ...next,
        props: { ...next.props, w: wB }
      };
    }
  };
  onDoubleClickEdge = (shape) => {
    if (!shape.props.autoSize) {
      return {
        id: shape.id,
        type: shape.type,
        props: {
          autoSize: true
        }
      };
    }
    if (shape.props.scale !== 1) {
      return {
        id: shape.id,
        type: shape.type,
        props: {
          scale: 1
        }
      };
    }
  };
};
function getTextSize(editor, props) {
  const { font, text, autoSize, size: size2, w } = props;
  const minWidth = autoSize ? 16 : Math.max(16, w);
  const fontSize = FONT_SIZES[size2];
  const cw = autoSize ? null : (
    // `measureText` floors the number so we need to do the same here to avoid issues.
    Math.floor(Math.max(minWidth, w))
  );
  const result = editor.textMeasure.measureText(text, {
    ...TEXT_PROPS,
    fontFamily: FONT_FAMILIES[font],
    fontSize,
    maxWidth: cw
  });
  if (autoSize) {
    result.w += 1;
  }
  return {
    width: Math.max(minWidth, result.w),
    height: Math.max(fontSize, result.h)
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/video/VideoShapeUtil.mjs
var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
var import_react53 = __toESM(require_react(), 1);
var VideoShapeUtil = class extends BaseBoxShapeUtil {
  static type = "video";
  static props = videoShapeProps;
  static migrations = videoShapeMigrations;
  canEdit = () => true;
  isAspectRatioLocked = () => true;
  getDefaultProps() {
    return {
      w: 100,
      h: 100,
      assetId: null,
      time: 0,
      playing: true,
      url: ""
    };
  }
  component(shape) {
    return (0, import_jsx_runtime75.jsx)(TLVideoUtilComponent, { shape, videoUtil: this });
  }
  indicator(shape) {
    return (0, import_jsx_runtime75.jsx)("rect", { width: toDomPrecision(shape.props.w), height: toDomPrecision(shape.props.h) });
  }
  toSvg(shape) {
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    const image = document.createElementNS("http://www.w3.org/2000/svg", "image");
    image.setAttributeNS("http://www.w3.org/1999/xlink", "href", serializeVideo(shape.id));
    image.setAttribute("width", shape.props.w.toString());
    image.setAttribute("height", shape.props.h.toString());
    g.appendChild(image);
    return g;
  }
};
function serializeVideo(id) {
  const splitId = id.split(":")[1];
  const video = document.querySelector(`.tl-video-shape-${splitId}`);
  if (video) {
    const canvas = document.createElement("canvas");
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext("2d").drawImage(video, 0, 0);
    return canvas.toDataURL("image/png");
  } else
    throw new Error("Video with id " + splitId + " not found");
}
var TLVideoUtilComponent = track(function TLVideoUtilComponent2(props) {
  const { shape, videoUtil } = props;
  const showControls = videoUtil.editor.getShapeGeometry(shape).bounds.w * videoUtil.editor.zoomLevel >= 110;
  const asset = shape.props.assetId ? videoUtil.editor.getAsset(shape.props.assetId) : null;
  const { time, playing } = shape.props;
  const isEditing = useIsEditing(shape.id);
  const prefersReducedMotion = usePrefersReducedMotion();
  const rVideo = import_react53.default.useRef(null);
  const handlePlay = import_react53.default.useCallback(
    (e) => {
      const video = e.currentTarget;
      videoUtil.editor.updateShapes([
        {
          type: "video",
          id: shape.id,
          props: {
            playing: true,
            time: video.currentTime
          }
        }
      ]);
    },
    [shape.id, videoUtil.editor]
  );
  const handlePause = import_react53.default.useCallback(
    (e) => {
      const video = e.currentTarget;
      videoUtil.editor.updateShapes([
        {
          type: "video",
          id: shape.id,
          props: {
            playing: false,
            time: video.currentTime
          }
        }
      ]);
    },
    [shape.id, videoUtil.editor]
  );
  const handleSetCurrentTime = import_react53.default.useCallback(
    (e) => {
      const video = e.currentTarget;
      if (isEditing) {
        videoUtil.editor.updateShapes([
          {
            type: "video",
            id: shape.id,
            props: {
              time: video.currentTime
            }
          }
        ]);
      }
    },
    [isEditing, shape.id, videoUtil.editor]
  );
  const [isLoaded, setIsLoaded] = import_react53.default.useState(false);
  const handleLoadedData = import_react53.default.useCallback(
    (e) => {
      const video = e.currentTarget;
      if (time !== video.currentTime) {
        video.currentTime = time;
      }
      if (!playing) {
        video.pause();
      }
      setIsLoaded(true);
    },
    [playing, time]
  );
  import_react53.default.useEffect(() => {
    const video = rVideo.current;
    if (!video)
      return;
    if (isLoaded && !isEditing && time !== video.currentTime) {
      video.currentTime = time;
    }
    if (isEditing) {
      if (document.activeElement !== video) {
        video.focus();
      }
    }
  }, [isEditing, isLoaded, time]);
  import_react53.default.useEffect(() => {
    if (prefersReducedMotion) {
      const video = rVideo.current;
      video.pause();
      video.currentTime = 0;
    }
  }, [rVideo, prefersReducedMotion]);
  return (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
    (0, import_jsx_runtime75.jsx)(HTMLContainer, { id: shape.id, children: (0, import_jsx_runtime75.jsx)("div", { className: "tl-counter-scaled", children: asset?.props.src ? (0, import_jsx_runtime75.jsx)(
      "video",
      {
        ref: rVideo,
        style: isEditing ? { pointerEvents: "all" } : void 0,
        className: `tl-video tl-video-shape-${shape.id.split(":")[1]}`,
        width: "100%",
        height: "100%",
        draggable: false,
        playsInline: true,
        autoPlay: true,
        muted: true,
        loop: true,
        disableRemotePlayback: true,
        disablePictureInPicture: true,
        controls: isEditing && showControls,
        onPlay: handlePlay,
        onPause: handlePause,
        onTimeUpdate: handleSetCurrentTime,
        onLoadedData: handleLoadedData,
        hidden: !isLoaded,
        children: (0, import_jsx_runtime75.jsx)("source", { src: asset.props.src })
      }
    ) : null }) }),
    "url" in shape.props && shape.props.url && (0, import_jsx_runtime75.jsx)(HyperlinkButton, { url: shape.props.url, zoomLevel: videoUtil.editor.zoomLevel })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/defaultShapeUtils.mjs
var defaultShapeUtils = [
  TextShapeUtil,
  BookmarkShapeUtil,
  DrawShapeUtil,
  GeoShapeUtil,
  NoteShapeUtil,
  LineShapeUtil,
  FrameShapeUtil,
  ArrowShapeUtil,
  HighlightShapeUtil,
  EmbedShapeUtil,
  ImageShapeUtil,
  VideoShapeUtil
];

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/defaultSideEffects.mjs
function registerDefaultSideEffects(editor) {
  return [
    editor.sideEffects.registerAfterChangeHandler("instance", (prev, next) => {
      if (prev.isFocused !== next.isFocused) {
        if (next.isFocused) {
          editor.getContainer().focus();
          editor.updateViewportScreenBounds();
        } else {
          editor.complete();
          editor.getContainer().blur();
          editor.updateViewportScreenBounds();
        }
      }
    }),
    editor.sideEffects.registerAfterChangeHandler("instance_page_state", (prev, next) => {
      if (prev.croppingShapeId !== next.croppingShapeId) {
        const isInCroppingState = editor.isInAny(
          "select.crop",
          "select.pointing_crop_handle",
          "select.cropping"
        );
        if (!prev.croppingShapeId && next.croppingShapeId) {
          if (!isInCroppingState) {
            editor.setCurrentTool("select.crop.idle");
          }
        } else if (prev.croppingShapeId && !next.croppingShapeId) {
          if (isInCroppingState) {
            editor.setCurrentTool("select.idle");
          }
        }
      }
      if (prev.editingShapeId !== next.editingShapeId) {
        if (!prev.editingShapeId && next.editingShapeId) {
          if (!editor.isIn("select.editing_shape")) {
            editor.setCurrentTool("select.editing_shape");
          }
        } else if (prev.editingShapeId && !next.editingShapeId) {
          if (editor.isIn("select.editing_shape")) {
            editor.setCurrentTool("select.idle");
          }
        }
      }
    })
  ];
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/shapes/shared/ScribbleManager.mjs
var ScribbleManager = class {
  // Scribble properties
  state;
  points;
  size;
  color;
  opacity;
  delay;
  timeoutMs = 0;
  delayRemaining = 0;
  // Callbacks
  onUpdate;
  onComplete;
  // Internal state
  prev = null;
  next = null;
  constructor(opts) {
    const { size: size2 = 20, color = "accent", opacity = 0.8, delay = 0, onComplete, onUpdate } = opts;
    this.onUpdate = onUpdate;
    this.onComplete = onComplete;
    this.size = size2;
    this.color = color;
    this.delay = delay;
    this.opacity = opacity;
    this.points = [];
    this.state = "starting";
    this.prev = null;
    this.next = null;
    this.delayRemaining = this.delay;
    this.resume();
  }
  resume = () => {
    this.state = "active";
  };
  pause = () => {
    this.state = "starting";
  };
  /**
   * Start stopping the scribble. The scribble won't be removed until its last point is cleared.
   *
   * @public
   */
  stop = () => {
    this.delayRemaining = Math.min(this.delayRemaining, 200);
    this.state = "stopping";
  };
  /**
   * Set the scribble's next point.
   *
   * @param point - The point to add.
   * @public
   */
  addPoint = (x, y) => {
    const { prev } = this;
    const point = { x, y, z: 0.5 };
    if (prev && Vec2d.Dist(prev, point) < 1)
      return;
    this.next = point;
  };
  /**
   * Get the current TLScribble object from the scribble manager.
   *
   * @public
   */
  getScribble() {
    return {
      state: this.state,
      size: this.size,
      color: this.color,
      opacity: this.opacity,
      delay: this.delay,
      points: [...this.points]
    };
  }
  updateScribble() {
    this.onUpdate(this.getScribble());
  }
  tick = (elapsed) => {
    this.timeoutMs += elapsed;
    if (this.delayRemaining > 0) {
      this.delayRemaining = Math.max(0, this.delayRemaining - elapsed);
    }
    if (this.timeoutMs >= 16) {
      this.timeoutMs = 0;
    }
    const { timeoutMs, state, prev, next, points } = this;
    switch (state) {
      case "active": {
        if (next && next !== prev) {
          this.prev = next;
          points.push(next);
          if (this.delayRemaining === 0) {
            if (points.length > 8) {
              points.shift();
            }
          }
          this.updateScribble();
        } else {
          if (timeoutMs === 0) {
            if (points.length > 1) {
              points.shift();
              this.updateScribble();
            } else {
              this.delayRemaining = this.delay;
            }
          }
        }
        break;
      }
      case "stopping": {
        if (this.delayRemaining === 0) {
          if (timeoutMs === 0) {
            if (points.length === 1) {
              this.state = "paused";
              this.onComplete();
              return;
            }
            this.size *= 0.9;
            points.shift();
            this.updateScribble();
          }
        }
        break;
      }
      case "paused": {
        break;
      }
    }
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/EraserTool/children/Erasing.mjs
var Erasing = class extends StateNode {
  static id = "erasing";
  info = {};
  scribble = {};
  markId = "";
  excludedShapeIds = /* @__PURE__ */ new Set();
  onEnter = (info) => {
    this.markId = "erase scribble begin";
    this.editor.mark(this.markId);
    this.info = info;
    const { originPagePoint } = this.editor.inputs;
    this.excludedShapeIds = new Set(
      this.editor.currentPageShapes.filter((shape) => {
        if (this.editor.isShapeOrAncestorLocked(shape))
          return true;
        if (this.editor.isShapeOfType(shape, "group") || this.editor.isShapeOfType(shape, "frame")) {
          const pointInShapeShape = this.editor.getPointInShapeSpace(shape, originPagePoint);
          const geometry = this.editor.getShapeGeometry(shape);
          return geometry.bounds.containsPoint(pointInShapeShape);
        }
        return false;
      }).map((shape) => shape.id)
    );
    this.startScribble();
    this.update();
  };
  startScribble = () => {
    if (this.scribble.tick) {
      this.editor.off("tick", this.scribble?.tick);
    }
    this.scribble = new ScribbleManager({
      onUpdate: this.onScribbleUpdate,
      onComplete: this.onScribbleComplete,
      color: "muted-1",
      size: 12
    });
    this.editor.on("tick", this.scribble.tick);
  };
  pushPointToScribble = () => {
    const { x, y } = this.editor.inputs.currentPagePoint;
    this.scribble.addPoint(x, y);
  };
  onScribbleUpdate = (scribble) => {
    this.editor.updateInstanceState({ scribble });
  };
  onScribbleComplete = () => {
    this.editor.off("tick", this.scribble.tick);
    this.editor.updateInstanceState({ scribble: null });
  };
  onExit = () => {
    this.scribble.stop();
  };
  onPointerMove = () => {
    this.update();
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  update() {
    const {
      zoomLevel,
      currentPageShapes,
      erasingShapeIds,
      inputs: { currentPagePoint, previousPagePoint }
    } = this.editor;
    const { excludedShapeIds } = this;
    this.pushPointToScribble();
    const erasing = new Set(erasingShapeIds);
    for (const shape of currentPageShapes) {
      if (this.editor.isShapeOfType(shape, "group"))
        continue;
      const pageMask = this.editor.getShapeMask(shape.id);
      if (pageMask && !pointInPolygon(currentPagePoint, pageMask)) {
        continue;
      }
      const geometry = this.editor.getShapeGeometry(shape);
      const A = this.editor.getPointInShapeSpace(shape, previousPagePoint);
      const B = this.editor.getPointInShapeSpace(shape, currentPagePoint);
      if (geometry.hitTestLineSegment(A, B, HIT_TEST_MARGIN / zoomLevel)) {
        erasing.add(this.editor.getOutermostSelectableShape(shape).id);
      }
    }
    this.editor.setErasingShapes([...erasing].filter((id) => !excludedShapeIds.has(id)));
  }
  complete() {
    this.editor.deleteShapes(this.editor.currentPageState.erasingShapeIds);
    this.editor.setErasingShapes([]);
    this.parent.transition("idle", {});
  }
  cancel() {
    this.editor.setErasingShapes([]);
    this.editor.bailToMark(this.markId);
    this.parent.transition("idle", this.info);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/EraserTool/children/Idle.mjs
var Idle8 = class extends StateNode {
  static id = "idle";
  onPointerDown = (info) => {
    this.parent.transition("pointing", info);
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/EraserTool/children/Pointing.mjs
var Pointing7 = class extends StateNode {
  static id = "pointing";
  onEnter = () => {
    const {
      inputs: { currentPagePoint },
      currentPageShapesSorted: sortedShapesOnCurrentPage,
      zoomLevel
    } = this.editor;
    const erasing = /* @__PURE__ */ new Set();
    const initialSize = erasing.size;
    for (let n = sortedShapesOnCurrentPage.length, i = n - 1; i >= 0; i--) {
      const shape = sortedShapesOnCurrentPage[i];
      if (this.editor.isShapeOrAncestorLocked(shape) || this.editor.isShapeOfType(shape, "group")) {
        continue;
      }
      if (this.editor.isPointInShape(shape, currentPagePoint, {
        hitInside: false,
        margin: HIT_TEST_MARGIN / zoomLevel
      })) {
        const hitShape = this.editor.getOutermostSelectableShape(shape);
        if (this.editor.isShapeOfType(hitShape, "frame") && erasing.size > initialSize) {
          break;
        }
        erasing.add(hitShape.id);
      }
    }
    this.editor.setErasingShapes([...erasing]);
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      this.parent.transition("erasing", info);
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  onInterrupt = () => {
    this.cancel();
  };
  complete() {
    const { erasingShapeIds } = this.editor;
    if (erasingShapeIds.length) {
      this.editor.mark("erase end");
      this.editor.deleteShapes(erasingShapeIds);
    }
    this.editor.setErasingShapes([]);
    this.parent.transition("idle", {});
  }
  cancel() {
    this.editor.setErasingShapes([]);
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/EraserTool/EraserTool.mjs
var EraserTool = class extends StateNode {
  static id = "eraser";
  static initial = "idle";
  static children = () => [Idle8, Pointing7, Erasing];
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/HandTool/children/Dragging.mjs
var Dragging = class extends StateNode {
  static id = "dragging";
  onEnter = () => {
    this.update();
  };
  onPointerMove = () => {
    this.update();
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  update() {
    const { currentScreenPoint, previousScreenPoint } = this.editor.inputs;
    const delta = Vec2d.Sub(currentScreenPoint, previousScreenPoint);
    if (Math.abs(delta.x) > 0 || Math.abs(delta.y) > 0) {
      this.editor.pan(delta);
    }
  }
  complete() {
    this.editor.slideCamera({
      speed: Math.min(2, this.editor.inputs.pointerVelocity.len()),
      direction: this.editor.inputs.pointerVelocity,
      friction: CAMERA_SLIDE_FRICTION
    });
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/HandTool/children/Idle.mjs
var Idle9 = class extends StateNode {
  static id = "idle";
  onEnter = () => {
    this.editor.setCursor({ type: "grab", rotation: 0 });
  };
  onPointerDown = (info) => {
    this.parent.transition("pointing", info);
  };
  onCancel = () => {
    this.editor.setCurrentTool("select");
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/HandTool/children/Pointing.mjs
var Pointing8 = class extends StateNode {
  static id = "pointing";
  onEnter = () => {
    this.editor.stopCameraAnimation();
    this.editor.updateInstanceState(
      { cursor: { type: "grabbing", rotation: 0 } },
      { ephemeral: true }
    );
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      this.parent.transition("dragging", info);
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onInterrupt = () => {
    this.complete();
  };
  complete() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/HandTool/HandTool.mjs
var HandTool = class extends StateNode {
  static id = "hand";
  static initial = "idle";
  static children = () => [Idle9, Pointing8, Dragging];
  onDoubleClick = (info) => {
    if (info.phase === "settle") {
      const { currentScreenPoint } = this.editor.inputs;
      this.editor.zoomIn(currentScreenPoint, { duration: 220, easing: EASINGS.easeOutQuint });
    }
  };
  onTripleClick = (info) => {
    if (info.phase === "settle") {
      const { currentScreenPoint } = this.editor.inputs;
      this.editor.zoomOut(currentScreenPoint, { duration: 320, easing: EASINGS.easeOutQuint });
    }
  };
  onQuadrupleClick = (info) => {
    if (info.phase === "settle") {
      const {
        zoomLevel,
        inputs: { currentScreenPoint }
      } = this.editor;
      if (zoomLevel === 1) {
        this.editor.zoomToFit({ duration: 400, easing: EASINGS.easeOutQuint });
      } else {
        this.editor.resetZoom(currentScreenPoint, { duration: 320, easing: EASINGS.easeOutQuint });
      }
    }
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/LaserTool/children/Idle.mjs
var Idle10 = class extends StateNode {
  static id = "idle";
  onPointerDown = (info) => {
    this.parent.transition("lasering", info);
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/LaserTool/children/Lasering.mjs
var Lasering = class extends StateNode {
  static id = "lasering";
  scribble = {};
  onEnter = () => {
    this.startScribble();
    this.pushPointToScribble();
  };
  onExit = () => {
    this.scribble.stop();
  };
  onPointerMove = () => {
    this.pushPointToScribble();
  };
  onPointerUp = () => {
    this.complete();
  };
  startScribble = () => {
    if (this.scribble.tick) {
      this.editor.off("tick", this.scribble?.tick);
    }
    this.scribble = new ScribbleManager({
      onUpdate: this.onScribbleUpdate,
      onComplete: this.onScribbleComplete,
      color: "laser",
      opacity: 0.7,
      size: 4,
      delay: 1200
    });
    this.editor.on("tick", this.scribble.tick);
  };
  pushPointToScribble = () => {
    const { x, y } = this.editor.inputs.currentPagePoint;
    this.scribble.addPoint(x, y);
  };
  onScribbleUpdate = (scribble) => {
    this.editor.updateInstanceState({ scribble });
  };
  onScribbleComplete = () => {
    this.editor.off("tick", this.scribble.tick);
    this.editor.updateInstanceState({ scribble: null });
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  complete() {
    this.parent.transition("idle", {});
  }
  cancel() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/LaserTool/LaserTool.mjs
var LaserTool = class extends StateNode {
  static id = "laser";
  static initial = "idle";
  static children = () => [Idle10, Lasering];
  onEnter = () => {
    this.editor.setCursor({ type: "cross", rotation: 0 });
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Brushing.mjs
var Brushing = class extends StateNode {
  static id = "brushing";
  info = {};
  brush = new Box2d();
  initialSelectedShapeIds = [];
  excludedShapeIds = /* @__PURE__ */ new Set();
  // The shape that the brush started on
  initialStartShape = null;
  onEnter = (info) => {
    const { altKey: altKey2, currentPagePoint } = this.editor.inputs;
    if (altKey2) {
      this.parent.transition("scribble_brushing", info);
      return;
    }
    this.excludedShapeIds = new Set(
      this.editor.currentPageShapes.filter(
        (shape) => this.editor.isShapeOfType(shape, "group") || this.editor.isShapeOrAncestorLocked(shape)
      ).map((shape) => shape.id)
    );
    this.info = info;
    this.initialSelectedShapeIds = this.editor.selectedShapeIds.slice();
    this.initialStartShape = this.editor.getShapesAtPoint(currentPagePoint)[0];
    this.onPointerMove();
  };
  onExit = () => {
    this.initialSelectedShapeIds = [];
    this.editor.updateInstanceState({ brush: null });
  };
  onPointerMove = () => {
    this.hitTestShapes();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = (info) => {
    this.editor.setSelectedShapes(this.initialSelectedShapeIds, { squashing: true });
    this.parent.transition("idle", info);
  };
  onKeyDown = (info) => {
    if (this.editor.inputs.altKey) {
      this.parent.transition("scribble_brushing", info);
    } else {
      this.hitTestShapes();
    }
  };
  onKeyUp = () => {
    this.hitTestShapes();
  };
  complete() {
    this.parent.transition("idle", {});
  }
  hitTestShapes() {
    const {
      zoomLevel,
      currentPageId,
      currentPageShapes,
      inputs: { originPagePoint, currentPagePoint, shiftKey, ctrlKey }
    } = this.editor;
    this.brush.setTo(Box2d.FromPoints([originPagePoint, currentPagePoint]));
    const results = new Set(shiftKey ? this.initialSelectedShapeIds : []);
    let A, B, shape, pageBounds, pageTransform, localCorners;
    const { corners } = this.brush;
    const { excludedShapeIds } = this;
    testAllShapes:
      for (let i = 0, n = currentPageShapes.length; i < n; i++) {
        shape = currentPageShapes[i];
        if (excludedShapeIds.has(shape.id))
          continue testAllShapes;
        if (results.has(shape.id))
          continue testAllShapes;
        pageBounds = this.editor.getShapePageBounds(shape);
        if (!pageBounds)
          continue testAllShapes;
        if (this.brush.contains(pageBounds)) {
          this.handleHit(shape, currentPagePoint, currentPageId, results, corners);
          continue testAllShapes;
        }
        if (ctrlKey || this.editor.isShapeOfType(shape, "frame")) {
          continue testAllShapes;
        }
        if (this.brush.collides(pageBounds)) {
          const geometry = this.editor.getShapeGeometry(shape);
          pageTransform = this.editor.getShapePageTransform(shape);
          if (!pageTransform) {
            continue testAllShapes;
          }
          localCorners = pageTransform.clone().invert().applyToPoints(corners);
          hitTestBrushEdges:
            for (let i2 = 0; i2 < localCorners.length; i2++) {
              A = localCorners[i2];
              B = localCorners[(i2 + 1) % localCorners.length];
              if (geometry.hitTestLineSegment(A, B, HIT_TEST_MARGIN / zoomLevel)) {
                this.handleHit(shape, currentPagePoint, currentPageId, results, corners);
                break hitTestBrushEdges;
              }
            }
        }
      }
    this.editor.updateInstanceState({ brush: { ...this.brush.toJson() } });
    this.editor.setSelectedShapes(Array.from(results), { squashing: true });
  }
  onInterrupt = () => {
    this.editor.updateInstanceState({ brush: null });
  };
  handleHit(shape, currentPagePoint, currentPageId, results, corners) {
    if (shape.parentId === currentPageId) {
      results.add(shape.id);
      return;
    }
    const selectedShape = this.editor.getOutermostSelectableShape(shape);
    const pageMask = this.editor.getShapeMask(selectedShape.id);
    if (pageMask && !polygonsIntersect(pageMask, corners) && !pointInPolygon(currentPagePoint, pageMask)) {
      return;
    }
    results.add(selectedShape.id);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs
function getHitShapeOnCanvasPointerDown(editor) {
  const {
    zoomLevel,
    inputs: { currentPagePoint }
  } = editor;
  return (
    // hovered shape at point
    // selected shape at point
    editor.getShapeAtPoint(currentPagePoint, {
      hitInside: false,
      hitLabels: false,
      margin: HIT_TEST_MARGIN / zoomLevel,
      renderingOnly: true
    }) ?? editor.getSelectedShapeAtPoint(currentPagePoint)
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Crop/children/crop_helpers.mjs
function getTranslateCroppedImageChange(editor, shape, delta) {
  if (!shape) {
    throw Error("Needs to translate a cropped shape!");
  }
  const { crop: oldCrop } = shape.props;
  if (!oldCrop) {
    return;
  }
  const flatten = editor.inputs.shiftKey ? Math.abs(delta.x) < Math.abs(delta.y) ? "x" : "y" : null;
  if (flatten === "x") {
    delta.x = 0;
  } else if (flatten === "y") {
    delta.y = 0;
  }
  delta.rot(-shape.rotation);
  const w = 1 / (oldCrop.bottomRight.x - oldCrop.topLeft.x) * shape.props.w;
  const h = 1 / (oldCrop.bottomRight.y - oldCrop.topLeft.y) * shape.props.h;
  const yCrop = oldCrop.bottomRight.y - oldCrop.topLeft.y;
  const xCrop = oldCrop.bottomRight.x - oldCrop.topLeft.x;
  const newCrop = deepCopy(oldCrop);
  newCrop.topLeft.x = Math.min(1 - xCrop, Math.max(0, newCrop.topLeft.x - delta.x / w));
  newCrop.topLeft.y = Math.min(1 - yCrop, Math.max(0, newCrop.topLeft.y - delta.y / h));
  newCrop.bottomRight.x = newCrop.topLeft.x + xCrop;
  newCrop.bottomRight.y = newCrop.topLeft.y + yCrop;
  const partial = {
    id: shape.id,
    type: shape.type,
    props: {
      crop: newCrop
    }
  };
  return partial;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Crop/children/Idle.mjs
var Idle11 = class extends StateNode {
  static id = "idle";
  onEnter = () => {
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
    const { onlySelectedShape } = this.editor;
    this.editor.on("change-history", this.cleanupCroppingState);
    if (onlySelectedShape) {
      this.editor.mark("crop");
      this.editor.setCroppingShape(onlySelectedShape.id);
    }
  };
  onExit = () => {
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
    this.editor.off("change-history", this.cleanupCroppingState);
  };
  onCancel = () => {
    this.editor.setCroppingShape(null);
    this.editor.setCurrentTool("select.idle", {});
  };
  onPointerDown = (info) => {
    if (this.editor.isMenuOpen)
      return;
    if (info.ctrlKey) {
      this.cancel();
      this.editor.root.handleEvent(info);
      return;
    }
    switch (info.target) {
      case "canvas": {
        const hitShape = getHitShapeOnCanvasPointerDown(this.editor);
        if (hitShape && !this.editor.isShapeOfType(hitShape, "group")) {
          this.onPointerDown({
            ...info,
            shape: hitShape,
            target: "shape"
          });
          return;
        }
        this.cancel();
        this.editor.root.handleEvent(info);
        break;
      }
      case "shape": {
        if (info.shape.id === this.editor.croppingShapeId) {
          this.editor.setCurrentTool("select.crop.pointing_crop", info);
          return;
        } else {
          if (this.editor.getShapeUtil(info.shape)?.canCrop(info.shape)) {
            this.editor.setCroppingShape(info.shape.id);
            this.editor.setSelectedShapes([info.shape.id]);
            this.editor.setCurrentTool("select.crop.pointing_crop", info);
          } else {
            this.cancel();
            this.editor.root.handleEvent(info);
          }
        }
        break;
      }
      case "selection": {
        switch (info.handle) {
          case "mobile_rotate":
          case "top_left_rotate":
          case "top_right_rotate":
          case "bottom_left_rotate":
          case "bottom_right_rotate": {
            this.editor.setCurrentTool("select.pointing_rotate_handle", {
              ...info,
              onInteractionEnd: "select.crop"
            });
            break;
          }
          case "top":
          case "right":
          case "bottom":
          case "left": {
            this.editor.setCurrentTool("select.pointing_crop_handle", {
              ...info,
              onInteractionEnd: "select.crop"
            });
            break;
          }
          case "top_left":
          case "top_right":
          case "bottom_left":
          case "bottom_right": {
            this.editor.setCurrentTool("select.pointing_crop_handle", {
              ...info,
              onInteractionEnd: "select.crop"
            });
            break;
          }
          default: {
            this.cancel();
          }
        }
        break;
      }
    }
  };
  onDoubleClick = (info) => {
    if (this.editor.inputs.shiftKey || info.phase !== "up")
      return;
    if (!this.editor.croppingShapeId)
      return;
    const shape = this.editor.getShape(this.editor.croppingShapeId);
    if (!shape)
      return;
    const util = this.editor.getShapeUtil(shape);
    if (!util)
      return;
    if (info.target === "selection") {
      util.onDoubleClickEdge?.(shape);
    }
  };
  onKeyDown = () => {
    this.nudgeCroppingImage(false);
  };
  onKeyRepeat = () => {
    this.nudgeCroppingImage(true);
  };
  onKeyUp = (info) => {
    switch (info.code) {
      case "Enter": {
        this.editor.setCroppingShape(null);
        this.editor.setCurrentTool("select.idle", {});
        break;
      }
    }
  };
  cancel() {
    this.editor.setCroppingShape(null);
    this.editor.setCurrentTool("select.idle", {});
  }
  cleanupCroppingState = () => {
    if (!this.editor.croppingShapeId) {
      this.editor.setCurrentTool("select.idle", {});
    }
  };
  nudgeCroppingImage(ephemeral = false) {
    const {
      editor: {
        inputs: { keys }
      }
    } = this;
    const shiftKey = keys.has("ShiftLeft");
    const delta = new Vec2d(0, 0);
    if (keys.has("ArrowLeft"))
      delta.x += 1;
    if (keys.has("ArrowRight"))
      delta.x -= 1;
    if (keys.has("ArrowUp"))
      delta.y += 1;
    if (keys.has("ArrowDown"))
      delta.y -= 1;
    if (delta.equals(new Vec2d(0, 0)))
      return;
    if (shiftKey)
      delta.mul(10);
    const shape = this.editor.getShape(this.editor.croppingShapeId);
    if (!shape)
      return;
    const partial = getTranslateCroppedImageChange(this.editor, shape, delta);
    if (partial) {
      if (!ephemeral) {
        this.editor.mark("translate crop");
      }
      this.editor.updateShapes([partial]);
    }
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Crop/children/PointingCrop.mjs
var PointingCrop = class extends StateNode {
  static id = "pointing_crop";
  onCancel = () => {
    this.editor.setCurrentTool("select.crop.idle", {});
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      this.editor.setCurrentTool("select.crop.translating_crop", info);
    }
  };
  onPointerUp = (info) => {
    this.editor.setCurrentTool("select.crop.idle", info);
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Crop/children/TranslatingCrop.mjs
var TranslatingCrop = class extends StateNode {
  static id = "translating_crop";
  info = {};
  markId = "translating crop";
  snapshot = {};
  onEnter = (info) => {
    this.info = info;
    this.snapshot = this.createSnapshot();
    this.editor.mark(this.markId);
    this.editor.setCursor({ type: "move", rotation: 0 });
    this.updateShapes();
  };
  onExit = () => {
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
  };
  onPointerMove = () => {
    this.updateShapes();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onKeyDown = (info) => {
    switch (info.key) {
      case "Alt":
      case "Shift": {
        this.updateShapes();
        return;
      }
    }
  };
  onKeyUp = (info) => {
    switch (info.key) {
      case "Enter": {
        this.complete();
        return;
      }
      case "Alt":
      case "Shift": {
        this.updateShapes();
      }
    }
  };
  complete() {
    this.updateShapes();
    this.editor.setCurrentTool("select.crop.idle", this.info);
  }
  cancel() {
    this.editor.bailToMark(this.markId);
    this.editor.setCurrentTool("select.crop.idle", this.info);
  }
  createSnapshot() {
    const shape = this.editor.onlySelectedShape;
    return { shape };
  }
  updateShapes() {
    const shape = this.snapshot.shape;
    if (!shape)
      return;
    const { originPagePoint, currentPagePoint } = this.editor.inputs;
    const delta = currentPagePoint.clone().sub(originPagePoint);
    const partial = getTranslateCroppedImageChange(this.editor, shape, delta);
    if (partial) {
      this.editor.updateShapes([partial], { squashing: true });
    }
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Crop/Crop.mjs
var Crop = class extends StateNode {
  static id = "crop";
  static initial = "idle";
  static children = () => [Idle11, TranslatingCrop, PointingCrop];
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Crop/crop-constants.mjs
var MIN_CROP_SIZE = 8;

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/PointingResizeHandle.mjs
var CursorTypeMap = {
  bottom: "ns-resize",
  top: "ns-resize",
  left: "ew-resize",
  right: "ew-resize",
  bottom_left: "nesw-resize",
  bottom_right: "nwse-resize",
  top_left: "nwse-resize",
  top_right: "nesw-resize",
  bottom_left_rotate: "swne-rotate",
  bottom_right_rotate: "senw-rotate",
  top_left_rotate: "nwse-rotate",
  top_right_rotate: "nesw-rotate",
  mobile_rotate: "grabbing"
};
var PointingResizeHandle = class extends StateNode {
  static id = "pointing_resize_handle";
  info = {};
  updateCursor() {
    const selected = this.editor.selectedShapes;
    const cursorType = CursorTypeMap[this.info.handle];
    this.editor.updateInstanceState({
      cursor: { type: cursorType, rotation: selected.length === 1 ? selected[0].rotation : 0 }
    });
  }
  onEnter = (info) => {
    this.info = info;
    this.updateCursor();
  };
  onPointerMove = () => {
    const isDragging = this.editor.inputs.isDragging;
    if (isDragging) {
      this.parent.transition("resizing", this.info);
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  // override onPinchStart: TLEventHandlers['onPinchStart'] = (info) => {
  // 	this.parent.transition('pinching', info)
  // }
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  complete() {
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, {});
    } else {
      this.parent.transition("idle", {});
    }
  }
  cancel() {
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, {});
    } else {
      this.parent.transition("idle", {});
    }
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Cropping.mjs
var Cropping = class extends StateNode {
  static id = "cropping";
  info = {};
  markId = "";
  snapshot = {};
  onEnter = (info) => {
    this.info = info;
    this.markId = "cropping";
    this.editor.mark(this.markId);
    this.snapshot = this.createSnapshot();
    this.updateShapes();
  };
  onPointerMove = () => {
    this.updateShapes();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  updateCursor() {
    const selectedShape = this.editor.selectedShapes[0];
    if (!selectedShape)
      return;
    const cursorType = CursorTypeMap[this.info.handle];
    this.editor.updateInstanceState({
      cursor: {
        type: cursorType,
        rotation: selectedShape.rotation
      }
    });
  }
  getDefaultCrop = () => ({
    topLeft: { x: 0, y: 0 },
    bottomRight: { x: 1, y: 1 }
  });
  updateShapes() {
    const { shape, cursorHandleOffset } = this.snapshot;
    if (!shape)
      return;
    const util = this.editor.getShapeUtil("image");
    if (!util)
      return;
    const props = shape.props;
    const currentPagePoint = this.editor.inputs.currentPagePoint.clone().sub(cursorHandleOffset);
    const originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset);
    const change = currentPagePoint.clone().sub(originPagePoint).rot(-shape.rotation);
    const crop = props.crop ?? this.getDefaultCrop();
    const newCrop = deepCopy(crop);
    const newPoint = new Vec2d(shape.x, shape.y);
    const pointDelta = new Vec2d(0, 0);
    const w = 1 / (crop.bottomRight.x - crop.topLeft.x) * props.w;
    const h = 1 / (crop.bottomRight.y - crop.topLeft.y) * props.h;
    let hasCropChanged = false;
    switch (this.info.handle) {
      case "top":
      case "top_left":
      case "top_right": {
        if (h < MIN_CROP_SIZE)
          break;
        hasCropChanged = true;
        newCrop.topLeft.y = newCrop.topLeft.y + change.y / h;
        const heightAfterCrop = h * (newCrop.bottomRight.y - newCrop.topLeft.y);
        if (heightAfterCrop < MIN_CROP_SIZE) {
          newCrop.topLeft.y = newCrop.bottomRight.y - MIN_CROP_SIZE / h;
          pointDelta.y = (newCrop.topLeft.y - crop.topLeft.y) * h;
        } else {
          if (newCrop.topLeft.y <= 0) {
            newCrop.topLeft.y = 0;
            pointDelta.y = (newCrop.topLeft.y - crop.topLeft.y) * h;
          } else {
            pointDelta.y = change.y;
          }
        }
        break;
      }
      case "bottom":
      case "bottom_left":
      case "bottom_right": {
        if (h < MIN_CROP_SIZE)
          break;
        hasCropChanged = true;
        newCrop.bottomRight.y = Math.min(1, newCrop.bottomRight.y + change.y / h);
        const heightAfterCrop = h * (newCrop.bottomRight.y - newCrop.topLeft.y);
        if (heightAfterCrop < MIN_CROP_SIZE) {
          newCrop.bottomRight.y = newCrop.topLeft.y + MIN_CROP_SIZE / h;
        }
        break;
      }
    }
    switch (this.info.handle) {
      case "left":
      case "top_left":
      case "bottom_left": {
        if (w < MIN_CROP_SIZE)
          break;
        hasCropChanged = true;
        newCrop.topLeft.x = newCrop.topLeft.x + change.x / w;
        const widthAfterCrop = w * (newCrop.bottomRight.x - newCrop.topLeft.x);
        if (widthAfterCrop < MIN_CROP_SIZE) {
          newCrop.topLeft.x = newCrop.bottomRight.x - MIN_CROP_SIZE / w;
          pointDelta.x = (newCrop.topLeft.x - crop.topLeft.x) * w;
        } else {
          if (newCrop.topLeft.x <= 0) {
            newCrop.topLeft.x = 0;
            pointDelta.x = (newCrop.topLeft.x - crop.topLeft.x) * w;
          } else {
            pointDelta.x = change.x;
          }
        }
        break;
      }
      case "right":
      case "top_right":
      case "bottom_right": {
        if (w < MIN_CROP_SIZE)
          break;
        hasCropChanged = true;
        newCrop.bottomRight.x = Math.min(1, newCrop.bottomRight.x + change.x / w);
        const widthAfterCrop = w * (newCrop.bottomRight.x - newCrop.topLeft.x);
        if (widthAfterCrop < MIN_CROP_SIZE) {
          newCrop.bottomRight.x = newCrop.topLeft.x + MIN_CROP_SIZE / w;
        }
        break;
      }
    }
    if (!hasCropChanged)
      return;
    newPoint.add(pointDelta.rot(shape.rotation));
    const partial = {
      id: shape.id,
      type: shape.type,
      x: newPoint.x,
      y: newPoint.y,
      props: {
        crop: newCrop,
        w: (newCrop.bottomRight.x - newCrop.topLeft.x) * w,
        h: (newCrop.bottomRight.y - newCrop.topLeft.y) * h
      }
    };
    this.editor.updateShapes([partial], { squashing: true });
    this.updateCursor();
  }
  complete() {
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
    } else {
      this.editor.setCroppingShape(null);
      this.parent.transition("idle", {});
    }
  }
  cancel() {
    this.editor.bailToMark(this.markId);
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
    } else {
      this.editor.setCroppingShape(null);
      this.parent.transition("idle", {});
    }
  }
  createSnapshot() {
    const {
      selectionRotation,
      inputs: { originPagePoint }
    } = this.editor;
    const shape = this.editor.onlySelectedShape;
    const selectionBounds = this.editor.selectionRotatedPageBounds;
    const dragHandlePoint = Vec2d.RotWith(
      selectionBounds.getHandlePoint(this.info.handle),
      selectionBounds.point,
      selectionRotation
    );
    const cursorHandleOffset = Vec2d.Sub(originPagePoint, dragHandlePoint);
    return {
      shape,
      cursorHandleOffset
    };
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/DraggingHandle.mjs
var DraggingHandle = class extends StateNode {
  static id = "dragging_handle";
  shapeId = "";
  initialHandle = {};
  initialAdjacentHandle = null;
  initialPagePoint = {};
  markId = "";
  initialPageTransform;
  initialPageRotation;
  info = {};
  isPrecise = false;
  isPreciseId = null;
  pointingId = null;
  onEnter = (info) => {
    const { shape, isCreating, handle } = info;
    this.info = info;
    this.parent.currentToolIdMask = info.onInteractionEnd;
    this.shapeId = shape.id;
    this.markId = isCreating ? `creating:${shape.id}` : "dragging handle";
    if (!isCreating)
      this.editor.mark(this.markId);
    this.initialHandle = deepCopy(handle);
    this.initialPageTransform = this.editor.getShapePageTransform(shape);
    this.initialPageRotation = this.initialPageTransform.rotation();
    this.initialPagePoint = this.editor.inputs.originPagePoint.clone();
    this.editor.updateInstanceState(
      { cursor: { type: isCreating ? "cross" : "grabbing", rotation: 0 } },
      { ephemeral: true }
    );
    const handles = this.editor.getShapeHandles(shape).sort(sortByIndex2);
    const index2 = handles.findIndex((h) => h.id === info.handle.id);
    this.initialAdjacentHandle = null;
    for (let i = index2 + 1; i < handles.length; i++) {
      const handle2 = handles[i];
      if (handle2.type === "vertex" && handle2.id !== "middle" && handle2.id !== info.handle.id) {
        this.initialAdjacentHandle = handle2;
        break;
      }
    }
    if (!this.initialAdjacentHandle) {
      for (let i = handles.length - 1; i >= 0; i--) {
        const handle2 = handles[i];
        if (handle2.type === "vertex" && handle2.id !== "middle" && handle2.id !== info.handle.id) {
          this.initialAdjacentHandle = handle2;
          break;
        }
      }
    }
    const initialTerminal = shape.props[info.handle.id];
    this.isPrecise = false;
    if (initialTerminal?.type === "binding") {
      this.editor.setHintingShapes([initialTerminal.boundShapeId]);
      this.isPrecise = !Vec2d.Equals(initialTerminal.normalizedAnchor, { x: 0.5, y: 0.5 });
      if (this.isPrecise) {
        this.isPreciseId = initialTerminal.boundShapeId;
      } else {
        this.resetExactTimeout();
      }
    } else {
      this.editor.setHintingShapes([]);
    }
    this.update();
    this.editor.select(this.shapeId);
  };
  // Only relevant to arrows
  exactTimeout = -1;
  // Only relevant to arrows
  resetExactTimeout() {
    if (this.exactTimeout !== -1) {
      this.clearExactTimeout();
    }
    this.exactTimeout = setTimeout(() => {
      if (this.isActive && !this.isPrecise) {
        this.isPrecise = true;
        this.isPreciseId = this.pointingId;
        this.update();
      }
      this.exactTimeout = -1;
    }, 750);
  }
  // Only relevant to arrows
  clearExactTimeout() {
    if (this.exactTimeout !== -1) {
      clearTimeout(this.exactTimeout);
      this.exactTimeout = -1;
    }
  }
  onPointerMove = () => {
    this.update();
  };
  onKeyDown = () => {
    this.update();
  };
  onKeyUp = () => {
    this.update();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onExit = () => {
    this.parent.currentToolIdMask = void 0;
    this.editor.setHintingShapes([]);
    this.editor.snaps.clear();
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
  };
  complete() {
    this.editor.snaps.clear();
    const { onInteractionEnd } = this.info;
    if (this.editor.instanceState.isToolLocked && onInteractionEnd) {
      this.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId });
      return;
    }
    this.parent.transition("idle", {});
  }
  cancel() {
    this.editor.bailToMark(this.markId);
    this.editor.snaps.clear();
    const { onInteractionEnd } = this.info;
    if (onInteractionEnd) {
      this.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId });
      return;
    }
    this.parent.transition("idle", {});
  }
  update() {
    const { editor, shapeId, initialPagePoint } = this;
    const { initialHandle, initialPageRotation, initialAdjacentHandle } = this;
    const {
      user: { isSnapMode },
      hintingShapeIds,
      snaps,
      inputs: { currentPagePoint, shiftKey, ctrlKey, altKey: altKey2, pointerVelocity }
    } = editor;
    const shape = editor.getShape(shapeId);
    if (!shape)
      return;
    const util = editor.getShapeUtil(shape);
    let point = currentPagePoint.clone().sub(initialPagePoint).rot(-initialPageRotation).add(initialHandle);
    if (shiftKey && initialAdjacentHandle && initialHandle.id !== "middle") {
      const angle = Vec2d.Angle(initialAdjacentHandle, point);
      const snappedAngle = snapAngle(angle, 24);
      const angleDifference = snappedAngle - angle;
      point = Vec2d.RotWith(point, initialAdjacentHandle, angleDifference);
    }
    editor.snaps.clear();
    if (initialHandle.canSnap && (isSnapMode ? !ctrlKey : ctrlKey)) {
      const pageTransform = editor.getShapePageTransform(shape.id);
      if (!pageTransform)
        throw Error("Expected a page transform");
      const handleIndex = editor.getShapeHandles(shape).filter(({ type }) => type === "vertex").sort(sortByIndex2).findIndex(({ index: index2 }) => initialHandle.index === index2);
      const additionalSegments = util.getOutlineSegments(shape).map((segment) => Matrix2d.applyToPoints(pageTransform, segment)).filter((_segment, i) => i !== handleIndex - 1 && i !== handleIndex);
      const snapDelta = snaps.getSnappingHandleDelta({
        additionalSegments,
        handlePoint: Matrix2d.applyToPoint(pageTransform, point)
      });
      if (snapDelta) {
        snapDelta.rot(-editor.getShapeParentTransform(shape).rotation());
        point.add(snapDelta);
      }
    }
    const changes = util.onHandleChange?.(shape, {
      handle: {
        ...initialHandle,
        x: point.x,
        y: point.y
      },
      isPrecise: this.isPrecise || altKey2
    });
    const next = { ...shape, ...changes };
    if (initialHandle.canBind) {
      const bindingAfter = next.props[initialHandle.id];
      if (bindingAfter?.type === "binding") {
        if (hintingShapeIds[0] !== bindingAfter.boundShapeId) {
          editor.setHintingShapes([bindingAfter.boundShapeId]);
          this.pointingId = bindingAfter.boundShapeId;
          this.isPrecise = pointerVelocity.len() < 0.5 || altKey2;
          this.isPreciseId = this.isPrecise ? bindingAfter.boundShapeId : null;
          this.resetExactTimeout();
        }
      } else {
        if (hintingShapeIds.length > 0) {
          editor.setHintingShapes([]);
          this.pointingId = null;
          this.isPrecise = false;
          this.isPreciseId = null;
          this.resetExactTimeout();
        }
      }
    }
    if (changes) {
      editor.updateShapes([next], { squashing: true });
    }
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/EditingShape.mjs
var EditingShape = class extends StateNode {
  static id = "editing_shape";
  onEnter = () => {
    const { editingShape } = this.editor;
    if (!editingShape)
      throw Error("Entered editing state without an editing shape");
    updateHoveredId(this.editor);
    this.editor.select(editingShape);
  };
  onExit = () => {
    const { editingShapeId } = this.editor.currentPageState;
    if (!editingShapeId)
      return;
    this.editor.setEditingShape(null);
    const shape = this.editor.getShape(editingShapeId);
    const util = this.editor.getShapeUtil(shape);
    util.onEditEnd?.(shape);
    setTimeout(() => {
      this.editor.updateViewportScreenBounds();
    }, 500);
  };
  onPointerMove = (info) => {
    switch (info.target) {
      case "shape":
      case "canvas": {
        updateHoveredId(this.editor);
        return;
      }
    }
  };
  onPointerDown = (info) => {
    switch (info.target) {
      case "canvas": {
        const hitShape = getHitShapeOnCanvasPointerDown(this.editor);
        if (hitShape) {
          this.onPointerDown({
            ...info,
            shape: hitShape,
            target: "shape"
          });
          return;
        }
        break;
      }
      case "shape": {
        const { shape } = info;
        const { editingShape } = this.editor;
        if (!editingShape) {
          throw Error("Expected an editing shape!");
        }
        if (shape.type === editingShape.type) {
          if (this.editor.isShapeOfType(shape, "geo") || this.editor.isShapeOfType(shape, "arrow")) {
            const geometry = this.editor.getShapeUtil(shape).getGeometry(shape);
            const labelGeometry = geometry.children[1];
            if (labelGeometry) {
              const pointInShapeSpace = this.editor.getPointInShapeSpace(
                shape,
                this.editor.inputs.currentPagePoint
              );
              if (labelGeometry.bounds.containsPoint(pointInShapeSpace)) {
                if (shape.id === editingShape.id) {
                  return;
                } else {
                  this.parent.transition("pointing_shape", info);
                  return;
                }
              }
            }
          } else {
            if (shape.id === editingShape.id) {
              if (this.editor.isShapeOfType(shape, "frame")) {
                this.editor.setEditingShape(null);
              }
            } else {
              this.parent.transition("pointing_shape", info);
              return;
            }
            return;
          }
        } else {
        }
        break;
      }
    }
    this.parent.transition("idle", info);
    this.editor.root.handleEvent(info);
  };
  onComplete = (info) => {
    this.parent.transition("idle", info);
  };
  onCancel = (info) => {
    this.parent.transition("idle", info);
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs
function getShouldEnterCropMode(editor) {
  const { onlySelectedShape } = editor;
  return !!(onlySelectedShape && !editor.isShapeOrAncestorLocked(onlySelectedShape) && editor.getShapeUtil(onlySelectedShape).canCrop(onlySelectedShape));
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs
function selectOnCanvasPointerUp(editor) {
  const { selectedShapeIds } = editor;
  const { shiftKey, altKey: altKey2, currentPagePoint } = editor.inputs;
  const hitShape = editor.getShapeAtPoint(currentPagePoint, {
    hitInside: false,
    margin: HIT_TEST_MARGIN / editor.zoomLevel,
    hitLabels: true,
    renderingOnly: true,
    filter: (shape) => !shape.isLocked
  });
  if (hitShape) {
    const outermostSelectableShape = editor.getOutermostSelectableShape(hitShape);
    if (shiftKey && !altKey2) {
      editor.cancelDoubleClick();
      if (selectedShapeIds.includes(outermostSelectableShape.id)) {
        editor.mark("deselecting shape");
        editor.deselect(outermostSelectableShape);
      } else {
        editor.mark("shift selecting shape");
        editor.setSelectedShapes([...selectedShapeIds, outermostSelectableShape.id]);
      }
    } else {
      let shapeToSelect = void 0;
      if (outermostSelectableShape === hitShape) {
        shapeToSelect = hitShape;
      } else {
        if (outermostSelectableShape.id === editor.focusedGroupId || selectedShapeIds.includes(outermostSelectableShape.id)) {
          shapeToSelect = hitShape;
        } else {
          shapeToSelect = outermostSelectableShape;
        }
      }
      if (shapeToSelect && !selectedShapeIds.includes(shapeToSelect.id)) {
        editor.mark("selecting shape");
        editor.select(shapeToSelect.id);
      }
    }
  } else {
    if (shiftKey) {
      return;
    } else {
      if (selectedShapeIds.length > 0) {
        editor.mark("selecting none");
        editor.selectNone();
      }
      const { focusedGroupId } = editor;
      if (isShapeId(focusedGroupId)) {
        const groupShape = editor.getShape(focusedGroupId);
        if (!editor.isPointInShape(groupShape, currentPagePoint, { margin: 0, hitInside: true })) {
          editor.setFocusedGroup(null);
        }
      }
    }
  }
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Idle.mjs
var Idle12 = class extends StateNode {
  static id = "idle";
  onEnter = () => {
    this.parent.currentToolIdMask = void 0;
    updateHoveredId(this.editor);
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
  };
  onPointerMove = () => {
    updateHoveredId(this.editor);
  };
  onPointerDown = (info) => {
    if (this.editor.isMenuOpen)
      return;
    const shouldEnterCropMode = info.ctrlKey && getShouldEnterCropMode(this.editor);
    if (info.ctrlKey && !shouldEnterCropMode) {
      if (info.target === "shape" && this.isDarwin && this.editor.inputs.keys.has("ControlLeft")) {
        if (!this.editor.isShapeOrAncestorLocked(info.shape)) {
          this.parent.transition("pointing_shape", info);
          return;
        }
      }
      this.parent.transition("brushing", info);
      return;
    }
    switch (info.target) {
      case "canvas": {
        const hitShape = getHitShapeOnCanvasPointerDown(this.editor);
        if (hitShape) {
          this.onPointerDown({
            ...info,
            shape: hitShape,
            target: "shape"
          });
          return;
        }
        const {
          onlySelectedShape,
          selectedShapeIds,
          inputs: { currentPagePoint }
        } = this.editor;
        if (selectedShapeIds.length > 1 || onlySelectedShape && !this.editor.getShapeUtil(onlySelectedShape).hideSelectionBoundsBg(onlySelectedShape)) {
          if (isPointInRotatedSelectionBounds(this.editor, currentPagePoint)) {
            this.onPointerDown({
              ...info,
              target: "selection"
            });
            return;
          }
        }
        this.parent.transition("pointing_canvas", info);
        break;
      }
      case "shape": {
        if (this.editor.isShapeOrAncestorLocked(info.shape))
          break;
        this.parent.transition("pointing_shape", info);
        break;
      }
      case "handle": {
        if (this.editor.instanceState.isReadonly)
          break;
        if (this.editor.inputs.altKey) {
          this.parent.transition("pointing_shape", info);
        } else {
          this.parent.transition("pointing_handle", info);
        }
        break;
      }
      case "selection": {
        switch (info.handle) {
          case "mobile_rotate":
          case "top_left_rotate":
          case "top_right_rotate":
          case "bottom_left_rotate":
          case "bottom_right_rotate": {
            this.parent.transition("pointing_rotate_handle", info);
            break;
          }
          case "top":
          case "right":
          case "bottom":
          case "left": {
            if (shouldEnterCropMode) {
              this.parent.transition("pointing_crop_handle", info);
            } else {
              this.parent.transition("pointing_resize_handle", info);
            }
            break;
          }
          case "top_left":
          case "top_right":
          case "bottom_left":
          case "bottom_right": {
            if (shouldEnterCropMode) {
              this.parent.transition("pointing_crop_handle", info);
            } else {
              this.parent.transition("pointing_resize_handle", info);
            }
            break;
          }
          default: {
            const { hoveredShape } = this.editor;
            if (hoveredShape && !this.editor.selectedShapeIds.includes(hoveredShape.id)) {
              this.onPointerDown({
                ...info,
                shape: hoveredShape,
                target: "shape"
              });
              return;
            }
            this.parent.transition("pointing_selection", info);
          }
        }
        break;
      }
    }
  };
  onDoubleClick = (info) => {
    if (this.editor.inputs.shiftKey || info.phase !== "up")
      return;
    switch (info.target) {
      case "canvas": {
        const { hoveredShape } = this.editor;
        const hitShape = hoveredShape && !this.editor.isShapeOfType(hoveredShape, "group") ? hoveredShape : this.editor.getSelectedShapeAtPoint(this.editor.inputs.currentPagePoint) ?? this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
          margin: HIT_TEST_MARGIN / this.editor.zoomLevel,
          hitInside: false
        });
        const { focusedGroupId } = this.editor;
        if (hitShape) {
          if (this.editor.isShapeOfType(hitShape, "group")) {
            selectOnCanvasPointerUp(this.editor);
            return;
          } else {
            const parent = this.editor.getShape(hitShape.parentId);
            if (parent && this.editor.isShapeOfType(parent, "group")) {
              if (focusedGroupId && parent.id === focusedGroupId) {
              } else {
                selectOnCanvasPointerUp(this.editor);
                return;
              }
            }
          }
          this.onDoubleClick({
            ...info,
            shape: hitShape,
            target: "shape"
          });
          return;
        }
        if (!this.editor.inputs.shiftKey) {
          this.handleDoubleClickOnCanvas(info);
        }
        break;
      }
      case "selection": {
        if (this.editor.instanceState.isReadonly)
          break;
        const { onlySelectedShape } = this.editor;
        if (onlySelectedShape) {
          const util = this.editor.getShapeUtil(onlySelectedShape);
          if (!this.canInteractWithShapeInReadOnly(onlySelectedShape)) {
            return;
          }
          if (info.handle === "right" || info.handle === "left" || info.handle === "top" || info.handle === "bottom") {
            const change = util.onDoubleClickEdge?.(onlySelectedShape);
            if (change) {
              this.editor.mark("double click edge");
              this.editor.updateShapes([change]);
              return;
            }
          }
          if (util.canCrop(onlySelectedShape) && !this.editor.isShapeOrAncestorLocked(onlySelectedShape)) {
            this.parent.transition("crop", info);
            return;
          }
          if (this.shouldStartEditingShape(onlySelectedShape)) {
            this.startEditingShape(onlySelectedShape, info);
          }
        }
        break;
      }
      case "shape": {
        const { shape } = info;
        const util = this.editor.getShapeUtil(shape);
        if (shape.type !== "video" && shape.type !== "embed" && this.editor.instanceState.isReadonly)
          break;
        if (util.onDoubleClick) {
          const change = util.onDoubleClick?.(shape);
          if (change) {
            this.editor.updateShapes([change]);
            return;
          } else if (util.canCrop(shape) && !this.editor.isShapeOrAncestorLocked(shape)) {
            this.editor.mark("select and crop");
            this.editor.select(info.shape?.id);
            this.parent.transition("crop", info);
            return;
          }
        }
        if (this.shouldStartEditingShape(shape)) {
          this.startEditingShape(shape, info);
        } else {
          this.handleDoubleClickOnCanvas(info);
        }
        break;
      }
      case "handle": {
        if (this.editor.instanceState.isReadonly)
          break;
        const { shape, handle } = info;
        const util = this.editor.getShapeUtil(shape);
        const changes = util.onDoubleClickHandle?.(shape, handle);
        if (changes) {
          this.editor.updateShapes([changes]);
        } else {
          if (this.shouldStartEditingShape(shape)) {
            this.startEditingShape(shape, info);
          }
        }
      }
    }
  };
  onRightClick = (info) => {
    switch (info.target) {
      case "canvas": {
        const { hoveredShape } = this.editor;
        const hitShape = hoveredShape && !this.editor.isShapeOfType(hoveredShape, "group") ? hoveredShape : this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
          margin: HIT_TEST_MARGIN / this.editor.zoomLevel,
          hitInside: false,
          hitLabels: true,
          hitFrameInside: false,
          renderingOnly: true
        });
        if (hitShape) {
          this.onRightClick({
            ...info,
            shape: hitShape,
            target: "shape"
          });
          return;
        }
        const {
          onlySelectedShape,
          selectedShapeIds,
          inputs: { currentPagePoint }
        } = this.editor;
        if (selectedShapeIds.length > 1 || onlySelectedShape && !this.editor.getShapeUtil(onlySelectedShape).hideSelectionBoundsBg(onlySelectedShape)) {
          if (isPointInRotatedSelectionBounds(this.editor, currentPagePoint)) {
            this.onRightClick({
              ...info,
              target: "selection"
            });
            return;
          }
        }
        this.editor.selectNone();
        break;
      }
      case "shape": {
        const { selectedShapeIds } = this.editor.currentPageState;
        const { shape } = info;
        const targetShape = this.editor.getOutermostSelectableShape(
          shape,
          (parent) => !selectedShapeIds.includes(parent.id)
        );
        if (!selectedShapeIds.includes(targetShape.id)) {
          this.editor.mark("selecting shape");
          this.editor.setSelectedShapes([targetShape.id]);
        }
        break;
      }
    }
  };
  onCancel = () => {
    if (this.editor.focusedGroupId !== this.editor.currentPageId && this.editor.selectedShapeIds.length > 0) {
      this.editor.popFocusedGroupId();
    } else {
      this.editor.mark("clearing selection");
      this.editor.selectNone();
    }
  };
  onKeyDown = (info) => {
    switch (info.code) {
      case "ArrowLeft":
      case "ArrowRight":
      case "ArrowUp":
      case "ArrowDown": {
        this.nudgeSelectedShapes(false);
        break;
      }
    }
  };
  onKeyRepeat = (info) => {
    switch (info.code) {
      case "ArrowLeft":
      case "ArrowRight":
      case "ArrowUp":
      case "ArrowDown": {
        this.nudgeSelectedShapes(true);
        break;
      }
    }
  };
  onKeyUp = (info) => {
    switch (info.code) {
      case "Enter": {
        const { selectedShapes } = this.editor;
        if (selectedShapes.every((shape) => this.editor.isShapeOfType(shape, "group"))) {
          this.editor.setSelectedShapes(
            selectedShapes.flatMap((shape) => this.editor.getSortedChildIdsForParent(shape.id))
          );
          return;
        }
        const { onlySelectedShape } = this.editor;
        if (onlySelectedShape && this.shouldStartEditingShape(onlySelectedShape)) {
          this.startEditingShape(onlySelectedShape, {
            ...info,
            target: "shape",
            shape: onlySelectedShape
          });
          return;
        }
        if (getShouldEnterCropMode(this.editor)) {
          this.parent.transition("crop", info);
        }
        break;
      }
    }
  };
  shouldStartEditingShape(shape = this.editor.onlySelectedShape) {
    if (!shape)
      return false;
    if (this.editor.isShapeOrAncestorLocked(shape) && shape.type !== "embed")
      return false;
    if (!this.canInteractWithShapeInReadOnly(shape))
      return false;
    return this.editor.getShapeUtil(shape).canEdit(shape);
  }
  startEditingShape(shape, info) {
    if (this.editor.isShapeOrAncestorLocked(shape) && shape.type !== "embed")
      return;
    this.editor.mark("editing shape");
    this.editor.setEditingShape(shape.id);
    this.parent.transition("editing_shape", info);
  }
  isDarwin = window.navigator.userAgent.toLowerCase().indexOf("mac") > -1;
  handleDoubleClickOnCanvas(info) {
    if (this.editor.instanceState.isReadonly)
      return;
    this.editor.mark("creating text shape");
    const id = createShapeId();
    const { x, y } = this.editor.inputs.currentPagePoint;
    this.editor.createShapes([
      {
        id,
        type: "text",
        x,
        y,
        props: {
          text: "",
          autoSize: true
        }
      }
    ]);
    const shape = this.editor.getShape(id);
    if (!shape)
      return;
    const util = this.editor.getShapeUtil(shape);
    if (this.editor.instanceState.isReadonly) {
      if (!util.canEditInReadOnly(shape)) {
        return;
      }
    }
    this.editor.setEditingShape(id);
    this.editor.select(id);
    this.parent.transition("editing_shape", info);
  }
  nudgeSelectedShapes(ephemeral = false) {
    const {
      editor: {
        inputs: { keys }
      }
    } = this;
    const shiftKey = keys.has("ShiftLeft");
    const delta = new Vec2d(0, 0);
    if (keys.has("ArrowLeft"))
      delta.x -= 1;
    if (keys.has("ArrowRight"))
      delta.x += 1;
    if (keys.has("ArrowUp"))
      delta.y -= 1;
    if (keys.has("ArrowDown"))
      delta.y += 1;
    if (delta.equals(new Vec2d(0, 0)))
      return;
    if (!ephemeral)
      this.editor.mark("nudge shapes");
    const { gridSize } = this.editor.documentSettings;
    const step = this.editor.instanceState.isGridMode ? shiftKey ? gridSize * GRID_INCREMENT : gridSize : shiftKey ? MAJOR_NUDGE_FACTOR : MINOR_NUDGE_FACTOR;
    this.editor.nudgeShapes(this.editor.selectedShapeIds, delta.mul(step));
  }
  canInteractWithShapeInReadOnly(shape) {
    if (!this.editor.instanceState.isReadonly)
      return true;
    const util = this.editor.getShapeUtil(shape);
    if (util.canEditInReadOnly(shape))
      return true;
    return false;
  }
};
var MAJOR_NUDGE_FACTOR = 10;
var MINOR_NUDGE_FACTOR = 1;
var GRID_INCREMENT = 5;
function isPointInRotatedSelectionBounds(editor, point) {
  const { selectionRotatedPageBounds: selectionBounds } = editor;
  if (!selectionBounds)
    return false;
  const { selectionRotation } = editor;
  if (!selectionRotation)
    return selectionBounds.containsPoint(point);
  return pointInPolygon(
    point,
    selectionBounds.corners.map((c) => Vec2d.RotWith(c, selectionBounds.point, selectionRotation))
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/PointingCanvas.mjs
var PointingCanvas = class extends StateNode {
  static id = "pointing_canvas";
  onEnter = () => {
    const { inputs } = this.editor;
    if (!inputs.shiftKey) {
      if (this.editor.selectedShapeIds.length > 0) {
        this.editor.mark("selecting none");
        this.editor.selectNone();
      }
    }
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      this.parent.transition("brushing", info);
    }
  };
  onPointerUp = () => {
    selectOnCanvasPointerUp(this.editor);
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onInterrupt = () => {
    this.parent.transition("idle", {});
  };
  complete() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/PointingCropHandle.mjs
var PointingCropHandle = class extends StateNode {
  static id = "pointing_crop_handle";
  info = {};
  updateCursor(shape) {
    const cursorType = CursorTypeMap[this.info.handle];
    this.editor.updateInstanceState({
      cursor: {
        type: cursorType,
        rotation: shape.rotation
      }
    });
  }
  onEnter = (info) => {
    this.info = info;
    this.parent.currentToolIdMask = info.onInteractionEnd;
    const selectedShape = this.editor.selectedShapes[0];
    if (!selectedShape)
      return;
    this.updateCursor(selectedShape);
    this.editor.setCroppingShape(selectedShape.id);
  };
  onExit = () => {
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
    this.parent.currentToolIdMask = void 0;
  };
  onPointerMove = () => {
    const isDragging = this.editor.inputs.isDragging;
    if (isDragging) {
      this.parent.transition("cropping", {
        ...this.info,
        onInteractionEnd: this.info.onInteractionEnd
      });
    }
  };
  onPointerUp = () => {
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
    } else {
      this.editor.setCroppingShape(null);
      this.parent.transition("idle", {});
    }
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  cancel() {
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
    } else {
      this.editor.setCroppingShape(null);
      this.parent.transition("idle", {});
    }
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/PointingHandle.mjs
var PointingHandle = class extends StateNode {
  static id = "pointing_handle";
  info = {};
  onEnter = (info) => {
    this.info = info;
    const initialTerminal = info.shape.props[info.handle.id];
    if (initialTerminal?.type === "binding") {
      this.editor.setHintingShapes([initialTerminal.boundShapeId]);
    }
    this.editor.updateInstanceState(
      { cursor: { type: "grabbing", rotation: 0 } },
      { ephemeral: true }
    );
  };
  onExit = () => {
    this.editor.setHintingShapes([]);
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
  };
  onPointerUp = () => {
    this.parent.transition("idle", this.info);
  };
  onPointerMove = () => {
    if (this.editor.inputs.isDragging) {
      this.parent.transition("dragging_handle", this.info);
    }
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  cancel() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/PointingRotateHandle.mjs
var PointingRotateHandle = class extends StateNode {
  static id = "pointing_rotate_handle";
  info = {};
  updateCursor() {
    const { selectionRotation } = this.editor;
    this.editor.updateInstanceState({
      cursor: {
        type: CursorTypeMap[this.info.handle],
        rotation: selectionRotation
      }
    });
  }
  onEnter = (info) => {
    this.parent.currentToolIdMask = info.onInteractionEnd;
    this.info = info;
    this.updateCursor();
  };
  onExit = () => {
    this.parent.currentToolIdMask = void 0;
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
  };
  onPointerMove = () => {
    const { isDragging } = this.editor.inputs;
    if (isDragging) {
      this.parent.transition("rotating", this.info);
    }
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  complete() {
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, {});
    } else {
      this.parent.transition("idle", {});
    }
  }
  cancel() {
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, {});
    } else {
      this.parent.transition("idle", {});
    }
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/PointingSelection.mjs
var PointingSelection = class extends StateNode {
  static id = "pointing_selection";
  info = {};
  onEnter = (info) => {
    this.info = info;
  };
  onPointerUp = (info) => {
    selectOnCanvasPointerUp(this.editor);
    this.parent.transition("idle", info);
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      if (this.editor.instanceState.isReadonly)
        return;
      this.parent.transition("translating", info);
    }
  };
  onDoubleClick = (info) => {
    const { hoveredShape } = this.editor;
    const hitShape = hoveredShape && !this.editor.isShapeOfType(hoveredShape, "group") ? hoveredShape : this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
      hitInside: true,
      margin: 0,
      renderingOnly: true
    });
    if (hitShape) {
      this.parent.transition("idle", {});
      this.parent.onDoubleClick?.({
        ...info,
        target: "shape",
        shape: this.editor.getShape(hitShape)
      });
      return;
    }
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  cancel() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/PointingShape.mjs
var PointingShape = class extends StateNode {
  static id = "pointing_shape";
  hitShape = {};
  hitShapeForPointerUp = {};
  didSelectOnEnter = false;
  onEnter = (info) => {
    const {
      selectedShapeIds,
      focusedGroupId,
      selectionRotatedPageBounds: selectionBounds,
      inputs: { currentPagePoint, shiftKey, altKey: altKey2 }
    } = this.editor;
    this.hitShape = info.shape;
    const outermostSelectingShape = this.editor.getOutermostSelectableShape(info.shape);
    if (
      // If the shape has an onClick handler
      this.editor.getShapeUtil(info.shape).onClick || // ...or if the shape is the focused layer (e.g. group)
      outermostSelectingShape.id === focusedGroupId || // ...or if the shape is within the selection
      selectedShapeIds.includes(outermostSelectingShape.id) || this.editor.isAncestorSelected(outermostSelectingShape.id) || // ...or if the current point is NOT within the selection bounds
      selectedShapeIds.length > 1 && selectionBounds?.containsPoint(currentPagePoint)
    ) {
      this.didSelectOnEnter = false;
      this.hitShapeForPointerUp = outermostSelectingShape;
      return;
    }
    this.didSelectOnEnter = true;
    if (shiftKey && !altKey2) {
      this.editor.cancelDoubleClick();
      if (!selectedShapeIds.includes(outermostSelectingShape.id)) {
        this.editor.mark("shift selecting shape");
        this.editor.setSelectedShapes([...selectedShapeIds, outermostSelectingShape.id]);
      }
    } else {
      this.editor.mark("selecting shape");
      this.editor.setSelectedShapes([outermostSelectingShape.id]);
    }
  };
  onPointerUp = (info) => {
    const {
      zoomLevel,
      focusedGroupId,
      selectedShapeIds,
      inputs: { currentPagePoint, shiftKey }
    } = this.editor;
    const hitShape = this.editor.getShapeAtPoint(currentPagePoint, {
      margin: HIT_TEST_MARGIN / zoomLevel,
      hitInside: true,
      renderingOnly: true
    }) ?? this.hitShape;
    const selectingShape = hitShape ? this.editor.getOutermostSelectableShape(hitShape) : this.hitShapeForPointerUp;
    if (selectingShape) {
      const util = this.editor.getShapeUtil(selectingShape);
      if (util.onClick) {
        const change = util.onClick?.(selectingShape);
        if (change) {
          this.editor.mark("shape on click");
          this.editor.updateShapes([change]);
          this.parent.transition("idle", info);
          return;
        }
      }
      if (selectingShape.id === focusedGroupId) {
        if (selectedShapeIds.length > 0) {
          this.editor.mark("clearing shape ids");
          this.editor.setSelectedShapes([]);
        } else {
          this.editor.popFocusedGroupId();
        }
        this.parent.transition("idle", info);
        return;
      }
    }
    if (!this.didSelectOnEnter) {
      const outermostSelectableShape = this.editor.getOutermostSelectableShape(
        hitShape,
        // if a group is selected, we want to stop before reaching that group
        // so we can drill down into the group
        (parent) => !selectedShapeIds.includes(parent.id)
      );
      if (selectedShapeIds.includes(outermostSelectableShape.id)) {
        if (shiftKey) {
          this.editor.mark("deselecting on pointer up");
          this.editor.deselect(selectingShape);
        } else {
          if (selectedShapeIds.includes(selectingShape.id)) {
            if (selectedShapeIds.length === 1 && (this.editor.isShapeOfType(selectingShape, "geo") || this.editor.isShapeOfType(selectingShape, "arrow"))) {
              const geometry = this.editor.getShapeGeometry(selectingShape);
              const labelGeometry = geometry.children[1];
              if (labelGeometry) {
                const pointInShapeSpace = this.editor.getPointInShapeSpace(
                  selectingShape,
                  currentPagePoint
                );
                if (labelGeometry.bounds.containsPoint(pointInShapeSpace, 0) && labelGeometry.hitTestPoint(pointInShapeSpace)) {
                  this.editor.batch(() => {
                    this.editor.mark("editing on pointer up");
                    this.editor.select(selectingShape.id);
                    const util = this.editor.getShapeUtil(selectingShape);
                    if (this.editor.instanceState.isReadonly) {
                      if (!util.canEditInReadOnly(selectingShape)) {
                        return;
                      }
                    }
                    this.editor.setEditingShape(selectingShape.id);
                    this.editor.setCurrentTool("select.editing_shape");
                  });
                  return;
                }
              }
            }
            this.editor.mark("selecting on pointer up");
            this.editor.select(selectingShape.id);
          } else {
            this.editor.mark("selecting on pointer up");
            this.editor.select(selectingShape);
          }
        }
      } else if (shiftKey) {
        const ancestors = this.editor.getShapeAncestors(outermostSelectableShape);
        this.editor.mark("shift deselecting on pointer up");
        this.editor.setSelectedShapes([
          ...this.editor.selectedShapeIds.filter((id) => !ancestors.find((a) => a.id === id)),
          outermostSelectableShape.id
        ]);
      } else {
        this.editor.mark("selecting on pointer up");
        this.editor.setSelectedShapes([outermostSelectableShape.id]);
      }
    }
    this.parent.transition("idle", info);
  };
  onPointerMove = (info) => {
    if (this.editor.inputs.isDragging) {
      if (this.editor.instanceState.isReadonly)
        return;
      this.parent.transition("translating", info);
    }
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.cancel();
  };
  onInterrupt = () => {
    this.cancel();
  };
  cancel() {
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Resizing.mjs
var Resizing = class extends StateNode {
  static id = "resizing";
  info = {};
  markId = "";
  // we transition into the resizing state from the geo pointing state, which starts with a shape of size w: 1, h: 1,
  // so if the user drags x: +50, y: +50 after mouseDown, the shape will be w: 51, h: 51, which is too many pixels, alas
  // so we allow passing a further offset into this state to negate such issues
  creationCursorOffset = { x: 0, y: 0 };
  editAfterComplete = false;
  snapshot = {};
  onEnter = (info) => {
    const {
      isCreating = false,
      editAfterComplete = false,
      creationCursorOffset = { x: 0, y: 0 }
    } = info;
    this.info = info;
    this.parent.currentToolIdMask = info.onInteractionEnd;
    this.editAfterComplete = editAfterComplete;
    this.creationCursorOffset = creationCursorOffset;
    if (info.isCreating) {
      this.editor.updateInstanceState(
        { cursor: { type: "cross", rotation: 0 } },
        { ephemeral: true }
      );
    }
    this.snapshot = this._createSnapshot();
    this.markId = isCreating ? `creating:${this.editor.onlySelectedShape.id}` : "starting resizing";
    if (!isCreating)
      this.editor.mark(this.markId);
    this.handleResizeStart();
    this.updateShapes();
  };
  onPointerMove = () => {
    this.updateShapes();
  };
  onKeyDown = () => {
    this.updateShapes();
  };
  onKeyUp = () => {
    this.updateShapes();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  cancel() {
    this.editor.bailToMark(this.markId);
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, {});
    } else {
      this.parent.transition("idle", {});
    }
  }
  complete() {
    this.handleResizeEnd();
    if (this.editAfterComplete && this.editor.onlySelectedShape) {
      this.editor.setEditingShape(this.editor.onlySelectedShape.id);
      this.editor.setCurrentTool("select.editing_shape");
      return;
    }
    if (this.editor.instanceState.isToolLocked && this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, {});
      return;
    }
    this.parent.transition("idle", {});
  }
  handleResizeStart() {
    const { shapeSnapshots } = this.snapshot;
    const changes = [];
    shapeSnapshots.forEach(({ shape }) => {
      const util = this.editor.getShapeUtil(shape);
      const change = util.onResizeStart?.(shape);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
  }
  handleResizeEnd() {
    const { shapeSnapshots } = this.snapshot;
    const changes = [];
    shapeSnapshots.forEach(({ shape }) => {
      const current = this.editor.getShape(shape.id);
      const util = this.editor.getShapeUtil(shape);
      const change = util.onResizeEnd?.(shape, current);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
  }
  updateShapes() {
    const { altKey: altKey2, shiftKey } = this.editor.inputs;
    const {
      shapeSnapshots,
      selectionBounds,
      cursorHandleOffset,
      selectedShapeIds,
      selectionRotation,
      canShapesDeform
    } = this.snapshot;
    const isAspectRatioLocked = shiftKey || !canShapesDeform;
    const { ctrlKey } = this.editor.inputs;
    const currentPagePoint = this.editor.inputs.currentPagePoint.clone().sub(cursorHandleOffset).sub(this.creationCursorOffset);
    const originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset);
    if (this.editor.instanceState.isGridMode && !ctrlKey) {
      const { gridSize } = this.editor.documentSettings;
      currentPagePoint.snapToGrid(gridSize);
    }
    const dragHandle = this.info.handle;
    const scaleOriginHandle = rotateSelectionHandle2(dragHandle, Math.PI);
    this.editor.snaps.clear();
    const shouldSnap = this.editor.user.isSnapMode ? !ctrlKey : ctrlKey;
    if (shouldSnap && selectionRotation % TAU === 0) {
      const { nudge } = this.editor.snaps.snapResize({
        dragDelta: Vec2d.Sub(currentPagePoint, originPagePoint),
        initialSelectionPageBounds: this.snapshot.initialSelectionPageBounds,
        handle: rotateSelectionHandle2(dragHandle, selectionRotation),
        isAspectRatioLocked,
        isResizingFromCenter: altKey2
      });
      currentPagePoint.add(nudge);
    }
    const scaleOriginPage = Vec2d.RotWith(
      altKey2 ? selectionBounds.center : selectionBounds.getHandlePoint(scaleOriginHandle),
      selectionBounds.point,
      selectionRotation
    );
    const distanceFromScaleOriginNow = Vec2d.Sub(currentPagePoint, scaleOriginPage).rot(
      -selectionRotation
    );
    const distanceFromScaleOriginAtStart = Vec2d.Sub(originPagePoint, scaleOriginPage).rot(
      -selectionRotation
    );
    const scale = Vec2d.DivV(distanceFromScaleOriginNow, distanceFromScaleOriginAtStart);
    if (!Number.isFinite(scale.x))
      scale.x = 1;
    if (!Number.isFinite(scale.y))
      scale.y = 1;
    const isXLocked = dragHandle === "top" || dragHandle === "bottom";
    const isYLocked = dragHandle === "left" || dragHandle === "right";
    if (isAspectRatioLocked) {
      if (isYLocked) {
        scale.y = Math.abs(scale.x);
      } else if (isXLocked) {
        scale.x = Math.abs(scale.y);
      } else if (Math.abs(scale.x) > Math.abs(scale.y)) {
        scale.y = Math.abs(scale.x) * (scale.y < 0 ? -1 : 1);
      } else {
        scale.x = Math.abs(scale.y) * (scale.x < 0 ? -1 : 1);
      }
    } else {
      if (isXLocked) {
        scale.x = 1;
      }
      if (isYLocked) {
        scale.y = 1;
      }
    }
    if (!this.info.isCreating) {
      this.updateCursor({
        dragHandle,
        isFlippedX: scale.x < 0,
        isFlippedY: scale.y < 0,
        rotation: selectionRotation
      });
    }
    for (const id of shapeSnapshots.keys()) {
      const snapshot = shapeSnapshots.get(id);
      this.editor.resizeShape(id, scale, {
        initialShape: snapshot.shape,
        initialBounds: snapshot.bounds,
        initialPageTransform: snapshot.pageTransform,
        dragHandle,
        mode: selectedShapeIds.length === 1 && id === selectedShapeIds[0] ? "resize_bounds" : "scale_shape",
        scaleOrigin: scaleOriginPage,
        scaleAxisRotation: selectionRotation
      });
    }
  }
  // ---
  updateCursor({
    dragHandle,
    isFlippedX,
    isFlippedY,
    rotation
  }) {
    const nextCursor = { ...this.editor.instanceState.cursor };
    switch (dragHandle) {
      case "top_left":
      case "bottom_right": {
        nextCursor.type = "nwse-resize";
        if (isFlippedX !== isFlippedY) {
          nextCursor.type = "nesw-resize";
        }
        break;
      }
      case "top_right":
      case "bottom_left": {
        nextCursor.type = "nesw-resize";
        if (isFlippedX !== isFlippedY) {
          nextCursor.type = "nwse-resize";
        }
        break;
      }
    }
    nextCursor.rotation = rotation;
    this.editor.setCursor(nextCursor);
  }
  onExit = () => {
    this.parent.currentToolIdMask = void 0;
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
    this.editor.snaps.clear();
  };
  _createSnapshot = () => {
    const {
      selectedShapeIds,
      selectionRotation,
      inputs: { originPagePoint }
    } = this.editor;
    const selectionBounds = this.editor.selectionRotatedPageBounds;
    const dragHandlePoint = Vec2d.RotWith(
      selectionBounds.getHandlePoint(this.info.handle),
      selectionBounds.point,
      selectionRotation
    );
    const cursorHandleOffset = Vec2d.Sub(originPagePoint, dragHandlePoint);
    const shapeSnapshots = /* @__PURE__ */ new Map();
    selectedShapeIds.forEach((id) => {
      const shape = this.editor.getShape(id);
      if (shape) {
        shapeSnapshots.set(shape.id, this._createShapeSnapshot(shape));
        if (this.editor.isShapeOfType(shape, "frame") && selectedShapeIds.length === 1)
          return;
        this.editor.visitDescendants(shape.id, (descendantId) => {
          const descendent = this.editor.getShape(descendantId);
          if (descendent) {
            shapeSnapshots.set(descendent.id, this._createShapeSnapshot(descendent));
            if (this.editor.isShapeOfType(descendent, "frame")) {
              return false;
            }
          }
        });
      }
    });
    const canShapesDeform = ![...shapeSnapshots.values()].some(
      (shape) => !areAnglesCompatible(shape.pageRotation, selectionRotation) || shape.isAspectRatioLocked
    );
    return {
      shapeSnapshots,
      selectionBounds,
      cursorHandleOffset,
      selectionRotation,
      selectedShapeIds,
      canShapesDeform,
      initialSelectionPageBounds: this.editor.selectionPageBounds
    };
  };
  _createShapeSnapshot = (shape) => {
    const pageTransform = this.editor.getShapePageTransform(shape);
    const util = this.editor.getShapeUtil(shape);
    return {
      shape,
      bounds: this.editor.getShapeGeometry(shape).bounds,
      pageTransform,
      pageRotation: Matrix2d.Decompose(pageTransform).rotation,
      isAspectRatioLocked: util.isAspectRatioLocked(shape)
    };
  };
};
var ORDERED_SELECTION_HANDLES2 = [
  "top",
  "top_right",
  "right",
  "bottom_right",
  "bottom",
  "bottom_left",
  "left",
  "top_left"
];
function rotateSelectionHandle2(handle, rotation) {
  rotation = rotation % PI2;
  const numSteps = Math.round(rotation / (PI / 4));
  const currentIndex = ORDERED_SELECTION_HANDLES2.indexOf(handle);
  return ORDERED_SELECTION_HANDLES2[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES2.length];
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Rotating.mjs
var Rotating = class extends StateNode {
  static id = "rotating";
  snapshot = {};
  info = {};
  markId = "";
  onEnter = (info) => {
    this.info = info;
    this.parent.currentToolIdMask = info.onInteractionEnd;
    this.markId = "rotate start";
    this.editor.mark(this.markId);
    const snapshot = getRotationSnapshot({ editor: this.editor });
    if (!snapshot)
      return this.parent.transition("idle", this.info);
    this.snapshot = snapshot;
    this.handleStart();
  };
  onExit = () => {
    this.editor.setCursor({ type: "default", rotation: 0 });
    this.parent.currentToolIdMask = void 0;
    this.snapshot = {};
  };
  onPointerMove = () => {
    this.update();
  };
  onKeyDown = () => {
    this.update();
  };
  onKeyUp = () => {
    this.update();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  // ---
  update = () => {
    const newSelectionRotation = this._getRotationFromPointerPosition({
      snapToNearestDegree: false
    });
    applyRotationToSnapshotShapes({
      editor: this.editor,
      delta: newSelectionRotation,
      snapshot: this.snapshot,
      stage: "update"
    });
    this.editor.updateInstanceState({
      cursor: {
        type: CursorTypeMap[this.info.handle],
        rotation: newSelectionRotation + this.snapshot.initialSelectionRotation
      }
    });
  };
  cancel = () => {
    this.editor.bailToMark(this.markId);
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
    } else {
      this.parent.transition("idle", this.info);
    }
  };
  complete = () => {
    applyRotationToSnapshotShapes({
      editor: this.editor,
      delta: this._getRotationFromPointerPosition({ snapToNearestDegree: true }),
      snapshot: this.snapshot,
      stage: "end"
    });
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
    } else {
      this.parent.transition("idle", this.info);
    }
  };
  handleStart() {
    const newSelectionRotation = this._getRotationFromPointerPosition({
      snapToNearestDegree: false
    });
    applyRotationToSnapshotShapes({
      editor: this.editor,
      delta: this._getRotationFromPointerPosition({ snapToNearestDegree: false }),
      snapshot: this.snapshot,
      stage: "start"
    });
    this.editor.updateInstanceState({
      cursor: {
        type: CursorTypeMap[this.info.handle],
        rotation: newSelectionRotation + this.snapshot.initialSelectionRotation
      }
    });
  }
  _getRotationFromPointerPosition({ snapToNearestDegree }) {
    const {
      selectionRotatedPageBounds: selectionBounds,
      selectionRotation,
      inputs: { shiftKey, currentPagePoint }
    } = this.editor;
    const { initialCursorAngle, initialSelectionRotation } = this.snapshot;
    if (!selectionBounds)
      return initialSelectionRotation;
    const selectionPageCenter = selectionBounds.center.clone().rotWith(selectionBounds.point, selectionRotation);
    const preSnapRotationDelta = selectionPageCenter.angle(currentPagePoint) - initialCursorAngle;
    let newSelectionRotation = initialSelectionRotation + preSnapRotationDelta;
    if (shiftKey) {
      newSelectionRotation = snapAngle(newSelectionRotation, 24);
    } else if (snapToNearestDegree) {
      newSelectionRotation = Math.round(newSelectionRotation / EPSILON) * EPSILON;
      if (this.editor.instanceState.isCoarsePointer) {
        const snappedToRightAngle = snapAngle(newSelectionRotation, 4);
        const angleToRightAngle = angleDelta(newSelectionRotation, snappedToRightAngle);
        if (Math.abs(angleToRightAngle) < degreesToRadians(5)) {
          newSelectionRotation = snappedToRightAngle;
        }
      }
    }
    return newSelectionRotation - initialSelectionRotation;
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/ScribbleBrushing.mjs
var ScribbleBrushing = class extends StateNode {
  static id = "scribble_brushing";
  hits = /* @__PURE__ */ new Set();
  size = 0;
  scribble = {};
  initialSelectedShapeIds = /* @__PURE__ */ new Set();
  newlySelectedShapeIds = /* @__PURE__ */ new Set();
  onEnter = () => {
    this.initialSelectedShapeIds = new Set(
      this.editor.inputs.shiftKey ? this.editor.selectedShapeIds : []
    );
    this.newlySelectedShapeIds = /* @__PURE__ */ new Set();
    this.size = 0;
    this.hits.clear();
    this.startScribble();
    this.updateScribbleSelection(true);
    requestAnimationFrame(() => {
      this.editor.updateInstanceState({ brush: null });
    });
  };
  onExit = () => {
    this.scribble.stop();
  };
  onPointerMove = () => {
    this.updateScribbleSelection(true);
  };
  onPointerUp = () => {
    this.complete();
  };
  onKeyDown = () => {
    this.updateScribbleSelection(false);
  };
  onKeyUp = () => {
    if (!this.editor.inputs.altKey) {
      this.parent.transition("brushing", {});
    } else {
      this.updateScribbleSelection(false);
    }
  };
  onCancel = () => {
    this.cancel();
  };
  onComplete = () => {
    this.complete();
  };
  startScribble = () => {
    if (this.scribble.tick) {
      this.editor.off("tick", this.scribble?.tick);
    }
    this.scribble = new ScribbleManager({
      onUpdate: this.onScribbleUpdate,
      onComplete: this.onScribbleComplete,
      color: "selection-stroke",
      opacity: 0.32,
      size: 12
    });
    this.editor.on("tick", this.scribble.tick);
  };
  pushPointToScribble = () => {
    const { x, y } = this.editor.inputs.currentPagePoint;
    this.scribble.addPoint(x, y);
  };
  onScribbleUpdate = (scribble) => {
    this.editor.updateInstanceState({ scribble });
  };
  onScribbleComplete = () => {
    this.editor.off("tick", this.scribble.tick);
    this.editor.updateInstanceState({ scribble: null });
  };
  updateScribbleSelection(addPoint) {
    const {
      zoomLevel,
      currentPageShapes,
      inputs: { shiftKey, originPagePoint, previousPagePoint, currentPagePoint }
    } = this.editor;
    const { newlySelectedShapeIds, initialSelectedShapeIds } = this;
    if (addPoint) {
      this.pushPointToScribble();
    }
    const shapes = currentPageShapes;
    let shape, geometry, A, B;
    for (let i = 0, n = shapes.length; i < n; i++) {
      shape = shapes[i];
      geometry = this.editor.getShapeGeometry(shape);
      if (this.editor.isShapeOfType(shape, "group") || newlySelectedShapeIds.has(shape.id) || this.editor.isShapeOrAncestorLocked(shape)) {
        continue;
      }
      if (this.editor.isShapeOfType(shape, "frame")) {
        const point = this.editor.getPointInShapeSpace(shape, originPagePoint);
        if (geometry.bounds.containsPoint(point)) {
          continue;
        }
      }
      A = this.editor.getPointInShapeSpace(shape, previousPagePoint);
      B = this.editor.getPointInShapeSpace(shape, currentPagePoint);
      if (geometry.hitTestLineSegment(A, B, HIT_TEST_MARGIN / zoomLevel)) {
        const outermostShape = this.editor.getOutermostSelectableShape(shape);
        const pageMask = this.editor.getShapeMask(outermostShape.id);
        if (pageMask) {
          const intersection = intersectLineSegmentPolyline(
            previousPagePoint,
            currentPagePoint,
            pageMask
          );
          if (intersection !== null) {
            const isInMask = pointInPolygon(currentPagePoint, pageMask);
            if (!isInMask)
              continue;
          }
        }
        newlySelectedShapeIds.add(outermostShape.id);
      }
    }
    this.editor.setSelectedShapes(
      [
        ...new Set(
          shiftKey ? [...newlySelectedShapeIds, ...initialSelectedShapeIds] : [...newlySelectedShapeIds]
        )
      ],
      { squashing: true }
    );
  }
  complete() {
    this.parent.transition("idle", {});
  }
  cancel() {
    this.editor.setSelectedShapes([...this.initialSelectedShapeIds], { squashing: true });
    this.parent.transition("idle", {});
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs
var LAG_DURATION = 100;
var DragAndDropManager = class {
  constructor(editor) {
    this.editor = editor;
    editor.disposables.add(this.dispose);
  }
  prevDroppingShapeId = null;
  droppingNodeTimer = null;
  first = true;
  updateDroppingNode(movingShapes, cb) {
    if (this.first) {
      this.prevDroppingShapeId = this.editor.getDroppingOverShape(this.editor.inputs.originPagePoint, movingShapes)?.id ?? null;
      this.first = false;
    }
    if (this.droppingNodeTimer === null) {
      this.setDragTimer(movingShapes, LAG_DURATION * 10, cb);
    } else if (this.editor.inputs.pointerVelocity.len() > 0.5) {
      clearInterval(this.droppingNodeTimer);
      this.setDragTimer(movingShapes, LAG_DURATION, cb);
    }
  }
  setDragTimer(movingShapes, duration, cb) {
    this.droppingNodeTimer = setTimeout(() => {
      this.editor.batch(() => {
        this.handleDrag(this.editor.inputs.currentPagePoint, movingShapes, cb);
      });
      this.droppingNodeTimer = null;
    }, duration);
  }
  handleDrag(point, movingShapes, cb) {
    movingShapes = compact(movingShapes.map((shape) => this.editor.getShape(shape.id)));
    const nextDroppingShapeId = this.editor.getDroppingOverShape(point, movingShapes)?.id ?? null;
    if (nextDroppingShapeId === this.prevDroppingShapeId) {
      return;
    }
    const { prevDroppingShapeId } = this;
    const prevDroppingShape = prevDroppingShapeId && this.editor.getShape(prevDroppingShapeId);
    const nextDroppingShape = nextDroppingShapeId && this.editor.getShape(nextDroppingShapeId);
    if (prevDroppingShape) {
      this.editor.getShapeUtil(prevDroppingShape).onDragShapesOut?.(prevDroppingShape, movingShapes);
    }
    if (nextDroppingShape) {
      const res = this.editor.getShapeUtil(nextDroppingShape).onDragShapesOver?.(nextDroppingShape, movingShapes);
      if (res && res.shouldHint) {
        this.editor.setHintingShapes([nextDroppingShape.id]);
      }
    } else {
      this.editor.setHintingShapes([]);
    }
    cb?.();
    this.prevDroppingShapeId = nextDroppingShapeId;
  }
  dropShapes(shapes) {
    const { prevDroppingShapeId } = this;
    this.handleDrag(this.editor.inputs.currentPagePoint, shapes);
    if (prevDroppingShapeId) {
      const shape = this.editor.getShape(prevDroppingShapeId);
      if (!shape)
        return;
      this.editor.getShapeUtil(shape).onDropShapesOver?.(shape, shapes);
    }
  }
  clear() {
    this.prevDroppingShapeId = null;
    if (this.droppingNodeTimer !== null) {
      clearInterval(this.droppingNodeTimer);
    }
    this.droppingNodeTimer = null;
    this.editor.setHintingShapes([]);
    this.first = true;
  }
  dispose = () => {
    this.clear();
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/children/Translating.mjs
var Translating = class extends StateNode {
  static id = "translating";
  info = {};
  selectionSnapshot = {};
  snapshot = {};
  markId = "";
  isCloning = false;
  isCreating = false;
  editAfterComplete = false;
  dragAndDropManager = new DragAndDropManager(this.editor);
  onEnter = (info) => {
    const { isCreating = false, editAfterComplete = false } = info;
    this.info = info;
    this.parent.currentToolIdMask = info.onInteractionEnd;
    this.isCreating = isCreating;
    this.editAfterComplete = editAfterComplete;
    this.markId = isCreating ? `creating:${this.editor.onlySelectedShape.id}` : "translating";
    this.editor.mark(this.markId);
    this.isCloning = false;
    this.info = info;
    this.editor.setCursor({ type: "move", rotation: 0 });
    this.selectionSnapshot = getTranslatingSnapshot(this.editor);
    if (!this.isCreating) {
      if (this.editor.inputs.altKey) {
        this.startCloning();
        return;
      }
    }
    this.snapshot = this.selectionSnapshot;
    this.handleStart();
    this.updateShapes();
    this.editor.on("tick", this.updateParent);
  };
  onExit = () => {
    this.parent.currentToolIdMask = void 0;
    this.editor.off("tick", this.updateParent);
    this.selectionSnapshot = {};
    this.snapshot = {};
    this.editor.snaps.clear();
    this.editor.updateInstanceState(
      { cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
    this.dragAndDropManager.clear();
  };
  onPointerMove = () => {
    this.updateShapes();
  };
  onKeyDown = () => {
    if (this.editor.inputs.altKey && !this.isCloning) {
      this.startCloning();
      return;
    }
    this.updateShapes();
  };
  onKeyUp = () => {
    if (!this.editor.inputs.altKey && this.isCloning) {
      this.stopCloning();
      return;
    }
    this.updateShapes();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  startCloning() {
    if (this.isCreating)
      return;
    this.isCloning = true;
    this.reset();
    this.markId = "translating";
    this.editor.mark(this.markId);
    this.editor.duplicateShapes(Array.from(this.editor.selectedShapeIds));
    this.snapshot = getTranslatingSnapshot(this.editor);
    this.handleStart();
    this.updateShapes();
  }
  stopCloning() {
    this.isCloning = false;
    this.snapshot = this.selectionSnapshot;
    this.reset();
    this.markId = "translating";
    this.editor.mark(this.markId);
    this.updateShapes();
  }
  updateParent = () => {
    const { snapshot } = this;
    this.dragAndDropManager.updateDroppingNode(snapshot.movingShapes, this.updateParentTransforms);
  };
  reset() {
    this.editor.bailToMark(this.markId);
  }
  complete() {
    this.updateShapes();
    this.dragAndDropManager.dropShapes(this.snapshot.movingShapes);
    this.handleEnd();
    if (this.editor.instanceState.isToolLocked && this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd);
    } else {
      if (this.editAfterComplete) {
        const onlySelected = this.editor.onlySelectedShape;
        if (onlySelected) {
          this.editor.setEditingShape(onlySelected.id);
          this.editor.setCurrentTool("select.editing_shape");
        }
      } else {
        this.parent.transition("idle", {});
      }
    }
  }
  cancel() {
    this.reset();
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd);
    } else {
      this.parent.transition("idle", this.info);
    }
  }
  handleStart() {
    const { movingShapes } = this.snapshot;
    const changes = [];
    movingShapes.forEach((shape) => {
      const util = this.editor.getShapeUtil(shape);
      const change = util.onTranslateStart?.(shape);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
    this.editor.setHoveredShape(null);
  }
  handleEnd() {
    const { movingShapes } = this.snapshot;
    const changes = [];
    movingShapes.forEach((shape) => {
      const current = this.editor.getShape(shape.id);
      const util = this.editor.getShapeUtil(shape);
      const change = util.onTranslateEnd?.(shape, current);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
  }
  handleChange() {
    const { movingShapes } = this.snapshot;
    const changes = [];
    movingShapes.forEach((shape) => {
      const current = this.editor.getShape(shape.id);
      const util = this.editor.getShapeUtil(shape);
      const change = util.onTranslate?.(shape, current);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
  }
  updateShapes() {
    const { snapshot } = this;
    this.dragAndDropManager.updateDroppingNode(snapshot.movingShapes, this.updateParentTransforms);
    moveShapesToPoint({
      editor: this.editor,
      shapeSnapshots: snapshot.shapeSnapshots,
      averagePagePoint: snapshot.averagePagePoint,
      initialSelectionPageBounds: snapshot.initialPageBounds,
      initialSelectionSnapPoints: snapshot.initialSnapPoints
    });
    this.handleChange();
  }
  updateParentTransforms = () => {
    const {
      editor,
      snapshot: { shapeSnapshots }
    } = this;
    const movingShapes = [];
    shapeSnapshots.forEach((shapeSnapshot) => {
      const shape = editor.getShape(shapeSnapshot.shape.id);
      if (!shape)
        return null;
      movingShapes.push(shape);
      const parentTransform = isPageId(shape.parentId) ? null : Matrix2d.Inverse(editor.getShapePageTransform(shape.parentId));
      shapeSnapshot.parentTransform = parentTransform;
    });
  };
};
function getTranslatingSnapshot(editor) {
  const movingShapes = [];
  const pagePoints = [];
  const shapeSnapshots = compact(
    editor.selectedShapeIds.map((id) => {
      const shape = editor.getShape(id);
      if (!shape)
        return null;
      movingShapes.push(shape);
      const pagePoint = editor.getShapePageTransform(id).point();
      if (!pagePoint)
        return null;
      pagePoints.push(pagePoint);
      const parentTransform = PageRecordType.isId(shape.parentId) ? null : Matrix2d.Inverse(editor.getShapePageTransform(shape.parentId));
      return {
        shape,
        pagePoint,
        parentTransform
      };
    })
  );
  return {
    averagePagePoint: Vec2d.Average(pagePoints),
    movingShapes,
    shapeSnapshots,
    initialPageBounds: editor.selectionPageBounds,
    initialSnapPoints: editor.selectedShapeIds.length === 1 ? editor.snaps.snapPointsCache.get(editor.selectedShapeIds[0]) : editor.selectionPageBounds ? editor.selectionPageBounds.snapPoints.map((p, i) => ({
      id: "selection:" + i,
      x: p.x,
      y: p.y
    })) : []
  };
}
function moveShapesToPoint({
  editor,
  shapeSnapshots: snapshots,
  averagePagePoint,
  initialSelectionPageBounds,
  initialSelectionSnapPoints
}) {
  const {
    inputs,
    instanceState: { isGridMode },
    documentSettings: { gridSize }
  } = editor;
  const delta = Vec2d.Sub(inputs.currentPagePoint, inputs.originPagePoint);
  const flatten = editor.inputs.shiftKey ? Math.abs(delta.x) < Math.abs(delta.y) ? "x" : "y" : null;
  if (flatten === "x") {
    delta.x = 0;
  } else if (flatten === "y") {
    delta.y = 0;
  }
  editor.snaps.clear();
  const shouldSnap = (editor.user.isSnapMode ? !inputs.ctrlKey : inputs.ctrlKey) && editor.inputs.pointerVelocity.len() < 0.5;
  if (shouldSnap) {
    const { nudge } = editor.snaps.snapTranslate({
      dragDelta: delta,
      initialSelectionPageBounds,
      lockedAxis: flatten,
      initialSelectionSnapPoints
    });
    delta.add(nudge);
  }
  const averageSnappedPoint = Vec2d.Add(averagePagePoint, delta);
  if (isGridMode && !inputs.ctrlKey) {
    averageSnappedPoint.snapToGrid(gridSize);
  }
  const averageSnap = Vec2d.Sub(averageSnappedPoint, averagePagePoint);
  editor.updateShapes(
    compact(
      snapshots.map(({ shape, pagePoint, parentTransform }) => {
        const newPagePoint = Vec2d.Add(pagePoint, averageSnap);
        const newLocalPoint = parentTransform ? Matrix2d.applyToPoint(parentTransform, newPagePoint) : newPagePoint;
        return {
          id: shape.id,
          type: shape.type,
          x: newLocalPoint.x,
          y: newLocalPoint.y
        };
      })
    ),
    { squashing: true }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/SelectTool/SelectTool.mjs
var SelectTool = class extends StateNode {
  static id = "select";
  static initial = "idle";
  static children = () => [
    Crop,
    Cropping,
    Idle12,
    PointingCanvas,
    PointingShape,
    Translating,
    Brushing,
    ScribbleBrushing,
    PointingCropHandle,
    PointingSelection,
    PointingResizeHandle,
    EditingShape,
    Resizing,
    Rotating,
    PointingRotateHandle,
    PointingHandle,
    DraggingHandle
  ];
  onExit = () => {
    if (this.editor.currentPageState.editingShapeId) {
      this.editor.setEditingShape(null);
    }
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/ZoomTool/children/Idle.mjs
var Idle13 = class extends StateNode {
  static id = "idle";
  info = {};
  onEnter = (info) => {
    this.info = info;
  };
  onPointerDown = () => {
    this.parent.transition("pointing", this.info);
  };
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/ZoomTool/children/Pointing.mjs
var Pointing9 = class extends StateNode {
  static id = "pointing";
  info = {};
  onEnter = (info) => {
    this.info = info;
  };
  onPointerUp = () => {
    this.complete();
  };
  onPointerMove = () => {
    if (this.editor.inputs.isDragging) {
      this.parent.transition("zoom_brushing", this.info);
    }
  };
  onCancel = () => {
    this.cancel();
  };
  complete() {
    const { currentScreenPoint } = this.editor.inputs;
    if (this.editor.inputs.altKey) {
      this.editor.zoomOut(currentScreenPoint, { duration: 220 });
    } else {
      this.editor.zoomIn(currentScreenPoint, { duration: 220 });
    }
    this.parent.transition("idle", this.info);
  }
  cancel() {
    this.parent.transition("idle", this.info);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/ZoomTool/children/ZoomBrushing.mjs
var ZoomBrushing = class extends StateNode {
  static id = "zoom_brushing";
  info = {};
  zoomBrush = new Box2d();
  onEnter = (info) => {
    this.info = info;
    this.update();
  };
  onExit = () => {
    this.editor.updateInstanceState({ zoomBrush: null });
  };
  onPointerMove = () => {
    this.update();
  };
  onPointerUp = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  update() {
    const {
      inputs: { originPagePoint, currentPagePoint }
    } = this.editor;
    this.zoomBrush.setTo(Box2d.FromPoints([originPagePoint, currentPagePoint]));
    this.editor.updateInstanceState({ zoomBrush: this.zoomBrush.toJson() });
  }
  cancel() {
    this.parent.transition("idle", this.info);
  }
  complete() {
    const { zoomBrush } = this;
    const threshold = 8 / this.editor.zoomLevel;
    if (zoomBrush.width < threshold && zoomBrush.height < threshold) {
      const point = this.editor.inputs.currentScreenPoint;
      if (this.editor.inputs.altKey) {
        this.editor.zoomOut(point, { duration: 220 });
      } else {
        this.editor.zoomIn(point, { duration: 220 });
      }
    } else {
      const zoomLevel = this.editor.inputs.altKey ? this.editor.zoomLevel / 2 : void 0;
      this.editor.zoomToBounds(zoomBrush, zoomLevel, { duration: 220 });
    }
    this.parent.transition("idle", this.info);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs
var ZoomTool = class extends StateNode {
  static id = "zoom";
  static initial = "idle";
  static children = () => [Idle13, ZoomBrushing, Pointing9];
  info = {};
  onEnter = (info) => {
    this.info = info;
    this.currentToolIdMask = info.onInteractionEnd;
    this.updateCursor();
  };
  onExit = () => {
    this.currentToolIdMask = void 0;
    this.editor.updateInstanceState(
      { zoomBrush: null, cursor: { type: "default", rotation: 0 } },
      { ephemeral: true }
    );
    this.currentToolIdMask = void 0;
  };
  onKeyDown = () => {
    this.updateCursor();
  };
  onKeyUp = (info) => {
    this.updateCursor();
    if (info.code === "KeyZ") {
      this.complete();
    }
  };
  onInterrupt = () => {
    this.complete();
  };
  complete() {
    if (this.info.onInteractionEnd && this.info.onInteractionEnd !== "select") {
      this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
    } else {
      this.parent.transition("select", {});
    }
  }
  updateCursor() {
    if (this.editor.inputs.altKey) {
      this.editor.updateInstanceState(
        { cursor: { type: "zoom-out", rotation: 0 } },
        { ephemeral: true }
      );
    } else {
      this.editor.updateInstanceState(
        { cursor: { type: "zoom-in", rotation: 0 } },
        { ephemeral: true }
      );
    }
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/defaultTools.mjs
var defaultTools = [EraserTool, HandTool, LaserTool, ZoomTool, SelectTool];

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/TldrawUi.mjs
var import_jsx_runtime125 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@radix-ui+react-toast@1.2.15/node_modules/@radix-ui/react-toast/dist/index.mjs
var React36 = __toESM(require_react(), 1);
var ReactDOM = __toESM(require_react_dom(), 1);
var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
var PROVIDER_NAME = "ToastProvider";
var [Collection, useCollection, createCollectionScope] = createCollection("Toast");
var [createToastContext, createToastScope] = createContextScope("Toast", [createCollectionScope]);
var [ToastProviderProvider, useToastProviderContext] = createToastContext(PROVIDER_NAME);
var ToastProvider = (props) => {
  const {
    __scopeToast,
    label = "Notification",
    duration = 5e3,
    swipeDirection = "right",
    swipeThreshold = 50,
    children
  } = props;
  const [viewport, setViewport] = React36.useState(null);
  const [toastCount, setToastCount] = React36.useState(0);
  const isFocusedToastEscapeKeyDownRef = React36.useRef(false);
  const isClosePausedRef = React36.useRef(false);
  if (!label.trim()) {
    console.error(
      `Invalid prop \`label\` supplied to \`${PROVIDER_NAME}\`. Expected non-empty \`string\`.`
    );
  }
  return (0, import_jsx_runtime76.jsx)(Collection.Provider, { scope: __scopeToast, children: (0, import_jsx_runtime76.jsx)(
    ToastProviderProvider,
    {
      scope: __scopeToast,
      label,
      duration,
      swipeDirection,
      swipeThreshold,
      toastCount,
      viewport,
      onViewportChange: setViewport,
      onToastAdd: React36.useCallback(() => setToastCount((prevCount) => prevCount + 1), []),
      onToastRemove: React36.useCallback(() => setToastCount((prevCount) => prevCount - 1), []),
      isFocusedToastEscapeKeyDownRef,
      isClosePausedRef,
      children
    }
  ) });
};
ToastProvider.displayName = PROVIDER_NAME;
var VIEWPORT_NAME = "ToastViewport";
var VIEWPORT_DEFAULT_HOTKEY = ["F8"];
var VIEWPORT_PAUSE = "toast.viewportPause";
var VIEWPORT_RESUME = "toast.viewportResume";
var ToastViewport = React36.forwardRef(
  (props, forwardedRef) => {
    const {
      __scopeToast,
      hotkey = VIEWPORT_DEFAULT_HOTKEY,
      label = "Notifications ({hotkey})",
      ...viewportProps
    } = props;
    const context = useToastProviderContext(VIEWPORT_NAME, __scopeToast);
    const getItems = useCollection(__scopeToast);
    const wrapperRef = React36.useRef(null);
    const headFocusProxyRef = React36.useRef(null);
    const tailFocusProxyRef = React36.useRef(null);
    const ref = React36.useRef(null);
    const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange);
    const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
    const hasToasts = context.toastCount > 0;
    React36.useEffect(() => {
      const handleKeyDown = (event) => {
        const isHotkeyPressed = hotkey.length !== 0 && hotkey.every((key) => event[key] || event.code === key);
        if (isHotkeyPressed)
          ref.current?.focus();
      };
      document.addEventListener("keydown", handleKeyDown);
      return () => document.removeEventListener("keydown", handleKeyDown);
    }, [hotkey]);
    React36.useEffect(() => {
      const wrapper = wrapperRef.current;
      const viewport = ref.current;
      if (hasToasts && wrapper && viewport) {
        const handlePause = () => {
          if (!context.isClosePausedRef.current) {
            const pauseEvent = new CustomEvent(VIEWPORT_PAUSE);
            viewport.dispatchEvent(pauseEvent);
            context.isClosePausedRef.current = true;
          }
        };
        const handleResume = () => {
          if (context.isClosePausedRef.current) {
            const resumeEvent = new CustomEvent(VIEWPORT_RESUME);
            viewport.dispatchEvent(resumeEvent);
            context.isClosePausedRef.current = false;
          }
        };
        const handleFocusOutResume = (event) => {
          const isFocusMovingOutside = !wrapper.contains(event.relatedTarget);
          if (isFocusMovingOutside)
            handleResume();
        };
        const handlePointerLeaveResume = () => {
          const isFocusInside = wrapper.contains(document.activeElement);
          if (!isFocusInside)
            handleResume();
        };
        wrapper.addEventListener("focusin", handlePause);
        wrapper.addEventListener("focusout", handleFocusOutResume);
        wrapper.addEventListener("pointermove", handlePause);
        wrapper.addEventListener("pointerleave", handlePointerLeaveResume);
        window.addEventListener("blur", handlePause);
        window.addEventListener("focus", handleResume);
        return () => {
          wrapper.removeEventListener("focusin", handlePause);
          wrapper.removeEventListener("focusout", handleFocusOutResume);
          wrapper.removeEventListener("pointermove", handlePause);
          wrapper.removeEventListener("pointerleave", handlePointerLeaveResume);
          window.removeEventListener("blur", handlePause);
          window.removeEventListener("focus", handleResume);
        };
      }
    }, [hasToasts, context.isClosePausedRef]);
    const getSortedTabbableCandidates = React36.useCallback(
      ({ tabbingDirection }) => {
        const toastItems = getItems();
        const tabbableCandidates = toastItems.map((toastItem) => {
          const toastNode = toastItem.ref.current;
          const toastTabbableCandidates = [toastNode, ...getTabbableCandidates(toastNode)];
          return tabbingDirection === "forwards" ? toastTabbableCandidates : toastTabbableCandidates.reverse();
        });
        return (tabbingDirection === "forwards" ? tabbableCandidates.reverse() : tabbableCandidates).flat();
      },
      [getItems]
    );
    React36.useEffect(() => {
      const viewport = ref.current;
      if (viewport) {
        const handleKeyDown = (event) => {
          const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
          const isTabKey = event.key === "Tab" && !isMetaKey;
          if (isTabKey) {
            const focusedElement = document.activeElement;
            const isTabbingBackwards = event.shiftKey;
            const targetIsViewport = event.target === viewport;
            if (targetIsViewport && isTabbingBackwards) {
              headFocusProxyRef.current?.focus();
              return;
            }
            const tabbingDirection = isTabbingBackwards ? "backwards" : "forwards";
            const sortedCandidates = getSortedTabbableCandidates({ tabbingDirection });
            const index2 = sortedCandidates.findIndex((candidate) => candidate === focusedElement);
            if (focusFirst(sortedCandidates.slice(index2 + 1))) {
              event.preventDefault();
            } else {
              isTabbingBackwards ? headFocusProxyRef.current?.focus() : tailFocusProxyRef.current?.focus();
            }
          }
        };
        viewport.addEventListener("keydown", handleKeyDown);
        return () => viewport.removeEventListener("keydown", handleKeyDown);
      }
    }, [getItems, getSortedTabbableCandidates]);
    return (0, import_jsx_runtime76.jsxs)(
      Branch,
      {
        ref: wrapperRef,
        role: "region",
        "aria-label": label.replace("{hotkey}", hotkeyLabel),
        tabIndex: -1,
        style: { pointerEvents: hasToasts ? void 0 : "none" },
        children: [
          hasToasts && (0, import_jsx_runtime76.jsx)(
            FocusProxy,
            {
              ref: headFocusProxyRef,
              onFocusFromOutsideViewport: () => {
                const tabbableCandidates = getSortedTabbableCandidates({
                  tabbingDirection: "forwards"
                });
                focusFirst(tabbableCandidates);
              }
            }
          ),
          (0, import_jsx_runtime76.jsx)(Collection.Slot, { scope: __scopeToast, children: (0, import_jsx_runtime76.jsx)(Primitive.ol, { tabIndex: -1, ...viewportProps, ref: composedRefs }) }),
          hasToasts && (0, import_jsx_runtime76.jsx)(
            FocusProxy,
            {
              ref: tailFocusProxyRef,
              onFocusFromOutsideViewport: () => {
                const tabbableCandidates = getSortedTabbableCandidates({
                  tabbingDirection: "backwards"
                });
                focusFirst(tabbableCandidates);
              }
            }
          )
        ]
      }
    );
  }
);
ToastViewport.displayName = VIEWPORT_NAME;
var FOCUS_PROXY_NAME = "ToastFocusProxy";
var FocusProxy = React36.forwardRef(
  (props, forwardedRef) => {
    const { __scopeToast, onFocusFromOutsideViewport, ...proxyProps } = props;
    const context = useToastProviderContext(FOCUS_PROXY_NAME, __scopeToast);
    return (0, import_jsx_runtime76.jsx)(
      VisuallyHidden,
      {
        tabIndex: 0,
        ...proxyProps,
        ref: forwardedRef,
        style: { position: "fixed" },
        onFocus: (event) => {
          const prevFocusedElement = event.relatedTarget;
          const isFocusFromOutsideViewport = !context.viewport?.contains(prevFocusedElement);
          if (isFocusFromOutsideViewport)
            onFocusFromOutsideViewport();
        }
      }
    );
  }
);
FocusProxy.displayName = FOCUS_PROXY_NAME;
var TOAST_NAME = "Toast";
var TOAST_SWIPE_START = "toast.swipeStart";
var TOAST_SWIPE_MOVE = "toast.swipeMove";
var TOAST_SWIPE_CANCEL = "toast.swipeCancel";
var TOAST_SWIPE_END = "toast.swipeEnd";
var Toast = React36.forwardRef(
  (props, forwardedRef) => {
    const { forceMount, open: openProp, defaultOpen, onOpenChange, ...toastProps } = props;
    const [open, setOpen] = useControllableState({
      prop: openProp,
      defaultProp: defaultOpen ?? true,
      onChange: onOpenChange,
      caller: TOAST_NAME
    });
    return (0, import_jsx_runtime76.jsx)(Presence, { present: forceMount || open, children: (0, import_jsx_runtime76.jsx)(
      ToastImpl,
      {
        open,
        ...toastProps,
        ref: forwardedRef,
        onClose: () => setOpen(false),
        onPause: useCallbackRef(props.onPause),
        onResume: useCallbackRef(props.onResume),
        onSwipeStart: composeEventHandlers(props.onSwipeStart, (event) => {
          event.currentTarget.setAttribute("data-swipe", "start");
        }),
        onSwipeMove: composeEventHandlers(props.onSwipeMove, (event) => {
          const { x, y } = event.detail.delta;
          event.currentTarget.setAttribute("data-swipe", "move");
          event.currentTarget.style.setProperty("--radix-toast-swipe-move-x", `${x}px`);
          event.currentTarget.style.setProperty("--radix-toast-swipe-move-y", `${y}px`);
        }),
        onSwipeCancel: composeEventHandlers(props.onSwipeCancel, (event) => {
          event.currentTarget.setAttribute("data-swipe", "cancel");
          event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
          event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
          event.currentTarget.style.removeProperty("--radix-toast-swipe-end-x");
          event.currentTarget.style.removeProperty("--radix-toast-swipe-end-y");
        }),
        onSwipeEnd: composeEventHandlers(props.onSwipeEnd, (event) => {
          const { x, y } = event.detail.delta;
          event.currentTarget.setAttribute("data-swipe", "end");
          event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
          event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
          event.currentTarget.style.setProperty("--radix-toast-swipe-end-x", `${x}px`);
          event.currentTarget.style.setProperty("--radix-toast-swipe-end-y", `${y}px`);
          setOpen(false);
        })
      }
    ) });
  }
);
Toast.displayName = TOAST_NAME;
var [ToastInteractiveProvider, useToastInteractiveContext] = createToastContext(TOAST_NAME, {
  onClose() {
  }
});
var ToastImpl = React36.forwardRef(
  (props, forwardedRef) => {
    const {
      __scopeToast,
      type = "foreground",
      duration: durationProp,
      open,
      onClose,
      onEscapeKeyDown,
      onPause,
      onResume,
      onSwipeStart,
      onSwipeMove,
      onSwipeCancel,
      onSwipeEnd,
      ...toastProps
    } = props;
    const context = useToastProviderContext(TOAST_NAME, __scopeToast);
    const [node, setNode] = React36.useState(null);
    const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
    const pointerStartRef = React36.useRef(null);
    const swipeDeltaRef = React36.useRef(null);
    const duration = durationProp || context.duration;
    const closeTimerStartTimeRef = React36.useRef(0);
    const closeTimerRemainingTimeRef = React36.useRef(duration);
    const closeTimerRef = React36.useRef(0);
    const { onToastAdd, onToastRemove } = context;
    const handleClose = useCallbackRef(() => {
      const isFocusInToast = node?.contains(document.activeElement);
      if (isFocusInToast)
        context.viewport?.focus();
      onClose();
    });
    const startTimer = React36.useCallback(
      (duration2) => {
        if (!duration2 || duration2 === Infinity)
          return;
        window.clearTimeout(closeTimerRef.current);
        closeTimerStartTimeRef.current = (/* @__PURE__ */ new Date()).getTime();
        closeTimerRef.current = window.setTimeout(handleClose, duration2);
      },
      [handleClose]
    );
    React36.useEffect(() => {
      const viewport = context.viewport;
      if (viewport) {
        const handleResume = () => {
          startTimer(closeTimerRemainingTimeRef.current);
          onResume?.();
        };
        const handlePause = () => {
          const elapsedTime = (/* @__PURE__ */ new Date()).getTime() - closeTimerStartTimeRef.current;
          closeTimerRemainingTimeRef.current = closeTimerRemainingTimeRef.current - elapsedTime;
          window.clearTimeout(closeTimerRef.current);
          onPause?.();
        };
        viewport.addEventListener(VIEWPORT_PAUSE, handlePause);
        viewport.addEventListener(VIEWPORT_RESUME, handleResume);
        return () => {
          viewport.removeEventListener(VIEWPORT_PAUSE, handlePause);
          viewport.removeEventListener(VIEWPORT_RESUME, handleResume);
        };
      }
    }, [context.viewport, duration, onPause, onResume, startTimer]);
    React36.useEffect(() => {
      if (open && !context.isClosePausedRef.current)
        startTimer(duration);
    }, [open, duration, context.isClosePausedRef, startTimer]);
    React36.useEffect(() => {
      onToastAdd();
      return () => onToastRemove();
    }, [onToastAdd, onToastRemove]);
    const announceTextContent = React36.useMemo(() => {
      return node ? getAnnounceTextContent(node) : null;
    }, [node]);
    if (!context.viewport)
      return null;
    return (0, import_jsx_runtime76.jsxs)(import_jsx_runtime76.Fragment, { children: [
      announceTextContent && (0, import_jsx_runtime76.jsx)(
        ToastAnnounce,
        {
          __scopeToast,
          role: "status",
          "aria-live": type === "foreground" ? "assertive" : "polite",
          children: announceTextContent
        }
      ),
      (0, import_jsx_runtime76.jsx)(ToastInteractiveProvider, { scope: __scopeToast, onClose: handleClose, children: ReactDOM.createPortal(
        (0, import_jsx_runtime76.jsx)(Collection.ItemSlot, { scope: __scopeToast, children: (0, import_jsx_runtime76.jsx)(
          Root,
          {
            asChild: true,
            onEscapeKeyDown: composeEventHandlers(onEscapeKeyDown, () => {
              if (!context.isFocusedToastEscapeKeyDownRef.current)
                handleClose();
              context.isFocusedToastEscapeKeyDownRef.current = false;
            }),
            children: (0, import_jsx_runtime76.jsx)(
              Primitive.li,
              {
                tabIndex: 0,
                "data-state": open ? "open" : "closed",
                "data-swipe-direction": context.swipeDirection,
                ...toastProps,
                ref: composedRefs,
                style: { userSelect: "none", touchAction: "none", ...props.style },
                onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
                  if (event.key !== "Escape")
                    return;
                  onEscapeKeyDown?.(event.nativeEvent);
                  if (!event.nativeEvent.defaultPrevented) {
                    context.isFocusedToastEscapeKeyDownRef.current = true;
                    handleClose();
                  }
                }),
                onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
                  if (event.button !== 0)
                    return;
                  pointerStartRef.current = { x: event.clientX, y: event.clientY };
                }),
                onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
                  if (!pointerStartRef.current)
                    return;
                  const x = event.clientX - pointerStartRef.current.x;
                  const y = event.clientY - pointerStartRef.current.y;
                  const hasSwipeMoveStarted = Boolean(swipeDeltaRef.current);
                  const isHorizontalSwipe = ["left", "right"].includes(context.swipeDirection);
                  const clamp4 = ["left", "up"].includes(context.swipeDirection) ? Math.min : Math.max;
                  const clampedX = isHorizontalSwipe ? clamp4(0, x) : 0;
                  const clampedY = !isHorizontalSwipe ? clamp4(0, y) : 0;
                  const moveStartBuffer = event.pointerType === "touch" ? 10 : 2;
                  const delta = { x: clampedX, y: clampedY };
                  const eventDetail = { originalEvent: event, delta };
                  if (hasSwipeMoveStarted) {
                    swipeDeltaRef.current = delta;
                    handleAndDispatchCustomEvent(TOAST_SWIPE_MOVE, onSwipeMove, eventDetail, {
                      discrete: false
                    });
                  } else if (isDeltaInDirection(delta, context.swipeDirection, moveStartBuffer)) {
                    swipeDeltaRef.current = delta;
                    handleAndDispatchCustomEvent(TOAST_SWIPE_START, onSwipeStart, eventDetail, {
                      discrete: false
                    });
                    event.target.setPointerCapture(event.pointerId);
                  } else if (Math.abs(x) > moveStartBuffer || Math.abs(y) > moveStartBuffer) {
                    pointerStartRef.current = null;
                  }
                }),
                onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
                  const delta = swipeDeltaRef.current;
                  const target = event.target;
                  if (target.hasPointerCapture(event.pointerId)) {
                    target.releasePointerCapture(event.pointerId);
                  }
                  swipeDeltaRef.current = null;
                  pointerStartRef.current = null;
                  if (delta) {
                    const toast = event.currentTarget;
                    const eventDetail = { originalEvent: event, delta };
                    if (isDeltaInDirection(delta, context.swipeDirection, context.swipeThreshold)) {
                      handleAndDispatchCustomEvent(TOAST_SWIPE_END, onSwipeEnd, eventDetail, {
                        discrete: true
                      });
                    } else {
                      handleAndDispatchCustomEvent(
                        TOAST_SWIPE_CANCEL,
                        onSwipeCancel,
                        eventDetail,
                        {
                          discrete: true
                        }
                      );
                    }
                    toast.addEventListener("click", (event2) => event2.preventDefault(), {
                      once: true
                    });
                  }
                })
              }
            )
          }
        ) }),
        context.viewport
      ) })
    ] });
  }
);
var ToastAnnounce = (props) => {
  const { __scopeToast, children, ...announceProps } = props;
  const context = useToastProviderContext(TOAST_NAME, __scopeToast);
  const [renderAnnounceText, setRenderAnnounceText] = React36.useState(false);
  const [isAnnounced, setIsAnnounced] = React36.useState(false);
  useNextFrame(() => setRenderAnnounceText(true));
  React36.useEffect(() => {
    const timer = window.setTimeout(() => setIsAnnounced(true), 1e3);
    return () => window.clearTimeout(timer);
  }, []);
  return isAnnounced ? null : (0, import_jsx_runtime76.jsx)(Portal, { asChild: true, children: (0, import_jsx_runtime76.jsx)(VisuallyHidden, { ...announceProps, children: renderAnnounceText && (0, import_jsx_runtime76.jsxs)(import_jsx_runtime76.Fragment, { children: [
    context.label,
    " ",
    children
  ] }) }) });
};
var TITLE_NAME = "ToastTitle";
var ToastTitle = React36.forwardRef(
  (props, forwardedRef) => {
    const { __scopeToast, ...titleProps } = props;
    return (0, import_jsx_runtime76.jsx)(Primitive.div, { ...titleProps, ref: forwardedRef });
  }
);
ToastTitle.displayName = TITLE_NAME;
var DESCRIPTION_NAME = "ToastDescription";
var ToastDescription = React36.forwardRef(
  (props, forwardedRef) => {
    const { __scopeToast, ...descriptionProps } = props;
    return (0, import_jsx_runtime76.jsx)(Primitive.div, { ...descriptionProps, ref: forwardedRef });
  }
);
ToastDescription.displayName = DESCRIPTION_NAME;
var ACTION_NAME = "ToastAction";
var ToastAction = React36.forwardRef(
  (props, forwardedRef) => {
    const { altText, ...actionProps } = props;
    if (!altText.trim()) {
      console.error(
        `Invalid prop \`altText\` supplied to \`${ACTION_NAME}\`. Expected non-empty \`string\`.`
      );
      return null;
    }
    return (0, import_jsx_runtime76.jsx)(ToastAnnounceExclude, { altText, asChild: true, children: (0, import_jsx_runtime76.jsx)(ToastClose, { ...actionProps, ref: forwardedRef }) });
  }
);
ToastAction.displayName = ACTION_NAME;
var CLOSE_NAME = "ToastClose";
var ToastClose = React36.forwardRef(
  (props, forwardedRef) => {
    const { __scopeToast, ...closeProps } = props;
    const interactiveContext = useToastInteractiveContext(CLOSE_NAME, __scopeToast);
    return (0, import_jsx_runtime76.jsx)(ToastAnnounceExclude, { asChild: true, children: (0, import_jsx_runtime76.jsx)(
      Primitive.button,
      {
        type: "button",
        ...closeProps,
        ref: forwardedRef,
        onClick: composeEventHandlers(props.onClick, interactiveContext.onClose)
      }
    ) });
  }
);
ToastClose.displayName = CLOSE_NAME;
var ToastAnnounceExclude = React36.forwardRef((props, forwardedRef) => {
  const { __scopeToast, altText, ...announceExcludeProps } = props;
  return (0, import_jsx_runtime76.jsx)(
    Primitive.div,
    {
      "data-radix-toast-announce-exclude": "",
      "data-radix-toast-announce-alt": altText || void 0,
      ...announceExcludeProps,
      ref: forwardedRef
    }
  );
});
function getAnnounceTextContent(container) {
  const textContent = [];
  const childNodes = Array.from(container.childNodes);
  childNodes.forEach((node) => {
    if (node.nodeType === node.TEXT_NODE && node.textContent)
      textContent.push(node.textContent);
    if (isHTMLElement(node)) {
      const isHidden = node.ariaHidden || node.hidden || node.style.display === "none";
      const isExcluded = node.dataset.radixToastAnnounceExclude === "";
      if (!isHidden) {
        if (isExcluded) {
          const altText = node.dataset.radixToastAnnounceAlt;
          if (altText)
            textContent.push(altText);
        } else {
          textContent.push(...getAnnounceTextContent(node));
        }
      }
    }
  });
  return textContent;
}
function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
  const currentTarget = detail.originalEvent.currentTarget;
  const event = new CustomEvent(name, { bubbles: true, cancelable: true, detail });
  if (handler)
    currentTarget.addEventListener(name, handler, { once: true });
  if (discrete) {
    dispatchDiscreteCustomEvent(currentTarget, event);
  } else {
    currentTarget.dispatchEvent(event);
  }
}
var isDeltaInDirection = (delta, direction, threshold = 0) => {
  const deltaX = Math.abs(delta.x);
  const deltaY = Math.abs(delta.y);
  const isDeltaX = deltaX > deltaY;
  if (direction === "left" || direction === "right") {
    return isDeltaX && deltaX > threshold;
  } else {
    return !isDeltaX && deltaY > threshold;
  }
};
function useNextFrame(callback = () => {
}) {
  const fn = useCallbackRef(callback);
  useLayoutEffect2(() => {
    let raf1 = 0;
    let raf2 = 0;
    raf1 = window.requestAnimationFrame(() => raf2 = window.requestAnimationFrame(fn));
    return () => {
      window.cancelAnimationFrame(raf1);
      window.cancelAnimationFrame(raf2);
    };
  }, [fn]);
}
function isHTMLElement(node) {
  return node.nodeType === node.ELEMENT_NODE;
}
function getTabbableCandidates(container) {
  const nodes = [];
  const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
    acceptNode: (node) => {
      const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
      if (node.disabled || node.hidden || isHiddenInput)
        return NodeFilter.FILTER_SKIP;
      return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    }
  });
  while (walker.nextNode())
    nodes.push(walker.currentNode);
  return nodes;
}
function focusFirst(candidates) {
  const previouslyFocusedElement = document.activeElement;
  return candidates.some((candidate) => {
    if (candidate === previouslyFocusedElement)
      return true;
    candidate.focus();
    return document.activeElement !== previouslyFocusedElement;
  });
}
var Root23 = Toast;
var Title2 = ToastTitle;
var Description = ToastDescription;
var Action = ToastAction;
var Close = ToastClose;

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/TldrawUi.mjs
var import_classnames25 = __toESM(require_classnames(), 1);
var import_react109 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/TldrawUiContextProvider.mjs
var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/version.mjs
var version = "2.0.0-alpha.17";

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/assetUrls.mjs
var import_react54 = __toESM(require_react(), 1);
var defaultEditorAssetUrls = {
  fonts: {
    draw: `https://unpkg.com/@tldraw/assets@${version}/fonts/Shantell_Sans-Normal-SemiBold.woff2`,
    serif: `https://unpkg.com/@tldraw/assets@${version}/fonts/IBMPlexSerif-Medium.woff2`,
    sansSerif: `https://unpkg.com/@tldraw/assets@${version}/fonts/IBMPlexSans-Medium.woff2`,
    monospace: `https://unpkg.com/@tldraw/assets@${version}/fonts/IBMPlexMono-Medium.woff2`
  }
};
function setDefaultEditorAssetUrls(assetUrls) {
  defaultEditorAssetUrls = assetUrls;
}
function useDefaultEditorAssetsWithOverrides(overrides) {
  return (0, import_react54.useMemo)(() => {
    if (!overrides)
      return defaultEditorAssetUrls;
    return {
      fonts: { ...defaultEditorAssetUrls.fonts, ...overrides?.fonts }
    };
  }, [overrides]);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/icon-types.mjs
var iconTypes = [
  "align-bottom-center",
  "align-bottom-left",
  "align-bottom-right",
  "align-bottom",
  "align-center-center",
  "align-center-horizontal",
  "align-center-left",
  "align-center-right",
  "align-center-vertical",
  "align-left",
  "align-right",
  "align-top-center",
  "align-top-left",
  "align-top-right",
  "align-top",
  "arrow-left",
  "arrowhead-arrow",
  "arrowhead-bar",
  "arrowhead-diamond",
  "arrowhead-dot",
  "arrowhead-none",
  "arrowhead-square",
  "arrowhead-triangle-inverted",
  "arrowhead-triangle",
  "aspect-ratio",
  "avatar",
  "blob",
  "bring-forward",
  "bring-to-front",
  "check",
  "checkbox-checked",
  "checkbox-empty",
  "chevron-down",
  "chevron-left",
  "chevron-right",
  "chevron-up",
  "chevrons-ne",
  "chevrons-sw",
  "clipboard-copied",
  "clipboard-copy",
  "code",
  "collab",
  "color",
  "comment",
  "cross-2",
  "cross",
  "dash-dashed",
  "dash-dotted",
  "dash-draw",
  "dash-solid",
  "discord",
  "distribute-horizontal",
  "distribute-vertical",
  "dot",
  "dots-horizontal",
  "dots-vertical",
  "drag-handle-dots",
  "duplicate",
  "edit",
  "external-link",
  "file",
  "fill-none",
  "fill-pattern",
  "fill-semi",
  "fill-solid",
  "follow",
  "following",
  "font-draw",
  "font-mono",
  "font-sans",
  "font-serif",
  "geo-arrow-down",
  "geo-arrow-left",
  "geo-arrow-right",
  "geo-arrow-up",
  "geo-check-box",
  "geo-cloud",
  "geo-diamond",
  "geo-ellipse",
  "geo-hexagon",
  "geo-octagon",
  "geo-oval",
  "geo-pentagon",
  "geo-rectangle",
  "geo-rhombus-2",
  "geo-rhombus",
  "geo-star",
  "geo-trapezoid",
  "geo-triangle",
  "geo-x-box",
  "github",
  "group",
  "hidden",
  "image",
  "info-circle",
  "leading",
  "link",
  "lock-small",
  "lock",
  "menu",
  "minus",
  "mixed",
  "pack",
  "page",
  "plus",
  "question-mark-circle",
  "question-mark",
  "redo",
  "reset-zoom",
  "rotate-ccw",
  "rotate-cw",
  "ruler",
  "search",
  "send-backward",
  "send-to-back",
  "settings-horizontal",
  "settings-vertical-1",
  "settings-vertical",
  "share-1",
  "share-2",
  "size-extra-large",
  "size-large",
  "size-medium",
  "size-small",
  "spline-cubic",
  "spline-line",
  "stack-horizontal",
  "stack-vertical",
  "status-offline",
  "status-online",
  "stretch-horizontal",
  "stretch-vertical",
  "text-align-center",
  "text-align-justify",
  "text-align-left",
  "text-align-right",
  "tool-arrow",
  "tool-embed",
  "tool-eraser",
  "tool-frame",
  "tool-hand",
  "tool-highlight",
  "tool-laser",
  "tool-line",
  "tool-media",
  "tool-note",
  "tool-pencil",
  "tool-pointer",
  "tool-text",
  "trash",
  "triangle-down",
  "triangle-up",
  "twitter",
  "undo",
  "ungroup",
  "unlock-small",
  "unlock",
  "vertical-align-center",
  "vertical-align-end",
  "vertical-align-start",
  "visible",
  "warning-triangle",
  "zoom-in",
  "zoom-out"
];

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/assetUrls.mjs
var defaultUiAssetUrls = {
  ...defaultEditorAssetUrls,
  icons: Object.fromEntries(
    iconTypes.map((name) => [
      name,
      `https://unpkg.com/@tldraw/assets@${version}/icons/icon/${name}.svg`
    ])
  ),
  translations: Object.fromEntries(
    LANGUAGES.map((lang) => [
      lang.locale,
      `https://unpkg.com/@tldraw/assets@${version}/translations/${lang.locale}.json`
    ])
  ),
  embedIcons: Object.fromEntries(
    EMBED_DEFINITIONS.map((def) => [
      def.type,
      `https://unpkg.com/@tldraw/assets@${version}/embed-icons/${def.type}.png`
    ])
  )
};
function setDefaultUiAssetUrls(urls) {
  defaultUiAssetUrls = urls;
}
function useDefaultUiAssetUrlsWithOverrides(overrides) {
  if (!overrides)
    return defaultUiAssetUrls;
  return {
    fonts: Object.assign({ ...defaultUiAssetUrls.fonts }, { ...overrides?.fonts }),
    icons: Object.assign({ ...defaultUiAssetUrls.icons }, { ...overrides?.icons }),
    embedIcons: Object.assign({ ...defaultUiAssetUrls.embedIcons }, { ...overrides?.embedIcons }),
    translations: Object.assign(
      { ...defaultUiAssetUrls.translations },
      { ...overrides?.translations }
    )
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useActions.mjs
var import_jsx_runtime82 = __toESM(require_jsx_runtime(), 1);
var React38 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/EditLinkDialog.mjs
var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1);
var import_react55 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Input.mjs
var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
var import_classnames19 = __toESM(require_classnames(), 1);
var React37 = __toESM(require_react(), 1);
var Input = React37.forwardRef(function Input2({
  className,
  label,
  icon,
  iconLeft,
  autoselect = false,
  autofocus = false,
  defaultValue,
  placeholder,
  onComplete,
  onValueChange,
  onCancel,
  onBlur,
  shouldManuallyMaintainScrollPositionWhenFocused = false,
  children,
  value
}, ref) {
  const editor = useEditor();
  const rInputRef = React37.useRef(null);
  React37.useImperativeHandle(ref, () => rInputRef.current);
  const msg2 = useTranslation();
  const rInitialValue = React37.useRef(defaultValue ?? "");
  const rCurrentValue = React37.useRef(defaultValue ?? "");
  const [isFocused, setIsFocused] = React37.useState(false);
  const handleFocus = React37.useCallback(
    (e) => {
      setIsFocused(true);
      const elm = e.currentTarget;
      rCurrentValue.current = elm.value;
      requestAnimationFrame(() => {
        if (autoselect) {
          elm.select();
        }
      });
    },
    [autoselect]
  );
  const handleChange = React37.useCallback(
    (e) => {
      const value2 = e.currentTarget.value;
      rCurrentValue.current = value2;
      onValueChange?.(value2);
    },
    [onValueChange]
  );
  const handleKeyUp = React37.useCallback(
    (e) => {
      switch (e.key) {
        case "Enter": {
          e.currentTarget.blur();
          stopEventPropagation(e);
          onComplete?.(e.currentTarget.value);
          break;
        }
        case "Escape": {
          e.currentTarget.value = rInitialValue.current;
          e.currentTarget.blur();
          stopEventPropagation(e);
          onCancel?.(e.currentTarget.value);
          break;
        }
      }
    },
    [onComplete, onCancel]
  );
  const handleBlur = React37.useCallback(
    (e) => {
      setIsFocused(false);
      const value2 = e.currentTarget.value;
      onBlur?.(value2);
    },
    [onBlur]
  );
  React37.useEffect(() => {
    if (!editor.environment.isIos)
      return;
    const visualViewport = window.visualViewport;
    if (isFocused && shouldManuallyMaintainScrollPositionWhenFocused && visualViewport) {
      const onViewportChange = () => {
        rInputRef.current?.scrollIntoView({ block: "center" });
      };
      visualViewport.addEventListener("resize", onViewportChange);
      visualViewport.addEventListener("scroll", onViewportChange);
      requestAnimationFrame(() => {
        rInputRef.current?.scrollIntoView({ block: "center" });
      });
      return () => {
        visualViewport.removeEventListener("resize", onViewportChange);
        visualViewport.removeEventListener("scroll", onViewportChange);
      };
    }
  }, [editor, isFocused, shouldManuallyMaintainScrollPositionWhenFocused]);
  return (0, import_jsx_runtime77.jsxs)("div", { draggable: false, className: "tlui-input__wrapper", children: [
    children,
    label && (0, import_jsx_runtime77.jsx)("label", { children: msg2(label) }),
    iconLeft && (0, import_jsx_runtime77.jsx)(Icon, { icon: iconLeft, className: "tlui-icon-left", small: true }),
    (0, import_jsx_runtime77.jsx)(
      "input",
      {
        ref: rInputRef,
        className: (0, import_classnames19.default)("tlui-input", className),
        type: "text",
        defaultValue,
        onKeyUp: handleKeyUp,
        onChange: handleChange,
        onFocus: handleFocus,
        onBlur: handleBlur,
        autoFocus: autofocus,
        placeholder,
        value
      }
    ),
    icon && (0, import_jsx_runtime77.jsx)(Icon, { icon, small: !!label })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/EditLinkDialog.mjs
function validateUrl(url) {
  if (isValidUrl(url)) {
    return { isValid: true, hasProtocol: true };
  }
  if (isValidUrl("https://" + url)) {
    return { isValid: true, hasProtocol: false };
  }
  return { isValid: false, hasProtocol: false };
}
var EditLinkDialog = track(function EditLinkDialog2({ onClose }) {
  const editor = useEditor();
  const selectedShape = editor.onlySelectedShape;
  if (!(selectedShape && "url" in selectedShape.props && typeof selectedShape.props.url === "string")) {
    return null;
  }
  return (0, import_jsx_runtime78.jsx)(EditLinkDialogInner, { onClose, selectedShape });
});
var EditLinkDialogInner = track(function EditLinkDialogInner2({
  onClose,
  selectedShape
}) {
  const editor = useEditor();
  const msg2 = useTranslation();
  const rInput = (0, import_react55.useRef)(null);
  (0, import_react55.useEffect)(() => {
    requestAnimationFrame(() => rInput.current?.focus());
  }, []);
  const rInitialValue = (0, import_react55.useRef)(selectedShape.props.url);
  const [urlInputState, setUrlInputState] = (0, import_react55.useState)(() => {
    const urlValidResult = validateUrl(selectedShape.props.url);
    const initialValue = urlValidResult.isValid === true ? urlValidResult.hasProtocol ? selectedShape.props.url : "https://" + selectedShape.props.url : "https://";
    return {
      actual: initialValue,
      safe: initialValue,
      valid: true
    };
  });
  const handleChange = (0, import_react55.useCallback)((rawValue) => {
    const fixedRawValue = rawValue.replace(/https?:\/\/(https?:\/\/)/, (_match, arg1) => {
      return arg1;
    });
    const urlValidResult = validateUrl(fixedRawValue);
    const safeValue = urlValidResult.isValid === true ? urlValidResult.hasProtocol ? fixedRawValue : "https://" + fixedRawValue : "https://";
    setUrlInputState({
      actual: fixedRawValue,
      safe: safeValue,
      valid: urlValidResult.isValid
    });
  }, []);
  const handleClear = (0, import_react55.useCallback)(() => {
    const { onlySelectedShape } = editor;
    if (!onlySelectedShape)
      return;
    editor.updateShapes([
      { id: onlySelectedShape.id, type: onlySelectedShape.type, props: { url: "" } }
    ]);
    onClose();
  }, [editor, onClose]);
  const handleComplete = (0, import_react55.useCallback)(() => {
    const { onlySelectedShape } = editor;
    if (!onlySelectedShape)
      return;
    if (onlySelectedShape && "url" in onlySelectedShape.props) {
      if (onlySelectedShape.props.url !== urlInputState.safe) {
        editor.updateShapes([
          {
            id: onlySelectedShape.id,
            type: onlySelectedShape.type,
            props: { url: urlInputState.safe }
          }
        ]);
      }
    }
    onClose();
  }, [editor, onClose, urlInputState]);
  const handleCancel = (0, import_react55.useCallback)(() => {
    onClose();
  }, [onClose]);
  if (!selectedShape) {
    onClose();
    return null;
  }
  const isRemoving = rInitialValue.current && !urlInputState.valid;
  return (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
    (0, import_jsx_runtime78.jsxs)(Header, { children: [
      (0, import_jsx_runtime78.jsx)(Title, { children: msg2("edit-link-dialog.title") }),
      (0, import_jsx_runtime78.jsx)(CloseButton, {})
    ] }),
    (0, import_jsx_runtime78.jsx)(Body, { children: (0, import_jsx_runtime78.jsxs)("div", { className: "tlui-edit-link-dialog", children: [
      (0, import_jsx_runtime78.jsx)(
        Input,
        {
          ref: rInput,
          className: "tlui-edit-link-dialog__input",
          label: "edit-link-dialog.url",
          autofocus: true,
          value: urlInputState.actual,
          onValueChange: handleChange,
          onComplete: handleComplete,
          onCancel: handleCancel
        }
      ),
      (0, import_jsx_runtime78.jsx)("div", { children: urlInputState.valid ? msg2("edit-link-dialog.detail") : msg2("edit-link-dialog.invalid-url") })
    ] }) }),
    (0, import_jsx_runtime78.jsxs)(Footer, { className: "tlui-dialog__footer__actions", children: [
      (0, import_jsx_runtime78.jsx)(Button, { onClick: handleCancel, onTouchEnd: handleCancel, children: msg2("edit-link-dialog.cancel") }),
      isRemoving ? (0, import_jsx_runtime78.jsx)(Button, { type: "danger", onTouchEnd: handleClear, onClick: handleClear, children: msg2("edit-link-dialog.clear") }) : (0, import_jsx_runtime78.jsx)(
        Button,
        {
          type: "primary",
          disabled: !urlInputState.valid,
          onTouchEnd: handleComplete,
          onClick: handleComplete,
          children: msg2("edit-link-dialog.save")
        }
      )
    ] })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/EmbedDialog.mjs
var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
var import_react56 = __toESM(require_react(), 1);
var EmbedDialog = track(function EmbedDialog2({ onClose }) {
  const editor = useEditor();
  const msg2 = useTranslation();
  const assetUrls = useAssetUrls();
  const [embedDefinition, setEmbedDefinition] = (0, import_react56.useState)(null);
  const [url, setUrl] = (0, import_react56.useState)("");
  const [embedInfoForUrl, setEmbedInfoForUrl] = (0, import_react56.useState)(null);
  const [showError, setShowError] = (0, import_react56.useState)(false);
  const rShowErrorTimeout = (0, import_react56.useRef)(-1);
  return (0, import_jsx_runtime79.jsxs)(import_jsx_runtime79.Fragment, { children: [
    (0, import_jsx_runtime79.jsxs)(Header, { children: [
      (0, import_jsx_runtime79.jsx)(Title, { children: embedDefinition ? `${msg2("embed-dialog.title")} — ${embedDefinition.title}` : msg2("embed-dialog.title") }),
      (0, import_jsx_runtime79.jsx)(CloseButton, {})
    ] }),
    embedDefinition ? (0, import_jsx_runtime79.jsxs)(import_jsx_runtime79.Fragment, { children: [
      (0, import_jsx_runtime79.jsxs)(Body, { className: "tlui-embed-dialog__enter", children: [
        (0, import_jsx_runtime79.jsx)(
          Input,
          {
            className: "tlui-embed-dialog__input",
            label: "embed-dialog.url",
            placeholder: "http://example.com",
            autofocus: true,
            onValueChange: (value) => {
              setUrl(value);
              const embedInfo = getEmbedInfo(value);
              setEmbedInfoForUrl(
                embedInfo && embedInfo.definition.type === embedDefinition.type ? embedInfo : null
              );
              setShowError(false);
              clearTimeout(rShowErrorTimeout.current);
              rShowErrorTimeout.current = setTimeout(() => setShowError(!embedInfo), 320);
            }
          }
        ),
        url === "" ? (0, import_jsx_runtime79.jsxs)("div", { className: "tlui-embed-dialog__instruction", children: [
          (0, import_jsx_runtime79.jsx)("span", { children: msg2("embed-dialog.instruction") }),
          " ",
          embedDefinition.instructionLink && (0, import_jsx_runtime79.jsxs)(
            "a",
            {
              target: "_blank",
              rel: "noopener noreferrer",
              href: embedDefinition.instructionLink,
              className: "tlui-embed-dialog__instruction__link",
              children: [
                "Learn more.",
                (0, import_jsx_runtime79.jsx)(Icon, { icon: "external-link", small: true })
              ]
            }
          )
        ] }) : (0, import_jsx_runtime79.jsx)("div", { className: "tlui-embed-dialog__warning", children: showError ? msg2("embed-dialog.invalid-url") : " " })
      ] }),
      (0, import_jsx_runtime79.jsxs)(Footer, { className: "tlui-dialog__footer__actions", children: [
        (0, import_jsx_runtime79.jsx)(
          Button,
          {
            onClick: () => {
              setEmbedDefinition(null);
              setEmbedInfoForUrl(null);
              setUrl("");
            },
            label: "embed-dialog.back"
          }
        ),
        (0, import_jsx_runtime79.jsx)("div", { className: "tlui-embed__spacer" }),
        (0, import_jsx_runtime79.jsx)(Button, { label: "embed-dialog.cancel", onClick: onClose }),
        (0, import_jsx_runtime79.jsx)(
          Button,
          {
            type: "primary",
            disabled: !embedInfoForUrl,
            label: "embed-dialog.create",
            onClick: () => {
              if (!embedInfoForUrl)
                return;
              editor.putExternalContent({
                type: "embed",
                url,
                point: editor.viewportPageCenter,
                embed: embedInfoForUrl.definition
              });
              onClose();
            }
          }
        )
      ] })
    ] }) : (0, import_jsx_runtime79.jsxs)(import_jsx_runtime79.Fragment, { children: [
      (0, import_jsx_runtime79.jsx)(Body, { className: "tlui-embed-dialog__list", children: EMBED_DEFINITIONS.map((def) => {
        return (0, import_jsx_runtime79.jsxs)(
          "button",
          {
            className: "tlui-embed-dialog__item",
            onClick: () => setEmbedDefinition(def),
            children: [
              (0, import_jsx_runtime79.jsx)("div", { className: "tlui-embed-dialog__item__image", children: (0, import_jsx_runtime79.jsx)(
                "div",
                {
                  className: "tlui-embed-dialog__item__image__img",
                  style: {
                    backgroundImage: `url(${assetUrls.embedIcons[def.type]})`
                  }
                }
              ) }),
              (0, import_jsx_runtime79.jsx)("div", { className: "tlui-embed-dialog__item__title", children: def.title })
            ]
          },
          def.type
        );
      }) }),
      (0, import_jsx_runtime79.jsx)("div", { className: "tlui-dialog__scrim" })
    ] })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs
var import_lz_string = __toESM(require_lz_string(), 1);
var import_react57 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/clipboard/pasteExcalidrawContent.mjs
async function pasteExcalidrawContent(editor, clipboard, point) {
  const { elements, files } = clipboard;
  const tldrawContent = {
    shapes: [],
    rootShapeIds: [],
    assets: [],
    schema: editor.store.schema.serialize()
  };
  const groupShapeIdToChildren = /* @__PURE__ */ new Map();
  const rotatedElements = /* @__PURE__ */ new Map();
  const { currentPageId } = editor;
  const excElementIdsToTldrawShapeIds = /* @__PURE__ */ new Map();
  const rootShapeIds = [];
  const skipIds = /* @__PURE__ */ new Set();
  elements.forEach((element) => {
    excElementIdsToTldrawShapeIds.set(element.id, createShapeId());
    if (element.boundElements !== null) {
      for (const boundElement of element.boundElements) {
        if (boundElement.type === "text") {
          skipIds.add(boundElement.id);
        }
      }
    }
  });
  let index2 = "a1";
  for (const element of elements) {
    if (skipIds.has(element.id)) {
      continue;
    }
    const id = excElementIdsToTldrawShapeIds.get(element.id);
    const base = {
      id,
      typeName: "shape",
      parentId: currentPageId,
      index: index2,
      x: element.x,
      y: element.y,
      rotation: 0,
      isLocked: element.locked,
      opacity: getOpacity(element.opacity),
      meta: {}
    };
    if (element.angle !== 0) {
      rotatedElements.set(id, element.angle);
    }
    if (element.groupIds && element.groupIds.length > 0) {
      if (groupShapeIdToChildren.has(element.groupIds[0])) {
        groupShapeIdToChildren.get(element.groupIds[0])?.push(id);
      } else {
        groupShapeIdToChildren.set(element.groupIds[0], [id]);
      }
    } else {
      rootShapeIds.push(id);
    }
    switch (element.type) {
      case "rectangle":
      case "ellipse":
      case "diamond": {
        let text = "";
        let align = "middle";
        if (element.boundElements !== null) {
          for (const boundElement of element.boundElements) {
            if (boundElement.type === "text") {
              const labelElement = elements.find((elm) => elm.id === boundElement.id);
              if (labelElement) {
                text = labelElement.text;
                align = textAlignToAlignTypes[labelElement.textAlign];
              }
            }
          }
        }
        const colorToUse = element.backgroundColor === "transparent" ? element.strokeColor : element.backgroundColor;
        tldrawContent.shapes.push({
          ...base,
          type: "geo",
          props: {
            geo: element.type,
            url: element.link ?? "",
            w: element.width,
            h: element.height,
            size: strokeWidthsToSizes[element.strokeWidth] ?? "draw",
            color: colorsToColors[colorToUse] ?? "black",
            text,
            align,
            dash: getDash(element),
            fill: getFill(element)
          }
        });
        break;
      }
      case "freedraw": {
        tldrawContent.shapes.push({
          ...base,
          type: "draw",
          props: {
            dash: getDash(element),
            size: strokeWidthsToSizes[element.strokeWidth],
            color: colorsToColors[element.strokeColor] ?? "black",
            segments: [
              {
                type: "free",
                points: element.points.map(([x, y, z = 0.5]) => ({
                  x,
                  y,
                  z
                }))
              }
            ]
          }
        });
        break;
      }
      case "line": {
        const start = element.points[0];
        const end = element.points[element.points.length - 1];
        const indices = getIndices(element.points.length);
        tldrawContent.shapes.push({
          ...base,
          type: "line",
          props: {
            dash: getDash(element),
            size: strokeWidthsToSizes[element.strokeWidth],
            color: colorsToColors[element.strokeColor] ?? "black",
            spline: element.roundness ? "cubic" : "line",
            handles: {
              start: {
                id: "start",
                type: "vertex",
                index: indices[0],
                x: start[0],
                y: start[1]
              },
              end: {
                id: "end",
                type: "vertex",
                index: indices[indices.length - 1],
                x: end[0],
                y: end[1]
              },
              ...Object.fromEntries(
                element.points.slice(1, -1).map(([x, y], i) => {
                  const id2 = uniqueId();
                  return [
                    id2,
                    {
                      id: id2,
                      type: "vertex",
                      index: indices[i + 1],
                      x,
                      y
                    }
                  ];
                })
              )
            }
          }
        });
        break;
      }
      case "arrow": {
        let text = "";
        if (element.boundElements !== null) {
          for (const boundElement of element.boundElements) {
            if (boundElement.type === "text") {
              const labelElement = elements.find((elm) => elm.id === boundElement.id);
              if (labelElement) {
                text = labelElement.text;
              }
            }
          }
        }
        const start = element.points[0];
        const end = element.points[element.points.length - 1];
        const startTargetId = excElementIdsToTldrawShapeIds.get(element.startBinding?.elementId);
        const endTargetId = excElementIdsToTldrawShapeIds.get(element.endBinding?.elementId);
        tldrawContent.shapes.push({
          ...base,
          type: "arrow",
          props: {
            text,
            bend: getBend(element, start, end),
            dash: getDash(element),
            size: strokeWidthsToSizes[element.strokeWidth] ?? "m",
            color: colorsToColors[element.strokeColor] ?? "black",
            start: startTargetId ? {
              type: "binding",
              boundShapeId: startTargetId,
              normalizedAnchor: { x: 0.5, y: 0.5 },
              isExact: false
            } : {
              type: "point",
              x: start[0],
              y: start[1]
            },
            end: endTargetId ? {
              type: "binding",
              boundShapeId: endTargetId,
              normalizedAnchor: { x: 0.5, y: 0.5 },
              isExact: false
            } : {
              type: "point",
              x: end[0],
              y: end[1]
            },
            arrowheadEnd: arrowheadsToArrowheadTypes[element.endArrowhead] ?? "none",
            arrowheadStart: arrowheadsToArrowheadTypes[element.startArrowhead] ?? "none"
          }
        });
        break;
      }
      case "text": {
        const { size: size2, scale } = getFontSizeAndScale(element.fontSize);
        tldrawContent.shapes.push({
          ...base,
          type: "text",
          props: {
            size: size2,
            scale,
            font: fontFamilyToFontType[element.fontFamily] ?? "draw",
            color: colorsToColors[element.strokeColor] ?? "black",
            text: element.text,
            align: textAlignToAlignTypes[element.textAlign]
          }
        });
        break;
      }
      case "image": {
        const file = files[element.fileId];
        if (!file)
          break;
        const assetId = AssetRecordType.createId();
        tldrawContent.assets.push({
          id: assetId,
          typeName: "asset",
          type: "image",
          props: {
            w: element.width,
            h: element.height,
            name: element.id ?? "Untitled",
            isAnimated: false,
            mimeType: file.mimeType,
            src: file.dataURL
          },
          meta: {}
        });
        tldrawContent.shapes.push({
          ...base,
          type: "image",
          props: {
            w: element.width,
            h: element.height,
            assetId
          }
        });
      }
    }
    index2 = getIndexAbove(index2);
  }
  const p = point ?? (editor.inputs.shiftKey ? editor.inputs.currentPagePoint : void 0);
  editor.mark("paste");
  editor.putContentOntoCurrentPage(tldrawContent, {
    point: p,
    select: false,
    preserveIds: true
  });
  for (const groupedShapeIds of groupShapeIdToChildren.values()) {
    if (groupedShapeIds.length > 1) {
      editor.groupShapes(groupedShapeIds);
      const groupShape = editor.getShape(groupedShapeIds[0]);
      if (groupShape?.parentId && isShapeId(groupShape.parentId)) {
        rootShapeIds.push(groupShape.parentId);
      }
    }
  }
  for (const [id, angle] of rotatedElements) {
    editor.select(id);
    editor.rotateShapesBy([id], angle);
  }
  const rootShapes = compact(rootShapeIds.map((id) => editor.getShape(id)));
  const bounds = Box2d.Common(rootShapes.map((s) => editor.getShapePageBounds(s)));
  const viewPortCenter = editor.viewportPageBounds.center;
  editor.updateShapes(
    rootShapes.map((s) => {
      const delta = {
        x: (s.x ?? 0) - (bounds.x + bounds.w / 2),
        y: (s.y ?? 0) - (bounds.y + bounds.h / 2)
      };
      return {
        id: s.id,
        type: s.type,
        x: viewPortCenter.x + delta.x,
        y: viewPortCenter.y + delta.y
      };
    })
  );
  editor.setSelectedShapes(rootShapeIds);
}
var getOpacity = (opacity) => {
  const t2 = opacity / 100;
  if (t2 < 0.2) {
    return 0.1;
  } else if (t2 < 0.4) {
    return 0.25;
  } else if (t2 < 0.6) {
    return 0.5;
  } else if (t2 < 0.8) {
    return 0.75;
  }
  return 1;
};
var strokeWidthsToSizes = {
  1: "s",
  2: "m",
  3: "l",
  4: "xl"
};
var fontSizesToSizes = {
  16: "s",
  20: "m",
  28: "l",
  36: "xl"
};
function getFontSizeAndScale(fontSize) {
  const size2 = fontSizesToSizes[fontSize];
  if (size2) {
    return { size: size2, scale: 1 };
  }
  if (fontSize < 16) {
    return { size: "s", scale: fontSize / 16 };
  }
  if (fontSize > 36) {
    return { size: "xl", scale: fontSize / 36 };
  }
  return { size: "m", scale: 1 };
}
var fontFamilyToFontType = {
  1: "draw",
  2: "sans",
  3: "mono"
};
var colorsToColors = {
  "#ffffff": "grey",
  // Strokes
  "#000000": "black",
  "#343a40": "black",
  "#495057": "grey",
  "#c92a2a": "red",
  "#a61e4d": "light-red",
  "#862e9c": "violet",
  "#5f3dc4": "light-violet",
  "#364fc7": "blue",
  "#1864ab": "light-blue",
  "#0b7285": "light-green",
  "#087f5b": "light-green",
  "#2b8a3e": "green",
  "#5c940d": "light-green",
  "#e67700": "yellow",
  "#d9480f": "orange",
  // Backgrounds
  "#ced4da": "grey",
  "#868e96": "grey",
  "#fa5252": "light-red",
  "#e64980": "red",
  "#be4bdb": "light-violet",
  "#7950f2": "violet",
  "#4c6ef5": "blue",
  "#228be6": "light-blue",
  "#15aabf": "light-green",
  "#12b886": "green",
  "#40c057": "green",
  "#82c91e": "light-green",
  "#fab005": "yellow",
  "#fd7e14": "orange",
  "#212529": "grey"
};
var strokeStylesToStrokeTypes = {
  solid: "draw",
  dashed: "dashed",
  dotted: "dotted"
};
var fillStylesToFillType = {
  "cross-hatch": "pattern",
  hachure: "pattern",
  solid: "solid"
};
var textAlignToAlignTypes = {
  left: "start",
  center: "middle",
  right: "end"
};
var arrowheadsToArrowheadTypes = {
  arrow: "arrow",
  dot: "dot",
  triangle: "triangle",
  bar: "pipe"
};
function getBend(element, startPoint, endPoint) {
  let bend = 0;
  if (element.points.length > 2) {
    const start = new Vec2d(startPoint[0], startPoint[1]);
    const end = new Vec2d(endPoint[0], endPoint[1]);
    const handle = new Vec2d(element.points[1][0], element.points[1][1]);
    const delta = Vec2d.Sub(end, start);
    const v = Vec2d.Per(delta);
    const med = Vec2d.Med(end, start);
    const A = Vec2d.Sub(med, v);
    const B = Vec2d.Add(med, v);
    const point = Vec2d.NearestPointOnLineSegment(A, B, handle, false);
    bend = Vec2d.Dist(point, med);
    if (Vec2d.Clockwise(point, end, med))
      bend *= -1;
  }
  return bend;
}
var getDash = (element) => {
  let dash = strokeStylesToStrokeTypes[element.strokeStyle] ?? "draw";
  if (dash === "draw" && element.roughness === 0) {
    dash = "solid";
  }
  return dash;
};
var getFill = (element) => {
  if (element.backgroundColor === "transparent") {
    return "none";
  }
  return fillStylesToFillType[element.fillStyle] ?? "solid";
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/clipboard/pasteFiles.mjs
async function pasteFiles(editor, urls, point, sources) {
  const blobs = await Promise.all(urls.map(async (url) => await (await fetch(url)).blob()));
  const files = blobs.map((blob) => new File([blob], "tldrawFile", { type: blob.type }));
  editor.mark("paste");
  await editor.putExternalContent({
    type: "files",
    files,
    point,
    ignoreParent: false,
    sources
  });
  urls.forEach((url) => URL.revokeObjectURL(url));
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/clipboard/pasteTldrawContent.mjs
function pasteTldrawContent(editor, clipboard, point) {
  const p = point ?? (editor.inputs.shiftKey ? editor.inputs.currentPagePoint : void 0);
  editor.mark("paste");
  editor.putContentOntoCurrentPage(clipboard, {
    point: p,
    select: true
  });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/clipboard/pasteUrl.mjs
async function pasteUrl(editor, url, point, sources) {
  try {
    const resp = await fetch(url);
    if (resp.headers.get("content-type")?.match(/^image\//)) {
      editor.mark("paste");
      pasteFiles(editor, [url]);
      return;
    }
  } catch (err) {
    if (err.message !== "Failed to fetch") {
      console.error(err);
    }
  }
  editor.mark("paste");
  return await editor.putExternalContent({
    type: "url",
    point,
    url,
    sources
  });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs
function stripHtml(html) {
  const doc = document.implementation.createHTMLDocument("");
  doc.documentElement.innerHTML = html.trim();
  return doc.body.textContent || doc.body.innerText || "";
}
var isValidHttpURL = (url) => {
  try {
    const u = new URL(url);
    return u.protocol === "http:" || u.protocol === "https:";
  } catch (e) {
    return false;
  }
};
var getValidHttpURLList = (url) => {
  const urls = url.split(/[\n\s]/);
  for (const url2 of urls) {
    try {
      const u = new URL(url2);
      if (!(u.protocol === "http:" || u.protocol === "https:")) {
        return;
      }
    } catch (e) {
      return;
    }
  }
  return uniq(urls);
};
var isSvgText = (text) => {
  return /^<svg/.test(text);
};
var INPUTS2 = ["input", "select", "textarea"];
function disallowClipboardEvents(editor) {
  const { activeElement } = document;
  return editor.isMenuOpen || activeElement && (activeElement.getAttribute("contenteditable") || INPUTS2.indexOf(activeElement.tagName.toLowerCase()) > -1);
}
async function blobAsString(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.addEventListener("loadend", () => {
      const text = reader.result;
      resolve(text);
    });
    reader.addEventListener("error", () => {
      reject(reader.error);
    });
    reader.readAsText(blob);
  });
}
var isFile = (item) => {
  return item.types.find((i) => i.match(/^image\//));
};
var handleText = (editor, data, point, sources) => {
  const validUrlList = getValidHttpURLList(data);
  if (validUrlList) {
    for (const url of validUrlList) {
      pasteUrl(editor, url, point);
    }
  } else if (isValidHttpURL(data)) {
    pasteUrl(editor, data, point);
  } else if (isSvgText(data)) {
    editor.mark("paste");
    editor.putExternalContent({
      type: "svg-text",
      text: data,
      point,
      sources
    });
  } else {
    editor.mark("paste");
    editor.putExternalContent({
      type: "text",
      text: data,
      point,
      sources
    });
  }
};
var handlePasteFromEventClipboardData = async (editor, clipboardData, point) => {
  if (editor.editingShapeId !== null)
    return;
  if (!clipboardData) {
    throw Error("No clipboard data");
  }
  const things = [];
  for (const item of Object.values(clipboardData.items)) {
    switch (item.kind) {
      case "file": {
        things.push({
          type: "file",
          source: new Promise((r) => r(item.getAsFile()))
        });
        break;
      }
      case "string": {
        if (item.type === "text/html") {
          things.push({
            type: "html",
            source: new Promise((r) => item.getAsString(r))
          });
        } else if (item.type === "text/plain") {
          things.push({
            type: "text",
            source: new Promise((r) => item.getAsString(r))
          });
        } else {
          things.push({ type: item.type, source: new Promise((r) => item.getAsString(r)) });
        }
        break;
      }
    }
  }
  handleClipboardThings(editor, things, point);
};
var handlePasteFromClipboardApi = async (editor, clipboardItems, point) => {
  const things = [];
  for (const item of clipboardItems) {
    if (isFile(item)) {
      for (const type of item.types) {
        if (type.match(/^image\//)) {
          things.push({ type: "blob", source: item.getType(type) });
        }
      }
    }
    if (item.types.includes("text/html")) {
      things.push({
        type: "html",
        source: new Promise(
          (r) => item.getType("text/html").then((blob) => blobAsString(blob).then(r))
        )
      });
    }
    if (item.types.includes("text/uri-list")) {
      things.push({
        type: "url",
        source: new Promise(
          (r) => item.getType("text/uri-list").then((blob) => blobAsString(blob).then(r))
        )
      });
    }
    if (item.types.includes("text/plain")) {
      things.push({
        type: "text",
        source: new Promise(
          (r) => item.getType("text/plain").then((blob) => blobAsString(blob).then(r))
        )
      });
    }
  }
  return await handleClipboardThings(editor, things, point);
};
async function handleClipboardThings(editor, things, point) {
  const files = things.filter(
    (t2) => (t2.type === "file" || t2.type === "blob") && t2.source !== null
  );
  if (files.length) {
    const fileBlobs = await Promise.all(files.map((t2) => t2.source));
    const urls = fileBlobs.filter(Boolean).map(
      (blob) => URL.createObjectURL(blob)
    );
    return await pasteFiles(editor, urls, point);
  }
  const results = await Promise.all(
    things.filter((t2) => t2.type !== "file").map(
      (t2) => new Promise((r) => {
        const thing = t2;
        if (thing.type === "file") {
          r({ type: "error", data: null, reason: "unexpected file" });
          return;
        }
        thing.source.then((text) => {
          const tldrawHtmlComment = text.match(/<tldraw[^>]*>(.*)<\/tldraw>/)?.[1];
          if (tldrawHtmlComment) {
            try {
              const jsonComment = (0, import_lz_string.decompressFromBase64)(tldrawHtmlComment);
              if (jsonComment === null) {
                r({
                  type: "error",
                  data: jsonComment,
                  reason: `found tldraw data comment but could not parse base64`
                });
                return;
              } else {
                const json = JSON.parse(jsonComment);
                if (json.type !== "application/tldraw") {
                  r({
                    type: "error",
                    data: json,
                    reason: `found tldraw data comment but JSON was of a different type: ${json.type}`
                  });
                }
                if (typeof json.data === "string") {
                  r({
                    type: "error",
                    data: json,
                    reason: "found tldraw json but data was a string instead of a TLClipboardModel object"
                  });
                  return;
                }
                r({ type: "tldraw", data: json.data });
                return;
              }
            } catch (e) {
              r({
                type: "error",
                data: tldrawHtmlComment,
                reason: "found tldraw json but data was a string instead of a TLClipboardModel object"
              });
              return;
            }
          } else {
            if (thing.type === "html") {
              r({ type: "text", data: text, subtype: "html" });
              return;
            }
            if (thing.type === "url") {
              r({ type: "text", data: text, subtype: "url" });
              return;
            }
            try {
              const json = JSON.parse(text);
              if (json.type === "excalidraw/clipboard") {
                r({ type: "excalidraw", data: json });
                return;
              } else {
                r({ type: "text", data: text, subtype: "json" });
                return;
              }
            } catch (e) {
              r({ type: "text", data: text, subtype: "text" });
              return;
            }
          }
          r({ type: "error", data: text, reason: "unhandled case" });
        });
      })
    )
  );
  for (const result of results) {
    if (result.type === "tldraw") {
      pasteTldrawContent(editor, result.data, point);
      return;
    }
  }
  for (const result of results) {
    if (result.type === "excalidraw") {
      pasteExcalidrawContent(editor, result.data, point);
      return;
    }
  }
  for (const result of results) {
    if (result.type === "text" && result.subtype === "html") {
      const rootNode = new DOMParser().parseFromString(result.data, "text/html");
      const bodyNode = rootNode.querySelector("body");
      const isHtmlSingleLink = bodyNode && Array.from(bodyNode.children).filter((el) => el.nodeType === 1).length === 1 && bodyNode.firstElementChild && bodyNode.firstElementChild.tagName === "A" && bodyNode.firstElementChild.hasAttribute("href") && bodyNode.firstElementChild.getAttribute("href") !== "";
      if (isHtmlSingleLink) {
        const href = bodyNode.firstElementChild.getAttribute("href");
        handleText(editor, href, point, results);
        return;
      }
      if (!results.some((r) => r.type === "text" && r.subtype !== "html") && result.data.trim()) {
        handleText(editor, stripHtml(result.data), point, results);
        return;
      }
    }
  }
  for (const result of results) {
    if (result.type === "text" && result.subtype === "url") {
      pasteUrl(editor, result.data, point, results);
      return;
    }
  }
  for (const result of results) {
    if (result.type === "text" && result.subtype === "text" && result.data.trim()) {
      handleText(editor, result.data, point, results);
      return;
    }
  }
}
var handleNativeOrMenuCopy = (editor) => {
  const content = editor.getContentFromCurrentPage(editor.selectedShapeIds);
  if (!content) {
    if (navigator && navigator.clipboard) {
      navigator.clipboard.writeText("");
    }
    return;
  }
  const stringifiedClipboard = (0, import_lz_string.compressToBase64)(
    JSON.stringify({
      type: "application/tldraw",
      kind: "content",
      data: content
    })
  );
  if (typeof navigator === "undefined") {
    return;
  } else {
    const textItems = content.shapes.map((shape) => {
      if (editor.isShapeOfType(shape, "text") || editor.isShapeOfType(shape, "geo") || editor.isShapeOfType(shape, "arrow")) {
        return shape.props.text;
      }
      if (editor.isShapeOfType(shape, "bookmark") || editor.isShapeOfType(shape, "embed")) {
        return shape.props.url;
      }
      return null;
    }).filter(isNonNull);
    if (navigator.clipboard?.write) {
      const htmlBlob = new Blob([`<tldraw>${stringifiedClipboard}</tldraw>`], {
        type: "text/html"
      });
      let textContent = textItems.join(" ");
      if (textContent === "") {
        textContent = " ";
      }
      navigator.clipboard.write([
        new ClipboardItem({
          "text/html": htmlBlob,
          // What is this second blob used for?
          "text/plain": new Blob([textContent], { type: "text/plain" })
        })
      ]);
    } else if (navigator.clipboard.writeText) {
      navigator.clipboard.writeText(`<tldraw>${stringifiedClipboard}</tldraw>`);
    }
  }
};
function useMenuClipboardEvents() {
  const editor = useEditor();
  const trackEvent = useUiEvents();
  const copy = (0, import_react57.useCallback)(
    function onCopy(source) {
      if (editor.selectedShapeIds.length === 0)
        return;
      handleNativeOrMenuCopy(editor);
      trackEvent("copy", { source });
    },
    [editor, trackEvent]
  );
  const cut = (0, import_react57.useCallback)(
    function onCut(source) {
      if (editor.selectedShapeIds.length === 0)
        return;
      handleNativeOrMenuCopy(editor);
      editor.deleteShapes(editor.selectedShapeIds);
      trackEvent("cut", { source });
    },
    [editor, trackEvent]
  );
  const paste = (0, import_react57.useCallback)(
    async function onPaste(data, source, point) {
      if (editor.editingShapeId !== null || disallowClipboardEvents(editor))
        return;
      if (Array.isArray(data) && data[0] instanceof ClipboardItem) {
        handlePasteFromClipboardApi(editor, data, point);
        trackEvent("paste", { source: "menu" });
      } else {
        navigator.clipboard.read().then((clipboardItems) => {
          paste(clipboardItems, source, point);
        });
      }
    },
    [editor, trackEvent]
  );
  return {
    copy,
    cut,
    paste
  };
}
function useNativeClipboardEvents() {
  const editor = useEditor();
  const trackEvent = useUiEvents();
  const appIsFocused = useValue("editor.isFocused", () => editor.instanceState.isFocused, [editor]);
  (0, import_react57.useEffect)(() => {
    if (!appIsFocused)
      return;
    const copy = () => {
      if (editor.selectedShapeIds.length === 0 || editor.editingShapeId !== null || disallowClipboardEvents(editor))
        return;
      handleNativeOrMenuCopy(editor);
      trackEvent("copy", { source: "kbd" });
    };
    function cut() {
      if (editor.selectedShapeIds.length === 0 || editor.editingShapeId !== null || disallowClipboardEvents(editor))
        return;
      handleNativeOrMenuCopy(editor);
      editor.deleteShapes(editor.selectedShapeIds);
      trackEvent("cut", { source: "kbd" });
    }
    let disablingMiddleClickPaste = false;
    const pointerUpHandler = (e) => {
      if (e.button === 1) {
        disablingMiddleClickPaste = true;
        requestAnimationFrame(() => {
          disablingMiddleClickPaste = false;
        });
      }
    };
    const paste = (event) => {
      if (disablingMiddleClickPaste) {
        event.stopPropagation();
        return;
      }
      if (editor.editingShapeId !== null || disallowClipboardEvents(editor))
        return;
      if (event.clipboardData && !editor.inputs.shiftKey) {
        handlePasteFromEventClipboardData(editor, event.clipboardData);
      } else {
        navigator.clipboard.read().then((clipboardItems) => {
          if (Array.isArray(clipboardItems) && clipboardItems[0] instanceof ClipboardItem) {
            handlePasteFromClipboardApi(editor, clipboardItems, editor.inputs.currentPagePoint);
          }
        });
      }
      trackEvent("paste", { source: "kbd" });
    };
    document.addEventListener("copy", copy);
    document.addEventListener("cut", cut);
    document.addEventListener("paste", paste);
    document.addEventListener("pointerup", pointerUpHandler);
    return () => {
      document.removeEventListener("copy", copy);
      document.removeEventListener("cut", cut);
      document.removeEventListener("paste", paste);
      document.removeEventListener("pointerup", pointerUpHandler);
    };
  }, [editor, trackEvent, appIsFocused]);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useCopyAs.mjs
var import_react59 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/export.mjs
function getSvgAsString(svg) {
  const clone = svg.cloneNode(true);
  svg.setAttribute("width", +svg.getAttribute("width") + "");
  svg.setAttribute("height", +svg.getAttribute("height") + "");
  const out = new XMLSerializer().serializeToString(clone).replaceAll("&#10;      ", "").replaceAll(/((\s|")[0-9]*\.[0-9]{2})([0-9]*)(\b|"|\))/g, "$1");
  return out;
}
async function getSvgAsImage(svg, options) {
  const { type, quality, scale } = options;
  const width = +svg.getAttribute("width");
  const height = +svg.getAttribute("height");
  let scaledWidth = width * scale;
  let scaledHeight = height * scale;
  const dataUrl = await getSvgAsDataUrl(svg);
  const canvasSizes = await getBrowserCanvasMaxSize();
  if (width > canvasSizes.maxWidth) {
    scaledWidth = canvasSizes.maxWidth;
    scaledHeight = scaledWidth / width * height;
  }
  if (height > canvasSizes.maxHeight) {
    scaledHeight = canvasSizes.maxHeight;
    scaledWidth = scaledHeight / height * width;
  }
  if (scaledWidth * scaledHeight > canvasSizes.maxArea) {
    const ratio = Math.sqrt(canvasSizes.maxArea / (scaledWidth * scaledHeight));
    scaledWidth *= ratio;
    scaledHeight *= ratio;
  }
  scaledWidth = Math.floor(scaledWidth);
  scaledHeight = Math.floor(scaledHeight);
  const effectiveScale = scaledWidth / width;
  const canvas = await new Promise((resolve) => {
    const image = new Image();
    image.crossOrigin = "anonymous";
    image.onload = async () => {
      await new Promise((resolve2) => setTimeout(resolve2, 250));
      const canvas2 = document.createElement("canvas");
      const ctx = canvas2.getContext("2d");
      canvas2.width = scaledWidth;
      canvas2.height = scaledHeight;
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = "high";
      ctx.drawImage(image, 0, 0, scaledWidth, scaledHeight);
      URL.revokeObjectURL(dataUrl);
      resolve(canvas2);
    };
    image.onerror = () => {
      resolve(null);
    };
    image.src = dataUrl;
  });
  if (!canvas)
    return null;
  const blob = await new Promise(
    (resolve) => canvas.toBlob(
      (blob2) => {
        if (!blob2 || debugFlags.throwToBlob.value) {
          resolve(null);
        }
        resolve(blob2);
      },
      "image/" + type,
      quality
    )
  );
  if (!blob)
    return null;
  const view = new DataView(await blob.arrayBuffer());
  return PngHelpers.setPhysChunk(view, effectiveScale, {
    type: "image/" + type
  });
}
async function getSvgAsDataUrl(svg) {
  const clone = svg.cloneNode(true);
  clone.setAttribute("encoding", 'UTF-8"');
  const fileReader = new FileReader();
  const imgs = Array.from(clone.querySelectorAll("image"));
  for (const img of imgs) {
    const src = img.getAttribute("xlink:href");
    if (src) {
      if (!src.startsWith("data:")) {
        const blob = await (await fetch(src)).blob();
        const base64 = await new Promise((resolve, reject) => {
          fileReader.onload = () => resolve(fileReader.result);
          fileReader.onerror = () => reject(fileReader.error);
          fileReader.readAsDataURL(blob);
        });
        img.setAttribute("xlink:href", base64);
      }
    }
  }
  return getSvgAsDataUrlSync(clone);
}
function getSvgAsDataUrlSync(node) {
  const svgStr = new XMLSerializer().serializeToString(node);
  const base64SVG = window.btoa(unescape(encodeURIComponent(svgStr)));
  return `data:image/svg+xml;base64,${base64SVG}`;
}
function downloadDataURLAsFile(dataUrl, filename) {
  const link = document.createElement("a");
  link.href = dataUrl;
  link.download = filename;
  link.click();
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useToastsProvider.mjs
var import_jsx_runtime80 = __toESM(require_jsx_runtime(), 1);
var import_react58 = __toESM(require_react(), 1);
var ToastsContext = (0, import_react58.createContext)({});
function ToastsProvider({ children }) {
  const [toasts, setToasts] = (0, import_react58.useState)([]);
  const addToast = (0, import_react58.useCallback)((toast) => {
    const id = toast.id ?? uniqueId();
    setToasts((d) => [...d.filter((m) => m.id !== toast.id), { ...toast, id }]);
    return id;
  }, []);
  const removeToast = (0, import_react58.useCallback)((id) => {
    setToasts((d) => d.filter((m) => m.id !== id));
    return id;
  }, []);
  const clearToasts = (0, import_react58.useCallback)(() => {
    setToasts(() => []);
  }, []);
  return (0, import_jsx_runtime80.jsx)(ToastsContext.Provider, { value: { toasts, addToast, removeToast, clearToasts }, children });
}
function useToasts() {
  const ctx = (0, import_react58.useContext)(ToastsContext);
  if (!ctx) {
    throw new Error("useToasts must be used within a ToastsProvider");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useCopyAs.mjs
function useCopyAs() {
  const editor = useEditor();
  const { addToast } = useToasts();
  const msg2 = useTranslation();
  return (0, import_react59.useCallback)(
    // it's important that this function itself isn't async - we need to
    // create the relevant `ClipboardItem`s synchronously to make sure
    // safari knows that the user _wants_ to copy:
    // https://bugs.webkit.org/show_bug.cgi?id=222262
    //
    // this is fine for navigator.clipboard.write, but for fallbacks it's a
    // little awkward.
    function copyAs(ids = editor.selectedShapeIds, format = "svg") {
      if (ids.length === 0) {
        ids = [...editor.currentPageShapeIds];
      }
      if (ids.length === 0) {
        return;
      }
      switch (format) {
        case "svg": {
          if (window.navigator.clipboard) {
            if (window.navigator.clipboard.write) {
              window.navigator.clipboard.write([
                new ClipboardItem({
                  "text/plain": getExportedSvgBlob(editor, ids)
                })
              ]);
            } else {
              fallbackWriteTextAsync(
                async () => getSvgAsString(await getExportSvgElement(editor, ids))
              );
            }
          }
          break;
        }
        case "jpeg":
        case "png": {
          const mimeType = format === "jpeg" ? "image/jpeg" : "image/png";
          const blobPromise = getExportedImageBlob(editor, ids, format).then((blob) => {
            if (blob) {
              if (window.navigator.clipboard) {
                return blob;
              }
              throw new Error("Copy not supported");
            } else {
              addToast({
                id: "copy-fail",
                icon: "warning-triangle",
                title: msg2("toast.error.copy-fail.title"),
                description: msg2("toast.error.copy-fail.desc")
              });
              throw new Error("Copy not possible");
            }
          });
          window.navigator.clipboard.write([
            new ClipboardItem({
              // Note: This needs to use the promise based approach for safari/ios to not bail on a permissions error.
              [mimeType]: blobPromise
            })
          ]).catch((err) => {
            if (!err.toString().match(/^TypeError: DOMString not supported/)) {
              console.error(err);
            }
            blobPromise.then((blob) => {
              window.navigator.clipboard.write([
                new ClipboardItem({
                  // Note: This needs to use the promise based approach for safari/ios to not bail on a permissions error.
                  [mimeType]: blob
                })
              ]);
            });
          });
          break;
        }
        case "json": {
          const data = editor.getContentFromCurrentPage(ids);
          if (window.navigator.clipboard) {
            const jsonStr = JSON.stringify(data);
            if (window.navigator.clipboard.write) {
              window.navigator.clipboard.write([
                new ClipboardItem({
                  "text/plain": new Blob([jsonStr], { type: "text/plain" })
                })
              ]);
            } else {
              fallbackWriteTextAsync(async () => jsonStr);
            }
          }
          break;
        }
        default:
          throw new Error(`Copy type ${format} not supported.`);
      }
    },
    [editor, addToast, msg2]
  );
}
async function getExportSvgElement(editor, ids) {
  const svg = await editor.getSvg(ids, {
    scale: 1,
    background: editor.instanceState.exportBackground
  });
  if (!svg)
    throw new Error("Could not construct SVG.");
  return svg;
}
async function getExportedSvgBlob(editor, ids) {
  return new Blob([getSvgAsString(await getExportSvgElement(editor, ids))], {
    type: "text/plain"
  });
}
async function getExportedImageBlob(editor, ids, format) {
  return await getSvgAsImage(await getExportSvgElement(editor, ids), {
    type: format,
    quality: 1,
    scale: 2
  });
}
async function fallbackWriteTextAsync(getText) {
  if (!(navigator && navigator.clipboard))
    return;
  navigator.clipboard.writeText(await getText());
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useDialogsProvider.mjs
var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1);
var import_react60 = __toESM(require_react(), 1);
var DialogsContext = (0, import_react60.createContext)({});
function DialogsProvider({ children }) {
  const editor = useEditor();
  const trackEvent = useUiEvents();
  const [dialogs, setDialogs] = (0, import_react60.useState)([]);
  const addDialog = (0, import_react60.useCallback)(
    (dialog) => {
      const id = dialog.id ?? uniqueId();
      setDialogs((d) => {
        return [...d.filter((m) => m.id !== dialog.id), { ...dialog, id }];
      });
      trackEvent("open-menu", { source: "dialog", id });
      editor.addOpenMenu(id);
      return id;
    },
    [editor, trackEvent]
  );
  const updateDialog = (0, import_react60.useCallback)(
    (id, newDialogData) => {
      setDialogs(
        (d) => d.map((m) => {
          if (m.id === id) {
            return {
              ...m,
              ...newDialogData
            };
          }
          return m;
        })
      );
      trackEvent("open-menu", { source: "dialog", id });
      editor.addOpenMenu(id);
      return id;
    },
    [editor, trackEvent]
  );
  const removeDialog = (0, import_react60.useCallback)(
    (id) => {
      setDialogs(
        (d) => d.filter((m) => {
          if (m.id === id) {
            m.onClose?.();
            return false;
          }
          return true;
        })
      );
      trackEvent("close-menu", { source: "dialog", id });
      editor.deleteOpenMenu(id);
      return id;
    },
    [editor, trackEvent]
  );
  const clearDialogs = (0, import_react60.useCallback)(() => {
    setDialogs((d) => {
      d.forEach((m) => {
        m.onClose?.();
        trackEvent("close-menu", { source: "dialog", id: m.id });
        editor.deleteOpenMenu(m.id);
      });
      return [];
    });
  }, [editor, trackEvent]);
  return (0, import_jsx_runtime81.jsx)(
    DialogsContext.Provider,
    {
      value: { dialogs, addDialog, removeDialog, clearDialogs, updateDialog },
      children
    }
  );
}
function useDialogs() {
  const ctx = (0, import_react60.useContext)(DialogsContext);
  if (!ctx) {
    throw new Error("useDialogs must be used within a DialogsProvider");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useExportAs.mjs
var import_react61 = __toESM(require_react(), 1);
function useExportAs() {
  const editor = useEditor();
  const { addToast } = useToasts();
  const msg2 = useTranslation();
  return (0, import_react61.useCallback)(
    async function exportAs(ids = editor.selectedShapeIds, format = "png") {
      if (ids.length === 0) {
        ids = [...editor.currentPageShapeIds];
      }
      if (ids.length === 0) {
        return;
      }
      const svg = await editor.getSvg(ids, {
        scale: 1,
        background: editor.instanceState.exportBackground
      });
      if (!svg)
        throw new Error("Could not construct SVG.");
      let name = "shapes" + getTimestamp();
      if (ids.length === 1) {
        const first = editor.getShape(ids[0]);
        if (editor.isShapeOfType(first, "frame")) {
          name = first.props.name ?? "frame";
        } else {
          name = first.id.replace(/:/, "_");
        }
      }
      switch (format) {
        case "svg": {
          const dataURL = await getSvgAsDataUrl(svg);
          downloadDataURLAsFile(dataURL, `${name}.svg`);
          return;
        }
        case "webp":
        case "png": {
          const image = await getSvgAsImage(svg, {
            type: format,
            quality: 1,
            scale: 2
          });
          if (!image) {
            addToast({
              id: "export-fail",
              // icon: 'error',
              title: msg2("toast.error.export-fail.title"),
              description: msg2("toast.error.export-fail.desc")
            });
            return;
          }
          const dataURL = URL.createObjectURL(image);
          downloadDataURLAsFile(dataURL, `${name}.${format}`);
          URL.revokeObjectURL(dataURL);
          return;
        }
        case "json": {
          const data = editor.getContentFromCurrentPage(ids);
          const dataURL = URL.createObjectURL(
            new Blob([JSON.stringify(data, null, 4)], { type: "application/json" })
          );
          downloadDataURLAsFile(dataURL, `${name || "shapes"}.json`);
          URL.revokeObjectURL(dataURL);
          return;
        }
        default:
          throw new Error(`Export type ${format} not supported.`);
      }
    },
    [editor, addToast, msg2]
  );
}
function getTimestamp() {
  const now = /* @__PURE__ */ new Date();
  const year = String(now.getFullYear()).slice(2);
  const month = String(now.getMonth() + 1).padStart(2, "0");
  const day = String(now.getDate()).padStart(2, "0");
  const hours = String(now.getHours()).padStart(2, "0");
  const minutes = String(now.getMinutes()).padStart(2, "0");
  const seconds = String(now.getSeconds()).padStart(2, "0");
  return ` at ${year}-${month}-${day} ${hours}.${minutes}.${seconds}`;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useInsertMedia.mjs
var import_react62 = __toESM(require_react(), 1);
function useInsertMedia() {
  const editor = useEditor();
  const inputRef = (0, import_react62.useRef)();
  (0, import_react62.useEffect)(() => {
    const input = window.document.createElement("input");
    input.type = "file";
    input.accept = "image/jpeg,image/png,image/gif,image/svg+xml,video/mp4,video/quicktime";
    input.multiple = true;
    inputRef.current = input;
    async function onchange(e) {
      const fileList = e.target.files;
      if (!fileList || fileList.length === 0)
        return;
      await editor.putExternalContent({
        type: "files",
        files: Array.from(fileList),
        point: editor.viewportPageBounds.center,
        ignoreParent: false
      });
      input.value = "";
    }
    input.addEventListener("change", onchange);
    return () => {
      inputRef.current = void 0;
      input.removeEventListener("change", onchange);
    };
  }, [editor]);
  return (0, import_react62.useCallback)(() => {
    inputRef.current?.click();
  }, [inputRef]);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/usePrint.mjs
var import_react63 = __toESM(require_react(), 1);
function usePrint() {
  const editor = useEditor();
  const prevPrintEl = (0, import_react63.useRef)(null);
  const prevStyleEl = (0, import_react63.useRef)(null);
  return (0, import_react63.useCallback)(
    async function printSelectionOrPages() {
      const el = document.createElement("div");
      const style = document.createElement("style");
      const clearElements = (printEl, styleEl) => {
        if (printEl)
          printEl.innerHTML = "";
        if (styleEl && document.head.contains(styleEl))
          document.head.removeChild(styleEl);
        if (printEl && document.body.contains(printEl)) {
          document.body.removeChild(printEl);
        }
      };
      clearElements(prevPrintEl.current, prevStyleEl.current);
      prevPrintEl.current = el;
      prevStyleEl.current = style;
      const className = `tl-print-surface-${uniqueId()}`;
      el.className = className;
      const enableMargins = false;
      const allowAllPages = false;
      style.innerHTML = `
			.${className} {
				display: none;
			}

			.${className} svg {
				max-width: 100%;
				height: 100%;
				display: block;
			}

			@media print {				  
				html, body {
					min-height: 100%;
					height: 100%;
					margin: 0;
				}

				body {
					position: relative;
				}

				body > * {
					display: none;
				}

				.${className} {
					display: block !important;
					background: white;
					min-height: 100%;
					height: 100%;
					max-width: 100%;
				}

				.${className}__item {
					padding: 10mm;
					display: flex;
					min-height: 100%;
					flex-direction: column;
					page-break-after: always;
					position: relative;
					overflow: hidden;
					height: 100%;
				}

				.${className}__item__main {
					flex: 1;
					display: flex;
					align-items: center;
					justify-content: center;
					max-height: 100%;
				}

				.${className}__item__header {
					display: none;
				}

				.${className}__item__footer {
					display: none;
					text-align: right;
				}

				.${className}__item__footer__hide {
					display: none;
				}

				${!enableMargins ? "" : `
					/**
					 * Note: Safari doesn't support removing the page margins to remove them all!
					 */
					@page {
						margin:0;
					}

					.${className} .${className}__item__header {
						display: block;
					}

					.${className} .${className}__item__footer {
						display: block;
					}
				`}
			}

		`;
      const beforePrintHandler = () => {
        document.head.appendChild(style);
        document.body.appendChild(el);
      };
      const afterPrintHandler = () => {
        editor.once("change-history", () => {
          clearElements(el, style);
        });
      };
      window.addEventListener("beforeprint", beforePrintHandler);
      window.addEventListener("afterprint", afterPrintHandler);
      function addPageToPrint(title, footer, svg) {
        try {
          el.innerHTML += `<div class="${className}__item">
        <div class="${className}__item__header">
          ${title.replace(/</g, "&lt;").replace(/>/g, "&gt;")}
        </div>
        <div class="${className}__item__main">
          ${svg.outerHTML}
        </div>
        <div class="${className}__item__footer ${className}__item__footer__${footer ? "" : "hide"}">
          ${footer ?? ""}
        </div>
      </div>`;
        } catch (e) {
          console.error(e);
        }
      }
      function triggerPrint() {
        if (editor.environment.isChromeForIos) {
          beforePrintHandler();
          window.print();
        } else if (editor.environment.isSafari) {
          beforePrintHandler();
          document.execCommand("print", false);
        } else {
          window.print();
        }
      }
      const { pages, currentPageId, selectedShapeIds } = editor;
      const preserveAspectRatio = "xMidYMid meet";
      const svgOpts = {
        scale: 1,
        background: false,
        darkMode: false,
        preserveAspectRatio
      };
      if (editor.selectedShapeIds.length > 0) {
        const svg = await editor.getSvg(selectedShapeIds, svgOpts);
        if (svg) {
          const page = pages.find((p) => p.id === currentPageId);
          addPageToPrint(`tldraw — ${page?.name}`, null, svg);
          triggerPrint();
        }
      } else {
        if (allowAllPages) {
          for (let i = 0; i < pages.length; i++) {
            const page = pages[i];
            const svg = await editor.getSvg(editor.getSortedChildIdsForParent(page.id), svgOpts);
            if (svg) {
              addPageToPrint(`tldraw — ${page.name}`, `${i}/${pages.length}`, svg);
            }
          }
          triggerPrint();
        } else {
          const page = editor.currentPage;
          const svg = await editor.getSvg(editor.getSortedChildIdsForParent(page.id), svgOpts);
          if (svg) {
            addPageToPrint(`tldraw — ${page.name}`, null, svg);
            triggerPrint();
          }
        }
      }
      window.removeEventListener("beforeprint", beforePrintHandler);
      window.removeEventListener("afterprint", afterPrintHandler);
    },
    [editor]
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useActions.mjs
var ActionsContext = React38.createContext({});
function makeActions(actions) {
  return Object.fromEntries(actions.map((action) => [action.id, action]));
}
function ActionsProvider({ overrides, children }) {
  const editor = useEditor();
  const { addDialog, clearDialogs } = useDialogs();
  const { clearToasts } = useToasts();
  const insertMedia = useInsertMedia();
  const printSelectionOrPages = usePrint();
  const { cut, copy, paste } = useMenuClipboardEvents();
  const copyAs = useCopyAs();
  const exportAs = useExportAs();
  const trackEvent = useUiEvents();
  const actions = React38.useMemo(() => {
    function mustGoBackToSelectToolFirst() {
      if (!editor.isIn("select")) {
        editor.complete();
        editor.setCurrentTool("select");
        return false;
      }
      return false;
    }
    function hasSelectedShapes() {
      return editor.selectedShapeIds.length > 0;
    }
    const actions2 = makeActions([
      {
        id: "edit-link",
        label: "action.edit-link",
        icon: "link",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("edit-link", { source });
          editor.mark("edit-link");
          addDialog({ component: EditLinkDialog });
        }
      },
      {
        id: "insert-embed",
        label: "action.insert-embed",
        readonlyOk: false,
        kbd: "$i",
        onSelect(source) {
          trackEvent("insert-embed", { source });
          addDialog({ component: EmbedDialog });
        }
      },
      {
        id: "insert-media",
        label: "action.insert-media",
        kbd: "$u",
        readonlyOk: false,
        onSelect(source) {
          trackEvent("insert-media", { source });
          insertMedia();
        }
      },
      {
        id: "undo",
        label: "action.undo",
        icon: "undo",
        kbd: "$z",
        readonlyOk: false,
        onSelect(source) {
          trackEvent("undo", { source });
          editor.undo();
        }
      },
      {
        id: "redo",
        label: "action.redo",
        icon: "redo",
        kbd: "$!z",
        readonlyOk: false,
        onSelect(source) {
          trackEvent("redo", { source });
          editor.redo();
        }
      },
      {
        id: "export-as-svg",
        label: "action.export-as-svg",
        menuLabel: "action.export-as-svg.short",
        contextMenuLabel: "action.export-as-svg.short",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("export-as", { format: "svg", source });
          exportAs(editor.selectedShapeIds, "svg");
        }
      },
      {
        id: "export-as-png",
        label: "action.export-as-png",
        menuLabel: "action.export-as-png.short",
        contextMenuLabel: "action.export-as-png.short",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("export-as", { format: "png", source });
          exportAs(editor.selectedShapeIds, "png");
        }
      },
      {
        id: "export-as-json",
        label: "action.export-as-json",
        menuLabel: "action.export-as-json.short",
        contextMenuLabel: "action.export-as-json.short",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("export-as", { format: "json", source });
          exportAs(editor.selectedShapeIds, "json");
        }
      },
      {
        id: "copy-as-svg",
        label: "action.copy-as-svg",
        menuLabel: "action.copy-as-svg.short",
        contextMenuLabel: "action.copy-as-svg.short",
        kbd: "$!c",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("copy-as", { format: "svg", source });
          copyAs(editor.selectedShapeIds, "svg");
        }
      },
      {
        id: "copy-as-png",
        label: "action.copy-as-png",
        menuLabel: "action.copy-as-png.short",
        contextMenuLabel: "action.copy-as-png.short",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("copy-as", { format: "png", source });
          copyAs(editor.selectedShapeIds, "png");
        }
      },
      {
        id: "copy-as-json",
        label: "action.copy-as-json",
        menuLabel: "action.copy-as-json.short",
        contextMenuLabel: "action.copy-as-json.short",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("copy-as", { format: "json", source });
          copyAs(editor.selectedShapeIds, "json");
        }
      },
      {
        id: "toggle-auto-size",
        label: "action.toggle-auto-size",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("toggle-auto-size", { source });
          editor.mark("toggling auto size");
          editor.updateShapes(
            editor.selectedShapes.filter(
              (shape) => editor.isShapeOfType(shape, "text") && shape.props.autoSize === false
            ).map((shape) => {
              return {
                id: shape.id,
                type: shape.type,
                props: {
                  ...shape.props,
                  w: 8,
                  autoSize: true
                }
              };
            })
          );
        }
      },
      {
        id: "open-embed-link",
        label: "action.open-embed-link",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("open-embed-link", { source });
          const ids = editor.selectedShapeIds;
          const warnMsg = "No embed shapes selected";
          if (ids.length !== 1) {
            console.error(warnMsg);
            return;
          }
          const shape = editor.getShape(ids[0]);
          if (!shape || !editor.isShapeOfType(shape, "embed")) {
            console.error(warnMsg);
            return;
          }
          openWindow(shape.props.url, "_blank");
        }
      },
      {
        id: "select-zoom-tool",
        readonlyOk: true,
        kbd: "z",
        onSelect(source) {
          if (editor.root.current.value?.id === "zoom")
            return;
          trackEvent("zoom-tool", { source });
          if (!(editor.inputs.shiftKey || editor.inputs.ctrlKey)) {
            const currentTool = editor.root.current.value;
            if (currentTool && currentTool.current.value?.id === "idle") {
              editor.setCurrentTool("zoom", { onInteractionEnd: currentTool.id, maskAs: "zoom" });
            }
          }
        }
      },
      {
        id: "convert-to-bookmark",
        label: "action.convert-to-bookmark",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          editor.batch(() => {
            trackEvent("convert-to-bookmark", { source });
            const shapes = editor.selectedShapes;
            const createList = [];
            const deleteList = [];
            for (const shape of shapes) {
              if (!shape || !editor.isShapeOfType(shape, "embed") || !shape.props.url)
                continue;
              const newPos = new Vec2d(shape.x, shape.y);
              newPos.rot(-shape.rotation);
              newPos.add(new Vec2d(shape.props.w / 2 - 300 / 2, shape.props.h / 2 - 320 / 2));
              newPos.rot(shape.rotation);
              const partial = {
                id: createShapeId(),
                type: "bookmark",
                rotation: shape.rotation,
                x: newPos.x,
                y: newPos.y,
                opacity: 1,
                props: {
                  url: shape.props.url
                }
              };
              createList.push(partial);
              deleteList.push(shape.id);
            }
            editor.mark("convert shapes to bookmark");
            editor.deleteShapes(deleteList);
            editor.createShapes(createList);
          });
        }
      },
      {
        id: "convert-to-embed",
        label: "action.convert-to-embed",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("convert-to-embed", { source });
          editor.batch(() => {
            const ids = editor.selectedShapeIds;
            const shapes = compact(ids.map((id) => editor.getShape(id)));
            const createList = [];
            const deleteList = [];
            for (const shape of shapes) {
              if (!editor.isShapeOfType(shape, "bookmark"))
                continue;
              const { url } = shape.props;
              const embedInfo = getEmbedInfo(shape.props.url);
              if (!embedInfo)
                continue;
              if (!embedInfo.definition)
                continue;
              const { width, height } = embedInfo.definition;
              const newPos = new Vec2d(shape.x, shape.y);
              newPos.rot(-shape.rotation);
              newPos.add(new Vec2d(shape.props.w / 2 - width / 2, shape.props.h / 2 - height / 2));
              newPos.rot(shape.rotation);
              const shapeToCreate = {
                id: createShapeId(),
                type: "embed",
                x: newPos.x,
                y: newPos.y,
                rotation: shape.rotation,
                props: {
                  url,
                  w: width,
                  h: height
                }
              };
              createList.push(shapeToCreate);
              deleteList.push(shape.id);
            }
            editor.mark("convert shapes to embed");
            editor.deleteShapes(deleteList);
            editor.createShapes(createList);
          });
        }
      },
      {
        id: "duplicate",
        kbd: "$d",
        label: "action.duplicate",
        icon: "duplicate",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("duplicate-shapes", { source });
          const ids = editor.selectedShapeIds;
          const commonBounds = Box2d.Common(compact(ids.map((id) => editor.getShapePageBounds(id))));
          const offset2 = editor.instanceState.canMoveCamera ? {
            x: commonBounds.width + 10,
            y: 0
          } : {
            x: 16 / editor.zoomLevel,
            y: 16 / editor.zoomLevel
          };
          editor.mark("duplicate shapes");
          editor.duplicateShapes(ids, offset2);
        }
      },
      {
        id: "ungroup",
        label: "action.ungroup",
        kbd: "$!g",
        icon: "ungroup",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("ungroup-shapes", { source });
          editor.mark("ungroup");
          editor.ungroupShapes(editor.selectedShapeIds);
        }
      },
      {
        id: "group",
        label: "action.group",
        kbd: "$g",
        icon: "group",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("group-shapes", { source });
          const { onlySelectedShape } = editor;
          if (onlySelectedShape && editor.isShapeOfType(onlySelectedShape, "group")) {
            editor.mark("ungroup");
            editor.ungroupShapes(editor.selectedShapeIds);
          } else {
            editor.mark("group");
            editor.groupShapes(editor.selectedShapeIds);
          }
        }
      },
      {
        id: "align-left",
        label: "action.align-left",
        kbd: "?A",
        icon: "align-left",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("align-shapes", { operation: "left", source });
          editor.mark("align left");
          editor.alignShapes(editor.selectedShapeIds, "left");
        }
      },
      {
        id: "align-center-horizontal",
        label: "action.align-center-horizontal",
        contextMenuLabel: "action.align-center-horizontal.short",
        kbd: "?H",
        icon: "align-center-horizontal",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("align-shapes", { operation: "center-horizontal", source });
          editor.mark("align center horizontal");
          editor.alignShapes(editor.selectedShapeIds, "center-horizontal");
        }
      },
      {
        id: "align-right",
        label: "action.align-right",
        kbd: "?D",
        icon: "align-right",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("align-shapes", { operation: "right", source });
          editor.mark("align right");
          editor.alignShapes(editor.selectedShapeIds, "right");
        }
      },
      {
        id: "align-center-vertical",
        label: "action.align-center-vertical",
        contextMenuLabel: "action.align-center-vertical.short",
        kbd: "?V",
        icon: "align-center-vertical",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("align-shapes", { operation: "center-vertical", source });
          editor.mark("align center vertical");
          editor.alignShapes(editor.selectedShapeIds, "center-vertical");
        }
      },
      {
        id: "align-top",
        label: "action.align-top",
        icon: "align-top",
        kbd: "?W",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("align-shapes", { operation: "top", source });
          editor.mark("align top");
          editor.alignShapes(editor.selectedShapeIds, "top");
        }
      },
      {
        id: "align-bottom",
        label: "action.align-bottom",
        icon: "align-bottom",
        kbd: "?S",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("align-shapes", { operation: "bottom", source });
          editor.mark("align bottom");
          editor.alignShapes(editor.selectedShapeIds, "bottom");
        }
      },
      {
        id: "distribute-horizontal",
        label: "action.distribute-horizontal",
        contextMenuLabel: "action.distribute-horizontal.short",
        icon: "distribute-horizontal",
        kbd: "?!h",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("distribute-shapes", { operation: "horizontal", source });
          editor.mark("distribute horizontal");
          editor.distributeShapes(editor.selectedShapeIds, "horizontal");
        }
      },
      {
        id: "distribute-vertical",
        label: "action.distribute-vertical",
        contextMenuLabel: "action.distribute-vertical.short",
        icon: "distribute-vertical",
        kbd: "?!V",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("distribute-shapes", { operation: "vertical", source });
          editor.mark("distribute vertical");
          editor.distributeShapes(editor.selectedShapeIds, "vertical");
        }
      },
      {
        id: "stretch-horizontal",
        label: "action.stretch-horizontal",
        contextMenuLabel: "action.stretch-horizontal.short",
        icon: "stretch-horizontal",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("stretch-shapes", { operation: "horizontal", source });
          editor.mark("stretch horizontal");
          editor.stretchShapes(editor.selectedShapeIds, "horizontal");
        }
      },
      {
        id: "stretch-vertical",
        label: "action.stretch-vertical",
        contextMenuLabel: "action.stretch-vertical.short",
        icon: "stretch-vertical",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("stretch-shapes", { operation: "vertical", source });
          editor.mark("stretch vertical");
          editor.stretchShapes(editor.selectedShapeIds, "vertical");
        }
      },
      {
        id: "flip-horizontal",
        label: "action.flip-horizontal",
        contextMenuLabel: "action.flip-horizontal.short",
        kbd: "!h",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("flip-shapes", { operation: "horizontal", source });
          editor.mark("flip horizontal");
          editor.flipShapes(editor.selectedShapeIds, "horizontal");
        }
      },
      {
        id: "flip-vertical",
        label: "action.flip-vertical",
        contextMenuLabel: "action.flip-vertical.short",
        kbd: "!v",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("flip-shapes", { operation: "vertical", source });
          editor.mark("flip vertical");
          editor.flipShapes(editor.selectedShapeIds, "vertical");
        }
      },
      {
        id: "pack",
        label: "action.pack",
        icon: "pack",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("pack-shapes", { source });
          editor.mark("pack");
          editor.packShapes(editor.selectedShapeIds, 16);
        }
      },
      {
        id: "stack-vertical",
        label: "action.stack-vertical",
        contextMenuLabel: "action.stack-vertical.short",
        icon: "stack-vertical",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("stack-shapes", { operation: "vertical", source });
          editor.mark("stack-vertical");
          editor.stackShapes(editor.selectedShapeIds, "vertical", 16);
        }
      },
      {
        id: "stack-horizontal",
        label: "action.stack-horizontal",
        contextMenuLabel: "action.stack-horizontal.short",
        icon: "stack-horizontal",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("stack-shapes", { operation: "horizontal", source });
          editor.mark("stack-horizontal");
          editor.stackShapes(editor.selectedShapeIds, "horizontal", 16);
        }
      },
      {
        id: "bring-to-front",
        label: "action.bring-to-front",
        kbd: "]",
        icon: "bring-to-front",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("reorder-shapes", { operation: "toFront", source });
          editor.mark("bring to front");
          editor.bringToFront(editor.selectedShapeIds);
        }
      },
      {
        id: "bring-forward",
        label: "action.bring-forward",
        icon: "bring-forward",
        kbd: "?]",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("reorder-shapes", { operation: "forward", source });
          editor.mark("bring forward");
          editor.bringForward(editor.selectedShapeIds);
        }
      },
      {
        id: "send-backward",
        label: "action.send-backward",
        icon: "send-backward",
        kbd: "?[",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("reorder-shapes", { operation: "backward", source });
          editor.mark("send backward");
          editor.sendBackward(editor.selectedShapeIds);
        }
      },
      {
        id: "send-to-back",
        label: "action.send-to-back",
        icon: "send-to-back",
        kbd: "[",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("reorder-shapes", { operation: "toBack", source });
          editor.mark("send to back");
          editor.sendToBack(editor.selectedShapeIds);
        }
      },
      {
        id: "cut",
        label: "action.cut",
        kbd: "$x",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          editor.mark("cut");
          cut(source);
        }
      },
      {
        id: "copy",
        label: "action.copy",
        kbd: "$c",
        readonlyOk: true,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          copy(source);
        }
      },
      {
        id: "paste",
        label: "action.paste",
        kbd: "$v",
        readonlyOk: false,
        onSelect(source) {
          navigator.clipboard?.read().then((clipboardItems) => {
            paste(
              clipboardItems,
              source,
              source === "context-menu" ? editor.inputs.currentPagePoint : void 0
            );
          });
        }
      },
      {
        id: "select-all",
        label: "action.select-all",
        kbd: "$a",
        readonlyOk: true,
        onSelect(source) {
          editor.batch(() => {
            if (mustGoBackToSelectToolFirst())
              return;
            trackEvent("select-all-shapes", { source });
            editor.mark("select all kbd");
            editor.selectAll();
          });
        }
      },
      {
        id: "select-none",
        label: "action.select-none",
        readonlyOk: true,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("select-none-shapes", { source });
          editor.mark("select none");
          editor.selectNone();
        }
      },
      {
        id: "delete",
        label: "action.delete",
        kbd: "⌫,del,backspace",
        icon: "trash",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("delete-shapes", { source });
          editor.mark("delete");
          editor.deleteShapes(editor.selectedShapeIds);
        }
      },
      {
        id: "rotate-cw",
        label: "action.rotate-cw",
        icon: "rotate-cw",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("rotate-cw", { source });
          editor.mark("rotate-cw");
          const offset2 = editor.selectionRotation % (TAU / 2);
          const dontUseOffset = approximately(offset2, 0) || approximately(offset2, TAU / 2);
          editor.rotateShapesBy(editor.selectedShapeIds, TAU / 2 - (dontUseOffset ? 0 : offset2));
        }
      },
      {
        id: "rotate-ccw",
        label: "action.rotate-ccw",
        icon: "rotate-ccw",
        readonlyOk: false,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("rotate-ccw", { source });
          editor.mark("rotate-ccw");
          const offset2 = editor.selectionRotation % (TAU / 2);
          const offsetCloseToZero = approximately(offset2, 0);
          editor.rotateShapesBy(editor.selectedShapeIds, offsetCloseToZero ? -(TAU / 2) : -offset2);
        }
      },
      {
        id: "zoom-in",
        label: "action.zoom-in",
        kbd: "$=,=",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("zoom-in", { source });
          editor.zoomIn(editor.viewportScreenCenter, { duration: ANIMATION_MEDIUM_MS });
        }
      },
      {
        id: "zoom-out",
        label: "action.zoom-out",
        kbd: "$-,-",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("zoom-out", { source });
          editor.zoomOut(editor.viewportScreenCenter, { duration: ANIMATION_MEDIUM_MS });
        }
      },
      {
        id: "zoom-to-100",
        label: "action.zoom-to-100",
        icon: "reset-zoom",
        kbd: "!0",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("reset-zoom", { source });
          editor.resetZoom(editor.viewportScreenCenter, { duration: ANIMATION_MEDIUM_MS });
        }
      },
      {
        id: "zoom-to-fit",
        label: "action.zoom-to-fit",
        kbd: "!1",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("zoom-to-fit", { source });
          editor.zoomToFit({ duration: ANIMATION_MEDIUM_MS });
        }
      },
      {
        id: "zoom-to-selection",
        label: "action.zoom-to-selection",
        kbd: "!2",
        readonlyOk: true,
        onSelect(source) {
          if (!hasSelectedShapes())
            return;
          if (mustGoBackToSelectToolFirst())
            return;
          trackEvent("zoom-to-selection", { source });
          editor.zoomToSelection({ duration: ANIMATION_MEDIUM_MS });
        }
      },
      {
        id: "toggle-snap-mode",
        label: "action.toggle-snap-mode",
        menuLabel: "action.toggle-snap-mode.menu",
        readonlyOk: false,
        onSelect(source) {
          trackEvent("toggle-snap-mode", { source });
          editor.user.updateUserPreferences({ isSnapMode: !editor.user.isSnapMode });
        },
        checkbox: true
      },
      {
        id: "toggle-dark-mode",
        label: "action.toggle-dark-mode",
        menuLabel: "action.toggle-dark-mode.menu",
        kbd: "$/",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("toggle-dark-mode", { source });
          editor.user.updateUserPreferences({ isDarkMode: !editor.user.isDarkMode });
        },
        checkbox: true
      },
      {
        id: "toggle-reduce-motion",
        label: "action.toggle-reduce-motion",
        menuLabel: "action.toggle-reduce-motion.menu",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("toggle-reduce-motion", { source });
          editor.user.updateUserPreferences({
            animationSpeed: editor.user.animationSpeed === 0 ? 1 : 0
          });
        },
        checkbox: true
      },
      {
        id: "toggle-transparent",
        label: "action.toggle-transparent",
        menuLabel: "action.toggle-transparent.menu",
        contextMenuLabel: "action.toggle-transparent.context-menu",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("toggle-transparent", { source });
          editor.updateInstanceState(
            {
              exportBackground: !editor.instanceState.exportBackground
            },
            { ephemeral: true }
          );
        },
        checkbox: true
      },
      {
        id: "toggle-tool-lock",
        label: "action.toggle-tool-lock",
        menuLabel: "action.toggle-tool-lock.menu",
        readonlyOk: false,
        kbd: "q",
        onSelect(source) {
          trackEvent("toggle-tool-lock", { source });
          editor.updateInstanceState({ isToolLocked: !editor.instanceState.isToolLocked });
        },
        checkbox: true
      },
      {
        id: "unlock-all",
        label: "action.unlock-all",
        readonlyOk: false,
        onSelect(source) {
          trackEvent("unlock-all", { source });
          const updates = [];
          for (const shape of editor.currentPageShapes) {
            if (shape.isLocked) {
              updates.push({ id: shape.id, type: shape.type, isLocked: false });
            }
          }
          if (updates.length > 0) {
            editor.updateShapes(updates);
          }
        }
      },
      {
        id: "toggle-focus-mode",
        label: "action.toggle-focus-mode",
        menuLabel: "action.toggle-focus-mode.menu",
        readonlyOk: true,
        kbd: "$.",
        checkbox: true,
        onSelect(source) {
          requestAnimationFrame(() => {
            editor.batch(() => {
              trackEvent("toggle-focus-mode", { source });
              clearDialogs();
              clearToasts();
              editor.updateInstanceState({ isFocusMode: !editor.instanceState.isFocusMode });
            });
          });
        }
      },
      {
        id: "toggle-grid",
        label: "action.toggle-grid",
        menuLabel: "action.toggle-grid.menu",
        readonlyOk: true,
        kbd: "$'",
        onSelect(source) {
          trackEvent("toggle-grid-mode", { source });
          editor.updateInstanceState({ isGridMode: !editor.instanceState.isGridMode });
        },
        checkbox: true
      },
      {
        id: "toggle-debug-mode",
        label: "action.toggle-debug-mode",
        menuLabel: "action.toggle-debug-mode.menu",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("toggle-debug-mode", { source });
          editor.updateInstanceState({
            isDebugMode: !editor.instanceState.isDebugMode
          });
        },
        checkbox: true
      },
      {
        id: "print",
        label: "action.print",
        kbd: "$p",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("print", { source });
          printSelectionOrPages();
        }
      },
      {
        id: "exit-pen-mode",
        label: "action.exit-pen-mode",
        icon: "cross-2",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("exit-pen-mode", { source });
          editor.updateInstanceState({ isPenMode: false });
        }
      },
      {
        id: "stop-following",
        label: "action.stop-following",
        icon: "cross-2",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("stop-following", { source });
          editor.stopFollowingUser();
        }
      },
      {
        id: "back-to-content",
        label: "action.back-to-content",
        icon: "arrow-left",
        readonlyOk: true,
        onSelect(source) {
          trackEvent("zoom-to-content", { source });
          editor.zoomToContent();
        }
      },
      {
        id: "toggle-lock",
        label: "action.toggle-lock",
        readonlyOk: false,
        kbd: "!l",
        onSelect(source) {
          editor.mark("locking");
          trackEvent("toggle-lock", { source });
          editor.toggleLock(editor.selectedShapeIds);
        }
      }
    ]);
    if (overrides) {
      return overrides(editor, actions2, void 0);
    }
    return actions2;
  }, [
    trackEvent,
    overrides,
    editor,
    addDialog,
    insertMedia,
    exportAs,
    copyAs,
    cut,
    copy,
    paste,
    clearDialogs,
    clearToasts,
    printSelectionOrPages
  ]);
  return (0, import_jsx_runtime82.jsx)(ActionsContext.Provider, { value: asActions(actions), children });
}
function useActions() {
  const ctx = React38.useContext(ActionsContext);
  if (!ctx) {
    throw new Error("useTools must be used within a ToolProvider");
  }
  return ctx;
}
function asActions(actions) {
  return actions;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useActionsMenuSchema.mjs
var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
var import_react65 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/menuHelpers.mjs
function compactMenuItems(arr) {
  return arr.filter((i) => i !== void 0 && i !== null && i !== false);
}
function menuGroup(id, ...children) {
  const childItems = compactMenuItems(children);
  if (childItems.length === 0)
    return null;
  return {
    id,
    type: "group",
    checkbox: childItems.every((child) => child.type === "item" && child.actionItem.checkbox),
    disabled: childItems.every((child) => child.disabled),
    readonlyOk: childItems.some((child) => child.readonlyOk),
    children: childItems
  };
}
function menuSubmenu(id, label, ...children) {
  const childItems = compactMenuItems(children);
  if (childItems.length === 0)
    return null;
  return {
    id,
    type: "submenu",
    label,
    children: childItems,
    disabled: childItems.every((child) => child.disabled),
    readonlyOk: childItems.some((child) => child.readonlyOk)
  };
}
function menuCustom(id, opts = {}) {
  const { readonlyOk = true, disabled = false } = opts;
  return {
    id,
    type: "custom",
    disabled,
    readonlyOk
  };
}
function menuItem(actionItem, opts = {}) {
  if (!actionItem) {
    throw Error("No action item provided to menuItem");
  }
  if (!actionItem.label) {
    throw Error("Trying to create menu item for action item that doesn't have a label");
  }
  const { checked = false, disabled = false } = opts;
  return {
    id: actionItem.id,
    type: "item",
    actionItem,
    disabled,
    checked,
    readonlyOk: actionItem.readonlyOk
  };
}
function shapesWithUnboundArrows(editor) {
  const { selectedShapeIds } = editor;
  const selectedShapes = selectedShapeIds.map((id) => {
    return editor.getShape(id);
  });
  return selectedShapes.filter((shape) => {
    if (!shape)
      return false;
    if (editor.isShapeOfType(shape, "arrow") && shape.props.start.type === "binding") {
      return false;
    }
    if (editor.isShapeOfType(shape, "arrow") && shape.props.end.type === "binding") {
      return false;
    }
    return true;
  });
}
var useThreeStackableItems = () => {
  const editor = useEditor();
  return useValue("threeStackableItems", () => shapesWithUnboundArrows(editor).length > 2, [editor]);
};
var useAllowGroup = () => {
  const editor = useEditor();
  return useValue("allowGroup", () => shapesWithUnboundArrows(editor).length > 1, [editor]);
};
var useAllowUngroup = () => {
  const editor = useEditor();
  return useValue(
    "allowUngroup",
    () => editor.selectedShapeIds.some((id) => editor.getShape(id)?.type === "group"),
    []
  );
};
function findMenuItem(menu, path) {
  const item = _findMenuItem(menu, path);
  assert(item, `Menu item ${path.join(" > ")} not found`);
  return item;
}
function _findMenuItem(menu, path) {
  const [next, ...rest] = path;
  if (!next)
    return null;
  const item = menu.find((item2) => item2.id === next);
  if (!item)
    return null;
  switch (item.type) {
    case "group":
    case "submenu":
      return rest.length === 0 ? item : _findMenuItem(item.children, rest);
    case "item":
    case "custom":
      return rest.length === 0 ? item : null;
    default:
      exhaustiveSwitchError(item, "type");
  }
}
var showMenuPaste = typeof window !== "undefined" && "navigator" in window && Boolean(navigator.clipboard) && Boolean(navigator.clipboard.read);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useBreakpoint.mjs
var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
var import_react64 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/constants.mjs
var PORTRAIT_BREAKPOINTS = [0, 380, 420, 460, 580, 640, 840, 1023];

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useBreakpoint.mjs
var BreakpointContext = import_react64.default.createContext(0);
function BreakPointProvider({ children }) {
  const editor = useEditor();
  const breakpoint = useValue(
    "breakpoint",
    () => {
      const { width } = editor.viewportScreenBounds;
      const breakpoints = PORTRAIT_BREAKPOINTS;
      for (let i = 0; i < breakpoints.length - 1; i++) {
        if (width > breakpoints[i] && width <= breakpoints[i + 1]) {
          return i;
        }
      }
      return breakpoints.length;
    },
    [editor]
  );
  return (0, import_jsx_runtime83.jsx)(BreakpointContext.Provider, { value: breakpoint, children });
}
function useBreakpoint() {
  let breakpoint = (0, import_react64.useContext)(BreakpointContext);
  const layoutQuery = new URL(window.location.href).searchParams.get("layout");
  if (layoutQuery === "desktop") {
    breakpoint = 7;
  } else if (layoutQuery === "mobile") {
    breakpoint = 1;
  }
  return breakpoint;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useHasLinkShapeSelected.mjs
function useHasLinkShapeSelected() {
  const editor = useEditor();
  return useValue(
    "hasLinkShapeSelected",
    () => {
      const { selectedShapes } = editor;
      return selectedShapes.length === 1 && "url" in selectedShapes[0].props && selectedShapes[0].type !== "embed";
    },
    [editor]
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useActionsMenuSchema.mjs
var ActionsMenuSchemaContext = import_react65.default.createContext({});
var ActionsMenuSchemaProvider = track(function ActionsMenuSchemaProvider2({
  overrides,
  children
}) {
  const editor = useEditor();
  const actions = useActions();
  const selectedCount = editor.selectedShapeIds.length;
  const oneSelected = selectedCount > 0;
  const twoSelected = selectedCount > 1;
  const threeSelected = selectedCount > 2;
  const threeStackableItems = useThreeStackableItems();
  const allowGroup = useAllowGroup();
  const allowUngroup = useAllowUngroup();
  const showEditLink = useHasLinkShapeSelected();
  const breakpoint = useBreakpoint();
  const isZoomedTo100 = editor.zoomLevel === 1;
  const actionTLUiMenuSchema = (0, import_react65.useMemo)(() => {
    const results = [
      menuItem(actions["align-left"], { disabled: !twoSelected }),
      menuItem(actions["align-center-horizontal"], { disabled: !twoSelected }),
      menuItem(actions["align-right"], { disabled: !twoSelected }),
      menuItem(actions["stretch-horizontal"], { disabled: !twoSelected }),
      menuItem(actions["align-top"], { disabled: !twoSelected }),
      menuItem(actions["align-center-vertical"], { disabled: !twoSelected }),
      menuItem(actions["align-bottom"], { disabled: !twoSelected }),
      menuItem(actions["stretch-vertical"], { disabled: !twoSelected }),
      menuItem(actions["distribute-horizontal"], { disabled: !threeSelected }),
      menuItem(actions["distribute-vertical"], { disabled: !threeSelected }),
      menuItem(actions["stack-horizontal"], { disabled: !threeStackableItems }),
      menuItem(actions["stack-vertical"], { disabled: !threeStackableItems }),
      menuItem(actions["send-to-back"], { disabled: !oneSelected }),
      menuItem(actions["send-backward"], { disabled: !oneSelected }),
      menuItem(actions["bring-forward"], { disabled: !oneSelected }),
      menuItem(actions["bring-to-front"], { disabled: !oneSelected }),
      breakpoint < 5 ? menuItem(actions["zoom-to-100"], { disabled: !!isZoomedTo100 }) : menuItem(actions["rotate-ccw"], { disabled: !oneSelected }),
      menuItem(actions["rotate-cw"], { disabled: !oneSelected }),
      menuItem(actions["edit-link"], { disabled: !showEditLink }),
      allowGroup ? menuItem(actions["group"], { disabled: !twoSelected }) : allowUngroup ? menuItem(actions["ungroup"]) : menuItem(actions["group"], { disabled: !twoSelected })
    ];
    if (overrides) {
      return overrides(editor, results, { actions, oneSelected, twoSelected, threeSelected });
    }
    return results;
  }, [
    editor,
    isZoomedTo100,
    allowGroup,
    overrides,
    actions,
    oneSelected,
    twoSelected,
    threeSelected,
    threeStackableItems,
    allowUngroup,
    showEditLink,
    breakpoint
  ]);
  return (0, import_jsx_runtime84.jsx)(ActionsMenuSchemaContext.Provider, { value: actionTLUiMenuSchema, children });
});
function useActionsMenuSchema() {
  const ctx = import_react65.default.useContext(ActionsMenuSchemaContext);
  if (!ctx) {
    throw new Error("useActionsMenuSchema must be used inside of a ActionsMenuSchemaProvider.");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useContextMenuSchema.mjs
var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1);
var import_react66 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useOnlyFlippableShape.mjs
function useOnlyFlippableShape() {
  const editor = useEditor();
  return useValue(
    "onlyFlippableShape",
    () => {
      const { selectedShapes } = editor;
      return selectedShapes.length === 1 && selectedShapes.every(
        (shape) => editor.isShapeOfType(shape, "group") || editor.isShapeOfType(shape, "arrow") || editor.isShapeOfType(shape, "line") || editor.isShapeOfType(shape, "draw")
      );
    },
    [editor]
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useShowAutoSizeToggle.mjs
function useShowAutoSizeToggle() {
  const editor = useEditor();
  return useValue(
    "showAutoSizeToggle",
    () => {
      const { selectedShapes } = editor;
      return selectedShapes.length === 1 && editor.isShapeOfType(selectedShapes[0], "text") && selectedShapes[0].props.autoSize === false;
    },
    [editor]
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useContextMenuSchema.mjs
var TLUiContextMenuSchemaContext = import_react66.default.createContext(
  {}
);
var TLUiContextMenuSchemaProvider = track(function TLUiContextMenuSchemaProvider2({
  overrides,
  children
}) {
  const editor = useEditor();
  const actions = useActions();
  const showAutoSizeToggle = useShowAutoSizeToggle();
  const onlyFlippableShapeSelected = useOnlyFlippableShape();
  const selectedCount = editor.selectedShapeIds.length;
  const oneSelected = selectedCount > 0;
  const twoSelected = selectedCount > 1;
  const threeSelected = selectedCount > 2;
  const threeStackableItems = useThreeStackableItems();
  const atLeastOneShapeOnPage = useValue(
    "atLeastOneShapeOnPage",
    () => editor.currentPageShapeIds.size > 0,
    []
  );
  const isTransparentBg = useValue(
    "isTransparentBg",
    () => editor.instanceState.exportBackground,
    []
  );
  const allowGroup = useAllowGroup();
  const allowUngroup = useAllowUngroup();
  const hasClipboardWrite = Boolean(window.navigator.clipboard?.write);
  const showEditLink = useHasLinkShapeSelected();
  const { onlySelectedShape } = editor;
  const isShapeLocked = onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape);
  const contextTLUiMenuSchema = (0, import_react66.useMemo)(() => {
    let contextTLUiMenuSchema2 = compactMenuItems([
      menuGroup(
        "selection",
        showAutoSizeToggle && menuItem(actions["toggle-auto-size"]),
        showEditLink && !isShapeLocked && menuItem(actions["edit-link"]),
        oneSelected && !isShapeLocked && menuItem(actions["duplicate"]),
        allowGroup && !isShapeLocked && menuItem(actions["group"]),
        allowUngroup && !isShapeLocked && menuItem(actions["ungroup"]),
        oneSelected && menuItem(actions["toggle-lock"])
      ),
      menuGroup(
        "modify",
        (twoSelected || onlyFlippableShapeSelected) && menuSubmenu(
          "arrange",
          "context-menu.arrange",
          twoSelected && menuGroup(
            "align",
            menuItem(actions["align-left"]),
            menuItem(actions["align-center-horizontal"]),
            menuItem(actions["align-right"]),
            menuItem(actions["align-top"]),
            menuItem(actions["align-center-vertical"]),
            menuItem(actions["align-bottom"])
          ),
          threeSelected && menuGroup(
            "distribute",
            menuItem(actions["distribute-horizontal"]),
            menuItem(actions["distribute-vertical"])
          ),
          twoSelected && menuGroup(
            "stretch",
            menuItem(actions["stretch-horizontal"]),
            menuItem(actions["stretch-vertical"])
          ),
          onlyFlippableShapeSelected && !isShapeLocked && menuGroup(
            "flip",
            menuItem(actions["flip-horizontal"]),
            menuItem(actions["flip-vertical"])
          ),
          twoSelected && menuGroup(
            "order",
            menuItem(actions["pack"], { disabled: !twoSelected }),
            threeStackableItems && menuItem(actions["stack-vertical"]),
            threeStackableItems && menuItem(actions["stack-horizontal"])
          )
        ),
        oneSelected && !isShapeLocked && menuSubmenu(
          "reorder",
          "context-menu.reorder",
          menuGroup(
            "reorder",
            menuItem(actions["bring-to-front"]),
            menuItem(actions["bring-forward"]),
            menuItem(actions["send-backward"]),
            menuItem(actions["send-to-back"])
          )
        ),
        oneSelected && !isShapeLocked && menuCustom("MOVE_TO_PAGE_MENU", { readonlyOk: false })
      ),
      menuGroup(
        "clipboard-group",
        oneSelected && !isShapeLocked && menuItem(actions["cut"]),
        oneSelected && menuItem(actions["copy"]),
        showMenuPaste && menuItem(actions["paste"])
      ),
      atLeastOneShapeOnPage && menuGroup(
        "conversions",
        menuSubmenu(
          "copy-as",
          "context-menu.copy-as",
          menuGroup(
            "copy-as-group",
            menuItem(actions["copy-as-svg"]),
            hasClipboardWrite && menuItem(actions["copy-as-png"]),
            menuItem(actions["copy-as-json"])
          ),
          menuGroup(
            "export-bg",
            menuItem(actions["toggle-transparent"], { checked: !isTransparentBg })
          )
        ),
        menuSubmenu(
          "export-as",
          "context-menu.export-as",
          menuGroup(
            "export-as-group",
            menuItem(actions["export-as-svg"]),
            menuItem(actions["export-as-png"]),
            menuItem(actions["export-as-json"])
          ),
          menuGroup(
            "export-bg,",
            menuItem(actions["toggle-transparent"], { checked: !isTransparentBg })
          )
        )
      ),
      atLeastOneShapeOnPage && menuGroup(
        "set-selection-group",
        menuItem(actions["select-all"]),
        oneSelected && menuItem(actions["select-none"])
      ),
      oneSelected && !isShapeLocked && menuGroup("delete-group", menuItem(actions["delete"]))
    ]);
    if (overrides) {
      contextTLUiMenuSchema2 = overrides(editor, contextTLUiMenuSchema2, {
        actions,
        oneSelected,
        twoSelected,
        threeSelected,
        showAutoSizeToggle,
        showUngroup: allowUngroup,
        onlyFlippableShapeSelected
      });
    }
    return contextTLUiMenuSchema2;
  }, [
    editor,
    overrides,
    actions,
    oneSelected,
    twoSelected,
    threeSelected,
    showAutoSizeToggle,
    onlyFlippableShapeSelected,
    atLeastOneShapeOnPage,
    threeStackableItems,
    allowGroup,
    allowUngroup,
    hasClipboardWrite,
    showEditLink,
    // oneEmbedSelected,
    // oneEmbeddableBookmarkSelected,
    isTransparentBg,
    isShapeLocked
  ]);
  return (0, import_jsx_runtime85.jsx)(TLUiContextMenuSchemaContext.Provider, { value: contextTLUiMenuSchema, children });
});
function useContextMenuSchema() {
  const ctx = import_react66.default.useContext(TLUiContextMenuSchemaContext);
  if (!ctx) {
    throw new Error("useContextMenuSchema must be used inside of a TLUiContextMenuSchemaProvider.");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useHelpMenuSchema.mjs
var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1);
var import_react68 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/KeyboardShortcutsDialog.mjs
var import_jsx_runtime88 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcutsSchema.mjs
var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1);
var import_react67 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useTools.mjs
var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1);
var React42 = __toESM(require_react(), 1);
var ToolsContext = React42.createContext({});
function ToolsProvider({ overrides, children }) {
  const editor = useEditor();
  const trackEvent = useUiEvents();
  const { addDialog } = useDialogs();
  const insertMedia = useInsertMedia();
  const tools = React42.useMemo(() => {
    const toolsArray = [
      {
        id: "select",
        label: "tool.select",
        icon: "tool-pointer",
        kbd: "v",
        readonlyOk: true,
        onSelect(source) {
          editor.setCurrentTool("select");
          trackEvent("select-tool", { source, id: "select" });
        }
      },
      {
        id: "hand",
        label: "tool.hand",
        icon: "tool-hand",
        kbd: "h",
        readonlyOk: true,
        onSelect(source) {
          editor.setCurrentTool("hand");
          trackEvent("select-tool", { source, id: "hand" });
        }
      },
      {
        id: "eraser",
        label: "tool.eraser",
        icon: "tool-eraser",
        kbd: "e",
        readonlyOk: false,
        onSelect(source) {
          editor.setCurrentTool("eraser");
          trackEvent("select-tool", { source, id: "eraser" });
        }
      },
      {
        id: "draw",
        label: "tool.draw",
        readonlyOk: false,
        icon: "tool-pencil",
        kbd: "d,b,x",
        onSelect(source) {
          editor.setCurrentTool("draw");
          trackEvent("select-tool", { source, id: "draw" });
        }
      },
      ...[...GeoShapeGeoStyle.values].map((id) => ({
        id,
        label: `tool.${id}`,
        readonlyOk: false,
        meta: {
          geo: id
        },
        kbd: id === "rectangle" ? "r" : id === "ellipse" ? "o" : void 0,
        icon: "geo-" + id,
        onSelect(source) {
          editor.batch(() => {
            editor.updateInstanceState(
              {
                stylesForNextShape: {
                  ...editor.instanceState.stylesForNextShape,
                  [GeoShapeGeoStyle.id]: id
                }
              },
              { ephemeral: true }
            );
            editor.setCurrentTool("geo");
            trackEvent("select-tool", { source, id: `geo-${id}` });
          });
        }
      })),
      {
        id: "arrow",
        label: "tool.arrow",
        readonlyOk: false,
        icon: "tool-arrow",
        kbd: "a",
        onSelect(source) {
          editor.setCurrentTool("arrow");
          trackEvent("select-tool", { source, id: "arrow" });
        }
      },
      {
        id: "line",
        label: "tool.line",
        readonlyOk: false,
        icon: "tool-line",
        kbd: "l",
        onSelect(source) {
          editor.setCurrentTool("line");
          trackEvent("select-tool", { source, id: "line" });
        }
      },
      {
        id: "frame",
        label: "tool.frame",
        readonlyOk: false,
        icon: "tool-frame",
        kbd: "f",
        onSelect(source) {
          editor.setCurrentTool("frame");
          trackEvent("select-tool", { source, id: "frame" });
        }
      },
      {
        id: "text",
        label: "tool.text",
        readonlyOk: false,
        icon: "tool-text",
        kbd: "t",
        onSelect(source) {
          editor.setCurrentTool("text");
          trackEvent("select-tool", { source, id: "text" });
        }
      },
      {
        id: "asset",
        label: "tool.asset",
        readonlyOk: false,
        icon: "tool-media",
        kbd: "$u",
        onSelect(source) {
          insertMedia();
          trackEvent("select-tool", { source, id: "media" });
        }
      },
      {
        id: "note",
        label: "tool.note",
        readonlyOk: false,
        icon: "tool-note",
        kbd: "n",
        onSelect(source) {
          editor.setCurrentTool("note");
          trackEvent("select-tool", { source, id: "note" });
        }
      },
      {
        id: "laser",
        label: "tool.laser",
        readonlyOk: true,
        icon: "tool-laser",
        kbd: "k",
        onSelect(source) {
          editor.setCurrentTool("laser");
          trackEvent("select-tool", { source, id: "laser" });
        }
      },
      {
        id: "embed",
        label: "tool.embed",
        readonlyOk: false,
        icon: "tool-embed",
        onSelect(source) {
          addDialog({ component: EmbedDialog });
          trackEvent("select-tool", { source, id: "embed" });
        }
      }
    ];
    toolsArray.push({
      id: "highlight",
      label: "tool.highlight",
      readonlyOk: true,
      icon: "tool-highlight",
      // TODO: pick a better shortcut
      kbd: "!d",
      onSelect(source) {
        editor.setCurrentTool("highlight");
        trackEvent("select-tool", { source, id: "highlight" });
      }
    });
    const tools2 = Object.fromEntries(toolsArray.map((t2) => [t2.id, t2]));
    if (overrides) {
      return overrides(editor, tools2, { insertMedia });
    }
    return tools2;
  }, [overrides, editor, trackEvent, insertMedia, addDialog]);
  return (0, import_jsx_runtime86.jsx)(ToolsContext.Provider, { value: tools, children });
}
function useTools() {
  const ctx = React42.useContext(ToolsContext);
  if (!ctx) {
    throw new Error("useTools must be used within a ToolProvider");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcutsSchema.mjs
var KeyboardShortcutsSchemaContext = import_react67.default.createContext(
  {}
);
var KeyboardShortcutsSchemaProvider = track(function KeyboardShortcutsSchemaProvider2({
  overrides,
  children
}) {
  const editor = useEditor();
  const tools = useTools();
  const actions = useActions();
  const keyboardShortcutsSchema = (0, import_react67.useMemo)(() => {
    const keyboardShortcutsSchema2 = compact([
      menuGroup(
        "shortcuts-dialog.tools",
        menuItem(actions["toggle-tool-lock"]),
        menuItem(tools["select"]),
        menuItem(tools["draw"]),
        menuItem(tools["eraser"]),
        menuItem(tools["hand"]),
        menuItem(tools["rectangle"]),
        menuItem(tools["ellipse"]),
        menuItem(tools["arrow"]),
        menuItem(tools["line"]),
        menuItem(tools["text"]),
        menuItem(tools["frame"]),
        menuItem(tools["note"]),
        menuItem(tools["laser"])
      ),
      menuGroup(
        "shortcuts-dialog.file",
        menuItem(actions["insert-media"]),
        menuItem(actions["print"])
      ),
      menuGroup(
        "shortcuts-dialog.preferences",
        menuItem(actions["toggle-dark-mode"]),
        menuItem(actions["toggle-focus-mode"]),
        menuItem(actions["toggle-grid"])
      ),
      menuGroup(
        "shortcuts-dialog.edit",
        menuItem(actions["undo"]),
        menuItem(actions["redo"]),
        menuItem(actions["cut"]),
        menuItem(actions["copy"]),
        menuItem(actions["paste"]),
        menuItem(actions["select-all"]),
        menuItem(actions["delete"]),
        menuItem(actions["duplicate"]),
        menuItem(actions["export-as-svg"]),
        menuItem(actions["export-as-png"])
      ),
      menuGroup(
        "shortcuts-dialog.view",
        menuItem(actions["zoom-in"]),
        menuItem(actions["zoom-out"]),
        menuItem(actions["zoom-to-100"]),
        menuItem(actions["zoom-to-fit"]),
        menuItem(actions["zoom-to-selection"])
      ),
      menuGroup(
        "shortcuts-dialog.transform",
        menuItem(actions["bring-to-front"]),
        menuItem(actions["bring-forward"]),
        menuItem(actions["send-backward"]),
        menuItem(actions["send-to-back"]),
        menuItem(actions["group"]),
        menuItem(actions["ungroup"]),
        menuItem(actions["flip-horizontal"]),
        menuItem(actions["flip-vertical"]),
        menuItem(actions["align-top"]),
        menuItem(actions["align-center-vertical"]),
        menuItem(actions["align-bottom"]),
        menuItem(actions["align-left"]),
        menuItem(actions["align-center-horizontal"]),
        menuItem(actions["align-right"])
      )
    ]);
    if (overrides) {
      return overrides(editor, keyboardShortcutsSchema2, { tools, actions });
    }
    return keyboardShortcutsSchema2;
  }, [editor, overrides, actions, tools]);
  return (0, import_jsx_runtime87.jsx)(KeyboardShortcutsSchemaContext.Provider, { value: keyboardShortcutsSchema, children });
});
function useKeyboardShortcutsSchema() {
  const ctx = import_react67.default.useContext(KeyboardShortcutsSchemaContext);
  if (!ctx) {
    throw new Error("Shortcuts must be used inside of a ShortcutsProvider.");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/KeyboardShortcutsDialog.mjs
var KeyboardShortcutsDialog = () => {
  const msg2 = useTranslation();
  const isReadonly = useReadonly();
  const shortcutsItems = useKeyboardShortcutsSchema();
  function getKeyboardShortcutItem(item) {
    if (isReadonly && !item.readonlyOk)
      return null;
    switch (item.type) {
      case "group": {
        return (0, import_jsx_runtime88.jsxs)("div", { className: "tlui-shortcuts-dialog__group", children: [
          (0, import_jsx_runtime88.jsx)("h2", { className: "tlui-shortcuts-dialog__group__title", children: msg2(item.id) }),
          (0, import_jsx_runtime88.jsx)("div", { className: "tlui-shortcuts-dialog__group__content", children: item.children.filter((item2) => item2.type === "item" && item2.actionItem.kbd).map(getKeyboardShortcutItem) })
        ] }, item.id);
      }
      case "item": {
        const { id, label, shortcutsLabel, kbd: kbd2 } = item.actionItem;
        return (0, import_jsx_runtime88.jsxs)("div", { className: "tlui-shortcuts-dialog__key-pair", children: [
          (0, import_jsx_runtime88.jsx)("div", { className: "tlui-shortcuts-dialog__key-pair__key", children: msg2(shortcutsLabel ?? label) }),
          (0, import_jsx_runtime88.jsx)("div", { className: "tlui-shortcuts-dialog__key-pair__value", children: (0, import_jsx_runtime88.jsx)(Kbd, { children: kbd2 }) })
        ] }, id);
      }
    }
  }
  return (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, { children: [
    (0, import_jsx_runtime88.jsxs)(Header, { className: "tlui-shortcuts-dialog__header", children: [
      (0, import_jsx_runtime88.jsx)(Title, { children: msg2("shortcuts-dialog.title") }),
      (0, import_jsx_runtime88.jsx)(CloseButton, {})
    ] }),
    (0, import_jsx_runtime88.jsx)(Body, { className: "tlui-shortcuts-dialog__body", children: shortcutsItems.map(getKeyboardShortcutItem) }),
    (0, import_jsx_runtime88.jsx)("div", { className: "tlui-dialog__scrim" })
  ] });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useTranslation/useLanguages.mjs
function useLanguages() {
  const editor = useEditor();
  return {
    languages: LANGUAGES,
    currentLanguage: editor.user.locale
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useHelpMenuSchema.mjs
var HelpMenuSchemaContext = import_react68.default.createContext({});
var HelpMenuSchemaProvider = track(function HelpMenuSchemaProvider2({
  overrides,
  children
}) {
  const editor = useEditor();
  const actions = useActions();
  const selectedCount = editor.selectedShapeIds.length;
  const oneSelected = selectedCount > 0;
  const twoSelected = selectedCount > 1;
  const threeSelected = selectedCount > 2;
  const { languages, currentLanguage } = useLanguages();
  const { addDialog } = useDialogs();
  const helpTLUiMenuSchema = (0, import_react68.useMemo)(() => {
    const helpTLUiMenuSchema2 = compact([
      menuGroup(
        "top",
        menuCustom("LANGUAGE_MENU", { readonlyOk: true }),
        menuItem({
          id: "keyboard-shortcuts",
          label: "help-menu.keyboard-shortcuts",
          readonlyOk: true,
          onSelect() {
            addDialog({ component: KeyboardShortcutsDialog });
          }
        })
      )
    ]);
    if (overrides) {
      return overrides(editor, helpTLUiMenuSchema2, {
        actions,
        currentLanguage,
        languages,
        oneSelected,
        twoSelected,
        threeSelected
      });
    }
    return helpTLUiMenuSchema2;
  }, [
    editor,
    overrides,
    languages,
    actions,
    oneSelected,
    twoSelected,
    threeSelected,
    currentLanguage,
    addDialog
  ]);
  return (0, import_jsx_runtime89.jsx)(HelpMenuSchemaContext.Provider, { value: helpTLUiMenuSchema, children });
});
function useHelpMenuSchema() {
  const ctx = import_react68.default.useContext(HelpMenuSchemaContext);
  if (!ctx) {
    throw new Error("useHelpMenuSchema must be used inside of a helpTLUiMenuSchemaProvider.");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useMenuSchema.mjs
var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1);
var import_react69 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useCanRedo.mjs
function useCanRedo() {
  const editor = useEditor();
  return useValue("useCanRedo", () => editor.canRedo, [editor]);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useCanUndo.mjs
function useCanUndo() {
  const editor = useEditor();
  return useValue("useCanUndo", () => editor.canUndo, [editor]);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useMenuSchema.mjs
var TLUiMenuSchemaContext = import_react69.default.createContext({});
function TLUiMenuSchemaProvider({ overrides, children }) {
  const editor = useEditor();
  const actions = useActions();
  const breakpoint = useBreakpoint();
  const isMobile = breakpoint < 5;
  const isDarkMode = useValue("isDarkMode", () => editor.user.isDarkMode, [editor]);
  const animationSpeed = useValue("animationSpeed", () => editor.user.animationSpeed, [editor]);
  const isGridMode = useValue("isGridMode", () => editor.instanceState.isGridMode, [editor]);
  const isSnapMode = useValue("isSnapMode", () => editor.user.isSnapMode, [editor]);
  const isToolLock = useValue("isToolLock", () => editor.instanceState.isToolLocked, [editor]);
  const isFocusMode = useValue("isFocusMode", () => editor.instanceState.isFocusMode, [editor]);
  const isDebugMode = useValue("isDebugMode", () => editor.instanceState.isDebugMode, [editor]);
  const exportBackground = useValue(
    "exportBackground",
    () => editor.instanceState.exportBackground,
    [editor]
  );
  const emptyPage = useValue("emptyPage", () => editor.currentPageShapeIds.size === 0, [editor]);
  const selectedCount = useValue("selectedCount", () => editor.selectedShapeIds.length, [editor]);
  const noneSelected = selectedCount === 0;
  const oneSelected = selectedCount > 0;
  const twoSelected = selectedCount > 1;
  const threeSelected = selectedCount > 2;
  const hasClipboardWrite = Boolean(window.navigator.clipboard?.write);
  const showEditLink = useHasLinkShapeSelected();
  const showAutoSizeToggle = useShowAutoSizeToggle();
  const allowGroup = useAllowGroup();
  const allowUngroup = useAllowUngroup();
  const canUndo = useCanUndo();
  const canRedo = useCanRedo();
  const isZoomedTo100 = useValue("isZoomedTo100", () => editor.zoomLevel === 1, [editor]);
  const oneEmbedSelected = useValue(
    "oneEmbedSelected",
    () => {
      const { onlySelectedShape } = editor;
      if (!onlySelectedShape)
        return false;
      return !!(editor.isShapeOfType(onlySelectedShape, "embed") && onlySelectedShape.props.url && !editor.isShapeOrAncestorLocked(onlySelectedShape));
    },
    []
  );
  const oneEmbeddableBookmarkSelected = useValue(
    "oneEmbeddableBookmarkSelected",
    () => {
      const { onlySelectedShape } = editor;
      if (!onlySelectedShape)
        return false;
      return !!(editor.isShapeOfType(onlySelectedShape, "bookmark") && onlySelectedShape.props.url && getEmbedInfo(onlySelectedShape.props.url) && !editor.isShapeOrAncestorLocked(onlySelectedShape));
    },
    []
  );
  const menuSchema = (0, import_react69.useMemo)(() => {
    const menuSchema2 = compactMenuItems([
      menuGroup(
        "menu",
        menuSubmenu(
          "file",
          "menu.file",
          menuGroup("print", menuItem(actions["print"], { disabled: emptyPage }))
        ),
        menuSubmenu(
          "edit",
          "menu.edit",
          menuGroup(
            "undo-actions",
            menuItem(actions["undo"], { disabled: !canUndo }),
            menuItem(actions["redo"], { disabled: !canRedo })
          ),
          menuGroup(
            "clipboard-actions",
            menuItem(actions["cut"], { disabled: noneSelected }),
            menuItem(actions["copy"], { disabled: noneSelected }),
            menuItem(actions["paste"], { disabled: !showMenuPaste })
          ),
          menuGroup(
            "conversions",
            menuSubmenu(
              "copy-as",
              "menu.copy-as",
              menuGroup(
                "copy-as-group",
                menuItem(actions["copy-as-svg"], { disabled: emptyPage }),
                menuItem(actions["copy-as-png"], { disabled: emptyPage || !hasClipboardWrite }),
                menuItem(actions["copy-as-json"], { disabled: emptyPage })
              ),
              menuGroup(
                "export-bg",
                menuItem(actions["toggle-transparent"], { checked: !exportBackground })
              )
            ),
            menuSubmenu(
              "export-as",
              "menu.export-as",
              menuGroup(
                "export-as-group",
                menuItem(actions["export-as-svg"], { disabled: emptyPage }),
                menuItem(actions["export-as-png"], { disabled: emptyPage }),
                menuItem(actions["export-as-json"], { disabled: emptyPage })
              ),
              menuGroup(
                "export-bg",
                menuItem(actions["toggle-transparent"], { checked: !exportBackground })
              )
            )
          ),
          menuGroup(
            "set-selection-group",
            menuItem(actions["select-all"], { disabled: emptyPage }),
            menuItem(actions["select-none"], { disabled: !oneSelected })
          ),
          menuGroup(
            "selection",
            showAutoSizeToggle && menuItem(actions["toggle-auto-size"]),
            showEditLink && menuItem(actions["edit-link"]),
            menuItem(actions["duplicate"], { disabled: !oneSelected }),
            allowGroup && menuItem(actions["group"]),
            allowUngroup && menuItem(actions["ungroup"]),
            menuItem(actions["unlock-all"], { disabled: emptyPage })
          ),
          menuGroup("delete-group", menuItem(actions["delete"], { disabled: !oneSelected })),
          menuGroup(
            "embeds",
            oneEmbedSelected && menuItem(actions["open-embed-link"]),
            oneEmbedSelected && menuItem(actions["convert-to-bookmark"]),
            oneEmbeddableBookmarkSelected && menuItem(actions["convert-to-embed"])
          )
        ),
        menuSubmenu(
          "view",
          "menu.view",
          menuGroup(
            "view-actions",
            menuItem(actions["zoom-in"]),
            menuItem(actions["zoom-out"]),
            menuItem(actions["zoom-to-100"], { disabled: isZoomedTo100 }),
            menuItem(actions["zoom-to-fit"], { disabled: emptyPage }),
            menuItem(actions["zoom-to-selection"], { disabled: emptyPage || !oneSelected })
          )
        )
      ),
      menuGroup("extras", menuItem(actions["insert-embed"]), menuItem(actions["insert-media"])),
      menuGroup(
        "preferences",
        menuSubmenu(
          "preferences",
          "menu.preferences",
          menuGroup(
            "preferences-actions",
            menuItem(actions["toggle-snap-mode"], { checked: isSnapMode }),
            menuItem(actions["toggle-tool-lock"], { checked: isToolLock }),
            menuItem(actions["toggle-grid"], { checked: isGridMode }),
            menuItem(actions["toggle-dark-mode"], { checked: isDarkMode }),
            menuItem(actions["toggle-focus-mode"], { checked: isFocusMode }),
            menuItem(actions["toggle-reduce-motion"], { checked: animationSpeed === 0 }),
            menuItem(actions["toggle-debug-mode"], { checked: isDebugMode })
          )
        ),
        isMobile && menuCustom("LANGUAGE_MENU", { readonlyOk: true })
      )
    ]);
    if (overrides) {
      return overrides(editor, menuSchema2, {
        actions,
        noneSelected,
        oneSelected,
        twoSelected,
        threeSelected
      });
    }
    return menuSchema2;
  }, [
    editor,
    overrides,
    actions,
    oneSelected,
    twoSelected,
    threeSelected,
    emptyPage,
    isMobile,
    allowGroup,
    allowUngroup,
    showEditLink,
    hasClipboardWrite,
    showAutoSizeToggle,
    noneSelected,
    canUndo,
    canRedo,
    animationSpeed,
    isDarkMode,
    isGridMode,
    isSnapMode,
    isToolLock,
    isFocusMode,
    exportBackground,
    isDebugMode,
    isZoomedTo100,
    oneEmbeddableBookmarkSelected,
    oneEmbedSelected
  ]);
  return (0, import_jsx_runtime90.jsx)(TLUiMenuSchemaContext.Provider, { value: menuSchema, children });
}
function useMenuSchema() {
  const ctx = import_react69.default.useContext(TLUiMenuSchemaContext);
  if (!ctx) {
    throw new Error("useMenuSchema must be used inside of a TLUiMenuSchemaProvider.");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useToolbarSchema.mjs
var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1);
var import_react70 = __toESM(require_react(), 1);
function toolbarItem(toolItem) {
  return {
    id: toolItem.id,
    type: "item",
    readonlyOk: toolItem.readonlyOk,
    toolItem
  };
}
var ToolbarSchemaContext = import_react70.default.createContext([]);
function ToolbarSchemaProvider({ overrides, children }) {
  const editor = useEditor();
  const tools = useTools();
  const toolbarSchema = import_react70.default.useMemo(() => {
    const schema = compact([
      toolbarItem(tools.select),
      toolbarItem(tools.hand),
      toolbarItem(tools.draw),
      toolbarItem(tools.eraser),
      toolbarItem(tools.arrow),
      toolbarItem(tools.text),
      toolbarItem(tools.note),
      toolbarItem(tools.asset),
      toolbarItem(tools["rectangle"]),
      toolbarItem(tools["ellipse"]),
      toolbarItem(tools["diamond"]),
      toolbarItem(tools["triangle"]),
      toolbarItem(tools["trapezoid"]),
      toolbarItem(tools["rhombus"]),
      toolbarItem(tools["hexagon"]),
      toolbarItem(tools["cloud"]),
      // toolbarItem(tools['octagon']),
      toolbarItem(tools["star"]),
      toolbarItem(tools["oval"]),
      toolbarItem(tools["x-box"]),
      toolbarItem(tools["check-box"]),
      toolbarItem(tools["arrow-left"]),
      toolbarItem(tools["arrow-up"]),
      toolbarItem(tools["arrow-down"]),
      toolbarItem(tools["arrow-right"]),
      toolbarItem(tools.frame),
      toolbarItem(tools.line),
      toolbarItem(tools.highlight),
      toolbarItem(tools.laser)
    ]);
    if (overrides) {
      return overrides(editor, schema, { tools });
    }
    return schema;
  }, [editor, overrides, tools]);
  return (0, import_jsx_runtime91.jsx)(ToolbarSchemaContext.Provider, { value: toolbarSchema, children });
}
function useToolbarSchema() {
  const ctx = import_react70.default.useContext(ToolbarSchemaContext);
  if (!ctx) {
    throw new Error("useToolbarSchema must be used within a ToolbarSchemaProvider");
  }
  return ctx;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/overrides.mjs
var import_react71 = __toESM(require_react(), 1);
function useDefaultHelpers() {
  const { addToast, removeToast, clearToasts } = useToasts();
  const { addDialog, clearDialogs, removeDialog, updateDialog } = useDialogs();
  const breakpoint = useBreakpoint();
  const isMobile = breakpoint < 5;
  const msg2 = useTranslation();
  return (0, import_react71.useMemo)(
    () => ({
      addToast,
      removeToast,
      clearToasts,
      addDialog,
      clearDialogs,
      removeDialog,
      updateDialog,
      msg: msg2,
      isMobile
    }),
    [
      addDialog,
      addToast,
      clearDialogs,
      clearToasts,
      msg2,
      removeDialog,
      removeToast,
      updateDialog,
      isMobile
    ]
  );
}
function mergeOverrides(overrides, defaultHelpers) {
  const mergedTranslations = {};
  for (const override of overrides) {
    if (override.translations) {
      for (const [key, value] of objectMapEntries(override.translations)) {
        let strings = mergedTranslations[key];
        if (!strings) {
          strings = mergedTranslations[key] = {};
        }
        Object.assign(strings, value);
      }
    }
  }
  return {
    actionsMenu: (editor, schema, helpers) => {
      for (const override of overrides) {
        if (override.actionsMenu) {
          schema = override.actionsMenu(editor, schema, { ...defaultHelpers, ...helpers });
        }
      }
      return schema;
    },
    actions: (editor, schema) => {
      for (const override of overrides) {
        if (override.actions) {
          schema = override.actions(editor, schema, defaultHelpers);
        }
      }
      return schema;
    },
    contextMenu: (editor, schema, helpers) => {
      for (const override of overrides) {
        if (override.contextMenu) {
          schema = override.contextMenu(editor, schema, { ...defaultHelpers, ...helpers });
        }
      }
      return schema;
    },
    helpMenu: (editor, schema, helpers) => {
      for (const override of overrides) {
        if (override.helpMenu) {
          schema = override.helpMenu(editor, schema, { ...defaultHelpers, ...helpers });
        }
      }
      return schema;
    },
    menu: (editor, schema, helpers) => {
      for (const override of overrides) {
        if (override.menu) {
          schema = override.menu(editor, schema, { ...defaultHelpers, ...helpers });
        }
      }
      return schema;
    },
    toolbar: (editor, schema, helpers) => {
      for (const override of overrides) {
        if (override.toolbar) {
          schema = override.toolbar(editor, schema, { ...defaultHelpers, ...helpers });
        }
      }
      return schema;
    },
    keyboardShortcutsMenu: (editor, schema, helpers) => {
      for (const override of overrides) {
        if (override.keyboardShortcutsMenu) {
          schema = override.keyboardShortcutsMenu(editor, schema, { ...defaultHelpers, ...helpers });
        }
      }
      return schema;
    },
    tools: (editor, schema, helpers) => {
      for (const override of overrides) {
        if (override.tools) {
          schema = override.tools(editor, schema, { ...defaultHelpers, ...helpers });
        }
      }
      return schema;
    },
    translations: mergedTranslations
  };
}
function useShallowArrayEquality(array2) {
  return (0, import_react71.useMemo)(() => array2, array2);
}
function useMergedTranslationOverrides(overrides) {
  const overridesArray = useShallowArrayEquality(
    overrides == null ? [] : Array.isArray(overrides) ? overrides : [overrides]
  );
  return (0, import_react71.useMemo)(() => {
    const mergedTranslations = {};
    for (const override of overridesArray) {
      if (override.translations) {
        for (const [key, value] of objectMapEntries(override.translations)) {
          let strings = mergedTranslations[key];
          if (!strings) {
            strings = mergedTranslations[key] = {};
          }
          Object.assign(strings, value);
        }
      }
    }
    return mergedTranslations;
  }, [overridesArray]);
}
function useMergedOverrides(overrides) {
  const defaultHelpers = useDefaultHelpers();
  const overridesArray = useShallowArrayEquality(
    overrides == null ? [] : Array.isArray(overrides) ? overrides : [overrides]
  );
  return (0, import_react71.useMemo)(
    () => mergeOverrides(overridesArray, defaultHelpers),
    [overridesArray, defaultHelpers]
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/TldrawUiContextProvider.mjs
function TldrawUiContextProvider({
  overrides,
  assetUrls,
  onUiEvent,
  children
}) {
  return (0, import_jsx_runtime92.jsx)(AssetUrlsProvider, { assetUrls: useDefaultUiAssetUrlsWithOverrides(assetUrls), children: (0, import_jsx_runtime92.jsx)(TranslationProvider, { overrides: useMergedTranslationOverrides(overrides), children: (0, import_jsx_runtime92.jsx)(UiEventsProvider, { onEvent: onUiEvent, children: (0, import_jsx_runtime92.jsx)(ToastsProvider, { children: (0, import_jsx_runtime92.jsx)(DialogsProvider, { children: (0, import_jsx_runtime92.jsx)(BreakPointProvider, { children: (0, import_jsx_runtime92.jsx)(InternalProviders, { overrides, children }) }) }) }) }) }) });
}
function InternalProviders({
  overrides,
  children
}) {
  const mergedOverrides = useMergedOverrides(overrides);
  return (0, import_jsx_runtime92.jsx)(ActionsProvider, { overrides: mergedOverrides.actions, children: (0, import_jsx_runtime92.jsx)(ToolsProvider, { overrides: mergedOverrides.tools, children: (0, import_jsx_runtime92.jsx)(ToolbarSchemaProvider, { overrides: mergedOverrides.toolbar, children: (0, import_jsx_runtime92.jsx)(ActionsMenuSchemaProvider, { overrides: mergedOverrides.actionsMenu, children: (0, import_jsx_runtime92.jsx)(KeyboardShortcutsSchemaProvider, { overrides: mergedOverrides.keyboardShortcutsMenu, children: (0, import_jsx_runtime92.jsx)(TLUiContextMenuSchemaProvider, { overrides: mergedOverrides.contextMenu, children: (0, import_jsx_runtime92.jsx)(HelpMenuSchemaProvider, { overrides: mergedOverrides.helpMenu, children: (0, import_jsx_runtime92.jsx)(TLUiMenuSchemaProvider, { overrides: mergedOverrides.menu, children }) }) }) }) }) }) }) });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/BackToContent.mjs
var import_jsx_runtime93 = __toESM(require_jsx_runtime(), 1);
var import_react72 = __toESM(require_react(), 1);
function BackToContent() {
  const editor = useEditor();
  const actions = useActions();
  const action = actions["back-to-content"];
  const [showBackToContent, setShowBackToContent] = (0, import_react72.useState)(false);
  (0, import_react72.useEffect)(() => {
    let showBackToContentPrev = false;
    const interval = setInterval(() => {
      const { renderingShapes, renderingBounds } = editor;
      const visibleShapes = renderingShapes.filter(
        (s) => s.maskedPageBounds && renderingBounds.includes(s.maskedPageBounds)
      );
      const showBackToContentNow = visibleShapes.length === 0 && editor.currentPageShapes.length > 0;
      if (showBackToContentPrev !== showBackToContentNow) {
        setShowBackToContent(showBackToContentNow);
        showBackToContentPrev = showBackToContentNow;
      }
    }, 1e3);
    return () => {
      clearInterval(interval);
    };
  }, [editor]);
  if (!showBackToContent)
    return null;
  return (0, import_jsx_runtime93.jsx)(
    Button,
    {
      iconLeft: action.icon,
      label: action.label,
      onClick: () => {
        action.onSelect("helper-buttons");
        setShowBackToContent(false);
      }
    }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/DebugPanel.mjs
var import_jsx_runtime94 = __toESM(require_jsx_runtime(), 1);
var React47 = __toESM(require_react(), 1);
var t = 0;
function createNShapes(editor, n) {
  const shapesToCreate = Array(n);
  const cols = Math.floor(Math.sqrt(n));
  for (let i = 0; i < n; i++) {
    t++;
    shapesToCreate[i] = {
      id: createShapeId("box" + t),
      type: "geo",
      x: i % cols * 132,
      y: Math.floor(i / cols) * 132
    };
  }
  editor.batch(() => {
    editor.createShapes(shapesToCreate).setSelectedShapes(shapesToCreate.map((s) => s.id));
  });
}
var DebugPanel = React47.memo(function DebugPanel2({
  renderDebugMenuItems
}) {
  const msg2 = useTranslation();
  return (0, import_jsx_runtime94.jsxs)("div", { className: "tlui-debug-panel", children: [
    (0, import_jsx_runtime94.jsx)(CurrentState, {}),
    (0, import_jsx_runtime94.jsx)(ShapeCount, {}),
    (0, import_jsx_runtime94.jsxs)(Root4, { id: "debug", children: [
      (0, import_jsx_runtime94.jsx)(Trigger2, { children: (0, import_jsx_runtime94.jsx)(Button, { icon: "dots-horizontal", title: msg2("debug-panel.more") }) }),
      (0, import_jsx_runtime94.jsx)(Content3, { side: "top", align: "end", alignOffset: 0, children: (0, import_jsx_runtime94.jsx)(DebugMenuContent, { renderDebugMenuItems }) })
    ] })
  ] });
});
var CurrentState = track(function CurrentState2() {
  const editor = useEditor();
  return (0, import_jsx_runtime94.jsx)("div", { className: "tlui-debug-panel__current-state", children: editor.root.path.value });
});
var ShapeCount = function ShapeCount2() {
  const editor = useEditor();
  const count = useValue("rendering shapes count", () => editor.renderingShapes.length, [editor]);
  return (0, import_jsx_runtime94.jsxs)("div", { children: [
    count,
    " Shapes"
  ] });
};
var DebugMenuContent = track(function DebugMenuContent2({
  renderDebugMenuItems
}) {
  const editor = useEditor();
  const { addToast } = useToasts();
  const { addDialog } = useDialogs();
  const [error, setError] = React47.useState(false);
  return (0, import_jsx_runtime94.jsxs)(import_jsx_runtime94.Fragment, { children: [
    (0, import_jsx_runtime94.jsxs)(Group3, { children: [
      (0, import_jsx_runtime94.jsx)(
        Item,
        {
          onClick: () => {
            addToast({
              id: uniqueId(),
              title: "Something happened",
              description: "Hey, attend to this thing over here. It might be important!"
              // icon?: string
              // title?: string
              // description?: string
              // actions?: TLUiToastAction[]
            });
          },
          children: (0, import_jsx_runtime94.jsx)("span", { children: "Show toast" })
        }
      ),
      (0, import_jsx_runtime94.jsx)(
        Item,
        {
          onClick: () => {
            addDialog({
              component: ({ onClose }) => (0, import_jsx_runtime94.jsx)(
                ExampleDialog,
                {
                  displayDontShowAgain: true,
                  onCancel: () => {
                    onClose();
                  },
                  onContinue: () => {
                    onClose();
                  }
                }
              ),
              onClose: () => {
              }
            });
          },
          children: (0, import_jsx_runtime94.jsx)("span", { children: "Show dialog" })
        }
      ),
      (0, import_jsx_runtime94.jsx)(Item, { onClick: () => createNShapes(editor, 100), children: (0, import_jsx_runtime94.jsx)("span", { children: "Create 100 shapes" }) }),
      (0, import_jsx_runtime94.jsx)(
        Item,
        {
          onClick: () => {
            function countDescendants({ children }) {
              let count = 0;
              if (!children.length)
                return 0;
              for (const el of [...children]) {
                count++;
                count += countDescendants(el);
              }
              return count;
            }
            const { selectedShapes } = editor;
            const shapes = selectedShapes.length === 0 ? editor.renderingShapes : selectedShapes;
            const elms = shapes.map(
              (shape) => document.getElementById(shape.id).parentElement
            );
            let descendants = elms.length;
            for (const elm of elms) {
              descendants += countDescendants(elm);
            }
            window.alert(`Shapes ${shapes.length}, DOM nodes:${descendants}`);
          },
          children: (0, import_jsx_runtime94.jsx)("span", { children: "Count shapes and nodes" })
        }
      ),
      (() => {
        if (error)
          throw Error("oh no!");
      })(),
      (0, import_jsx_runtime94.jsx)(
        Item,
        {
          onClick: () => {
            setError(true);
          },
          children: (0, import_jsx_runtime94.jsx)("span", { children: "Throw error" })
        }
      ),
      (0, import_jsx_runtime94.jsx)(
        Item,
        {
          onClick: () => {
            hardResetEditor();
          },
          children: (0, import_jsx_runtime94.jsx)("span", { children: "Hard reset" })
        }
      )
    ] }),
    (0, import_jsx_runtime94.jsxs)(Group3, { children: [
      (0, import_jsx_runtime94.jsx)(DebugFlagToggle, { flag: debugFlags.debugSvg }),
      (0, import_jsx_runtime94.jsx)(DebugFlagToggle, { flag: debugFlags.forceSrgb }),
      (0, import_jsx_runtime94.jsx)(DebugFlagToggle, { flag: debugFlags.debugGeometry }),
      (0, import_jsx_runtime94.jsx)(DebugFlagToggle, { flag: debugFlags.hideShapes })
    ] }),
    (0, import_jsx_runtime94.jsx)(Group3, { children: Object.values(featureFlags).map((flag) => {
      return (0, import_jsx_runtime94.jsx)(DebugFlagToggle, { flag }, flag.name);
    }) }),
    renderDebugMenuItems?.()
  ] });
});
function Toggle({
  label,
  value,
  onChange
}) {
  return (0, import_jsx_runtime94.jsx)(CheckboxItem3, { title: label, checked: value, onSelect: () => onChange(!value), children: label });
}
var DebugFlagToggle = track(function DebugFlagToggle2({
  flag,
  onChange
}) {
  return (0, import_jsx_runtime94.jsx)(
    Toggle,
    {
      label: flag.name.replace(/([a-z0-9])([A-Z])/g, (m) => `${m[0]} ${m[1].toLowerCase()}`).replace(/^[a-z]/, (m) => m.toUpperCase()),
      value: flag.value,
      onChange: (newValue) => {
        flag.set(newValue);
        onChange?.(newValue);
      }
    }
  );
});
function ExampleDialog({
  title = "title",
  body = "hello hello hello",
  cancel = "Cancel",
  confirm = "Continue",
  displayDontShowAgain = false,
  onCancel,
  onContinue
}) {
  const [dontShowAgain, setDontShowAgain] = React47.useState(false);
  return (0, import_jsx_runtime94.jsxs)(import_jsx_runtime94.Fragment, { children: [
    (0, import_jsx_runtime94.jsxs)(Header, { children: [
      (0, import_jsx_runtime94.jsx)(Title, { children: title }),
      (0, import_jsx_runtime94.jsx)(CloseButton, {})
    ] }),
    (0, import_jsx_runtime94.jsx)(Body, { style: { maxWidth: 350 }, children: body }),
    (0, import_jsx_runtime94.jsxs)(Footer, { className: "tlui-dialog__footer__actions", children: [
      displayDontShowAgain && (0, import_jsx_runtime94.jsx)(
        Button,
        {
          onClick: () => setDontShowAgain(!dontShowAgain),
          iconLeft: dontShowAgain ? "checkbox-checked" : "checkbox-empty",
          style: { marginRight: "auto" },
          children: `Don't show again`
        }
      ),
      (0, import_jsx_runtime94.jsx)(Button, { onClick: onCancel, children: cancel }),
      (0, import_jsx_runtime94.jsx)(Button, { type: "primary", onClick: async () => onContinue(), children: confirm })
    ] })
  ] });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/Dialogs.mjs
var import_jsx_runtime95 = __toESM(require_jsx_runtime(), 1);
var import_react73 = __toESM(require_react(), 1);
var Dialog = ({ id, component: ModalContent, onClose }) => {
  const { removeDialog } = useDialogs();
  const container = useContainer();
  const handleOpenChange = (0, import_react73.useCallback)(
    (isOpen) => {
      if (!isOpen) {
        if (onClose) {
          try {
            onClose();
          } catch (err) {
            console.warn(err);
          }
        }
        removeDialog(id);
      }
    },
    [id, onClose, removeDialog]
  );
  return (0, import_jsx_runtime95.jsx)(Root2, { onOpenChange: handleOpenChange, defaultOpen: true, children: (0, import_jsx_runtime95.jsx)(Portal2, { container, children: (0, import_jsx_runtime95.jsx)(Overlay, { dir: "ltr", className: "tlui-dialog__overlay", children: (0, import_jsx_runtime95.jsx)(Content, { dir: "ltr", className: "tlui-dialog__content", children: (0, import_jsx_runtime95.jsx)(ModalContent, { onClose: () => handleOpenChange(false) }) }) }) }) });
};
function _Dialogs() {
  const { dialogs } = useDialogs();
  return (0, import_jsx_runtime95.jsx)(import_jsx_runtime95.Fragment, { children: dialogs.map((dialog) => (0, import_jsx_runtime95.jsx)(Dialog, { ...dialog }, dialog.id)) });
}
var Dialogs = import_react73.default.memo(_Dialogs);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/FollowingIndicator.mjs
var import_jsx_runtime96 = __toESM(require_jsx_runtime(), 1);
function FollowingIndicator() {
  const editor = useEditor();
  const followingUserId = useValue("follow", () => editor.instanceState.followingUserId, [editor]);
  if (!followingUserId)
    return null;
  return (0, import_jsx_runtime96.jsx)(FollowingIndicatorInner, { userId: followingUserId });
}
function FollowingIndicatorInner({ userId }) {
  const presence = usePresence(userId);
  if (!presence)
    return null;
  return (0, import_jsx_runtime96.jsx)("div", { className: "tlui-following", style: { borderColor: presence.color } });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/HelpMenu.mjs
var import_jsx_runtime98 = __toESM(require_jsx_runtime(), 1);
var React49 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/LanguageMenu.mjs
var import_jsx_runtime97 = __toESM(require_jsx_runtime(), 1);
var import_react74 = __toESM(require_react(), 1);
function LanguageMenu() {
  const editor = useEditor();
  const { languages, currentLanguage } = useLanguages();
  const handleLanguageSelect = (0, import_react74.useCallback)(
    (locale) => editor.user.updateUserPreferences({ locale }),
    [editor]
  );
  return (0, import_jsx_runtime97.jsxs)(Sub3, { id: "help menu language", children: [
    (0, import_jsx_runtime97.jsx)(SubTrigger3, { label: "menu.language", "data-direction": "left" }),
    (0, import_jsx_runtime97.jsx)(SubContent3, { sideOffset: -4, children: (0, import_jsx_runtime97.jsx)(Group3, { children: languages.map(({ locale, label }) => (0, import_jsx_runtime97.jsx)(
      RadioItem2,
      {
        title: locale,
        checked: locale === currentLanguage,
        onSelect: () => handleLanguageSelect(locale),
        children: (0, import_jsx_runtime97.jsx)("span", { children: label })
      },
      locale
    )) }) })
  ] });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/HelpMenu.mjs
var HelpMenu = React49.memo(function HelpMenu2() {
  const container = useContainer();
  const msg2 = useTranslation();
  const [isOpen, onOpenChange] = useMenuIsOpen("help menu");
  return (0, import_jsx_runtime98.jsx)("div", { className: "tlui-help-menu", children: (0, import_jsx_runtime98.jsxs)(Root22, { dir: "ltr", open: isOpen, onOpenChange, modal: false, children: [
    (0, import_jsx_runtime98.jsx)(
      Trigger,
      {
        className: "tlui-button tlui-help-menu__button",
        dir: "ltr",
        title: msg2("help-menu.title"),
        children: (0, import_jsx_runtime98.jsx)(Icon, { icon: "question-mark" })
      }
    ),
    (0, import_jsx_runtime98.jsx)(Portal22, { container, dir: "ltr", children: (0, import_jsx_runtime98.jsx)(
      Content22,
      {
        className: "tlui-menu",
        side: "top",
        sideOffset: 8,
        align: "end",
        alignOffset: 0,
        collisionPadding: 4,
        children: (0, import_jsx_runtime98.jsx)(HelpMenuContent, {})
      }
    ) })
  ] }) });
});
function HelpMenuContent() {
  const menuSchema = useHelpMenuSchema();
  const isReadonly = useReadonly();
  function getHelpMenuItem(item) {
    if (isReadonly && !item.readonlyOk)
      return null;
    switch (item.type) {
      case "custom": {
        if (item.id === "LANGUAGE_MENU") {
          return (0, import_jsx_runtime98.jsx)(LanguageMenu, {}, "item");
        }
        break;
      }
      case "group": {
        return (0, import_jsx_runtime98.jsx)(Group3, { size: "small", children: item.children.map(getHelpMenuItem) }, item.id);
      }
      case "submenu": {
        return (0, import_jsx_runtime98.jsxs)(Sub3, { id: `help menu ${item.id}`, children: [
          (0, import_jsx_runtime98.jsx)(SubTrigger3, { label: item.label }),
          (0, import_jsx_runtime98.jsx)(SubContent3, { children: item.children.map(getHelpMenuItem) })
        ] }, item.id);
      }
      case "item": {
        const { id, kbd: kbd2, label, onSelect, icon } = item.actionItem;
        return (0, import_jsx_runtime98.jsx)(
          Item,
          {
            kbd: kbd2,
            label,
            onClick: () => onSelect("help-menu"),
            iconLeft: icon
          },
          id
        );
      }
    }
  }
  return (0, import_jsx_runtime98.jsx)(import_jsx_runtime98.Fragment, { children: menuSchema.map(getHelpMenuItem) });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/MenuZone.mjs
var import_jsx_runtime109 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/ActionsMenu.mjs
var import_jsx_runtime100 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@radix-ui+react-popover@1.0.6-rc.5/node_modules/@radix-ui/react-popover/dist/index.module.js
var import_react92 = __toESM(require_react());

// node_modules/.deno/@radix-ui+primitive@1.0.0/node_modules/@radix-ui/primitive/dist/index.module.js
function $e42e1063c40fb3ef$export$b9ecd428b558ff10(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
  return function handleEvent(event) {
    originalEventHandler === null || originalEventHandler === void 0 || originalEventHandler(event);
    if (checkForDefaultPrevented === false || !event.defaultPrevented)
      return ourEventHandler === null || ourEventHandler === void 0 ? void 0 : ourEventHandler(event);
  };
}

// node_modules/.deno/@radix-ui+react-compose-refs@1.0.0/node_modules/@radix-ui/react-compose-refs/dist/index.module.js
var import_react75 = __toESM(require_react());
function $6ed0406888f73fc4$var$setRef(ref, value) {
  if (typeof ref === "function")
    ref(value);
  else if (ref !== null && ref !== void 0)
    ref.current = value;
}
function $6ed0406888f73fc4$export$43e446d32b3d21af(...refs) {
  return (node) => refs.forEach(
    (ref) => $6ed0406888f73fc4$var$setRef(ref, node)
  );
}
function $6ed0406888f73fc4$export$c7b2cbe3552a0d05(...refs) {
  return (0, import_react75.useCallback)($6ed0406888f73fc4$export$43e446d32b3d21af(...refs), refs);
}

// node_modules/.deno/@radix-ui+react-context@1.0.0/node_modules/@radix-ui/react-context/dist/index.module.js
var import_react76 = __toESM(require_react());
function $c512c27ab02ef895$export$50c7b4e9d9f19c1(scopeName, createContextScopeDeps = []) {
  let defaultContexts = [];
  function $c512c27ab02ef895$export$fd42f52fd3ae1109(rootComponentName, defaultContext) {
    const BaseContext = (0, import_react76.createContext)(defaultContext);
    const index2 = defaultContexts.length;
    defaultContexts = [
      ...defaultContexts,
      defaultContext
    ];
    function Provider(props) {
      const { scope, children, ...context } = props;
      const Context = (scope === null || scope === void 0 ? void 0 : scope[scopeName][index2]) || BaseContext;
      const value = (0, import_react76.useMemo)(
        () => context,
        Object.values(context)
      );
      return (0, import_react76.createElement)(Context.Provider, {
        value
      }, children);
    }
    function useContext11(consumerName, scope) {
      const Context = (scope === null || scope === void 0 ? void 0 : scope[scopeName][index2]) || BaseContext;
      const context = (0, import_react76.useContext)(Context);
      if (context)
        return context;
      if (defaultContext !== void 0)
        return defaultContext;
      throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
    }
    Provider.displayName = rootComponentName + "Provider";
    return [
      Provider,
      useContext11
    ];
  }
  const createScope = () => {
    const scopeContexts = defaultContexts.map((defaultContext) => {
      return (0, import_react76.createContext)(defaultContext);
    });
    return function useScope(scope) {
      const contexts = (scope === null || scope === void 0 ? void 0 : scope[scopeName]) || scopeContexts;
      return (0, import_react76.useMemo)(
        () => ({
          [`__scope${scopeName}`]: {
            ...scope,
            [scopeName]: contexts
          }
        }),
        [
          scope,
          contexts
        ]
      );
    };
  };
  createScope.scopeName = scopeName;
  return [
    $c512c27ab02ef895$export$fd42f52fd3ae1109,
    $c512c27ab02ef895$var$composeContextScopes(createScope, ...createContextScopeDeps)
  ];
}
function $c512c27ab02ef895$var$composeContextScopes(...scopes) {
  const baseScope = scopes[0];
  if (scopes.length === 1)
    return baseScope;
  const createScope1 = () => {
    const scopeHooks = scopes.map(
      (createScope) => ({
        useScope: createScope(),
        scopeName: createScope.scopeName
      })
    );
    return function useComposedScopes(overrideScopes) {
      const nextScopes1 = scopeHooks.reduce((nextScopes, { useScope, scopeName }) => {
        const scopeProps = useScope(overrideScopes);
        const currentScope = scopeProps[`__scope${scopeName}`];
        return {
          ...nextScopes,
          ...currentScope
        };
      }, {});
      return (0, import_react76.useMemo)(
        () => ({
          [`__scope${baseScope.scopeName}`]: nextScopes1
        }),
        [
          nextScopes1
        ]
      );
    };
  };
  createScope1.scopeName = baseScope.scopeName;
  return createScope1;
}

// node_modules/.deno/@radix-ui+react-dismissable-layer@1.0.3/node_modules/@radix-ui/react-dismissable-layer/dist/index.module.js
var import_react81 = __toESM(require_react());

// node_modules/.deno/@radix-ui+react-primitive@1.0.2/node_modules/@radix-ui/react-primitive/dist/index.module.js
var import_react78 = __toESM(require_react());
var import_react_dom = __toESM(require_react_dom());

// node_modules/.deno/@radix-ui+react-slot@1.0.1/node_modules/@radix-ui/react-slot/dist/index.module.js
var import_react77 = __toESM(require_react());
var $5e63c961fc1ce211$export$8c6ed5c666ac1360 = (0, import_react77.forwardRef)((props, forwardedRef) => {
  const { children, ...slotProps } = props;
  const childrenArray = import_react77.Children.toArray(children);
  const slottable = childrenArray.find($5e63c961fc1ce211$var$isSlottable);
  if (slottable) {
    const newElement = slottable.props.children;
    const newChildren = childrenArray.map((child) => {
      if (child === slottable) {
        if (import_react77.Children.count(newElement) > 1)
          return import_react77.Children.only(null);
        return (0, import_react77.isValidElement)(newElement) ? newElement.props.children : null;
      } else
        return child;
    });
    return (0, import_react77.createElement)($5e63c961fc1ce211$var$SlotClone, _extends({}, slotProps, {
      ref: forwardedRef
    }), (0, import_react77.isValidElement)(newElement) ? (0, import_react77.cloneElement)(newElement, void 0, newChildren) : null);
  }
  return (0, import_react77.createElement)($5e63c961fc1ce211$var$SlotClone, _extends({}, slotProps, {
    ref: forwardedRef
  }), children);
});
$5e63c961fc1ce211$export$8c6ed5c666ac1360.displayName = "Slot";
var $5e63c961fc1ce211$var$SlotClone = (0, import_react77.forwardRef)((props, forwardedRef) => {
  const { children, ...slotProps } = props;
  if ((0, import_react77.isValidElement)(children))
    return (0, import_react77.cloneElement)(children, {
      ...$5e63c961fc1ce211$var$mergeProps(slotProps, children.props),
      ref: $6ed0406888f73fc4$export$43e446d32b3d21af(forwardedRef, children.ref)
    });
  return import_react77.Children.count(children) > 1 ? import_react77.Children.only(null) : null;
});
$5e63c961fc1ce211$var$SlotClone.displayName = "SlotClone";
var $5e63c961fc1ce211$export$d9f1ccf0bdb05d45 = ({ children }) => {
  return (0, import_react77.createElement)(import_react77.Fragment, null, children);
};
function $5e63c961fc1ce211$var$isSlottable(child) {
  return (0, import_react77.isValidElement)(child) && child.type === $5e63c961fc1ce211$export$d9f1ccf0bdb05d45;
}
function $5e63c961fc1ce211$var$mergeProps(slotProps, childProps) {
  const overrideProps = {
    ...childProps
  };
  for (const propName in childProps) {
    const slotPropValue = slotProps[propName];
    const childPropValue = childProps[propName];
    const isHandler = /^on[A-Z]/.test(propName);
    if (isHandler) {
      if (slotPropValue && childPropValue)
        overrideProps[propName] = (...args) => {
          childPropValue(...args);
          slotPropValue(...args);
        };
      else if (slotPropValue)
        overrideProps[propName] = slotPropValue;
    } else if (propName === "style")
      overrideProps[propName] = {
        ...slotPropValue,
        ...childPropValue
      };
    else if (propName === "className")
      overrideProps[propName] = [
        slotPropValue,
        childPropValue
      ].filter(Boolean).join(" ");
  }
  return {
    ...slotProps,
    ...overrideProps
  };
}

// node_modules/.deno/@radix-ui+react-primitive@1.0.2/node_modules/@radix-ui/react-primitive/dist/index.module.js
var $8927f6f2acc4f386$var$NODES = [
  "a",
  "button",
  "div",
  "form",
  "h2",
  "h3",
  "img",
  "input",
  "label",
  "li",
  "nav",
  "ol",
  "p",
  "span",
  "svg",
  "ul"
];
var $8927f6f2acc4f386$export$250ffa63cdc0d034 = $8927f6f2acc4f386$var$NODES.reduce((primitive, node) => {
  const Node2 = (0, import_react78.forwardRef)((props, forwardedRef) => {
    const { asChild, ...primitiveProps } = props;
    const Comp = asChild ? $5e63c961fc1ce211$export$8c6ed5c666ac1360 : node;
    (0, import_react78.useEffect)(() => {
      window[Symbol.for("radix-ui")] = true;
    }, []);
    return (0, import_react78.createElement)(Comp, _extends({}, primitiveProps, {
      ref: forwardedRef
    }));
  });
  Node2.displayName = `Primitive.${node}`;
  return {
    ...primitive,
    [node]: Node2
  };
}, {});
function $8927f6f2acc4f386$export$6d1a0317bde7de7f(target, event) {
  if (target)
    (0, import_react_dom.flushSync)(
      () => target.dispatchEvent(event)
    );
}

// node_modules/.deno/@radix-ui+react-use-callback-ref@1.0.0/node_modules/@radix-ui/react-use-callback-ref/dist/index.module.js
var import_react79 = __toESM(require_react());
function $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(callback) {
  const callbackRef = (0, import_react79.useRef)(callback);
  (0, import_react79.useEffect)(() => {
    callbackRef.current = callback;
  });
  return (0, import_react79.useMemo)(
    () => (...args) => {
      var _callbackRef$current;
      return (_callbackRef$current = callbackRef.current) === null || _callbackRef$current === void 0 ? void 0 : _callbackRef$current.call(callbackRef, ...args);
    },
    []
  );
}

// node_modules/.deno/@radix-ui+react-use-escape-keydown@1.0.2/node_modules/@radix-ui/react-use-escape-keydown/dist/index.module.js
var import_react80 = __toESM(require_react());
function $addc16e1bbe58fd0$export$3a72a57244d6e765(onEscapeKeyDownProp, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
  const onEscapeKeyDown = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onEscapeKeyDownProp);
  (0, import_react80.useEffect)(() => {
    const handleKeyDown = (event) => {
      if (event.key === "Escape")
        onEscapeKeyDown(event);
    };
    ownerDocument.addEventListener("keydown", handleKeyDown);
    return () => ownerDocument.removeEventListener("keydown", handleKeyDown);
  }, [
    onEscapeKeyDown,
    ownerDocument
  ]);
}

// node_modules/.deno/@radix-ui+react-dismissable-layer@1.0.3/node_modules/@radix-ui/react-dismissable-layer/dist/index.module.js
var $5cb92bef7577960e$var$DISMISSABLE_LAYER_NAME = "DismissableLayer";
var $5cb92bef7577960e$var$CONTEXT_UPDATE = "dismissableLayer.update";
var $5cb92bef7577960e$var$POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
var $5cb92bef7577960e$var$FOCUS_OUTSIDE = "dismissableLayer.focusOutside";
var $5cb92bef7577960e$var$originalBodyPointerEvents;
var $5cb92bef7577960e$var$DismissableLayerContext = (0, import_react81.createContext)({
  layers: /* @__PURE__ */ new Set(),
  layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
  branches: /* @__PURE__ */ new Set()
});
var $5cb92bef7577960e$export$177fb62ff3ec1f22 = (0, import_react81.forwardRef)((props, forwardedRef) => {
  var _node$ownerDocument;
  const { disableOutsidePointerEvents = false, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, ...layerProps } = props;
  const context = (0, import_react81.useContext)($5cb92bef7577960e$var$DismissableLayerContext);
  const [node1, setNode] = (0, import_react81.useState)(null);
  const ownerDocument = (_node$ownerDocument = node1 === null || node1 === void 0 ? void 0 : node1.ownerDocument) !== null && _node$ownerDocument !== void 0 ? _node$ownerDocument : globalThis === null || globalThis === void 0 ? void 0 : globalThis.document;
  const [, force] = (0, import_react81.useState)({});
  const composedRefs = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(
    forwardedRef,
    (node) => setNode(node)
  );
  const layers = Array.from(context.layers);
  const [highestLayerWithOutsidePointerEventsDisabled] = [
    ...context.layersWithOutsidePointerEventsDisabled
  ].slice(-1);
  const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
  const index2 = node1 ? layers.indexOf(node1) : -1;
  const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
  const isPointerEventsEnabled = index2 >= highestLayerWithOutsidePointerEventsDisabledIndex;
  const pointerDownOutside = $5cb92bef7577960e$var$usePointerDownOutside((event) => {
    const target = event.target;
    const isPointerDownOnBranch = [
      ...context.branches
    ].some(
      (branch) => branch.contains(target)
    );
    if (!isPointerEventsEnabled || isPointerDownOnBranch)
      return;
    onPointerDownOutside === null || onPointerDownOutside === void 0 || onPointerDownOutside(event);
    onInteractOutside === null || onInteractOutside === void 0 || onInteractOutside(event);
    if (!event.defaultPrevented)
      onDismiss === null || onDismiss === void 0 || onDismiss();
  }, ownerDocument);
  const focusOutside = $5cb92bef7577960e$var$useFocusOutside((event) => {
    const target = event.target;
    const isFocusInBranch = [
      ...context.branches
    ].some(
      (branch) => branch.contains(target)
    );
    if (isFocusInBranch)
      return;
    onFocusOutside === null || onFocusOutside === void 0 || onFocusOutside(event);
    onInteractOutside === null || onInteractOutside === void 0 || onInteractOutside(event);
    if (!event.defaultPrevented)
      onDismiss === null || onDismiss === void 0 || onDismiss();
  }, ownerDocument);
  $addc16e1bbe58fd0$export$3a72a57244d6e765((event) => {
    const isHighestLayer = index2 === context.layers.size - 1;
    if (!isHighestLayer)
      return;
    onEscapeKeyDown === null || onEscapeKeyDown === void 0 || onEscapeKeyDown(event);
    if (!event.defaultPrevented && onDismiss) {
      event.preventDefault();
      onDismiss();
    }
  }, ownerDocument);
  (0, import_react81.useEffect)(() => {
    if (!node1)
      return;
    if (disableOutsidePointerEvents) {
      if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
        $5cb92bef7577960e$var$originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
        ownerDocument.body.style.pointerEvents = "none";
      }
      context.layersWithOutsidePointerEventsDisabled.add(node1);
    }
    context.layers.add(node1);
    $5cb92bef7577960e$var$dispatchUpdate();
    return () => {
      if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1)
        ownerDocument.body.style.pointerEvents = $5cb92bef7577960e$var$originalBodyPointerEvents;
    };
  }, [
    node1,
    ownerDocument,
    disableOutsidePointerEvents,
    context
  ]);
  (0, import_react81.useEffect)(() => {
    return () => {
      if (!node1)
        return;
      context.layers.delete(node1);
      context.layersWithOutsidePointerEventsDisabled.delete(node1);
      $5cb92bef7577960e$var$dispatchUpdate();
    };
  }, [
    node1,
    context
  ]);
  (0, import_react81.useEffect)(() => {
    const handleUpdate = () => force({});
    document.addEventListener($5cb92bef7577960e$var$CONTEXT_UPDATE, handleUpdate);
    return () => document.removeEventListener($5cb92bef7577960e$var$CONTEXT_UPDATE, handleUpdate);
  }, []);
  return (0, import_react81.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.div, _extends({}, layerProps, {
    ref: composedRefs,
    style: {
      pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
      ...props.style
    },
    onFocusCapture: $e42e1063c40fb3ef$export$b9ecd428b558ff10(props.onFocusCapture, focusOutside.onFocusCapture),
    onBlurCapture: $e42e1063c40fb3ef$export$b9ecd428b558ff10(props.onBlurCapture, focusOutside.onBlurCapture),
    onPointerDownCapture: $e42e1063c40fb3ef$export$b9ecd428b558ff10(props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture)
  }));
});
Object.assign($5cb92bef7577960e$export$177fb62ff3ec1f22, {
  displayName: $5cb92bef7577960e$var$DISMISSABLE_LAYER_NAME
});
var $5cb92bef7577960e$var$BRANCH_NAME = "DismissableLayerBranch";
var $5cb92bef7577960e$export$4d5eb2109db14228 = (0, import_react81.forwardRef)((props, forwardedRef) => {
  const context = (0, import_react81.useContext)($5cb92bef7577960e$var$DismissableLayerContext);
  const ref = (0, import_react81.useRef)(null);
  const composedRefs = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(forwardedRef, ref);
  (0, import_react81.useEffect)(() => {
    const node = ref.current;
    if (node) {
      context.branches.add(node);
      return () => {
        context.branches.delete(node);
      };
    }
  }, [
    context.branches
  ]);
  return (0, import_react81.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.div, _extends({}, props, {
    ref: composedRefs
  }));
});
Object.assign($5cb92bef7577960e$export$4d5eb2109db14228, {
  displayName: $5cb92bef7577960e$var$BRANCH_NAME
});
function $5cb92bef7577960e$var$usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
  const handlePointerDownOutside = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onPointerDownOutside);
  const isPointerInsideReactTreeRef = (0, import_react81.useRef)(false);
  const handleClickRef = (0, import_react81.useRef)(() => {
  });
  (0, import_react81.useEffect)(() => {
    const handlePointerDown = (event) => {
      if (event.target && !isPointerInsideReactTreeRef.current) {
        let handleAndDispatchPointerDownOutsideEvent = function() {
          $5cb92bef7577960e$var$handleAndDispatchCustomEvent($5cb92bef7577960e$var$POINTER_DOWN_OUTSIDE, handlePointerDownOutside, eventDetail, {
            discrete: true
          });
        };
        const eventDetail = {
          originalEvent: event
        };
        if (event.pointerType === "touch") {
          ownerDocument.removeEventListener("click", handleClickRef.current);
          handleClickRef.current = handleAndDispatchPointerDownOutsideEvent;
          ownerDocument.addEventListener("click", handleClickRef.current, {
            once: true
          });
        } else
          handleAndDispatchPointerDownOutsideEvent();
      }
      isPointerInsideReactTreeRef.current = false;
    };
    const timerId = window.setTimeout(() => {
      ownerDocument.addEventListener("pointerdown", handlePointerDown);
    }, 0);
    return () => {
      window.clearTimeout(timerId);
      ownerDocument.removeEventListener("pointerdown", handlePointerDown);
      ownerDocument.removeEventListener("click", handleClickRef.current);
    };
  }, [
    ownerDocument,
    handlePointerDownOutside
  ]);
  return {
    // ensures we check React component tree (not just DOM tree)
    onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true
  };
}
function $5cb92bef7577960e$var$useFocusOutside(onFocusOutside, ownerDocument = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) {
  const handleFocusOutside = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onFocusOutside);
  const isFocusInsideReactTreeRef = (0, import_react81.useRef)(false);
  (0, import_react81.useEffect)(() => {
    const handleFocus = (event) => {
      if (event.target && !isFocusInsideReactTreeRef.current) {
        const eventDetail = {
          originalEvent: event
        };
        $5cb92bef7577960e$var$handleAndDispatchCustomEvent($5cb92bef7577960e$var$FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {
          discrete: false
        });
      }
    };
    ownerDocument.addEventListener("focusin", handleFocus);
    return () => ownerDocument.removeEventListener("focusin", handleFocus);
  }, [
    ownerDocument,
    handleFocusOutside
  ]);
  return {
    onFocusCapture: () => isFocusInsideReactTreeRef.current = true,
    onBlurCapture: () => isFocusInsideReactTreeRef.current = false
  };
}
function $5cb92bef7577960e$var$dispatchUpdate() {
  const event = new CustomEvent($5cb92bef7577960e$var$CONTEXT_UPDATE);
  document.dispatchEvent(event);
}
function $5cb92bef7577960e$var$handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
  const target = detail.originalEvent.target;
  const event = new CustomEvent(name, {
    bubbles: false,
    cancelable: true,
    detail
  });
  if (handler)
    target.addEventListener(name, handler, {
      once: true
    });
  if (discrete)
    $8927f6f2acc4f386$export$6d1a0317bde7de7f(target, event);
  else
    target.dispatchEvent(event);
}

// node_modules/.deno/@radix-ui+react-focus-guards@1.0.0/node_modules/@radix-ui/react-focus-guards/dist/index.module.js
var import_react82 = __toESM(require_react());
var $3db38b7d1fb3fe6a$var$count = 0;
function $3db38b7d1fb3fe6a$export$b7ece24a22aeda8c() {
  (0, import_react82.useEffect)(() => {
    var _edgeGuards$, _edgeGuards$2;
    const edgeGuards = document.querySelectorAll("[data-radix-focus-guard]");
    document.body.insertAdjacentElement("afterbegin", (_edgeGuards$ = edgeGuards[0]) !== null && _edgeGuards$ !== void 0 ? _edgeGuards$ : $3db38b7d1fb3fe6a$var$createFocusGuard());
    document.body.insertAdjacentElement("beforeend", (_edgeGuards$2 = edgeGuards[1]) !== null && _edgeGuards$2 !== void 0 ? _edgeGuards$2 : $3db38b7d1fb3fe6a$var$createFocusGuard());
    $3db38b7d1fb3fe6a$var$count++;
    return () => {
      if ($3db38b7d1fb3fe6a$var$count === 1)
        document.querySelectorAll("[data-radix-focus-guard]").forEach(
          (node) => node.remove()
        );
      $3db38b7d1fb3fe6a$var$count--;
    };
  }, []);
}
function $3db38b7d1fb3fe6a$var$createFocusGuard() {
  const element = document.createElement("span");
  element.setAttribute("data-radix-focus-guard", "");
  element.tabIndex = 0;
  element.style.cssText = "outline: none; opacity: 0; position: fixed; pointer-events: none";
  return element;
}

// node_modules/.deno/@radix-ui+react-focus-scope@1.0.2/node_modules/@radix-ui/react-focus-scope/dist/index.module.js
var import_react83 = __toESM(require_react());
var $d3863c46a17e8a28$var$AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
var $d3863c46a17e8a28$var$AUTOFOCUS_ON_UNMOUNT = "focusScope.autoFocusOnUnmount";
var $d3863c46a17e8a28$var$EVENT_OPTIONS = {
  bubbles: false,
  cancelable: true
};
var $d3863c46a17e8a28$var$FOCUS_SCOPE_NAME = "FocusScope";
var $d3863c46a17e8a28$export$20e40289641fbbb6 = (0, import_react83.forwardRef)((props, forwardedRef) => {
  const { loop = false, trapped = false, onMountAutoFocus: onMountAutoFocusProp, onUnmountAutoFocus: onUnmountAutoFocusProp, ...scopeProps } = props;
  const [container1, setContainer] = (0, import_react83.useState)(null);
  const onMountAutoFocus = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onMountAutoFocusProp);
  const onUnmountAutoFocus = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onUnmountAutoFocusProp);
  const lastFocusedElementRef = (0, import_react83.useRef)(null);
  const composedRefs = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(
    forwardedRef,
    (node) => setContainer(node)
  );
  const focusScope = (0, import_react83.useRef)({
    paused: false,
    pause() {
      this.paused = true;
    },
    resume() {
      this.paused = false;
    }
  }).current;
  (0, import_react83.useEffect)(() => {
    if (trapped) {
      let handleFocusIn = function(event) {
        if (focusScope.paused || !container1)
          return;
        const target = event.target;
        if (container1.contains(target))
          lastFocusedElementRef.current = target;
        else
          $d3863c46a17e8a28$var$focus(lastFocusedElementRef.current, {
            select: true
          });
      }, handleFocusOut = function(event) {
        if (focusScope.paused || !container1)
          return;
        if (!container1.contains(event.relatedTarget))
          $d3863c46a17e8a28$var$focus(lastFocusedElementRef.current, {
            select: true
          });
      };
      document.addEventListener("focusin", handleFocusIn);
      document.addEventListener("focusout", handleFocusOut);
      return () => {
        document.removeEventListener("focusin", handleFocusIn);
        document.removeEventListener("focusout", handleFocusOut);
      };
    }
  }, [
    trapped,
    container1,
    focusScope.paused
  ]);
  (0, import_react83.useEffect)(() => {
    if (container1) {
      $d3863c46a17e8a28$var$focusScopesStack.add(focusScope);
      const previouslyFocusedElement = document.activeElement;
      const hasFocusedCandidate = container1.contains(previouslyFocusedElement);
      if (!hasFocusedCandidate) {
        const mountEvent = new CustomEvent($d3863c46a17e8a28$var$AUTOFOCUS_ON_MOUNT, $d3863c46a17e8a28$var$EVENT_OPTIONS);
        container1.addEventListener($d3863c46a17e8a28$var$AUTOFOCUS_ON_MOUNT, onMountAutoFocus);
        container1.dispatchEvent(mountEvent);
        if (!mountEvent.defaultPrevented) {
          $d3863c46a17e8a28$var$focusFirst($d3863c46a17e8a28$var$removeLinks($d3863c46a17e8a28$var$getTabbableCandidates(container1)), {
            select: true
          });
          if (document.activeElement === previouslyFocusedElement)
            $d3863c46a17e8a28$var$focus(container1);
        }
      }
      return () => {
        container1.removeEventListener($d3863c46a17e8a28$var$AUTOFOCUS_ON_MOUNT, onMountAutoFocus);
        setTimeout(() => {
          const unmountEvent = new CustomEvent($d3863c46a17e8a28$var$AUTOFOCUS_ON_UNMOUNT, $d3863c46a17e8a28$var$EVENT_OPTIONS);
          container1.addEventListener($d3863c46a17e8a28$var$AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);
          container1.dispatchEvent(unmountEvent);
          if (!unmountEvent.defaultPrevented)
            $d3863c46a17e8a28$var$focus(previouslyFocusedElement !== null && previouslyFocusedElement !== void 0 ? previouslyFocusedElement : document.body, {
              select: true
            });
          container1.removeEventListener($d3863c46a17e8a28$var$AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);
          $d3863c46a17e8a28$var$focusScopesStack.remove(focusScope);
        }, 0);
      };
    }
  }, [
    container1,
    onMountAutoFocus,
    onUnmountAutoFocus,
    focusScope
  ]);
  const handleKeyDown = (0, import_react83.useCallback)((event) => {
    if (!loop && !trapped)
      return;
    if (focusScope.paused)
      return;
    const isTabKey = event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey;
    const focusedElement = document.activeElement;
    if (isTabKey && focusedElement) {
      const container = event.currentTarget;
      const [first, last2] = $d3863c46a17e8a28$var$getTabbableEdges(container);
      const hasTabbableElementsInside = first && last2;
      if (!hasTabbableElementsInside) {
        if (focusedElement === container)
          event.preventDefault();
      } else {
        if (!event.shiftKey && focusedElement === last2) {
          event.preventDefault();
          if (loop)
            $d3863c46a17e8a28$var$focus(first, {
              select: true
            });
        } else if (event.shiftKey && focusedElement === first) {
          event.preventDefault();
          if (loop)
            $d3863c46a17e8a28$var$focus(last2, {
              select: true
            });
        }
      }
    }
  }, [
    loop,
    trapped,
    focusScope.paused
  ]);
  return (0, import_react83.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.div, _extends({
    tabIndex: -1
  }, scopeProps, {
    ref: composedRefs,
    onKeyDown: handleKeyDown
  }));
});
Object.assign($d3863c46a17e8a28$export$20e40289641fbbb6, {
  displayName: $d3863c46a17e8a28$var$FOCUS_SCOPE_NAME
});
function $d3863c46a17e8a28$var$focusFirst(candidates, { select = false } = {}) {
  const previouslyFocusedElement = document.activeElement;
  for (const candidate of candidates) {
    $d3863c46a17e8a28$var$focus(candidate, {
      select
    });
    if (document.activeElement !== previouslyFocusedElement)
      return;
  }
}
function $d3863c46a17e8a28$var$getTabbableEdges(container) {
  const candidates = $d3863c46a17e8a28$var$getTabbableCandidates(container);
  const first = $d3863c46a17e8a28$var$findVisible(candidates, container);
  const last2 = $d3863c46a17e8a28$var$findVisible(candidates.reverse(), container);
  return [
    first,
    last2
  ];
}
function $d3863c46a17e8a28$var$getTabbableCandidates(container) {
  const nodes = [];
  const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
    acceptNode: (node) => {
      const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
      if (node.disabled || node.hidden || isHiddenInput)
        return NodeFilter.FILTER_SKIP;
      return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    }
  });
  while (walker.nextNode())
    nodes.push(walker.currentNode);
  return nodes;
}
function $d3863c46a17e8a28$var$findVisible(elements, container) {
  for (const element of elements) {
    if (!$d3863c46a17e8a28$var$isHidden(element, {
      upTo: container
    }))
      return element;
  }
}
function $d3863c46a17e8a28$var$isHidden(node, { upTo }) {
  if (getComputedStyle(node).visibility === "hidden")
    return true;
  while (node) {
    if (upTo !== void 0 && node === upTo)
      return false;
    if (getComputedStyle(node).display === "none")
      return true;
    node = node.parentElement;
  }
  return false;
}
function $d3863c46a17e8a28$var$isSelectableInput(element) {
  return element instanceof HTMLInputElement && "select" in element;
}
function $d3863c46a17e8a28$var$focus(element, { select = false } = {}) {
  if (element && element.focus) {
    const previouslyFocusedElement = document.activeElement;
    element.focus({
      preventScroll: true
    });
    if (element !== previouslyFocusedElement && $d3863c46a17e8a28$var$isSelectableInput(element) && select)
      element.select();
  }
}
var $d3863c46a17e8a28$var$focusScopesStack = $d3863c46a17e8a28$var$createFocusScopesStack();
function $d3863c46a17e8a28$var$createFocusScopesStack() {
  let stack3 = [];
  return {
    add(focusScope) {
      const activeFocusScope = stack3[0];
      if (focusScope !== activeFocusScope)
        activeFocusScope === null || activeFocusScope === void 0 || activeFocusScope.pause();
      stack3 = $d3863c46a17e8a28$var$arrayRemove(stack3, focusScope);
      stack3.unshift(focusScope);
    },
    remove(focusScope) {
      var _stack$;
      stack3 = $d3863c46a17e8a28$var$arrayRemove(stack3, focusScope);
      (_stack$ = stack3[0]) === null || _stack$ === void 0 || _stack$.resume();
    }
  };
}
function $d3863c46a17e8a28$var$arrayRemove(array2, item) {
  const updatedArray = [
    ...array2
  ];
  const index2 = updatedArray.indexOf(item);
  if (index2 !== -1)
    updatedArray.splice(index2, 1);
  return updatedArray;
}
function $d3863c46a17e8a28$var$removeLinks(items) {
  return items.filter(
    (item) => item.tagName !== "A"
  );
}

// node_modules/.deno/@radix-ui+react-id@1.0.0/node_modules/@radix-ui/react-id/dist/index.module.js
var $2AODx$react = __toESM(require_react());

// node_modules/.deno/@radix-ui+react-use-layout-effect@1.0.0/node_modules/@radix-ui/react-use-layout-effect/dist/index.module.js
var import_react84 = __toESM(require_react());
var $9f79659886946c16$export$e5c5a5f917a5871c = Boolean(globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) ? import_react84.useLayoutEffect : () => {
};

// node_modules/.deno/@radix-ui+react-id@1.0.0/node_modules/@radix-ui/react-id/dist/index.module.js
var $1746a345f3d73bb7$var$useReactId = $2AODx$react["useId".toString()] || (() => void 0);
var $1746a345f3d73bb7$var$count = 0;
function $1746a345f3d73bb7$export$f680877a34711e37(deterministicId) {
  const [id, setId] = $2AODx$react.useState($1746a345f3d73bb7$var$useReactId());
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    if (!deterministicId)
      setId(
        (reactId) => reactId !== null && reactId !== void 0 ? reactId : String($1746a345f3d73bb7$var$count++)
      );
  }, [
    deterministicId
  ]);
  return deterministicId || (id ? `radix-${id}` : "");
}

// node_modules/.deno/@radix-ui+react-popper@1.1.2-rc.5/node_modules/@radix-ui/react-popper/dist/index.module.js
var import_react88 = __toESM(require_react());

// node_modules/.deno/@floating-ui+core@0.7.3/node_modules/@floating-ui/core/dist/floating-ui.core.browser.mjs
function getSide(placement) {
  return placement.split("-")[0];
}
function getAlignment(placement) {
  return placement.split("-")[1];
}
function getMainAxisFromPlacement(placement) {
  return ["top", "bottom"].includes(getSide(placement)) ? "x" : "y";
}
function getLengthFromAxis(axis) {
  return axis === "y" ? "height" : "width";
}
function computeCoordsFromPlacement(_ref, placement, rtl) {
  let {
    reference,
    floating
  } = _ref;
  const commonX = reference.x + reference.width / 2 - floating.width / 2;
  const commonY = reference.y + reference.height / 2 - floating.height / 2;
  const mainAxis = getMainAxisFromPlacement(placement);
  const length = getLengthFromAxis(mainAxis);
  const commonAlign = reference[length] / 2 - floating[length] / 2;
  const side = getSide(placement);
  const isVertical = mainAxis === "x";
  let coords;
  switch (side) {
    case "top":
      coords = {
        x: commonX,
        y: reference.y - floating.height
      };
      break;
    case "bottom":
      coords = {
        x: commonX,
        y: reference.y + reference.height
      };
      break;
    case "right":
      coords = {
        x: reference.x + reference.width,
        y: commonY
      };
      break;
    case "left":
      coords = {
        x: reference.x - floating.width,
        y: commonY
      };
      break;
    default:
      coords = {
        x: reference.x,
        y: reference.y
      };
  }
  switch (getAlignment(placement)) {
    case "start":
      coords[mainAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
      break;
    case "end":
      coords[mainAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
      break;
  }
  return coords;
}
var computePosition = async (reference, floating, config) => {
  const {
    placement = "bottom",
    strategy = "absolute",
    middleware = [],
    platform: platform2
  } = config;
  const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
  {
    if (platform2 == null) {
      console.error(["Floating UI: `platform` property was not passed to config. If you", "want to use Floating UI on the web, install @floating-ui/dom", "instead of the /core package. Otherwise, you can create your own", "`platform`: https://floating-ui.com/docs/platform"].join(" "));
    }
    if (middleware.filter((_ref) => {
      let {
        name
      } = _ref;
      return name === "autoPlacement" || name === "flip";
    }).length > 1) {
      throw new Error(["Floating UI: duplicate `flip` and/or `autoPlacement`", "middleware detected. This will lead to an infinite loop. Ensure only", "one of either has been passed to the `middleware` array."].join(" "));
    }
  }
  let rects = await platform2.getElementRects({
    reference,
    floating,
    strategy
  });
  let {
    x,
    y
  } = computeCoordsFromPlacement(rects, placement, rtl);
  let statefulPlacement = placement;
  let middlewareData = {};
  let resetCount = 0;
  for (let i = 0; i < middleware.length; i++) {
    const {
      name,
      fn
    } = middleware[i];
    const {
      x: nextX,
      y: nextY,
      data,
      reset
    } = await fn({
      x,
      y,
      initialPlacement: placement,
      placement: statefulPlacement,
      strategy,
      middlewareData,
      rects,
      platform: platform2,
      elements: {
        reference,
        floating
      }
    });
    x = nextX != null ? nextX : x;
    y = nextY != null ? nextY : y;
    middlewareData = {
      ...middlewareData,
      [name]: {
        ...middlewareData[name],
        ...data
      }
    };
    {
      if (resetCount > 50) {
        console.warn(["Floating UI: The middleware lifecycle appears to be running in an", "infinite loop. This is usually caused by a `reset` continually", "being returned without a break condition."].join(" "));
      }
    }
    if (reset && resetCount <= 50) {
      resetCount++;
      if (typeof reset === "object") {
        if (reset.placement) {
          statefulPlacement = reset.placement;
        }
        if (reset.rects) {
          rects = reset.rects === true ? await platform2.getElementRects({
            reference,
            floating,
            strategy
          }) : reset.rects;
        }
        ({
          x,
          y
        } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
      }
      i = -1;
      continue;
    }
  }
  return {
    x,
    y,
    placement: statefulPlacement,
    strategy,
    middlewareData
  };
};
function expandPaddingObject(padding) {
  return {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    ...padding
  };
}
function getSideObjectFromPadding(padding) {
  return typeof padding !== "number" ? expandPaddingObject(padding) : {
    top: padding,
    right: padding,
    bottom: padding,
    left: padding
  };
}
function rectToClientRect(rect) {
  return {
    ...rect,
    top: rect.y,
    left: rect.x,
    right: rect.x + rect.width,
    bottom: rect.y + rect.height
  };
}
async function detectOverflow(middlewareArguments, options) {
  var _await$platform$isEle;
  if (options === void 0) {
    options = {};
  }
  const {
    x,
    y,
    platform: platform2,
    rects,
    elements,
    strategy
  } = middlewareArguments;
  const {
    boundary = "clippingAncestors",
    rootBoundary = "viewport",
    elementContext = "floating",
    altBoundary = false,
    padding = 0
  } = options;
  const paddingObject = getSideObjectFromPadding(padding);
  const altContext = elementContext === "floating" ? "reference" : "floating";
  const element = elements[altBoundary ? altContext : elementContext];
  const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
    element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
    boundary,
    rootBoundary,
    strategy
  }));
  const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
    rect: elementContext === "floating" ? {
      ...rects.floating,
      x,
      y
    } : rects.reference,
    offsetParent: await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating)),
    strategy
  }) : rects[elementContext]);
  return {
    top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
    bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
    left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
    right: elementClientRect.right - clippingClientRect.right + paddingObject.right
  };
}
var min2 = Math.min;
var max = Math.max;
function within(min$1, value, max$1) {
  return max(min$1, min2(value, max$1));
}
var arrow = (options) => ({
  name: "arrow",
  options,
  async fn(middlewareArguments) {
    const {
      element,
      padding = 0
    } = options != null ? options : {};
    const {
      x,
      y,
      placement,
      rects,
      platform: platform2
    } = middlewareArguments;
    if (element == null) {
      {
        console.warn("Floating UI: No `element` was passed to the `arrow` middleware.");
      }
      return {};
    }
    const paddingObject = getSideObjectFromPadding(padding);
    const coords = {
      x,
      y
    };
    const axis = getMainAxisFromPlacement(placement);
    const alignment = getAlignment(placement);
    const length = getLengthFromAxis(axis);
    const arrowDimensions = await platform2.getDimensions(element);
    const minProp = axis === "y" ? "top" : "left";
    const maxProp = axis === "y" ? "bottom" : "right";
    const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length];
    const startDiff = coords[axis] - rects.reference[axis];
    const arrowOffsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(element));
    let clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
    if (clientSize === 0) {
      clientSize = rects.floating[length];
    }
    const centerToReference = endDiff / 2 - startDiff / 2;
    const min4 = paddingObject[minProp];
    const max3 = clientSize - arrowDimensions[length] - paddingObject[maxProp];
    const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
    const offset2 = within(min4, center, max3);
    const alignmentPadding = alignment === "start" ? paddingObject[minProp] : paddingObject[maxProp];
    const shouldAddOffset = alignmentPadding > 0 && center !== offset2 && rects.reference[length] <= rects.floating[length];
    const alignmentOffset = shouldAddOffset ? center < min4 ? min4 - center : max3 - center : 0;
    return {
      [axis]: coords[axis] - alignmentOffset,
      data: {
        [axis]: offset2,
        centerOffset: center - offset2
      }
    };
  }
});
var hash$1 = {
  left: "right",
  right: "left",
  bottom: "top",
  top: "bottom"
};
function getOppositePlacement(placement) {
  return placement.replace(/left|right|bottom|top/g, (matched) => hash$1[matched]);
}
function getAlignmentSides(placement, rects, rtl) {
  if (rtl === void 0) {
    rtl = false;
  }
  const alignment = getAlignment(placement);
  const mainAxis = getMainAxisFromPlacement(placement);
  const length = getLengthFromAxis(mainAxis);
  let mainAlignmentSide = mainAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
  if (rects.reference[length] > rects.floating[length]) {
    mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
  }
  return {
    main: mainAlignmentSide,
    cross: getOppositePlacement(mainAlignmentSide)
  };
}
var hash = {
  start: "end",
  end: "start"
};
function getOppositeAlignmentPlacement(placement) {
  return placement.replace(/start|end/g, (matched) => hash[matched]);
}
var sides = ["top", "right", "bottom", "left"];
var allPlacements = sides.reduce((acc, side) => acc.concat(side, side + "-start", side + "-end"), []);
function getExpandedPlacements(placement) {
  const oppositePlacement = getOppositePlacement(placement);
  return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
var flip = function(options) {
  if (options === void 0) {
    options = {};
  }
  return {
    name: "flip",
    options,
    async fn(middlewareArguments) {
      var _middlewareData$flip;
      const {
        placement,
        middlewareData,
        rects,
        initialPlacement,
        platform: platform2,
        elements
      } = middlewareArguments;
      const {
        mainAxis: checkMainAxis = true,
        crossAxis: checkCrossAxis = true,
        fallbackPlacements: specifiedFallbackPlacements,
        fallbackStrategy = "bestFit",
        flipAlignment = true,
        ...detectOverflowOptions
      } = options;
      const side = getSide(placement);
      const isBasePlacement = side === initialPlacement;
      const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
      const placements = [initialPlacement, ...fallbackPlacements];
      const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
      const overflows = [];
      let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
      if (checkMainAxis) {
        overflows.push(overflow[side]);
      }
      if (checkCrossAxis) {
        const {
          main,
          cross: cross2
        } = getAlignmentSides(placement, rects, await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating)));
        overflows.push(overflow[main], overflow[cross2]);
      }
      overflowsData = [...overflowsData, {
        placement,
        overflows
      }];
      if (!overflows.every((side2) => side2 <= 0)) {
        var _middlewareData$flip$, _middlewareData$flip2;
        const nextIndex = ((_middlewareData$flip$ = (_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) != null ? _middlewareData$flip$ : 0) + 1;
        const nextPlacement = placements[nextIndex];
        if (nextPlacement) {
          return {
            data: {
              index: nextIndex,
              overflows: overflowsData
            },
            reset: {
              placement: nextPlacement
            }
          };
        }
        let resetPlacement = "bottom";
        switch (fallbackStrategy) {
          case "bestFit": {
            var _overflowsData$map$so;
            const placement2 = (_overflowsData$map$so = overflowsData.map((d) => [d, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0].placement;
            if (placement2) {
              resetPlacement = placement2;
            }
            break;
          }
          case "initialPlacement":
            resetPlacement = initialPlacement;
            break;
        }
        if (placement !== resetPlacement) {
          return {
            reset: {
              placement: resetPlacement
            }
          };
        }
      }
      return {};
    }
  };
};
function getSideOffsets(overflow, rect) {
  return {
    top: overflow.top - rect.height,
    right: overflow.right - rect.width,
    bottom: overflow.bottom - rect.height,
    left: overflow.left - rect.width
  };
}
function isAnySideFullyClipped(overflow) {
  return sides.some((side) => overflow[side] >= 0);
}
var hide = function(_temp) {
  let {
    strategy = "referenceHidden",
    ...detectOverflowOptions
  } = _temp === void 0 ? {} : _temp;
  return {
    name: "hide",
    async fn(middlewareArguments) {
      const {
        rects
      } = middlewareArguments;
      switch (strategy) {
        case "referenceHidden": {
          const overflow = await detectOverflow(middlewareArguments, {
            ...detectOverflowOptions,
            elementContext: "reference"
          });
          const offsets = getSideOffsets(overflow, rects.reference);
          return {
            data: {
              referenceHiddenOffsets: offsets,
              referenceHidden: isAnySideFullyClipped(offsets)
            }
          };
        }
        case "escaped": {
          const overflow = await detectOverflow(middlewareArguments, {
            ...detectOverflowOptions,
            altBoundary: true
          });
          const offsets = getSideOffsets(overflow, rects.floating);
          return {
            data: {
              escapedOffsets: offsets,
              escaped: isAnySideFullyClipped(offsets)
            }
          };
        }
        default: {
          return {};
        }
      }
    }
  };
};
async function convertValueToCoords(middlewareArguments, value) {
  const {
    placement,
    platform: platform2,
    elements
  } = middlewareArguments;
  const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
  const side = getSide(placement);
  const alignment = getAlignment(placement);
  const isVertical = getMainAxisFromPlacement(placement) === "x";
  const mainAxisMulti = ["left", "top"].includes(side) ? -1 : 1;
  const crossAxisMulti = rtl && isVertical ? -1 : 1;
  const rawValue = typeof value === "function" ? value(middlewareArguments) : value;
  let {
    mainAxis,
    crossAxis,
    alignmentAxis
  } = typeof rawValue === "number" ? {
    mainAxis: rawValue,
    crossAxis: 0,
    alignmentAxis: null
  } : {
    mainAxis: 0,
    crossAxis: 0,
    alignmentAxis: null,
    ...rawValue
  };
  if (alignment && typeof alignmentAxis === "number") {
    crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
  }
  return isVertical ? {
    x: crossAxis * crossAxisMulti,
    y: mainAxis * mainAxisMulti
  } : {
    x: mainAxis * mainAxisMulti,
    y: crossAxis * crossAxisMulti
  };
}
var offset = function(value) {
  if (value === void 0) {
    value = 0;
  }
  return {
    name: "offset",
    options: value,
    async fn(middlewareArguments) {
      const {
        x,
        y
      } = middlewareArguments;
      const diffCoords = await convertValueToCoords(middlewareArguments, value);
      return {
        x: x + diffCoords.x,
        y: y + diffCoords.y,
        data: diffCoords
      };
    }
  };
};
function getCrossAxis(axis) {
  return axis === "x" ? "y" : "x";
}
var shift = function(options) {
  if (options === void 0) {
    options = {};
  }
  return {
    name: "shift",
    options,
    async fn(middlewareArguments) {
      const {
        x,
        y,
        placement
      } = middlewareArguments;
      const {
        mainAxis: checkMainAxis = true,
        crossAxis: checkCrossAxis = false,
        limiter = {
          fn: (_ref) => {
            let {
              x: x2,
              y: y2
            } = _ref;
            return {
              x: x2,
              y: y2
            };
          }
        },
        ...detectOverflowOptions
      } = options;
      const coords = {
        x,
        y
      };
      const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
      const mainAxis = getMainAxisFromPlacement(getSide(placement));
      const crossAxis = getCrossAxis(mainAxis);
      let mainAxisCoord = coords[mainAxis];
      let crossAxisCoord = coords[crossAxis];
      if (checkMainAxis) {
        const minSide = mainAxis === "y" ? "top" : "left";
        const maxSide = mainAxis === "y" ? "bottom" : "right";
        const min4 = mainAxisCoord + overflow[minSide];
        const max3 = mainAxisCoord - overflow[maxSide];
        mainAxisCoord = within(min4, mainAxisCoord, max3);
      }
      if (checkCrossAxis) {
        const minSide = crossAxis === "y" ? "top" : "left";
        const maxSide = crossAxis === "y" ? "bottom" : "right";
        const min4 = crossAxisCoord + overflow[minSide];
        const max3 = crossAxisCoord - overflow[maxSide];
        crossAxisCoord = within(min4, crossAxisCoord, max3);
      }
      const limitedCoords = limiter.fn({
        ...middlewareArguments,
        [mainAxis]: mainAxisCoord,
        [crossAxis]: crossAxisCoord
      });
      return {
        ...limitedCoords,
        data: {
          x: limitedCoords.x - x,
          y: limitedCoords.y - y
        }
      };
    }
  };
};
var limitShift = function(options) {
  if (options === void 0) {
    options = {};
  }
  return {
    options,
    fn(middlewareArguments) {
      const {
        x,
        y,
        placement,
        rects,
        middlewareData
      } = middlewareArguments;
      const {
        offset: offset2 = 0,
        mainAxis: checkMainAxis = true,
        crossAxis: checkCrossAxis = true
      } = options;
      const coords = {
        x,
        y
      };
      const mainAxis = getMainAxisFromPlacement(placement);
      const crossAxis = getCrossAxis(mainAxis);
      let mainAxisCoord = coords[mainAxis];
      let crossAxisCoord = coords[crossAxis];
      const rawOffset = typeof offset2 === "function" ? offset2({
        ...rects,
        placement
      }) : offset2;
      const computedOffset = typeof rawOffset === "number" ? {
        mainAxis: rawOffset,
        crossAxis: 0
      } : {
        mainAxis: 0,
        crossAxis: 0,
        ...rawOffset
      };
      if (checkMainAxis) {
        const len = mainAxis === "y" ? "height" : "width";
        const limitMin = rects.reference[mainAxis] - rects.floating[len] + computedOffset.mainAxis;
        const limitMax = rects.reference[mainAxis] + rects.reference[len] - computedOffset.mainAxis;
        if (mainAxisCoord < limitMin) {
          mainAxisCoord = limitMin;
        } else if (mainAxisCoord > limitMax) {
          mainAxisCoord = limitMax;
        }
      }
      if (checkCrossAxis) {
        var _middlewareData$offse, _middlewareData$offse2, _middlewareData$offse3, _middlewareData$offse4;
        const len = mainAxis === "y" ? "width" : "height";
        const isOriginSide = ["top", "left"].includes(getSide(placement));
        const limitMin = rects.reference[crossAxis] - rects.floating[len] + (isOriginSide ? (_middlewareData$offse = (_middlewareData$offse2 = middlewareData.offset) == null ? void 0 : _middlewareData$offse2[crossAxis]) != null ? _middlewareData$offse : 0 : 0) + (isOriginSide ? 0 : computedOffset.crossAxis);
        const limitMax = rects.reference[crossAxis] + rects.reference[len] + (isOriginSide ? 0 : (_middlewareData$offse3 = (_middlewareData$offse4 = middlewareData.offset) == null ? void 0 : _middlewareData$offse4[crossAxis]) != null ? _middlewareData$offse3 : 0) - (isOriginSide ? computedOffset.crossAxis : 0);
        if (crossAxisCoord < limitMin) {
          crossAxisCoord = limitMin;
        } else if (crossAxisCoord > limitMax) {
          crossAxisCoord = limitMax;
        }
      }
      return {
        [mainAxis]: mainAxisCoord,
        [crossAxis]: crossAxisCoord
      };
    }
  };
};
var size = function(options) {
  if (options === void 0) {
    options = {};
  }
  return {
    name: "size",
    options,
    async fn(middlewareArguments) {
      const {
        placement,
        rects,
        platform: platform2,
        elements
      } = middlewareArguments;
      const {
        apply,
        ...detectOverflowOptions
      } = options;
      const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
      const side = getSide(placement);
      const alignment = getAlignment(placement);
      let heightSide;
      let widthSide;
      if (side === "top" || side === "bottom") {
        heightSide = side;
        widthSide = alignment === (await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating)) ? "start" : "end") ? "left" : "right";
      } else {
        widthSide = side;
        heightSide = alignment === "end" ? "top" : "bottom";
      }
      const xMin = max(overflow.left, 0);
      const xMax = max(overflow.right, 0);
      const yMin = max(overflow.top, 0);
      const yMax = max(overflow.bottom, 0);
      const dimensions = {
        availableHeight: rects.floating.height - (["left", "right"].includes(placement) ? 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom)) : overflow[heightSide]),
        availableWidth: rects.floating.width - (["top", "bottom"].includes(placement) ? 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right)) : overflow[widthSide])
      };
      const prevDimensions = await platform2.getDimensions(elements.floating);
      apply == null ? void 0 : apply({
        ...middlewareArguments,
        ...dimensions
      });
      const nextDimensions = await platform2.getDimensions(elements.floating);
      if (prevDimensions.width !== nextDimensions.width || prevDimensions.height !== nextDimensions.height) {
        return {
          reset: {
            rects: true
          }
        };
      }
      return {};
    }
  };
};

// node_modules/.deno/@floating-ui+dom@0.5.4/node_modules/@floating-ui/dom/dist/floating-ui.dom.browser.mjs
function isWindow(value) {
  return value && value.document && value.location && value.alert && value.setInterval;
}
function getWindow(node) {
  if (node == null) {
    return window;
  }
  if (!isWindow(node)) {
    const ownerDocument = node.ownerDocument;
    return ownerDocument ? ownerDocument.defaultView || window : window;
  }
  return node;
}
function getComputedStyle$1(element) {
  return getWindow(element).getComputedStyle(element);
}
function getNodeName(node) {
  return isWindow(node) ? "" : node ? (node.nodeName || "").toLowerCase() : "";
}
function getUAString() {
  const uaData = navigator.userAgentData;
  if (uaData != null && uaData.brands) {
    return uaData.brands.map((item) => item.brand + "/" + item.version).join(" ");
  }
  return navigator.userAgent;
}
function isHTMLElement2(value) {
  return value instanceof getWindow(value).HTMLElement;
}
function isElement(value) {
  return value instanceof getWindow(value).Element;
}
function isNode(value) {
  return value instanceof getWindow(value).Node;
}
function isShadowRoot(node) {
  if (typeof ShadowRoot === "undefined") {
    return false;
  }
  const OwnElement = getWindow(node).ShadowRoot;
  return node instanceof OwnElement || node instanceof ShadowRoot;
}
function isOverflowElement(element) {
  const {
    overflow,
    overflowX,
    overflowY
  } = getComputedStyle$1(element);
  return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
}
function isTableElement(element) {
  return ["table", "td", "th"].includes(getNodeName(element));
}
function isContainingBlock(element) {
  const isFirefox = /firefox/i.test(getUAString());
  const css = getComputedStyle$1(element);
  return css.transform !== "none" || css.perspective !== "none" || // @ts-ignore (TS 4.1 compat)
  css.contain === "paint" || ["transform", "perspective"].includes(css.willChange) || isFirefox && css.willChange === "filter" || isFirefox && (css.filter ? css.filter !== "none" : false);
}
function isLayoutViewport() {
  return !/^((?!chrome|android).)*safari/i.test(getUAString());
}
var min3 = Math.min;
var max2 = Math.max;
var round2 = Math.round;
function getBoundingClientRect(element, includeScale, isFixedStrategy) {
  var _win$visualViewport$o, _win$visualViewport, _win$visualViewport$o2, _win$visualViewport2;
  if (includeScale === void 0) {
    includeScale = false;
  }
  if (isFixedStrategy === void 0) {
    isFixedStrategy = false;
  }
  const clientRect = element.getBoundingClientRect();
  let scaleX = 1;
  let scaleY = 1;
  if (includeScale && isHTMLElement2(element)) {
    scaleX = element.offsetWidth > 0 ? round2(clientRect.width) / element.offsetWidth || 1 : 1;
    scaleY = element.offsetHeight > 0 ? round2(clientRect.height) / element.offsetHeight || 1 : 1;
  }
  const win = isElement(element) ? getWindow(element) : window;
  const addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
  const x = (clientRect.left + (addVisualOffsets ? (_win$visualViewport$o = (_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) != null ? _win$visualViewport$o : 0 : 0)) / scaleX;
  const y = (clientRect.top + (addVisualOffsets ? (_win$visualViewport$o2 = (_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) != null ? _win$visualViewport$o2 : 0 : 0)) / scaleY;
  const width = clientRect.width / scaleX;
  const height = clientRect.height / scaleY;
  return {
    width,
    height,
    top: y,
    right: x + width,
    bottom: y + height,
    left: x,
    x,
    y
  };
}
function getDocumentElement(node) {
  return ((isNode(node) ? node.ownerDocument : node.document) || window.document).documentElement;
}
function getNodeScroll(element) {
  if (isElement(element)) {
    return {
      scrollLeft: element.scrollLeft,
      scrollTop: element.scrollTop
    };
  }
  return {
    scrollLeft: element.pageXOffset,
    scrollTop: element.pageYOffset
  };
}
function getWindowScrollBarX(element) {
  return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
}
function isScaled(element) {
  const rect = getBoundingClientRect(element);
  return round2(rect.width) !== element.offsetWidth || round2(rect.height) !== element.offsetHeight;
}
function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
  const isOffsetParentAnElement = isHTMLElement2(offsetParent);
  const documentElement = getDocumentElement(offsetParent);
  const rect = getBoundingClientRect(
    element,
    // @ts-ignore - checked above (TS 4.1 compat)
    isOffsetParentAnElement && isScaled(offsetParent),
    strategy === "fixed"
  );
  let scroll = {
    scrollLeft: 0,
    scrollTop: 0
  };
  const offsets = {
    x: 0,
    y: 0
  };
  if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== "fixed") {
    if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
      scroll = getNodeScroll(offsetParent);
    }
    if (isHTMLElement2(offsetParent)) {
      const offsetRect = getBoundingClientRect(offsetParent, true);
      offsets.x = offsetRect.x + offsetParent.clientLeft;
      offsets.y = offsetRect.y + offsetParent.clientTop;
    } else if (documentElement) {
      offsets.x = getWindowScrollBarX(documentElement);
    }
  }
  return {
    x: rect.left + scroll.scrollLeft - offsets.x,
    y: rect.top + scroll.scrollTop - offsets.y,
    width: rect.width,
    height: rect.height
  };
}
function getParentNode(node) {
  if (getNodeName(node) === "html") {
    return node;
  }
  return (
    // this is a quicker (but less type safe) way to save quite some bytes from the bundle
    // @ts-ignore
    node.assignedSlot || // step into the shadow DOM of the parent of a slotted node
    node.parentNode || // DOM Element detected
    (isShadowRoot(node) ? node.host : null) || // ShadowRoot detected
    getDocumentElement(node)
  );
}
function getTrueOffsetParent(element) {
  if (!isHTMLElement2(element) || getComputedStyle(element).position === "fixed") {
    return null;
  }
  return element.offsetParent;
}
function getContainingBlock(element) {
  let currentNode = getParentNode(element);
  if (isShadowRoot(currentNode)) {
    currentNode = currentNode.host;
  }
  while (isHTMLElement2(currentNode) && !["html", "body"].includes(getNodeName(currentNode))) {
    if (isContainingBlock(currentNode)) {
      return currentNode;
    } else {
      currentNode = currentNode.parentNode;
    }
  }
  return null;
}
function getOffsetParent(element) {
  const window3 = getWindow(element);
  let offsetParent = getTrueOffsetParent(element);
  while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") {
    offsetParent = getTrueOffsetParent(offsetParent);
  }
  if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static" && !isContainingBlock(offsetParent))) {
    return window3;
  }
  return offsetParent || getContainingBlock(element) || window3;
}
function getDimensions(element) {
  if (isHTMLElement2(element)) {
    return {
      width: element.offsetWidth,
      height: element.offsetHeight
    };
  }
  const rect = getBoundingClientRect(element);
  return {
    width: rect.width,
    height: rect.height
  };
}
function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
  let {
    rect,
    offsetParent,
    strategy
  } = _ref;
  const isOffsetParentAnElement = isHTMLElement2(offsetParent);
  const documentElement = getDocumentElement(offsetParent);
  if (offsetParent === documentElement) {
    return rect;
  }
  let scroll = {
    scrollLeft: 0,
    scrollTop: 0
  };
  const offsets = {
    x: 0,
    y: 0
  };
  if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== "fixed") {
    if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
      scroll = getNodeScroll(offsetParent);
    }
    if (isHTMLElement2(offsetParent)) {
      const offsetRect = getBoundingClientRect(offsetParent, true);
      offsets.x = offsetRect.x + offsetParent.clientLeft;
      offsets.y = offsetRect.y + offsetParent.clientTop;
    }
  }
  return {
    ...rect,
    x: rect.x - scroll.scrollLeft + offsets.x,
    y: rect.y - scroll.scrollTop + offsets.y
  };
}
function getViewportRect(element, strategy) {
  const win = getWindow(element);
  const html = getDocumentElement(element);
  const visualViewport = win.visualViewport;
  let width = html.clientWidth;
  let height = html.clientHeight;
  let x = 0;
  let y = 0;
  if (visualViewport) {
    width = visualViewport.width;
    height = visualViewport.height;
    const layoutViewport = isLayoutViewport();
    if (layoutViewport || !layoutViewport && strategy === "fixed") {
      x = visualViewport.offsetLeft;
      y = visualViewport.offsetTop;
    }
  }
  return {
    width,
    height,
    x,
    y
  };
}
function getDocumentRect(element) {
  var _element$ownerDocumen;
  const html = getDocumentElement(element);
  const scroll = getNodeScroll(element);
  const body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
  const width = max2(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
  const height = max2(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
  let x = -scroll.scrollLeft + getWindowScrollBarX(element);
  const y = -scroll.scrollTop;
  if (getComputedStyle$1(body || html).direction === "rtl") {
    x += max2(html.clientWidth, body ? body.clientWidth : 0) - width;
  }
  return {
    width,
    height,
    x,
    y
  };
}
function getNearestOverflowAncestor(node) {
  const parentNode = getParentNode(node);
  if (["html", "body", "#document"].includes(getNodeName(parentNode))) {
    return node.ownerDocument.body;
  }
  if (isHTMLElement2(parentNode) && isOverflowElement(parentNode)) {
    return parentNode;
  }
  return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list) {
  var _node$ownerDocument;
  if (list === void 0) {
    list = [];
  }
  const scrollableAncestor = getNearestOverflowAncestor(node);
  const isBody = scrollableAncestor === ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.body);
  const win = getWindow(scrollableAncestor);
  const target = isBody ? [win].concat(win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []) : scrollableAncestor;
  const updatedList = list.concat(target);
  return isBody ? updatedList : (
    // @ts-ignore: isBody tells us target will be an HTMLElement here
    updatedList.concat(getOverflowAncestors(target))
  );
}
function contains(parent, child) {
  const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();
  if (parent.contains(child)) {
    return true;
  } else if (rootNode && isShadowRoot(rootNode)) {
    let next = child;
    do {
      if (next && parent === next) {
        return true;
      }
      next = next.parentNode || next.host;
    } while (next);
  }
  return false;
}
function getInnerBoundingClientRect(element, strategy) {
  const clientRect = getBoundingClientRect(element, false, strategy === "fixed");
  const top = clientRect.top + element.clientTop;
  const left = clientRect.left + element.clientLeft;
  return {
    top,
    left,
    x: left,
    y: top,
    right: left + element.clientWidth,
    bottom: top + element.clientHeight,
    width: element.clientWidth,
    height: element.clientHeight
  };
}
function getClientRectFromClippingAncestor(element, clippingParent, strategy) {
  if (clippingParent === "viewport") {
    return rectToClientRect(getViewportRect(element, strategy));
  }
  if (isElement(clippingParent)) {
    return getInnerBoundingClientRect(clippingParent, strategy);
  }
  return rectToClientRect(getDocumentRect(getDocumentElement(element)));
}
function getClippingAncestors(element) {
  const clippingAncestors = getOverflowAncestors(element);
  const canEscapeClipping = ["absolute", "fixed"].includes(getComputedStyle$1(element).position);
  const clipperElement = canEscapeClipping && isHTMLElement2(element) ? getOffsetParent(element) : element;
  if (!isElement(clipperElement)) {
    return [];
  }
  return clippingAncestors.filter((clippingAncestors2) => isElement(clippingAncestors2) && contains(clippingAncestors2, clipperElement) && getNodeName(clippingAncestors2) !== "body");
}
function getClippingRect(_ref) {
  let {
    element,
    boundary,
    rootBoundary,
    strategy
  } = _ref;
  const mainClippingAncestors = boundary === "clippingAncestors" ? getClippingAncestors(element) : [].concat(boundary);
  const clippingAncestors = [...mainClippingAncestors, rootBoundary];
  const firstClippingAncestor = clippingAncestors[0];
  const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
    const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
    accRect.top = max2(rect.top, accRect.top);
    accRect.right = min3(rect.right, accRect.right);
    accRect.bottom = min3(rect.bottom, accRect.bottom);
    accRect.left = max2(rect.left, accRect.left);
    return accRect;
  }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
  return {
    width: clippingRect.right - clippingRect.left,
    height: clippingRect.bottom - clippingRect.top,
    x: clippingRect.left,
    y: clippingRect.top
  };
}
var platform = {
  getClippingRect,
  convertOffsetParentRelativeRectToViewportRelativeRect,
  isElement,
  getDimensions,
  getOffsetParent,
  getDocumentElement,
  getElementRects: (_ref) => {
    let {
      reference,
      floating,
      strategy
    } = _ref;
    return {
      reference: getRectRelativeToOffsetParent(reference, getOffsetParent(floating), strategy),
      floating: {
        ...getDimensions(floating),
        x: 0,
        y: 0
      }
    };
  },
  getClientRects: (element) => Array.from(element.getClientRects()),
  isRTL: (element) => getComputedStyle$1(element).direction === "rtl"
};
function autoUpdate(reference, floating, update, options) {
  if (options === void 0) {
    options = {};
  }
  const {
    ancestorScroll: _ancestorScroll = true,
    ancestorResize: _ancestorResize = true,
    elementResize = true,
    animationFrame = false
  } = options;
  const ancestorScroll = _ancestorScroll && !animationFrame;
  const ancestorResize = _ancestorResize && !animationFrame;
  const ancestors = ancestorScroll || ancestorResize ? [...isElement(reference) ? getOverflowAncestors(reference) : [], ...getOverflowAncestors(floating)] : [];
  ancestors.forEach((ancestor) => {
    ancestorScroll && ancestor.addEventListener("scroll", update, {
      passive: true
    });
    ancestorResize && ancestor.addEventListener("resize", update);
  });
  let observer = null;
  if (elementResize) {
    let initialUpdate = true;
    observer = new ResizeObserver(() => {
      if (!initialUpdate) {
        update();
      }
      initialUpdate = false;
    });
    isElement(reference) && !animationFrame && observer.observe(reference);
    observer.observe(floating);
  }
  let frameId;
  let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
  if (animationFrame) {
    frameLoop();
  }
  function frameLoop() {
    const nextRefRect = getBoundingClientRect(reference);
    if (prevRefRect && (nextRefRect.x !== prevRefRect.x || nextRefRect.y !== prevRefRect.y || nextRefRect.width !== prevRefRect.width || nextRefRect.height !== prevRefRect.height)) {
      update();
    }
    prevRefRect = nextRefRect;
    frameId = requestAnimationFrame(frameLoop);
  }
  update();
  return () => {
    var _observer;
    ancestors.forEach((ancestor) => {
      ancestorScroll && ancestor.removeEventListener("scroll", update);
      ancestorResize && ancestor.removeEventListener("resize", update);
    });
    (_observer = observer) == null ? void 0 : _observer.disconnect();
    observer = null;
    if (animationFrame) {
      cancelAnimationFrame(frameId);
    }
  };
}
var computePosition2 = (reference, floating, options) => computePosition(reference, floating, {
  platform,
  ...options
});

// node_modules/.deno/@floating-ui+react-dom@0.7.2/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.esm.js
var React50 = __toESM(require_react());
var import_react85 = __toESM(require_react());
var ReactDOM2 = __toESM(require_react_dom());
var index = typeof document !== "undefined" ? import_react85.useLayoutEffect : import_react85.useEffect;
function deepEqual(a, b) {
  if (a === b) {
    return true;
  }
  if (typeof a !== typeof b) {
    return false;
  }
  if (typeof a === "function" && a.toString() === b.toString()) {
    return true;
  }
  let length, i, keys;
  if (a && b && typeof a == "object") {
    if (Array.isArray(a)) {
      length = a.length;
      if (length != b.length)
        return false;
      for (i = length; i-- !== 0; ) {
        if (!deepEqual(a[i], b[i])) {
          return false;
        }
      }
      return true;
    }
    keys = Object.keys(a);
    length = keys.length;
    if (length !== Object.keys(b).length) {
      return false;
    }
    for (i = length; i-- !== 0; ) {
      if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
        return false;
      }
    }
    for (i = length; i-- !== 0; ) {
      const key = keys[i];
      if (key === "_owner" && a.$$typeof) {
        continue;
      }
      if (!deepEqual(a[key], b[key])) {
        return false;
      }
    }
    return true;
  }
  return a !== a && b !== b;
}
function useLatestRef(value) {
  const ref = React50.useRef(value);
  index(() => {
    ref.current = value;
  });
  return ref;
}
function useFloating(_temp) {
  let {
    middleware,
    placement = "bottom",
    strategy = "absolute",
    whileElementsMounted
  } = _temp === void 0 ? {} : _temp;
  const reference = React50.useRef(null);
  const floating = React50.useRef(null);
  const whileElementsMountedRef = useLatestRef(whileElementsMounted);
  const cleanupRef = React50.useRef(null);
  const [data, setData] = React50.useState({
    // Setting these to `null` will allow the consumer to determine if
    // `computePosition()` has run yet
    x: null,
    y: null,
    strategy,
    placement,
    middlewareData: {}
  });
  const [latestMiddleware, setLatestMiddleware] = React50.useState(middleware);
  if (!deepEqual(latestMiddleware == null ? void 0 : latestMiddleware.map((_ref) => {
    let {
      options
    } = _ref;
    return options;
  }), middleware == null ? void 0 : middleware.map((_ref2) => {
    let {
      options
    } = _ref2;
    return options;
  }))) {
    setLatestMiddleware(middleware);
  }
  const update = React50.useCallback(() => {
    if (!reference.current || !floating.current) {
      return;
    }
    computePosition2(reference.current, floating.current, {
      middleware: latestMiddleware,
      placement,
      strategy
    }).then((data2) => {
      if (isMountedRef.current) {
        ReactDOM2.flushSync(() => {
          setData(data2);
        });
      }
    });
  }, [latestMiddleware, placement, strategy]);
  index(() => {
    if (isMountedRef.current) {
      update();
    }
  }, [update]);
  const isMountedRef = React50.useRef(false);
  index(() => {
    isMountedRef.current = true;
    return () => {
      isMountedRef.current = false;
    };
  }, []);
  const runElementMountCallback = React50.useCallback(() => {
    if (typeof cleanupRef.current === "function") {
      cleanupRef.current();
      cleanupRef.current = null;
    }
    if (reference.current && floating.current) {
      if (whileElementsMountedRef.current) {
        const cleanupFn = whileElementsMountedRef.current(reference.current, floating.current, update);
        cleanupRef.current = cleanupFn;
      } else {
        update();
      }
    }
  }, [update, whileElementsMountedRef]);
  const setReference = React50.useCallback((node) => {
    reference.current = node;
    runElementMountCallback();
  }, [runElementMountCallback]);
  const setFloating = React50.useCallback((node) => {
    floating.current = node;
    runElementMountCallback();
  }, [runElementMountCallback]);
  const refs = React50.useMemo(() => ({
    reference,
    floating
  }), []);
  return React50.useMemo(() => ({
    ...data,
    update,
    refs,
    reference: setReference,
    floating: setFloating
  }), [data, update, refs, setReference, setFloating]);
}
var arrow2 = (options) => {
  const {
    element,
    padding
  } = options;
  function isRef(value) {
    return Object.prototype.hasOwnProperty.call(value, "current");
  }
  return {
    name: "arrow",
    options,
    fn(args) {
      if (isRef(element)) {
        if (element.current != null) {
          return arrow({
            element: element.current,
            padding
          }).fn(args);
        }
        return {};
      } else if (element) {
        return arrow({
          element,
          padding
        }).fn(args);
      }
      return {};
    }
  };
};

// node_modules/.deno/@radix-ui+react-arrow@1.0.2/node_modules/@radix-ui/react-arrow/dist/index.module.js
var import_react86 = __toESM(require_react());
var $7e8f5cd07187803e$var$NAME = "Arrow";
var $7e8f5cd07187803e$export$21b07c8f274aebd5 = (0, import_react86.forwardRef)((props, forwardedRef) => {
  const { children, width = 10, height = 5, ...arrowProps } = props;
  return (0, import_react86.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.svg, _extends({}, arrowProps, {
    ref: forwardedRef,
    width,
    height,
    viewBox: "0 0 30 10",
    preserveAspectRatio: "none"
  }), props.asChild ? children : (0, import_react86.createElement)("polygon", {
    points: "0,0 30,0 15,10"
  }));
});
Object.assign($7e8f5cd07187803e$export$21b07c8f274aebd5, {
  displayName: $7e8f5cd07187803e$var$NAME
});
var $7e8f5cd07187803e$export$be92b6f5f03c0fe9 = $7e8f5cd07187803e$export$21b07c8f274aebd5;

// node_modules/.deno/@radix-ui+react-use-size@1.0.0/node_modules/@radix-ui/react-use-size/dist/index.module.js
var import_react87 = __toESM(require_react());
function $db6c3485150b8e66$export$1ab7ae714698c4b8(element) {
  const [size2, setSize] = (0, import_react87.useState)(void 0);
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    if (element) {
      setSize({
        width: element.offsetWidth,
        height: element.offsetHeight
      });
      const resizeObserver = new ResizeObserver((entries) => {
        if (!Array.isArray(entries))
          return;
        if (!entries.length)
          return;
        const entry = entries[0];
        let width;
        let height;
        if ("borderBoxSize" in entry) {
          const borderSizeEntry = entry["borderBoxSize"];
          const borderSize = Array.isArray(borderSizeEntry) ? borderSizeEntry[0] : borderSizeEntry;
          width = borderSize["inlineSize"];
          height = borderSize["blockSize"];
        } else {
          width = element.offsetWidth;
          height = element.offsetHeight;
        }
        setSize({
          width,
          height
        });
      });
      resizeObserver.observe(element, {
        box: "border-box"
      });
      return () => resizeObserver.unobserve(element);
    } else
      setSize(void 0);
  }, [
    element
  ]);
  return size2;
}

// node_modules/.deno/@radix-ui+react-popper@1.1.2-rc.5/node_modules/@radix-ui/react-popper/dist/index.module.js
var $cf1ac5d9fe0e8206$var$POPPER_NAME = "Popper";
var [$cf1ac5d9fe0e8206$var$createPopperContext, $cf1ac5d9fe0e8206$export$722aac194ae923] = $c512c27ab02ef895$export$50c7b4e9d9f19c1($cf1ac5d9fe0e8206$var$POPPER_NAME);
var [$cf1ac5d9fe0e8206$var$PopperProvider, $cf1ac5d9fe0e8206$var$usePopperContext] = $cf1ac5d9fe0e8206$var$createPopperContext($cf1ac5d9fe0e8206$var$POPPER_NAME);
var $cf1ac5d9fe0e8206$export$badac9ada3a0bdf9 = (props) => {
  const { __scopePopper, children } = props;
  const [anchor, setAnchor] = (0, import_react88.useState)(null);
  return (0, import_react88.createElement)($cf1ac5d9fe0e8206$var$PopperProvider, {
    scope: __scopePopper,
    anchor,
    onAnchorChange: setAnchor
  }, children);
};
Object.assign($cf1ac5d9fe0e8206$export$badac9ada3a0bdf9, {
  displayName: $cf1ac5d9fe0e8206$var$POPPER_NAME
});
var $cf1ac5d9fe0e8206$var$ANCHOR_NAME = "PopperAnchor";
var $cf1ac5d9fe0e8206$export$ecd4e1ccab6ed6d = (0, import_react88.forwardRef)((props, forwardedRef) => {
  const { __scopePopper, virtualRef, ...anchorProps } = props;
  const context = $cf1ac5d9fe0e8206$var$usePopperContext($cf1ac5d9fe0e8206$var$ANCHOR_NAME, __scopePopper);
  const ref = (0, import_react88.useRef)(null);
  const composedRefs = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(forwardedRef, ref);
  (0, import_react88.useEffect)(() => {
    context.onAnchorChange((virtualRef === null || virtualRef === void 0 ? void 0 : virtualRef.current) || ref.current);
  });
  return virtualRef ? null : (0, import_react88.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.div, _extends({}, anchorProps, {
    ref: composedRefs
  }));
});
Object.assign($cf1ac5d9fe0e8206$export$ecd4e1ccab6ed6d, {
  displayName: $cf1ac5d9fe0e8206$var$ANCHOR_NAME
});
var $cf1ac5d9fe0e8206$var$CONTENT_NAME = "PopperContent";
var [$cf1ac5d9fe0e8206$var$PopperContentProvider, $cf1ac5d9fe0e8206$var$useContentContext] = $cf1ac5d9fe0e8206$var$createPopperContext($cf1ac5d9fe0e8206$var$CONTENT_NAME);
var [$cf1ac5d9fe0e8206$var$PositionContextProvider, $cf1ac5d9fe0e8206$var$usePositionContext] = $cf1ac5d9fe0e8206$var$createPopperContext($cf1ac5d9fe0e8206$var$CONTENT_NAME, {
  hasParent: false,
  positionUpdateFns: /* @__PURE__ */ new Set()
});
var $cf1ac5d9fe0e8206$export$bc4ae5855d3c4fc = (0, import_react88.forwardRef)((props, forwardedRef) => {
  var _arrowSize$width, _arrowSize$height, _middlewareData$arrow, _middlewareData$arrow2, _middlewareData$arrow3, _middlewareData$hide, _middlewareData$trans, _middlewareData$trans2;
  const { __scopePopper, side = "bottom", sideOffset = 0, align = "center", alignOffset = 0, arrowPadding = 0, collisionBoundary = [], collisionPadding: collisionPaddingProp = 0, sticky = "partial", hideWhenDetached = false, avoidCollisions = true, onPlaced, ...contentProps } = props;
  const context = $cf1ac5d9fe0e8206$var$usePopperContext($cf1ac5d9fe0e8206$var$CONTENT_NAME, __scopePopper);
  const [content, setContent] = (0, import_react88.useState)(null);
  const composedRefs = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(
    forwardedRef,
    (node) => setContent(node)
  );
  const [arrow3, setArrow] = (0, import_react88.useState)(null);
  const arrowSize = $db6c3485150b8e66$export$1ab7ae714698c4b8(arrow3);
  const arrowWidth = (_arrowSize$width = arrowSize === null || arrowSize === void 0 ? void 0 : arrowSize.width) !== null && _arrowSize$width !== void 0 ? _arrowSize$width : 0;
  const arrowHeight = (_arrowSize$height = arrowSize === null || arrowSize === void 0 ? void 0 : arrowSize.height) !== null && _arrowSize$height !== void 0 ? _arrowSize$height : 0;
  const desiredPlacement = side + (align !== "center" ? "-" + align : "");
  const collisionPadding = typeof collisionPaddingProp === "number" ? collisionPaddingProp : {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    ...collisionPaddingProp
  };
  const boundary = Array.isArray(collisionBoundary) ? collisionBoundary : [
    collisionBoundary
  ];
  const hasExplicitBoundaries = boundary.length > 0;
  const detectOverflowOptions = {
    padding: collisionPadding,
    boundary: boundary.filter($cf1ac5d9fe0e8206$var$isNotNull),
    // with `strategy: 'fixed'`, this is the only way to get it to respect boundaries
    altBoundary: hasExplicitBoundaries
  };
  const { reference, floating, strategy, x, y, placement, middlewareData, update } = useFloating({
    // default to `fixed` strategy so users don't have to pick and we also avoid focus scroll issues
    strategy: "fixed",
    placement: desiredPlacement,
    whileElementsMounted: autoUpdate,
    middleware: [
      offset({
        mainAxis: sideOffset + arrowHeight,
        alignmentAxis: alignOffset
      }),
      avoidCollisions ? shift({
        mainAxis: true,
        crossAxis: false,
        limiter: sticky === "partial" ? limitShift() : void 0,
        ...detectOverflowOptions
      }) : void 0,
      avoidCollisions ? flip({
        ...detectOverflowOptions
      }) : void 0,
      size({
        ...detectOverflowOptions,
        apply: ({ elements, rects, availableWidth, availableHeight }) => {
          const { width: anchorWidth, height: anchorHeight } = rects.reference;
          const contentStyle = elements.floating.style;
          contentStyle.setProperty("--radix-popper-available-width", `${availableWidth}px`);
          contentStyle.setProperty("--radix-popper-available-height", `${availableHeight}px`);
          contentStyle.setProperty("--radix-popper-anchor-width", `${anchorWidth}px`);
          contentStyle.setProperty("--radix-popper-anchor-height", `${anchorHeight}px`);
        }
      }),
      arrow3 ? arrow2({
        element: arrow3,
        padding: arrowPadding
      }) : void 0,
      $cf1ac5d9fe0e8206$var$transformOrigin({
        arrowWidth,
        arrowHeight
      }),
      hideWhenDetached ? hide({
        strategy: "referenceHidden"
      }) : void 0
    ].filter($cf1ac5d9fe0e8206$var$isDefined)
  });
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    reference(context.anchor);
  }, [
    reference,
    context.anchor
  ]);
  const isPlaced = x !== null && y !== null;
  const [placedSide, placedAlign] = $cf1ac5d9fe0e8206$var$getSideAndAlignFromPlacement(placement);
  const handlePlaced = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onPlaced);
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    if (isPlaced)
      handlePlaced === null || handlePlaced === void 0 || handlePlaced();
  }, [
    isPlaced,
    handlePlaced
  ]);
  const arrowX = (_middlewareData$arrow = middlewareData.arrow) === null || _middlewareData$arrow === void 0 ? void 0 : _middlewareData$arrow.x;
  const arrowY = (_middlewareData$arrow2 = middlewareData.arrow) === null || _middlewareData$arrow2 === void 0 ? void 0 : _middlewareData$arrow2.y;
  const cannotCenterArrow = ((_middlewareData$arrow3 = middlewareData.arrow) === null || _middlewareData$arrow3 === void 0 ? void 0 : _middlewareData$arrow3.centerOffset) !== 0;
  const [contentZIndex, setContentZIndex] = (0, import_react88.useState)();
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    if (content)
      setContentZIndex(window.getComputedStyle(content).zIndex);
  }, [
    content
  ]);
  const { hasParent, positionUpdateFns } = $cf1ac5d9fe0e8206$var$usePositionContext($cf1ac5d9fe0e8206$var$CONTENT_NAME, __scopePopper);
  const isRoot = !hasParent;
  (0, import_react88.useLayoutEffect)(() => {
    if (!isRoot) {
      positionUpdateFns.add(update);
      return () => {
        positionUpdateFns.delete(update);
      };
    }
  }, [
    isRoot,
    positionUpdateFns,
    update
  ]);
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    if (isRoot && isPlaced)
      Array.from(positionUpdateFns).reverse().forEach(
        (fn) => requestAnimationFrame(fn)
      );
  }, [
    isRoot,
    isPlaced,
    positionUpdateFns
  ]);
  const commonProps = {
    "data-side": placedSide,
    "data-align": placedAlign,
    ...contentProps,
    ref: composedRefs,
    style: {
      ...contentProps.style,
      // if the PopperContent hasn't been placed yet (not all measurements done)
      // we prevent animations so that users's animation don't kick in too early referring wrong sides
      animation: !isPlaced ? "none" : void 0,
      // hide the content if using the hide middleware and should be hidden
      opacity: (_middlewareData$hide = middlewareData.hide) !== null && _middlewareData$hide !== void 0 && _middlewareData$hide.referenceHidden ? 0 : void 0
    }
  };
  return (0, import_react88.createElement)("div", {
    ref: floating,
    "data-radix-popper-content-wrapper": "",
    style: {
      position: strategy,
      left: 0,
      top: 0,
      transform: isPlaced ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)` : "translate3d(0, -200%, 0)",
      // keep off the page when measuring
      minWidth: "max-content",
      zIndex: contentZIndex,
      ["--radix-popper-transform-origin"]: [
        (_middlewareData$trans = middlewareData.transformOrigin) === null || _middlewareData$trans === void 0 ? void 0 : _middlewareData$trans.x,
        (_middlewareData$trans2 = middlewareData.transformOrigin) === null || _middlewareData$trans2 === void 0 ? void 0 : _middlewareData$trans2.y
      ].join(" ")
    },
    dir: props.dir
  }, (0, import_react88.createElement)($cf1ac5d9fe0e8206$var$PopperContentProvider, {
    scope: __scopePopper,
    placedSide,
    onArrowChange: setArrow,
    arrowX,
    arrowY,
    shouldHideArrow: cannotCenterArrow
  }, isRoot ? (0, import_react88.createElement)($cf1ac5d9fe0e8206$var$PositionContextProvider, {
    scope: __scopePopper,
    hasParent: true,
    positionUpdateFns
  }, (0, import_react88.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.div, commonProps)) : (0, import_react88.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.div, commonProps)));
});
Object.assign($cf1ac5d9fe0e8206$export$bc4ae5855d3c4fc, {
  displayName: $cf1ac5d9fe0e8206$var$CONTENT_NAME
});
var $cf1ac5d9fe0e8206$var$ARROW_NAME = "PopperArrow";
var $cf1ac5d9fe0e8206$var$OPPOSITE_SIDE = {
  top: "bottom",
  right: "left",
  bottom: "top",
  left: "right"
};
var $cf1ac5d9fe0e8206$export$79d62cd4e10a3fd0 = (0, import_react88.forwardRef)(function $cf1ac5d9fe0e8206$export$79d62cd4e10a3fd02(props, forwardedRef) {
  const { __scopePopper, ...arrowProps } = props;
  const contentContext = $cf1ac5d9fe0e8206$var$useContentContext($cf1ac5d9fe0e8206$var$ARROW_NAME, __scopePopper);
  const baseSide = $cf1ac5d9fe0e8206$var$OPPOSITE_SIDE[contentContext.placedSide];
  return (
    // we have to use an extra wrapper because `ResizeObserver` (used by `useSize`)
    // doesn't report size as we'd expect on SVG elements.
    // it reports their bounding box which is effectively the largest path inside the SVG.
    (0, import_react88.createElement)("span", {
      ref: contentContext.onArrowChange,
      style: {
        position: "absolute",
        left: contentContext.arrowX,
        top: contentContext.arrowY,
        [baseSide]: 0,
        transformOrigin: {
          top: "",
          right: "0 0",
          bottom: "center 0",
          left: "100% 0"
        }[contentContext.placedSide],
        transform: {
          top: "translateY(100%)",
          right: "translateY(50%) rotate(90deg) translateX(-50%)",
          bottom: `rotate(180deg)`,
          left: "translateY(50%) rotate(-90deg) translateX(50%)"
        }[contentContext.placedSide],
        visibility: contentContext.shouldHideArrow ? "hidden" : void 0
      }
    }, (0, import_react88.createElement)($7e8f5cd07187803e$export$be92b6f5f03c0fe9, _extends({}, arrowProps, {
      ref: forwardedRef,
      style: {
        ...arrowProps.style,
        // ensures the element can be measured correctly (mostly for if SVG)
        display: "block"
      }
    })))
  );
});
Object.assign($cf1ac5d9fe0e8206$export$79d62cd4e10a3fd0, {
  displayName: $cf1ac5d9fe0e8206$var$ARROW_NAME
});
function $cf1ac5d9fe0e8206$var$isDefined(value) {
  return value !== void 0;
}
function $cf1ac5d9fe0e8206$var$isNotNull(value) {
  return value !== null;
}
var $cf1ac5d9fe0e8206$var$transformOrigin = (options) => ({
  name: "transformOrigin",
  options,
  fn(data) {
    var _middlewareData$arrow4, _middlewareData$arrow5, _middlewareData$arrow6, _middlewareData$arrow7, _middlewareData$arrow8;
    const { placement, rects, middlewareData } = data;
    const cannotCenterArrow = ((_middlewareData$arrow4 = middlewareData.arrow) === null || _middlewareData$arrow4 === void 0 ? void 0 : _middlewareData$arrow4.centerOffset) !== 0;
    const isArrowHidden = cannotCenterArrow;
    const arrowWidth = isArrowHidden ? 0 : options.arrowWidth;
    const arrowHeight = isArrowHidden ? 0 : options.arrowHeight;
    const [placedSide, placedAlign] = $cf1ac5d9fe0e8206$var$getSideAndAlignFromPlacement(placement);
    const noArrowAlign = {
      start: "0%",
      center: "50%",
      end: "100%"
    }[placedAlign];
    const arrowXCenter = ((_middlewareData$arrow5 = (_middlewareData$arrow6 = middlewareData.arrow) === null || _middlewareData$arrow6 === void 0 ? void 0 : _middlewareData$arrow6.x) !== null && _middlewareData$arrow5 !== void 0 ? _middlewareData$arrow5 : 0) + arrowWidth / 2;
    const arrowYCenter = ((_middlewareData$arrow7 = (_middlewareData$arrow8 = middlewareData.arrow) === null || _middlewareData$arrow8 === void 0 ? void 0 : _middlewareData$arrow8.y) !== null && _middlewareData$arrow7 !== void 0 ? _middlewareData$arrow7 : 0) + arrowHeight / 2;
    let x = "";
    let y = "";
    if (placedSide === "bottom") {
      x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
      y = `${-arrowHeight}px`;
    } else if (placedSide === "top") {
      x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
      y = `${rects.floating.height + arrowHeight}px`;
    } else if (placedSide === "right") {
      x = `${-arrowHeight}px`;
      y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
    } else if (placedSide === "left") {
      x = `${rects.floating.width + arrowHeight}px`;
      y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
    }
    return {
      data: {
        x,
        y
      }
    };
  }
});
function $cf1ac5d9fe0e8206$var$getSideAndAlignFromPlacement(placement) {
  const [side, align = "center"] = placement.split("-");
  return [
    side,
    align
  ];
}
var $cf1ac5d9fe0e8206$export$be92b6f5f03c0fe9 = $cf1ac5d9fe0e8206$export$badac9ada3a0bdf9;
var $cf1ac5d9fe0e8206$export$b688253958b8dfe7 = $cf1ac5d9fe0e8206$export$ecd4e1ccab6ed6d;
var $cf1ac5d9fe0e8206$export$7c6e2c02157bb7d2 = $cf1ac5d9fe0e8206$export$bc4ae5855d3c4fc;
var $cf1ac5d9fe0e8206$export$21b07c8f274aebd5 = $cf1ac5d9fe0e8206$export$79d62cd4e10a3fd0;

// node_modules/.deno/@radix-ui+react-portal@1.0.2/node_modules/@radix-ui/react-portal/dist/index.module.js
var import_react89 = __toESM(require_react());
var import_react_dom3 = __toESM(require_react_dom());
var $f1701beae083dbae$var$PORTAL_NAME = "Portal";
var $f1701beae083dbae$export$602eac185826482c = (0, import_react89.forwardRef)((props, forwardedRef) => {
  var _globalThis$document;
  const { container = globalThis === null || globalThis === void 0 ? void 0 : (_globalThis$document = globalThis.document) === null || _globalThis$document === void 0 ? void 0 : _globalThis$document.body, ...portalProps } = props;
  return container ? import_react_dom3.default.createPortal((0, import_react89.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.div, _extends({}, portalProps, {
    ref: forwardedRef
  })), container) : null;
});
Object.assign($f1701beae083dbae$export$602eac185826482c, {
  displayName: $f1701beae083dbae$var$PORTAL_NAME
});

// node_modules/.deno/@radix-ui+react-presence@1.0.0/node_modules/@radix-ui/react-presence/dist/index.module.js
var import_react90 = __toESM(require_react());
var import_react_dom4 = __toESM(require_react_dom());
function $fe963b355347cc68$export$3e6543de14f8614f(initialState2, machine) {
  return (0, import_react90.useReducer)((state, event) => {
    const nextState = machine[state][event];
    return nextState !== null && nextState !== void 0 ? nextState : state;
  }, initialState2);
}
var $921a889cee6df7e8$export$99c2b779aa4e8b8b = (props) => {
  const { present, children } = props;
  const presence = $921a889cee6df7e8$var$usePresence(present);
  const child = typeof children === "function" ? children({
    present: presence.isPresent
  }) : import_react90.Children.only(children);
  const ref = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(presence.ref, child.ref);
  const forceMount = typeof children === "function";
  return forceMount || presence.isPresent ? (0, import_react90.cloneElement)(child, {
    ref
  }) : null;
};
$921a889cee6df7e8$export$99c2b779aa4e8b8b.displayName = "Presence";
function $921a889cee6df7e8$var$usePresence(present) {
  const [node1, setNode] = (0, import_react90.useState)();
  const stylesRef = (0, import_react90.useRef)({});
  const prevPresentRef = (0, import_react90.useRef)(present);
  const prevAnimationNameRef = (0, import_react90.useRef)("none");
  const initialState2 = present ? "mounted" : "unmounted";
  const [state, send] = $fe963b355347cc68$export$3e6543de14f8614f(initialState2, {
    mounted: {
      UNMOUNT: "unmounted",
      ANIMATION_OUT: "unmountSuspended"
    },
    unmountSuspended: {
      MOUNT: "mounted",
      ANIMATION_END: "unmounted"
    },
    unmounted: {
      MOUNT: "mounted"
    }
  });
  (0, import_react90.useEffect)(() => {
    const currentAnimationName = $921a889cee6df7e8$var$getAnimationName(stylesRef.current);
    prevAnimationNameRef.current = state === "mounted" ? currentAnimationName : "none";
  }, [
    state
  ]);
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    const styles = stylesRef.current;
    const wasPresent = prevPresentRef.current;
    const hasPresentChanged = wasPresent !== present;
    if (hasPresentChanged) {
      const prevAnimationName = prevAnimationNameRef.current;
      const currentAnimationName = $921a889cee6df7e8$var$getAnimationName(styles);
      if (present)
        send("MOUNT");
      else if (currentAnimationName === "none" || (styles === null || styles === void 0 ? void 0 : styles.display) === "none")
        send("UNMOUNT");
      else {
        const isAnimating = prevAnimationName !== currentAnimationName;
        if (wasPresent && isAnimating)
          send("ANIMATION_OUT");
        else
          send("UNMOUNT");
      }
      prevPresentRef.current = present;
    }
  }, [
    present,
    send
  ]);
  $9f79659886946c16$export$e5c5a5f917a5871c(() => {
    if (node1) {
      const handleAnimationEnd = (event) => {
        const currentAnimationName = $921a889cee6df7e8$var$getAnimationName(stylesRef.current);
        const isCurrentAnimation = currentAnimationName.includes(event.animationName);
        if (event.target === node1 && isCurrentAnimation)
          (0, import_react_dom4.flushSync)(
            () => send("ANIMATION_END")
          );
      };
      const handleAnimationStart = (event) => {
        if (event.target === node1)
          prevAnimationNameRef.current = $921a889cee6df7e8$var$getAnimationName(stylesRef.current);
      };
      node1.addEventListener("animationstart", handleAnimationStart);
      node1.addEventListener("animationcancel", handleAnimationEnd);
      node1.addEventListener("animationend", handleAnimationEnd);
      return () => {
        node1.removeEventListener("animationstart", handleAnimationStart);
        node1.removeEventListener("animationcancel", handleAnimationEnd);
        node1.removeEventListener("animationend", handleAnimationEnd);
      };
    } else
      send("ANIMATION_END");
  }, [
    node1,
    send
  ]);
  return {
    isPresent: [
      "mounted",
      "unmountSuspended"
    ].includes(state),
    ref: (0, import_react90.useCallback)((node) => {
      if (node)
        stylesRef.current = getComputedStyle(node);
      setNode(node);
    }, [])
  };
}
function $921a889cee6df7e8$var$getAnimationName(styles) {
  return (styles === null || styles === void 0 ? void 0 : styles.animationName) || "none";
}

// node_modules/.deno/@radix-ui+react-use-controllable-state@1.0.0/node_modules/@radix-ui/react-use-controllable-state/dist/index.module.js
var import_react91 = __toESM(require_react());
function $71cd76cc60e0454e$export$6f32135080cb4c3({ prop, defaultProp, onChange = () => {
} }) {
  const [uncontrolledProp, setUncontrolledProp] = $71cd76cc60e0454e$var$useUncontrolledState({
    defaultProp,
    onChange
  });
  const isControlled = prop !== void 0;
  const value1 = isControlled ? prop : uncontrolledProp;
  const handleChange = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onChange);
  const setValue = (0, import_react91.useCallback)((nextValue) => {
    if (isControlled) {
      const setter = nextValue;
      const value = typeof nextValue === "function" ? setter(prop) : nextValue;
      if (value !== prop)
        handleChange(value);
    } else
      setUncontrolledProp(nextValue);
  }, [
    isControlled,
    prop,
    setUncontrolledProp,
    handleChange
  ]);
  return [
    value1,
    setValue
  ];
}
function $71cd76cc60e0454e$var$useUncontrolledState({ defaultProp, onChange }) {
  const uncontrolledState = (0, import_react91.useState)(defaultProp);
  const [value] = uncontrolledState;
  const prevValueRef = (0, import_react91.useRef)(value);
  const handleChange = $b1b2314f5f9a1d84$export$25bec8c6f54ee79a(onChange);
  (0, import_react91.useEffect)(() => {
    if (prevValueRef.current !== value) {
      handleChange(value);
      prevValueRef.current = value;
    }
  }, [
    value,
    prevValueRef,
    handleChange
  ]);
  return uncontrolledState;
}

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/Combination.js
var React53 = __toESM(require_react());

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/UI.js
var React51 = __toESM(require_react());

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/medium.js
var effectCar = createSidecarMedium();

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/UI.js
var nothing = function() {
  return;
};
var RemoveScroll = React51.forwardRef(function(props, parentRef) {
  var ref = React51.useRef(null);
  var _a = React51.useState({
    onScrollCapture: nothing,
    onWheelCapture: nothing,
    onTouchMoveCapture: nothing
  }), callbacks = _a[0], setCallbacks = _a[1];
  var forwardProps = props.forwardProps, children = props.children, className = props.className, removeScrollBar = props.removeScrollBar, enabled = props.enabled, shards = props.shards, sideCar = props.sideCar, noIsolation = props.noIsolation, inert = props.inert, allowPinchZoom = props.allowPinchZoom, _b = props.as, Container = _b === void 0 ? "div" : _b, rest = __rest(props, ["forwardProps", "children", "className", "removeScrollBar", "enabled", "shards", "sideCar", "noIsolation", "inert", "allowPinchZoom", "as"]);
  var SideCar = sideCar;
  var containerRef = useMergeRefs([ref, parentRef]);
  var containerProps = __assign(__assign({}, rest), callbacks);
  return React51.createElement(
    React51.Fragment,
    null,
    enabled && React51.createElement(SideCar, { sideCar: effectCar, removeScrollBar, shards, noIsolation, inert, setCallbacks, allowPinchZoom: !!allowPinchZoom, lockRef: ref }),
    forwardProps ? React51.cloneElement(React51.Children.only(children), __assign(__assign({}, containerProps), { ref: containerRef })) : React51.createElement(Container, __assign({}, containerProps, { className, ref: containerRef }), children)
  );
});
RemoveScroll.defaultProps = {
  enabled: true,
  removeScrollBar: true,
  inert: false
};
RemoveScroll.classNames = {
  fullWidth: fullWidthClassName,
  zeroRight: zeroRightClassName
};

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/SideEffect.js
var React52 = __toESM(require_react());

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/aggresiveCapture.js
var passiveSupported = false;
if (typeof window !== "undefined") {
  try {
    options = Object.defineProperty({}, "passive", {
      get: function() {
        passiveSupported = true;
        return true;
      }
    });
    window.addEventListener("test", options, options);
    window.removeEventListener("test", options, options);
  } catch (err) {
    passiveSupported = false;
  }
}
var options;
var nonPassive = passiveSupported ? { passive: false } : false;

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/handleScroll.js
var alwaysContainsScroll = function(node) {
  return node.tagName === "TEXTAREA";
};
var elementCanBeScrolled = function(node, overflow) {
  var styles = window.getComputedStyle(node);
  return (
    // not-not-scrollable
    styles[overflow] !== "hidden" && // contains scroll inside self
    !(styles.overflowY === styles.overflowX && !alwaysContainsScroll(node) && styles[overflow] === "visible")
  );
};
var elementCouldBeVScrolled = function(node) {
  return elementCanBeScrolled(node, "overflowY");
};
var elementCouldBeHScrolled = function(node) {
  return elementCanBeScrolled(node, "overflowX");
};
var locationCouldBeScrolled = function(axis, node) {
  var current = node;
  do {
    if (typeof ShadowRoot !== "undefined" && current instanceof ShadowRoot) {
      current = current.host;
    }
    var isScrollable = elementCouldBeScrolled(axis, current);
    if (isScrollable) {
      var _a = getScrollVariables(axis, current), s = _a[1], d = _a[2];
      if (s > d) {
        return true;
      }
    }
    current = current.parentNode;
  } while (current && current !== document.body);
  return false;
};
var getVScrollVariables = function(_a) {
  var scrollTop = _a.scrollTop, scrollHeight = _a.scrollHeight, clientHeight = _a.clientHeight;
  return [
    scrollTop,
    scrollHeight,
    clientHeight
  ];
};
var getHScrollVariables = function(_a) {
  var scrollLeft = _a.scrollLeft, scrollWidth = _a.scrollWidth, clientWidth = _a.clientWidth;
  return [
    scrollLeft,
    scrollWidth,
    clientWidth
  ];
};
var elementCouldBeScrolled = function(axis, node) {
  return axis === "v" ? elementCouldBeVScrolled(node) : elementCouldBeHScrolled(node);
};
var getScrollVariables = function(axis, node) {
  return axis === "v" ? getVScrollVariables(node) : getHScrollVariables(node);
};
var getDirectionFactor = function(axis, direction) {
  return axis === "h" && direction === "rtl" ? -1 : 1;
};
var handleScroll = function(axis, endTarget, event, sourceDelta, noOverscroll) {
  var directionFactor = getDirectionFactor(axis, window.getComputedStyle(endTarget).direction);
  var delta = directionFactor * sourceDelta;
  var target = event.target;
  var targetInLock = endTarget.contains(target);
  var shouldCancelScroll = false;
  var isDeltaPositive = delta > 0;
  var availableScroll = 0;
  var availableScrollTop = 0;
  do {
    var _a = getScrollVariables(axis, target), position = _a[0], scroll_1 = _a[1], capacity = _a[2];
    var elementScroll = scroll_1 - capacity - directionFactor * position;
    if (position || elementScroll) {
      if (elementCouldBeScrolled(axis, target)) {
        availableScroll += elementScroll;
        availableScrollTop += position;
      }
    }
    target = target.parentNode;
  } while (
    // portaled content
    !targetInLock && target !== document.body || // self content
    targetInLock && (endTarget.contains(target) || endTarget === target)
  );
  if (isDeltaPositive && (noOverscroll && availableScroll === 0 || !noOverscroll && delta > availableScroll)) {
    shouldCancelScroll = true;
  } else if (!isDeltaPositive && (noOverscroll && availableScrollTop === 0 || !noOverscroll && -delta > availableScrollTop)) {
    shouldCancelScroll = true;
  }
  return shouldCancelScroll;
};

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/SideEffect.js
var getTouchXY = function(event) {
  return "changedTouches" in event ? [event.changedTouches[0].clientX, event.changedTouches[0].clientY] : [0, 0];
};
var getDeltaXY = function(event) {
  return [event.deltaX, event.deltaY];
};
var extractRef = function(ref) {
  return ref && "current" in ref ? ref.current : ref;
};
var deltaCompare = function(x, y) {
  return x[0] === y[0] && x[1] === y[1];
};
var generateStyle = function(id) {
  return "\n  .block-interactivity-".concat(id, " {pointer-events: none;}\n  .allow-interactivity-").concat(id, " {pointer-events: all;}\n");
};
var idCounter = 0;
var lockStack = [];
function RemoveScrollSideCar(props) {
  var shouldPreventQueue = React52.useRef([]);
  var touchStartRef = React52.useRef([0, 0]);
  var activeAxis = React52.useRef();
  var id = React52.useState(idCounter++)[0];
  var Style = React52.useState(function() {
    return styleSingleton();
  })[0];
  var lastProps = React52.useRef(props);
  React52.useEffect(function() {
    lastProps.current = props;
  }, [props]);
  React52.useEffect(function() {
    if (props.inert) {
      document.body.classList.add("block-interactivity-".concat(id));
      var allow_1 = __spreadArray([props.lockRef.current], (props.shards || []).map(extractRef), true).filter(Boolean);
      allow_1.forEach(function(el) {
        return el.classList.add("allow-interactivity-".concat(id));
      });
      return function() {
        document.body.classList.remove("block-interactivity-".concat(id));
        allow_1.forEach(function(el) {
          return el.classList.remove("allow-interactivity-".concat(id));
        });
      };
    }
    return;
  }, [props.inert, props.lockRef.current, props.shards]);
  var shouldCancelEvent = React52.useCallback(function(event, parent) {
    if ("touches" in event && event.touches.length === 2) {
      return !lastProps.current.allowPinchZoom;
    }
    var touch = getTouchXY(event);
    var touchStart = touchStartRef.current;
    var deltaX = "deltaX" in event ? event.deltaX : touchStart[0] - touch[0];
    var deltaY = "deltaY" in event ? event.deltaY : touchStart[1] - touch[1];
    var currentAxis;
    var target = event.target;
    var moveDirection = Math.abs(deltaX) > Math.abs(deltaY) ? "h" : "v";
    if ("touches" in event && moveDirection === "h" && target.type === "range") {
      return false;
    }
    var canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);
    if (!canBeScrolledInMainDirection) {
      return true;
    }
    if (canBeScrolledInMainDirection) {
      currentAxis = moveDirection;
    } else {
      currentAxis = moveDirection === "v" ? "h" : "v";
      canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);
    }
    if (!canBeScrolledInMainDirection) {
      return false;
    }
    if (!activeAxis.current && "changedTouches" in event && (deltaX || deltaY)) {
      activeAxis.current = currentAxis;
    }
    if (!currentAxis) {
      return true;
    }
    var cancelingAxis = activeAxis.current || currentAxis;
    return handleScroll(cancelingAxis, parent, event, cancelingAxis === "h" ? deltaX : deltaY, true);
  }, []);
  var shouldPrevent = React52.useCallback(function(_event) {
    var event = _event;
    if (!lockStack.length || lockStack[lockStack.length - 1] !== Style) {
      return;
    }
    var delta = "deltaY" in event ? getDeltaXY(event) : getTouchXY(event);
    var sourceEvent = shouldPreventQueue.current.filter(function(e) {
      return e.name === event.type && e.target === event.target && deltaCompare(e.delta, delta);
    })[0];
    if (sourceEvent && sourceEvent.should) {
      if (event.cancelable) {
        event.preventDefault();
      }
      return;
    }
    if (!sourceEvent) {
      var shardNodes = (lastProps.current.shards || []).map(extractRef).filter(Boolean).filter(function(node) {
        return node.contains(event.target);
      });
      var shouldStop = shardNodes.length > 0 ? shouldCancelEvent(event, shardNodes[0]) : !lastProps.current.noIsolation;
      if (shouldStop) {
        if (event.cancelable) {
          event.preventDefault();
        }
      }
    }
  }, []);
  var shouldCancel = React52.useCallback(function(name, delta, target, should) {
    var event = { name, delta, target, should };
    shouldPreventQueue.current.push(event);
    setTimeout(function() {
      shouldPreventQueue.current = shouldPreventQueue.current.filter(function(e) {
        return e !== event;
      });
    }, 1);
  }, []);
  var scrollTouchStart = React52.useCallback(function(event) {
    touchStartRef.current = getTouchXY(event);
    activeAxis.current = void 0;
  }, []);
  var scrollWheel = React52.useCallback(function(event) {
    shouldCancel(event.type, getDeltaXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));
  }, []);
  var scrollTouchMove = React52.useCallback(function(event) {
    shouldCancel(event.type, getTouchXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));
  }, []);
  React52.useEffect(function() {
    lockStack.push(Style);
    props.setCallbacks({
      onScrollCapture: scrollWheel,
      onWheelCapture: scrollWheel,
      onTouchMoveCapture: scrollTouchMove
    });
    document.addEventListener("wheel", shouldPrevent, nonPassive);
    document.addEventListener("touchmove", shouldPrevent, nonPassive);
    document.addEventListener("touchstart", scrollTouchStart, nonPassive);
    return function() {
      lockStack = lockStack.filter(function(inst) {
        return inst !== Style;
      });
      document.removeEventListener("wheel", shouldPrevent, nonPassive);
      document.removeEventListener("touchmove", shouldPrevent, nonPassive);
      document.removeEventListener("touchstart", scrollTouchStart, nonPassive);
    };
  }, []);
  var removeScrollBar = props.removeScrollBar, inert = props.inert;
  return React52.createElement(
    React52.Fragment,
    null,
    inert ? React52.createElement(Style, { styles: generateStyle(id) }) : null,
    removeScrollBar ? React52.createElement(RemoveScrollBar, { gapMode: "margin" }) : null
  );
}

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/sidecar.js
var sidecar_default = exportSidecar(effectCar, RemoveScrollSideCar);

// node_modules/.deno/react-remove-scroll@2.5.5/node_modules/react-remove-scroll/dist/es2015/Combination.js
var ReactRemoveScroll = React53.forwardRef(function(props, ref) {
  return React53.createElement(RemoveScroll, __assign({}, props, { ref, sideCar: sidecar_default }));
});
ReactRemoveScroll.classNames = RemoveScroll.classNames;
var Combination_default = ReactRemoveScroll;

// node_modules/.deno/@radix-ui+react-popover@1.0.6-rc.5/node_modules/@radix-ui/react-popover/dist/index.module.js
var $cb5cc270b50c6fcd$var$POPOVER_NAME = "Popover";
var [$cb5cc270b50c6fcd$var$createPopoverContext, $cb5cc270b50c6fcd$export$c8393c9e73286932] = $c512c27ab02ef895$export$50c7b4e9d9f19c1($cb5cc270b50c6fcd$var$POPOVER_NAME, [
  $cf1ac5d9fe0e8206$export$722aac194ae923
]);
var $cb5cc270b50c6fcd$var$usePopperScope = $cf1ac5d9fe0e8206$export$722aac194ae923();
var [$cb5cc270b50c6fcd$var$PopoverProvider, $cb5cc270b50c6fcd$var$usePopoverContext] = $cb5cc270b50c6fcd$var$createPopoverContext($cb5cc270b50c6fcd$var$POPOVER_NAME);
var $cb5cc270b50c6fcd$export$5b6b19405a83ff9d = (props) => {
  const { __scopePopover, children, open: openProp, defaultOpen, onOpenChange, modal = false } = props;
  const popperScope = $cb5cc270b50c6fcd$var$usePopperScope(__scopePopover);
  const triggerRef = (0, import_react92.useRef)(null);
  const [hasCustomAnchor, setHasCustomAnchor] = (0, import_react92.useState)(false);
  const [open = false, setOpen] = $71cd76cc60e0454e$export$6f32135080cb4c3({
    prop: openProp,
    defaultProp: defaultOpen,
    onChange: onOpenChange
  });
  return (0, import_react92.createElement)($cf1ac5d9fe0e8206$export$be92b6f5f03c0fe9, popperScope, (0, import_react92.createElement)($cb5cc270b50c6fcd$var$PopoverProvider, {
    scope: __scopePopover,
    contentId: $1746a345f3d73bb7$export$f680877a34711e37(),
    triggerRef,
    open,
    onOpenChange: setOpen,
    onOpenToggle: (0, import_react92.useCallback)(
      () => setOpen(
        (prevOpen) => !prevOpen
      ),
      [
        setOpen
      ]
    ),
    hasCustomAnchor,
    onCustomAnchorAdd: (0, import_react92.useCallback)(
      () => setHasCustomAnchor(true),
      []
    ),
    onCustomAnchorRemove: (0, import_react92.useCallback)(
      () => setHasCustomAnchor(false),
      []
    ),
    modal
  }, children));
};
Object.assign($cb5cc270b50c6fcd$export$5b6b19405a83ff9d, {
  displayName: $cb5cc270b50c6fcd$var$POPOVER_NAME
});
var $cb5cc270b50c6fcd$var$ANCHOR_NAME = "PopoverAnchor";
var $cb5cc270b50c6fcd$export$96e5381f42521a79 = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const { __scopePopover, ...anchorProps } = props;
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$ANCHOR_NAME, __scopePopover);
  const popperScope = $cb5cc270b50c6fcd$var$usePopperScope(__scopePopover);
  const { onCustomAnchorAdd, onCustomAnchorRemove } = context;
  (0, import_react92.useEffect)(() => {
    onCustomAnchorAdd();
    return () => onCustomAnchorRemove();
  }, [
    onCustomAnchorAdd,
    onCustomAnchorRemove
  ]);
  return (0, import_react92.createElement)($cf1ac5d9fe0e8206$export$b688253958b8dfe7, _extends({}, popperScope, anchorProps, {
    ref: forwardedRef
  }));
});
Object.assign($cb5cc270b50c6fcd$export$96e5381f42521a79, {
  displayName: $cb5cc270b50c6fcd$var$ANCHOR_NAME
});
var $cb5cc270b50c6fcd$var$TRIGGER_NAME = "PopoverTrigger";
var $cb5cc270b50c6fcd$export$7dacb05d26466c3 = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const { __scopePopover, ...triggerProps } = props;
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$TRIGGER_NAME, __scopePopover);
  const popperScope = $cb5cc270b50c6fcd$var$usePopperScope(__scopePopover);
  const composedTriggerRef = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(forwardedRef, context.triggerRef);
  const trigger2 = (0, import_react92.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.button, _extends({
    type: "button",
    "aria-haspopup": "dialog",
    "aria-expanded": context.open,
    "aria-controls": context.contentId,
    "data-state": $cb5cc270b50c6fcd$var$getState(context.open)
  }, triggerProps, {
    ref: composedTriggerRef,
    onClick: $e42e1063c40fb3ef$export$b9ecd428b558ff10(props.onClick, context.onOpenToggle)
  }));
  return context.hasCustomAnchor ? trigger2 : (0, import_react92.createElement)($cf1ac5d9fe0e8206$export$b688253958b8dfe7, _extends({
    asChild: true
  }, popperScope), trigger2);
});
Object.assign($cb5cc270b50c6fcd$export$7dacb05d26466c3, {
  displayName: $cb5cc270b50c6fcd$var$TRIGGER_NAME
});
var $cb5cc270b50c6fcd$var$PORTAL_NAME = "PopoverPortal";
var [$cb5cc270b50c6fcd$var$PortalProvider, $cb5cc270b50c6fcd$var$usePortalContext] = $cb5cc270b50c6fcd$var$createPopoverContext($cb5cc270b50c6fcd$var$PORTAL_NAME, {
  forceMount: void 0
});
var $cb5cc270b50c6fcd$export$dd679ffb4362d2d4 = (props) => {
  const { __scopePopover, forceMount, children, container } = props;
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$PORTAL_NAME, __scopePopover);
  return (0, import_react92.createElement)($cb5cc270b50c6fcd$var$PortalProvider, {
    scope: __scopePopover,
    forceMount
  }, (0, import_react92.createElement)($921a889cee6df7e8$export$99c2b779aa4e8b8b, {
    present: forceMount || context.open
  }, (0, import_react92.createElement)($f1701beae083dbae$export$602eac185826482c, {
    asChild: true,
    container
  }, children)));
};
Object.assign($cb5cc270b50c6fcd$export$dd679ffb4362d2d4, {
  displayName: $cb5cc270b50c6fcd$var$PORTAL_NAME
});
var $cb5cc270b50c6fcd$var$CONTENT_NAME = "PopoverContent";
var $cb5cc270b50c6fcd$export$d7e1f420b25549ff = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const portalContext = $cb5cc270b50c6fcd$var$usePortalContext($cb5cc270b50c6fcd$var$CONTENT_NAME, props.__scopePopover);
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$CONTENT_NAME, props.__scopePopover);
  return (0, import_react92.createElement)($921a889cee6df7e8$export$99c2b779aa4e8b8b, {
    present: forceMount || context.open
  }, context.modal ? (0, import_react92.createElement)($cb5cc270b50c6fcd$var$PopoverContentModal, _extends({}, contentProps, {
    ref: forwardedRef
  })) : (0, import_react92.createElement)($cb5cc270b50c6fcd$var$PopoverContentNonModal, _extends({}, contentProps, {
    ref: forwardedRef
  })));
});
Object.assign($cb5cc270b50c6fcd$export$d7e1f420b25549ff, {
  displayName: $cb5cc270b50c6fcd$var$CONTENT_NAME
});
var $cb5cc270b50c6fcd$var$PopoverContentModal = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$CONTENT_NAME, props.__scopePopover);
  const contentRef = (0, import_react92.useRef)(null);
  const composedRefs = $6ed0406888f73fc4$export$c7b2cbe3552a0d05(forwardedRef, contentRef);
  const isRightClickOutsideRef = (0, import_react92.useRef)(false);
  (0, import_react92.useEffect)(() => {
    const content = contentRef.current;
    if (content)
      return hideOthers(content);
  }, []);
  return (0, import_react92.createElement)(Combination_default, {
    as: $5e63c961fc1ce211$export$8c6ed5c666ac1360,
    allowPinchZoom: true
  }, (0, import_react92.createElement)($cb5cc270b50c6fcd$var$PopoverContentImpl, _extends({}, props, {
    ref: composedRefs,
    trapFocus: context.open,
    disableOutsidePointerEvents: true,
    onCloseAutoFocus: $e42e1063c40fb3ef$export$b9ecd428b558ff10(props.onCloseAutoFocus, (event) => {
      var _context$triggerRef$c;
      event.preventDefault();
      if (!isRightClickOutsideRef.current)
        (_context$triggerRef$c = context.triggerRef.current) === null || _context$triggerRef$c === void 0 || _context$triggerRef$c.focus();
    }),
    onPointerDownOutside: $e42e1063c40fb3ef$export$b9ecd428b558ff10(props.onPointerDownOutside, (event) => {
      const originalEvent = event.detail.originalEvent;
      const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
      const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
      isRightClickOutsideRef.current = isRightClick;
    }, {
      checkForDefaultPrevented: false
    }),
    onFocusOutside: $e42e1063c40fb3ef$export$b9ecd428b558ff10(
      props.onFocusOutside,
      (event) => event.preventDefault(),
      {
        checkForDefaultPrevented: false
      }
    )
  })));
});
var $cb5cc270b50c6fcd$var$PopoverContentNonModal = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$CONTENT_NAME, props.__scopePopover);
  const hasInteractedOutsideRef = (0, import_react92.useRef)(false);
  const hasPointerDownOutsideRef = (0, import_react92.useRef)(false);
  return (0, import_react92.createElement)($cb5cc270b50c6fcd$var$PopoverContentImpl, _extends({}, props, {
    ref: forwardedRef,
    trapFocus: false,
    disableOutsidePointerEvents: false,
    onCloseAutoFocus: (event) => {
      var _props$onCloseAutoFoc;
      (_props$onCloseAutoFoc = props.onCloseAutoFocus) === null || _props$onCloseAutoFoc === void 0 || _props$onCloseAutoFoc.call(props, event);
      if (!event.defaultPrevented) {
        var _context$triggerRef$c2;
        if (!hasInteractedOutsideRef.current)
          (_context$triggerRef$c2 = context.triggerRef.current) === null || _context$triggerRef$c2 === void 0 || _context$triggerRef$c2.focus();
        event.preventDefault();
      }
      hasInteractedOutsideRef.current = false;
      hasPointerDownOutsideRef.current = false;
    },
    onInteractOutside: (event) => {
      var _props$onInteractOuts, _context$triggerRef$c3;
      (_props$onInteractOuts = props.onInteractOutside) === null || _props$onInteractOuts === void 0 || _props$onInteractOuts.call(props, event);
      if (!event.defaultPrevented) {
        hasInteractedOutsideRef.current = true;
        if (event.detail.originalEvent.type === "pointerdown")
          hasPointerDownOutsideRef.current = true;
      }
      const target = event.target;
      const targetIsTrigger = (_context$triggerRef$c3 = context.triggerRef.current) === null || _context$triggerRef$c3 === void 0 ? void 0 : _context$triggerRef$c3.contains(target);
      if (targetIsTrigger)
        event.preventDefault();
      if (event.detail.originalEvent.type === "focusin" && hasPointerDownOutsideRef.current)
        event.preventDefault();
    }
  }));
});
var $cb5cc270b50c6fcd$var$PopoverContentImpl = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const { __scopePopover, trapFocus, onOpenAutoFocus, onCloseAutoFocus, disableOutsidePointerEvents, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, ...contentProps } = props;
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$CONTENT_NAME, __scopePopover);
  const popperScope = $cb5cc270b50c6fcd$var$usePopperScope(__scopePopover);
  $3db38b7d1fb3fe6a$export$b7ece24a22aeda8c();
  return (0, import_react92.createElement)($d3863c46a17e8a28$export$20e40289641fbbb6, {
    asChild: true,
    loop: true,
    trapped: trapFocus,
    onMountAutoFocus: onOpenAutoFocus,
    onUnmountAutoFocus: onCloseAutoFocus
  }, (0, import_react92.createElement)($5cb92bef7577960e$export$177fb62ff3ec1f22, {
    asChild: true,
    disableOutsidePointerEvents,
    onInteractOutside,
    onEscapeKeyDown,
    onPointerDownOutside,
    onFocusOutside,
    onDismiss: () => context.onOpenChange(false)
  }, (0, import_react92.createElement)($cf1ac5d9fe0e8206$export$7c6e2c02157bb7d2, _extends({
    "data-state": $cb5cc270b50c6fcd$var$getState(context.open),
    role: "dialog",
    id: context.contentId
  }, popperScope, contentProps, {
    ref: forwardedRef,
    style: {
      ...contentProps.style,
      "--radix-popover-content-transform-origin": "var(--radix-popper-transform-origin)",
      "--radix-popover-content-available-width": "var(--radix-popper-available-width)",
      "--radix-popover-content-available-height": "var(--radix-popper-available-height)",
      "--radix-popover-trigger-width": "var(--radix-popper-anchor-width)",
      "--radix-popover-trigger-height": "var(--radix-popper-anchor-height)"
    }
  }))));
});
var $cb5cc270b50c6fcd$var$CLOSE_NAME = "PopoverClose";
var $cb5cc270b50c6fcd$export$d6ac43ebaa40d53e = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const { __scopePopover, ...closeProps } = props;
  const context = $cb5cc270b50c6fcd$var$usePopoverContext($cb5cc270b50c6fcd$var$CLOSE_NAME, __scopePopover);
  return (0, import_react92.createElement)($8927f6f2acc4f386$export$250ffa63cdc0d034.button, _extends({
    type: "button"
  }, closeProps, {
    ref: forwardedRef,
    onClick: $e42e1063c40fb3ef$export$b9ecd428b558ff10(
      props.onClick,
      () => context.onOpenChange(false)
    )
  }));
});
Object.assign($cb5cc270b50c6fcd$export$d6ac43ebaa40d53e, {
  displayName: $cb5cc270b50c6fcd$var$CLOSE_NAME
});
var $cb5cc270b50c6fcd$var$ARROW_NAME = "PopoverArrow";
var $cb5cc270b50c6fcd$export$3152841115e061b2 = (0, import_react92.forwardRef)((props, forwardedRef) => {
  const { __scopePopover, ...arrowProps } = props;
  const popperScope = $cb5cc270b50c6fcd$var$usePopperScope(__scopePopover);
  return (0, import_react92.createElement)($cf1ac5d9fe0e8206$export$21b07c8f274aebd5, _extends({}, popperScope, arrowProps, {
    ref: forwardedRef
  }));
});
Object.assign($cb5cc270b50c6fcd$export$3152841115e061b2, {
  displayName: $cb5cc270b50c6fcd$var$ARROW_NAME
});
function $cb5cc270b50c6fcd$var$getState(open) {
  return open ? "open" : "closed";
}
var $cb5cc270b50c6fcd$export$be92b6f5f03c0fe9 = $cb5cc270b50c6fcd$export$5b6b19405a83ff9d;
var $cb5cc270b50c6fcd$export$41fb9f06171c75f4 = $cb5cc270b50c6fcd$export$7dacb05d26466c3;
var $cb5cc270b50c6fcd$export$602eac185826482c = $cb5cc270b50c6fcd$export$dd679ffb4362d2d4;
var $cb5cc270b50c6fcd$export$7c6e2c02157bb7d2 = $cb5cc270b50c6fcd$export$d7e1f420b25549ff;

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/ActionsMenu.mjs
var import_react93 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Popover.mjs
var import_jsx_runtime99 = __toESM(require_jsx_runtime(), 1);
var Popover = ({ id, children, onOpenChange }) => {
  const [isOpen, handleOpenChange] = useMenuIsOpen(id, onOpenChange);
  return (0, import_jsx_runtime99.jsx)($cb5cc270b50c6fcd$export$be92b6f5f03c0fe9, { onOpenChange: handleOpenChange, open: isOpen, children: (0, import_jsx_runtime99.jsx)("div", { className: "tlui-popover", children }) });
};
var PopoverTrigger = ({ children, disabled, "data-testid": testId }) => {
  return (0, import_jsx_runtime99.jsx)($cb5cc270b50c6fcd$export$41fb9f06171c75f4, { "data-testid": testId, disabled, asChild: true, dir: "ltr", children });
};
var PopoverContent = ({ side, children, align = "center", sideOffset = 8, alignOffset = 0 }) => {
  const container = useContainer();
  return (0, import_jsx_runtime99.jsx)($cb5cc270b50c6fcd$export$602eac185826482c, { dir: "ltr", container, children: (0, import_jsx_runtime99.jsx)(
    $cb5cc270b50c6fcd$export$7c6e2c02157bb7d2,
    {
      className: "tlui-popover__content",
      side,
      sideOffset,
      align,
      alignOffset,
      dir: "ltr",
      children
    }
  ) });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/ActionsMenu.mjs
var ActionsMenu = (0, import_react93.memo)(function ActionsMenu2() {
  const msg2 = useTranslation();
  const container = useContainer();
  const menuSchema = useActionsMenuSchema();
  const isReadonly = useReadonly();
  function getActionMenuItem(item) {
    if (isReadonly && !item.readonlyOk)
      return null;
    switch (item.type) {
      case "item": {
        const { id, icon, label, kbd: kbd2, onSelect } = item.actionItem;
        return (0, import_jsx_runtime100.jsx)(
          Button,
          {
            className: "tlui-button-grid__button",
            "data-testid": `menu-item.${item.id}`,
            icon,
            title: label ? kbd2 ? `${msg2(label)} ${kbdStr(kbd2)}` : `${msg2(label)}` : kbd2 ? `${kbdStr(kbd2)}` : "",
            onClick: () => onSelect("actions-menu"),
            disabled: item.disabled
          },
          id
        );
      }
    }
  }
  return (0, import_jsx_runtime100.jsxs)(Popover, { id: "actions menu", children: [
    (0, import_jsx_runtime100.jsx)(PopoverTrigger, { children: (0, import_jsx_runtime100.jsx)(
      Button,
      {
        className: "tlui-menu__trigger",
        "data-testid": "main.action-menu",
        icon: "dots-vertical",
        title: msg2("actions-menu.title"),
        smallIcon: true
      }
    ) }),
    (0, import_jsx_runtime100.jsx)($cb5cc270b50c6fcd$export$602eac185826482c, { dir: "ltr", container, children: (0, import_jsx_runtime100.jsx)(
      $cb5cc270b50c6fcd$export$7c6e2c02157bb7d2,
      {
        className: "tlui-popover__content",
        side: "bottom",
        dir: "ltr",
        sideOffset: 6,
        children: (0, import_jsx_runtime100.jsx)("div", { className: "tlui-actions-menu tlui-button-grid__four", children: menuSchema.map(getActionMenuItem) })
      }
    ) })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/DuplicateButton.mjs
var import_jsx_runtime101 = __toESM(require_jsx_runtime(), 1);
var DuplicateButton = track(function DuplicateButton2() {
  const editor = useEditor();
  const actions = useActions();
  const msg2 = useTranslation();
  const action = actions["duplicate"];
  return (0, import_jsx_runtime101.jsx)(
    Button,
    {
      icon: action.icon,
      onClick: () => action.onSelect("quick-actions"),
      disabled: !(editor.isIn("select") && editor.selectedShapeIds.length > 0),
      title: `${msg2(action.label)} ${kbdStr(action.kbd)}`,
      smallIcon: true
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/Menu.mjs
var import_jsx_runtime102 = __toESM(require_jsx_runtime(), 1);
var React54 = __toESM(require_react(), 1);
var Menu = React54.memo(function Menu2() {
  const msg2 = useTranslation();
  return (0, import_jsx_runtime102.jsxs)(Root4, { id: "main menu", children: [
    (0, import_jsx_runtime102.jsx)(Trigger2, { children: (0, import_jsx_runtime102.jsx)(
      Button,
      {
        className: "tlui-menu__trigger",
        "data-testid": "main.menu",
        title: msg2("menu.title"),
        icon: "menu"
      }
    ) }),
    (0, import_jsx_runtime102.jsx)(Content3, { alignOffset: 0, sideOffset: 6, children: (0, import_jsx_runtime102.jsx)(MenuContent, {}) })
  ] });
});
function MenuContent() {
  const editor = useEditor();
  const msg2 = useTranslation();
  const menuSchema = useMenuSchema();
  const breakpoint = useBreakpoint();
  const isReadonly = useReadonly();
  function getMenuItem(editor2, item, parent, depth) {
    switch (item.type) {
      case "custom": {
        if (isReadonly && !item.readonlyOk)
          return null;
        if (item.id === "LANGUAGE_MENU") {
          return (0, import_jsx_runtime102.jsx)(LanguageMenu, {}, "item");
        }
        return null;
      }
      case "group": {
        if (isReadonly && !item.readonlyOk)
          return null;
        return (0, import_jsx_runtime102.jsx)(
          Group3,
          {
            size: depth <= 1 ? "medium" : breakpoint < 3 || parent?.type === "submenu" && depth > 2 ? "tiny" : "medium",
            children: item.children.map((child) => getMenuItem(editor2, child, item, depth + 1))
          },
          item.id
        );
      }
      case "submenu": {
        if (isReadonly && !item.readonlyOk)
          return null;
        return (0, import_jsx_runtime102.jsxs)(Sub3, { id: `main menu ${parent ? parent.id + " " : ""}${item.id}`, children: [
          (0, import_jsx_runtime102.jsx)(SubTrigger3, { label: item.label, "data-testid": `menu-item.${item.id}` }),
          (0, import_jsx_runtime102.jsx)(SubContent3, { sideOffset: -4, alignOffset: -1, children: item.children.map((child) => getMenuItem(editor2, child, item, depth + 1)) })
        ] }, item.id);
      }
      case "item": {
        if (isReadonly && !item.readonlyOk)
          return null;
        const { id, checkbox, menuLabel, label, onSelect, kbd: kbd2 } = item.actionItem;
        const labelToUse = menuLabel ?? label;
        const labelStr = labelToUse ? msg2(labelToUse) : void 0;
        if (checkbox) {
          return (0, import_jsx_runtime102.jsxs)(
            CheckboxItem3,
            {
              onSelect: () => onSelect("menu"),
              title: labelStr ? labelStr : "",
              checked: item.checked,
              disabled: item.disabled,
              children: [
                labelStr && (0, import_jsx_runtime102.jsx)("span", { children: labelStr }),
                kbd2 && (0, import_jsx_runtime102.jsx)(Kbd, { children: kbd2 })
              ]
            },
            id
          );
        }
        return (0, import_jsx_runtime102.jsx)(
          Item,
          {
            "data-testid": `menu-item.${item.id}`,
            kbd: kbd2,
            label: labelToUse,
            onClick: () => onSelect("menu"),
            disabled: item.disabled
          },
          id
        );
      }
    }
  }
  return (0, import_jsx_runtime102.jsx)(import_jsx_runtime102.Fragment, { children: menuSchema.map((item) => getMenuItem(editor, item, null, 0)) });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/PageMenu/PageMenu.mjs
var import_jsx_runtime105 = __toESM(require_jsx_runtime(), 1);
var import_react96 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs
var import_jsx_runtime103 = __toESM(require_jsx_runtime(), 1);
var import_react94 = __toESM(require_react(), 1);
var PageItemInput = function PageItemInput2({
  name,
  id,
  isCurrentPage
}) {
  const editor = useEditor();
  const rInput = (0, import_react94.useRef)(null);
  const handleChange = (0, import_react94.useCallback)(
    (value) => {
      editor.renamePage(id, value ? value : "New Page", { ephemeral: true });
    },
    [editor, id]
  );
  const handleComplete = (0, import_react94.useCallback)(
    (value) => {
      editor.mark("rename page");
      editor.renamePage(id, value || "New Page", { ephemeral: false });
    },
    [editor, id]
  );
  return (0, import_jsx_runtime103.jsx)(
    Input,
    {
      className: "tlui-page-menu__item__input",
      ref: (el) => rInput.current = el,
      defaultValue: name,
      onValueChange: handleChange,
      onComplete: handleComplete,
      onCancel: handleComplete,
      shouldManuallyMaintainScrollPositionWhenFocused: true,
      autofocus: isCurrentPage,
      autoselect: true
    }
  );
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/PageMenu/PageItemSubmenu.mjs
var import_jsx_runtime104 = __toESM(require_jsx_runtime(), 1);
var import_react95 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/PageMenu/edit-pages-shared.mjs
var onMovePage = (editor, id, from, to) => {
  let index2;
  const pages = editor.pages;
  const below = from > to ? pages[to - 1] : pages[to];
  const above = from > to ? pages[to] : pages[to + 1];
  if (below && !above) {
    index2 = getIndexAbove(below.index);
  } else if (!below && above) {
    index2 = getIndexBelow(pages[0].index);
  } else {
    index2 = getIndexBetween(below.index, above.index);
  }
  if (index2 !== pages[from].index) {
    editor.mark("moving page");
    editor.updatePage({
      id,
      index: index2
    });
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/PageMenu/PageItemSubmenu.mjs
var PageItemSubmenu = track(function PageItemSubmenu2({
  index: index2,
  listSize,
  item,
  onRename
}) {
  const editor = useEditor();
  const msg2 = useTranslation();
  const pages = editor.pages;
  const onDuplicate = (0, import_react95.useCallback)(() => {
    editor.mark("creating page");
    const newId = PageRecordType.createId();
    editor.duplicatePage(item.id, newId);
  }, [editor, item]);
  const onMoveUp = (0, import_react95.useCallback)(() => {
    onMovePage(editor, item.id, index2, index2 - 1);
  }, [editor, item, index2]);
  const onMoveDown = (0, import_react95.useCallback)(() => {
    onMovePage(editor, item.id, index2, index2 + 1);
  }, [editor, item, index2]);
  const onDelete = (0, import_react95.useCallback)(() => {
    editor.mark("deleting page");
    editor.deletePage(item.id);
  }, [editor, item]);
  return (0, import_jsx_runtime104.jsxs)(Root4, { id: `page item submenu ${index2}`, children: [
    (0, import_jsx_runtime104.jsx)(Trigger2, { children: (0, import_jsx_runtime104.jsx)(Button, { title: msg2("page-menu.submenu.title"), icon: "dots-vertical" }) }),
    (0, import_jsx_runtime104.jsxs)(Content3, { alignOffset: 0, children: [
      (0, import_jsx_runtime104.jsxs)(Group3, { children: [
        onRename && (0, import_jsx_runtime104.jsx)(Item22, { dir: "ltr", onSelect: onRename, asChild: true, children: (0, import_jsx_runtime104.jsx)(Button, { className: "tlui-menu__button", label: "page-menu.submenu.rename" }) }),
        (0, import_jsx_runtime104.jsx)(
          Item22,
          {
            dir: "ltr",
            onSelect: onDuplicate,
            disabled: pages.length >= MAX_PAGES,
            asChild: true,
            children: (0, import_jsx_runtime104.jsx)(Button, { className: "tlui-menu__button", label: "page-menu.submenu.duplicate-page" })
          }
        ),
        index2 > 0 && (0, import_jsx_runtime104.jsx)(Item22, { dir: "ltr", onSelect: onMoveUp, asChild: true, children: (0, import_jsx_runtime104.jsx)(Button, { className: "tlui-menu__button", label: "page-menu.submenu.move-up" }) }),
        index2 < listSize - 1 && (0, import_jsx_runtime104.jsx)(Item22, { dir: "ltr", onSelect: onMoveDown, asChild: true, children: (0, import_jsx_runtime104.jsx)(Button, { className: "tlui-menu__button", label: "page-menu.submenu.move-down" }) })
      ] }),
      listSize > 1 && (0, import_jsx_runtime104.jsx)(Group3, { children: (0, import_jsx_runtime104.jsx)(Item22, { dir: "ltr", onSelect: onDelete, asChild: true, children: (0, import_jsx_runtime104.jsx)(Button, { className: "tlui-menu__button", label: "page-menu.submenu.delete" }) }) })
    ] })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/PageMenu/PageMenu.mjs
var PageMenu = function PageMenu2() {
  const editor = useEditor();
  const msg2 = useTranslation();
  const breakpoint = useBreakpoint();
  const handleOpenChange = (0, import_react96.useCallback)(() => setIsEditing(false), []);
  const [isOpen, onOpenChange] = useMenuIsOpen("page-menu", handleOpenChange);
  const ITEM_HEIGHT = breakpoint < 5 ? 36 : 40;
  const rSortableContainer = (0, import_react96.useRef)(null);
  const pages = useValue("pages", () => editor.pages, [editor]);
  const currentPage = useValue("currentPage", () => editor.currentPage, [editor]);
  const currentPageId = useValue("currentPageId", () => editor.currentPageId, [editor]);
  const isReadonlyMode = useReadonly();
  const maxPageCountReached = useValue(
    "maxPageCountReached",
    () => editor.pages.length >= MAX_PAGES,
    [editor]
  );
  const isCoarsePointer = useValue("isCoarsePointer", () => editor.instanceState.isCoarsePointer, [
    editor
  ]);
  const [isEditing, setIsEditing] = (0, import_react96.useState)(false);
  const toggleEditing = (0, import_react96.useCallback)(() => {
    if (isReadonlyMode)
      return;
    setIsEditing((s) => !s);
  }, [isReadonlyMode]);
  const rMutables = (0, import_react96.useRef)({
    isPointing: false,
    status: "idle",
    pointing: null,
    startY: 0,
    startIndex: 0,
    dragIndex: 0
  });
  const [sortablePositionItems, setSortablePositionItems] = (0, import_react96.useState)(
    Object.fromEntries(
      pages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])
    )
  );
  (0, import_react96.useLayoutEffect)(() => {
    setSortablePositionItems(
      Object.fromEntries(
        pages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])
      )
    );
  }, [ITEM_HEIGHT, pages]);
  (0, import_react96.useEffect)(() => {
    if (!isOpen)
      return;
    requestAnimationFrame(() => {
      const elm = document.querySelector(
        `[data-testid="page-menu-item-${currentPageId}"]`
      );
      if (elm) {
        const container = rSortableContainer.current;
        if (!container)
          return;
        const elmTopPosition = elm.offsetTop;
        const containerScrollTopPosition = container.scrollTop;
        if (elmTopPosition < containerScrollTopPosition) {
          container.scrollTo({ top: elmTopPosition });
        }
        const elmBottomPosition = elmTopPosition + ITEM_HEIGHT;
        const containerScrollBottomPosition = container.scrollTop + container.offsetHeight;
        if (elmBottomPosition > containerScrollBottomPosition) {
          container.scrollTo({ top: elmBottomPosition - container.offsetHeight });
        }
      }
    });
  }, [ITEM_HEIGHT, currentPageId, isOpen]);
  const handlePointerDown = (0, import_react96.useCallback)(
    (e) => {
      const { clientY, currentTarget } = e;
      const {
        dataset: { id, index: index2 }
      } = currentTarget;
      if (!id || !index2)
        return;
      const mut = rMutables.current;
      setPointerCapture(e.currentTarget, e);
      mut.status = "pointing";
      mut.pointing = { id, index: +index2 };
      const current = sortablePositionItems[id];
      const dragY = current.y;
      mut.startY = clientY;
      mut.startIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1));
    },
    [ITEM_HEIGHT, pages.length, sortablePositionItems]
  );
  const handlePointerMove = (0, import_react96.useCallback)(
    (e) => {
      const mut = rMutables.current;
      if (mut.status === "pointing") {
        const { clientY } = e;
        const offset2 = clientY - mut.startY;
        if (Math.abs(offset2) > 5) {
          mut.status = "dragging";
        }
      }
      if (mut.status === "dragging") {
        const { clientY } = e;
        const offsetY = clientY - mut.startY;
        const current = sortablePositionItems[mut.pointing.id];
        const { startIndex, pointing } = mut;
        const dragY = current.y + offsetY;
        const dragIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1));
        const next = { ...sortablePositionItems };
        next[pointing.id] = {
          y: current.y,
          offsetY,
          isSelected: true
        };
        if (dragIndex !== mut.dragIndex) {
          mut.dragIndex = dragIndex;
          for (let i = 0; i < pages.length; i++) {
            const item = pages[i];
            if (item.id === mut.pointing.id) {
              continue;
            }
            let { y } = next[item.id];
            if (dragIndex === startIndex) {
              y = i * ITEM_HEIGHT;
            } else if (dragIndex < startIndex) {
              if (dragIndex <= i && i < startIndex) {
                y = (i + 1) * ITEM_HEIGHT;
              } else {
                y = i * ITEM_HEIGHT;
              }
            } else if (dragIndex > startIndex) {
              if (dragIndex >= i && i > startIndex) {
                y = (i - 1) * ITEM_HEIGHT;
              } else {
                y = i * ITEM_HEIGHT;
              }
            }
            if (y !== next[item.id].y) {
              next[item.id] = { y, offsetY: 0, isSelected: true };
            }
          }
        }
        setSortablePositionItems(next);
      }
    },
    [ITEM_HEIGHT, pages, sortablePositionItems]
  );
  const handlePointerUp = (0, import_react96.useCallback)(
    (e) => {
      const mut = rMutables.current;
      if (mut.status === "dragging") {
        const { id, index: index2 } = mut.pointing;
        onMovePage(editor, id, index2, mut.dragIndex);
      }
      releasePointerCapture(e.currentTarget, e);
      mut.status = "idle";
    },
    [editor]
  );
  const handleKeyDown = (0, import_react96.useCallback)(
    (e) => {
      const mut = rMutables.current;
      if (e.key === "Escape") {
        if (mut.status === "dragging") {
          setSortablePositionItems(
            Object.fromEntries(
              pages.map((page, i) => [
                page.id,
                { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }
              ])
            )
          );
        }
        mut.status = "idle";
      }
    },
    [ITEM_HEIGHT, pages]
  );
  const handleCreatePageClick = (0, import_react96.useCallback)(() => {
    if (isReadonlyMode)
      return;
    editor.batch(() => {
      editor.mark("creating page");
      const newPageId = PageRecordType.createId();
      editor.createPage({ name: msg2("page-menu.new-page-initial-name"), id: newPageId });
      editor.setCurrentPage(newPageId);
      setIsEditing(true);
    });
  }, [editor, msg2, isReadonlyMode]);
  return (0, import_jsx_runtime105.jsxs)(Popover, { id: "page menu", onOpenChange, open: isOpen, children: [
    (0, import_jsx_runtime105.jsx)(PopoverTrigger, { children: (0, import_jsx_runtime105.jsx)(
      Button,
      {
        className: "tlui-page-menu__trigger tlui-menu__trigger",
        "data-testid": "main.page-menu",
        icon: "chevron-down",
        title: currentPage.name,
        children: (0, import_jsx_runtime105.jsx)("div", { className: "tlui-page-menu__name", children: currentPage.name })
      }
    ) }),
    (0, import_jsx_runtime105.jsx)(PopoverContent, { side: "bottom", align: "start", sideOffset: 6, children: (0, import_jsx_runtime105.jsxs)("div", { className: "tlui-page-menu__wrapper", children: [
      (0, import_jsx_runtime105.jsxs)("div", { className: "tlui-page-menu__header", children: [
        (0, import_jsx_runtime105.jsx)("div", { className: "tlui-page-menu__header__title", children: msg2("page-menu.title") }),
        !isReadonlyMode && (0, import_jsx_runtime105.jsxs)(import_jsx_runtime105.Fragment, { children: [
          (0, import_jsx_runtime105.jsx)(
            Button,
            {
              "data-testid": "page-menu.edit",
              title: msg2(isEditing ? "page-menu.edit-done" : "page-menu.edit-start"),
              icon: isEditing ? "check" : "edit",
              onClick: toggleEditing
            }
          ),
          (0, import_jsx_runtime105.jsx)(
            Button,
            {
              "data-testid": "page-menu.create",
              icon: "plus",
              title: msg2(
                maxPageCountReached ? "page-menu.max-page-count-reached" : "page-menu.create-new-page"
              ),
              disabled: maxPageCountReached,
              onClick: handleCreatePageClick
            }
          )
        ] })
      ] }),
      (0, import_jsx_runtime105.jsx)(
        "div",
        {
          className: "tlui-page-menu__list tlui-menu__group",
          style: { height: ITEM_HEIGHT * pages.length + 4 },
          ref: rSortableContainer,
          children: pages.map((page, index2) => {
            const position = sortablePositionItems[page.id] ?? {
              position: index2 * 40,
              offsetY: 0
            };
            return isEditing ? (0, import_jsx_runtime105.jsxs)(
              "div",
              {
                "data-testid": `page-menu-item-${page.id}`,
                className: "tlui-page_menu__item__sortable",
                style: {
                  zIndex: page.id === currentPage.id ? 888 : index2,
                  transform: `translate(0px, ${position.y + position.offsetY}px)`
                },
                children: [
                  (0, import_jsx_runtime105.jsx)(
                    Button,
                    {
                      tabIndex: -1,
                      className: "tlui-page_menu__item__sortable__handle",
                      icon: "drag-handle-dots",
                      onPointerDown: handlePointerDown,
                      onPointerUp: handlePointerUp,
                      onPointerMove: handlePointerMove,
                      onKeyDown: handleKeyDown,
                      "data-id": page.id,
                      "data-index": index2
                    }
                  ),
                  breakpoint < 5 && isCoarsePointer ? (
                    // sigh, this is a workaround for iOS Safari
                    // because the device and the radix popover seem
                    // to be fighting over scroll position. Nothing
                    // else seems to work!
                    (0, import_jsx_runtime105.jsx)(Button, {
                      className: "tlui-page-menu__item__button",
                      onClick: () => {
                        const name = window.prompt("Rename page", page.name);
                        if (name && name !== page.name) {
                          editor.renamePage(page.id, name);
                        }
                      },
                      onDoubleClick: toggleEditing,
                      isChecked: page.id === currentPage.id,
                      children: (0, import_jsx_runtime105.jsx)("span", { children: page.name })
                    })
                  ) : (0, import_jsx_runtime105.jsx)(
                    "div",
                    {
                      className: "tlui-page_menu__item__sortable__title",
                      style: { height: ITEM_HEIGHT },
                      children: (0, import_jsx_runtime105.jsx)(
                        PageItemInput,
                        {
                          id: page.id,
                          name: page.name,
                          isCurrentPage: page.id === currentPage.id
                        }
                      )
                    }
                  ),
                  !isReadonlyMode && (0, import_jsx_runtime105.jsx)("div", { className: "tlui-page_menu__item__submenu", "data-isediting": isEditing, children: (0, import_jsx_runtime105.jsx)(PageItemSubmenu, { index: index2, item: page, listSize: pages.length }) })
                ]
              },
              page.id + "_editing"
            ) : (0, import_jsx_runtime105.jsxs)(
              "div",
              {
                "data-testid": `page-menu-item-${page.id}`,
                className: "tlui-page-menu__item",
                children: [
                  (0, import_jsx_runtime105.jsxs)(
                    Button,
                    {
                      className: "tlui-page-menu__item__button tlui-page-menu__item__button__checkbox",
                      onClick: () => editor.setCurrentPage(page.id),
                      onDoubleClick: toggleEditing,
                      isChecked: page.id === currentPage.id,
                      title: msg2("page-menu.go-to-page"),
                      children: [
                        (0, import_jsx_runtime105.jsx)("div", { className: "tlui-page-menu__item__button__check", children: page.id === currentPage.id && (0, import_jsx_runtime105.jsx)(Icon, { icon: "check" }) }),
                        (0, import_jsx_runtime105.jsx)("span", { children: page.name })
                      ]
                    }
                  ),
                  !isReadonlyMode && (0, import_jsx_runtime105.jsx)("div", { className: "tlui-page_menu__item__submenu", children: (0, import_jsx_runtime105.jsx)(
                    PageItemSubmenu,
                    {
                      index: index2,
                      item: page,
                      listSize: pages.length,
                      onRename: () => {
                        if (editor.environment.isIos) {
                          const name = window.prompt("Rename page", page.name);
                          if (name && name !== page.name) {
                            editor.renamePage(page.id, name);
                          }
                        } else {
                          editor.batch(() => {
                            setIsEditing(true);
                            editor.setCurrentPage(page.id);
                          });
                        }
                      }
                    }
                  ) })
                ]
              },
              page.id
            );
          })
        }
      )
    ] }) })
  ] });
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/RedoButton.mjs
var import_jsx_runtime106 = __toESM(require_jsx_runtime(), 1);
var import_react97 = __toESM(require_react(), 1);
var RedoButton = (0, import_react97.memo)(function RedoButton2() {
  const msg2 = useTranslation();
  const canRedo = useCanRedo();
  const actions = useActions();
  const redo = actions["redo"];
  return (0, import_jsx_runtime106.jsx)(
    Button,
    {
      "data-testid": "main.redo",
      icon: redo.icon,
      title: `${msg2(redo.label)} ${kbdStr(redo.kbd)}`,
      disabled: !canRedo,
      onClick: () => redo.onSelect("quick-actions"),
      smallIcon: true
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/TrashButton.mjs
var import_jsx_runtime107 = __toESM(require_jsx_runtime(), 1);
var TrashButton = track(function TrashButton2() {
  const editor = useEditor();
  const actions = useActions();
  const msg2 = useTranslation();
  const action = actions["delete"];
  const isReadonly = useReadonly();
  if (isReadonly)
    return null;
  return (0, import_jsx_runtime107.jsx)(
    Button,
    {
      icon: action.icon,
      onClick: () => action.onSelect("quick-actions"),
      disabled: !(editor.isIn("select") && editor.selectedShapeIds.length > 0),
      title: `${msg2(action.label)} ${kbdStr(action.kbd)}`,
      smallIcon: true
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/UndoButton.mjs
var import_jsx_runtime108 = __toESM(require_jsx_runtime(), 1);
var import_react98 = __toESM(require_react(), 1);
var UndoButton = (0, import_react98.memo)(function UndoButton2() {
  const msg2 = useTranslation();
  const canUndo = useCanUndo();
  const actions = useActions();
  const undo = actions["undo"];
  return (0, import_jsx_runtime108.jsx)(
    Button,
    {
      "data-testid": "main.undo",
      icon: undo.icon,
      title: `${msg2(undo.label)} ${kbdStr(undo.kbd)}`,
      disabled: !canUndo,
      onClick: () => undo.onSelect("quick-actions"),
      smallIcon: true
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/MenuZone.mjs
var MenuZone = track(function MenuZone2() {
  const editor = useEditor();
  const breakpoint = useBreakpoint();
  const isReadonly = useReadonly();
  return (0, import_jsx_runtime109.jsx)("div", { className: "tlui-menu-zone", children: (0, import_jsx_runtime109.jsxs)("div", { className: "tlui-menu-zone__controls", children: [
    (0, import_jsx_runtime109.jsx)(Menu, {}),
    (0, import_jsx_runtime109.jsx)("div", { className: "tlui-menu-zone__divider" }),
    (0, import_jsx_runtime109.jsx)(PageMenu, {}),
    breakpoint >= 6 && !isReadonly && !editor.isInAny("hand", "zoom") && (0, import_jsx_runtime109.jsxs)(import_jsx_runtime109.Fragment, { children: [
      (0, import_jsx_runtime109.jsx)("div", { className: "tlui-menu-zone__divider" }),
      (0, import_jsx_runtime109.jsx)(UndoButton, {}),
      (0, import_jsx_runtime109.jsx)(RedoButton, {}),
      (0, import_jsx_runtime109.jsx)(TrashButton, {}),
      (0, import_jsx_runtime109.jsx)(DuplicateButton, {}),
      (0, import_jsx_runtime109.jsx)(ActionsMenu, {})
    ] })
  ] }) });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/NavigationZone/NavigationZone.mjs
var import_jsx_runtime112 = __toESM(require_jsx_runtime(), 1);
var import_react100 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useLocalStorageState.mjs
var import_react99 = __toESM(require_react(), 1);
function useLocalStorageState(key, defaultValue) {
  const [state, setState] = import_react99.default.useState(defaultValue);
  import_react99.default.useLayoutEffect(() => {
    const value = localStorage.getItem(key);
    if (value) {
      try {
        setState(JSON.parse(value));
      } catch (e) {
        console.error(`Could not restore value ${key} from local storage.`);
      }
    }
  }, [key]);
  const updateValue = import_react99.default.useCallback(
    (setter) => {
      setState((s) => {
        const value = typeof setter === "function" ? setter(s) : setter;
        localStorage.setItem(key, JSON.stringify(value));
        return value;
      });
    },
    [key]
  );
  return [state, updateValue];
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/NavigationZone/Minimap.mjs
var import_jsx_runtime110 = __toESM(require_jsx_runtime(), 1);
var React56 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/NavigationZone/MinimapManager.mjs
var MinimapManager = class _MinimapManager {
  constructor(editor) {
    this.editor = editor;
  }
  dpr = 1;
  colors = {
    shapeFill: "rgba(144, 144, 144, .1)",
    selectFill: "#2f80ed",
    viewportFill: "rgba(144, 144, 144, .1)"
  };
  id = uniqueId();
  cvs = null;
  pageBounds = [];
  collaborators = [];
  canvasScreenBounds = new Box2d();
  canvasPageBounds = new Box2d();
  contentPageBounds = new Box2d();
  contentScreenBounds = new Box2d();
  originPagePoint = new Vec2d();
  originPageCenter = new Vec2d();
  isInViewport = false;
  debug = false;
  setDpr(dpr) {
    this.dpr = +dpr.toFixed(2);
  }
  updateContentScreenBounds = () => {
    const { contentScreenBounds, contentPageBounds: content, canvasScreenBounds: canvas } = this;
    let { x, y, w, h } = contentScreenBounds;
    if (content.w > content.h) {
      const sh = canvas.w / (content.w / content.h);
      if (sh > canvas.h) {
        x = (canvas.w - canvas.w * (canvas.h / sh)) / 2;
        y = 0;
        w = canvas.w * (canvas.h / sh);
        h = canvas.h;
      } else {
        x = 0;
        y = (canvas.h - sh) / 2;
        w = canvas.w;
        h = sh;
      }
    } else if (content.w < content.h) {
      const sw = canvas.h / (content.h / content.w);
      x = (canvas.w - sw) / 2;
      y = 0;
      w = sw;
      h = canvas.h;
    } else {
      x = canvas.h / 2;
      y = 0;
      w = canvas.h;
      h = canvas.h;
    }
    contentScreenBounds.set(x, y, w, h);
  };
  /** Get the canvas's true bounds converted to page bounds. */
  updateCanvasPageBounds = () => {
    const { canvasPageBounds, canvasScreenBounds, contentPageBounds, contentScreenBounds } = this;
    canvasPageBounds.set(
      0,
      0,
      contentPageBounds.width / (contentScreenBounds.width / canvasScreenBounds.width),
      contentPageBounds.height / (contentScreenBounds.height / canvasScreenBounds.height)
    );
    canvasPageBounds.center = contentPageBounds.center;
  };
  getScreenPoint = (x, y) => {
    const { canvasScreenBounds } = this;
    const screenX = (x - canvasScreenBounds.minX) * this.dpr;
    const screenY = (y - canvasScreenBounds.minY) * this.dpr;
    return { x: screenX, y: screenY };
  };
  getPagePoint = (x, y) => {
    const { contentPageBounds, contentScreenBounds, canvasPageBounds } = this;
    const { x: screenX, y: screenY } = this.getScreenPoint(x, y);
    return new Vec2d(
      canvasPageBounds.minX + screenX * contentPageBounds.width / contentScreenBounds.width,
      canvasPageBounds.minY + screenY * contentPageBounds.height / contentScreenBounds.height,
      1
    );
  };
  minimapScreenPointToPagePoint = (x, y, shiftKey = false, clampToBounds = false) => {
    const { editor } = this;
    const { viewportPageBounds } = editor;
    let { x: px, y: py } = this.getPagePoint(x, y);
    if (clampToBounds) {
      const shapesPageBounds = this.editor.currentPageBounds;
      const vpPageBounds = viewportPageBounds;
      const minX = (shapesPageBounds?.minX ?? 0) - vpPageBounds.width / 2;
      const maxX = (shapesPageBounds?.maxX ?? 0) + vpPageBounds.width / 2;
      const minY = (shapesPageBounds?.minY ?? 0) - vpPageBounds.height / 2;
      const maxY = (shapesPageBounds?.maxY ?? 0) + vpPageBounds.height / 2;
      const lx = Math.max(0, minX + vpPageBounds.width - px);
      const rx = Math.max(0, -(maxX - vpPageBounds.width - px));
      const ly = Math.max(0, minY + vpPageBounds.height - py);
      const ry = Math.max(0, -(maxY - vpPageBounds.height - py));
      const ql = Math.max(0, lx - rx);
      const qr = Math.max(0, rx - lx);
      const qt = Math.max(0, ly - ry);
      const qb = Math.max(0, ry - ly);
      if (ql && ql > qr) {
        px += ql / 2;
      } else if (qr) {
        px -= qr / 2;
      }
      if (qt && qt > qb) {
        py += qt / 2;
      } else if (qb) {
        py -= qb / 2;
      }
      px = clamp(px, minX, maxX);
      py = clamp(py, minY, maxY);
    }
    if (shiftKey) {
      const { originPagePoint } = this;
      const dx = Math.abs(px - originPagePoint.x);
      const dy = Math.abs(py - originPagePoint.y);
      if (dx > dy) {
        py = originPagePoint.y;
      } else {
        px = originPagePoint.x;
      }
    }
    return new Vec2d(px, py);
  };
  render = () => {
    const { cvs, pageBounds } = this;
    this.updateCanvasPageBounds();
    const { editor, canvasScreenBounds, canvasPageBounds, contentPageBounds, contentScreenBounds } = this;
    const { width: cw, height: ch } = canvasScreenBounds;
    const { viewportPageBounds, selectedShapeIds } = editor;
    if (!cvs || !pageBounds) {
      return;
    }
    const ctx = cvs.getContext("2d");
    if (!ctx) {
      throw new Error("Minimap (shapes): Could not get context");
    }
    ctx.resetTransform();
    ctx.globalAlpha = 1;
    ctx.clearRect(0, 0, cw, ch);
    const sx = contentScreenBounds.width / contentPageBounds.width;
    const sy = contentScreenBounds.height / contentPageBounds.height;
    ctx.translate((cw - contentScreenBounds.width) / 2, (ch - contentScreenBounds.height) / 2);
    ctx.scale(sx, sy);
    ctx.translate(-contentPageBounds.minX, -contentPageBounds.minY);
    const rx = 8 / sx;
    const ry = 8 / sx;
    const ax = 1 / sx;
    const ay = 1 / sx;
    const bx = rx / 4;
    const by = ry / 4;
    const shapesPath = new Path2D();
    const selectedPath = new Path2D();
    const { shapeFill, selectFill, viewportFill } = this.colors;
    let pb;
    for (let i = 0, n = pageBounds.length; i < n; i++) {
      pb = pageBounds[i];
      _MinimapManager.roundedRect(
        selectedShapeIds.includes(pb.id) ? selectedPath : shapesPath,
        pb.minX,
        pb.minY,
        pb.width,
        pb.height,
        clamp(rx, ax, pb.width / bx),
        clamp(ry, ay, pb.height / by)
      );
    }
    ctx.fillStyle = shapeFill;
    ctx.fill(shapesPath);
    ctx.fillStyle = selectFill;
    ctx.fill(selectedPath);
    if (this.debug) {
      const commonBounds = Box2d.Common(pageBounds);
      const { minX, minY, width, height } = commonBounds;
      ctx.strokeStyle = "green";
      ctx.lineWidth = 2 / sx;
      ctx.strokeRect(minX + 1 / sx, minY + 1 / sy, width - 2 / sx, height - 2 / sy);
    }
    {
      const { brush } = editor.instanceState;
      if (brush) {
        const { x, y, w, h } = brush;
        ctx.beginPath();
        _MinimapManager.sharpRect(ctx, x, y, w, h);
        ctx.closePath();
        ctx.fillStyle = viewportFill;
        ctx.fill();
      }
    }
    {
      const { minX, minY, width, height } = viewportPageBounds;
      ctx.beginPath();
      const rx2 = 12 / sx;
      const ry2 = 12 / sx;
      _MinimapManager.roundedRect(
        ctx,
        minX,
        minY,
        width,
        height,
        Math.min(width / 4, rx2),
        Math.min(height / 4, ry2)
      );
      ctx.closePath();
      ctx.fillStyle = viewportFill;
      ctx.fill();
      if (this.debug) {
        ctx.strokeStyle = "orange";
        ctx.strokeRect(minX + 1 / sx, minY + 1 / sy, width - 2 / sx, height - 2 / sy);
      }
    }
    const px = 2.5 / sx;
    const py = 2.5 / sy;
    const { currentPageId } = editor;
    let collaborator;
    for (let i = 0; i < this.collaborators.length; i++) {
      collaborator = this.collaborators[i];
      if (collaborator.currentPageId !== currentPageId) {
        continue;
      }
      ctx.beginPath();
      ctx.ellipse(
        clamp(collaborator.cursor.x, canvasPageBounds.minX + px, canvasPageBounds.maxX - px),
        clamp(collaborator.cursor.y, canvasPageBounds.minY + py, canvasPageBounds.maxY - py),
        5 / sx,
        5 / sy,
        0,
        0,
        PI2
      );
      ctx.fillStyle = collaborator.color;
      ctx.fill();
    }
    if (this.debug) {
      ctx.lineWidth = 2 / sx;
      {
        const { minX, minY, width, height } = contentPageBounds;
        ctx.strokeStyle = "red";
        ctx.strokeRect(minX + 1 / sx, minY + 1 / sy, width - 2 / sx, height - 2 / sy);
      }
      {
        const { minX, minY, width, height } = canvasPageBounds;
        ctx.strokeStyle = "blue";
        ctx.strokeRect(minX + 1 / sx, minY + 1 / sy, width - 2 / sx, height - 2 / sy);
      }
    }
  };
  static roundedRect(ctx, x, y, width, height, rx, ry) {
    if (rx < 1 && ry < 1) {
      ctx.rect(x, y, width, height);
      return;
    }
    ctx.moveTo(x + rx, y);
    ctx.lineTo(x + width - rx, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + ry);
    ctx.lineTo(x + width, y + height - ry);
    ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height);
    ctx.lineTo(x + rx, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - ry);
    ctx.lineTo(x, y + ry);
    ctx.quadraticCurveTo(x, y, x + rx, y);
  }
  static sharpRect(ctx, x, y, width, height, _rx, _ry) {
    ctx.rect(x, y, width, height);
  }
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/NavigationZone/Minimap.mjs
function Minimap({ shapeFill, selectFill, viewportFill }) {
  const editor = useEditor();
  const rCanvas = React56.useRef(null);
  const rPointing = React56.useRef(false);
  const isDarkMode = useIsDarkMode();
  const devicePixelRatio = useComputed("dpr", () => editor.instanceState.devicePixelRatio, [editor]);
  const presences = React56.useMemo(() => editor.store.query.records("instance_presence"), [editor]);
  const minimap = React56.useMemo(() => new MinimapManager(editor), [editor]);
  React56.useEffect(() => {
    const raf2 = requestAnimationFrame(() => {
      const style = getComputedStyle(editor.getContainer());
      minimap.colors = {
        shapeFill: style.getPropertyValue(shapeFill).trim(),
        selectFill: style.getPropertyValue(selectFill).trim(),
        viewportFill: style.getPropertyValue(viewportFill).trim()
      };
      minimap.render();
    });
    return () => {
      cancelAnimationFrame(raf2);
    };
  }, [editor, selectFill, shapeFill, viewportFill, minimap, isDarkMode]);
  const onDoubleClick = React56.useCallback(
    (e) => {
      if (!editor.currentPageShapeIds.size)
        return;
      const point = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, false, false);
      const clampedPoint = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, false, true);
      minimap.originPagePoint.setTo(clampedPoint);
      minimap.originPageCenter.setTo(editor.viewportPageBounds.center);
      editor.centerOnPoint(point, { duration: ANIMATION_MEDIUM_MS });
    },
    [editor, minimap]
  );
  const onPointerDown = React56.useCallback(
    (e) => {
      const elm = e.currentTarget;
      setPointerCapture(elm, e);
      if (!editor.currentPageShapeIds.size)
        return;
      rPointing.current = true;
      minimap.isInViewport = false;
      const point = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, false, false);
      const clampedPoint = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, false, true);
      const _vpPageBounds = editor.viewportPageBounds;
      minimap.isInViewport = _vpPageBounds.containsPoint(clampedPoint);
      if (minimap.isInViewport) {
        minimap.originPagePoint.setTo(clampedPoint);
        minimap.originPageCenter.setTo(_vpPageBounds.center);
      } else {
        const delta = Vec2d.Sub(_vpPageBounds.center, _vpPageBounds.point);
        const pagePoint = Vec2d.Add(point, delta);
        minimap.originPagePoint.setTo(pagePoint);
        minimap.originPageCenter.setTo(point);
        editor.centerOnPoint(point, { duration: ANIMATION_MEDIUM_MS });
      }
      function release(e2) {
        if (elm) {
          releasePointerCapture(elm, e2);
        }
        rPointing.current = false;
        document.body.removeEventListener("pointerup", release);
      }
      document.body.addEventListener("pointerup", release);
    },
    [editor, minimap]
  );
  const onPointerMove = React56.useCallback(
    (e) => {
      const point = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, e.shiftKey, true);
      if (rPointing.current) {
        if (minimap.isInViewport) {
          const delta = minimap.originPagePoint.clone().sub(minimap.originPageCenter);
          editor.centerOnPoint(Vec2d.Sub(point, delta));
          return;
        }
        editor.centerOnPoint(point);
      }
      const pagePoint = minimap.getPagePoint(e.clientX, e.clientY);
      const screenPoint = editor.pageToScreen(pagePoint);
      const info = {
        type: "pointer",
        target: "canvas",
        name: "pointer_move",
        ...getPointerInfo(e),
        point: screenPoint,
        isPen: editor.instanceState.isPenMode
      };
      editor.dispatch(info);
    },
    [editor, minimap]
  );
  const onWheel = React56.useCallback(
    (e) => {
      const offset2 = normalizeWheel(e);
      editor.dispatch({
        type: "wheel",
        name: "wheel",
        delta: offset2,
        shiftKey: e.shiftKey,
        altKey: e.altKey,
        ctrlKey: e.metaKey || e.ctrlKey
      });
    },
    [editor]
  );
  useQuickReactor(
    "update when dpr changes",
    () => {
      const dpr = devicePixelRatio.value;
      minimap.setDpr(dpr);
      const canvas = rCanvas.current;
      const rect = canvas.getBoundingClientRect();
      const width = rect.width * dpr;
      const height = rect.height * dpr;
      canvas.width = width;
      canvas.height = height;
      minimap.canvasScreenBounds.set(rect.x, rect.y, width, height);
      minimap.cvs = rCanvas.current;
    },
    [devicePixelRatio, minimap]
  );
  useQuickReactor(
    "minimap render when pagebounds or collaborators changes",
    () => {
      const {
        currentPageShapeIds: shapeIdsOnCurrentPage,
        viewportPageBounds,
        currentPageBounds: commonBoundsOfAllShapesOnCurrentPage
      } = editor;
      const _dpr = devicePixelRatio.value;
      minimap.contentPageBounds = commonBoundsOfAllShapesOnCurrentPage ? Box2d.Expand(commonBoundsOfAllShapesOnCurrentPage, viewportPageBounds) : viewportPageBounds;
      minimap.updateContentScreenBounds();
      const allShapeBounds = [];
      shapeIdsOnCurrentPage.forEach((id) => {
        let pageBounds = editor.getShapePageBounds(id);
        if (!pageBounds)
          return;
        const pageMask = editor.getShapeMask(id);
        if (pageMask) {
          const intersection = intersectPolygonPolygon(pageMask, pageBounds.corners);
          if (!intersection) {
            return;
          }
          pageBounds = Box2d.FromPoints(intersection);
        }
        if (pageBounds) {
          pageBounds.id = id;
          allShapeBounds.push(pageBounds);
        }
      });
      minimap.pageBounds = allShapeBounds;
      minimap.collaborators = presences.value;
      minimap.render();
    },
    [editor, minimap]
  );
  return (0, import_jsx_runtime110.jsx)("div", { className: "tlui-minimap", children: (0, import_jsx_runtime110.jsx)(
    "canvas",
    {
      ref: rCanvas,
      className: "tlui-minimap__canvas",
      onDoubleClick,
      onPointerMove,
      onPointerDown,
      onWheel
    }
  ) });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/NavigationZone/ZoomMenu.mjs
var import_jsx_runtime111 = __toESM(require_jsx_runtime(), 1);
var React57 = __toESM(require_react(), 1);
var ZoomMenu = track(function ZoomMenu2() {
  const editor = useEditor();
  const msg2 = useTranslation();
  const breakpoint = useBreakpoint();
  const zoom = editor.zoomLevel;
  const hasShapes = editor.currentPageShapeIds.size > 0;
  const hasSelected = editor.selectedShapeIds.length > 0;
  const isZoomedTo100 = editor.zoomLevel === 1;
  const handleDoubleClick = React57.useCallback(() => {
    editor.resetZoom(editor.viewportScreenCenter, { duration: ANIMATION_MEDIUM_MS });
  }, [editor]);
  return (0, import_jsx_runtime111.jsxs)(Root4, { id: "zoom", children: [
    (0, import_jsx_runtime111.jsx)(Trigger2, { children: (0, import_jsx_runtime111.jsx)(
      Button,
      {
        title: `${msg2("navigation-zone.zoom")}`,
        "data-testid": "minimap.zoom-menu",
        className: breakpoint < 5 ? "tlui-zoom-menu__button" : "tlui-zoom-menu__button__pct",
        onDoubleClick: handleDoubleClick,
        icon: breakpoint < 4 ? "zoom-in" : void 0,
        children: breakpoint < 4 ? null : (0, import_jsx_runtime111.jsxs)("span", { style: { flexGrow: 0, textAlign: "center" }, children: [
          Math.floor(zoom * 100),
          "%"
        ] })
      }
    ) }),
    (0, import_jsx_runtime111.jsx)(Content3, { side: "top", align: "start", alignOffset: 0, children: (0, import_jsx_runtime111.jsxs)(Group3, { children: [
      (0, import_jsx_runtime111.jsx)(ZoomMenuItem, { action: "zoom-in", "data-testid": "minimap.zoom-menu.zoom-in", noClose: true }),
      (0, import_jsx_runtime111.jsx)(ZoomMenuItem, { action: "zoom-out", "data-testid": "minimap.zoom-menu.zoom-out", noClose: true }),
      (0, import_jsx_runtime111.jsx)(
        ZoomMenuItem,
        {
          action: "zoom-to-100",
          "data-testid": "minimap.zoom-menu.zoom-to-100",
          noClose: true,
          disabled: isZoomedTo100
        }
      ),
      (0, import_jsx_runtime111.jsx)(
        ZoomMenuItem,
        {
          action: "zoom-to-fit",
          disabled: !hasShapes,
          "data-testid": "minimap.zoom-menu.zoom-to-fit",
          noClose: true
        }
      ),
      (0, import_jsx_runtime111.jsx)(
        ZoomMenuItem,
        {
          action: "zoom-to-selection",
          disabled: !hasSelected,
          "data-testid": "minimap.zoom-menu.zoom-to-selection",
          noClose: true
        }
      )
    ] }) })
  ] });
});
function ZoomMenuItem(props) {
  const { action, disabled = false, noClose = false } = props;
  const actions = useActions();
  return (0, import_jsx_runtime111.jsx)(
    Item,
    {
      label: actions[action].label,
      kbd: actions[action].kbd,
      "data-testid": props["data-testid"],
      onClick: () => actions[action].onSelect("zoom-menu"),
      noClose,
      disabled
    }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/NavigationZone/NavigationZone.mjs
var NavigationZone = (0, import_react100.memo)(function NavigationZone2() {
  const actions = useActions();
  const msg2 = useTranslation();
  const breakpoint = useBreakpoint();
  const [collapsed, setCollapsed] = useLocalStorageState("minimap", true);
  const toggleMinimap = (0, import_react100.useCallback)(() => {
    setCollapsed((s) => !s);
  }, [setCollapsed]);
  if (breakpoint < 4) {
    return null;
  }
  return (0, import_jsx_runtime112.jsxs)("div", { className: "tlui-navigation-zone", children: [
    (0, import_jsx_runtime112.jsx)("div", { className: "tlui-navigation-zone__controls", children: breakpoint < 6 ? (0, import_jsx_runtime112.jsx)(ZoomMenu, {}) : collapsed ? (0, import_jsx_runtime112.jsxs)(import_jsx_runtime112.Fragment, { children: [
      (0, import_jsx_runtime112.jsx)(ZoomMenu, {}),
      (0, import_jsx_runtime112.jsx)(
        Button,
        {
          title: msg2("navigation-zone.toggle-minimap"),
          className: "tlui-navigation-zone__toggle",
          "data-testid": "minimap.toggle",
          onClick: toggleMinimap,
          icon: collapsed ? "chevrons-ne" : "chevrons-sw"
        }
      )
    ] }) : (0, import_jsx_runtime112.jsxs)(import_jsx_runtime112.Fragment, { children: [
      (0, import_jsx_runtime112.jsx)(
        Button,
        {
          icon: "minus",
          "data-testid": "minimap.zoom-out",
          title: `${msg2(actions["zoom-out"].label)} ${kbdStr(actions["zoom-out"].kbd)}`,
          onClick: () => actions["zoom-out"].onSelect("navigation-zone")
        }
      ),
      (0, import_jsx_runtime112.jsx)(ZoomMenu, {}),
      (0, import_jsx_runtime112.jsx)(
        Button,
        {
          icon: "plus",
          "data-testid": "minimap.zoom-in",
          title: `${msg2(actions["zoom-in"].label)} ${kbdStr(actions["zoom-in"].kbd)}`,
          onClick: () => actions["zoom-in"].onSelect("navigation-zone")
        }
      ),
      (0, import_jsx_runtime112.jsx)(
        Button,
        {
          title: msg2("navigation-zone.toggle-minimap"),
          className: "tlui-navigation-zone__toggle",
          onClick: toggleMinimap,
          icon: collapsed ? "chevrons-ne" : "chevrons-sw"
        }
      )
    ] }) }),
    breakpoint >= 6 && !collapsed && (0, import_jsx_runtime112.jsx)(
      Minimap,
      {
        viewportFill: "--color-muted-1",
        selectFill: "--color-selected",
        shapeFill: "--color-text-3"
      }
    )
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/PenModeToggle.mjs
var import_jsx_runtime113 = __toESM(require_jsx_runtime(), 1);
var ExitPenMode = track(function ExitPenMode2() {
  const editor = useEditor();
  const isPenMode = editor.instanceState.isPenMode;
  const actions = useActions();
  if (!isPenMode)
    return null;
  const action = actions["exit-pen-mode"];
  return (0, import_jsx_runtime113.jsx)(
    Button,
    {
      label: action.label,
      iconLeft: action.icon,
      onClick: () => action.onSelect("helper-buttons")
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/StopFollowing.mjs
var import_jsx_runtime114 = __toESM(require_jsx_runtime(), 1);
var StopFollowing = track(function ExitPenMode3() {
  const editor = useEditor();
  const actions = useActions();
  if (!editor.instanceState.followingUserId) {
    return null;
  }
  const action = actions["stop-following"];
  return (0, import_jsx_runtime114.jsx)(
    Button,
    {
      label: action.label,
      iconLeft: action.icon,
      onClick: () => action.onSelect("people-menu")
    }
  );
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/StylePanel/StylePanel.mjs
var import_jsx_runtime120 = __toESM(require_jsx_runtime(), 1);
var import_react103 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useRevelantStyles.mjs
var selectToolStyles = [DefaultColorStyle, DefaultDashStyle, DefaultFillStyle, DefaultSizeStyle];
function useRelevantStyles() {
  const editor = useEditor();
  return useValue(
    "getRelevantStyles",
    () => {
      const styles = new SharedStyleMap(editor.sharedStyles);
      const hasShape = editor.selectedShapeIds.length > 0 || !!editor.root.current.value?.shapeType;
      if (styles.size === 0 && editor.isIn("select") && editor.selectedShapeIds.length === 0) {
        for (const style of selectToolStyles) {
          styles.applyValue(style, editor.getStyleForNextShape(style));
        }
      }
      if (styles.size === 0 && !hasShape)
        return null;
      return { styles, opacity: editor.sharedOpacity };
    },
    [editor]
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/ButtonPicker.mjs
var import_jsx_runtime115 = __toESM(require_jsx_runtime(), 1);
var import_classnames20 = __toESM(require_classnames(), 1);
var React58 = __toESM(require_react(), 1);
var import_react101 = __toESM(require_react(), 1);
function _ButtonPicker(props) {
  const {
    uiType,
    items,
    title,
    style,
    value,
    columns = clamp(items.length, 2, 4),
    onValueChange
  } = props;
  const editor = useEditor();
  const msg2 = useTranslation();
  const rPointing = (0, import_react101.useRef)(false);
  const {
    handleButtonClick,
    handleButtonPointerDown,
    handleButtonPointerEnter,
    handleButtonPointerUp
  } = React58.useMemo(() => {
    const handlePointerUp = () => {
      rPointing.current = false;
      window.removeEventListener("pointerup", handlePointerUp);
    };
    const handleButtonClick2 = (e) => {
      const { id } = e.currentTarget.dataset;
      if (value.type === "shared" && value.value === id)
        return;
      editor.mark("point picker item");
      onValueChange(style, id, false);
    };
    const handleButtonPointerDown2 = (e) => {
      const { id } = e.currentTarget.dataset;
      editor.mark("point picker item");
      onValueChange(style, id, true);
      rPointing.current = true;
      window.addEventListener("pointerup", handlePointerUp);
    };
    const handleButtonPointerEnter2 = (e) => {
      if (!rPointing.current)
        return;
      const { id } = e.currentTarget.dataset;
      onValueChange(style, id, true);
    };
    const handleButtonPointerUp2 = (e) => {
      const { id } = e.currentTarget.dataset;
      onValueChange(style, id, false);
    };
    return {
      handleButtonClick: handleButtonClick2,
      handleButtonPointerDown: handleButtonPointerDown2,
      handleButtonPointerEnter: handleButtonPointerEnter2,
      handleButtonPointerUp: handleButtonPointerUp2
    };
  }, [value, editor, onValueChange, style]);
  const theme = useValue(
    "theme",
    () => getDefaultColorTheme({ isDarkMode: editor.user.isDarkMode }),
    [editor]
  );
  return (0, import_jsx_runtime115.jsx)(
    "div",
    {
      className: (0, import_classnames20.default)("tlui-button-grid", {
        "tlui-button-grid__two": columns === 2,
        "tlui-button-grid__three": columns === 3,
        "tlui-button-grid__four": columns === 4
      }),
      children: items.map((item) => (0, import_jsx_runtime115.jsx)(
        Button,
        {
          "data-id": item.value,
          "data-testid": `style.${uiType}.${item.value}`,
          "aria-label": item.value,
          "data-state": value.type === "shared" && value.value === item.value ? "hinted" : void 0,
          title: title + " — " + msg2(`${uiType}-style.${item.value}`),
          className: (0, import_classnames20.default)("tlui-button-grid__button"),
          style: style === DefaultColorStyle ? { color: theme[item.value].solid } : void 0,
          onPointerEnter: handleButtonPointerEnter,
          onPointerDown: handleButtonPointerDown,
          onPointerUp: handleButtonPointerUp,
          onClick: handleButtonClick,
          icon: item.icon
        },
        item.value
      ))
    }
  );
}
var ButtonPicker = React58.memo(_ButtonPicker);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Slider.mjs
var import_jsx_runtime117 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@radix-ui+react-slider@1.3.6/node_modules/@radix-ui/react-slider/dist/index.mjs
var React60 = __toESM(require_react(), 1);

// node_modules/.deno/@radix-ui+number@1.1.1/node_modules/@radix-ui/number/dist/index.mjs
function clamp3(value, [min4, max3]) {
  return Math.min(max3, Math.max(min4, value));
}

// node_modules/.deno/@radix-ui+react-use-previous@1.1.1/node_modules/@radix-ui/react-use-previous/dist/index.mjs
var React59 = __toESM(require_react(), 1);
function usePrevious(value) {
  const ref = React59.useRef({ value, previous: value });
  return React59.useMemo(() => {
    if (ref.current.value !== value) {
      ref.current.previous = ref.current.value;
      ref.current.value = value;
    }
    return ref.current.previous;
  }, [value]);
}

// node_modules/.deno/@radix-ui+react-slider@1.3.6/node_modules/@radix-ui/react-slider/dist/index.mjs
var import_jsx_runtime116 = __toESM(require_jsx_runtime(), 1);
var PAGE_KEYS = ["PageUp", "PageDown"];
var ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
var BACK_KEYS = {
  "from-left": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
  "from-right": ["Home", "PageDown", "ArrowDown", "ArrowRight"],
  "from-bottom": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
  "from-top": ["Home", "PageDown", "ArrowUp", "ArrowLeft"]
};
var SLIDER_NAME = "Slider";
var [Collection2, useCollection2, createCollectionScope2] = createCollection(SLIDER_NAME);
var [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [
  createCollectionScope2
]);
var [SliderProvider, useSliderContext] = createSliderContext(SLIDER_NAME);
var Slider = React60.forwardRef(
  (props, forwardedRef) => {
    const {
      name,
      min: min4 = 0,
      max: max3 = 100,
      step = 1,
      orientation = "horizontal",
      disabled = false,
      minStepsBetweenThumbs = 0,
      defaultValue = [min4],
      value,
      onValueChange = () => {
      },
      onValueCommit = () => {
      },
      inverted = false,
      form,
      ...sliderProps
    } = props;
    const thumbRefs = React60.useRef(/* @__PURE__ */ new Set());
    const valueIndexToChangeRef = React60.useRef(0);
    const isHorizontal = orientation === "horizontal";
    const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;
    const [values = [], setValues] = useControllableState({
      prop: value,
      defaultProp: defaultValue,
      onChange: (value2) => {
        const thumbs = [...thumbRefs.current];
        thumbs[valueIndexToChangeRef.current]?.focus();
        onValueChange(value2);
      }
    });
    const valuesBeforeSlideStartRef = React60.useRef(values);
    function handleSlideStart(value2) {
      const closestIndex = getClosestValueIndex(values, value2);
      updateValues(value2, closestIndex);
    }
    function handleSlideMove(value2) {
      updateValues(value2, valueIndexToChangeRef.current);
    }
    function handleSlideEnd() {
      const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];
      const nextValue = values[valueIndexToChangeRef.current];
      const hasChanged = nextValue !== prevValue;
      if (hasChanged)
        onValueCommit(values);
    }
    function updateValues(value2, atIndex, { commit } = { commit: false }) {
      const decimalCount = getDecimalCount(step);
      const snapToStep = roundValue(Math.round((value2 - min4) / step) * step + min4, decimalCount);
      const nextValue = clamp3(snapToStep, [min4, max3]);
      setValues((prevValues = []) => {
        const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);
        if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {
          valueIndexToChangeRef.current = nextValues.indexOf(nextValue);
          const hasChanged = String(nextValues) !== String(prevValues);
          if (hasChanged && commit)
            onValueCommit(nextValues);
          return hasChanged ? nextValues : prevValues;
        } else {
          return prevValues;
        }
      });
    }
    return (0, import_jsx_runtime116.jsx)(
      SliderProvider,
      {
        scope: props.__scopeSlider,
        name,
        disabled,
        min: min4,
        max: max3,
        valueIndexToChangeRef,
        thumbs: thumbRefs.current,
        values,
        orientation,
        form,
        children: (0, import_jsx_runtime116.jsx)(Collection2.Provider, { scope: props.__scopeSlider, children: (0, import_jsx_runtime116.jsx)(Collection2.Slot, { scope: props.__scopeSlider, children: (0, import_jsx_runtime116.jsx)(
          SliderOrientation,
          {
            "aria-disabled": disabled,
            "data-disabled": disabled ? "" : void 0,
            ...sliderProps,
            ref: forwardedRef,
            onPointerDown: composeEventHandlers(sliderProps.onPointerDown, () => {
              if (!disabled)
                valuesBeforeSlideStartRef.current = values;
            }),
            min: min4,
            max: max3,
            inverted,
            onSlideStart: disabled ? void 0 : handleSlideStart,
            onSlideMove: disabled ? void 0 : handleSlideMove,
            onSlideEnd: disabled ? void 0 : handleSlideEnd,
            onHomeKeyDown: () => !disabled && updateValues(min4, 0, { commit: true }),
            onEndKeyDown: () => !disabled && updateValues(max3, values.length - 1, { commit: true }),
            onStepKeyDown: ({ event, direction: stepDirection }) => {
              if (!disabled) {
                const isPageKey = PAGE_KEYS.includes(event.key);
                const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS.includes(event.key);
                const multiplier = isSkipKey ? 10 : 1;
                const atIndex = valueIndexToChangeRef.current;
                const value2 = values[atIndex];
                const stepInDirection = step * multiplier * stepDirection;
                updateValues(value2 + stepInDirection, atIndex, { commit: true });
              }
            }
          }
        ) }) })
      }
    );
  }
);
Slider.displayName = SLIDER_NAME;
var [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext(SLIDER_NAME, {
  startEdge: "left",
  endEdge: "right",
  size: "width",
  direction: 1
});
var SliderHorizontal = React60.forwardRef(
  (props, forwardedRef) => {
    const {
      min: min4,
      max: max3,
      dir,
      inverted,
      onSlideStart,
      onSlideMove,
      onSlideEnd,
      onStepKeyDown,
      ...sliderProps
    } = props;
    const [slider, setSlider] = React60.useState(null);
    const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));
    const rectRef = React60.useRef(void 0);
    const direction = useDirection(dir);
    const isDirectionLTR = direction === "ltr";
    const isSlidingFromLeft = isDirectionLTR && !inverted || !isDirectionLTR && inverted;
    function getValueFromPointer(pointerPosition) {
      const rect = rectRef.current || slider.getBoundingClientRect();
      const input = [0, rect.width];
      const output = isSlidingFromLeft ? [min4, max3] : [max3, min4];
      const value = linearScale(input, output);
      rectRef.current = rect;
      return value(pointerPosition - rect.left);
    }
    return (0, import_jsx_runtime116.jsx)(
      SliderOrientationProvider,
      {
        scope: props.__scopeSlider,
        startEdge: isSlidingFromLeft ? "left" : "right",
        endEdge: isSlidingFromLeft ? "right" : "left",
        direction: isSlidingFromLeft ? 1 : -1,
        size: "width",
        children: (0, import_jsx_runtime116.jsx)(
          SliderImpl,
          {
            dir: direction,
            "data-orientation": "horizontal",
            ...sliderProps,
            ref: composedRefs,
            style: {
              ...sliderProps.style,
              ["--radix-slider-thumb-transform"]: "translateX(-50%)"
            },
            onSlideStart: (event) => {
              const value = getValueFromPointer(event.clientX);
              onSlideStart?.(value);
            },
            onSlideMove: (event) => {
              const value = getValueFromPointer(event.clientX);
              onSlideMove?.(value);
            },
            onSlideEnd: () => {
              rectRef.current = void 0;
              onSlideEnd?.();
            },
            onStepKeyDown: (event) => {
              const slideDirection = isSlidingFromLeft ? "from-left" : "from-right";
              const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
              onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });
            }
          }
        )
      }
    );
  }
);
var SliderVertical = React60.forwardRef(
  (props, forwardedRef) => {
    const {
      min: min4,
      max: max3,
      inverted,
      onSlideStart,
      onSlideMove,
      onSlideEnd,
      onStepKeyDown,
      ...sliderProps
    } = props;
    const sliderRef = React60.useRef(null);
    const ref = useComposedRefs(forwardedRef, sliderRef);
    const rectRef = React60.useRef(void 0);
    const isSlidingFromBottom = !inverted;
    function getValueFromPointer(pointerPosition) {
      const rect = rectRef.current || sliderRef.current.getBoundingClientRect();
      const input = [0, rect.height];
      const output = isSlidingFromBottom ? [max3, min4] : [min4, max3];
      const value = linearScale(input, output);
      rectRef.current = rect;
      return value(pointerPosition - rect.top);
    }
    return (0, import_jsx_runtime116.jsx)(
      SliderOrientationProvider,
      {
        scope: props.__scopeSlider,
        startEdge: isSlidingFromBottom ? "bottom" : "top",
        endEdge: isSlidingFromBottom ? "top" : "bottom",
        size: "height",
        direction: isSlidingFromBottom ? 1 : -1,
        children: (0, import_jsx_runtime116.jsx)(
          SliderImpl,
          {
            "data-orientation": "vertical",
            ...sliderProps,
            ref,
            style: {
              ...sliderProps.style,
              ["--radix-slider-thumb-transform"]: "translateY(50%)"
            },
            onSlideStart: (event) => {
              const value = getValueFromPointer(event.clientY);
              onSlideStart?.(value);
            },
            onSlideMove: (event) => {
              const value = getValueFromPointer(event.clientY);
              onSlideMove?.(value);
            },
            onSlideEnd: () => {
              rectRef.current = void 0;
              onSlideEnd?.();
            },
            onStepKeyDown: (event) => {
              const slideDirection = isSlidingFromBottom ? "from-bottom" : "from-top";
              const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
              onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });
            }
          }
        )
      }
    );
  }
);
var SliderImpl = React60.forwardRef(
  (props, forwardedRef) => {
    const {
      __scopeSlider,
      onSlideStart,
      onSlideMove,
      onSlideEnd,
      onHomeKeyDown,
      onEndKeyDown,
      onStepKeyDown,
      ...sliderProps
    } = props;
    const context = useSliderContext(SLIDER_NAME, __scopeSlider);
    return (0, import_jsx_runtime116.jsx)(
      Primitive.span,
      {
        ...sliderProps,
        ref: forwardedRef,
        onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
          if (event.key === "Home") {
            onHomeKeyDown(event);
            event.preventDefault();
          } else if (event.key === "End") {
            onEndKeyDown(event);
            event.preventDefault();
          } else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) {
            onStepKeyDown(event);
            event.preventDefault();
          }
        }),
        onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
          const target = event.target;
          target.setPointerCapture(event.pointerId);
          event.preventDefault();
          if (context.thumbs.has(target)) {
            target.focus();
          } else {
            onSlideStart(event);
          }
        }),
        onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
          const target = event.target;
          if (target.hasPointerCapture(event.pointerId))
            onSlideMove(event);
        }),
        onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
          const target = event.target;
          if (target.hasPointerCapture(event.pointerId)) {
            target.releasePointerCapture(event.pointerId);
            onSlideEnd(event);
          }
        })
      }
    );
  }
);
var TRACK_NAME = "SliderTrack";
var SliderTrack = React60.forwardRef(
  (props, forwardedRef) => {
    const { __scopeSlider, ...trackProps } = props;
    const context = useSliderContext(TRACK_NAME, __scopeSlider);
    return (0, import_jsx_runtime116.jsx)(
      Primitive.span,
      {
        "data-disabled": context.disabled ? "" : void 0,
        "data-orientation": context.orientation,
        ...trackProps,
        ref: forwardedRef
      }
    );
  }
);
SliderTrack.displayName = TRACK_NAME;
var RANGE_NAME = "SliderRange";
var SliderRange = React60.forwardRef(
  (props, forwardedRef) => {
    const { __scopeSlider, ...rangeProps } = props;
    const context = useSliderContext(RANGE_NAME, __scopeSlider);
    const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);
    const ref = React60.useRef(null);
    const composedRefs = useComposedRefs(forwardedRef, ref);
    const valuesCount = context.values.length;
    const percentages = context.values.map(
      (value) => convertValueToPercentage(value, context.min, context.max)
    );
    const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;
    const offsetEnd = 100 - Math.max(...percentages);
    return (0, import_jsx_runtime116.jsx)(
      Primitive.span,
      {
        "data-orientation": context.orientation,
        "data-disabled": context.disabled ? "" : void 0,
        ...rangeProps,
        ref: composedRefs,
        style: {
          ...props.style,
          [orientation.startEdge]: offsetStart + "%",
          [orientation.endEdge]: offsetEnd + "%"
        }
      }
    );
  }
);
SliderRange.displayName = RANGE_NAME;
var THUMB_NAME = "SliderThumb";
var SliderThumb = React60.forwardRef(
  (props, forwardedRef) => {
    const getItems = useCollection2(props.__scopeSlider);
    const [thumb, setThumb] = React60.useState(null);
    const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
    const index2 = React60.useMemo(
      () => thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1,
      [getItems, thumb]
    );
    return (0, import_jsx_runtime116.jsx)(SliderThumbImpl, { ...props, ref: composedRefs, index: index2 });
  }
);
var SliderThumbImpl = React60.forwardRef(
  (props, forwardedRef) => {
    const { __scopeSlider, index: index2, name, ...thumbProps } = props;
    const context = useSliderContext(THUMB_NAME, __scopeSlider);
    const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider);
    const [thumb, setThumb] = React60.useState(null);
    const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
    const isFormControl = thumb ? context.form || !!thumb.closest("form") : true;
    const size2 = useSize(thumb);
    const value = context.values[index2];
    const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);
    const label = getLabel(index2, context.values.length);
    const orientationSize = size2?.[orientation.size];
    const thumbInBoundsOffset = orientationSize ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction) : 0;
    React60.useEffect(() => {
      if (thumb) {
        context.thumbs.add(thumb);
        return () => {
          context.thumbs.delete(thumb);
        };
      }
    }, [thumb, context.thumbs]);
    return (0, import_jsx_runtime116.jsxs)(
      "span",
      {
        style: {
          transform: "var(--radix-slider-thumb-transform)",
          position: "absolute",
          [orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`
        },
        children: [
          (0, import_jsx_runtime116.jsx)(Collection2.ItemSlot, { scope: props.__scopeSlider, children: (0, import_jsx_runtime116.jsx)(
            Primitive.span,
            {
              role: "slider",
              "aria-label": props["aria-label"] || label,
              "aria-valuemin": context.min,
              "aria-valuenow": value,
              "aria-valuemax": context.max,
              "aria-orientation": context.orientation,
              "data-orientation": context.orientation,
              "data-disabled": context.disabled ? "" : void 0,
              tabIndex: context.disabled ? void 0 : 0,
              ...thumbProps,
              ref: composedRefs,
              style: value === void 0 ? { display: "none" } : props.style,
              onFocus: composeEventHandlers(props.onFocus, () => {
                context.valueIndexToChangeRef.current = index2;
              })
            }
          ) }),
          isFormControl && (0, import_jsx_runtime116.jsx)(
            SliderBubbleInput,
            {
              name: name ?? (context.name ? context.name + (context.values.length > 1 ? "[]" : "") : void 0),
              form: context.form,
              value
            },
            index2
          )
        ]
      }
    );
  }
);
SliderThumb.displayName = THUMB_NAME;
var BUBBLE_INPUT_NAME = "RadioBubbleInput";
var SliderBubbleInput = React60.forwardRef(
  ({ __scopeSlider, value, ...props }, forwardedRef) => {
    const ref = React60.useRef(null);
    const composedRefs = useComposedRefs(ref, forwardedRef);
    const prevValue = usePrevious(value);
    React60.useEffect(() => {
      const input = ref.current;
      if (!input)
        return;
      const inputProto = window.HTMLInputElement.prototype;
      const descriptor = Object.getOwnPropertyDescriptor(inputProto, "value");
      const setValue = descriptor.set;
      if (prevValue !== value && setValue) {
        const event = new Event("input", { bubbles: true });
        setValue.call(input, value);
        input.dispatchEvent(event);
      }
    }, [prevValue, value]);
    return (0, import_jsx_runtime116.jsx)(
      Primitive.input,
      {
        style: { display: "none" },
        ...props,
        ref: composedRefs,
        defaultValue: value
      }
    );
  }
);
SliderBubbleInput.displayName = BUBBLE_INPUT_NAME;
function getNextSortedValues(prevValues = [], nextValue, atIndex) {
  const nextValues = [...prevValues];
  nextValues[atIndex] = nextValue;
  return nextValues.sort((a, b) => a - b);
}
function convertValueToPercentage(value, min4, max3) {
  const maxSteps = max3 - min4;
  const percentPerStep = 100 / maxSteps;
  const percentage = percentPerStep * (value - min4);
  return clamp3(percentage, [0, 100]);
}
function getLabel(index2, totalValues) {
  if (totalValues > 2) {
    return `Value ${index2 + 1} of ${totalValues}`;
  } else if (totalValues === 2) {
    return ["Minimum", "Maximum"][index2];
  } else {
    return void 0;
  }
}
function getClosestValueIndex(values, nextValue) {
  if (values.length === 1)
    return 0;
  const distances = values.map((value) => Math.abs(value - nextValue));
  const closestDistance = Math.min(...distances);
  return distances.indexOf(closestDistance);
}
function getThumbInBoundsOffset(width, left, direction) {
  const halfWidth = width / 2;
  const halfPercent = 50;
  const offset2 = linearScale([0, halfPercent], [0, halfWidth]);
  return (halfWidth - offset2(left) * direction) * direction;
}
function getStepsBetweenValues(values) {
  return values.slice(0, -1).map((value, index2) => values[index2 + 1] - value);
}
function hasMinStepsBetweenValues(values, minStepsBetweenValues) {
  if (minStepsBetweenValues > 0) {
    const stepsBetweenValues = getStepsBetweenValues(values);
    const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);
    return actualMinStepsBetweenValues >= minStepsBetweenValues;
  }
  return true;
}
function linearScale(input, output) {
  return (value) => {
    if (input[0] === input[1] || output[0] === output[1])
      return output[0];
    const ratio = (output[1] - output[0]) / (input[1] - input[0]);
    return output[0] + ratio * (value - input[0]);
  };
}
function getDecimalCount(value) {
  return (String(value).split(".")[1] || "").length;
}
function roundValue(value, decimalCount) {
  const rounder = Math.pow(10, decimalCount);
  return Math.round(value * rounder) / rounder;
}
var Root5 = Slider;
var Track = SliderTrack;
var Range2 = SliderRange;
var Thumb = SliderThumb;

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/primitives/Slider.mjs
var import_react102 = __toESM(require_react(), 1);
var Slider2 = (0, import_react102.memo)(function Slider22(props) {
  const { title, steps, value, label, onValueChange } = props;
  const editor = useEditor();
  const msg2 = useTranslation();
  const handleValueChange = (0, import_react102.useCallback)(
    (value2) => {
      onValueChange(value2[0], true);
    },
    [onValueChange]
  );
  const handlePointerDown = (0, import_react102.useCallback)(() => {
    editor.mark("click slider");
  }, [editor]);
  const handlePointerUp = (0, import_react102.useCallback)(() => {
    if (!value)
      return;
    onValueChange(value, false);
  }, [value, onValueChange]);
  return (0, import_jsx_runtime117.jsx)("div", { className: "tlui-slider__container", children: (0, import_jsx_runtime117.jsxs)(
    Root5,
    {
      "data-testid": props["data-testid"],
      className: "tlui-slider",
      "area-label": "Opacity",
      dir: "ltr",
      min: 0,
      max: steps,
      step: 1,
      value: value ? [value] : void 0,
      onPointerDown: handlePointerDown,
      onValueChange: handleValueChange,
      onPointerUp: handlePointerUp,
      title: title + " — " + msg2(label),
      children: [
        (0, import_jsx_runtime117.jsx)(Track, { className: "tlui-slider__track", dir: "ltr", children: value !== null && (0, import_jsx_runtime117.jsx)(Range2, { className: "tlui-slider__range", dir: "ltr" }) }),
        value !== null && (0, import_jsx_runtime117.jsx)(Thumb, { className: "tlui-slider__thumb", dir: "ltr" })
      ]
    }
  ) });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs
var import_jsx_runtime118 = __toESM(require_jsx_runtime(), 1);
var import_classnames21 = __toESM(require_classnames(), 1);
var React61 = __toESM(require_react(), 1);
var DoubleDropdownPicker = React61.memo(function DoubleDropdownPicker2({
  label,
  uiTypeA,
  uiTypeB,
  labelA,
  labelB,
  itemsA,
  itemsB,
  styleA,
  styleB,
  valueA,
  valueB,
  onValueChange
}) {
  const msg2 = useTranslation();
  const iconA = React61.useMemo(
    () => itemsA.find((item) => valueA.type === "shared" && valueA.value === item.value)?.icon ?? "mixed",
    [itemsA, valueA]
  );
  const iconB = React61.useMemo(
    () => itemsB.find((item) => valueB.type === "shared" && valueB.value === item.value)?.icon ?? "mixed",
    [itemsB, valueB]
  );
  if (valueA === void 0 && valueB === void 0)
    return null;
  return (0, import_jsx_runtime118.jsxs)("div", { className: "tlui-style-panel__double-select-picker", children: [
    (0, import_jsx_runtime118.jsx)("div", { title: msg2(label), className: "tlui-style-panel__double-select-picker-label", children: msg2(label) }),
    (0, import_jsx_runtime118.jsxs)(Root4, { id: `style panel ${uiTypeA} A`, children: [
      (0, import_jsx_runtime118.jsx)(
        Trigger,
        {
          asChild: true,
          onTouchEnd: (e) => preventDefault(e),
          children: (0, import_jsx_runtime118.jsx)(
            Button,
            {
              "data-testid": `style.${uiTypeA}`,
              title: msg2(labelA) + " — " + (valueA === null ? msg2("style-panel.mixed") : msg2(`${uiTypeA}-style.${valueA}`)),
              icon: iconA,
              invertIcon: true,
              smallIcon: true
            }
          )
        }
      ),
      (0, import_jsx_runtime118.jsx)(Content3, { side: "bottom", align: "end", sideOffset: 0, alignOffset: -2, children: (0, import_jsx_runtime118.jsx)(
        "div",
        {
          className: (0, import_classnames21.default)("tlui-button-grid", {
            "tlui-button-grid__two": itemsA.length < 4,
            "tlui-button-grid__four": itemsA.length >= 4
          }),
          children: itemsA.map((item) => {
            return (0, import_jsx_runtime118.jsx)(
              Item,
              {
                className: "tlui-button-grid__button",
                title: msg2(labelA) + " — " + msg2(`${uiTypeA}-style.${item.value}`),
                "data-testid": `style.${uiTypeA}.${item.value}`,
                icon: item.icon,
                onClick: () => onValueChange(styleA, item.value, false),
                invertIcon: true
              },
              item.value
            );
          })
        }
      ) })
    ] }),
    (0, import_jsx_runtime118.jsxs)(Root4, { id: `style panel ${uiTypeB}`, children: [
      (0, import_jsx_runtime118.jsx)(
        Trigger,
        {
          asChild: true,
          onTouchEnd: (e) => preventDefault(e),
          children: (0, import_jsx_runtime118.jsx)(
            Button,
            {
              "data-testid": `style.${uiTypeB}`,
              title: msg2(labelB) + " — " + (valueB === null ? msg2("style-panel.mixed") : msg2(`${uiTypeB}-style.${valueB}`)),
              icon: iconB,
              smallIcon: true
            }
          )
        }
      ),
      (0, import_jsx_runtime118.jsx)(Content3, { side: "bottom", align: "end", sideOffset: 0, alignOffset: -2, children: (0, import_jsx_runtime118.jsx)(
        "div",
        {
          className: (0, import_classnames21.default)("tlui-button-grid", {
            "tlui-button-grid__two": itemsA.length < 4,
            "tlui-button-grid__four": itemsA.length >= 4
          }),
          children: itemsB.map((item) => {
            return (0, import_jsx_runtime118.jsx)(
              Item,
              {
                className: "tlui-button-grid__button",
                title: msg2(labelB) + " — " + msg2(`${uiTypeB}-style.${item.value}`),
                "data-testid": `style.${uiTypeB}.${item.value}`,
                icon: item.icon,
                onClick: () => onValueChange(styleB, item.value, false)
              },
              item.value
            );
          })
        }
      ) })
    ] })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs
var import_jsx_runtime119 = __toESM(require_jsx_runtime(), 1);
var import_classnames22 = __toESM(require_classnames(), 1);
var React62 = __toESM(require_react(), 1);
var DropdownPicker = React62.memo(function DropdownPicker2({
  id,
  label,
  uiType,
  style,
  items,
  value,
  onValueChange
}) {
  const msg2 = useTranslation();
  const icon = React62.useMemo(
    () => items.find((item) => value.type === "shared" && item.value === value.value)?.icon,
    [items, value]
  );
  return (0, import_jsx_runtime119.jsxs)(Root4, { id: `style panel ${id}`, children: [
    (0, import_jsx_runtime119.jsx)(
      Trigger,
      {
        asChild: true,
        onTouchEnd: (e) => preventDefault(e),
        children: (0, import_jsx_runtime119.jsx)(
          Button,
          {
            "data-testid": `style.${uiType}`,
            title: value.type === "mixed" ? msg2("style-panel.mixed") : msg2(`${uiType}-style.${value.value}`),
            label,
            icon: icon ?? "mixed"
          }
        )
      }
    ),
    (0, import_jsx_runtime119.jsx)(Content3, { side: "left", align: "center", alignOffset: 0, children: (0, import_jsx_runtime119.jsx)(
      "div",
      {
        className: (0, import_classnames22.default)("tlui-button-grid", {
          "tlui-button-grid__two": items.length < 3,
          "tlui-button-grid__three": items.length == 3,
          "tlui-button-grid__four": items.length >= 4
        }),
        children: items.map((item) => {
          return (0, import_jsx_runtime119.jsx)(
            Item,
            {
              className: "tlui-button-grid__button",
              "data-testid": `style.${uiType}.${item.value}`,
              title: msg2(`${uiType}-style.${item.value}`),
              icon: item.icon,
              onClick: () => onValueChange(style, item.value, false)
            },
            item.value
          );
        })
      }
    ) })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/StylePanel/styles.mjs
var STYLES = {
  color: [
    { value: "black", icon: "color" },
    { value: "grey", icon: "color" },
    { value: "light-violet", icon: "color" },
    { value: "violet", icon: "color" },
    { value: "blue", icon: "color" },
    { value: "light-blue", icon: "color" },
    { value: "yellow", icon: "color" },
    { value: "orange", icon: "color" },
    { value: "green", icon: "color" },
    { value: "light-green", icon: "color" },
    { value: "light-red", icon: "color" },
    { value: "red", icon: "color" }
  ],
  fill: [
    { value: "none", icon: "fill-none" },
    { value: "semi", icon: "fill-semi" },
    { value: "solid", icon: "fill-solid" },
    { value: "pattern", icon: "fill-pattern" }
  ],
  dash: [
    { value: "draw", icon: "dash-draw" },
    { value: "dashed", icon: "dash-dashed" },
    { value: "dotted", icon: "dash-dotted" },
    { value: "solid", icon: "dash-solid" }
  ],
  size: [
    { value: "s", icon: "size-small" },
    { value: "m", icon: "size-medium" },
    { value: "l", icon: "size-large" },
    { value: "xl", icon: "size-extra-large" }
  ],
  font: [
    { value: "draw", icon: "font-draw" },
    { value: "sans", icon: "font-sans" },
    { value: "serif", icon: "font-serif" },
    { value: "mono", icon: "font-mono" }
  ],
  horizontalAlign: [
    { value: "start", icon: "text-align-left" },
    { value: "middle", icon: "text-align-center" },
    { value: "end", icon: "text-align-right" }
  ],
  verticalAlign: [
    { value: "start", icon: "vertical-align-start" },
    { value: "middle", icon: "vertical-align-center" },
    { value: "end", icon: "vertical-align-end" }
  ],
  geo: [
    { value: "rectangle", icon: "geo-rectangle" },
    { value: "ellipse", icon: "geo-ellipse" },
    { value: "cloud", icon: "geo-cloud" },
    { value: "triangle", icon: "geo-triangle" },
    { value: "diamond", icon: "geo-diamond" },
    { value: "pentagon", icon: "geo-pentagon" },
    { value: "hexagon", icon: "geo-hexagon" },
    { value: "octagon", icon: "geo-octagon" },
    { value: "star", icon: "geo-star" },
    { value: "rhombus", icon: "geo-rhombus" },
    { value: "rhombus-2", icon: "geo-rhombus-2" },
    { value: "oval", icon: "geo-oval" },
    { value: "trapezoid", icon: "geo-trapezoid" },
    { value: "arrow-right", icon: "geo-arrow-right" },
    { value: "arrow-left", icon: "geo-arrow-left" },
    { value: "arrow-up", icon: "geo-arrow-up" },
    { value: "arrow-down", icon: "geo-arrow-down" },
    { value: "x-box", icon: "geo-x-box" },
    { value: "check-box", icon: "geo-check-box" }
  ],
  arrowheadStart: [
    { value: "none", icon: "arrowhead-none" },
    { value: "arrow", icon: "arrowhead-arrow" },
    { value: "triangle", icon: "arrowhead-triangle" },
    { value: "square", icon: "arrowhead-square" },
    { value: "dot", icon: "arrowhead-dot" },
    { value: "diamond", icon: "arrowhead-diamond" },
    { value: "inverted", icon: "arrowhead-triangle-inverted" },
    { value: "bar", icon: "arrowhead-bar" }
  ],
  arrowheadEnd: [
    { value: "none", icon: "arrowhead-none" },
    { value: "arrow", icon: "arrowhead-arrow" },
    { value: "triangle", icon: "arrowhead-triangle" },
    { value: "square", icon: "arrowhead-square" },
    { value: "dot", icon: "arrowhead-dot" },
    { value: "diamond", icon: "arrowhead-diamond" },
    { value: "inverted", icon: "arrowhead-triangle-inverted" },
    { value: "bar", icon: "arrowhead-bar" }
  ],
  spline: [
    { value: "line", icon: "spline-line" },
    { value: "cubic", icon: "spline-cubic" }
  ]
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/StylePanel/StylePanel.mjs
var StylePanel = function StylePanel2({ isMobile }) {
  const editor = useEditor();
  const relevantStyles = useRelevantStyles();
  const handlePointerOut = (0, import_react103.useCallback)(() => {
    if (!isMobile) {
      editor.updateInstanceState({ isChangingStyle: false });
    }
  }, [editor, isMobile]);
  if (!relevantStyles)
    return null;
  const { styles, opacity } = relevantStyles;
  const geo = styles.get(GeoShapeGeoStyle);
  const arrowheadEnd = styles.get(ArrowShapeArrowheadEndStyle);
  const arrowheadStart = styles.get(ArrowShapeArrowheadStartStyle);
  const spline = styles.get(LineShapeSplineStyle);
  const font = styles.get(DefaultFontStyle);
  const hideGeo = geo === void 0;
  const hideArrowHeads = arrowheadEnd === void 0 && arrowheadStart === void 0;
  const hideSpline = spline === void 0;
  const hideText = font === void 0;
  return (0, import_jsx_runtime120.jsxs)("div", { className: "tlui-style-panel", "data-ismobile": isMobile, onPointerLeave: handlePointerOut, children: [
    (0, import_jsx_runtime120.jsx)(CommonStylePickerSet, { styles, opacity }),
    !hideText && (0, import_jsx_runtime120.jsx)(TextStylePickerSet, { styles }),
    !(hideGeo && hideArrowHeads && hideSpline) && (0, import_jsx_runtime120.jsxs)("div", { className: "tlui-style-panel__section", "aria-label": "style panel styles", children: [
      (0, import_jsx_runtime120.jsx)(GeoStylePickerSet, { styles }),
      (0, import_jsx_runtime120.jsx)(ArrowheadStylePickerSet, { styles }),
      (0, import_jsx_runtime120.jsx)(SplineStylePickerSet, { styles })
    ] })
  ] });
};
function useStyleChangeCallback() {
  const editor = useEditor();
  return import_react103.default.useMemo(() => {
    return function handleStyleChange(style, value, squashing) {
      editor.batch(() => {
        if (editor.isIn("select")) {
          editor.setStyleForSelectedShapes(style, value, { squashing });
        }
        editor.setStyleForNextShapes(style, value, { squashing });
        editor.updateInstanceState({ isChangingStyle: true });
      });
    };
  }, [editor]);
}
var tldrawSupportedOpacities = [0.1, 0.25, 0.5, 0.75, 1];
function CommonStylePickerSet({
  styles,
  opacity
}) {
  const editor = useEditor();
  const msg2 = useTranslation();
  const handleValueChange = useStyleChangeCallback();
  const handleOpacityValueChange = import_react103.default.useCallback(
    (value, ephemeral) => {
      const item = tldrawSupportedOpacities[value];
      editor.batch(() => {
        if (editor.isIn("select")) {
          editor.setOpacityForSelectedShapes(item, { ephemeral });
        }
        editor.setOpacityForNextShapes(item, { ephemeral });
        editor.updateInstanceState({ isChangingStyle: true });
      });
    },
    [editor]
  );
  const color = styles.get(DefaultColorStyle);
  const fill = styles.get(DefaultFillStyle);
  const dash = styles.get(DefaultDashStyle);
  const size2 = styles.get(DefaultSizeStyle);
  const showPickers = fill !== void 0 || dash !== void 0 || size2 !== void 0;
  const opacityIndex = opacity.type === "mixed" ? -1 : tldrawSupportedOpacities.indexOf(
    minBy(
      tldrawSupportedOpacities,
      (supportedOpacity) => Math.abs(supportedOpacity - opacity.value)
    )
  );
  return (0, import_jsx_runtime120.jsxs)(import_jsx_runtime120.Fragment, { children: [
    (0, import_jsx_runtime120.jsxs)(
      "div",
      {
        tabIndex: -1,
        className: "tlui-style-panel__section__common",
        "aria-label": "style panel styles",
        children: [
          color === void 0 ? null : (0, import_jsx_runtime120.jsx)(
            ButtonPicker,
            {
              title: msg2("style-panel.color"),
              uiType: "color",
              style: DefaultColorStyle,
              items: STYLES.color,
              value: color,
              onValueChange: handleValueChange
            }
          ),
          opacity === void 0 ? null : (0, import_jsx_runtime120.jsx)(
            Slider2,
            {
              "data-testid": "style.opacity",
              value: opacityIndex >= 0 ? opacityIndex : tldrawSupportedOpacities.length - 1,
              label: opacity.type === "mixed" ? "style-panel.mixed" : `opacity-style.${opacity.value}`,
              onValueChange: handleOpacityValueChange,
              steps: tldrawSupportedOpacities.length - 1,
              title: msg2("style-panel.opacity")
            }
          )
        ]
      }
    ),
    showPickers && (0, import_jsx_runtime120.jsxs)("div", { className: "tlui-style-panel__section", "aria-label": "style panel styles", children: [
      fill === void 0 ? null : (0, import_jsx_runtime120.jsx)(
        ButtonPicker,
        {
          title: msg2("style-panel.fill"),
          uiType: "fill",
          style: DefaultFillStyle,
          items: STYLES.fill,
          value: fill,
          onValueChange: handleValueChange
        }
      ),
      dash === void 0 ? null : (0, import_jsx_runtime120.jsx)(
        ButtonPicker,
        {
          title: msg2("style-panel.dash"),
          uiType: "dash",
          style: DefaultDashStyle,
          items: STYLES.dash,
          value: dash,
          onValueChange: handleValueChange
        }
      ),
      size2 === void 0 ? null : (0, import_jsx_runtime120.jsx)(
        ButtonPicker,
        {
          title: msg2("style-panel.size"),
          uiType: "size",
          style: DefaultSizeStyle,
          items: STYLES.size,
          value: size2,
          onValueChange: handleValueChange
        }
      )
    ] })
  ] });
}
function TextStylePickerSet({ styles }) {
  const msg2 = useTranslation();
  const handleValueChange = useStyleChangeCallback();
  const font = styles.get(DefaultFontStyle);
  const align = styles.get(DefaultHorizontalAlignStyle);
  const verticalAlign = styles.get(DefaultVerticalAlignStyle);
  if (font === void 0 && align === void 0) {
    return null;
  }
  return (0, import_jsx_runtime120.jsxs)("div", { className: "tlui-style-panel__section", "aria-label": "style panel text", children: [
    font === void 0 ? null : (0, import_jsx_runtime120.jsx)(
      ButtonPicker,
      {
        title: msg2("style-panel.font"),
        uiType: "font",
        style: DefaultFontStyle,
        items: STYLES.font,
        value: font,
        onValueChange: handleValueChange
      }
    ),
    align === void 0 ? null : (0, import_jsx_runtime120.jsxs)("div", { className: "tlui-style-panel__row", children: [
      (0, import_jsx_runtime120.jsx)(
        ButtonPicker,
        {
          title: msg2("style-panel.align"),
          uiType: "align",
          style: DefaultHorizontalAlignStyle,
          items: STYLES.horizontalAlign,
          value: align,
          onValueChange: handleValueChange
        }
      ),
      verticalAlign === void 0 ? (0, import_jsx_runtime120.jsx)(
        Button,
        {
          title: msg2("style-panel.vertical-align"),
          "data-testid": "vertical-align",
          icon: "vertical-align-center",
          disabled: true
        }
      ) : (0, import_jsx_runtime120.jsx)(
        DropdownPicker,
        {
          id: "geo-vertical-alignment",
          uiType: "verticalAlign",
          style: DefaultVerticalAlignStyle,
          items: STYLES.verticalAlign,
          value: verticalAlign,
          onValueChange: handleValueChange
        }
      )
    ] })
  ] });
}
function GeoStylePickerSet({ styles }) {
  const handleValueChange = useStyleChangeCallback();
  const geo = styles.get(GeoShapeGeoStyle);
  if (geo === void 0) {
    return null;
  }
  return (0, import_jsx_runtime120.jsx)(
    DropdownPicker,
    {
      id: "geo",
      label: "style-panel.geo",
      uiType: "geo",
      style: GeoShapeGeoStyle,
      items: STYLES.geo,
      value: geo,
      onValueChange: handleValueChange
    }
  );
}
function SplineStylePickerSet({ styles }) {
  const handleValueChange = useStyleChangeCallback();
  const spline = styles.get(LineShapeSplineStyle);
  if (spline === void 0) {
    return null;
  }
  return (0, import_jsx_runtime120.jsx)(
    DropdownPicker,
    {
      id: "spline",
      label: "style-panel.spline",
      uiType: "spline",
      style: LineShapeSplineStyle,
      items: STYLES.spline,
      value: spline,
      onValueChange: handleValueChange
    }
  );
}
function ArrowheadStylePickerSet({ styles }) {
  const handleValueChange = useStyleChangeCallback();
  const arrowheadEnd = styles.get(ArrowShapeArrowheadEndStyle);
  const arrowheadStart = styles.get(ArrowShapeArrowheadStartStyle);
  if (!arrowheadEnd || !arrowheadStart) {
    return null;
  }
  return (0, import_jsx_runtime120.jsx)(
    DoubleDropdownPicker,
    {
      label: "style-panel.arrowheads",
      uiTypeA: "arrowheadStart",
      styleA: ArrowShapeArrowheadStartStyle,
      itemsA: STYLES.arrowheadStart,
      valueA: arrowheadStart,
      uiTypeB: "arrowheadEnd",
      styleB: ArrowShapeArrowheadEndStyle,
      itemsB: STYLES.arrowheadEnd,
      valueB: arrowheadEnd,
      onValueChange: handleValueChange,
      labelA: "style-panel.arrowhead-start",
      labelB: "style-panel.arrowhead-end"
    }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/Toasts.mjs
var import_jsx_runtime121 = __toESM(require_jsx_runtime(), 1);
var React64 = __toESM(require_react(), 1);
function Toast2({ toast }) {
  const { removeToast } = useToasts();
  const msg2 = useTranslation();
  const onOpenChange = (isOpen) => {
    if (!isOpen) {
      removeToast(toast.id);
    }
  };
  const hasActions = toast.actions && toast.actions.length > 0;
  return (0, import_jsx_runtime121.jsxs)(
    Root23,
    {
      onOpenChange,
      className: "tlui-toast__container",
      duration: toast.keepOpen ? Infinity : 5e3,
      children: [
        toast.icon && (0, import_jsx_runtime121.jsx)("div", { className: "tlui-toast__icon", children: (0, import_jsx_runtime121.jsx)(Icon, { icon: toast.icon }) }),
        (0, import_jsx_runtime121.jsxs)("div", { className: "tlui-toast__main", children: [
          (0, import_jsx_runtime121.jsxs)("div", { className: "tlui-toast__content", children: [
            toast.title && (0, import_jsx_runtime121.jsx)(Title2, { className: "tlui-toast__title", children: toast.title }),
            toast.description && (0, import_jsx_runtime121.jsx)(Description, { className: "tlui-toast__description", children: toast.description })
          ] }),
          toast.actions && (0, import_jsx_runtime121.jsxs)("div", { className: "tlui-toast__actions", children: [
            toast.actions.map((action, i) => (0, import_jsx_runtime121.jsx)(Action, { altText: action.label, asChild: true, onClick: action.onClick, children: (0, import_jsx_runtime121.jsx)(
              Button,
              {
                className: action.type === "warn" ? "tlui-button__warning" : "tlui-button__primary",
                children: action.label
              }
            ) }, i)),
            hasActions && (0, import_jsx_runtime121.jsx)(Close, { asChild: true, children: (0, import_jsx_runtime121.jsx)(Button, { className: "tlui-toast__close", style: { marginLeft: "auto" }, children: toast.closeLabel ?? msg2("toast.close") }) })
          ] })
        ] }),
        !hasActions && (0, import_jsx_runtime121.jsx)(Close, { asChild: true, children: (0, import_jsx_runtime121.jsx)(Button, { className: "tlui-toast__close", children: toast.closeLabel ?? msg2("toast.close") }) })
      ]
    }
  );
}
function _Toasts() {
  const { toasts } = useToasts();
  return (0, import_jsx_runtime121.jsx)(import_jsx_runtime121.Fragment, { children: toasts.map((toast) => (0, import_jsx_runtime121.jsx)(Toast2, { toast }, toast.id)) });
}
var Toasts = React64.memo(_Toasts);
function ToastViewport2() {
  const { toasts } = useToasts();
  const [hasToasts, setHasToasts] = React64.useState(false);
  React64.useEffect(() => {
    let cancelled = false;
    if (toasts.length) {
      setHasToasts(true);
    } else {
      setTimeout(() => {
        if (!cancelled) {
          setHasToasts(false);
        }
      }, 1e3);
    }
    return () => {
      cancelled = true;
    };
  }, [toasts.length, setHasToasts]);
  if (!hasToasts)
    return null;
  return (0, import_jsx_runtime121.jsx)(ToastViewport, { className: "tlui-toast__viewport" });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/Toolbar/Toolbar.mjs
var import_jsx_runtime124 = __toESM(require_jsx_runtime(), 1);
var import_classnames24 = __toESM(require_classnames(), 1);
var import_react106 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/MobileStylePanel.mjs
var import_jsx_runtime122 = __toESM(require_jsx_runtime(), 1);
var import_react105 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useOpenMenuCloser.mjs
var import_react104 = __toESM(require_react(), 1);
function useOpenMenuCloser() {
  const editor = useEditor();
  const rIsPointingToClose = (0, import_react104.useRef)(false);
  const handlePointerDown = (0, import_react104.useCallback)(() => {
    if (editor.openMenus.length > 0) {
      editor.updateInstanceState({ openMenus: [] });
      rIsPointingToClose.current = true;
    }
  }, [editor]);
  const handleClick = (0, import_react104.useCallback)((e) => {
    if (rIsPointingToClose.current) {
      preventDefault(e);
    }
    rIsPointingToClose.current = false;
  }, []);
  return { handlePointerDown, handleClick };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/MobileStylePanel.mjs
function MobileStylePanel() {
  const editor = useEditor();
  const msg2 = useTranslation();
  const relevantStyles = useRelevantStyles();
  const color = relevantStyles?.styles.get(DefaultColorStyle);
  const theme = getDefaultColorTheme({ isDarkMode: editor.user.isDarkMode });
  const currentColor = (color?.type === "shared" ? theme[color.value] : theme.black).solid;
  const disableStylePanel = useValue(
    "isHandOrEraserToolActive",
    () => editor.isInAny("hand", "zoom", "eraser", "laser"),
    [editor]
  );
  const handleStylesOpenChange = (0, import_react105.useCallback)(
    (isOpen) => {
      if (!isOpen) {
        editor.updateInstanceState({ isChangingStyle: false });
      }
    },
    [editor]
  );
  const extraEventsToToggleMenu = useOpenMenuCloser();
  return (0, import_jsx_runtime122.jsxs)(Popover, { id: "style menu", onOpenChange: handleStylesOpenChange, children: [
    (0, import_jsx_runtime122.jsx)(PopoverTrigger, { disabled: disableStylePanel, children: (0, import_jsx_runtime122.jsx)(
      Button,
      {
        className: "tlui-toolbar__tools__button tlui-toolbar__styles__button",
        "data-testid": "mobile.styles",
        style: {
          color: disableStylePanel ? "var(--color-muted-1)" : currentColor
        },
        title: msg2("style-panel.title"),
        ...extraEventsToToggleMenu,
        children: (0, import_jsx_runtime122.jsx)(Icon, { icon: disableStylePanel ? "blob" : color?.type === "mixed" ? "mixed" : "blob" })
      }
    ) }),
    (0, import_jsx_runtime122.jsx)(PopoverContent, { side: "top", align: "end", children: (0, import_jsx_runtime122.jsx)(StylePanel, { isMobile: true }) })
  ] });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs
var import_jsx_runtime123 = __toESM(require_jsx_runtime(), 1);
var import_classnames23 = __toESM(require_classnames(), 1);
var NOT_LOCKABLE_TOOLS = [
  "select",
  "hand",
  "draw",
  "eraser",
  "text",
  "zoom",
  "laser",
  "highlight"
];
function ToggleToolLockedButton({ activeToolId }) {
  const editor = useEditor();
  const breakpoint = useBreakpoint();
  const msg2 = useTranslation();
  const isToolLocked = useValue("is tool locked", () => editor.instanceState.isToolLocked, [editor]);
  if (!activeToolId || NOT_LOCKABLE_TOOLS.includes(activeToolId))
    return null;
  return (0, import_jsx_runtime123.jsx)(
    Button,
    {
      title: msg2("action.toggle-tool-lock"),
      className: (0, import_classnames23.default)("tlui-toolbar__lock-button", {
        "tlui-toolbar__lock-button__mobile": breakpoint < 5
      }),
      icon: isToolLocked ? "lock" : "unlock",
      onClick: () => editor.updateInstanceState({ isToolLocked: !isToolLocked }),
      smallIcon: true
    }
  );
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/Toolbar/Toolbar.mjs
var Toolbar = (0, import_react106.memo)(function Toolbar2() {
  const editor = useEditor();
  const msg2 = useTranslation();
  const breakpoint = useBreakpoint();
  const rMostRecentlyActiveDropdownItem = import_react106.default.useRef(void 0);
  const isReadonly = useReadonly();
  const toolbarItems = useToolbarSchema();
  const laserTool = toolbarItems.find((item) => item.toolItem.id === "laser");
  const activeToolId = useValue("current tool id", () => editor.currentToolId, [editor]);
  const geoState = useValue("geo", () => editor.sharedStyles.getAsKnownValue(GeoShapeGeoStyle), [
    editor
  ]);
  const showEditingTools = !isReadonly;
  const getTitle = (item) => item.label ? `${msg2(item.label)} ${item.kbd ? kbdStr(item.kbd) : ""}` : "";
  const activeTLUiToolbarItem = toolbarItems.find((item) => {
    return isActiveTLUiToolItem(item.toolItem, activeToolId, geoState);
  });
  const { itemsInPanel, itemsInDropdown, dropdownFirstItem } = import_react106.default.useMemo(() => {
    const itemsInPanel2 = [];
    const itemsInDropdown2 = [];
    let dropdownFirstItem2;
    const overflowIndex = Math.min(8, 5 + breakpoint);
    for (let i = 4; i < toolbarItems.length; i++) {
      const item = toolbarItems[i];
      if (i < overflowIndex) {
        itemsInPanel2.push(item);
      } else {
        if (item === activeTLUiToolbarItem) {
          dropdownFirstItem2 = item;
        }
        itemsInDropdown2.push(item);
      }
    }
    if (dropdownFirstItem2) {
    } else {
      if (!rMostRecentlyActiveDropdownItem.current) {
        rMostRecentlyActiveDropdownItem.current = itemsInDropdown2[0];
      }
      dropdownFirstItem2 = rMostRecentlyActiveDropdownItem.current;
      if (!itemsInDropdown2.includes(dropdownFirstItem2)) {
        dropdownFirstItem2 = itemsInDropdown2[0];
      }
    }
    rMostRecentlyActiveDropdownItem.current = dropdownFirstItem2;
    if (itemsInDropdown2.length <= 2) {
      itemsInPanel2.push(...itemsInDropdown2);
      itemsInDropdown2.length = 0;
    }
    return { itemsInPanel: itemsInPanel2, itemsInDropdown: itemsInDropdown2, dropdownFirstItem: dropdownFirstItem2 };
  }, [toolbarItems, activeTLUiToolbarItem, breakpoint]);
  return (0, import_jsx_runtime124.jsx)("div", { className: "tlui-toolbar", children: (0, import_jsx_runtime124.jsxs)("div", { className: "tlui-toolbar__inner", children: [
    (0, import_jsx_runtime124.jsxs)("div", { className: "tlui-toolbar__left", children: [
      !isReadonly && (0, import_jsx_runtime124.jsxs)("div", { className: "tlui-toolbar__extras", children: [
        breakpoint < 6 && !(activeToolId === "hand" || activeToolId === "zoom") && (0, import_jsx_runtime124.jsxs)("div", { className: "tlui-toolbar__extras__controls", children: [
          (0, import_jsx_runtime124.jsx)(UndoButton, {}),
          (0, import_jsx_runtime124.jsx)(RedoButton, {}),
          (0, import_jsx_runtime124.jsx)(TrashButton, {}),
          (0, import_jsx_runtime124.jsx)(DuplicateButton, {}),
          (0, import_jsx_runtime124.jsx)(ActionsMenu, {})
        ] }),
        (0, import_jsx_runtime124.jsx)(ToggleToolLockedButton, { activeToolId })
      ] }),
      (0, import_jsx_runtime124.jsxs)(
        "div",
        {
          className: (0, import_classnames24.default)("tlui-toolbar__tools", {
            "tlui-toolbar__tools__mobile": breakpoint < 5
          }),
          children: [
            toolbarItems.slice(0, 2).map(({ toolItem }) => {
              return (0, import_jsx_runtime124.jsx)(
                ToolbarButton,
                {
                  item: toolItem,
                  title: getTitle(toolItem),
                  isSelected: isActiveTLUiToolItem(toolItem, activeToolId, geoState)
                },
                toolItem.id
              );
            }),
            isReadonly && laserTool && (0, import_jsx_runtime124.jsx)(
              ToolbarButton,
              {
                item: laserTool.toolItem,
                title: getTitle(laserTool.toolItem),
                isSelected: isActiveTLUiToolItem(laserTool.toolItem, activeToolId, geoState)
              },
              laserTool.toolItem.id
            ),
            showEditingTools && (0, import_jsx_runtime124.jsxs)(import_jsx_runtime124.Fragment, { children: [
              (0, import_jsx_runtime124.jsx)("div", { className: "tlui-toolbar__divider" }),
              toolbarItems.slice(2, 4).map(({ toolItem }) => (0, import_jsx_runtime124.jsx)(
                ToolbarButton,
                {
                  item: toolItem,
                  title: getTitle(toolItem),
                  isSelected: isActiveTLUiToolItem(toolItem, activeToolId, geoState)
                },
                toolItem.id
              )),
              (0, import_jsx_runtime124.jsx)("div", { className: "tlui-toolbar__divider" }),
              itemsInPanel.map(({ toolItem }) => (0, import_jsx_runtime124.jsx)(
                ToolbarButton,
                {
                  item: toolItem,
                  title: getTitle(toolItem),
                  isSelected: isActiveTLUiToolItem(toolItem, activeToolId, geoState)
                },
                toolItem.id
              )),
              itemsInDropdown.length ? (0, import_jsx_runtime124.jsxs)(import_jsx_runtime124.Fragment, { children: [
                (0, import_jsx_runtime124.jsx)(
                  ToolbarButton,
                  {
                    item: dropdownFirstItem.toolItem,
                    title: getTitle(dropdownFirstItem.toolItem),
                    isSelected: isActiveTLUiToolItem(
                      dropdownFirstItem.toolItem,
                      activeToolId,
                      geoState
                    )
                  },
                  dropdownFirstItem.toolItem.id
                ),
                (0, import_jsx_runtime124.jsxs)(Root4, { id: "toolbar overflow", modal: false, children: [
                  (0, import_jsx_runtime124.jsx)(Trigger2, { children: (0, import_jsx_runtime124.jsx)(
                    Button,
                    {
                      className: "tlui-toolbar__tools__button tlui-toolbar__overflow",
                      icon: "chevron-up",
                      "data-testid": "tools.more",
                      title: msg2("tool-panel.more")
                    }
                  ) }),
                  (0, import_jsx_runtime124.jsx)(Content3, { side: "top", align: "center", children: (0, import_jsx_runtime124.jsx)(OverflowToolsContent, { toolbarItems: itemsInDropdown }) })
                ] })
              ] }) : null
            ] })
          ]
        }
      )
    ] }),
    breakpoint < 5 && !isReadonly && (0, import_jsx_runtime124.jsx)("div", { className: "tlui-toolbar__tools", children: (0, import_jsx_runtime124.jsx)(MobileStylePanel, {}) })
  ] }) });
});
var OverflowToolsContent = track(function OverflowToolsContent2({
  toolbarItems
}) {
  const msg2 = useTranslation();
  return (0, import_jsx_runtime124.jsx)("div", { className: "tlui-button-grid__four tlui-button-grid__reverse", children: toolbarItems.map(({ toolItem: { id, meta, kbd: kbd2, label, onSelect, icon } }) => {
    return (0, import_jsx_runtime124.jsx)(
      Item,
      {
        className: "tlui-button-grid__button",
        "data-testid": `tools.${id}`,
        "data-tool": id,
        "data-geo": meta?.geo ?? "",
        "aria-label": label,
        onClick: () => onSelect("toolbar"),
        title: label ? `${msg2(label)} ${kbd2 ? kbdStr(kbd2) : ""}` : "",
        icon
      },
      id
    );
  }) });
});
function ToolbarButton({
  item,
  title,
  isSelected
}) {
  return (0, import_jsx_runtime124.jsx)(
    Button,
    {
      className: "tlui-toolbar__tools__button",
      "data-testid": `tools.${item.id}`,
      "data-tool": item.id,
      "data-geo": item.meta?.geo ?? "",
      "aria-label": item.label,
      title,
      icon: item.icon,
      "data-state": isSelected ? "selected" : void 0,
      onClick: () => item.onSelect("toolbar"),
      onTouchStart: (e) => {
        preventDefault(e);
        item.onSelect("toolbar");
      }
    }
  );
}
var isActiveTLUiToolItem = (item, activeToolId, geoState) => {
  return item.meta?.geo ? activeToolId === "geo" && geoState === item.meta?.geo : activeToolId === item.id;
};

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useEditorEvents.mjs
var import_react107 = __toESM(require_react(), 1);
function useEditorEvents() {
  const editor = useEditor();
  const { addToast } = useToasts();
  (0, import_react107.useEffect)(() => {
    function handleMaxShapes({ name, count }) {
      addToast({
        title: "Maximum Shapes Reached",
        description: `You've reached the maximum number of shapes allowed on ${name} (${count}). Please delete some shapes or move to a different page to continue.`
      });
    }
    editor.addListener("max-shapes", handleMaxShapes);
    return () => {
      editor.removeListener("max-shapes", handleMaxShapes);
    };
  }, [editor, addToast]);
}

// node_modules/.deno/hotkeys-js@3.13.15/node_modules/hotkeys-js/dist/hotkeys.esm.js
var isff = typeof navigator !== "undefined" ? navigator.userAgent.toLowerCase().indexOf("firefox") > 0 : false;
function addEvent(object2, event, method, useCapture) {
  if (object2.addEventListener) {
    object2.addEventListener(event, method, useCapture);
  } else if (object2.attachEvent) {
    object2.attachEvent("on".concat(event), method);
  }
}
function removeEvent(object2, event, method, useCapture) {
  if (object2.removeEventListener) {
    object2.removeEventListener(event, method, useCapture);
  } else if (object2.detachEvent) {
    object2.detachEvent("on".concat(event), method);
  }
}
function getMods(modifier, key) {
  const mods = key.slice(0, key.length - 1);
  for (let i = 0; i < mods.length; i++)
    mods[i] = modifier[mods[i].toLowerCase()];
  return mods;
}
function getKeys(key) {
  if (typeof key !== "string")
    key = "";
  key = key.replace(/\s/g, "");
  const keys = key.split(",");
  let index2 = keys.lastIndexOf("");
  for (; index2 >= 0; ) {
    keys[index2 - 1] += ",";
    keys.splice(index2, 1);
    index2 = keys.lastIndexOf("");
  }
  return keys;
}
function compareArray(a1, a2) {
  const arr1 = a1.length >= a2.length ? a1 : a2;
  const arr2 = a1.length >= a2.length ? a2 : a1;
  let isIndex = true;
  for (let i = 0; i < arr1.length; i++) {
    if (arr2.indexOf(arr1[i]) === -1)
      isIndex = false;
  }
  return isIndex;
}
var _keyMap = {
  backspace: 8,
  "⌫": 8,
  tab: 9,
  clear: 12,
  enter: 13,
  "↩": 13,
  return: 13,
  esc: 27,
  escape: 27,
  space: 32,
  left: 37,
  up: 38,
  right: 39,
  down: 40,
  /// https://w3c.github.io/uievents/#events-keyboard-key-location
  arrowup: 38,
  arrowdown: 40,
  arrowleft: 37,
  arrowright: 39,
  del: 46,
  delete: 46,
  ins: 45,
  insert: 45,
  home: 36,
  end: 35,
  pageup: 33,
  pagedown: 34,
  capslock: 20,
  num_0: 96,
  num_1: 97,
  num_2: 98,
  num_3: 99,
  num_4: 100,
  num_5: 101,
  num_6: 102,
  num_7: 103,
  num_8: 104,
  num_9: 105,
  num_multiply: 106,
  num_add: 107,
  num_enter: 108,
  num_subtract: 109,
  num_decimal: 110,
  num_divide: 111,
  "⇪": 20,
  ",": 188,
  ".": 190,
  "/": 191,
  "`": 192,
  "-": isff ? 173 : 189,
  "=": isff ? 61 : 187,
  ";": isff ? 59 : 186,
  "'": 222,
  "{": 219,
  "}": 221,
  "[": 219,
  "]": 221,
  "\\": 220
};
var _modifier = {
  // shiftKey
  "⇧": 16,
  shift: 16,
  // altKey
  "⌥": 18,
  alt: 18,
  option: 18,
  // ctrlKey
  "⌃": 17,
  ctrl: 17,
  control: 17,
  // metaKey
  "⌘": 91,
  cmd: 91,
  meta: 91,
  command: 91
};
var modifierMap = {
  16: "shiftKey",
  18: "altKey",
  17: "ctrlKey",
  91: "metaKey",
  shiftKey: 16,
  ctrlKey: 17,
  altKey: 18,
  metaKey: 91
};
var _mods = {
  16: false,
  18: false,
  17: false,
  91: false
};
var _handlers = {};
for (let k = 1; k < 20; k++) {
  _keyMap["f".concat(k)] = 111 + k;
}
var _downKeys = [];
var winListendFocus = null;
var _scope = "all";
var elementEventMap = /* @__PURE__ */ new Map();
var code = (x) => _keyMap[x.toLowerCase()] || _modifier[x.toLowerCase()] || x.toUpperCase().charCodeAt(0);
var getKey = (x) => Object.keys(_keyMap).find((k) => _keyMap[k] === x);
var getModifier = (x) => Object.keys(_modifier).find((k) => _modifier[k] === x);
function setScope(scope) {
  _scope = scope || "all";
}
function getScope() {
  return _scope || "all";
}
function getPressedKeyCodes() {
  return _downKeys.slice(0);
}
function getPressedKeyString() {
  return _downKeys.map((c) => getKey(c) || getModifier(c) || String.fromCharCode(c));
}
function getAllKeyCodes() {
  const result = [];
  Object.keys(_handlers).forEach((k) => {
    _handlers[k].forEach((_ref) => {
      let {
        key,
        scope,
        mods,
        shortcut
      } = _ref;
      result.push({
        scope,
        shortcut,
        mods,
        keys: key.split("+").map((v) => code(v))
      });
    });
  });
  return result;
}
function filter(event) {
  const target = event.target || event.srcElement;
  const {
    tagName
  } = target;
  let flag = true;
  const isInput = tagName === "INPUT" && !["checkbox", "radio", "range", "button", "file", "reset", "submit", "color"].includes(target.type);
  if (target.isContentEditable || (isInput || tagName === "TEXTAREA" || tagName === "SELECT") && !target.readOnly) {
    flag = false;
  }
  return flag;
}
function isPressed(keyCode) {
  if (typeof keyCode === "string") {
    keyCode = code(keyCode);
  }
  return _downKeys.indexOf(keyCode) !== -1;
}
function deleteScope(scope, newScope) {
  let handlers;
  let i;
  if (!scope)
    scope = getScope();
  for (const key in _handlers) {
    if (Object.prototype.hasOwnProperty.call(_handlers, key)) {
      handlers = _handlers[key];
      for (i = 0; i < handlers.length; ) {
        if (handlers[i].scope === scope) {
          const deleteItems = handlers.splice(i, 1);
          deleteItems.forEach((_ref2) => {
            let {
              element
            } = _ref2;
            return removeKeyEvent(element);
          });
        } else {
          i++;
        }
      }
    }
  }
  if (getScope() === scope)
    setScope(newScope || "all");
}
function clearModifier(event) {
  let key = event.keyCode || event.which || event.charCode;
  if (event.key && event.key.toLowerCase() === "capslock") {
    key = code(event.key);
  }
  const i = _downKeys.indexOf(key);
  if (i >= 0) {
    _downKeys.splice(i, 1);
  }
  if (event.key && event.key.toLowerCase() === "meta") {
    _downKeys.splice(0, _downKeys.length);
  }
  if (key === 93 || key === 224)
    key = 91;
  if (key in _mods) {
    _mods[key] = false;
    for (const k in _modifier)
      if (_modifier[k] === key)
        hotkeys[k] = false;
  }
}
function unbind(keysInfo) {
  if (typeof keysInfo === "undefined") {
    Object.keys(_handlers).forEach((key) => {
      Array.isArray(_handlers[key]) && _handlers[key].forEach((info) => eachUnbind(info));
      delete _handlers[key];
    });
    removeKeyEvent(null);
  } else if (Array.isArray(keysInfo)) {
    keysInfo.forEach((info) => {
      if (info.key)
        eachUnbind(info);
    });
  } else if (typeof keysInfo === "object") {
    if (keysInfo.key)
      eachUnbind(keysInfo);
  } else if (typeof keysInfo === "string") {
    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      args[_key - 1] = arguments[_key];
    }
    let [scope, method] = args;
    if (typeof scope === "function") {
      method = scope;
      scope = "";
    }
    eachUnbind({
      key: keysInfo,
      scope,
      method,
      splitKey: "+"
    });
  }
}
var eachUnbind = (_ref3) => {
  let {
    key,
    scope,
    method,
    splitKey = "+"
  } = _ref3;
  const multipleKeys = getKeys(key);
  multipleKeys.forEach((originKey) => {
    const unbindKeys = originKey.split(splitKey);
    const len = unbindKeys.length;
    const lastKey = unbindKeys[len - 1];
    const keyCode = lastKey === "*" ? "*" : code(lastKey);
    if (!_handlers[keyCode])
      return;
    if (!scope)
      scope = getScope();
    const mods = len > 1 ? getMods(_modifier, unbindKeys) : [];
    const unbindElements = [];
    _handlers[keyCode] = _handlers[keyCode].filter((record) => {
      const isMatchingMethod = method ? record.method === method : true;
      const isUnbind = isMatchingMethod && record.scope === scope && compareArray(record.mods, mods);
      if (isUnbind)
        unbindElements.push(record.element);
      return !isUnbind;
    });
    unbindElements.forEach((element) => removeKeyEvent(element));
  });
};
function eventHandler(event, handler, scope, element) {
  if (handler.element !== element) {
    return;
  }
  let modifiersMatch;
  if (handler.scope === scope || handler.scope === "all") {
    modifiersMatch = handler.mods.length > 0;
    for (const y in _mods) {
      if (Object.prototype.hasOwnProperty.call(_mods, y)) {
        if (!_mods[y] && handler.mods.indexOf(+y) > -1 || _mods[y] && handler.mods.indexOf(+y) === -1) {
          modifiersMatch = false;
        }
      }
    }
    if (handler.mods.length === 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91] || modifiersMatch || handler.shortcut === "*") {
      handler.keys = [];
      handler.keys = handler.keys.concat(_downKeys);
      if (handler.method(event, handler) === false) {
        if (event.preventDefault)
          event.preventDefault();
        else
          event.returnValue = false;
        if (event.stopPropagation)
          event.stopPropagation();
        if (event.cancelBubble)
          event.cancelBubble = true;
      }
    }
  }
}
function dispatch(event, element) {
  const asterisk = _handlers["*"];
  let key = event.keyCode || event.which || event.charCode;
  if (event.key && event.key.toLowerCase() === "capslock") {
    return;
  }
  if (!hotkeys.filter.call(this, event))
    return;
  if (key === 93 || key === 224)
    key = 91;
  if (_downKeys.indexOf(key) === -1 && key !== 229)
    _downKeys.push(key);
  ["metaKey", "ctrlKey", "altKey", "shiftKey"].forEach((keyName) => {
    const keyNum = modifierMap[keyName];
    if (event[keyName] && _downKeys.indexOf(keyNum) === -1) {
      _downKeys.push(keyNum);
    } else if (!event[keyName] && _downKeys.indexOf(keyNum) > -1) {
      _downKeys.splice(_downKeys.indexOf(keyNum), 1);
    } else if (keyName === "metaKey" && event[keyName]) {
      _downKeys = _downKeys.filter((k) => k in modifierMap || k === key);
    }
  });
  if (key in _mods) {
    _mods[key] = true;
    for (const k in _modifier) {
      if (Object.prototype.hasOwnProperty.call(_modifier, k)) {
        const eventKey = modifierMap[_modifier[k]];
        hotkeys[k] = event[eventKey];
      }
    }
    if (!asterisk)
      return;
  }
  for (const e in _mods) {
    if (Object.prototype.hasOwnProperty.call(_mods, e)) {
      _mods[e] = event[modifierMap[e]];
    }
  }
  if (event.getModifierState && !(event.altKey && !event.ctrlKey) && event.getModifierState("AltGraph")) {
    if (_downKeys.indexOf(17) === -1) {
      _downKeys.push(17);
    }
    if (_downKeys.indexOf(18) === -1) {
      _downKeys.push(18);
    }
    _mods[17] = true;
    _mods[18] = true;
  }
  const scope = getScope();
  if (asterisk) {
    for (let i = 0; i < asterisk.length; i++) {
      if (asterisk[i].scope === scope && (event.type === "keydown" && asterisk[i].keydown || event.type === "keyup" && asterisk[i].keyup)) {
        eventHandler(event, asterisk[i], scope, element);
      }
    }
  }
  if (!(key in _handlers))
    return;
  const handlerKey = _handlers[key];
  const keyLen = handlerKey.length;
  for (let i = 0; i < keyLen; i++) {
    if (event.type === "keydown" && handlerKey[i].keydown || event.type === "keyup" && handlerKey[i].keyup) {
      if (handlerKey[i].key) {
        const record = handlerKey[i];
        const {
          splitKey
        } = record;
        const keyShortcut = record.key.split(splitKey);
        const _downKeysCurrent = [];
        for (let a = 0; a < keyShortcut.length; a++) {
          _downKeysCurrent.push(code(keyShortcut[a]));
        }
        if (_downKeysCurrent.sort().join("") === _downKeys.sort().join("")) {
          eventHandler(event, record, scope, element);
        }
      }
    }
  }
}
function hotkeys(key, option, method) {
  _downKeys = [];
  const keys = getKeys(key);
  let mods = [];
  let scope = "all";
  let element = document;
  let i = 0;
  let keyup = false;
  let keydown = true;
  let splitKey = "+";
  let capture = false;
  let single = false;
  if (method === void 0 && typeof option === "function") {
    method = option;
  }
  if (Object.prototype.toString.call(option) === "[object Object]") {
    if (option.scope)
      scope = option.scope;
    if (option.element)
      element = option.element;
    if (option.keyup)
      keyup = option.keyup;
    if (option.keydown !== void 0)
      keydown = option.keydown;
    if (option.capture !== void 0)
      capture = option.capture;
    if (typeof option.splitKey === "string")
      splitKey = option.splitKey;
    if (option.single === true)
      single = true;
  }
  if (typeof option === "string")
    scope = option;
  if (single)
    unbind(key, scope);
  for (; i < keys.length; i++) {
    key = keys[i].split(splitKey);
    mods = [];
    if (key.length > 1)
      mods = getMods(_modifier, key);
    key = key[key.length - 1];
    key = key === "*" ? "*" : code(key);
    if (!(key in _handlers))
      _handlers[key] = [];
    _handlers[key].push({
      keyup,
      keydown,
      scope,
      mods,
      shortcut: keys[i],
      method,
      key: keys[i],
      splitKey,
      element
    });
  }
  if (typeof element !== "undefined" && window) {
    if (!elementEventMap.has(element)) {
      const keydownListener = function() {
        let event = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : window.event;
        return dispatch(event, element);
      };
      const keyupListenr = function() {
        let event = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : window.event;
        dispatch(event, element);
        clearModifier(event);
      };
      elementEventMap.set(element, {
        keydownListener,
        keyupListenr,
        capture
      });
      addEvent(element, "keydown", keydownListener, capture);
      addEvent(element, "keyup", keyupListenr, capture);
    }
    if (!winListendFocus) {
      const listener = () => {
        _downKeys = [];
      };
      winListendFocus = {
        listener,
        capture
      };
      addEvent(window, "focus", listener, capture);
    }
  }
}
function trigger(shortcut) {
  let scope = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "all";
  Object.keys(_handlers).forEach((key) => {
    const dataList = _handlers[key].filter((item) => item.scope === scope && item.shortcut === shortcut);
    dataList.forEach((data) => {
      if (data && data.method) {
        data.method();
      }
    });
  });
}
function removeKeyEvent(element) {
  const values = Object.values(_handlers).flat();
  const findindex = values.findIndex((_ref4) => {
    let {
      element: el
    } = _ref4;
    return el === element;
  });
  if (findindex < 0) {
    const {
      keydownListener,
      keyupListenr,
      capture
    } = elementEventMap.get(element) || {};
    if (keydownListener && keyupListenr) {
      removeEvent(element, "keyup", keyupListenr, capture);
      removeEvent(element, "keydown", keydownListener, capture);
      elementEventMap.delete(element);
    }
  }
  if (values.length <= 0 || elementEventMap.size <= 0) {
    const eventKeys = Object.keys(elementEventMap);
    eventKeys.forEach((el) => {
      const {
        keydownListener,
        keyupListenr,
        capture
      } = elementEventMap.get(el) || {};
      if (keydownListener && keyupListenr) {
        removeEvent(el, "keyup", keyupListenr, capture);
        removeEvent(el, "keydown", keydownListener, capture);
        elementEventMap.delete(el);
      }
    });
    elementEventMap.clear();
    Object.keys(_handlers).forEach((key) => delete _handlers[key]);
    if (winListendFocus) {
      const {
        listener,
        capture
      } = winListendFocus;
      removeEvent(window, "focus", listener, capture);
      winListendFocus = null;
    }
  }
}
var _api = {
  getPressedKeyString,
  setScope,
  getScope,
  deleteScope,
  getPressedKeyCodes,
  getAllKeyCodes,
  isPressed,
  filter,
  trigger,
  unbind,
  keyMap: _keyMap,
  modifier: _modifier,
  modifierMap
};
for (const a in _api) {
  if (Object.prototype.hasOwnProperty.call(_api, a)) {
    hotkeys[a] = _api[a];
  }
}
if (typeof window !== "undefined") {
  const _hotkeys = window.hotkeys;
  hotkeys.noConflict = (deep) => {
    if (deep && window.hotkeys === hotkeys) {
      window.hotkeys = _hotkeys;
    }
    return hotkeys;
  };
  window.hotkeys = hotkeys;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs
var import_react108 = __toESM(require_react(), 1);
var SKIP_KBDS = [
  // we set these in useNativeClipboardEvents instead
  "copy",
  "cut",
  "paste",
  // There's also an upload asset action, so we don't want to set the kbd twice
  "asset"
];
function useKeyboardShortcuts() {
  const editor = useEditor();
  const isReadonly = useReadonly();
  const actions = useActions();
  const tools = useTools();
  const isFocused = useValue("is focused", () => editor.instanceState.isFocused, [editor]);
  (0, import_react108.useEffect)(() => {
    if (!isFocused)
      return;
    const container = editor.getContainer();
    hotkeys.setScope(editor.store.id);
    const hot = (keys, callback) => {
      hotkeys(keys, { element: container, scope: editor.store.id }, callback);
    };
    const areShortcutsDisabled = () => editor.isMenuOpen || editor.editingShapeId !== null || editor.crashingError;
    for (const action of Object.values(actions)) {
      if (!action.kbd)
        continue;
      if (isReadonly && !action.readonlyOk)
        continue;
      if (SKIP_KBDS.includes(action.id))
        continue;
      hot(getHotkeysStringFromKbd(action.kbd), (event) => {
        if (areShortcutsDisabled())
          return;
        preventDefault(event);
        action.onSelect("kbd");
      });
    }
    for (const tool of Object.values(tools)) {
      if (!tool.kbd || !tool.readonlyOk && editor.instanceState.isReadonly) {
        continue;
      }
      if (SKIP_KBDS.includes(tool.id))
        continue;
      hot(getHotkeysStringFromKbd(tool.kbd), (event) => {
        if (areShortcutsDisabled())
          return;
        preventDefault(event);
        tool.onSelect("kbd");
      });
    }
    return () => {
      hotkeys.deleteScope(editor.store.id);
    };
  }, [actions, tools, isReadonly, editor, isFocused]);
}
function getHotkeysStringFromKbd(kbd2) {
  return getKeys2(kbd2).map((kbd22) => {
    let str = "";
    const chars = kbd22.split("");
    if (chars.length === 1) {
      str = chars[0];
    } else {
      if (chars[0] === "!") {
        str = `shift+${chars[1]}`;
      } else if (chars[0] === "?") {
        if (chars.length === 3 && chars[1] === "!") {
          str = `alt+shift+${chars[2]}`;
        } else {
          str = `alt+${chars[1]}`;
        }
      } else if (chars[0] === "$") {
        if (chars[1] === "!") {
          str = `cmd+shift+${chars[2]},ctrl+shift+${chars[2]}`;
        } else if (chars[1] === "?") {
          str = `cmd+⌥+${chars[2]},ctrl+alt+${chars[2]}`;
        } else {
          str = `cmd+${chars[1]},ctrl+${chars[1]}`;
        }
      } else {
        str = kbd22;
      }
    }
    return str;
  }).join(",");
}
function getKeys2(key) {
  if (typeof key !== "string")
    key = "";
  key = key.replace(/\s/g, "");
  const keys = key.split(",");
  let index2 = keys.lastIndexOf("");
  for (; index2 >= 0; ) {
    keys[index2 - 1] += ",";
    keys.splice(index2, 1);
    index2 = keys.lastIndexOf("");
  }
  return keys;
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/TldrawUi.mjs
var TldrawUi = import_react109.default.memo(function TldrawUi2({
  shareZone,
  topZone,
  renderDebugMenuItems,
  children,
  hideUi,
  ...rest
}) {
  return (0, import_jsx_runtime125.jsx)(TldrawUiContextProvider, { ...rest, children: (0, import_jsx_runtime125.jsx)(
    TldrawUiInner,
    {
      hideUi,
      shareZone,
      topZone,
      renderDebugMenuItems,
      children
    }
  ) });
});
var TldrawUiInner = import_react109.default.memo(function TldrawUiInner2({
  children,
  hideUi,
  ...rest
}) {
  return (0, import_jsx_runtime125.jsxs)(import_jsx_runtime125.Fragment, { children: [
    children,
    hideUi ? null : (0, import_jsx_runtime125.jsx)(TldrawUiContent, { ...rest })
  ] });
});
var TldrawUiContent = import_react109.default.memo(function TldrawUI({
  shareZone,
  topZone,
  renderDebugMenuItems
}) {
  const editor = useEditor();
  const msg2 = useTranslation();
  const breakpoint = useBreakpoint();
  const isReadonlyMode = useValue("isReadonlyMode", () => editor.instanceState.isReadonly, [editor]);
  const isFocusMode = useValue("focus", () => editor.instanceState.isFocusMode, [editor]);
  const isDebugMode = useValue("debug", () => editor.instanceState.isDebugMode, [editor]);
  useKeyboardShortcuts();
  useNativeClipboardEvents();
  useEditorEvents();
  const { "toggle-focus-mode": toggleFocus } = useActions();
  return (0, import_jsx_runtime125.jsx)(ToastProvider, { children: (0, import_jsx_runtime125.jsxs)(
    "div",
    {
      className: (0, import_classnames25.default)("tlui-layout", {
        "tlui-layout__mobile": breakpoint < 5
      }),
      "data-breakpoint": breakpoint,
      children: [
        isFocusMode ? (0, import_jsx_runtime125.jsx)("div", { className: "tlui-layout__top", children: (0, import_jsx_runtime125.jsx)(
          Button,
          {
            className: "tlui-focus-button",
            title: `${msg2("focus-mode.toggle-focus-mode")}`,
            icon: "dot",
            onClick: () => toggleFocus.onSelect("menu")
          }
        ) }) : (0, import_jsx_runtime125.jsxs)(import_jsx_runtime125.Fragment, { children: [
          (0, import_jsx_runtime125.jsxs)("div", { className: "tlui-layout__top", children: [
            (0, import_jsx_runtime125.jsxs)("div", { className: "tlui-layout__top__left", children: [
              (0, import_jsx_runtime125.jsx)(MenuZone, {}),
              (0, import_jsx_runtime125.jsxs)("div", { className: "tlui-helper-buttons", children: [
                (0, import_jsx_runtime125.jsx)(ExitPenMode, {}),
                (0, import_jsx_runtime125.jsx)(BackToContent, {}),
                (0, import_jsx_runtime125.jsx)(StopFollowing, {})
              ] })
            ] }),
            (0, import_jsx_runtime125.jsx)("div", { className: "tlui-layout__top__center", children: topZone }),
            (0, import_jsx_runtime125.jsxs)("div", { className: "tlui-layout__top__right", children: [
              shareZone,
              breakpoint >= 5 && !isReadonlyMode && (0, import_jsx_runtime125.jsx)("div", { className: "tlui-style-panel__wrapper", children: (0, import_jsx_runtime125.jsx)(StylePanel, {}) })
            ] })
          ] }),
          (0, import_jsx_runtime125.jsxs)("div", { className: "tlui-layout__bottom", children: [
            (0, import_jsx_runtime125.jsxs)("div", { className: "tlui-layout__bottom__main", children: [
              (0, import_jsx_runtime125.jsx)(NavigationZone, {}),
              (0, import_jsx_runtime125.jsx)(Toolbar, {}),
              breakpoint >= 4 && (0, import_jsx_runtime125.jsx)(HelpMenu, {})
            ] }),
            isDebugMode && (0, import_jsx_runtime125.jsx)(DebugPanel, { renderDebugMenuItems: renderDebugMenuItems ?? null })
          ] })
        ] }),
        (0, import_jsx_runtime125.jsx)(Toasts, {}),
        (0, import_jsx_runtime125.jsx)(Dialogs, {}),
        (0, import_jsx_runtime125.jsx)(ToastViewport2, {}),
        (0, import_jsx_runtime125.jsx)(FollowingIndicator, {})
      ]
    }
  ) });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/ContextMenu.mjs
var import_jsx_runtime128 = __toESM(require_jsx_runtime(), 1);

// node_modules/.deno/@radix-ui+react-context-menu@2.2.16/node_modules/@radix-ui/react-context-menu/dist/index.mjs
var React67 = __toESM(require_react(), 1);
var import_jsx_runtime126 = __toESM(require_jsx_runtime(), 1);
var CONTEXT_MENU_NAME = "ContextMenu";
var [createContextMenuContext, createContextMenuScope] = createContextScope(CONTEXT_MENU_NAME, [
  createMenuScope
]);
var useMenuScope = createMenuScope();
var [ContextMenuProvider, useContextMenuContext] = createContextMenuContext(CONTEXT_MENU_NAME);
var ContextMenu = (props) => {
  const { __scopeContextMenu, children, onOpenChange, dir, modal = true } = props;
  const [open, setOpen] = React67.useState(false);
  const menuScope = useMenuScope(__scopeContextMenu);
  const handleOpenChangeProp = useCallbackRef(onOpenChange);
  const handleOpenChange = React67.useCallback(
    (open2) => {
      setOpen(open2);
      handleOpenChangeProp(open2);
    },
    [handleOpenChangeProp]
  );
  return (0, import_jsx_runtime126.jsx)(
    ContextMenuProvider,
    {
      scope: __scopeContextMenu,
      open,
      onOpenChange: handleOpenChange,
      modal,
      children: (0, import_jsx_runtime126.jsx)(
        Root3,
        {
          ...menuScope,
          dir,
          open,
          onOpenChange: handleOpenChange,
          modal,
          children
        }
      )
    }
  );
};
ContextMenu.displayName = CONTEXT_MENU_NAME;
var TRIGGER_NAME = "ContextMenuTrigger";
var ContextMenuTrigger = React67.forwardRef(
  (props, forwardedRef) => {
    const { __scopeContextMenu, disabled = false, ...triggerProps } = props;
    const context = useContextMenuContext(TRIGGER_NAME, __scopeContextMenu);
    const menuScope = useMenuScope(__scopeContextMenu);
    const pointRef = React67.useRef({ x: 0, y: 0 });
    const virtualRef = React67.useRef({
      getBoundingClientRect: () => DOMRect.fromRect({ width: 0, height: 0, ...pointRef.current })
    });
    const longPressTimerRef = React67.useRef(0);
    const clearLongPress = React67.useCallback(
      () => window.clearTimeout(longPressTimerRef.current),
      []
    );
    const handleOpen = (event) => {
      pointRef.current = { x: event.clientX, y: event.clientY };
      context.onOpenChange(true);
    };
    React67.useEffect(() => clearLongPress, [clearLongPress]);
    React67.useEffect(() => void (disabled && clearLongPress()), [disabled, clearLongPress]);
    return (0, import_jsx_runtime126.jsxs)(import_jsx_runtime126.Fragment, { children: [
      (0, import_jsx_runtime126.jsx)(Anchor2, { ...menuScope, virtualRef }),
      (0, import_jsx_runtime126.jsx)(
        Primitive.span,
        {
          "data-state": context.open ? "open" : "closed",
          "data-disabled": disabled ? "" : void 0,
          ...triggerProps,
          ref: forwardedRef,
          style: { WebkitTouchCallout: "none", ...props.style },
          onContextMenu: disabled ? props.onContextMenu : composeEventHandlers(props.onContextMenu, (event) => {
            clearLongPress();
            handleOpen(event);
            event.preventDefault();
          }),
          onPointerDown: disabled ? props.onPointerDown : composeEventHandlers(
            props.onPointerDown,
            whenTouchOrPen((event) => {
              clearLongPress();
              longPressTimerRef.current = window.setTimeout(() => handleOpen(event), 700);
            })
          ),
          onPointerMove: disabled ? props.onPointerMove : composeEventHandlers(props.onPointerMove, whenTouchOrPen(clearLongPress)),
          onPointerCancel: disabled ? props.onPointerCancel : composeEventHandlers(props.onPointerCancel, whenTouchOrPen(clearLongPress)),
          onPointerUp: disabled ? props.onPointerUp : composeEventHandlers(props.onPointerUp, whenTouchOrPen(clearLongPress))
        }
      )
    ] });
  }
);
ContextMenuTrigger.displayName = TRIGGER_NAME;
var PORTAL_NAME = "ContextMenuPortal";
var ContextMenuPortal = (props) => {
  const { __scopeContextMenu, ...portalProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(Portal3, { ...menuScope, ...portalProps });
};
ContextMenuPortal.displayName = PORTAL_NAME;
var CONTENT_NAME = "ContextMenuContent";
var ContextMenuContent = React67.forwardRef(
  (props, forwardedRef) => {
    const { __scopeContextMenu, ...contentProps } = props;
    const context = useContextMenuContext(CONTENT_NAME, __scopeContextMenu);
    const menuScope = useMenuScope(__scopeContextMenu);
    const hasInteractedOutsideRef = React67.useRef(false);
    return (0, import_jsx_runtime126.jsx)(
      Content2,
      {
        ...menuScope,
        ...contentProps,
        ref: forwardedRef,
        side: "right",
        sideOffset: 2,
        align: "start",
        onCloseAutoFocus: (event) => {
          props.onCloseAutoFocus?.(event);
          if (!event.defaultPrevented && hasInteractedOutsideRef.current) {
            event.preventDefault();
          }
          hasInteractedOutsideRef.current = false;
        },
        onInteractOutside: (event) => {
          props.onInteractOutside?.(event);
          if (!event.defaultPrevented && !context.modal)
            hasInteractedOutsideRef.current = true;
        },
        style: {
          ...props.style,
          // re-namespace exposed content custom properties
          ...{
            "--radix-context-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
            "--radix-context-menu-content-available-width": "var(--radix-popper-available-width)",
            "--radix-context-menu-content-available-height": "var(--radix-popper-available-height)",
            "--radix-context-menu-trigger-width": "var(--radix-popper-anchor-width)",
            "--radix-context-menu-trigger-height": "var(--radix-popper-anchor-height)"
          }
        }
      }
    );
  }
);
ContextMenuContent.displayName = CONTENT_NAME;
var GROUP_NAME = "ContextMenuGroup";
var ContextMenuGroup = React67.forwardRef(
  (props, forwardedRef) => {
    const { __scopeContextMenu, ...groupProps } = props;
    const menuScope = useMenuScope(__scopeContextMenu);
    return (0, import_jsx_runtime126.jsx)(Group, { ...menuScope, ...groupProps, ref: forwardedRef });
  }
);
ContextMenuGroup.displayName = GROUP_NAME;
var LABEL_NAME = "ContextMenuLabel";
var ContextMenuLabel = React67.forwardRef(
  (props, forwardedRef) => {
    const { __scopeContextMenu, ...labelProps } = props;
    const menuScope = useMenuScope(__scopeContextMenu);
    return (0, import_jsx_runtime126.jsx)(Label, { ...menuScope, ...labelProps, ref: forwardedRef });
  }
);
ContextMenuLabel.displayName = LABEL_NAME;
var ITEM_NAME = "ContextMenuItem";
var ContextMenuItem = React67.forwardRef(
  (props, forwardedRef) => {
    const { __scopeContextMenu, ...itemProps } = props;
    const menuScope = useMenuScope(__scopeContextMenu);
    return (0, import_jsx_runtime126.jsx)(Item2, { ...menuScope, ...itemProps, ref: forwardedRef });
  }
);
ContextMenuItem.displayName = ITEM_NAME;
var CHECKBOX_ITEM_NAME = "ContextMenuCheckboxItem";
var ContextMenuCheckboxItem = React67.forwardRef((props, forwardedRef) => {
  const { __scopeContextMenu, ...checkboxItemProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(CheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
});
ContextMenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
var RADIO_GROUP_NAME = "ContextMenuRadioGroup";
var ContextMenuRadioGroup = React67.forwardRef((props, forwardedRef) => {
  const { __scopeContextMenu, ...radioGroupProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(RadioGroup, { ...menuScope, ...radioGroupProps, ref: forwardedRef });
});
ContextMenuRadioGroup.displayName = RADIO_GROUP_NAME;
var RADIO_ITEM_NAME = "ContextMenuRadioItem";
var ContextMenuRadioItem = React67.forwardRef((props, forwardedRef) => {
  const { __scopeContextMenu, ...radioItemProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(RadioItem, { ...menuScope, ...radioItemProps, ref: forwardedRef });
});
ContextMenuRadioItem.displayName = RADIO_ITEM_NAME;
var INDICATOR_NAME = "ContextMenuItemIndicator";
var ContextMenuItemIndicator = React67.forwardRef((props, forwardedRef) => {
  const { __scopeContextMenu, ...itemIndicatorProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(ItemIndicator, { ...menuScope, ...itemIndicatorProps, ref: forwardedRef });
});
ContextMenuItemIndicator.displayName = INDICATOR_NAME;
var SEPARATOR_NAME = "ContextMenuSeparator";
var ContextMenuSeparator = React67.forwardRef((props, forwardedRef) => {
  const { __scopeContextMenu, ...separatorProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(Separator, { ...menuScope, ...separatorProps, ref: forwardedRef });
});
ContextMenuSeparator.displayName = SEPARATOR_NAME;
var ARROW_NAME = "ContextMenuArrow";
var ContextMenuArrow = React67.forwardRef(
  (props, forwardedRef) => {
    const { __scopeContextMenu, ...arrowProps } = props;
    const menuScope = useMenuScope(__scopeContextMenu);
    return (0, import_jsx_runtime126.jsx)(Arrow2, { ...menuScope, ...arrowProps, ref: forwardedRef });
  }
);
ContextMenuArrow.displayName = ARROW_NAME;
var SUB_NAME = "ContextMenuSub";
var ContextMenuSub = (props) => {
  const { __scopeContextMenu, children, onOpenChange, open: openProp, defaultOpen } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  const [open, setOpen] = useControllableState({
    prop: openProp,
    defaultProp: defaultOpen ?? false,
    onChange: onOpenChange,
    caller: SUB_NAME
  });
  return (0, import_jsx_runtime126.jsx)(Sub, { ...menuScope, open, onOpenChange: setOpen, children });
};
ContextMenuSub.displayName = SUB_NAME;
var SUB_TRIGGER_NAME = "ContextMenuSubTrigger";
var ContextMenuSubTrigger = React67.forwardRef((props, forwardedRef) => {
  const { __scopeContextMenu, ...triggerItemProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(SubTrigger, { ...menuScope, ...triggerItemProps, ref: forwardedRef });
});
ContextMenuSubTrigger.displayName = SUB_TRIGGER_NAME;
var SUB_CONTENT_NAME = "ContextMenuSubContent";
var ContextMenuSubContent = React67.forwardRef((props, forwardedRef) => {
  const { __scopeContextMenu, ...subContentProps } = props;
  const menuScope = useMenuScope(__scopeContextMenu);
  return (0, import_jsx_runtime126.jsx)(
    SubContent,
    {
      ...menuScope,
      ...subContentProps,
      ref: forwardedRef,
      style: {
        ...props.style,
        // re-namespace exposed content custom properties
        ...{
          "--radix-context-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
          "--radix-context-menu-content-available-width": "var(--radix-popper-available-width)",
          "--radix-context-menu-content-available-height": "var(--radix-popper-available-height)",
          "--radix-context-menu-trigger-width": "var(--radix-popper-anchor-width)",
          "--radix-context-menu-trigger-height": "var(--radix-popper-anchor-height)"
        }
      }
    }
  );
});
ContextMenuSubContent.displayName = SUB_CONTENT_NAME;
function whenTouchOrPen(handler) {
  return (event) => event.pointerType !== "mouse" ? handler(event) : void 0;
}
var Root24 = ContextMenu;
var Trigger3 = ContextMenuTrigger;
var Portal23 = ContextMenuPortal;
var Content23 = ContextMenuContent;
var Group22 = ContextMenuGroup;
var Item23 = ContextMenuItem;
var CheckboxItem22 = ContextMenuCheckboxItem;
var Sub22 = ContextMenuSub;
var SubTrigger22 = ContextMenuSubTrigger;
var SubContent22 = ContextMenuSubContent;

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/ContextMenu.mjs
var import_classnames26 = __toESM(require_classnames(), 1);
var import_react110 = __toESM(require_react(), 1);

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/MoveToPageMenu.mjs
var import_jsx_runtime127 = __toESM(require_jsx_runtime(), 1);
var MoveToPageMenu = track(function MoveToPageMenu2() {
  const editor = useEditor();
  const container = useContainer();
  const pages = editor.pages;
  const currentPageId = editor.currentPageId;
  const msg2 = useTranslation();
  const { addToast } = useToasts();
  return (0, import_jsx_runtime127.jsxs)(Sub22, { children: [
    (0, import_jsx_runtime127.jsx)(SubTrigger22, { dir: "ltr", asChild: true, children: (0, import_jsx_runtime127.jsx)(
      Button,
      {
        className: "tlui-menu__button",
        label: "context-menu.move-to-page",
        "data-testid": "menu-item.move-to-page",
        icon: "chevron-right"
      }
    ) }),
    (0, import_jsx_runtime127.jsx)(Portal23, { container, dir: "ltr", children: (0, import_jsx_runtime127.jsxs)(SubContent22, { className: "tlui-menu", sideOffset: -4, collisionPadding: 4, children: [
      (0, import_jsx_runtime127.jsx)(
        Group22,
        {
          dir: "ltr",
          className: "tlui-menu__group",
          "data-testid": `menu-item.pages`,
          children: pages.map((page) => (0, import_jsx_runtime127.jsx)(
            Item23,
            {
              disabled: currentPageId === page.id,
              onSelect: () => {
                editor.mark("move_shapes_to_page");
                editor.moveShapesToPage(editor.selectedShapeIds, page.id);
                const toPage = editor.getPage(page.id);
                if (toPage) {
                  addToast({
                    title: "Changed Page",
                    description: `Moved to ${toPage.name}.`,
                    actions: [
                      {
                        label: "Go Back",
                        type: "primary",
                        onClick: () => {
                          editor.mark("change-page");
                          editor.setCurrentPage(currentPageId);
                        }
                      }
                    ]
                  });
                }
              },
              asChild: true,
              children: (0, import_jsx_runtime127.jsx)(
                Button,
                {
                  title: page.name,
                  className: "tlui-menu__button tlui-context-menu__move-to-page__name",
                  children: (0, import_jsx_runtime127.jsx)("span", { children: page.name })
                }
              )
            },
            page.id
          ))
        },
        "pages"
      ),
      (0, import_jsx_runtime127.jsx)(
        Group22,
        {
          dir: "ltr",
          className: "tlui-menu__group",
          "data-testid": `menu-item.new-page`,
          children: (0, import_jsx_runtime127.jsx)(
            Item23,
            {
              onSelect: () => {
                const newPageId = PageRecordType.createId();
                const ids = editor.selectedShapeIds;
                editor.batch(() => {
                  editor.mark("move_shapes_to_page");
                  editor.createPage({ name: "Page", id: newPageId });
                  editor.moveShapesToPage(ids, newPageId);
                });
              },
              asChild: true,
              children: (0, import_jsx_runtime127.jsx)(
                Button,
                {
                  title: msg2("context.pages.new-page"),
                  className: "tlui-menu__button tlui-context-menu__move-to-page__name",
                  children: msg2("context.pages.new-page")
                }
              )
            },
            "new-page"
          )
        },
        "new-page"
      )
    ] }) })
  ] });
});

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/ContextMenu.mjs
var ContextMenu2 = function ContextMenu22({ children }) {
  const editor = useEditor();
  const contextTLUiMenuSchema = useContextMenuSchema();
  const cb = (0, import_react110.useCallback)(
    (isOpen) => {
      if (!isOpen) {
        const { onlySelectedShape } = editor;
        if (onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape)) {
          editor.setSelectedShapes([]);
        }
      } else {
        if (editor.instanceState.isCoarsePointer) {
          const {
            selectedShapes,
            inputs: { currentPagePoint }
          } = editor;
          const shapesAtPoint = editor.getShapesAtPoint(currentPagePoint);
          if (
            // if there are no selected shapes
            !editor.selectedShapes.length || // OR if none of the shapes at the point include the selected shape
            !shapesAtPoint.some((s) => selectedShapes.includes(s))
          ) {
            const lockedShapes = shapesAtPoint.filter((s) => editor.isShapeOrAncestorLocked(s));
            if (lockedShapes.length) {
              editor.select(...lockedShapes.map((s) => s.id));
            }
          }
        }
      }
    },
    [editor]
  );
  const container = useContainer();
  const [_, handleOpenChange] = useMenuIsOpen("context menu", cb);
  const isReadonly = useReadonly();
  const noItemsToShow = contextTLUiMenuSchema.length === 0 || isReadonly && contextTLUiMenuSchema.every((item) => !item.readonlyOk);
  const selectToolActive = useValue("isSelectToolActive", () => editor.currentToolId === "select", [
    editor
  ]);
  const disabled = !selectToolActive || noItemsToShow;
  return (0, import_jsx_runtime128.jsxs)(Root24, { dir: "ltr", onOpenChange: handleOpenChange, children: [
    (0, import_jsx_runtime128.jsx)(
      Trigger3,
      {
        onContextMenu: disabled ? preventDefault : void 0,
        dir: "ltr",
        disabled,
        children
      }
    ),
    (0, import_jsx_runtime128.jsx)(Portal23, { container, children: (0, import_jsx_runtime128.jsx)(ContextMenuContent2, {}) })
  ] });
};
function ContextMenuContent2() {
  const editor = useEditor();
  const msg2 = useTranslation();
  const menuSchema = useContextMenuSchema();
  const [_, handleSubOpenChange] = useMenuIsOpen("context menu sub");
  const isReadonly = useReadonly();
  const breakpoint = useBreakpoint();
  const container = useContainer();
  const [disableClicks, setDisableClicks] = (0, import_react110.useState)(false);
  function getContextMenuItem(editor2, item, parent, depth) {
    if (isReadonly && !item.readonlyOk)
      return null;
    switch (item.type) {
      case "custom": {
        switch (item.id) {
          case "MOVE_TO_PAGE_MENU": {
            return (0, import_jsx_runtime128.jsx)(MoveToPageMenu, {}, item.id);
          }
        }
        break;
      }
      case "group": {
        return (0, import_jsx_runtime128.jsx)(
          Group22,
          {
            dir: "ltr",
            className: (0, import_classnames26.default)("tlui-menu__group", {
              "tlui-menu__group__small": parent?.type === "submenu"
            }),
            "data-testid": `menu-item.${item.id}`,
            children: item.children.map((child) => getContextMenuItem(editor2, child, item, depth + 1))
          },
          item.id
        );
      }
      case "submenu": {
        return (0, import_jsx_runtime128.jsxs)(Sub22, { onOpenChange: handleSubOpenChange, children: [
          (0, import_jsx_runtime128.jsx)(SubTrigger22, { dir: "ltr", disabled: item.disabled, asChild: true, children: (0, import_jsx_runtime128.jsx)(
            Button,
            {
              className: "tlui-menu__button",
              label: item.label,
              "data-testid": `menu-item.${item.id}`,
              icon: "chevron-right"
            }
          ) }),
          (0, import_jsx_runtime128.jsx)(Portal23, { container, dir: "ltr", children: (0, import_jsx_runtime128.jsx)(SubContent22, { className: "tlui-menu", sideOffset: -4, collisionPadding: 4, children: item.children.map((child) => getContextMenuItem(editor2, child, item, depth + 1)) }) })
        ] }, item.id);
      }
      case "item": {
        if (isReadonly && !item.readonlyOk)
          return null;
        const { id, checkbox, contextMenuLabel, label, onSelect, kbd: kbd2, icon } = item.actionItem;
        const labelToUse = contextMenuLabel ?? label;
        const labelStr = labelToUse ? msg2(labelToUse) : void 0;
        if (checkbox) {
          return (0, import_jsx_runtime128.jsxs)(
            CheckboxItem22,
            {
              className: "tlui-button tlui-menu__button tlui-menu__checkbox-item",
              dir: "ltr",
              disabled: item.disabled,
              onSelect: (e) => {
                onSelect("context-menu");
                preventDefault(e);
              },
              title: labelStr ? labelStr : void 0,
              checked: item.checked,
              children: [
                (0, import_jsx_runtime128.jsx)(
                  "div",
                  {
                    className: "tlui-menu__checkbox-item__check",
                    style: {
                      transformOrigin: "75% center",
                      transform: `scale(${item.checked ? 1 : 0.5})`,
                      opacity: item.checked ? 1 : 0.5
                    },
                    children: (0, import_jsx_runtime128.jsx)(Icon, { small: true, icon: item.checked ? "check" : "checkbox-empty" })
                  }
                ),
                labelStr && (0, import_jsx_runtime128.jsx)("span", { children: labelStr }),
                kbd2 && (0, import_jsx_runtime128.jsx)(Kbd, { children: kbd2 })
              ]
            },
            id
          );
        }
        return (0, import_jsx_runtime128.jsx)(Item23, { dir: "ltr", asChild: true, children: (0, import_jsx_runtime128.jsx)(
          Button,
          {
            className: "tlui-menu__button",
            "data-testid": `menu-item.${id}`,
            kbd: kbd2,
            label: labelToUse,
            disabled: item.disabled,
            iconLeft: breakpoint < 3 && depth > 2 ? icon : void 0,
            onClick: () => {
              if (disableClicks) {
                setDisableClicks(false);
              } else {
                onSelect("context-menu");
              }
            }
          }
        ) }, id);
      }
    }
  }
  return (0, import_jsx_runtime128.jsx)(Portal23, { dir: "ltr", container, children: (0, import_jsx_runtime128.jsx)(
    Content23,
    {
      className: "tlui-menu scrollable",
      alignOffset: -4,
      collisionPadding: 4,
      onContextMenu: preventDefault,
      children: menuSchema.map((item) => getContextMenuItem(editor, item, null, 0))
    }
  ) });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/usePreloadAssets.mjs
var import_react111 = __toESM(require_react(), 1);
var PreloadStatus = ((PreloadStatus2) => {
  PreloadStatus2[PreloadStatus2["SUCCESS"] = 0] = "SUCCESS";
  PreloadStatus2[PreloadStatus2["FAILED"] = 1] = "FAILED";
  PreloadStatus2[PreloadStatus2["WAITING"] = 2] = "WAITING";
  return PreloadStatus2;
})(PreloadStatus || {});
var usePreloadFont = (id, font) => {
  const [state, setState] = (0, import_react111.useState)(
    2
    /* WAITING */
  );
  (0, import_react111.useEffect)(() => {
    const {
      url,
      style = "normal",
      weight = "500",
      display,
      featureSettings,
      stretch,
      unicodeRange,
      variant
    } = font;
    let cancelled = false;
    setState(
      2
      /* WAITING */
    );
    const descriptors = {
      style,
      weight,
      display,
      featureSettings,
      stretch,
      unicodeRange,
      variant
    };
    const fontInstance = new FontFace(id, `url(${url})`, descriptors);
    fontInstance.load().then(() => {
      if (cancelled)
        return;
      document.fonts.add(fontInstance);
      setState(
        0
        /* SUCCESS */
      );
    }).catch((err) => {
      if (cancelled)
        return;
      console.error(err);
      setState(
        1
        /* FAILED */
      );
    });
    fontInstance.$$_url = url;
    fontInstance.$$_fontface = `
@font-face {
	font-family: ${fontInstance.family};
	font-stretch: ${fontInstance.stretch};
	font-weight: ${fontInstance.weight};
	font-style: ${fontInstance.style};
	src: url("${url}") format("woff2")
}`;
    return () => {
      document.fonts.delete(fontInstance);
      cancelled = true;
    };
  }, [id, font]);
  return state;
};
function getTypefaces(assetUrls) {
  return {
    draw: { url: assetUrls.fonts.draw },
    serif: { url: assetUrls.fonts.serif },
    sansSerif: { url: assetUrls.fonts.sansSerif },
    monospace: { url: assetUrls.fonts.monospace }
  };
}
function usePreloadAssets(assetUrls) {
  const typefaces = (0, import_react111.useMemo)(() => getTypefaces(assetUrls), [assetUrls]);
  const results = [
    usePreloadFont("tldraw_draw", typefaces.draw),
    usePreloadFont("tldraw_serif", typefaces.serif),
    usePreloadFont("tldraw_sans", typefaces.sansSerif),
    usePreloadFont("tldraw_mono", typefaces.monospace)
  ];
  return {
    // If any of the results have errored, then preloading has failed
    error: results.some(
      (result) => result === 1
      /* FAILED */
    ),
    // If any of the results are waiting, then we're not done yet
    done: !results.some(
      (result) => result === 2
      /* WAITING */
    )
  };
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/Tldraw.mjs
function Tldraw(props) {
  const {
    children,
    maxImageDimension,
    maxAssetSize,
    acceptedImageMimeTypes,
    acceptedVideoMimeTypes,
    onMount,
    ...rest
  } = props;
  const withDefaults = {
    initialState: "select",
    ...rest,
    components: (0, import_react112.useMemo)(
      () => ({
        Scribble: TldrawScribble,
        CollaboratorScribble: TldrawScribble,
        SelectionForeground: TldrawSelectionForeground,
        SelectionBackground: TldrawSelectionBackground,
        Handles: TldrawHandles,
        HoveredShapeIndicator: TldrawHoveredShapeIndicator,
        ...rest.components
      }),
      [rest.components]
    ),
    shapeUtils: (0, import_react112.useMemo)(
      () => [...defaultShapeUtils, ...rest.shapeUtils ?? []],
      [rest.shapeUtils]
    ),
    tools: (0, import_react112.useMemo)(
      () => [...defaultTools, ...defaultShapeTools, ...rest.tools ?? []],
      [rest.tools]
    )
  };
  const assets = useDefaultEditorAssetsWithOverrides(rest.assetUrls);
  const { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets);
  if (preloadingError) {
    return (0, import_jsx_runtime129.jsx)(ErrorScreen, { children: "Could not load assets. Please refresh the page." });
  }
  if (!preloadingComplete) {
    return (0, import_jsx_runtime129.jsx)(LoadingScreen, { children: "Loading assets..." });
  }
  return (0, import_jsx_runtime129.jsx)(TldrawEditor, { ...withDefaults, children: (0, import_jsx_runtime129.jsxs)(TldrawUi, { ...withDefaults, children: [
    (0, import_jsx_runtime129.jsx)(ContextMenu2, { children: (0, import_jsx_runtime129.jsx)(Canvas, {}) }),
    (0, import_jsx_runtime129.jsx)(
      InsideOfEditorContext,
      {
        maxImageDimension,
        maxAssetSize,
        acceptedImageMimeTypes,
        acceptedVideoMimeTypes,
        onMount
      }
    ),
    children
  ] }) });
}
function InsideOfEditorContext({
  maxImageDimension = 1e3,
  maxAssetSize = 10 * 1024 * 1024,
  // 10mb
  acceptedImageMimeTypes = ["image/jpeg", "image/png", "image/gif", "image/svg+xml"],
  acceptedVideoMimeTypes = ["video/mp4", "video/quicktime"],
  onMount
}) {
  const editor = useEditor();
  const onMountEvent = useEvent2((editor2) => {
    const unsubs = [];
    unsubs.push(...registerDefaultSideEffects(editor2));
    registerDefaultExternalContentHandlers(editor2, {
      maxImageDimension,
      maxAssetSize,
      acceptedImageMimeTypes,
      acceptedVideoMimeTypes
    });
    unsubs.push(onMount?.(editor2));
    return () => {
      unsubs.forEach((fn) => fn?.());
    };
  });
  (0, import_react112.useLayoutEffect)(() => {
    if (editor)
      return onMountEvent?.(editor);
  }, [editor, onMountEvent]);
  return null;
}
function useEvent2(handler) {
  const handlerRef = (0, import_react112.useRef)();
  (0, import_react112.useLayoutEffect)(() => {
    handlerRef.current = handler;
  });
  (0, import_react112.useDebugValue)(handler);
  return (0, import_react112.useCallback)((...args) => {
    const fn = handlerRef.current;
    assert(fn, "fn does not exist");
    return fn(...args);
  }, []);
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs
var import_jsx_runtime130 = __toESM(require_jsx_runtime(), 1);
var import_classnames27 = __toESM(require_classnames(), 1);
var import_react113 = __toESM(require_react(), 1);
function OfflineIndicator() {
  const msg2 = useTranslation();
  const rContainer = (0, import_react113.useRef)(null);
  return (0, import_jsx_runtime130.jsxs)("div", { className: (0, import_classnames27.default)("tlui-offline-indicator"), ref: rContainer, children: [
    msg2("status.offline"),
    (0, import_jsx_runtime130.jsx)(Icon, { "aria-label": "offline", icon: "status-offline", small: true })
  ] });
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/buildFromV1Document.mjs
var TLDRAW_V1_VERSION = 15.5;
function buildFromV1Document(editor, document2) {
  editor.batch(() => {
    document2 = migrate2(document2, TLDRAW_V1_VERSION);
    editor.cancel().cancel().cancel().cancel();
    const firstPageId = editor.pages[0].id;
    editor.setCurrentPage(firstPageId);
    for (const page of editor.pages.slice(1)) {
      editor.deletePage(page.id);
    }
    editor.selectAll();
    editor.deleteShapes(editor.selectedShapeIds);
    const v1AssetIdsToV2AssetIds = /* @__PURE__ */ new Map();
    Object.values(document2.assets ?? {}).forEach((v1Asset) => {
      switch (v1Asset.type) {
        case "image": {
          const assetId = AssetRecordType.createId();
          v1AssetIdsToV2AssetIds.set(v1Asset.id, assetId);
          const placeholderAsset = {
            id: assetId,
            typeName: "asset",
            type: "image",
            props: {
              w: coerceDimension(v1Asset.size[0]),
              h: coerceDimension(v1Asset.size[1]),
              name: v1Asset.fileName ?? "Untitled",
              isAnimated: false,
              mimeType: null,
              src: v1Asset.src
            },
            meta: {}
          };
          editor.createAssets([placeholderAsset]);
          tryMigrateAsset(editor, placeholderAsset);
          break;
        }
        case "video":
          {
            const assetId = AssetRecordType.createId();
            v1AssetIdsToV2AssetIds.set(v1Asset.id, assetId);
            editor.createAssets([
              {
                id: assetId,
                typeName: "asset",
                type: "video",
                props: {
                  w: coerceDimension(v1Asset.size[0]),
                  h: coerceDimension(v1Asset.size[1]),
                  name: v1Asset.fileName ?? "Untitled",
                  isAnimated: true,
                  mimeType: null,
                  src: v1Asset.src
                },
                meta: {}
              }
            ]);
          }
          break;
      }
    });
    const v1PageIdsToV2PageIds = /* @__PURE__ */ new Map();
    Object.values(document2.pages ?? {}).sort((a, b) => (a.childIndex ?? 1) < (b.childIndex ?? 1) ? -1 : 1).forEach((v1Page, i) => {
      if (i === 0) {
        v1PageIdsToV2PageIds.set(v1Page.id, editor.currentPageId);
      } else {
        const pageId = PageRecordType.createId();
        v1PageIdsToV2PageIds.set(v1Page.id, pageId);
        editor.createPage({ name: v1Page.name ?? "Page", id: pageId });
      }
    });
    Object.values(document2.pages ?? {}).sort((a, b) => (a.childIndex ?? 1) < (b.childIndex ?? 1) ? -1 : 1).forEach((v1Page) => {
      editor.setCurrentPage(v1PageIdsToV2PageIds.get(v1Page.id));
      const v1ShapeIdsToV2ShapeIds = /* @__PURE__ */ new Map();
      const v1GroupShapeIdsToV1ChildIds = /* @__PURE__ */ new Map();
      const v1Shapes = Object.values(v1Page.shapes ?? {}).sort((a, b) => a.childIndex < b.childIndex ? -1 : 1).slice(0, MAX_SHAPES_PER_PAGE);
      v1Shapes.forEach((v1Shape) => {
        if (v1Shape.type !== "group")
          return;
        const shapeId = createShapeId();
        v1ShapeIdsToV2ShapeIds.set(v1Shape.id, shapeId);
        v1GroupShapeIdsToV1ChildIds.set(v1Shape.id, []);
      });
      function decideNotToCreateShape(v1Shape) {
        v1ShapeIdsToV2ShapeIds.delete(v1Shape.id);
        const v1GroupParent = v1GroupShapeIdsToV1ChildIds.has(v1Shape.parentId);
        if (v1GroupParent) {
          const ids = v1GroupShapeIdsToV1ChildIds.get(v1Shape.parentId).filter((id) => id !== v1Shape.id);
          v1GroupShapeIdsToV1ChildIds.set(v1Shape.parentId, ids);
        }
      }
      v1Shapes.forEach((v1Shape) => {
        if (v1Shape.type === "group") {
          return;
        }
        const shapeId = createShapeId();
        v1ShapeIdsToV2ShapeIds.set(v1Shape.id, shapeId);
        if (v1Shape.parentId !== v1Page.id) {
          if (v1GroupShapeIdsToV1ChildIds.has(v1Shape.parentId)) {
            v1GroupShapeIdsToV1ChildIds.get(v1Shape.parentId).push(v1Shape.id);
          } else {
            console.warn("parent does not exist", v1Shape);
          }
        }
        const parentId = v1PageIdsToV2PageIds.get(v1Page.id);
        const inCommon = {
          id: shapeId,
          parentId,
          x: coerceNumber(v1Shape.point[0]),
          y: coerceNumber(v1Shape.point[1]),
          rotation: 0,
          isLocked: !!v1Shape.isLocked
        };
        switch (v1Shape.type) {
          case "sticky": {
            editor.createShapes([
              {
                ...inCommon,
                type: "note",
                props: {
                  text: v1Shape.text ?? "",
                  color: getV2Color(v1Shape.style.color),
                  size: getV2Size(v1Shape.style.size),
                  font: getV2Font(v1Shape.style.font),
                  align: getV2Align(v1Shape.style.textAlign)
                }
              }
            ]);
            break;
          }
          case "rectangle": {
            editor.createShapes([
              {
                ...inCommon,
                type: "geo",
                props: {
                  geo: "rectangle",
                  w: coerceDimension(v1Shape.size[0]),
                  h: coerceDimension(v1Shape.size[1]),
                  text: v1Shape.label ?? "",
                  fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
                  labelColor: getV2Color(v1Shape.style.color),
                  color: getV2Color(v1Shape.style.color),
                  size: getV2Size(v1Shape.style.size),
                  font: getV2Font(v1Shape.style.font),
                  dash: getV2Dash(v1Shape.style.dash),
                  align: "middle"
                }
              }
            ]);
            const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id);
            editor.updateShapes([
              {
                id: inCommon.id,
                type: "geo",
                props: {
                  text: v1Shape.label ?? ""
                }
              }
            ]);
            if (pageBoundsBeforeLabel.width === pageBoundsBeforeLabel.height) {
              const shape = editor.getShape(inCommon.id);
              const { growY } = shape.props;
              const w = coerceDimension(shape.props.w);
              const h = coerceDimension(shape.props.h);
              const newW = w + growY / 2;
              const newH = h + growY / 2;
              editor.updateShapes([
                {
                  id: inCommon.id,
                  type: "geo",
                  x: coerceNumber(shape.x) - (newW - w) / 2,
                  y: coerceNumber(shape.y) - (newH - h) / 2,
                  props: {
                    w: newW,
                    h: newH
                  }
                }
              ]);
            }
            break;
          }
          case "triangle": {
            editor.createShapes([
              {
                ...inCommon,
                type: "geo",
                props: {
                  geo: "triangle",
                  w: coerceDimension(v1Shape.size[0]),
                  h: coerceDimension(v1Shape.size[1]),
                  fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
                  labelColor: getV2Color(v1Shape.style.color),
                  color: getV2Color(v1Shape.style.color),
                  size: getV2Size(v1Shape.style.size),
                  font: getV2Font(v1Shape.style.font),
                  dash: getV2Dash(v1Shape.style.dash),
                  align: "middle"
                }
              }
            ]);
            const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id);
            editor.updateShapes([
              {
                id: inCommon.id,
                type: "geo",
                props: {
                  text: v1Shape.label ?? ""
                }
              }
            ]);
            if (pageBoundsBeforeLabel.width === pageBoundsBeforeLabel.height) {
              const shape = editor.getShape(inCommon.id);
              const { growY } = shape.props;
              const w = coerceDimension(shape.props.w);
              const h = coerceDimension(shape.props.h);
              const newW = w + growY / 2;
              const newH = h + growY / 2;
              editor.updateShapes([
                {
                  id: inCommon.id,
                  type: "geo",
                  x: coerceNumber(shape.x) - (newW - w) / 2,
                  y: coerceNumber(shape.y) - (newH - h) / 2,
                  props: {
                    w: newW,
                    h: newH
                  }
                }
              ]);
            }
            break;
          }
          case "ellipse": {
            editor.createShapes([
              {
                ...inCommon,
                type: "geo",
                props: {
                  geo: "ellipse",
                  w: coerceDimension(v1Shape.radius[0]) * 2,
                  h: coerceDimension(v1Shape.radius[1]) * 2,
                  fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
                  labelColor: getV2Color(v1Shape.style.color),
                  color: getV2Color(v1Shape.style.color),
                  size: getV2Size(v1Shape.style.size),
                  font: getV2Font(v1Shape.style.font),
                  dash: getV2Dash(v1Shape.style.dash),
                  align: "middle"
                }
              }
            ]);
            const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id);
            editor.updateShapes([
              {
                id: inCommon.id,
                type: "geo",
                props: {
                  text: v1Shape.label ?? ""
                }
              }
            ]);
            if (pageBoundsBeforeLabel.width === pageBoundsBeforeLabel.height) {
              const shape = editor.getShape(inCommon.id);
              const { growY } = shape.props;
              const w = coerceDimension(shape.props.w);
              const h = coerceDimension(shape.props.h);
              const newW = w + growY / 2;
              const newH = h + growY / 2;
              editor.updateShapes([
                {
                  id: inCommon.id,
                  type: "geo",
                  x: coerceNumber(shape.x) - (newW - w) / 2,
                  y: coerceNumber(shape.y) - (newH - h) / 2,
                  props: {
                    w: newW,
                    h: newH
                  }
                }
              ]);
            }
            break;
          }
          case "draw": {
            if (v1Shape.points.length === 0) {
              decideNotToCreateShape(v1Shape);
              break;
            }
            editor.createShapes([
              {
                ...inCommon,
                type: "draw",
                props: {
                  fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
                  color: getV2Color(v1Shape.style.color),
                  size: getV2Size(v1Shape.style.size),
                  dash: getV2Dash(v1Shape.style.dash),
                  isPen: false,
                  isComplete: v1Shape.isComplete,
                  segments: [{ type: "free", points: v1Shape.points.map(getV2Point) }]
                }
              }
            ]);
            break;
          }
          case "arrow": {
            const v1Bend = coerceNumber(v1Shape.bend);
            const v1Start = getV2Point(v1Shape.handles.start.point);
            const v1End = getV2Point(v1Shape.handles.end.point);
            const dist = Vec2d.Dist(v1Start, v1End);
            const v2Bend = dist * -v1Bend / 2;
            editor.createShapes([
              {
                ...inCommon,
                type: "arrow",
                props: {
                  text: v1Shape.label ?? "",
                  color: getV2Color(v1Shape.style.color),
                  labelColor: getV2Color(v1Shape.style.color),
                  size: getV2Size(v1Shape.style.size),
                  font: getV2Font(v1Shape.style.font),
                  dash: getV2Dash(v1Shape.style.dash),
                  arrowheadStart: getV2Arrowhead(v1Shape.decorations?.start),
                  arrowheadEnd: getV2Arrowhead(v1Shape.decorations?.end),
                  start: {
                    type: "point",
                    x: coerceNumber(v1Shape.handles.start.point[0]),
                    y: coerceNumber(v1Shape.handles.start.point[1])
                  },
                  end: {
                    type: "point",
                    x: coerceNumber(v1Shape.handles.end.point[0]),
                    y: coerceNumber(v1Shape.handles.end.point[1])
                  },
                  bend: v2Bend
                }
              }
            ]);
            break;
          }
          case "text": {
            editor.createShapes([
              {
                ...inCommon,
                type: "text",
                props: {
                  text: v1Shape.text ?? " ",
                  color: getV2Color(v1Shape.style.color),
                  size: getV2TextSize(v1Shape.style.size),
                  font: getV2Font(v1Shape.style.font),
                  align: getV2Align(v1Shape.style.textAlign),
                  scale: v1Shape.style.scale ?? 1
                }
              }
            ]);
            break;
          }
          case "image": {
            const assetId = v1AssetIdsToV2AssetIds.get(v1Shape.assetId);
            if (!assetId) {
              console.warn("Could not find asset id", v1Shape.assetId);
              return;
            }
            editor.createShapes([
              {
                ...inCommon,
                type: "image",
                props: {
                  w: coerceDimension(v1Shape.size[0]),
                  h: coerceDimension(v1Shape.size[1]),
                  assetId
                }
              }
            ]);
            break;
          }
          case "video": {
            const assetId = v1AssetIdsToV2AssetIds.get(v1Shape.assetId);
            if (!assetId) {
              console.warn("Could not find asset id", v1Shape.assetId);
              return;
            }
            editor.createShapes([
              {
                ...inCommon,
                type: "video",
                props: {
                  w: coerceDimension(v1Shape.size[0]),
                  h: coerceDimension(v1Shape.size[1]),
                  assetId
                }
              }
            ]);
            break;
          }
        }
        const rotation = coerceNumber(v1Shape.rotation);
        if (rotation !== 0) {
          editor.select(shapeId);
          editor.rotateShapesBy([shapeId], rotation);
        }
      });
      v1GroupShapeIdsToV1ChildIds.forEach((v1ChildIds, v1GroupId) => {
        const v2ChildShapeIds = v1ChildIds.map((id) => v1ShapeIdsToV2ShapeIds.get(id));
        const v2GroupId = v1ShapeIdsToV2ShapeIds.get(v1GroupId);
        editor.groupShapes(v2ChildShapeIds, v2GroupId);
        const v1Group = v1Page.shapes[v1GroupId];
        const rotation = coerceNumber(v1Group.rotation);
        if (rotation !== 0) {
          editor.select(v2GroupId);
          editor.rotateShapesBy([v2GroupId], rotation);
        }
      });
      v1Shapes.forEach((v1Shape) => {
        if (v1Shape.type !== "arrow") {
          return;
        }
        const v2ShapeId = v1ShapeIdsToV2ShapeIds.get(v1Shape.id);
        const util = editor.getShapeUtil("arrow");
        editor.inputs.ctrlKey = false;
        for (const handleId of ["start", "end"]) {
          const bindingId = v1Shape.handles[handleId].bindingId;
          if (bindingId) {
            const binding = v1Page.bindings[bindingId];
            if (!binding) {
              continue;
            }
            const targetId = v1ShapeIdsToV2ShapeIds.get(binding.toId);
            const targetShape = editor.getShape(targetId);
            if (!targetShape)
              continue;
            if (targetId) {
              const bounds2 = editor.getShapePageBounds(targetId);
              const v2ShapeFresh = editor.getShape(v2ShapeId);
              const nx = clamp((coerceNumber(binding.point[0]) + 0.5) / 2, 0.2, 0.8);
              const ny = clamp((coerceNumber(binding.point[1]) + 0.5) / 2, 0.2, 0.8);
              const point = editor.getPointInShapeSpace(v2ShapeFresh, {
                x: bounds2.minX + bounds2.width * nx,
                y: bounds2.minY + bounds2.height * ny
              });
              const handles = editor.getShapeHandles(v2ShapeFresh);
              const change = util.onHandleChange(v2ShapeFresh, {
                handle: {
                  ...handles.find((h) => h.id === handleId),
                  x: point.x,
                  y: point.y
                },
                isPrecise: point.x !== 0.5 || point.y !== 0.5
              });
              if (change) {
                if (change.props?.[handleId]) {
                  const terminal = change.props?.[handleId];
                  if (terminal.type === "binding") {
                    terminal.isExact = binding.distance === 0;
                    if (terminal.boundShapeId !== targetId) {
                      console.warn("Hit the wrong shape!");
                      terminal.boundShapeId = targetId;
                      terminal.normalizedAnchor = { x: 0.5, y: 0.5 };
                    }
                  }
                }
                editor.updateShapes([change]);
              }
            }
          }
        }
      });
    });
    editor.setCurrentPage(firstPageId);
    editor.history.clear();
    editor.selectNone();
    editor.updateViewportScreenBounds();
    const bounds = editor.currentPageBounds;
    if (bounds) {
      editor.zoomToBounds(bounds, 1);
    }
  });
}
function coerceNumber(n) {
  if (typeof n !== "number")
    return 0;
  if (Number.isNaN(n))
    return 0;
  if (!Number.isFinite(n))
    return 0;
  return n;
}
function coerceDimension(d) {
  const n = coerceNumber(d);
  if (n <= 0)
    return 1;
  return n;
}
async function tryMigrateAsset(editor, placeholderAsset) {
  try {
    if (placeholderAsset.type === "bookmark" || !placeholderAsset.props.src)
      return;
    const response = await fetch(placeholderAsset.props.src);
    if (!response.ok)
      return;
    const file = new File([await response.blob()], placeholderAsset.props.name, {
      type: response.headers.get("content-type") ?? placeholderAsset.props.mimeType ?? void 0
    });
    const newAsset = await editor.getAssetForExternalContent({ type: "file", file });
    if (!newAsset)
      throw new Error("Could not get asset for external content");
    if (newAsset.type === "bookmark")
      return;
    editor.updateAssets([
      {
        id: placeholderAsset.id,
        type: placeholderAsset.type,
        props: {
          ...newAsset.props,
          name: placeholderAsset.props.name
        }
      }
    ]);
  } catch (err) {
  }
}
function migrate2(document2, newVersion) {
  const { version: version2 = 0 } = document2;
  if (!document2.assets) {
    document2.assets = {};
  }
  const assetIdsInUse = /* @__PURE__ */ new Set();
  Object.values(document2.pages).forEach(
    (page) => Object.values(page.shapes).forEach((shape) => {
      const { parentId, children, assetId } = shape;
      if (assetId) {
        assetIdsInUse.add(assetId);
      }
      if (parentId !== page.id && !page.shapes[parentId]) {
        console.warn("Encountered a shape with a missing parent!");
        shape.parentId = page.id;
      }
      if (shape.type === "group" && children) {
        children.forEach((childId) => {
          if (!page.shapes[childId]) {
            console.warn("Encountered a parent with a missing child!", shape.id, childId);
            children?.splice(children.indexOf(childId), 1);
          }
        });
      }
    })
  );
  Object.keys(document2.assets).forEach((assetId) => {
    if (!assetIdsInUse.has(assetId)) {
      delete document2.assets[assetId];
    }
  });
  if (version2 !== newVersion) {
    if (version2 < 14) {
      Object.values(document2.pages).forEach((page) => {
        Object.values(page.shapes).filter(
          (shape) => shape.type === "text"
          /* Text */
        ).forEach((shape) => {
          if (shape.style.font === void 0) {
            ;
            shape.style.font === "script";
          }
        });
      });
    }
    if (version2 <= 13) {
      Object.values(document2.pages).forEach((page) => {
        Object.values(page.bindings).forEach((binding) => {
          Object.assign(binding, binding.meta);
        });
        Object.values(page.shapes).forEach((shape) => {
          Object.entries(shape.style).forEach(([id, style]) => {
            if (typeof style === "string") {
              shape.style[id] = style.toLowerCase();
            }
          });
          if (shape.type === "arrow") {
            if (shape.decorations) {
              Object.entries(shape.decorations).forEach(([id, decoration]) => {
                if (decoration === "Arrow") {
                  shape.decorations = {
                    ...shape.decorations,
                    [id]: "arrow"
                    /* Arrow */
                  };
                }
              });
            }
          }
        });
      });
    }
    if (version2 <= 13.1 && document2.name == null) {
      document2.name = "New Document";
    }
    if (version2 < 15 && document2.assets == null) {
      document2.assets = {};
    }
    Object.values(document2.pages).forEach((page) => {
      Object.values(page.shapes).forEach((shape) => {
        if (version2 < 15.2) {
          if ((shape.type === "image" || shape.type === "video") && shape.style.isFilled == null) {
            shape.style.isFilled = true;
          }
        }
        if (version2 < 15.3) {
          if (shape.type === "rectangle" || shape.type === "triangle" || shape.type === "ellipse" || shape.type === "arrow") {
            if ("text" in shape && typeof shape.text === "string") {
              shape.label = shape.text;
            }
            if (!shape.label) {
              shape.label = "";
            }
            if (!shape.labelPoint) {
              shape.labelPoint = [0.5, 0.5];
            }
          }
        }
      });
    });
  }
  Object.values(document2.pageStates).forEach((pageState) => {
    pageState.selectedIds = pageState.selectedIds.filter((id) => {
      return document2.pages[pageState.id].shapes[id] !== void 0;
    });
    pageState.bindingId = void 0;
    pageState.editingId = void 0;
    pageState.hoveredId = void 0;
    pageState.pointedId = void 0;
  });
  document2.version = newVersion;
  return document2;
}
var TDShapeType = ((TDShapeType2) => {
  TDShapeType2["Sticky"] = "sticky";
  TDShapeType2["Ellipse"] = "ellipse";
  TDShapeType2["Rectangle"] = "rectangle";
  TDShapeType2["Triangle"] = "triangle";
  TDShapeType2["Draw"] = "draw";
  TDShapeType2["Arrow"] = "arrow";
  TDShapeType2["Text"] = "text";
  TDShapeType2["Group"] = "group";
  TDShapeType2["Image"] = "image";
  TDShapeType2["Video"] = "video";
  return TDShapeType2;
})(TDShapeType || {});
var ColorStyle = ((ColorStyle2) => {
  ColorStyle2["White"] = "white";
  ColorStyle2["LightGray"] = "lightGray";
  ColorStyle2["Gray"] = "gray";
  ColorStyle2["Black"] = "black";
  ColorStyle2["Green"] = "green";
  ColorStyle2["Cyan"] = "cyan";
  ColorStyle2["Blue"] = "blue";
  ColorStyle2["Indigo"] = "indigo";
  ColorStyle2["Violet"] = "violet";
  ColorStyle2["Red"] = "red";
  ColorStyle2["Orange"] = "orange";
  ColorStyle2["Yellow"] = "yellow";
  return ColorStyle2;
})(ColorStyle || {});
var SizeStyle = ((SizeStyle2) => {
  SizeStyle2["Small"] = "small";
  SizeStyle2["Medium"] = "medium";
  SizeStyle2["Large"] = "large";
  return SizeStyle2;
})(SizeStyle || {});
var DashStyle = ((DashStyle2) => {
  DashStyle2["Draw"] = "draw";
  DashStyle2["Solid"] = "solid";
  DashStyle2["Dashed"] = "dashed";
  DashStyle2["Dotted"] = "dotted";
  return DashStyle2;
})(DashStyle || {});
var AlignStyle = ((AlignStyle2) => {
  AlignStyle2["Start"] = "start";
  AlignStyle2["Middle"] = "middle";
  AlignStyle2["End"] = "end";
  AlignStyle2["Justify"] = "justify";
  return AlignStyle2;
})(AlignStyle || {});
var FontStyle = ((FontStyle2) => {
  FontStyle2["Script"] = "script";
  FontStyle2["Sans"] = "sans";
  FontStyle2["Serif"] = "serif";
  FontStyle2["Mono"] = "mono";
  return FontStyle2;
})(FontStyle || {});
var Decoration = ((Decoration2) => {
  Decoration2["Arrow"] = "arrow";
  return Decoration2;
})(Decoration || {});
var TDAssetType = ((TDAssetType2) => {
  TDAssetType2["Image"] = "image";
  TDAssetType2["Video"] = "video";
  return TDAssetType2;
})(TDAssetType || {});
var v1ColorsToV2Colors = {
  [
    "white"
    /* White */
  ]: "black",
  [
    "black"
    /* Black */
  ]: "black",
  [
    "lightGray"
    /* LightGray */
  ]: "grey",
  [
    "gray"
    /* Gray */
  ]: "grey",
  [
    "green"
    /* Green */
  ]: "light-green",
  [
    "cyan"
    /* Cyan */
  ]: "green",
  [
    "blue"
    /* Blue */
  ]: "light-blue",
  [
    "indigo"
    /* Indigo */
  ]: "blue",
  [
    "orange"
    /* Orange */
  ]: "orange",
  [
    "yellow"
    /* Yellow */
  ]: "yellow",
  [
    "red"
    /* Red */
  ]: "red",
  [
    "violet"
    /* Violet */
  ]: "light-violet"
};
var v1FontsToV2Fonts = {
  [
    "mono"
    /* Mono */
  ]: "mono",
  [
    "sans"
    /* Sans */
  ]: "sans",
  [
    "script"
    /* Script */
  ]: "draw",
  [
    "serif"
    /* Serif */
  ]: "serif"
};
var v1AlignsToV2Aligns = {
  [
    "start"
    /* Start */
  ]: "start",
  [
    "middle"
    /* Middle */
  ]: "middle",
  [
    "end"
    /* End */
  ]: "end",
  [
    "justify"
    /* Justify */
  ]: "start"
};
var v1TextSizesToV2TextSizes = {
  [
    "small"
    /* Small */
  ]: "s",
  [
    "medium"
    /* Medium */
  ]: "l",
  [
    "large"
    /* Large */
  ]: "xl"
};
var v1SizesToV2Sizes = {
  [
    "small"
    /* Small */
  ]: "m",
  [
    "medium"
    /* Medium */
  ]: "l",
  [
    "large"
    /* Large */
  ]: "xl"
};
var v1DashesToV2Dashes = {
  [
    "solid"
    /* Solid */
  ]: "solid",
  [
    "dashed"
    /* Dashed */
  ]: "dashed",
  [
    "dotted"
    /* Dotted */
  ]: "dotted",
  [
    "draw"
    /* Draw */
  ]: "draw"
};
function getV2Color(color) {
  return color ? v1ColorsToV2Colors[color] ?? "black" : "black";
}
function getV2Font(font) {
  return font ? v1FontsToV2Fonts[font] ?? "draw" : "draw";
}
function getV2Align(align) {
  return align ? v1AlignsToV2Aligns[align] ?? "middle" : "middle";
}
function getV2TextSize(size2) {
  return size2 ? v1TextSizesToV2TextSizes[size2] ?? "m" : "m";
}
function getV2Size(size2) {
  return size2 ? v1SizesToV2Sizes[size2] ?? "l" : "l";
}
function getV2Dash(dash) {
  return dash ? v1DashesToV2Dashes[dash] ?? "draw" : "draw";
}
function getV2Point(point) {
  return {
    x: coerceNumber(point[0]),
    y: coerceNumber(point[1]),
    z: point[2] == null ? 0.5 : coerceNumber(point[2])
  };
}
function getV2Arrowhead(decoration) {
  return decoration === "arrow" ? "arrow" : "none";
}
function getV2Fill(isFilled, color) {
  return isFilled ? color === "black" || color === "white" ? "semi" : "solid" : "none";
}

// node_modules/.deno/@tldraw+tldraw@2.0.0-alpha.17/node_modules/@tldraw/tldraw/dist-esm/lib/utils/file.mjs
var TLDRAW_FILE_MIMETYPE = "application/vnd.tldraw+json";
var TLDRAW_FILE_EXTENSION = ".tldr";
var LATEST_TLDRAW_FILE_FORMAT_VERSION = 1;
var tldrawFileValidator = validation_exports.object({
  tldrawFileFormatVersion: validation_exports.nonZeroInteger,
  schema: validation_exports.object({
    schemaVersion: validation_exports.positiveInteger,
    storeVersion: validation_exports.positiveInteger,
    recordVersions: validation_exports.dict(
      validation_exports.string,
      validation_exports.object({
        version: validation_exports.positiveInteger,
        subTypeVersions: validation_exports.dict(validation_exports.string, validation_exports.positiveInteger).optional(),
        subTypeKey: validation_exports.string.optional()
      })
    )
  }),
  records: validation_exports.arrayOf(
    validation_exports.object({
      id: validation_exports.string,
      typeName: validation_exports.string
    }).allowUnknownProperties()
  )
});
function isV1File(data) {
  try {
    if (data.document?.version) {
      return true;
    }
    return false;
  } catch (e) {
    return false;
  }
}
function parseTldrawJsonFile({
  json,
  schema
}) {
  let data;
  try {
    data = tldrawFileValidator.validate(JSON.parse(json));
  } catch (e) {
    try {
      data = JSON.parse(json);
      if (isV1File(data)) {
        return Result.err({ type: "v1File", data });
      }
    } catch (e2) {
    }
    return Result.err({ type: "notATldrawFile", cause: e });
  }
  if (data.tldrawFileFormatVersion > LATEST_TLDRAW_FILE_FORMAT_VERSION) {
    return Result.err({
      type: "fileFormatVersionTooNew",
      version: data.tldrawFileFormatVersion
    });
  }
  let migrationResult;
  try {
    const storeSnapshot = Object.fromEntries(data.records.map((r) => [r.id, r]));
    migrationResult = schema.migrateStoreSnapshot({ store: storeSnapshot, schema: data.schema });
  } catch (e) {
    return Result.err({ type: "invalidRecords", cause: e });
  }
  if (migrationResult.type === "error") {
    return Result.err({ type: "migrationFailed", reason: migrationResult.reason });
  }
  try {
    return Result.ok(
      createTLStore({
        initialData: migrationResult.value,
        schema
      })
    );
  } catch (e) {
    return Result.err({ type: "invalidRecords", cause: e });
  }
}
async function serializeTldrawJson(store) {
  const records = [];
  const usedAssets = /* @__PURE__ */ new Set();
  const assets = [];
  for (const record of store.allRecords()) {
    switch (record.typeName) {
      case "asset":
        if (record.type !== "bookmark" && record.props.src && !record.props.src.startsWith("data:")) {
          let assetSrcToSave;
          try {
            assetSrcToSave = await FileHelpers.fileToBase64(
              await (await fetch(record.props.src)).blob()
            );
          } catch {
            assetSrcToSave = record.props.src;
          }
          assets.push({
            ...record,
            props: {
              ...record.props,
              src: assetSrcToSave
            }
          });
        } else {
          assets.push(record);
        }
        break;
      case "shape":
        if ("assetId" in record.props) {
          usedAssets.add(record.props.assetId);
        }
        records.push(record);
        break;
      default:
        records.push(record);
        break;
    }
  }
  const recordsToSave = records.concat(assets.filter((a) => usedAssets.has(a.id)));
  return JSON.stringify({
    tldrawFileFormatVersion: LATEST_TLDRAW_FILE_FORMAT_VERSION,
    schema: store.schema.serialize(),
    records: recordsToSave
  });
}
async function serializeTldrawJsonBlob(store) {
  return new Blob([await serializeTldrawJson(store)], { type: TLDRAW_FILE_MIMETYPE });
}
async function parseAndLoadDocument(editor, document2, msg2, addToast, onV1FileLoad, forceDarkMode) {
  const parseFileResult = parseTldrawJsonFile({
    schema: editor.store.schema,
    json: document2
  });
  if (!parseFileResult.ok) {
    let description;
    switch (parseFileResult.error.type) {
      case "notATldrawFile":
        editor.annotateError(parseFileResult.error.cause, {
          origin: "file-system.open.parse",
          willCrashApp: false,
          tags: { parseErrorType: parseFileResult.error.type }
        });
        reportError(parseFileResult.error.cause);
        description = msg2("file-system.file-open-error.not-a-tldraw-file");
        break;
      case "fileFormatVersionTooNew":
        description = msg2("file-system.file-open-error.file-format-version-too-new");
        break;
      case "migrationFailed":
        if (parseFileResult.error.reason === MigrationFailureReason.TargetVersionTooNew) {
          description = msg2("file-system.file-open-error.file-format-version-too-new");
        } else {
          description = msg2("file-system.file-open-error.generic-corrupted-file");
        }
        break;
      case "invalidRecords":
        editor.annotateError(parseFileResult.error.cause, {
          origin: "file-system.open.parse",
          willCrashApp: false,
          tags: { parseErrorType: parseFileResult.error.type }
        });
        reportError(parseFileResult.error.cause);
        description = msg2("file-system.file-open-error.generic-corrupted-file");
        break;
      case "v1File": {
        buildFromV1Document(editor, parseFileResult.error.data.document);
        onV1FileLoad?.();
        return;
      }
      default:
        exhaustiveSwitchError(parseFileResult.error, "type");
    }
    addToast({
      title: msg2("file-system.file-open-error.title"),
      description
    });
    return;
  }
  transact(() => {
    editor.store.clear();
    const [shapes, nonShapes] = partition(
      parseFileResult.value.allRecords(),
      (record) => record.typeName === "shape"
    );
    editor.store.put(nonShapes, "initialize");
    editor.store.ensureStoreIsUsable();
    editor.store.put(shapes, "initialize");
    editor.history.clear();
    editor.updateViewportScreenBounds();
    editor.updateRenderingBounds();
    const bounds = editor.currentPageBounds;
    if (bounds) {
      editor.zoomToBounds(bounds, 1);
    }
  });
  if (forceDarkMode)
    editor.user.updateUserPreferences({ isDarkMode: true });
}

export {
  EMPTY_ARRAY,
  whyAmIRunning,
  transaction,
  transact,
  atom,
  computed,
  react,
  track,
  useComputed,
  useQuickReactor,
  useReactor,
  useValue,
  IncrementalSetConstructor,
  rotateArray,
  dedupe,
  compact,
  last,
  minBy,
  partition,
  throttle,
  omitFromStackTrace,
  noop,
  Result,
  exhaustiveSwitchError,
  assert,
  assertExists,
  promiseWithResolve,
  debounce,
  annotateError,
  getErrorAnnotations,
  FileHelpers,
  getHashForString,
  getHashForObject,
  lns,
  getFirstFromIterable,
  PngHelpers,
  MediaHelpers,
  lerp,
  rng,
  modulate,
  hasOwnProperty,
  getOwnProperty,
  deepCopy,
  objectMapKeys,
  objectMapValues,
  objectMapEntries,
  objectMapFromEntries,
  filterEntries,
  mapObjectMapValues,
  rafThrottle,
  throttledRaf,
  sortById,
  isValidUrl,
  isDefined,
  isNonNull,
  isNonNullish,
  structuredClone2 as structuredClone,
  RecordType,
  createRecordType,
  assertIdType,
  devFreeze,
  Store,
  squashRecordDiffs,
  reverseRecordsDiff,
  defineMigrations,
  MigrationFailureReason,
  getRecordVersion,
  compareRecordVersions,
  migrateRecord,
  migrate,
  StoreSchema,
  compareSchemas,
  Validator,
  ArrayOfValidator,
  ObjectValidator,
  UnionValidator,
  DictValidator,
  validation_exports,
  idValidator,
  assetIdValidator,
  createAssetValidator,
  CameraRecordType,
  vec2dModelValidator,
  box2dModelValidator,
  opacityValidator,
  TL_CANVAS_UI_COLOR_TYPES,
  canvasUiColorTypeValidator,
  scribbleValidator,
  pageIdValidator,
  PageRecordType,
  isPageId,
  TLINSTANCE_ID,
  parentIdValidator,
  shapeIdValidator,
  createShapeValidator,
  InstancePageStateRecordType,
  PointerRecordType,
  TLPOINTER_ID,
  InstancePresenceRecordType,
  createPresenceStateDerivation,
  DocumentRecordType,
  TLDOCUMENT_ID,
  assetValidator,
  assetMigrations,
  AssetRecordType,
  StyleProp,
  EnumStyleProp,
  rootShapeMigrations,
  isShape,
  isShapeId,
  createShapeId,
  getShapePropKeysByStyle,
  createTLSchema,
  DefaultColorThemePalette,
  getDefaultColorTheme,
  DefaultColorStyle,
  DefaultDashStyle,
  DefaultFillStyle,
  DefaultFontStyle,
  DefaultFontFamilies,
  DefaultSizeStyle,
  ArrowShapeArrowheadStartStyle,
  ArrowShapeArrowheadEndStyle,
  arrowShapeProps,
  arrowShapeMigrations,
  bookmarkShapeProps,
  bookmarkShapeMigrations,
  drawShapeProps,
  drawShapeMigrations,
  EMBED_DEFINITIONS,
  embedShapePermissionDefaults,
  embedShapeProps,
  embedShapeMigrations,
  frameShapeProps,
  frameShapeMigrations,
  DefaultHorizontalAlignStyle,
  DefaultVerticalAlignStyle,
  GeoShapeGeoStyle,
  geoShapeProps,
  geoShapeMigrations,
  groupShapeProps,
  groupShapeMigrations,
  highlightShapeProps,
  highlightShapeMigrations,
  imageShapeProps,
  imageShapeMigrations,
  LineShapeSplineStyle,
  lineShapeProps,
  lineShapeMigrations,
  noteShapeProps,
  noteShapeMigrations,
  textShapeProps,
  textShapeMigrations,
  videoShapeProps,
  videoShapeMigrations,
  LANGUAGES,
  getDefaultTranslationLocale,
  featureFlags,
  debugFlags,
  loopToHtmlElement,
  preventDefault,
  setPointerCapture,
  releasePointerCapture,
  stopEventPropagation,
  getPointerInfo,
  useEditor,
  useContainer,
  ErrorBoundary,
  OptionalErrorBoundary,
  ShapeIndicator,
  DefaultBackground,
  useTransform,
  EASINGS,
  Vec2d,
  Box2d,
  rotateSelectionHandle,
  ROTATE_CORNER_TO_SELECTION_CORNER,
  precise,
  average,
  PI,
  TAU,
  PI2,
  EPSILON,
  SIN,
  clamp,
  toPrecision,
  approximately,
  perimeterOfEllipse,
  canonicalizeRotation,
  clockwiseAngleDist,
  shortAngleDist,
  longAngleDist,
  lerpAngles,
  angleDelta,
  getSweep,
  clampRadians,
  snapAngle,
  areAnglesCompatible,
  isAngleBetween,
  degreesToRadians,
  radiansToDegrees,
  getArcLength,
  getPointOnCircle,
  getPolygonVertices,
  rangeIntersection,
  getStarBounds,
  pointInCircle,
  pointInEllipse,
  pointInRect,
  pointInPolygon,
  pointInBounds,
  pointInPolyline,
  pointNearToPolyline,
  pointNearToLineSegment,
  toDomPrecision,
  toFixed,
  isSafeFloat,
  DefaultBrush,
  DefaultCollaboratorHint,
  DefaultCursor,
  runtime,
  setRuntimeOverrides,
  hardResetEditor,
  refreshPage,
  DefaultErrorFallback,
  MAX_SHAPES_PER_PAGE,
  MAX_PAGES,
  ANIMATION_SHORT_MS,
  ANIMATION_MEDIUM_MS,
  ZOOMS,
  MIN_ZOOM,
  MAX_ZOOM,
  DOUBLE_CLICK_DURATION,
  MULTI_CLICK_DURATION,
  DRAG_DISTANCE,
  SVG_PADDING,
  HASH_PATTERN_ZOOM_NAMES,
  DEFAULT_ANIMATION_OPTIONS,
  CAMERA_SLIDE_FRICTION,
  GRID_STEPS,
  HIT_TEST_MARGIN,
  DefaultGrid,
  DefaultHandle,
  DefaultHandles,
  DefaultHoveredShapeIndicator,
  getSvgPathFromPoints,
  DefaultScribble,
  DefaultSelectionBackground,
  DefaultSelectionForeground,
  DefaultSnapLine,
  DefaultSpinner,
  DefaultSvgDefs,
  normalizeWheel,
  Matrix2d,
  uniq,
  usePeerIds,
  usePresence,
  Canvas,
  uniqueId,
  USER_COLORS,
  defaultUserPreferences,
  getFreshUserPreferences,
  setUserPreferences,
  getUserPreferences,
  createTLUser,
  SVGContainer,
  Geometry2d,
  Group2d,
  intersectLineSegmentPolyline,
  intersectLineSegmentPolygon,
  linesIntersect,
  intersectPolygonPolygon,
  polygonsIntersect,
  Edge2d,
  Polyline2d,
  Polygon2d,
  Rectangle2d,
  ShapeUtil,
  GroupShapeUtil,
  coreShapes,
  ReadonlySharedStyleMap,
  SharedStyleMap,
  WeakMapCache,
  dataUrlToFile,
  getIncrementedName,
  getIndicesBetween,
  getIndicesAbove,
  getIndicesBelow,
  getIndexBetween,
  getIndexAbove,
  getIndexBelow,
  getIndices,
  sortByIndex2 as sortByIndex,
  getRotationSnapshot,
  applyRotationToSnapshotShapes,
  SnapManager,
  getArrowTerminalsInArrowSpace,
  getStraightArrowHandlePath,
  getSolidStraightArrowPath,
  getCurvedArrowHandlePath,
  getSolidCurvedArrowPath,
  EVENT_NAME_MAP,
  StateNode,
  Editor,
  useIsDarkMode,
  getCursor,
  TAB_ID,
  createSessionStateSnapshotSignal,
  loadSessionStateSnapshotIntoStore,
  extractSessionStateFromLegacySnapshot,
  createTLStore,
  useTLStore,
  useLocalStore,
  TldrawEditor,
  LoadingScreen,
  ErrorScreen,
  HTMLContainer,
  PositionedOnCanvas,
  resizeBox,
  BaseBoxShapeUtil,
  getArrowheadPathForType,
  BaseBoxShapeTool,
  useIsCropping,
  useIsEditing,
  useSelectionEvents,
  Arc2d,
  Circle2d,
  CubicBezier2d,
  CubicSpline2d,
  Ellipse2d,
  Stadium2d,
  hardReset,
  openWindow,
  AssetUrlsProvider,
  useAssetUrls,
  useTranslation,
  Spinner,
  Icon,
  Button,
  Dialog_exports,
  UiEventsProvider,
  useUiEvents,
  useMenuIsOpen,
  DropdownMenu_exports,
  useReadonly,
  containBoxSize,
  getResizedImageDataUrl,
  DEFAULT_ACCEPTED_IMG_TYPE,
  DEFAULT_ACCEPTED_VID_TYPE,
  isGifAnimated,
  getEmbedInfo,
  truncateStringWithEllipsis,
  ArrowShapeTool,
  DrawShapeTool,
  FrameShapeTool,
  GeoShapeTool,
  HighlightShapeTool,
  LineShapeTool,
  NoteShapeTool,
  TextShapeTool,
  defaultShapeTools,
  ArrowShapeUtil,
  BookmarkShapeUtil,
  DrawShapeUtil,
  EmbedShapeUtil,
  FrameShapeUtil,
  GeoShapeUtil,
  HighlightShapeUtil,
  ImageShapeUtil,
  LineShapeUtil,
  NoteShapeUtil,
  TextShapeUtil,
  VideoShapeUtil,
  defaultShapeUtils,
  EraserTool,
  HandTool,
  LaserTool,
  SelectTool,
  ZoomTool,
  defaultTools,
  setDefaultEditorAssetUrls,
  setDefaultUiAssetUrls,
  Input,
  useMenuClipboardEvents,
  useNativeClipboardEvents,
  useToasts,
  useCopyAs,
  useDialogs,
  useExportAs,
  useActions,
  compactMenuItems,
  menuGroup,
  menuSubmenu,
  menuCustom,
  menuItem,
  findMenuItem,
  BreakPointProvider,
  useBreakpoint,
  useActionsMenuSchema,
  useContextMenuSchema,
  useTools,
  useKeyboardShortcutsSchema,
  useHelpMenuSchema,
  useCanRedo,
  useCanUndo,
  useMenuSchema,
  toolbarItem,
  useToolbarSchema,
  useDefaultHelpers,
  TldrawUiContextProvider,
  useLocalStorageState,
  useKeyboardShortcuts,
  TldrawUi,
  ContextMenu2 as ContextMenu,
  Tldraw,
  OfflineIndicator,
  buildFromV1Document,
  TLDRAW_FILE_EXTENSION,
  parseTldrawJsonFile,
  serializeTldrawJson,
  serializeTldrawJsonBlob,
  parseAndLoadDocument
};
/*! Bundled license information:

classnames/index.js:
  (*!
  	Copyright (c) 2018 Jed Watson.
  	Licensed under the MIT License (MIT), see
  	http://jedwatson.github.io/classnames
  *)

canvas-size/dist/canvas-size.esm.js:
  (*!
   * canvas-size
   * v1.2.6
   * https://github.com/jhildenbiddle/canvas-size
   * (c) 2015-2023 John Hildenbiddle <http://hildenbiddle.com>
   * MIT license
   *)
*/
//# sourceMappingURL=chunk-HZMZCFKT.js.map
