91 Plus

自由轉調、輕鬆練歌,打造 91 譜的最佳體驗!

Version au 21/03/2024. Voir la dernière version.

Avant de procéder à l'installation, Greasy Forkattention ce script contient des contre-fonctionnalités, qui sont là pour le bénéfice de l'auteur du script, plutôt que pour le vôtre.

Ce script contient du code qui suivra votre navigation. L'auteur de ce script explique: 使用 Google Analytics 了解使用情況

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         91 Plus
// @namespace    https://github.com/DonkeyBear
// @version      1.7.0
// @author       DonkeyBear
// @description  自由轉調、輕鬆練歌,打造 91 譜的最佳體驗!
// @icon         https://www.91pu.com.tw/icons/favicon-32x32.png
// @match        *://www.91pu.com.tw/m/*
// @match        *://www.91pu.com.tw/song/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @antifeature  tracking  使用 Google Analytics 了解使用情況
// ==/UserScript==

(e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const t=document.createElement("style");t.textContent=e,document.head.append(t)})(' @import"https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css";#trigger-overlay[data-v-658df74c]{position:fixed;top:0;left:0;right:0;bottom:0;z-index:500}.bi[data-v-33d92514]{color:var(--2d5c579c);font-size:var(--0168355c);-webkit-text-stroke:var(--5c7f6b49) var(--2d5c579c)}.bi[data-v-33d92514]:before{transition:text-shadow .2s}.bi[active=true][data-v-33d92514]:before{text-shadow:0 0 .5rem rgb(75,156,169)}.toolbar-icon[data-v-2b5c1219]{cursor:pointer;padding:.25rem .75rem}.adjust-widget[data-v-1c41dc23]{display:flex}.adjust-widget .adjust-button[data-v-1c41dc23]{border:0;border-radius:.25rem;background:transparent}.adjust-widget .adjust-button[data-v-1c41dc23]:hover{background:rgba(0,0,0,.025)}.adjust-widget .adjust-button[data-v-1c41dc23]:disabled{opacity:.25}.adjust-widget .adjust-button.adjust-button-middle[data-v-1c41dc23]{flex-grow:1;color:var(--791a4684);font-size:calc(var(--37e19b46) * .75);font-weight:700}.adjust-widget .adjust-button.adjust-button-left[data-v-1c41dc23]{padding-right:1rem}.adjust-widget .adjust-button.adjust-button-right[data-v-1c41dc23]{padding-left:1rem}.slide-and-fade-enter-active[data-v-f161c46c],.slide-and-fade-leave-active[data-v-f161c46c]{transition:all .2s}.slide-and-fade-enter-from[data-v-f161c46c],.slide-and-fade-leave-to[data-v-f161c46c]{transform:translateY(10%);opacity:0}#plus91-sheet-popup[data-v-f161c46c]{position:absolute;left:0;right:0;bottom:100%;background:#fafafa;border:1px solid lightgray;padding:1rem 2rem;border-radius:1rem;margin:.5rem 1rem}.transpose-range-container[data-v-f161c46c]{margin-top:1rem}.transpose-range-container input[type=range][data-v-f161c46c]{width:100%}.instrument-select-container[data-v-f161c46c]{display:flex;border:1px solid lightgray;border-radius:.25rem;margin-top:1rem;background:white}.instrument-select-container .instrument-select-button[data-v-f161c46c]{width:33.3333333333%;border:0;border-right:1px solid lightgray;background:transparent;color:#666;padding:.5rem;font-size:.65rem;font-weight:700;cursor:pointer!important}.instrument-select-container .instrument-select-button[data-v-f161c46c]:last-child{border:0;border-radius:0 .25rem .25rem 0}.instrument-select-container .instrument-select-button[data-v-f161c46c]:first-child{border-radius:.25rem 0 0 .25rem}.instrument-select-container .instrument-select-button[data-v-f161c46c]:hover{background:whitesmoke}.chord-container .chord-name[data-v-1eb5094e]{font-size:.5rem;font-weight:900;color:#666;text-align:center}.chord-container .chord-chart[data-v-1eb5094e]{margin:-.6rem 0 -.25rem}.slide-and-fade-enter-active[data-v-84de48ae],.slide-and-fade-leave-active[data-v-84de48ae]{transition:all .2s}.slide-and-fade-enter-from[data-v-84de48ae],.slide-and-fade-leave-to[data-v-84de48ae]{transform:translateY(10%);opacity:0}#plus91-chord-popup[data-v-84de48ae]{position:absolute;left:0;right:0;bottom:100%;background:#fafafa;border:1px solid lightgray;border-radius:1rem;margin:.5rem 1rem;padding:1rem}#plus91-chord-popup .banner[data-v-84de48ae]{display:flex;align-items:center;background:rgba(75,156,169,.25);color:color-mix(in srgb,rgba(75,156,169,.65) 50%,black 50%);border-radius:.5rem;padding:.5rem .75rem;margin-bottom:.25rem}#plus91-chord-popup .banner section[data-v-84de48ae]{flex-grow:1;margin-left:.5rem}#plus91-chord-popup .chord-popup-container[data-v-84de48ae]{display:grid;grid-template-columns:repeat(6,1fr);column-gap:.5rem;padding-top:.4rem}.slide-and-fade-enter-active[data-v-eff17405],.slide-and-fade-leave-active[data-v-eff17405]{transition:all .2s}.slide-and-fade-enter-from[data-v-eff17405],.slide-and-fade-leave-to[data-v-eff17405]{transform:translateY(10%);opacity:0}#plus91-font-popup[data-v-eff17405]{position:absolute;left:0;right:0;bottom:100%;background:#fafafa;border:1px solid lightgray;padding:1rem 2rem;border-radius:1rem;margin:.5rem 1rem}.slide-and-fade-enter-active[data-v-e329f5af],.slide-and-fade-leave-active[data-v-e329f5af]{transition:all .2s}.slide-and-fade-enter-from[data-v-e329f5af],.slide-and-fade-leave-to[data-v-e329f5af]{transform:translateY(10%);opacity:0}#plus91-settings-popup[data-v-e329f5af]{position:absolute;left:0;right:0;bottom:100%;background:#fafafa;border:1px solid lightgray;border-radius:1rem;margin:.5rem 1rem;padding:1rem}#plus91-settings-popup .setting-item[data-v-e329f5af]{display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;border-radius:.5rem;cursor:pointer}#plus91-settings-popup .setting-item[data-v-e329f5af]:hover{background:rgba(0,0,0,.05)}.icon-button[data-v-e9902592]{display:flex;flex-direction:column;align-items:center;cursor:pointer;padding:0 .6rem .4rem;border-radius:.25rem}.icon-button[data-v-e9902592]:hover{background:rgba(0,0,0,.025)}.icon-button .button-text[data-v-e9902592]{font-size:.5rem;color:var(--9047bc34)}.slide-and-fade-enter-active[data-v-d041b049],.slide-and-fade-leave-active[data-v-d041b049]{transition:all .2s}.slide-and-fade-enter-from[data-v-d041b049],.slide-and-fade-leave-to[data-v-d041b049]{transform:translateY(10%);opacity:0}#plus91-menu-popup[data-v-d041b049]{position:absolute;left:0;right:0;bottom:100%;background:#fafafa;border:1px solid lightgray;padding:1rem 2rem;border-radius:1rem;margin:.5rem 1rem}#plus91-menu-popup .menu-popup-container[data-v-d041b049]{display:flex;justify-content:space-around}.hotkey-item[data-v-9f1c2e95]{display:flex;justify-content:space-between;align-items:center;padding:0 .25rem;border-radius:.25rem;height:1.4rem}.hotkey-item[data-v-9f1c2e95]:nth-child(odd){background:rgba(0,0,0,.025)}.desc.title[data-v-9f1c2e95]{font-size:.55rem;color:#999}.hotkeys[data-v-9f1c2e95]{display:flex}.hr[data-v-9f1c2e95]{display:flex;flex-grow:1;border-top:1px solid lightgray;margin-left:.25rem}kbd[data-v-9f1c2e95]{font-size:.6rem;border:solid lightgray;border-width:1px .1rem .15rem;border-radius:.2rem;padding:0 .2rem;letter-spacing:-.025rem;color:#666;margin-left:.15rem}.slide-and-fade-enter-active[data-v-a88e7568],.slide-and-fade-leave-active[data-v-a88e7568]{transition:all .2s}.slide-and-fade-enter-from[data-v-a88e7568],.slide-and-fade-leave-to[data-v-a88e7568]{transform:translateY(10%);opacity:0}#plus91-hotkey-popup[data-v-a88e7568]{position:absolute;left:0;right:0;bottom:100%;background:#fafafa;border:1px solid lightgray;padding:1rem 2rem;border-radius:1rem;margin:.5rem 1rem}#plus91-hotkey-popup .hotkey-popup-container[data-v-a88e7568]{display:flex;color:#444}#plus91-hotkey-popup section[data-v-a88e7568]{flex-grow:1;width:50%;margin:-.1rem 0}#plus91-hotkey-popup section.left-part[data-v-a88e7568]{border-right:1px solid lightgray;margin-left:-.5rem;padding-right:.5rem}#plus91-hotkey-popup section.right-part[data-v-a88e7568]{padding-left:.5rem;margin-right:-.5rem}#plus91-hotkey-popup kbd[data-v-a88e7568]{font-size:.65rem;border:solid lightgray;border-width:1px .1rem .15rem;border-radius:.2rem;padding:0 .2rem;letter-spacing:-.025rem;color:#666}.slide-enter-active[data-v-a29224c8],.slide-leave-active[data-v-a29224c8]{transition:transform .2s}.slide-enter-from[data-v-a29224c8],.slide-leave-to[data-v-a29224c8]{transform:translateY(100%)}#plus91-footer[data-v-a29224c8]{z-index:1000;display:flex;justify-content:center;position:fixed;left:0;right:0;bottom:0}.footer-container[data-v-a29224c8]{width:min(100vw,768px);background:rgba(75,156,169,.65);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);padding:.25rem .5rem .75rem;display:flex;justify-content:space-between;align-items:center;border-radius:1rem 1rem 0 0;border:1px solid rgb(90,140,160);border-bottom:0}.slide-enter-active[data-v-265bcfd2],.slide-leave-active[data-v-265bcfd2]{transition:transform .2s}.slide-enter-from[data-v-265bcfd2],.slide-leave-to[data-v-265bcfd2]{transform:translateY(-100%)}#plus91-header[data-v-265bcfd2]{z-index:1000;display:flex;justify-content:center;position:fixed;left:0;right:0;top:0}.header-container[data-v-265bcfd2]{width:min(100vw,768px);background:rgba(75,156,169,.65);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);padding:.25rem .5rem;display:flex;justify-content:space-between;align-items:center;border-radius:0 0 1rem 1rem;border:1px solid rgb(90,140,160);border-top:0}.header-container input[data-v-265bcfd2]{flex-grow:1;width:100%;border-radius:50rem;border:0;font-size:.8rem;font-weight:700;padding:.35rem 1.25rem;background:rgba(255,255,255,.6666666667);color:#0009;opacity:.5;transition:all .2s}.header-container input[data-v-265bcfd2]:focus-visible{outline:0;opacity:1}.fade-enter-active[data-v-e9c78cc3],.fade-leave-active[data-v-e9c78cc3]{transition:opacity .2s}.fade-enter-from[data-v-e9c78cc3],.fade-leave-to[data-v-e9c78cc3]{opacity:0}#dark-mode-overlay[data-v-e9c78cc3]{position:fixed;top:0;left:0;right:0;bottom:0;z-index:800;-webkit-backdrop-filter:invert(1) hue-rotate(145deg) saturate(.75);backdrop-filter:invert(1) hue-rotate(145deg) saturate(.75);pointer-events:none}html{background:#fafafa url(/templets/pu/images/tone-bg.gif)}#vue-91plus{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif}.tfunc2{margin:10px}#mtitle{font-family:system-ui}input[type=range],input[type=range]::-webkit-slider-thumb,input[type=range]::-webkit-slider-runnable-track{-webkit-appearance:none;box-shadow:none}input[type=range]::-webkit-slider-thumb,input[type=range]::-webkit-slider-runnable-track{border:1px solid rgba(68,68,68,.25)}input[type=range]::-webkit-slider-thumb{background:#60748d}#viptoneWindow.window,#bottomad,.update_vip_bar,.wmask,header,footer,.autoscroll,.backplace,.set .keys,.set .plays,.set .clear,.setint .hr:nth-child(4),.setint .hr:nth-child(5),.setint .hr:nth-child(6),.adsbygoogle{display:none!important} ');

(function (vue) {
  'use strict';

  var __defProp = Object.defineProperty;
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __publicField = (obj, key, value) => {
    __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
    return value;
  };
  var __accessCheck = (obj, member, msg) => {
    if (!member.has(obj))
      throw TypeError("Cannot " + msg);
  };
  var __privateGet = (obj, member, getter) => {
    __accessCheck(obj, member, "read from private field");
    return getter ? getter.call(obj) : member.get(obj);
  };
  var __privateAdd = (obj, member, value) => {
    if (member.has(obj))
      throw TypeError("Cannot add the same private member more than once");
    member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
  };
  var __privateSet = (obj, member, value, setter) => {
    __accessCheck(obj, member, "write to private field");
    setter ? setter.call(obj, value) : member.set(obj, value);
    return value;
  };
  var __privateMethod = (obj, member, method) => {
    __accessCheck(obj, member, "access private method");
    return method;
  };
  var _unformat, unformat_fn, _store, _watchTranspose, watchTranspose_fn, _watchFontSize, watchFontSize_fn;
  var isVue2 = false;
  /*!
   * pinia v2.1.7
   * (c) 2023 Eduardo San Martin Morote
   * @license MIT
   */
  let activePinia;
  const setActivePinia = (pinia2) => activePinia = pinia2;
  const piniaSymbol = (
    /* istanbul ignore next */
    Symbol()
  );
  function isPlainObject(o) {
    return o && typeof o === "object" && Object.prototype.toString.call(o) === "[object Object]" && typeof o.toJSON !== "function";
  }
  var MutationType;
  (function(MutationType2) {
    MutationType2["direct"] = "direct";
    MutationType2["patchObject"] = "patch object";
    MutationType2["patchFunction"] = "patch function";
  })(MutationType || (MutationType = {}));
  function createPinia() {
    const scope = vue.effectScope(true);
    const state = scope.run(() => vue.ref({}));
    let _p = [];
    let toBeInstalled = [];
    const pinia2 = vue.markRaw({
      install(app) {
        setActivePinia(pinia2);
        {
          pinia2._a = app;
          app.provide(piniaSymbol, pinia2);
          app.config.globalProperties.$pinia = pinia2;
          toBeInstalled.forEach((plugin) => _p.push(plugin));
          toBeInstalled = [];
        }
      },
      use(plugin) {
        if (!this._a && !isVue2) {
          toBeInstalled.push(plugin);
        } else {
          _p.push(plugin);
        }
        return this;
      },
      _p,
      // it's actually undefined here
      // @ts-expect-error
      _a: null,
      _e: scope,
      _s: /* @__PURE__ */ new Map(),
      state
    });
    return pinia2;
  }
  const noop$1 = () => {
  };
  function addSubscription(subscriptions, callback, detached, onCleanup = noop$1) {
    subscriptions.push(callback);
    const removeSubscription = () => {
      const idx = subscriptions.indexOf(callback);
      if (idx > -1) {
        subscriptions.splice(idx, 1);
        onCleanup();
      }
    };
    if (!detached && vue.getCurrentScope()) {
      vue.onScopeDispose(removeSubscription);
    }
    return removeSubscription;
  }
  function triggerSubscriptions(subscriptions, ...args) {
    subscriptions.slice().forEach((callback) => {
      callback(...args);
    });
  }
  const fallbackRunWithContext = (fn) => fn();
  function mergeReactiveObjects(target, patchToApply) {
    if (target instanceof Map && patchToApply instanceof Map) {
      patchToApply.forEach((value, key) => target.set(key, value));
    }
    if (target instanceof Set && patchToApply instanceof Set) {
      patchToApply.forEach(target.add, target);
    }
    for (const key in patchToApply) {
      if (!patchToApply.hasOwnProperty(key))
        continue;
      const subPatch = patchToApply[key];
      const targetValue = target[key];
      if (isPlainObject(targetValue) && isPlainObject(subPatch) && target.hasOwnProperty(key) && !vue.isRef(subPatch) && !vue.isReactive(subPatch)) {
        target[key] = mergeReactiveObjects(targetValue, subPatch);
      } else {
        target[key] = subPatch;
      }
    }
    return target;
  }
  const skipHydrateSymbol = (
    /* istanbul ignore next */
    Symbol()
  );
  function shouldHydrate(obj) {
    return !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
  }
  const { assign } = Object;
  function isComputed(o) {
    return !!(vue.isRef(o) && o.effect);
  }
  function createOptionsStore(id, options, pinia2, hot) {
    const { state, actions, getters } = options;
    const initialState = pinia2.state.value[id];
    let store;
    function setup() {
      if (!initialState && true) {
        {
          pinia2.state.value[id] = state ? state() : {};
        }
      }
      const localState = vue.toRefs(pinia2.state.value[id]);
      return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => {
        computedGetters[name] = vue.markRaw(vue.computed(() => {
          setActivePinia(pinia2);
          const store2 = pinia2._s.get(id);
          return getters[name].call(store2, store2);
        }));
        return computedGetters;
      }, {}));
    }
    store = createSetupStore(id, setup, options, pinia2, hot, true);
    return store;
  }
  function createSetupStore($id, setup, options = {}, pinia2, hot, isOptionsStore) {
    let scope;
    const optionsForPlugin = assign({ actions: {} }, options);
    const $subscribeOptions = {
      deep: true
      // flush: 'post',
    };
    let isListening;
    let isSyncListening;
    let subscriptions = [];
    let actionSubscriptions = [];
    let debuggerEvents;
    const initialState = pinia2.state.value[$id];
    if (!isOptionsStore && !initialState && true) {
      {
        pinia2.state.value[$id] = {};
      }
    }
    vue.ref({});
    let activeListener;
    function $patch(partialStateOrMutator) {
      let subscriptionMutation;
      isListening = isSyncListening = false;
      if (typeof partialStateOrMutator === "function") {
        partialStateOrMutator(pinia2.state.value[$id]);
        subscriptionMutation = {
          type: MutationType.patchFunction,
          storeId: $id,
          events: debuggerEvents
        };
      } else {
        mergeReactiveObjects(pinia2.state.value[$id], partialStateOrMutator);
        subscriptionMutation = {
          type: MutationType.patchObject,
          payload: partialStateOrMutator,
          storeId: $id,
          events: debuggerEvents
        };
      }
      const myListenerId = activeListener = Symbol();
      vue.nextTick().then(() => {
        if (activeListener === myListenerId) {
          isListening = true;
        }
      });
      isSyncListening = true;
      triggerSubscriptions(subscriptions, subscriptionMutation, pinia2.state.value[$id]);
    }
    const $reset = isOptionsStore ? function $reset2() {
      const { state } = options;
      const newState = state ? state() : {};
      this.$patch(($state) => {
        assign($state, newState);
      });
    } : (
      /* istanbul ignore next */
      noop$1
    );
    function $dispose() {
      scope.stop();
      subscriptions = [];
      actionSubscriptions = [];
      pinia2._s.delete($id);
    }
    function wrapAction(name, action) {
      return function() {
        setActivePinia(pinia2);
        const args = Array.from(arguments);
        const afterCallbackList = [];
        const onErrorCallbackList = [];
        function after2(callback) {
          afterCallbackList.push(callback);
        }
        function onError(callback) {
          onErrorCallbackList.push(callback);
        }
        triggerSubscriptions(actionSubscriptions, {
          args,
          name,
          store,
          after: after2,
          onError
        });
        let ret;
        try {
          ret = action.apply(this && this.$id === $id ? this : store, args);
        } catch (error) {
          triggerSubscriptions(onErrorCallbackList, error);
          throw error;
        }
        if (ret instanceof Promise) {
          return ret.then((value) => {
            triggerSubscriptions(afterCallbackList, value);
            return value;
          }).catch((error) => {
            triggerSubscriptions(onErrorCallbackList, error);
            return Promise.reject(error);
          });
        }
        triggerSubscriptions(afterCallbackList, ret);
        return ret;
      };
    }
    const partialStore = {
      _p: pinia2,
      // _s: scope,
      $id,
      $onAction: addSubscription.bind(null, actionSubscriptions),
      $patch,
      $reset,
      $subscribe(callback, options2 = {}) {
        const removeSubscription = addSubscription(subscriptions, callback, options2.detached, () => stopWatcher());
        const stopWatcher = scope.run(() => vue.watch(() => pinia2.state.value[$id], (state) => {
          if (options2.flush === "sync" ? isSyncListening : isListening) {
            callback({
              storeId: $id,
              type: MutationType.direct,
              events: debuggerEvents
            }, state);
          }
        }, assign({}, $subscribeOptions, options2)));
        return removeSubscription;
      },
      $dispose
    };
    const store = vue.reactive(partialStore);
    pinia2._s.set($id, store);
    const runWithContext = pinia2._a && pinia2._a.runWithContext || fallbackRunWithContext;
    const setupStore = runWithContext(() => pinia2._e.run(() => (scope = vue.effectScope()).run(setup)));
    for (const key in setupStore) {
      const prop = setupStore[key];
      if (vue.isRef(prop) && !isComputed(prop) || vue.isReactive(prop)) {
        if (!isOptionsStore) {
          if (initialState && shouldHydrate(prop)) {
            if (vue.isRef(prop)) {
              prop.value = initialState[key];
            } else {
              mergeReactiveObjects(prop, initialState[key]);
            }
          }
          {
            pinia2.state.value[$id][key] = prop;
          }
        }
      } else if (typeof prop === "function") {
        const actionValue = wrapAction(key, prop);
        {
          setupStore[key] = actionValue;
        }
        optionsForPlugin.actions[key] = prop;
      } else
        ;
    }
    {
      assign(store, setupStore);
      assign(vue.toRaw(store), setupStore);
    }
    Object.defineProperty(store, "$state", {
      get: () => pinia2.state.value[$id],
      set: (state) => {
        $patch(($state) => {
          assign($state, state);
        });
      }
    });
    pinia2._p.forEach((extender) => {
      {
        assign(store, scope.run(() => extender({
          store,
          app: pinia2._a,
          pinia: pinia2,
          options: optionsForPlugin
        })));
      }
    });
    if (initialState && isOptionsStore && options.hydrate) {
      options.hydrate(store.$state, initialState);
    }
    isListening = true;
    isSyncListening = true;
    return store;
  }
  function defineStore(idOrOptions, setup, setupOptions) {
    let id;
    let options;
    const isSetupStore = typeof setup === "function";
    if (typeof idOrOptions === "string") {
      id = idOrOptions;
      options = isSetupStore ? setupOptions : setup;
    } else {
      options = idOrOptions;
      id = idOrOptions.id;
    }
    function useStore2(pinia2, hot) {
      const hasContext = vue.hasInjectionContext();
      pinia2 = // in test mode, ignore the argument provided as we can always retrieve a
      // pinia instance with getActivePinia()
      pinia2 || (hasContext ? vue.inject(piniaSymbol, null) : null);
      if (pinia2)
        setActivePinia(pinia2);
      pinia2 = activePinia;
      if (!pinia2._s.has(id)) {
        if (isSetupStore) {
          createSetupStore(id, setup, options, pinia2);
        } else {
          createOptionsStore(id, options, pinia2);
        }
      }
      const store = pinia2._s.get(id);
      return store;
    }
    useStore2.$id = id;
    return useStore2;
  }
  function isObject$1(v) {
    return typeof v === "object" && v !== null;
  }
  function normalizeOptions(options, factoryOptions) {
    options = isObject$1(options) ? options : /* @__PURE__ */ Object.create(null);
    return new Proxy(options, {
      get(target, key, receiver) {
        if (key === "key")
          return Reflect.get(target, key, receiver);
        return Reflect.get(target, key, receiver) || Reflect.get(factoryOptions, key, receiver);
      }
    });
  }
  function get(state, path) {
    return path.reduce((obj, p) => {
      return obj == null ? void 0 : obj[p];
    }, state);
  }
  function set(state, path, val) {
    return path.slice(0, -1).reduce((obj, p) => {
      if (/^(__proto__)$/.test(p))
        return {};
      else
        return obj[p] = obj[p] || {};
    }, state)[path[path.length - 1]] = val, state;
  }
  function pick(baseState, paths) {
    return paths.reduce((substate, path) => {
      const pathArray = path.split(".");
      return set(substate, pathArray, get(baseState, pathArray));
    }, {});
  }
  function hydrateStore(store, { storage, serializer, key, debug }) {
    try {
      const fromStorage = storage == null ? void 0 : storage.getItem(key);
      if (fromStorage)
        store.$patch(serializer == null ? void 0 : serializer.deserialize(fromStorage));
    } catch (error) {
      if (debug)
        console.error(error);
    }
  }
  function persistState(state, { storage, serializer, key, paths, debug }) {
    try {
      const toStore = Array.isArray(paths) ? pick(state, paths) : state;
      storage.setItem(key, serializer.serialize(toStore));
    } catch (error) {
      if (debug)
        console.error(error);
    }
  }
  function createPersistedState(factoryOptions = {}) {
    return (context) => {
      const { auto = false } = factoryOptions;
      const {
        options: { persist = auto },
        store,
        pinia: pinia2
      } = context;
      if (!persist)
        return;
      if (!(store.$id in pinia2.state.value)) {
        const original_store = pinia2._s.get(store.$id.replace("__hot:", ""));
        if (original_store)
          Promise.resolve().then(() => original_store.$persist());
        return;
      }
      const persistences = (Array.isArray(persist) ? persist.map((p) => normalizeOptions(p, factoryOptions)) : [normalizeOptions(persist, factoryOptions)]).map(
        ({
          storage = localStorage,
          beforeRestore = null,
          afterRestore = null,
          serializer = {
            serialize: JSON.stringify,
            deserialize: JSON.parse
          },
          key = store.$id,
          paths = null,
          debug = false
        }) => {
          var _a;
          return {
            storage,
            beforeRestore,
            afterRestore,
            serializer,
            key: ((_a = factoryOptions.key) != null ? _a : (k) => k)(typeof key == "string" ? key : key(store.$id)),
            paths,
            debug
          };
        }
      );
      store.$persist = () => {
        persistences.forEach((persistence) => {
          persistState(store.$state, persistence);
        });
      };
      store.$hydrate = ({ runHooks = true } = {}) => {
        persistences.forEach((persistence) => {
          const { beforeRestore, afterRestore } = persistence;
          if (runHooks)
            beforeRestore == null ? void 0 : beforeRestore(context);
          hydrateStore(store, persistence);
          if (runHooks)
            afterRestore == null ? void 0 : afterRestore(context);
        });
      };
      persistences.forEach((persistence) => {
        const { beforeRestore, afterRestore } = persistence;
        beforeRestore == null ? void 0 : beforeRestore(context);
        hydrateStore(store, persistence);
        afterRestore == null ? void 0 : afterRestore(context);
        store.$subscribe(
          (_mutation, state) => {
            persistState(state, persistence);
          },
          {
            detached: true
          }
        );
      });
    };
  }
  var src_default = createPersistedState();
  const _export_sfc = (sfc, props) => {
    const target = sfc.__vccOpts || sfc;
    for (const [key, val] of props) {
      target[key] = val;
    }
    return target;
  };
  const _sfc_main$g = {};
  const _hoisted_1$f = { id: "trigger-overlay" };
  function _sfc_render(_ctx, _cache) {
    return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$f);
  }
  const TriggerOverlay = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render], ["__scopeId", "data-v-658df74c"]]);
  const _Chord = class _Chord {
    /** @param {string} chordString  */
    constructor(chordString) {
      this.chordString = chordString;
    }
    /**
     * @param {number} delta
     * @returns {Chord}
     */
    transpose(delta) {
      this.chordString = this.chordString.replaceAll(/[A-G][#b]?/g, (note) => {
        const isSharp = _Chord.sharps.includes(note);
        const scale = isSharp ? _Chord.sharps : _Chord.flats;
        const noteIndex = scale.indexOf(note);
        const transposedIndex = (noteIndex + delta + 12) % 12;
        const transposedNote = scale[transposedIndex];
        return transposedNote;
      });
      return this;
    }
    /** @returns {Chord} */
    switchModifier() {
      this.chordString = this.chordString.replaceAll(/[A-G][#b]/g, (note) => {
        const scale = note.includes("#") ? _Chord.sharps : _Chord.flats;
        const newScale = note.includes("#") ? _Chord.flats : _Chord.sharps;
        const noteIndex = scale.indexOf(note);
        return newScale[noteIndex];
      });
      return this;
    }
    /** @returns {Chord} */
    useSharpModifier() {
      this.chordString = this.chordString.replaceAll(/[A-G]b/g, (note) => {
        const noteIndex = _Chord.flats.indexOf(note);
        return _Chord.sharps[noteIndex];
      });
      return this;
    }
    /** @returns {Chord} */
    useFlatModifier() {
      this.chordString = this.chordString.replaceAll(/[A-G]#/g, (note) => {
        const noteIndex = _Chord.sharps.indexOf(note);
        return _Chord.flats[noteIndex];
      });
      return this;
    }
    /** @returns {string} */
    toString() {
      return this.chordString;
    }
    /** @returns {string} */
    toFormattedString() {
      return this.chordString.replaceAll(
        /[#b]/g,
        /* html */
        `<sup>$&</sup>`
      );
    }
  };
  __publicField(_Chord, "sharps", ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]);
  __publicField(_Chord, "flats", ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"]);
  let Chord = _Chord;
  var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  class MonkeyStorage {
    /**
     * @param {String} key 
     * @returns {String|null}
     */
    static getItem(key) {
      if (_GM_getValue) {
        return _GM_getValue(key, null);
      } else {
        return localStorage.getItem(key);
      }
    }
    /**
     * @param {String} key 
     * @param {String} value 
     * @returns {void}
     */
    static setItem(key, value) {
      if (_GM_setValue) {
        _GM_setValue(key, value);
      } else {
        localStorage.setItem(key, value);
      }
    }
  }
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
  var lib = {};
  var compress$1 = {};
  var any = {};
  var constants = {};
  (function(exports) {
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.FLOAT_COMPRESSION_PRECISION = 1e3;
    exports.DATE_LOW_PRECISION = 1e5;
    exports.FLOAT_FULL_PRECISION_DELIMITER = ",";
    exports.FLOAT_REDUCED_PRECISION_DELIMITER = ".";
    exports.INTEGER_TOKEN = "¢";
    exports.FLOAT_TOKEN = "£";
    exports.STRING_TOKEN = "¨";
    exports.DATE_TOKEN = "ø";
    exports.LP_DATE_TOKEN = "±";
    exports.UNREFERENCED_INTEGER_TOKEN = "¤";
    exports.UNREFERENCED_FLOAT_TOKEN = "¥";
    exports.UNREFERENCED_STRING_TOKEN = "´";
    exports.UNREFERENCED_DATE_TOKEN = "¿";
    exports.UNREFERENCED_LP_DATE_TOKEN = "ÿ";
    exports.REF_INTEGER_TOKEN = "º";
    exports.REF_FLOAT_TOKEN = "Ý";
    exports.REF_STRING_TOKEN = "ß";
    exports.REF_DATE_TOKEN = "×";
    exports.REF_LP_DATE_TOKEN = "ü";
    exports.NULL_TOKEN = "§";
    exports.UNDEFINED_TOKEN = "µ";
    exports.BOOLEAN_TRUE_TOKEN = "»";
    exports.BOOLEAN_FALSE_TOKEN = "«";
    exports.ESCAPE_CHARACTER = "\\";
    exports.ESCAPED_STRING_TOKEN = "" + exports.ESCAPE_CHARACTER + exports.STRING_TOKEN;
    exports.ESCAPED_UNREFERENCED_STRING_TOKEN = "" + exports.ESCAPE_CHARACTER + exports.UNREFERENCED_STRING_TOKEN;
    exports.REGEX_ESCAPE_CHARACTER = new RegExp(exports.ESCAPE_CHARACTER.replace("\\", "\\\\"), "g");
    exports.REGEX_ESCAPED_ESCAPE_CHARACTER = new RegExp(exports.ESCAPE_CHARACTER.replace("\\", "\\\\") + exports.ESCAPE_CHARACTER.replace("\\", "\\\\"), "g");
    exports.REGEX_STRING_TOKEN = new RegExp(exports.STRING_TOKEN, "g");
    exports.REGEX_ESCAPED_STRING_TOKEN = new RegExp(exports.ESCAPE_CHARACTER + exports.ESCAPED_STRING_TOKEN, "g");
    exports.REGEX_UNREFERENCED_STRING_TOKEN = new RegExp(exports.UNREFERENCED_STRING_TOKEN, "g");
    exports.REGEX_UNREFERENCED_ESCAPED_STRING_TOKEN = new RegExp(exports.ESCAPE_CHARACTER + exports.ESCAPED_UNREFERENCED_STRING_TOKEN, "g");
    exports.DATE_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z/;
    exports.OBJECT_START_TOKEN = "{";
    exports.OBJECT_END_TOKEN = "}";
    exports.TEMPLATE_OBJECT_START = "¦";
    exports.TEMPLATE_OBJECT_END = "‡";
    exports.TEMPLATE_OBJECT_FINAL = "—";
    exports.ARRAY_START_TOKEN = "|";
    exports.ARRAY_END_TOKEN = "÷";
    exports.ARRAY_REPEAT_TOKEN = "þ";
    exports.ARRAY_REPEAT_MANY_TOKEN = "^";
    exports.ARRAY_REPEAT_COUNT_THRESHOLD = 4;
    exports.REFERENCE_HEADER_LENGTH = 1;
    exports.DELIMITING_TOKENS_THRESHOLD = 122;
    exports.STRING_IDENT_PREFIX = "$";
    exports.INTEGER_SMALL_EXCLUSIVE_BOUND_LOWER = -10;
    exports.INTEGER_SMALL_EXCLUSIVE_BOUND_UPPER = 10;
    exports.INTEGER_SMALL_TOKEN_EXCLUSIVE_BOUND_LOWER = 191;
    exports.INTEGER_SMALL_TOKEN_EXCLUSIVE_BOUND_UPPER = 211;
    exports.INTEGER_SMALL_TOKEN_OFFSET = -201;
    exports.INTEGER_SMALL_TOKEN_ELEMENT_OFFSET = 9;
    exports.INTEGER_SMALL_TOKENS = ["À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò"];
  })(constants);
  Object.defineProperty(any, "__esModule", { value: true });
  var constants_1$a = constants;
  function compressAny(compressors2, context, obj, invertedIndex, writer2, options) {
    var type = typeof obj;
    if (type === "number") {
      compressors2.number(compressors2, context, obj, invertedIndex, writer2, options);
    } else if (type === "string") {
      compressors2.string(compressors2, context, obj, invertedIndex, writer2, options);
    } else if (type === "boolean") {
      writer2.write(obj ? constants_1$a.BOOLEAN_TRUE_TOKEN : constants_1$a.BOOLEAN_FALSE_TOKEN);
    } else if (obj === null) {
      writer2.write(constants_1$a.NULL_TOKEN);
    } else if (obj === void 0) {
      writer2.write(constants_1$a.UNDEFINED_TOKEN);
    } else if (Array.isArray(obj)) {
      compressors2.array(compressors2, context, obj, invertedIndex, writer2, options);
    } else if (obj instanceof Date) {
      compressors2.date(compressors2, context, obj.getTime(), invertedIndex, writer2, options);
    } else {
      compressors2.object(compressors2, context, obj, invertedIndex, writer2, options);
    }
  }
  any.compressAny = compressAny;
  var array$1 = {};
  var writer = {};
  var __extends = commonjsGlobal && commonjsGlobal.__extends || function() {
    var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) {
      d.__proto__ = b;
    } || function(d, b) {
      for (var p in b)
        if (b.hasOwnProperty(p))
          d[p] = b[p];
    };
    return function(d, b) {
      extendStatics(d, b);
      function __() {
        this.constructor = d;
      }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
  }();
  Object.defineProperty(writer, "__esModule", { value: true });
  var ZipsonWriter = (
    /** @class */
    function() {
      function ZipsonWriter2() {
      }
      return ZipsonWriter2;
    }()
  );
  writer.ZipsonWriter = ZipsonWriter;
  var ZipsonStringWriter = (
    /** @class */
    function(_super) {
      __extends(ZipsonStringWriter2, _super);
      function ZipsonStringWriter2() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.value = "";
        return _this;
      }
      ZipsonStringWriter2.prototype.write = function(data2) {
        this.value += data2;
      };
      ZipsonStringWriter2.prototype.end = function() {
      };
      return ZipsonStringWriter2;
    }(ZipsonWriter)
  );
  writer.ZipsonStringWriter = ZipsonStringWriter;
  var util$1 = {};
  Object.defineProperty(util$1, "__esModule", { value: true });
  var constants_1$9 = constants;
  var maxInteger = 2147483648;
  var minInteger = -2147483649;
  var base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  function compressInteger(number2) {
    if (number2 === 0) {
      return "0";
    }
    var result = "";
    var carry = number2 < 0 ? -number2 : number2;
    var current = 0;
    var fraction;
    while (carry > 0) {
      carry = carry / 62;
      fraction = carry % 1;
      current = fraction * 62 + 0.1 << 0;
      carry -= fraction;
      result = base62[current] + result;
    }
    result = number2 < 0 ? "-" + result : result;
    return result;
  }
  util$1.compressInteger = compressInteger;
  function decompressInteger(compressedInteger) {
    var value = 0;
    if (compressedInteger[0] === "0") {
      return value;
    } else {
      var negative = compressedInteger[0] === "-";
      var multiplier = 1;
      var leftBound = negative ? 1 : 0;
      for (var i = compressedInteger.length - 1; i >= leftBound; i--) {
        var code = compressedInteger.charCodeAt(i);
        var current = code - 48;
        if (code >= 97) {
          current -= 13;
        } else if (code >= 65) {
          current -= 7;
        }
        value += current * multiplier;
        multiplier *= 62;
      }
      return negative ? -value : value;
    }
  }
  util$1.decompressInteger = decompressInteger;
  function compressFloat(float, fullPrecision) {
    if (fullPrecision === void 0) {
      fullPrecision = false;
    }
    if (fullPrecision) {
      var _a = float.toString().split("."), integer = _a[0], fraction = _a[1];
      var operator = integer === "-0" ? "-" : "";
      return "" + operator + compressInteger(parseInt(integer)) + constants_1$9.FLOAT_FULL_PRECISION_DELIMITER + fraction;
    } else {
      var integer = float >= maxInteger ? Math.floor(float) : float <= minInteger ? Math.ceil(float) : float << 0;
      var fraction = Math.round(constants_1$9.FLOAT_COMPRESSION_PRECISION * (float % 1));
      return "" + compressInteger(integer) + constants_1$9.FLOAT_REDUCED_PRECISION_DELIMITER + compressInteger(fraction);
    }
  }
  util$1.compressFloat = compressFloat;
  function decompressFloat(compressedFloat) {
    if (compressedFloat.indexOf(constants_1$9.FLOAT_FULL_PRECISION_DELIMITER) > -1) {
      var _a = compressedFloat.split(constants_1$9.FLOAT_FULL_PRECISION_DELIMITER), integer = _a[0], fraction = _a[1];
      var mult = integer === "-0" ? -1 : 1;
      var uncompressedInteger = decompressInteger(integer);
      return mult * parseFloat(uncompressedInteger + "." + fraction);
    } else {
      var _b = compressedFloat.split(constants_1$9.FLOAT_REDUCED_PRECISION_DELIMITER), integer = _b[0], fraction = _b[1];
      var uncompressedInteger = decompressInteger(integer);
      var uncompressedFraction = decompressInteger(fraction);
      return uncompressedInteger + uncompressedFraction / constants_1$9.FLOAT_COMPRESSION_PRECISION;
    }
  }
  util$1.decompressFloat = decompressFloat;
  Object.defineProperty(array$1, "__esModule", { value: true });
  var constants_1$8 = constants;
  var writer_1 = writer;
  var util_1$5 = util$1;
  function compressArray(compressors2, context, array2, invertedIndex, writer2, options) {
    context.arrayLevel++;
    if (context.arrayLevel > context.arrayItemWriters.length) {
      context.arrayItemWriters.push(new writer_1.ZipsonStringWriter());
    }
    var arrayItemWriter = context.arrayItemWriters[context.arrayLevel - 1];
    var parentWriter = context.arrayItemWriters[context.arrayLevel - 2] || writer2;
    parentWriter.write(constants_1$8.ARRAY_START_TOKEN);
    var previousItem = "";
    var repeatedTimes = 0;
    var repeatManyCount = 0;
    var templateObject = new compressors2.template.Object(array2[0], array2[1]);
    if (templateObject.isTemplating) {
      templateObject.compressTemplate(compressors2, context, invertedIndex, parentWriter, options);
    }
    for (var i = 0; i < array2.length; i++) {
      var item = array2[i];
      arrayItemWriter.value = "";
      if (item === void 0) {
        item = null;
      }
      if (i > 1 && templateObject.isTemplating) {
        templateObject.isNextTemplateable(array2[i], parentWriter);
      }
      if (templateObject.isTemplating) {
        templateObject.compressTemplateValues(compressors2, context, invertedIndex, arrayItemWriter, options, array2[i]);
      } else {
        compressors2.any(compressors2, context, item, invertedIndex, arrayItemWriter, options);
      }
      if (arrayItemWriter.value === previousItem) {
        repeatedTimes++;
        if (repeatedTimes >= constants_1$8.ARRAY_REPEAT_COUNT_THRESHOLD) {
          if (repeatManyCount === 0) {
            parentWriter.write(constants_1$8.ARRAY_REPEAT_MANY_TOKEN);
          }
          repeatManyCount++;
        } else {
          parentWriter.write(constants_1$8.ARRAY_REPEAT_TOKEN);
        }
      } else {
        repeatedTimes = 0;
        if (repeatManyCount > 0) {
          parentWriter.write(util_1$5.compressInteger(repeatManyCount));
          repeatManyCount = 0;
        }
        parentWriter.write(arrayItemWriter.value);
        previousItem = arrayItemWriter.value;
      }
    }
    if (repeatManyCount > 0) {
      parentWriter.write(util_1$5.compressInteger(repeatManyCount));
    }
    if (templateObject.isTemplating) {
      templateObject.end(parentWriter);
    }
    parentWriter.write(constants_1$8.ARRAY_END_TOKEN);
    context.arrayLevel--;
  }
  array$1.compressArray = compressArray;
  var string = {};
  Object.defineProperty(string, "__esModule", { value: true });
  var constants_1$7 = constants;
  var util_1$4 = util$1;
  function compressString(compressors2, context, obj, invertedIndex, writer2, options) {
    var foundRef;
    var stringIdent = constants_1$7.STRING_IDENT_PREFIX + obj;
    if (options.detectUtcTimestamps && obj[obj.length - 1] === "Z" && obj.match(constants_1$7.DATE_REGEX)) {
      var date2 = Date.parse(obj);
      compressors2.date(compressors2, context, date2, invertedIndex, writer2, options);
    } else if ((foundRef = invertedIndex.stringMap[stringIdent]) !== void 0) {
      writer2.write("" + constants_1$7.REF_STRING_TOKEN + foundRef);
    } else {
      var ref2 = util_1$4.compressInteger(invertedIndex.stringCount);
      var newRef = "" + constants_1$7.STRING_TOKEN + obj.replace(constants_1$7.REGEX_ESCAPE_CHARACTER, constants_1$7.ESCAPE_CHARACTER + constants_1$7.ESCAPE_CHARACTER).replace(constants_1$7.REGEX_STRING_TOKEN, constants_1$7.ESCAPED_STRING_TOKEN) + constants_1$7.STRING_TOKEN;
      if (ref2.length + constants_1$7.REFERENCE_HEADER_LENGTH + 1 < newRef.length) {
        invertedIndex.stringMap[stringIdent] = ref2;
        invertedIndex.stringCount++;
        writer2.write(newRef);
      } else {
        writer2.write("" + constants_1$7.UNREFERENCED_STRING_TOKEN + obj.replace(constants_1$7.REGEX_ESCAPE_CHARACTER, constants_1$7.ESCAPE_CHARACTER + constants_1$7.ESCAPE_CHARACTER).replace(constants_1$7.REGEX_UNREFERENCED_STRING_TOKEN, constants_1$7.ESCAPED_UNREFERENCED_STRING_TOKEN) + constants_1$7.UNREFERENCED_STRING_TOKEN);
      }
    }
  }
  string.compressString = compressString;
  var number = {};
  Object.defineProperty(number, "__esModule", { value: true });
  var constants_1$6 = constants;
  var util_1$3 = util$1;
  function compressNumber(compressors2, context, obj, invertedIndex, writer2, options) {
    var foundRef;
    if (obj % 1 === 0) {
      if (obj < constants_1$6.INTEGER_SMALL_EXCLUSIVE_BOUND_UPPER && obj > constants_1$6.INTEGER_SMALL_EXCLUSIVE_BOUND_LOWER) {
        writer2.write(constants_1$6.INTEGER_SMALL_TOKENS[obj + constants_1$6.INTEGER_SMALL_TOKEN_ELEMENT_OFFSET]);
      } else if ((foundRef = invertedIndex.integerMap[obj]) !== void 0) {
        writer2.write("" + constants_1$6.REF_INTEGER_TOKEN + foundRef);
      } else {
        var ref2 = util_1$3.compressInteger(invertedIndex.integerCount);
        var compressedInteger = util_1$3.compressInteger(obj);
        var newRef = "" + constants_1$6.INTEGER_TOKEN + compressedInteger;
        if (ref2.length + constants_1$6.REFERENCE_HEADER_LENGTH < newRef.length) {
          invertedIndex.integerMap[obj] = ref2;
          invertedIndex.integerCount++;
          writer2.write(newRef);
        } else {
          writer2.write("" + constants_1$6.UNREFERENCED_INTEGER_TOKEN + compressedInteger);
        }
      }
    } else {
      var compressedFloat = util_1$3.compressFloat(obj, options.fullPrecisionFloats);
      if ((foundRef = invertedIndex.floatMap[compressedFloat]) !== void 0) {
        writer2.write("" + constants_1$6.REF_FLOAT_TOKEN + foundRef);
      } else {
        var ref2 = util_1$3.compressInteger(invertedIndex.floatCount);
        var newRef = "" + constants_1$6.FLOAT_TOKEN + compressedFloat;
        if (ref2.length + constants_1$6.REFERENCE_HEADER_LENGTH < newRef.length) {
          invertedIndex.floatMap[compressedFloat] = ref2;
          invertedIndex.floatCount++;
          writer2.write(newRef);
        } else {
          writer2.write("" + constants_1$6.UNREFERENCED_FLOAT_TOKEN + compressedFloat);
        }
      }
    }
  }
  number.compressNumber = compressNumber;
  var object$1 = {};
  Object.defineProperty(object$1, "__esModule", { value: true });
  var constants_1$5 = constants;
  function compressObject(compressors2, context, obj, invertedIndex, writer2, options) {
    writer2.write(constants_1$5.OBJECT_START_TOKEN);
    var keys = Object.keys(obj);
    var templateObject = new compressors2.template.Object(obj[keys[0]], obj[keys[1]]);
    if (templateObject.isTemplating) {
      templateObject.compressTemplate(compressors2, context, invertedIndex, writer2, options);
    }
    for (var i = 0; i < keys.length; i++) {
      if (i > 1 && templateObject.isTemplating) {
        templateObject.isNextTemplateable(obj[keys[i]], writer2);
      }
      if (templateObject.isTemplating) {
        compressors2.string(compressors2, context, keys[i], invertedIndex, writer2, options);
        templateObject.compressTemplateValues(compressors2, context, invertedIndex, writer2, options, obj[keys[i]]);
      } else {
        var key = keys[i];
        var val = obj[key];
        if (val !== void 0) {
          compressors2.string(compressors2, context, key, invertedIndex, writer2, options);
          compressors2.any(compressors2, context, val, invertedIndex, writer2, options);
        }
      }
    }
    if (templateObject.isTemplating) {
      templateObject.end(writer2);
    }
    writer2.write(constants_1$5.OBJECT_END_TOKEN);
  }
  object$1.compressObject = compressObject;
  var date = {};
  Object.defineProperty(date, "__esModule", { value: true });
  var constants_1$4 = constants;
  var util_1$2 = util$1;
  function compressDate(compressors2, context, obj, invertedIndex, writer2, options) {
    var foundRef;
    var lowPrecisionDate = obj / constants_1$4.DATE_LOW_PRECISION;
    var isLowPrecision = lowPrecisionDate % 1 === 0;
    if (isLowPrecision) {
      if ((foundRef = invertedIndex.lpDateMap[lowPrecisionDate]) !== void 0) {
        writer2.write("" + constants_1$4.REF_LP_DATE_TOKEN + foundRef);
      } else {
        var ref2 = util_1$2.compressInteger(invertedIndex.lpDateCount);
        var compressedDate = util_1$2.compressInteger(lowPrecisionDate);
        var newRef = "" + constants_1$4.LP_DATE_TOKEN + compressedDate;
        if (ref2.length + constants_1$4.REFERENCE_HEADER_LENGTH < newRef.length) {
          invertedIndex.lpDateMap[lowPrecisionDate] = ref2;
          invertedIndex.lpDateCount++;
          writer2.write(newRef);
        } else {
          writer2.write("" + constants_1$4.UNREFERENCED_LP_DATE_TOKEN + compressedDate);
        }
      }
    } else {
      if ((foundRef = invertedIndex.dateMap[obj]) !== void 0) {
        writer2.write("" + constants_1$4.REF_DATE_TOKEN + foundRef);
      } else {
        var ref2 = util_1$2.compressInteger(invertedIndex.dateCount);
        var compressedDate = util_1$2.compressInteger(obj);
        var newRef = "" + constants_1$4.DATE_TOKEN + compressedDate;
        if (ref2.length + constants_1$4.REFERENCE_HEADER_LENGTH < newRef.length) {
          invertedIndex.dateMap[obj] = ref2;
          invertedIndex.dateCount++;
          writer2.write(newRef);
        } else {
          writer2.write("" + constants_1$4.UNREFERENCED_DATE_TOKEN + compressedDate);
        }
      }
    }
  }
  date.compressDate = compressDate;
  var object = {};
  var util = {};
  Object.defineProperty(util, "__esModule", { value: true });
  function isObject(obj) {
    var type = typeof obj;
    if (type === "number") {
      return false;
    } else if (type === "string") {
      return false;
    } else if (type === "boolean") {
      return false;
    } else if (obj === null) {
      return false;
    } else if (Array.isArray(obj)) {
      return false;
    } else if (obj instanceof Date) {
      return false;
    } else if (obj === void 0) {
      return false;
    } else {
      return true;
    }
  }
  util.isObject = isObject;
  Object.defineProperty(object, "__esModule", { value: true });
  var constants_1$3 = constants;
  var util_1$1 = util;
  var TemplateObject = (
    /** @class */
    function() {
      function TemplateObject2(a, b) {
        this.isTemplating = false;
        this.struct = [];
        if (a != null && b != null) {
          this.isTemplating = buildTemplate(a, b, this.struct);
        }
      }
      TemplateObject2.prototype.compressTemplate = function(compressors2, context, invertedIndex, writer2, options) {
        compresObjectTemplate(compressors2, context, invertedIndex, writer2, options, this.struct);
      };
      TemplateObject2.prototype.compressTemplateValues = function(compressors2, context, invertedIndex, writer2, options, obj) {
        compressObjectValues(compressors2, context, invertedIndex, writer2, options, this.struct, obj);
      };
      TemplateObject2.prototype.isNextTemplateable = function(obj, writer2) {
        this.isTemplating = conformsToStructure(this.struct, obj);
        if (!this.isTemplating) {
          writer2.write(constants_1$3.TEMPLATE_OBJECT_FINAL);
        }
      };
      TemplateObject2.prototype.end = function(writer2) {
        writer2.write(constants_1$3.TEMPLATE_OBJECT_FINAL);
      };
      return TemplateObject2;
    }()
  );
  object.TemplateObject = TemplateObject;
  function buildTemplate(a, b, struct, level) {
    if (level === void 0) {
      level = 0;
    }
    if (level > 6) {
      return false;
    }
    var keysA = Object.keys(a);
    var keysB = Object.keys(b);
    if (keysA.length !== keysB.length) {
      return false;
    }
    if (keysA.length > 10) {
      return false;
    }
    keysA.sort(function(a2, b2) {
      return a2.localeCompare(b2);
    });
    keysB.sort(function(a2, b2) {
      return a2.localeCompare(b2);
    });
    for (var i = 0; i < keysA.length; i++) {
      var keyA = keysA[i];
      var keyB = keysB[i];
      if (keyA !== keyB) {
        return false;
      }
      var valueA = a[keyA];
      var valueB = b[keyB];
      if (util_1$1.isObject(valueA)) {
        if (!util_1$1.isObject(valueB)) {
          return false;
        }
        var nextStruct = [];
        struct.push([keyA, nextStruct]);
        if (!buildTemplate(valueA, valueB, nextStruct, level + 1)) {
          return false;
        }
      } else if (util_1$1.isObject(valueB)) {
        return false;
      } else {
        struct.push([keyA]);
      }
    }
    return level > 0 || util_1$1.isObject(a);
  }
  function conformsToStructure(struct, obj) {
    if (!obj) {
      return false;
    }
    if (Object.keys(obj).length !== struct.length) {
      return false;
    }
    for (var i = 0; i < struct.length; i++) {
      var key = struct[i][0];
      var isNested = struct[i].length > 1;
      if (obj[key] === void 0) {
        return false;
      }
      if (isNested) {
        var x2 = struct[i];
        x2[1];
        if (!conformsToStructure(struct[i][1], obj[key])) {
          return false;
        }
      } else {
        if (util_1$1.isObject(obj[key])) {
          return false;
        }
      }
    }
    return true;
  }
  function compresObjectTemplate(compressors2, context, invertedIndex, writer2, options, struct) {
    writer2.write(constants_1$3.TEMPLATE_OBJECT_START);
    for (var i = 0; i < struct.length; i++) {
      var key = struct[i][0];
      var isNested = struct[i].length > 1;
      compressors2.string(compressors2, context, key, invertedIndex, writer2, options);
      if (isNested) {
        compresObjectTemplate(compressors2, context, invertedIndex, writer2, options, struct[i][1]);
      }
    }
    writer2.write(constants_1$3.TEMPLATE_OBJECT_END);
  }
  function compressObjectValues(compressors2, context, invertedIndex, writer2, options, struct, obj) {
    for (var i = 0; i < struct.length; i++) {
      var key = struct[i][0];
      var value = obj[key];
      var isNested = struct[i].length > 1;
      if (isNested) {
        compressObjectValues(compressors2, context, invertedIndex, writer2, options, struct[i][1], value);
      } else {
        compressors2.any(compressors2, context, value, invertedIndex, writer2, options);
      }
    }
  }
  Object.defineProperty(compress$1, "__esModule", { value: true });
  var any_1 = any;
  var array_1 = array$1;
  var string_1 = string;
  var number_1 = number;
  var object_1 = object$1;
  var date_1 = date;
  var object_2 = object;
  var compressors = {
    any: any_1.compressAny,
    array: array_1.compressArray,
    object: object_1.compressObject,
    string: string_1.compressString,
    date: date_1.compressDate,
    number: number_1.compressNumber,
    template: {
      Object: object_2.TemplateObject
    }
  };
  function makeCompressContext() {
    return {
      arrayItemWriters: [],
      arrayLevel: 0
    };
  }
  compress$1.makeCompressContext = makeCompressContext;
  function makeInvertedIndex() {
    return {
      stringMap: {},
      integerMap: {},
      floatMap: {},
      dateMap: {},
      lpDateMap: {},
      stringCount: 0,
      integerCount: 0,
      floatCount: 0,
      dateCount: 0,
      lpDateCount: 0
    };
  }
  compress$1.makeInvertedIndex = makeInvertedIndex;
  function compress(context, obj, invertedIndex, writer2, options) {
    compressors.any(compressors, context, obj, invertedIndex, writer2, options);
  }
  compress$1.compress = compress;
  var decompress$1 = {};
  var common = {};
  (function(exports) {
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.SKIP_SCALAR = {};
    (function(TargetType) {
      TargetType["ARRAY"] = "ARRAY";
      TargetType["OBJECT"] = "OBJECT";
      TargetType["SCALAR"] = "SCALAR";
      TargetType["TEMPLATE_OBJECT"] = "TEMPLATE_OBJECT";
      TargetType["TEMPLATE_OBJECT_PROPERTIES"] = "TEMPLATE_OBJECT_PROPERTIES";
      TargetType["TEMPLATE_OBJECT_ELEMENTS"] = "TEMPLATE_OBJECT_ELEMENTS";
    })(exports.TargetType || (exports.TargetType = {}));
  })(common);
  var stages = {};
  var scalar = {};
  Object.defineProperty(scalar, "__esModule", { value: true });
  var constants_1$2 = constants;
  var common_1$3 = common;
  var util_1 = util$1;
  function decompressScalar(token, data2, cursor, orderedIndex) {
    var startIndex = cursor.index;
    var endIndex = cursor.index + 1;
    var foundStringToken;
    if (token === constants_1$2.STRING_TOKEN && (foundStringToken = constants_1$2.STRING_TOKEN) || token === constants_1$2.UNREFERENCED_STRING_TOKEN && (foundStringToken = constants_1$2.UNREFERENCED_STRING_TOKEN)) {
      var escaped = true;
      while (escaped && endIndex < data2.length) {
        endIndex = data2.indexOf(foundStringToken, endIndex);
        var iNumEscapeCharacters = 1;
        escaped = false;
        while (data2[endIndex - iNumEscapeCharacters] === constants_1$2.ESCAPE_CHARACTER) {
          escaped = iNumEscapeCharacters % 2 === 1;
          iNumEscapeCharacters++;
        }
        endIndex++;
      }
      if (endIndex <= startIndex) {
        endIndex = data2.length;
      }
    } else {
      while (!(data2.charCodeAt(endIndex) > constants_1$2.DELIMITING_TOKENS_THRESHOLD) && endIndex < data2.length) {
        endIndex++;
      }
    }
    if (!cursor.drain && endIndex === data2.length) {
      return common_1$3.SKIP_SCALAR;
    }
    cursor.index = endIndex - 1;
    var tokenCharCode = token.charCodeAt(0);
    if (tokenCharCode > constants_1$2.INTEGER_SMALL_TOKEN_EXCLUSIVE_BOUND_LOWER && tokenCharCode < constants_1$2.INTEGER_SMALL_TOKEN_EXCLUSIVE_BOUND_UPPER) {
      return tokenCharCode + constants_1$2.INTEGER_SMALL_TOKEN_OFFSET;
    } else if (token === constants_1$2.ARRAY_REPEAT_MANY_TOKEN) {
      return util_1.decompressInteger(data2.substring(startIndex + 1, endIndex));
    } else if (token === constants_1$2.REF_STRING_TOKEN) {
      return orderedIndex.strings[util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))];
    } else if (token === constants_1$2.REF_INTEGER_TOKEN) {
      return orderedIndex.integers[util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))];
    } else if (token === constants_1$2.REF_FLOAT_TOKEN) {
      return orderedIndex.floats[util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))];
    } else if (token === constants_1$2.REF_DATE_TOKEN) {
      return orderedIndex.dates[util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))];
    } else if (token === constants_1$2.REF_LP_DATE_TOKEN) {
      return orderedIndex.lpDates[util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))];
    } else if (token === constants_1$2.STRING_TOKEN) {
      return orderedIndex.strings[orderedIndex.strings.length] = data2.substring(startIndex + 1, endIndex - 1).replace(constants_1$2.REGEX_ESCAPED_ESCAPE_CHARACTER, constants_1$2.ESCAPE_CHARACTER).replace(constants_1$2.REGEX_ESCAPED_STRING_TOKEN, constants_1$2.STRING_TOKEN);
    } else if (token === constants_1$2.INTEGER_TOKEN) {
      return orderedIndex.integers[orderedIndex.integers.length] = util_1.decompressInteger(data2.substring(startIndex + 1, endIndex));
    } else if (token === constants_1$2.FLOAT_TOKEN) {
      return orderedIndex.floats[orderedIndex.floats.length] = util_1.decompressFloat(data2.substring(startIndex + 1, endIndex));
    } else if (token === constants_1$2.DATE_TOKEN) {
      return orderedIndex.dates[orderedIndex.dates.length] = new Date(util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))).toISOString();
    } else if (token === constants_1$2.LP_DATE_TOKEN) {
      return orderedIndex.lpDates[orderedIndex.lpDates.length] = new Date(constants_1$2.DATE_LOW_PRECISION * util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))).toISOString();
    } else if (token === constants_1$2.UNREFERENCED_STRING_TOKEN) {
      return data2.substring(startIndex + 1, endIndex - 1).replace(constants_1$2.REGEX_ESCAPED_ESCAPE_CHARACTER, constants_1$2.ESCAPE_CHARACTER).replace(constants_1$2.REGEX_UNREFERENCED_ESCAPED_STRING_TOKEN, constants_1$2.UNREFERENCED_STRING_TOKEN);
    } else if (token === constants_1$2.UNREFERENCED_INTEGER_TOKEN) {
      return util_1.decompressInteger(data2.substring(startIndex + 1, endIndex));
    } else if (token === constants_1$2.UNREFERENCED_FLOAT_TOKEN) {
      return util_1.decompressFloat(data2.substring(startIndex + 1, endIndex));
    } else if (token === constants_1$2.UNREFERENCED_DATE_TOKEN) {
      return new Date(util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))).toISOString();
    } else if (token === constants_1$2.UNREFERENCED_LP_DATE_TOKEN) {
      return new Date(constants_1$2.DATE_LOW_PRECISION * util_1.decompressInteger(data2.substring(startIndex + 1, endIndex))).toISOString();
    } else if (token === constants_1$2.BOOLEAN_TRUE_TOKEN) {
      return true;
    } else if (token === constants_1$2.BOOLEAN_FALSE_TOKEN) {
      return false;
    } else if (token === constants_1$2.NULL_TOKEN) {
      return null;
    } else if (token === constants_1$2.UNDEFINED_TOKEN) {
      return void 0;
    }
    throw new Error("Unexpected scalar " + token + " at " + startIndex + "-" + endIndex);
  }
  scalar.decompressScalar = decompressScalar;
  var element = {};
  var template = {};
  Object.defineProperty(template, "__esModule", { value: true });
  function appendTemplateObjectValue(templateObjectTarget, targetValue) {
    var currentPath = templateObjectTarget.paths[templateObjectTarget.currentPathIndex];
    var i = 0;
    var targetObject = templateObjectTarget.currentObject;
    for (; i < currentPath.length - 1; i++) {
      var fragment = currentPath[i];
      targetObject = targetObject[fragment] = targetObject[fragment] || {};
    }
    if (targetValue !== void 0) {
      targetObject[currentPath[i]] = targetValue;
    }
  }
  function appendTemplateObjectPropertiesValue(templateObjectElementsTarget, targetValue) {
    if (templateObjectElementsTarget.currentPathIndex === -1) {
      templateObjectElementsTarget.value[targetValue] = templateObjectElementsTarget.currentObject = {};
    } else {
      appendTemplateObjectValue(templateObjectElementsTarget, targetValue);
    }
    if (++templateObjectElementsTarget.currentPathIndex === templateObjectElementsTarget.expectedPaths) {
      templateObjectElementsTarget.currentPathIndex = -1;
    }
  }
  template.appendTemplateObjectPropertiesValue = appendTemplateObjectPropertiesValue;
  function appendTemplateObjectElementsValue(templateObjectPropertiesTarget, targetValue) {
    if (templateObjectPropertiesTarget.currentPathIndex === 0) {
      templateObjectPropertiesTarget.currentObject = {};
      templateObjectPropertiesTarget.value.push(templateObjectPropertiesTarget.currentObject);
    }
    appendTemplateObjectValue(templateObjectPropertiesTarget, targetValue);
    if (++templateObjectPropertiesTarget.currentPathIndex === templateObjectPropertiesTarget.expectedPaths) {
      templateObjectPropertiesTarget.currentPathIndex = 0;
    }
  }
  template.appendTemplateObjectElementsValue = appendTemplateObjectElementsValue;
  Object.defineProperty(element, "__esModule", { value: true });
  var constants_1$1 = constants;
  var common_1$2 = common;
  var scalar_1$1 = scalar;
  var template_1 = template;
  function decompressElement(c, cursor, data2, orderedIndex) {
    var targetValue;
    if (c === constants_1$1.ARRAY_END_TOKEN || c === constants_1$1.OBJECT_END_TOKEN) {
      targetValue = cursor.currentTarget.value;
      cursor.currentTarget = cursor.stack[cursor.pointer - 1];
      cursor.pointer--;
    } else {
      targetValue = scalar_1$1.decompressScalar(c, data2, cursor, orderedIndex);
      if (targetValue === common_1$2.SKIP_SCALAR) {
        return false;
      }
    }
    if (cursor.currentTarget.type === common_1$2.TargetType.SCALAR) {
      cursor.currentTarget.value = targetValue;
    } else if (cursor.currentTarget.type === common_1$2.TargetType.ARRAY) {
      cursor.currentTarget.value[cursor.currentTarget.value.length] = targetValue;
    } else if (cursor.currentTarget.type === common_1$2.TargetType.OBJECT) {
      if (cursor.currentTarget.key != null) {
        cursor.currentTarget.value[cursor.currentTarget.key] = targetValue;
        cursor.currentTarget.key = void 0;
      } else {
        cursor.currentTarget.key = targetValue;
      }
    } else if (cursor.currentTarget.type === common_1$2.TargetType.TEMPLATE_OBJECT) {
      cursor.currentTarget.currentToken = targetValue;
      cursor.currentTarget.currentTokens.push(targetValue);
    } else if (cursor.currentTarget.type === common_1$2.TargetType.TEMPLATE_OBJECT_PROPERTIES) {
      template_1.appendTemplateObjectPropertiesValue(cursor.currentTarget, targetValue);
    } else if (cursor.currentTarget.type === common_1$2.TargetType.TEMPLATE_OBJECT_ELEMENTS) {
      template_1.appendTemplateObjectElementsValue(cursor.currentTarget, targetValue);
    }
    return true;
  }
  element.decompressElement = decompressElement;
  Object.defineProperty(stages, "__esModule", { value: true });
  var constants_1 = constants;
  var common_1$1 = common;
  var scalar_1 = scalar;
  var element_1 = element;
  function decompressStages(cursor, data2, orderedIndex) {
    for (; cursor.index < data2.length; cursor.index++) {
      var c = data2[cursor.index];
      if (c === constants_1.ARRAY_START_TOKEN) {
        cursor.currentTarget = { type: common_1$1.TargetType.ARRAY, value: [] };
        cursor.stack[++cursor.pointer] = cursor.currentTarget;
      } else if (c === constants_1.OBJECT_START_TOKEN) {
        cursor.currentTarget = { type: common_1$1.TargetType.OBJECT, value: {} };
        cursor.stack[++cursor.pointer] = cursor.currentTarget;
      } else if (c === constants_1.ARRAY_REPEAT_TOKEN && (cursor.currentTarget.type === common_1$1.TargetType.ARRAY || cursor.currentTarget.type === common_1$1.TargetType.TEMPLATE_OBJECT_ELEMENTS)) {
        var repeatedItem = cursor.currentTarget.value[cursor.currentTarget.value.length - 1];
        cursor.currentTarget.value.push(repeatedItem);
      } else if (c === constants_1.ARRAY_REPEAT_MANY_TOKEN && (cursor.currentTarget.type === common_1$1.TargetType.ARRAY || cursor.currentTarget.type === common_1$1.TargetType.TEMPLATE_OBJECT_ELEMENTS)) {
        var repeatCount = scalar_1.decompressScalar(data2[cursor.index], data2, cursor, orderedIndex);
        if (repeatCount === common_1$1.SKIP_SCALAR) {
          return;
        }
        var repeatedItem = cursor.currentTarget.value[cursor.currentTarget.value.length - 1];
        for (var i = 0; i < repeatCount; i++) {
          cursor.currentTarget.value.push(repeatedItem);
        }
      } else if (c === constants_1.TEMPLATE_OBJECT_START && (cursor.currentTarget.type === common_1$1.TargetType.TEMPLATE_OBJECT || cursor.currentTarget.type === common_1$1.TargetType.OBJECT || cursor.currentTarget.type === common_1$1.TargetType.ARRAY)) {
        if (cursor.currentTarget.type !== common_1$1.TargetType.TEMPLATE_OBJECT) {
          var parentTarget = cursor.currentTarget;
          cursor.currentTarget = { type: common_1$1.TargetType.TEMPLATE_OBJECT, value: void 0, currentTokens: [], currentRoute: [], paths: [], level: 0, parentTarget };
          cursor.stack[++cursor.pointer] = cursor.currentTarget;
        } else {
          for (var i = 0; i < cursor.currentTarget.currentTokens.length - 1; i++) {
            var currentToken = cursor.currentTarget.currentTokens[i];
            cursor.currentTarget.paths[cursor.currentTarget.paths.length] = cursor.currentTarget.currentRoute.concat(currentToken);
          }
          if (cursor.currentTarget.currentToken != null) {
            cursor.currentTarget.currentRoute.push(cursor.currentTarget.currentToken);
          }
          cursor.currentTarget.currentTokens = [];
          cursor.currentTarget.level++;
        }
      } else if (c === constants_1.TEMPLATE_OBJECT_END && cursor.currentTarget.type === common_1$1.TargetType.TEMPLATE_OBJECT) {
        for (var i = 0; i < cursor.currentTarget.currentTokens.length; i++) {
          var currentToken = cursor.currentTarget.currentTokens[i];
          cursor.currentTarget.paths[cursor.currentTarget.paths.length] = cursor.currentTarget.currentRoute.concat(currentToken);
        }
        cursor.currentTarget.currentTokens = [];
        cursor.currentTarget.currentRoute = cursor.currentTarget.currentRoute.slice(0, -1);
        cursor.currentTarget.level--;
        if (cursor.currentTarget.level < 0) {
          var paths = cursor.currentTarget.paths;
          var parentTarget = cursor.currentTarget.parentTarget;
          cursor.pointer--;
          if (parentTarget.type === common_1$1.TargetType.ARRAY) {
            cursor.currentTarget = { type: common_1$1.TargetType.TEMPLATE_OBJECT_ELEMENTS, value: parentTarget.value, paths, currentPathIndex: 0, expectedPaths: paths.length, currentObject: {} };
          } else if (parentTarget.type === common_1$1.TargetType.OBJECT) {
            cursor.currentTarget = { type: common_1$1.TargetType.TEMPLATE_OBJECT_PROPERTIES, value: parentTarget.value, paths, currentPathIndex: -1, expectedPaths: paths.length, currentObject: {} };
          }
          cursor.stack[++cursor.pointer] = cursor.currentTarget;
        }
      } else if (c === constants_1.TEMPLATE_OBJECT_FINAL) {
        cursor.currentTarget = cursor.stack[--cursor.pointer];
      } else {
        if (!element_1.decompressElement(c, cursor, data2, orderedIndex)) {
          return;
        }
      }
    }
  }
  stages.decompressStages = decompressStages;
  Object.defineProperty(decompress$1, "__esModule", { value: true });
  var common_1 = common;
  var stages_1 = stages;
  function makeOrderedIndex() {
    return {
      strings: [],
      integers: [],
      floats: [],
      dates: [],
      lpDates: []
    };
  }
  decompress$1.makeOrderedIndex = makeOrderedIndex;
  function makeCursor(drain) {
    var rootTarget = { type: common_1.TargetType.SCALAR, value: void 0 };
    var stack = new Array(10);
    stack[0] = rootTarget;
    return { index: 0, rootTarget, stack, currentTarget: rootTarget, pointer: 0, drain };
  }
  function decompress(data2, orderedIndex) {
    var cursor = makeCursor(true);
    stages_1.decompressStages(cursor, data2, orderedIndex);
    return cursor.rootTarget.value;
  }
  decompress$1.decompress = decompress;
  function decompressIncremental(orderedIndex) {
    var cursor = makeCursor(false);
    var buffer = "";
    function increment(data2) {
      if (data2 === null) {
        cursor.drain = true;
      } else if (data2.length === 0) {
        return;
      } else {
        buffer += data2;
      }
      var cursorIndexBefore = cursor.index;
      stages_1.decompressStages(cursor, buffer, orderedIndex);
      var movedAmount = cursor.index - cursorIndexBefore;
      if (movedAmount > 0) {
        buffer = buffer.substring(movedAmount);
        cursor.index -= movedAmount;
      }
    }
    return { increment, cursor };
  }
  decompress$1.decompressIncremental = decompressIncremental;
  (function(exports) {
    function __export(m) {
      for (var p in m)
        if (!exports.hasOwnProperty(p))
          exports[p] = m[p];
    }
    Object.defineProperty(exports, "__esModule", { value: true });
    var compress_1 = compress$1;
    var writer_12 = writer;
    var decompress_1 = decompress$1;
    __export(writer);
    __export(common);
    function parse(data2) {
      var orderedIndex = decompress_1.makeOrderedIndex();
      return decompress_1.decompress(data2, orderedIndex);
    }
    exports.parse = parse;
    function parseIncremental() {
      var orderedIndex = decompress_1.makeOrderedIndex();
      var _a = decompress_1.decompressIncremental(orderedIndex), cursor = _a.cursor, increment = _a.increment;
      return function(data2) {
        increment(data2);
        if (data2 === null) {
          return cursor.rootTarget.value;
        }
      };
    }
    exports.parseIncremental = parseIncremental;
    function stringifyTo(data2, writer2, options) {
      if (options === void 0) {
        options = {};
      }
      var invertedIndex = compress_1.makeInvertedIndex();
      var context = compress_1.makeCompressContext();
      compress_1.compress(context, data2, invertedIndex, writer2, options);
      writer2.end();
    }
    exports.stringifyTo = stringifyTo;
    function stringify(data2, options) {
      var writer2 = new writer_12.ZipsonStringWriter();
      stringifyTo(data2, writer2, options);
      return writer2.value;
    }
    exports.stringify = stringify;
  })(lib);
  const useStore = defineStore("store", {
    state() {
      return {
        // ####################
        // 元件相關狀態
        // ####################
        isDarkMode: false,
        isToolbarsShow: false,
        isPopupShow: {
          sheet: false,
          chord: false,
          font: false,
          settings: false,
          menu: false,
          // 選單內功能
          hotkey: false
        },
        // ####################
        // 偏好設定相關狀態
        // ####################
        agreeToArchiveSheet: true,
        // ####################
        // 譜面相關狀態
        // ####################
        transpose: 0,
        /** 在 `StoreHandler` 裡賦值 */
        originalCapo: 0,
        /** 在 `StoreHandler` 裡賦值,HTML 格式 */
        originalKey: "",
        /** `font-size` 的變化值 */
        fontSizeDelta: 0,
        /** 在 `StoreHandler` 裡賦值,單位為 px */
        originalFontSize: 0,
        /** 在 `StoreHandler` 裡賦值,單位為 px */
        originalLineHeight: 0
      };
    },
    persist: {
      key: "plus91-preferences",
      storage: MonkeyStorage,
      deserialize: lib.parse,
      serialize: lib.stringify,
      paths: ["isDarkMode", "agreeToArchiveSheet"],
      beforeRestore() {
        console.log("[91 Plus] 讀取偏好設置中");
      },
      afterRestore() {
        console.log("[91 Plus] 偏好設置讀取完畢");
      },
      debug: true
    },
    getters: {
      currentCapo() {
        return this.originalCapo + this.transpose;
      },
      currentKey() {
        return new Chord(this.originalKey).transpose(-this.transpose).toFormattedString();
      }
    },
    actions: {
      toggleToolbars() {
        if (this.isToolbarsShow) {
          this.closePopups();
        } else {
          this.isPopupShow.sheet = true;
        }
        this.isToolbarsShow = !this.isToolbarsShow;
      },
      closePopups() {
        for (const popup in this.isPopupShow) {
          this.isPopupShow[popup] = false;
        }
      },
      /** @param {'sheet'|'chord'|'font'|'settings'|'menu'|'hotkey'} name */
      togglePopup(name) {
        for (const popup in this.isPopupShow) {
          if (popup === name) {
            this.isPopupShow[popup] = !this.isPopupShow[popup];
          } else {
            this.isPopupShow[popup] = false;
          }
        }
      },
      plusTranspose(numberToPlus) {
        let newTranspose = this.transpose + numberToPlus;
        const newCapo = this.originalCapo + newTranspose;
        if (newCapo === 12 || newCapo === -12) {
          newTranspose = -this.originalCapo;
        }
        this.transpose = newTranspose;
      }
    }
  });
  const _hoisted_1$e = ["active"];
  const _sfc_main$f = {
    __name: "BootstrapIcon",
    props: {
      icon: {
        type: String,
        required: true
      },
      color: {
        type: String,
        default: "whitesmoke"
      },
      size: {
        type: String,
        default: "1rem"
      },
      stroke: {
        type: String,
        default: "0"
      },
      active: {
        type: Boolean,
        default: false
      }
    },
    setup(__props) {
      vue.useCssVars((_ctx) => ({
        "2d5c579c": __props.color,
        "0168355c": __props.size,
        "5c7f6b49": __props.stroke
      }));
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("i", {
          class: vue.normalizeClass(`bi bi-${__props.icon}`),
          active: __props.active
        }, null, 10, _hoisted_1$e);
      };
    }
  };
  const BootstrapIcon = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-33d92514"]]);
  const _hoisted_1$d = { class: "toolbar-icon" };
  const _sfc_main$e = {
    __name: "ToolbarIcon",
    props: {
      icon: {
        type: String,
        required: true
      },
      stroke: {
        type: String,
        default: "0"
      },
      active: {
        type: Boolean,
        default: false
      },
      color: {
        type: String,
        default: "whitesmoke"
      }
    },
    setup(__props) {
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$d, [
          vue.createVNode(BootstrapIcon, {
            icon: __props.icon,
            color: __props.color,
            size: "1.3rem",
            stroke: __props.stroke,
            active: __props.active
          }, null, 8, ["icon", "color", "stroke", "active"])
        ]);
      };
    }
  };
  const ToolbarIcon = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-2b5c1219"]]);
  const _hoisted_1$c = { class: "adjust-widget" };
  const _hoisted_2$b = ["disabled"];
  const _hoisted_3$6 = ["disabled"];
  const _hoisted_4$4 = ["disabled"];
  const _sfc_main$d = {
    __name: "AdjustWidget",
    props: {
      iconLeft: {
        type: String,
        default: "caret-left-fill"
      },
      iconRight: {
        type: String,
        default: "caret-right-fill"
      },
      disabledLeft: {
        type: Boolean,
        default: false
      },
      disabledMiddle: {
        type: Boolean,
        default: false
      },
      disabledRight: {
        type: Boolean,
        default: false
      },
      color: {
        type: String,
        default: "#444"
      },
      size: {
        type: String,
        default: "1.25rem"
      },
      onclickLeft: Function,
      onclickMiddle: Function,
      onclickRight: Function
    },
    setup(__props) {
      vue.useCssVars((_ctx) => ({
        "791a4684": __props.color,
        "37e19b46": __props.size
      }));
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, [
          vue.createElementVNode("button", {
            class: "adjust-button adjust-button-left",
            onClick: _cache[0] || (_cache[0] = (...args) => __props.onclickLeft && __props.onclickLeft(...args)),
            disabled: __props.disabledLeft
          }, [
            vue.createVNode(BootstrapIcon, {
              icon: __props.iconLeft,
              color: __props.color,
              size: __props.size
            }, null, 8, ["icon", "color", "size"])
          ], 8, _hoisted_2$b),
          vue.createElementVNode("button", {
            class: "adjust-button adjust-button-middle",
            onClick: _cache[1] || (_cache[1] = (...args) => __props.onclickMiddle && __props.onclickMiddle(...args)),
            disabled: __props.disabledMiddle
          }, [
            vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
          ], 8, _hoisted_3$6),
          vue.createElementVNode("button", {
            class: "adjust-button adjust-button-right",
            onClick: _cache[2] || (_cache[2] = (...args) => __props.onclickRight && __props.onclickRight(...args)),
            disabled: __props.disabledRight
          }, [
            vue.createVNode(BootstrapIcon, {
              icon: __props.iconRight,
              color: __props.color,
              size: __props.size
            }, null, 8, ["icon", "color", "size"])
          ], 8, _hoisted_4$4)
        ]);
      };
    }
  };
  const AdjustWidget = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["__scopeId", "data-v-1c41dc23"]]);
  class ChordSheetElement {
    /** @param {HTMLElement} chordSheetElement  */
    constructor(chordSheetElement) {
      /** @param {NodeList} nodeList */
      __privateAdd(this, _unformat);
      this.chordSheetElement = chordSheetElement;
    }
    /**
     * 將 Header 和譜上的和弦移調,並實質修改於 DOM
     * @param {number} delta 相對於當前調的移調值
     */
    static transposeSheet(delta) {
      $("#tone_z .tf").each(function() {
        const chord = new Chord($(this).text());
        const newChordHTML = chord.transpose(-delta).toFormattedString();
        $(this).html(newChordHTML);
      });
    }
    /** @returns {ChordSheetElement} */
    formatUnderlines() {
      const underlineEl = this.chordSheetElement.querySelectorAll("u");
      const doubleUnderlineEl = this.chordSheetElement.querySelectorAll("abbr");
      underlineEl.forEach((el) => {
        el.innerText = `{_${el.innerText}_}`;
      });
      doubleUnderlineEl.forEach((el) => {
        el.innerText = `{=${el.innerText}=}`;
      });
      return this;
    }
    /** @returns {ChordSheetElement} */
    unformatUnderlines() {
      const underlineEl = this.chordSheetElement.querySelectorAll("u");
      const doubleUnderlineEl = this.chordSheetElement.querySelectorAll("abbr");
      __privateMethod(this, _unformat, unformat_fn).call(this, underlineEl);
      __privateMethod(this, _unformat, unformat_fn).call(this, doubleUnderlineEl);
      return this;
    }
  }
  _unformat = new WeakSet();
  unformat_fn = function(nodeList) {
    nodeList.forEach((el) => {
      el.innerHTML = el.innerText.replaceAll(/{_|{=|=}|_}/g, "").replaceAll(
        /[a-zA-Z0-9#/]+/g,
        /* html */
        `<span class="tf">$&</span>`
      );
    });
  };
  class ChordSheetDocument {
    constructor() {
      this.el = {
        mtitle: document.getElementById("mtitle"),
        tkinfo: document.querySelector(".tkinfo"),
        capoSelect: document.querySelector(".capo .select"),
        tinfo: document.querySelector(".tinfo"),
        tone_z: document.getElementById("tone_z")
      };
    }
    getId() {
      const urlParams = new URLSearchParams(window.location.search);
      return Number(urlParams.get("id"));
    }
    getTitle() {
      return this.el.mtitle.innerText.trim();
    }
    getKey() {
      var _a;
      const match = (_a = this.el.tkinfo) == null ? void 0 : _a.innerText.match(new RegExp("(?<=原調:)\\w*"));
      return match ? match[0].trim() : "";
    }
    getPlay() {
      var _a;
      const match = (_a = this.el.capoSelect) == null ? void 0 : _a.innerText.split(/\s*\/\s*/);
      return match ? match[1].trim() : "";
    }
    getCapo() {
      var _a;
      const match = (_a = this.el.capoSelect) == null ? void 0 : _a.innerText.split(/\s*\/\s*/);
      return match ? Number(match[0]) : 0;
    }
    getSinger() {
      var _a;
      const match = (_a = this.el.tinfo) == null ? void 0 : _a.innerText.match(new RegExp("(?<=演唱:).*(?=\\n|$)"));
      return match ? match[0].trim() : "";
    }
    getComposer() {
      var _a;
      const match = (_a = this.el.tinfo) == null ? void 0 : _a.innerText.match(new RegExp("(?<=曲:).*?(?=詞:|$)"));
      return match ? match[0].trim() : "";
    }
    getLyricist() {
      var _a;
      const match = (_a = this.el.tinfo) == null ? void 0 : _a.innerText.match(new RegExp("(?<=詞:).*?(?=曲:|$)"));
      return match ? match[0].trim() : "";
    }
    getBpm() {
      var _a;
      const match = (_a = this.el.tkinfo) == null ? void 0 : _a.innerText.match(/\d+/);
      return match ? Number(match[0]) : 0;
    }
    getSheetText() {
      const formattedChordSheet = this.el.tone_z.innerText.replaceAll(/\s+?\n/g, "\n").replaceAll("\n\n", "\n").trim().replaceAll(/\s+/g, (match) => {
        return `{%${match.length}%}`;
      });
      return formattedChordSheet;
    }
  }
  class StoreHandler {
    constructor() {
      /** 當 `#store.transpose` 變動時,將譜面上的和弦進行移調 */
      __privateAdd(this, _watchTranspose);
      __privateAdd(this, _watchFontSize);
      // 命 `#store` 為私有屬性,在建立實例時再賦值,避免衝突
      __privateAdd(this, _store, void 0);
      __privateSet(this, _store, useStore());
    }
    initState() {
      const capoSelected = $(".capo .select").eq(0).text().trim();
      const originalCapo = +capoSelected.split(/\s*\/\s*/)[0];
      const originalKey = capoSelected.split(/\s*\/\s*/)[1];
      __privateGet(this, _store).originalCapo = originalCapo;
      __privateGet(this, _store).originalKey = originalKey;
      const fontSize = +$("#tone_z").css("font-size").match(/^\d+/)[0];
      const lineHeight = +$("#tone_z > p").css("line-height").match(/^\d+/)[0];
      __privateGet(this, _store).originalFontSize = fontSize;
      __privateGet(this, _store).originalLineHeight = lineHeight;
      const params = getQueryParams();
      if (params.transpose) {
        __privateGet(this, _store).transpose = params.transpose;
      }
    }
    start() {
      __privateMethod(this, _watchTranspose, watchTranspose_fn).call(this);
      __privateMethod(this, _watchFontSize, watchFontSize_fn).call(this);
      return this;
    }
    static handleKeydown(key) {
      const store = useStore();
      switch (key) {
        case " ": {
          store.toggleToolbars();
          break;
        }
        case "/": {
          if (!store.isToolbarsShow) {
            store.toggleToolbars();
            store.closePopups();
          }
          setTimeout(() => {
            $("#plus91-header input").get(0).focus();
          }, 0);
          break;
        }
        case "Escape": {
          if (store.isToolbarsShow) {
            store.toggleToolbars();
          }
          break;
        }
      }
      if (store.isPopupShow.sheet) {
        switch (key) {
          case "ArrowLeft": {
            store.plusTranspose(-1);
            break;
          }
          case "ArrowRight": {
            store.plusTranspose(1);
            break;
          }
          case "ArrowDown": {
            store.transpose = 0;
            break;
          }
        }
      }
    }
  }
  _store = new WeakMap();
  _watchTranspose = new WeakSet();
  watchTranspose_fn = function() {
    vue.watch(() => {
      return __privateGet(this, _store).transpose;
    }, (newValue, oldValue) => {
      ChordSheetElement.transposeSheet((newValue - oldValue) % 12);
    });
  };
  _watchFontSize = new WeakSet();
  watchFontSize_fn = function() {
    vue.watch(() => {
      return __privateGet(this, _store).fontSizeDelta;
    }, (newValue) => {
      const oFontSize = __privateGet(this, _store).originalFontSize;
      const oLineHeight = __privateGet(this, _store).originalLineHeight;
      $("#tone_z").css("font-size", `${oFontSize + newValue}px`);
      $("#tone_z > p").css("line-height", `${oLineHeight + newValue}px`);
    });
  };
  function redirect() {
    const currentUrl = window.location.href;
    if (/\/song\//.test(currentUrl)) {
      const sheetId = currentUrl.match(new RegExp("(?<=\\/)\\d+(?=\\.)"))[0];
      const newUrl = `https://www.91pu.com.tw/m/tone.shtml?id=${sheetId}`;
      window.location.replace(newUrl);
    }
  }
  function injectGtag() {
    const newScript = document.createElement("script");
    newScript.src = "https://www.googletagmanager.com/gtag/js?id=G-JF4S3HZY31";
    newScript.async = true;
    document.head.appendChild(newScript);
    newScript.onload = () => {
      window.dataLayer = window.dataLayer || [];
      function gtag() {
        window.dataLayer.push(arguments);
      }
      gtag("js", /* @__PURE__ */ new Date());
      gtag("config", "G-JF4S3HZY31");
    };
  }
  function getQueryParams() {
    const url = new URL(window.location.href);
    const params = {
      transpose: +url.searchParams.get("transpose"),
      darkMode: !!url.searchParams.get("darkmode")
    };
    return params;
  }
  function changeTitle() {
    const newTitle = $("#mtitle").text().trim();
    document.title = `${newTitle} | 91+`;
  }
  function archiveChordSheet() {
    const sheet = document.getElementById("tone_z");
    const chordSheetDocument = new ChordSheetDocument();
    try {
      const chordSheetElement = new ChordSheetElement(sheet);
      chordSheetElement.formatUnderlines();
      const formBody = {
        id: chordSheetDocument.getId(),
        title: chordSheetDocument.getTitle(),
        key: chordSheetDocument.getKey(),
        play: chordSheetDocument.getPlay(),
        capo: chordSheetDocument.getCapo(),
        singer: chordSheetDocument.getSinger(),
        composer: chordSheetDocument.getComposer(),
        lyricist: chordSheetDocument.getLyricist(),
        bpm: chordSheetDocument.getBpm(),
        sheet_text: chordSheetDocument.getSheetText()
      };
      chordSheetElement.unformatUnderlines();
      fetch("https://91-plus-plus-api.fly.dev/archive", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify(formBody)
      }).then((response) => {
        console.log("[91 Plus] 雲端樂譜備份成功:", response);
      }).catch((error) => {
        console.error("[91 Plus] 雲端樂譜備份失敗:", error);
      });
    } catch {
      console.warn("[91 Plus] 樂譜解析失敗,無法備份");
      fetch(
        `https://91-plus-plus-api.fly.dev/report?id=${chordSheetDocument.getId()}`
      );
    }
  }
  function initMutationObserver() {
    return new MutationObserver((records, observer) => {
      const isMutationDone = !!document.querySelector("#tone_z").childElementCount;
      if (!isMutationDone) {
        return;
      }
      $("body").trigger("mutation.done");
      observer.disconnect();
    }).observe(document.body, { childList: true, subtree: true });
  }
  function onDomReady(callback) {
    $("body").on("mutation.done", callback);
  }
  function handleEvents() {
    $("html").on("keydown", (event) => {
      const excludedTags = ["input"];
      const tagName = event.target.tagName.toLowerCase();
      if (excludedTags.includes(tagName)) {
        return;
      }
      StoreHandler.handleKeydown(event.key);
    });
  }
  function switchInstrument(instrument) {
    switch (instrument) {
      case "guitar": {
        $(".schord").trigger("click");
        break;
      }
      case "ukulele": {
        $(".ukschord").trigger("click");
        break;
      }
      default: {
        $(".nsChord").trigger("click");
        break;
      }
    }
  }
  function getChordShapes() {
    const chordShapes = window.chord_shapes;
    return chordShapes;
  }
  function getChordList() {
    const chordList = [];
    $("#tone_z .tf").each(function() {
      chordList.push($(this).text());
    });
    return [...new Set(chordList)];
  }
  function convertChordName(chordName) {
    const root2 = chordName.match(/^[A-G]#?/)[0];
    const rest = chordName.replace(/^[A-G]#?/, "");
    return `${rest} ${root2}`;
  }
  const _hoisted_1$b = { id: "plus91-sheet-popup" };
  const _hoisted_2$a = { class: "sheet-popup-container" };
  const _hoisted_3$5 = { class: "text-capo" };
  const _hoisted_4$3 = ["innerHTML"];
  const _hoisted_5$1 = { class: "transpose-range-container" };
  const _hoisted_6$1 = ["value"];
  const _hoisted_7 = { class: "instrument-select-container" };
  const _sfc_main$c = {
    __name: "SheetPopup",
    setup(__props) {
      const store = useStore();
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide-and-fade" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$b, [
              vue.createElementVNode("div", _hoisted_2$a, [
                vue.createVNode(AdjustWidget, {
                  "onclick-left": () => {
                    vue.unref(store).plusTranspose(-1);
                  },
                  "onclick-middle": () => {
                    vue.unref(store).transpose = 0;
                  },
                  "onclick-right": () => {
                    vue.unref(store).plusTranspose(1);
                  }
                }, {
                  default: vue.withCtx(() => [
                    vue.createTextVNode(" CAPO:"),
                    vue.createElementVNode("span", _hoisted_3$5, vue.toDisplayString(vue.unref(store).currentCapo), 1),
                    vue.createTextVNode(" ("),
                    vue.createElementVNode("span", {
                      class: "text-key",
                      innerHTML: vue.unref(store).currentKey
                    }, null, 8, _hoisted_4$3),
                    vue.createTextVNode(") ")
                  ]),
                  _: 1
                }, 8, ["onclick-left", "onclick-middle", "onclick-right"]),
                vue.createElementVNode("div", _hoisted_5$1, [
                  vue.createElementVNode("input", {
                    type: "range",
                    min: "-11",
                    max: "11",
                    value: vue.unref(store).currentCapo,
                    onInput: _cache[0] || (_cache[0] = ($event) => {
                      vue.unref(store).transpose = $event.target.value - vue.unref(store).originalCapo;
                    })
                  }, null, 40, _hoisted_6$1)
                ]),
                vue.createElementVNode("div", _hoisted_7, [
                  vue.createElementVNode("button", {
                    class: "instrument-select-button",
                    onClick: _cache[1] || (_cache[1] = () => {
                      vue.unref(switchInstrument)("");
                    })
                  }, " 無 "),
                  vue.createElementVNode("button", {
                    class: "instrument-select-button",
                    onClick: _cache[2] || (_cache[2] = () => {
                      vue.unref(switchInstrument)("guitar");
                    })
                  }, " 吉他 "),
                  vue.createElementVNode("button", {
                    class: "instrument-select-button",
                    onClick: _cache[3] || (_cache[3] = () => {
                      vue.unref(switchInstrument)("ukulele");
                    })
                  }, " 烏克莉莉 ")
                ])
              ])
            ], 512), [
              [vue.vShow, vue.unref(store).isPopupShow.sheet]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const SheetPopup = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-f161c46c"]]);
  const methods$1 = {};
  const names = [];
  function registerMethods(name, m) {
    if (Array.isArray(name)) {
      for (const _name of name) {
        registerMethods(_name, m);
      }
      return;
    }
    if (typeof name === "object") {
      for (const _name in name) {
        registerMethods(_name, name[_name]);
      }
      return;
    }
    addMethodNames(Object.getOwnPropertyNames(m));
    methods$1[name] = Object.assign(methods$1[name] || {}, m);
  }
  function getMethodsFor(name) {
    return methods$1[name] || {};
  }
  function getMethodNames() {
    return [...new Set(names)];
  }
  function addMethodNames(_names) {
    names.push(..._names);
  }
  function map(array2, block) {
    let i;
    const il = array2.length;
    const result = [];
    for (i = 0; i < il; i++) {
      result.push(block(array2[i]));
    }
    return result;
  }
  function filter(array2, block) {
    let i;
    const il = array2.length;
    const result = [];
    for (i = 0; i < il; i++) {
      if (block(array2[i])) {
        result.push(array2[i]);
      }
    }
    return result;
  }
  function radians(d) {
    return d % 360 * Math.PI / 180;
  }
  function camelCase(s) {
    return s.toLowerCase().replace(/-(.)/g, function(m, g) {
      return g.toUpperCase();
    });
  }
  function unCamelCase(s) {
    return s.replace(/([A-Z])/g, function(m, g) {
      return "-" + g.toLowerCase();
    });
  }
  function capitalize(s) {
    return s.charAt(0).toUpperCase() + s.slice(1);
  }
  function proportionalSize(element2, width2, height2, box) {
    if (width2 == null || height2 == null) {
      box = box || element2.bbox();
      if (width2 == null) {
        width2 = box.width / box.height * height2;
      } else if (height2 == null) {
        height2 = box.height / box.width * width2;
      }
    }
    return {
      width: width2,
      height: height2
    };
  }
  function getOrigin(o, element2) {
    const origin = o.origin;
    let ox = o.ox != null ? o.ox : o.originX != null ? o.originX : "center";
    let oy = o.oy != null ? o.oy : o.originY != null ? o.originY : "center";
    if (origin != null) {
      [ox, oy] = Array.isArray(origin) ? origin : typeof origin === "object" ? [origin.x, origin.y] : [origin, origin];
    }
    const condX = typeof ox === "string";
    const condY = typeof oy === "string";
    if (condX || condY) {
      const {
        height: height2,
        width: width2,
        x: x2,
        y: y2
      } = element2.bbox();
      if (condX) {
        ox = ox.includes("left") ? x2 : ox.includes("right") ? x2 + width2 : x2 + width2 / 2;
      }
      if (condY) {
        oy = oy.includes("top") ? y2 : oy.includes("bottom") ? y2 + height2 : y2 + height2 / 2;
      }
    }
    return [ox, oy];
  }
  const svg = "http://www.w3.org/2000/svg";
  const html = "http://www.w3.org/1999/xhtml";
  const xmlns = "http://www.w3.org/2000/xmlns/";
  const xlink = "http://www.w3.org/1999/xlink";
  const svgjs = "http://svgjs.dev/svgjs";
  const globals = {
    window: typeof window === "undefined" ? null : window,
    document: typeof document === "undefined" ? null : document
  };
  class Base {
    // constructor (node/*, {extensions = []} */) {
    //   // this.tags = []
    //   //
    //   // for (let extension of extensions) {
    //   //   extension.setup.call(this, node)
    //   //   this.tags.push(extension.name)
    //   // }
    // }
  }
  const elements = {};
  const root = "___SYMBOL___ROOT___";
  function create(name, ns = svg) {
    return globals.document.createElementNS(ns, name);
  }
  function makeInstance(element2, isHTML = false) {
    if (element2 instanceof Base)
      return element2;
    if (typeof element2 === "object") {
      return adopter(element2);
    }
    if (element2 == null) {
      return new elements[root]();
    }
    if (typeof element2 === "string" && element2.charAt(0) !== "<") {
      return adopter(globals.document.querySelector(element2));
    }
    const wrapper = isHTML ? globals.document.createElement("div") : create("svg");
    wrapper.innerHTML = element2;
    element2 = adopter(wrapper.firstChild);
    wrapper.removeChild(wrapper.firstChild);
    return element2;
  }
  function nodeOrNew(name, node) {
    return node && node.ownerDocument && node instanceof node.ownerDocument.defaultView.Node ? node : create(name);
  }
  function adopt(node) {
    if (!node)
      return null;
    if (node.instance instanceof Base)
      return node.instance;
    if (node.nodeName === "#document-fragment") {
      return new elements.Fragment(node);
    }
    let className = capitalize(node.nodeName || "Dom");
    if (className === "LinearGradient" || className === "RadialGradient") {
      className = "Gradient";
    } else if (!elements[className]) {
      className = "Dom";
    }
    return new elements[className](node);
  }
  let adopter = adopt;
  function register(element2, name = element2.name, asRoot = false) {
    elements[name] = element2;
    if (asRoot)
      elements[root] = element2;
    addMethodNames(Object.getOwnPropertyNames(element2.prototype));
    return element2;
  }
  function getClass(name) {
    return elements[name];
  }
  let did = 1e3;
  function eid(name) {
    return "Svgjs" + capitalize(name) + did++;
  }
  function assignNewId(node) {
    for (let i = node.children.length - 1; i >= 0; i--) {
      assignNewId(node.children[i]);
    }
    if (node.id) {
      node.id = eid(node.nodeName);
      return node;
    }
    return node;
  }
  function extend(modules, methods2) {
    let key, i;
    modules = Array.isArray(modules) ? modules : [modules];
    for (i = modules.length - 1; i >= 0; i--) {
      for (key in methods2) {
        modules[i].prototype[key] = methods2[key];
      }
    }
  }
  function wrapWithAttrCheck(fn) {
    return function(...args) {
      const o = args[args.length - 1];
      if (o && o.constructor === Object && !(o instanceof Array)) {
        return fn.apply(this, args.slice(0, -1)).attr(o);
      } else {
        return fn.apply(this, args);
      }
    };
  }
  function siblings() {
    return this.parent().children();
  }
  function position() {
    return this.parent().index(this);
  }
  function next() {
    return this.siblings()[this.position() + 1];
  }
  function prev() {
    return this.siblings()[this.position() - 1];
  }
  function forward() {
    const i = this.position();
    const p = this.parent();
    p.add(this.remove(), i + 1);
    return this;
  }
  function backward() {
    const i = this.position();
    const p = this.parent();
    p.add(this.remove(), i ? i - 1 : 0);
    return this;
  }
  function front() {
    const p = this.parent();
    p.add(this.remove());
    return this;
  }
  function back() {
    const p = this.parent();
    p.add(this.remove(), 0);
    return this;
  }
  function before(element2) {
    element2 = makeInstance(element2);
    element2.remove();
    const i = this.position();
    this.parent().add(element2, i);
    return this;
  }
  function after(element2) {
    element2 = makeInstance(element2);
    element2.remove();
    const i = this.position();
    this.parent().add(element2, i + 1);
    return this;
  }
  function insertBefore(element2) {
    element2 = makeInstance(element2);
    element2.before(this);
    return this;
  }
  function insertAfter(element2) {
    element2 = makeInstance(element2);
    element2.after(this);
    return this;
  }
  registerMethods("Dom", {
    siblings,
    position,
    next,
    prev,
    forward,
    backward,
    front,
    back,
    before,
    after,
    insertBefore,
    insertAfter
  });
  const numberAndUnit = /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i;
  const hex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
  const rgb = /rgb\((\d+),(\d+),(\d+)\)/;
  const reference = /(#[a-z_][a-z0-9\-_]*)/i;
  const transforms = /\)\s*,?\s*/;
  const whitespace = /\s/g;
  const isHex = /^#[a-f0-9]{3}$|^#[a-f0-9]{6}$/i;
  const isRgb = /^rgb\(/;
  const isBlank = /^(\s+)?$/;
  const isNumber = /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i;
  const isImage = /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i;
  const delimiter = /[\s,]+/;
  const isPathLetter = /[MLHVCSQTAZ]/i;
  function classes() {
    const attr2 = this.attr("class");
    return attr2 == null ? [] : attr2.trim().split(delimiter);
  }
  function hasClass(name) {
    return this.classes().indexOf(name) !== -1;
  }
  function addClass(name) {
    if (!this.hasClass(name)) {
      const array2 = this.classes();
      array2.push(name);
      this.attr("class", array2.join(" "));
    }
    return this;
  }
  function removeClass(name) {
    if (this.hasClass(name)) {
      this.attr("class", this.classes().filter(function(c) {
        return c !== name;
      }).join(" "));
    }
    return this;
  }
  function toggleClass(name) {
    return this.hasClass(name) ? this.removeClass(name) : this.addClass(name);
  }
  registerMethods("Dom", {
    classes,
    hasClass,
    addClass,
    removeClass,
    toggleClass
  });
  function css(style, val) {
    const ret = {};
    if (arguments.length === 0) {
      this.node.style.cssText.split(/\s*;\s*/).filter(function(el) {
        return !!el.length;
      }).forEach(function(el) {
        const t = el.split(/\s*:\s*/);
        ret[t[0]] = t[1];
      });
      return ret;
    }
    if (arguments.length < 2) {
      if (Array.isArray(style)) {
        for (const name of style) {
          const cased = camelCase(name);
          ret[name] = this.node.style[cased];
        }
        return ret;
      }
      if (typeof style === "string") {
        return this.node.style[camelCase(style)];
      }
      if (typeof style === "object") {
        for (const name in style) {
          this.node.style[camelCase(name)] = style[name] == null || isBlank.test(style[name]) ? "" : style[name];
        }
      }
    }
    if (arguments.length === 2) {
      this.node.style[camelCase(style)] = val == null || isBlank.test(val) ? "" : val;
    }
    return this;
  }
  function show() {
    return this.css("display", "");
  }
  function hide() {
    return this.css("display", "none");
  }
  function visible() {
    return this.css("display") !== "none";
  }
  registerMethods("Dom", {
    css,
    show,
    hide,
    visible
  });
  function data(a, v, r) {
    if (a == null) {
      return this.data(map(filter(this.node.attributes, (el) => el.nodeName.indexOf("data-") === 0), (el) => el.nodeName.slice(5)));
    } else if (a instanceof Array) {
      const data2 = {};
      for (const key of a) {
        data2[key] = this.data(key);
      }
      return data2;
    } else if (typeof a === "object") {
      for (v in a) {
        this.data(v, a[v]);
      }
    } else if (arguments.length < 2) {
      try {
        return JSON.parse(this.attr("data-" + a));
      } catch (e) {
        return this.attr("data-" + a);
      }
    } else {
      this.attr("data-" + a, v === null ? null : r === true || typeof v === "string" || typeof v === "number" ? v : JSON.stringify(v));
    }
    return this;
  }
  registerMethods("Dom", {
    data
  });
  function remember(k, v) {
    if (typeof arguments[0] === "object") {
      for (const key in k) {
        this.remember(key, k[key]);
      }
    } else if (arguments.length === 1) {
      return this.memory()[k];
    } else {
      this.memory()[k] = v;
    }
    return this;
  }
  function forget() {
    if (arguments.length === 0) {
      this._memory = {};
    } else {
      for (let i = arguments.length - 1; i >= 0; i--) {
        delete this.memory()[arguments[i]];
      }
    }
    return this;
  }
  function memory() {
    return this._memory = this._memory || {};
  }
  registerMethods("Dom", {
    remember,
    forget,
    memory
  });
  function sixDigitHex(hex2) {
    return hex2.length === 4 ? ["#", hex2.substring(1, 2), hex2.substring(1, 2), hex2.substring(2, 3), hex2.substring(2, 3), hex2.substring(3, 4), hex2.substring(3, 4)].join("") : hex2;
  }
  function componentHex(component) {
    const integer = Math.round(component);
    const bounded = Math.max(0, Math.min(255, integer));
    const hex2 = bounded.toString(16);
    return hex2.length === 1 ? "0" + hex2 : hex2;
  }
  function is(object2, space) {
    for (let i = space.length; i--; ) {
      if (object2[space[i]] == null) {
        return false;
      }
    }
    return true;
  }
  function getParameters(a, b) {
    const params = is(a, "rgb") ? {
      _a: a.r,
      _b: a.g,
      _c: a.b,
      _d: 0,
      space: "rgb"
    } : is(a, "xyz") ? {
      _a: a.x,
      _b: a.y,
      _c: a.z,
      _d: 0,
      space: "xyz"
    } : is(a, "hsl") ? {
      _a: a.h,
      _b: a.s,
      _c: a.l,
      _d: 0,
      space: "hsl"
    } : is(a, "lab") ? {
      _a: a.l,
      _b: a.a,
      _c: a.b,
      _d: 0,
      space: "lab"
    } : is(a, "lch") ? {
      _a: a.l,
      _b: a.c,
      _c: a.h,
      _d: 0,
      space: "lch"
    } : is(a, "cmyk") ? {
      _a: a.c,
      _b: a.m,
      _c: a.y,
      _d: a.k,
      space: "cmyk"
    } : {
      _a: 0,
      _b: 0,
      _c: 0,
      space: "rgb"
    };
    params.space = b || params.space;
    return params;
  }
  function cieSpace(space) {
    if (space === "lab" || space === "xyz" || space === "lch") {
      return true;
    } else {
      return false;
    }
  }
  function hueToRgb(p, q, t) {
    if (t < 0)
      t += 1;
    if (t > 1)
      t -= 1;
    if (t < 1 / 6)
      return p + (q - p) * 6 * t;
    if (t < 1 / 2)
      return q;
    if (t < 2 / 3)
      return p + (q - p) * (2 / 3 - t) * 6;
    return p;
  }
  class Color {
    constructor(...inputs) {
      this.init(...inputs);
    }
    // Test if given value is a color
    static isColor(color) {
      return color && (color instanceof Color || this.isRgb(color) || this.test(color));
    }
    // Test if given value is an rgb object
    static isRgb(color) {
      return color && typeof color.r === "number" && typeof color.g === "number" && typeof color.b === "number";
    }
    /*
    Generating random colors
    */
    static random(mode = "vibrant", t, u) {
      const {
        random,
        round,
        sin,
        PI: pi
      } = Math;
      if (mode === "vibrant") {
        const l = (81 - 57) * random() + 57;
        const c = (83 - 45) * random() + 45;
        const h = 360 * random();
        const color = new Color(l, c, h, "lch");
        return color;
      } else if (mode === "sine") {
        t = t == null ? random() : t;
        const r = round(80 * sin(2 * pi * t / 0.5 + 0.01) + 150);
        const g = round(50 * sin(2 * pi * t / 0.5 + 4.6) + 200);
        const b = round(100 * sin(2 * pi * t / 0.5 + 2.3) + 150);
        const color = new Color(r, g, b);
        return color;
      } else if (mode === "pastel") {
        const l = (94 - 86) * random() + 86;
        const c = (26 - 9) * random() + 9;
        const h = 360 * random();
        const color = new Color(l, c, h, "lch");
        return color;
      } else if (mode === "dark") {
        const l = 10 + 10 * random();
        const c = (125 - 75) * random() + 86;
        const h = 360 * random();
        const color = new Color(l, c, h, "lch");
        return color;
      } else if (mode === "rgb") {
        const r = 255 * random();
        const g = 255 * random();
        const b = 255 * random();
        const color = new Color(r, g, b);
        return color;
      } else if (mode === "lab") {
        const l = 100 * random();
        const a = 256 * random() - 128;
        const b = 256 * random() - 128;
        const color = new Color(l, a, b, "lab");
        return color;
      } else if (mode === "grey") {
        const grey = 255 * random();
        const color = new Color(grey, grey, grey);
        return color;
      } else {
        throw new Error("Unsupported random color mode");
      }
    }
    // Test if given value is a color string
    static test(color) {
      return typeof color === "string" && (isHex.test(color) || isRgb.test(color));
    }
    cmyk() {
      const {
        _a,
        _b,
        _c
      } = this.rgb();
      const [r, g, b] = [_a, _b, _c].map((v) => v / 255);
      const k = Math.min(1 - r, 1 - g, 1 - b);
      if (k === 1) {
        return new Color(0, 0, 0, 1, "cmyk");
      }
      const c = (1 - r - k) / (1 - k);
      const m = (1 - g - k) / (1 - k);
      const y2 = (1 - b - k) / (1 - k);
      const color = new Color(c, m, y2, k, "cmyk");
      return color;
    }
    hsl() {
      const {
        _a,
        _b,
        _c
      } = this.rgb();
      const [r, g, b] = [_a, _b, _c].map((v) => v / 255);
      const max = Math.max(r, g, b);
      const min = Math.min(r, g, b);
      const l = (max + min) / 2;
      const isGrey = max === min;
      const delta = max - min;
      const s = isGrey ? 0 : l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
      const h = isGrey ? 0 : max === r ? ((g - b) / delta + (g < b ? 6 : 0)) / 6 : max === g ? ((b - r) / delta + 2) / 6 : max === b ? ((r - g) / delta + 4) / 6 : 0;
      const color = new Color(360 * h, 100 * s, 100 * l, "hsl");
      return color;
    }
    init(a = 0, b = 0, c = 0, d = 0, space = "rgb") {
      a = !a ? 0 : a;
      if (this.space) {
        for (const component in this.space) {
          delete this[this.space[component]];
        }
      }
      if (typeof a === "number") {
        space = typeof d === "string" ? d : space;
        d = typeof d === "string" ? 0 : d;
        Object.assign(this, {
          _a: a,
          _b: b,
          _c: c,
          _d: d,
          space
        });
      } else if (a instanceof Array) {
        this.space = b || (typeof a[3] === "string" ? a[3] : a[4]) || "rgb";
        Object.assign(this, {
          _a: a[0],
          _b: a[1],
          _c: a[2],
          _d: a[3] || 0
        });
      } else if (a instanceof Object) {
        const values = getParameters(a, b);
        Object.assign(this, values);
      } else if (typeof a === "string") {
        if (isRgb.test(a)) {
          const noWhitespace = a.replace(whitespace, "");
          const [_a2, _b2, _c2] = rgb.exec(noWhitespace).slice(1, 4).map((v) => parseInt(v));
          Object.assign(this, {
            _a: _a2,
            _b: _b2,
            _c: _c2,
            _d: 0,
            space: "rgb"
          });
        } else if (isHex.test(a)) {
          const hexParse = (v) => parseInt(v, 16);
          const [, _a2, _b2, _c2] = hex.exec(sixDigitHex(a)).map(hexParse);
          Object.assign(this, {
            _a: _a2,
            _b: _b2,
            _c: _c2,
            _d: 0,
            space: "rgb"
          });
        } else
          throw Error("Unsupported string format, can't construct Color");
      }
      const {
        _a,
        _b,
        _c,
        _d
      } = this;
      const components = this.space === "rgb" ? {
        r: _a,
        g: _b,
        b: _c
      } : this.space === "xyz" ? {
        x: _a,
        y: _b,
        z: _c
      } : this.space === "hsl" ? {
        h: _a,
        s: _b,
        l: _c
      } : this.space === "lab" ? {
        l: _a,
        a: _b,
        b: _c
      } : this.space === "lch" ? {
        l: _a,
        c: _b,
        h: _c
      } : this.space === "cmyk" ? {
        c: _a,
        m: _b,
        y: _c,
        k: _d
      } : {};
      Object.assign(this, components);
    }
    lab() {
      const {
        x: x2,
        y: y2,
        z
      } = this.xyz();
      const l = 116 * y2 - 16;
      const a = 500 * (x2 - y2);
      const b = 200 * (y2 - z);
      const color = new Color(l, a, b, "lab");
      return color;
    }
    lch() {
      const {
        l,
        a,
        b
      } = this.lab();
      const c = Math.sqrt(a ** 2 + b ** 2);
      let h = 180 * Math.atan2(b, a) / Math.PI;
      if (h < 0) {
        h *= -1;
        h = 360 - h;
      }
      const color = new Color(l, c, h, "lch");
      return color;
    }
    /*
    Conversion Methods
    */
    rgb() {
      if (this.space === "rgb") {
        return this;
      } else if (cieSpace(this.space)) {
        let {
          x: x2,
          y: y2,
          z
        } = this;
        if (this.space === "lab" || this.space === "lch") {
          let {
            l,
            a,
            b: b2
          } = this;
          if (this.space === "lch") {
            const {
              c,
              h
            } = this;
            const dToR = Math.PI / 180;
            a = c * Math.cos(dToR * h);
            b2 = c * Math.sin(dToR * h);
          }
          const yL = (l + 16) / 116;
          const xL = a / 500 + yL;
          const zL = yL - b2 / 200;
          const ct = 16 / 116;
          const mx = 8856e-6;
          const nm = 7.787;
          x2 = 0.95047 * (xL ** 3 > mx ? xL ** 3 : (xL - ct) / nm);
          y2 = 1 * (yL ** 3 > mx ? yL ** 3 : (yL - ct) / nm);
          z = 1.08883 * (zL ** 3 > mx ? zL ** 3 : (zL - ct) / nm);
        }
        const rU = x2 * 3.2406 + y2 * -1.5372 + z * -0.4986;
        const gU = x2 * -0.9689 + y2 * 1.8758 + z * 0.0415;
        const bU = x2 * 0.0557 + y2 * -0.204 + z * 1.057;
        const pow = Math.pow;
        const bd = 31308e-7;
        const r = rU > bd ? 1.055 * pow(rU, 1 / 2.4) - 0.055 : 12.92 * rU;
        const g = gU > bd ? 1.055 * pow(gU, 1 / 2.4) - 0.055 : 12.92 * gU;
        const b = bU > bd ? 1.055 * pow(bU, 1 / 2.4) - 0.055 : 12.92 * bU;
        const color = new Color(255 * r, 255 * g, 255 * b);
        return color;
      } else if (this.space === "hsl") {
        let {
          h,
          s,
          l
        } = this;
        h /= 360;
        s /= 100;
        l /= 100;
        if (s === 0) {
          l *= 255;
          const color2 = new Color(l, l, l);
          return color2;
        }
        const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        const p = 2 * l - q;
        const r = 255 * hueToRgb(p, q, h + 1 / 3);
        const g = 255 * hueToRgb(p, q, h);
        const b = 255 * hueToRgb(p, q, h - 1 / 3);
        const color = new Color(r, g, b);
        return color;
      } else if (this.space === "cmyk") {
        const {
          c,
          m,
          y: y2,
          k
        } = this;
        const r = 255 * (1 - Math.min(1, c * (1 - k) + k));
        const g = 255 * (1 - Math.min(1, m * (1 - k) + k));
        const b = 255 * (1 - Math.min(1, y2 * (1 - k) + k));
        const color = new Color(r, g, b);
        return color;
      } else {
        return this;
      }
    }
    toArray() {
      const {
        _a,
        _b,
        _c,
        _d,
        space
      } = this;
      return [_a, _b, _c, _d, space];
    }
    toHex() {
      const [r, g, b] = this._clamped().map(componentHex);
      return `#${r}${g}${b}`;
    }
    toRgb() {
      const [rV, gV, bV] = this._clamped();
      const string2 = `rgb(${rV},${gV},${bV})`;
      return string2;
    }
    toString() {
      return this.toHex();
    }
    xyz() {
      const {
        _a: r255,
        _b: g255,
        _c: b255
      } = this.rgb();
      const [r, g, b] = [r255, g255, b255].map((v) => v / 255);
      const rL = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
      const gL = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
      const bL = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
      const xU = (rL * 0.4124 + gL * 0.3576 + bL * 0.1805) / 0.95047;
      const yU = (rL * 0.2126 + gL * 0.7152 + bL * 0.0722) / 1;
      const zU = (rL * 0.0193 + gL * 0.1192 + bL * 0.9505) / 1.08883;
      const x2 = xU > 8856e-6 ? Math.pow(xU, 1 / 3) : 7.787 * xU + 16 / 116;
      const y2 = yU > 8856e-6 ? Math.pow(yU, 1 / 3) : 7.787 * yU + 16 / 116;
      const z = zU > 8856e-6 ? Math.pow(zU, 1 / 3) : 7.787 * zU + 16 / 116;
      const color = new Color(x2, y2, z, "xyz");
      return color;
    }
    /*
    Input and Output methods
    */
    _clamped() {
      const {
        _a,
        _b,
        _c
      } = this.rgb();
      const {
        max,
        min,
        round
      } = Math;
      const format = (v) => max(0, min(round(v), 255));
      return [_a, _b, _c].map(format);
    }
    /*
    Constructing colors
    */
  }
  class Point {
    // Initialize
    constructor(...args) {
      this.init(...args);
    }
    // Clone point
    clone() {
      return new Point(this);
    }
    init(x2, y2) {
      const base = {
        x: 0,
        y: 0
      };
      const source = Array.isArray(x2) ? {
        x: x2[0],
        y: x2[1]
      } : typeof x2 === "object" ? {
        x: x2.x,
        y: x2.y
      } : {
        x: x2,
        y: y2
      };
      this.x = source.x == null ? base.x : source.x;
      this.y = source.y == null ? base.y : source.y;
      return this;
    }
    toArray() {
      return [this.x, this.y];
    }
    transform(m) {
      return this.clone().transformO(m);
    }
    // Transform point with matrix
    transformO(m) {
      if (!Matrix.isMatrixLike(m)) {
        m = new Matrix(m);
      }
      const {
        x: x2,
        y: y2
      } = this;
      this.x = m.a * x2 + m.c * y2 + m.e;
      this.y = m.b * x2 + m.d * y2 + m.f;
      return this;
    }
  }
  function point(x2, y2) {
    return new Point(x2, y2).transformO(this.screenCTM().inverseO());
  }
  function closeEnough(a, b, threshold) {
    return Math.abs(b - a) < (threshold || 1e-6);
  }
  class Matrix {
    constructor(...args) {
      this.init(...args);
    }
    static formatTransforms(o) {
      const flipBoth = o.flip === "both" || o.flip === true;
      const flipX = o.flip && (flipBoth || o.flip === "x") ? -1 : 1;
      const flipY = o.flip && (flipBoth || o.flip === "y") ? -1 : 1;
      const skewX = o.skew && o.skew.length ? o.skew[0] : isFinite(o.skew) ? o.skew : isFinite(o.skewX) ? o.skewX : 0;
      const skewY = o.skew && o.skew.length ? o.skew[1] : isFinite(o.skew) ? o.skew : isFinite(o.skewY) ? o.skewY : 0;
      const scaleX = o.scale && o.scale.length ? o.scale[0] * flipX : isFinite(o.scale) ? o.scale * flipX : isFinite(o.scaleX) ? o.scaleX * flipX : flipX;
      const scaleY = o.scale && o.scale.length ? o.scale[1] * flipY : isFinite(o.scale) ? o.scale * flipY : isFinite(o.scaleY) ? o.scaleY * flipY : flipY;
      const shear = o.shear || 0;
      const theta = o.rotate || o.theta || 0;
      const origin = new Point(o.origin || o.around || o.ox || o.originX, o.oy || o.originY);
      const ox = origin.x;
      const oy = origin.y;
      const position2 = new Point(o.position || o.px || o.positionX || NaN, o.py || o.positionY || NaN);
      const px = position2.x;
      const py = position2.y;
      const translate = new Point(o.translate || o.tx || o.translateX, o.ty || o.translateY);
      const tx = translate.x;
      const ty = translate.y;
      const relative = new Point(o.relative || o.rx || o.relativeX, o.ry || o.relativeY);
      const rx2 = relative.x;
      const ry2 = relative.y;
      return {
        scaleX,
        scaleY,
        skewX,
        skewY,
        shear,
        theta,
        rx: rx2,
        ry: ry2,
        tx,
        ty,
        ox,
        oy,
        px,
        py
      };
    }
    static fromArray(a) {
      return {
        a: a[0],
        b: a[1],
        c: a[2],
        d: a[3],
        e: a[4],
        f: a[5]
      };
    }
    static isMatrixLike(o) {
      return o.a != null || o.b != null || o.c != null || o.d != null || o.e != null || o.f != null;
    }
    // left matrix, right matrix, target matrix which is overwritten
    static matrixMultiply(l, r, o) {
      const a = l.a * r.a + l.c * r.b;
      const b = l.b * r.a + l.d * r.b;
      const c = l.a * r.c + l.c * r.d;
      const d = l.b * r.c + l.d * r.d;
      const e = l.e + l.a * r.e + l.c * r.f;
      const f = l.f + l.b * r.e + l.d * r.f;
      o.a = a;
      o.b = b;
      o.c = c;
      o.d = d;
      o.e = e;
      o.f = f;
      return o;
    }
    around(cx2, cy2, matrix) {
      return this.clone().aroundO(cx2, cy2, matrix);
    }
    // Transform around a center point
    aroundO(cx2, cy2, matrix) {
      const dx2 = cx2 || 0;
      const dy2 = cy2 || 0;
      return this.translateO(-dx2, -dy2).lmultiplyO(matrix).translateO(dx2, dy2);
    }
    // Clones this matrix
    clone() {
      return new Matrix(this);
    }
    // Decomposes this matrix into its affine parameters
    decompose(cx2 = 0, cy2 = 0) {
      const a = this.a;
      const b = this.b;
      const c = this.c;
      const d = this.d;
      const e = this.e;
      const f = this.f;
      const determinant = a * d - b * c;
      const ccw = determinant > 0 ? 1 : -1;
      const sx = ccw * Math.sqrt(a * a + b * b);
      const thetaRad = Math.atan2(ccw * b, ccw * a);
      const theta = 180 / Math.PI * thetaRad;
      const ct = Math.cos(thetaRad);
      const st = Math.sin(thetaRad);
      const lam = (a * c + b * d) / determinant;
      const sy = c * sx / (lam * a - b) || d * sx / (lam * b + a);
      const tx = e - cx2 + cx2 * ct * sx + cy2 * (lam * ct * sx - st * sy);
      const ty = f - cy2 + cx2 * st * sx + cy2 * (lam * st * sx + ct * sy);
      return {
        // Return the affine parameters
        scaleX: sx,
        scaleY: sy,
        shear: lam,
        rotate: theta,
        translateX: tx,
        translateY: ty,
        originX: cx2,
        originY: cy2,
        // Return the matrix parameters
        a: this.a,
        b: this.b,
        c: this.c,
        d: this.d,
        e: this.e,
        f: this.f
      };
    }
    // Check if two matrices are equal
    equals(other) {
      if (other === this)
        return true;
      const comp = new Matrix(other);
      return closeEnough(this.a, comp.a) && closeEnough(this.b, comp.b) && closeEnough(this.c, comp.c) && closeEnough(this.d, comp.d) && closeEnough(this.e, comp.e) && closeEnough(this.f, comp.f);
    }
    // Flip matrix on x or y, at a given offset
    flip(axis, around) {
      return this.clone().flipO(axis, around);
    }
    flipO(axis, around) {
      return axis === "x" ? this.scaleO(-1, 1, around, 0) : axis === "y" ? this.scaleO(1, -1, 0, around) : this.scaleO(-1, -1, axis, around || axis);
    }
    // Initialize
    init(source) {
      const base = Matrix.fromArray([1, 0, 0, 1, 0, 0]);
      source = source instanceof Element ? source.matrixify() : typeof source === "string" ? Matrix.fromArray(source.split(delimiter).map(parseFloat)) : Array.isArray(source) ? Matrix.fromArray(source) : typeof source === "object" && Matrix.isMatrixLike(source) ? source : typeof source === "object" ? new Matrix().transform(source) : arguments.length === 6 ? Matrix.fromArray([].slice.call(arguments)) : base;
      this.a = source.a != null ? source.a : base.a;
      this.b = source.b != null ? source.b : base.b;
      this.c = source.c != null ? source.c : base.c;
      this.d = source.d != null ? source.d : base.d;
      this.e = source.e != null ? source.e : base.e;
      this.f = source.f != null ? source.f : base.f;
      return this;
    }
    inverse() {
      return this.clone().inverseO();
    }
    // Inverses matrix
    inverseO() {
      const a = this.a;
      const b = this.b;
      const c = this.c;
      const d = this.d;
      const e = this.e;
      const f = this.f;
      const det = a * d - b * c;
      if (!det)
        throw new Error("Cannot invert " + this);
      const na = d / det;
      const nb = -b / det;
      const nc = -c / det;
      const nd = a / det;
      const ne = -(na * e + nc * f);
      const nf = -(nb * e + nd * f);
      this.a = na;
      this.b = nb;
      this.c = nc;
      this.d = nd;
      this.e = ne;
      this.f = nf;
      return this;
    }
    lmultiply(matrix) {
      return this.clone().lmultiplyO(matrix);
    }
    lmultiplyO(matrix) {
      const r = this;
      const l = matrix instanceof Matrix ? matrix : new Matrix(matrix);
      return Matrix.matrixMultiply(l, r, this);
    }
    // Left multiplies by the given matrix
    multiply(matrix) {
      return this.clone().multiplyO(matrix);
    }
    multiplyO(matrix) {
      const l = this;
      const r = matrix instanceof Matrix ? matrix : new Matrix(matrix);
      return Matrix.matrixMultiply(l, r, this);
    }
    // Rotate matrix
    rotate(r, cx2, cy2) {
      return this.clone().rotateO(r, cx2, cy2);
    }
    rotateO(r, cx2 = 0, cy2 = 0) {
      r = radians(r);
      const cos = Math.cos(r);
      const sin = Math.sin(r);
      const {
        a,
        b,
        c,
        d,
        e,
        f
      } = this;
      this.a = a * cos - b * sin;
      this.b = b * cos + a * sin;
      this.c = c * cos - d * sin;
      this.d = d * cos + c * sin;
      this.e = e * cos - f * sin + cy2 * sin - cx2 * cos + cx2;
      this.f = f * cos + e * sin - cx2 * sin - cy2 * cos + cy2;
      return this;
    }
    // Scale matrix
    scale(x2, y2, cx2, cy2) {
      return this.clone().scaleO(...arguments);
    }
    scaleO(x2, y2 = x2, cx2 = 0, cy2 = 0) {
      if (arguments.length === 3) {
        cy2 = cx2;
        cx2 = y2;
        y2 = x2;
      }
      const {
        a,
        b,
        c,
        d,
        e,
        f
      } = this;
      this.a = a * x2;
      this.b = b * y2;
      this.c = c * x2;
      this.d = d * y2;
      this.e = e * x2 - cx2 * x2 + cx2;
      this.f = f * y2 - cy2 * y2 + cy2;
      return this;
    }
    // Shear matrix
    shear(a, cx2, cy2) {
      return this.clone().shearO(a, cx2, cy2);
    }
    shearO(lx, cx2 = 0, cy2 = 0) {
      const {
        a,
        b,
        c,
        d,
        e,
        f
      } = this;
      this.a = a + b * lx;
      this.c = c + d * lx;
      this.e = e + f * lx - cy2 * lx;
      return this;
    }
    // Skew Matrix
    skew(x2, y2, cx2, cy2) {
      return this.clone().skewO(...arguments);
    }
    skewO(x2, y2 = x2, cx2 = 0, cy2 = 0) {
      if (arguments.length === 3) {
        cy2 = cx2;
        cx2 = y2;
        y2 = x2;
      }
      x2 = radians(x2);
      y2 = radians(y2);
      const lx = Math.tan(x2);
      const ly = Math.tan(y2);
      const {
        a,
        b,
        c,
        d,
        e,
        f
      } = this;
      this.a = a + b * lx;
      this.b = b + a * ly;
      this.c = c + d * lx;
      this.d = d + c * ly;
      this.e = e + f * lx - cy2 * lx;
      this.f = f + e * ly - cx2 * ly;
      return this;
    }
    // SkewX
    skewX(x2, cx2, cy2) {
      return this.skew(x2, 0, cx2, cy2);
    }
    // SkewY
    skewY(y2, cx2, cy2) {
      return this.skew(0, y2, cx2, cy2);
    }
    toArray() {
      return [this.a, this.b, this.c, this.d, this.e, this.f];
    }
    // Convert matrix to string
    toString() {
      return "matrix(" + this.a + "," + this.b + "," + this.c + "," + this.d + "," + this.e + "," + this.f + ")";
    }
    // Transform a matrix into another matrix by manipulating the space
    transform(o) {
      if (Matrix.isMatrixLike(o)) {
        const matrix = new Matrix(o);
        return matrix.multiplyO(this);
      }
      const t = Matrix.formatTransforms(o);
      const current = this;
      const {
        x: ox,
        y: oy
      } = new Point(t.ox, t.oy).transform(current);
      const transformer = new Matrix().translateO(t.rx, t.ry).lmultiplyO(current).translateO(-ox, -oy).scaleO(t.scaleX, t.scaleY).skewO(t.skewX, t.skewY).shearO(t.shear).rotateO(t.theta).translateO(ox, oy);
      if (isFinite(t.px) || isFinite(t.py)) {
        const origin = new Point(ox, oy).transform(transformer);
        const dx2 = isFinite(t.px) ? t.px - origin.x : 0;
        const dy2 = isFinite(t.py) ? t.py - origin.y : 0;
        transformer.translateO(dx2, dy2);
      }
      transformer.translateO(t.tx, t.ty);
      return transformer;
    }
    // Translate matrix
    translate(x2, y2) {
      return this.clone().translateO(x2, y2);
    }
    translateO(x2, y2) {
      this.e += x2 || 0;
      this.f += y2 || 0;
      return this;
    }
    valueOf() {
      return {
        a: this.a,
        b: this.b,
        c: this.c,
        d: this.d,
        e: this.e,
        f: this.f
      };
    }
  }
  function ctm() {
    return new Matrix(this.node.getCTM());
  }
  function screenCTM() {
    if (typeof this.isRoot === "function" && !this.isRoot()) {
      const rect = this.rect(1, 1);
      const m = rect.node.getScreenCTM();
      rect.remove();
      return new Matrix(m);
    }
    return new Matrix(this.node.getScreenCTM());
  }
  register(Matrix, "Matrix");
  function parser() {
    if (!parser.nodes) {
      const svg2 = makeInstance().size(2, 0);
      svg2.node.style.cssText = ["opacity: 0", "position: absolute", "left: -100%", "top: -100%", "overflow: hidden"].join(";");
      svg2.attr("focusable", "false");
      svg2.attr("aria-hidden", "true");
      const path = svg2.path().node;
      parser.nodes = {
        svg: svg2,
        path
      };
    }
    if (!parser.nodes.svg.node.parentNode) {
      const b = globals.document.body || globals.document.documentElement;
      parser.nodes.svg.addTo(b);
    }
    return parser.nodes;
  }
  function isNulledBox(box) {
    return !box.width && !box.height && !box.x && !box.y;
  }
  function domContains(node) {
    return node === globals.document || (globals.document.documentElement.contains || function(node2) {
      while (node2.parentNode) {
        node2 = node2.parentNode;
      }
      return node2 === globals.document;
    }).call(globals.document.documentElement, node);
  }
  class Box {
    constructor(...args) {
      this.init(...args);
    }
    addOffset() {
      this.x += globals.window.pageXOffset;
      this.y += globals.window.pageYOffset;
      return new Box(this);
    }
    init(source) {
      const base = [0, 0, 0, 0];
      source = typeof source === "string" ? source.split(delimiter).map(parseFloat) : Array.isArray(source) ? source : typeof source === "object" ? [source.left != null ? source.left : source.x, source.top != null ? source.top : source.y, source.width, source.height] : arguments.length === 4 ? [].slice.call(arguments) : base;
      this.x = source[0] || 0;
      this.y = source[1] || 0;
      this.width = this.w = source[2] || 0;
      this.height = this.h = source[3] || 0;
      this.x2 = this.x + this.w;
      this.y2 = this.y + this.h;
      this.cx = this.x + this.w / 2;
      this.cy = this.y + this.h / 2;
      return this;
    }
    isNulled() {
      return isNulledBox(this);
    }
    // Merge rect box with another, return a new instance
    merge(box) {
      const x2 = Math.min(this.x, box.x);
      const y2 = Math.min(this.y, box.y);
      const width2 = Math.max(this.x + this.width, box.x + box.width) - x2;
      const height2 = Math.max(this.y + this.height, box.y + box.height) - y2;
      return new Box(x2, y2, width2, height2);
    }
    toArray() {
      return [this.x, this.y, this.width, this.height];
    }
    toString() {
      return this.x + " " + this.y + " " + this.width + " " + this.height;
    }
    transform(m) {
      if (!(m instanceof Matrix)) {
        m = new Matrix(m);
      }
      let xMin = Infinity;
      let xMax = -Infinity;
      let yMin = Infinity;
      let yMax = -Infinity;
      const pts = [new Point(this.x, this.y), new Point(this.x2, this.y), new Point(this.x, this.y2), new Point(this.x2, this.y2)];
      pts.forEach(function(p) {
        p = p.transform(m);
        xMin = Math.min(xMin, p.x);
        xMax = Math.max(xMax, p.x);
        yMin = Math.min(yMin, p.y);
        yMax = Math.max(yMax, p.y);
      });
      return new Box(xMin, yMin, xMax - xMin, yMax - yMin);
    }
  }
  function getBox(el, getBBoxFn, retry) {
    let box;
    try {
      box = getBBoxFn(el.node);
      if (isNulledBox(box) && !domContains(el.node)) {
        throw new Error("Element not in the dom");
      }
    } catch (e) {
      box = retry(el);
    }
    return box;
  }
  function bbox() {
    const getBBox = (node) => node.getBBox();
    const retry = (el) => {
      try {
        const clone = el.clone().addTo(parser().svg).show();
        const box2 = clone.node.getBBox();
        clone.remove();
        return box2;
      } catch (e) {
        throw new Error(`Getting bbox of element "${el.node.nodeName}" is not possible: ${e.toString()}`);
      }
    };
    const box = getBox(this, getBBox, retry);
    const bbox2 = new Box(box);
    return bbox2;
  }
  function rbox(el) {
    const getRBox = (node) => node.getBoundingClientRect();
    const retry = (el2) => {
      throw new Error(`Getting rbox of element "${el2.node.nodeName}" is not possible`);
    };
    const box = getBox(this, getRBox, retry);
    const rbox2 = new Box(box);
    if (el) {
      return rbox2.transform(el.screenCTM().inverseO());
    }
    return rbox2.addOffset();
  }
  function inside(x2, y2) {
    const box = this.bbox();
    return x2 > box.x && y2 > box.y && x2 < box.x + box.width && y2 < box.y + box.height;
  }
  registerMethods({
    viewbox: {
      viewbox(x2, y2, width2, height2) {
        if (x2 == null)
          return new Box(this.attr("viewBox"));
        return this.attr("viewBox", new Box(x2, y2, width2, height2));
      },
      zoom(level, point2) {
        let {
          width: width2,
          height: height2
        } = this.attr(["width", "height"]);
        if (!width2 && !height2 || typeof width2 === "string" || typeof height2 === "string") {
          width2 = this.node.clientWidth;
          height2 = this.node.clientHeight;
        }
        if (!width2 || !height2) {
          throw new Error("Impossible to get absolute width and height. Please provide an absolute width and height attribute on the zooming element");
        }
        const v = this.viewbox();
        const zoomX = width2 / v.width;
        const zoomY = height2 / v.height;
        const zoom = Math.min(zoomX, zoomY);
        if (level == null) {
          return zoom;
        }
        let zoomAmount = zoom / level;
        if (zoomAmount === Infinity)
          zoomAmount = Number.MAX_SAFE_INTEGER / 100;
        point2 = point2 || new Point(width2 / 2 / zoomX + v.x, height2 / 2 / zoomY + v.y);
        const box = new Box(v).transform(new Matrix({
          scale: zoomAmount,
          origin: point2
        }));
        return this.viewbox(box);
      }
    }
  });
  register(Box, "Box");
  class List extends Array {
    constructor(arr = [], ...args) {
      super(arr, ...args);
      if (typeof arr === "number")
        return this;
      this.length = 0;
      this.push(...arr);
    }
  }
  extend([List], {
    each(fnOrMethodName, ...args) {
      if (typeof fnOrMethodName === "function") {
        return this.map((el, i, arr) => {
          return fnOrMethodName.call(el, el, i, arr);
        });
      } else {
        return this.map((el) => {
          return el[fnOrMethodName](...args);
        });
      }
    },
    toArray() {
      return Array.prototype.concat.apply([], this);
    }
  });
  const reserved = ["toArray", "constructor", "each"];
  List.extend = function(methods2) {
    methods2 = methods2.reduce((obj, name) => {
      if (reserved.includes(name))
        return obj;
      if (name[0] === "_")
        return obj;
      obj[name] = function(...attrs2) {
        return this.each(name, ...attrs2);
      };
      return obj;
    }, {});
    extend([List], methods2);
  };
  function baseFind(query, parent) {
    return new List(map((parent || globals.document).querySelectorAll(query), function(node) {
      return adopt(node);
    }));
  }
  function find(query) {
    return baseFind(query, this.node);
  }
  function findOne(query) {
    return adopt(this.node.querySelector(query));
  }
  let listenerId = 0;
  const windowEvents = {};
  function getEvents(instance) {
    let n = instance.getEventHolder();
    if (n === globals.window)
      n = windowEvents;
    if (!n.events)
      n.events = {};
    return n.events;
  }
  function getEventTarget(instance) {
    return instance.getEventTarget();
  }
  function clearEvents(instance) {
    let n = instance.getEventHolder();
    if (n === globals.window)
      n = windowEvents;
    if (n.events)
      n.events = {};
  }
  function on(node, events, listener, binding, options) {
    const l = listener.bind(binding || node);
    const instance = makeInstance(node);
    const bag = getEvents(instance);
    const n = getEventTarget(instance);
    events = Array.isArray(events) ? events : events.split(delimiter);
    if (!listener._svgjsListenerId) {
      listener._svgjsListenerId = ++listenerId;
    }
    events.forEach(function(event) {
      const ev = event.split(".")[0];
      const ns = event.split(".")[1] || "*";
      bag[ev] = bag[ev] || {};
      bag[ev][ns] = bag[ev][ns] || {};
      bag[ev][ns][listener._svgjsListenerId] = l;
      n.addEventListener(ev, l, options || false);
    });
  }
  function off(node, events, listener, options) {
    const instance = makeInstance(node);
    const bag = getEvents(instance);
    const n = getEventTarget(instance);
    if (typeof listener === "function") {
      listener = listener._svgjsListenerId;
      if (!listener)
        return;
    }
    events = Array.isArray(events) ? events : (events || "").split(delimiter);
    events.forEach(function(event) {
      const ev = event && event.split(".")[0];
      const ns = event && event.split(".")[1];
      let namespace, l;
      if (listener) {
        if (bag[ev] && bag[ev][ns || "*"]) {
          n.removeEventListener(ev, bag[ev][ns || "*"][listener], options || false);
          delete bag[ev][ns || "*"][listener];
        }
      } else if (ev && ns) {
        if (bag[ev] && bag[ev][ns]) {
          for (l in bag[ev][ns]) {
            off(n, [ev, ns].join("."), l);
          }
          delete bag[ev][ns];
        }
      } else if (ns) {
        for (event in bag) {
          for (namespace in bag[event]) {
            if (ns === namespace) {
              off(n, [event, ns].join("."));
            }
          }
        }
      } else if (ev) {
        if (bag[ev]) {
          for (namespace in bag[ev]) {
            off(n, [ev, namespace].join("."));
          }
          delete bag[ev];
        }
      } else {
        for (event in bag) {
          off(n, event);
        }
        clearEvents(instance);
      }
    });
  }
  function dispatch(node, event, data2, options) {
    const n = getEventTarget(node);
    if (event instanceof globals.window.Event) {
      n.dispatchEvent(event);
    } else {
      event = new globals.window.CustomEvent(event, {
        detail: data2,
        cancelable: true,
        ...options
      });
      n.dispatchEvent(event);
    }
    return event;
  }
  class EventTarget extends Base {
    addEventListener() {
    }
    dispatch(event, data2, options) {
      return dispatch(this, event, data2, options);
    }
    dispatchEvent(event) {
      const bag = this.getEventHolder().events;
      if (!bag)
        return true;
      const events = bag[event.type];
      for (const i in events) {
        for (const j in events[i]) {
          events[i][j](event);
        }
      }
      return !event.defaultPrevented;
    }
    // Fire given event
    fire(event, data2, options) {
      this.dispatch(event, data2, options);
      return this;
    }
    getEventHolder() {
      return this;
    }
    getEventTarget() {
      return this;
    }
    // Unbind event from listener
    off(event, listener, options) {
      off(this, event, listener, options);
      return this;
    }
    // Bind given event to listener
    on(event, listener, binding, options) {
      on(this, event, listener, binding, options);
      return this;
    }
    removeEventListener() {
    }
  }
  register(EventTarget, "EventTarget");
  function noop() {
  }
  const timeline = {
    duration: 400,
    ease: ">",
    delay: 0
  };
  const attrs = {
    // fill and stroke
    "fill-opacity": 1,
    "stroke-opacity": 1,
    "stroke-width": 0,
    "stroke-linejoin": "miter",
    "stroke-linecap": "butt",
    fill: "#000000",
    stroke: "#000000",
    opacity: 1,
    // position
    x: 0,
    y: 0,
    cx: 0,
    cy: 0,
    // size
    width: 0,
    height: 0,
    // radius
    r: 0,
    rx: 0,
    ry: 0,
    // gradient
    offset: 0,
    "stop-opacity": 1,
    "stop-color": "#000000",
    // text
    "text-anchor": "start"
  };
  class SVGArray extends Array {
    constructor(...args) {
      super(...args);
      this.init(...args);
    }
    clone() {
      return new this.constructor(this);
    }
    init(arr) {
      if (typeof arr === "number")
        return this;
      this.length = 0;
      this.push(...this.parse(arr));
      return this;
    }
    // Parse whitespace separated string
    parse(array2 = []) {
      if (array2 instanceof Array)
        return array2;
      return array2.trim().split(delimiter).map(parseFloat);
    }
    toArray() {
      return Array.prototype.concat.apply([], this);
    }
    toSet() {
      return new Set(this);
    }
    toString() {
      return this.join(" ");
    }
    // Flattens the array if needed
    valueOf() {
      const ret = [];
      ret.push(...this);
      return ret;
    }
  }
  class SVGNumber {
    // Initialize
    constructor(...args) {
      this.init(...args);
    }
    convert(unit) {
      return new SVGNumber(this.value, unit);
    }
    // Divide number
    divide(number2) {
      number2 = new SVGNumber(number2);
      return new SVGNumber(this / number2, this.unit || number2.unit);
    }
    init(value, unit) {
      unit = Array.isArray(value) ? value[1] : unit;
      value = Array.isArray(value) ? value[0] : value;
      this.value = 0;
      this.unit = unit || "";
      if (typeof value === "number") {
        this.value = isNaN(value) ? 0 : !isFinite(value) ? value < 0 ? -34e37 : 34e37 : value;
      } else if (typeof value === "string") {
        unit = value.match(numberAndUnit);
        if (unit) {
          this.value = parseFloat(unit[1]);
          if (unit[5] === "%") {
            this.value /= 100;
          } else if (unit[5] === "s") {
            this.value *= 1e3;
          }
          this.unit = unit[5];
        }
      } else {
        if (value instanceof SVGNumber) {
          this.value = value.valueOf();
          this.unit = value.unit;
        }
      }
      return this;
    }
    // Subtract number
    minus(number2) {
      number2 = new SVGNumber(number2);
      return new SVGNumber(this - number2, this.unit || number2.unit);
    }
    // Add number
    plus(number2) {
      number2 = new SVGNumber(number2);
      return new SVGNumber(this + number2, this.unit || number2.unit);
    }
    // Multiply number
    times(number2) {
      number2 = new SVGNumber(number2);
      return new SVGNumber(this * number2, this.unit || number2.unit);
    }
    toArray() {
      return [this.value, this.unit];
    }
    toJSON() {
      return this.toString();
    }
    toString() {
      return (this.unit === "%" ? ~~(this.value * 1e8) / 1e6 : this.unit === "s" ? this.value / 1e3 : this.value) + this.unit;
    }
    valueOf() {
      return this.value;
    }
  }
  const hooks = [];
  function registerAttrHook(fn) {
    hooks.push(fn);
  }
  function attr(attr2, val, ns) {
    if (attr2 == null) {
      attr2 = {};
      val = this.node.attributes;
      for (const node of val) {
        attr2[node.nodeName] = isNumber.test(node.nodeValue) ? parseFloat(node.nodeValue) : node.nodeValue;
      }
      return attr2;
    } else if (attr2 instanceof Array) {
      return attr2.reduce((last, curr) => {
        last[curr] = this.attr(curr);
        return last;
      }, {});
    } else if (typeof attr2 === "object" && attr2.constructor === Object) {
      for (val in attr2)
        this.attr(val, attr2[val]);
    } else if (val === null) {
      this.node.removeAttribute(attr2);
    } else if (val == null) {
      val = this.node.getAttribute(attr2);
      return val == null ? attrs[attr2] : isNumber.test(val) ? parseFloat(val) : val;
    } else {
      val = hooks.reduce((_val, hook) => {
        return hook(attr2, _val, this);
      }, val);
      if (typeof val === "number") {
        val = new SVGNumber(val);
      } else if (Color.isColor(val)) {
        val = new Color(val);
      } else if (val.constructor === Array) {
        val = new SVGArray(val);
      }
      if (attr2 === "leading") {
        if (this.leading) {
          this.leading(val);
        }
      } else {
        typeof ns === "string" ? this.node.setAttributeNS(ns, attr2, val.toString()) : this.node.setAttribute(attr2, val.toString());
      }
      if (this.rebuild && (attr2 === "font-size" || attr2 === "x")) {
        this.rebuild();
      }
    }
    return this;
  }
  class Dom extends EventTarget {
    constructor(node, attrs2) {
      super();
      this.node = node;
      this.type = node.nodeName;
      if (attrs2 && node !== attrs2) {
        this.attr(attrs2);
      }
    }
    // Add given element at a position
    add(element2, i) {
      element2 = makeInstance(element2);
      if (element2.removeNamespace && this.node instanceof globals.window.SVGElement) {
        element2.removeNamespace();
      }
      if (i == null) {
        this.node.appendChild(element2.node);
      } else if (element2.node !== this.node.childNodes[i]) {
        this.node.insertBefore(element2.node, this.node.childNodes[i]);
      }
      return this;
    }
    // Add element to given container and return self
    addTo(parent, i) {
      return makeInstance(parent).put(this, i);
    }
    // Returns all child elements
    children() {
      return new List(map(this.node.children, function(node) {
        return adopt(node);
      }));
    }
    // Remove all elements in this container
    clear() {
      while (this.node.hasChildNodes()) {
        this.node.removeChild(this.node.lastChild);
      }
      return this;
    }
    // Clone element
    clone(deep = true, assignNewIds = true) {
      this.writeDataToDom();
      let nodeClone = this.node.cloneNode(deep);
      if (assignNewIds) {
        nodeClone = assignNewId(nodeClone);
      }
      return new this.constructor(nodeClone);
    }
    // Iterates over all children and invokes a given block
    each(block, deep) {
      const children = this.children();
      let i, il;
      for (i = 0, il = children.length; i < il; i++) {
        block.apply(children[i], [i, children]);
        if (deep) {
          children[i].each(block, deep);
        }
      }
      return this;
    }
    element(nodeName, attrs2) {
      return this.put(new Dom(create(nodeName), attrs2));
    }
    // Get first child
    first() {
      return adopt(this.node.firstChild);
    }
    // Get a element at the given index
    get(i) {
      return adopt(this.node.childNodes[i]);
    }
    getEventHolder() {
      return this.node;
    }
    getEventTarget() {
      return this.node;
    }
    // Checks if the given element is a child
    has(element2) {
      return this.index(element2) >= 0;
    }
    html(htmlOrFn, outerHTML) {
      return this.xml(htmlOrFn, outerHTML, html);
    }
    // Get / set id
    id(id) {
      if (typeof id === "undefined" && !this.node.id) {
        this.node.id = eid(this.type);
      }
      return this.attr("id", id);
    }
    // Gets index of given element
    index(element2) {
      return [].slice.call(this.node.childNodes).indexOf(element2.node);
    }
    // Get the last child
    last() {
      return adopt(this.node.lastChild);
    }
    // matches the element vs a css selector
    matches(selector) {
      const el = this.node;
      const matcher = el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector || null;
      return matcher && matcher.call(el, selector);
    }
    // Returns the parent element instance
    parent(type) {
      let parent = this;
      if (!parent.node.parentNode)
        return null;
      parent = adopt(parent.node.parentNode);
      if (!type)
        return parent;
      do {
        if (typeof type === "string" ? parent.matches(type) : parent instanceof type)
          return parent;
      } while (parent = adopt(parent.node.parentNode));
      return parent;
    }
    // Basically does the same as `add()` but returns the added element instead
    put(element2, i) {
      element2 = makeInstance(element2);
      this.add(element2, i);
      return element2;
    }
    // Add element to given container and return container
    putIn(parent, i) {
      return makeInstance(parent).add(this, i);
    }
    // Remove element
    remove() {
      if (this.parent()) {
        this.parent().removeElement(this);
      }
      return this;
    }
    // Remove a given child
    removeElement(element2) {
      this.node.removeChild(element2.node);
      return this;
    }
    // Replace this with element
    replace(element2) {
      element2 = makeInstance(element2);
      if (this.node.parentNode) {
        this.node.parentNode.replaceChild(element2.node, this.node);
      }
      return element2;
    }
    round(precision = 2, map2 = null) {
      const factor = 10 ** precision;
      const attrs2 = this.attr(map2);
      for (const i in attrs2) {
        if (typeof attrs2[i] === "number") {
          attrs2[i] = Math.round(attrs2[i] * factor) / factor;
        }
      }
      this.attr(attrs2);
      return this;
    }
    // Import / Export raw svg
    svg(svgOrFn, outerSVG) {
      return this.xml(svgOrFn, outerSVG, svg);
    }
    // Return id on string conversion
    toString() {
      return this.id();
    }
    words(text) {
      this.node.textContent = text;
      return this;
    }
    wrap(node) {
      const parent = this.parent();
      if (!parent) {
        return this.addTo(node);
      }
      const position2 = parent.index(this);
      return parent.put(node, position2).put(this);
    }
    // write svgjs data to the dom
    writeDataToDom() {
      this.each(function() {
        this.writeDataToDom();
      });
      return this;
    }
    // Import / Export raw svg
    xml(xmlOrFn, outerXML, ns) {
      if (typeof xmlOrFn === "boolean") {
        ns = outerXML;
        outerXML = xmlOrFn;
        xmlOrFn = null;
      }
      if (xmlOrFn == null || typeof xmlOrFn === "function") {
        outerXML = outerXML == null ? true : outerXML;
        this.writeDataToDom();
        let current = this;
        if (xmlOrFn != null) {
          current = adopt(current.node.cloneNode(true));
          if (outerXML) {
            const result = xmlOrFn(current);
            current = result || current;
            if (result === false)
              return "";
          }
          current.each(function() {
            const result = xmlOrFn(this);
            const _this = result || this;
            if (result === false) {
              this.remove();
            } else if (result && this !== _this) {
              this.replace(_this);
            }
          }, true);
        }
        return outerXML ? current.node.outerHTML : current.node.innerHTML;
      }
      outerXML = outerXML == null ? false : outerXML;
      const well = create("wrapper", ns);
      const fragment = globals.document.createDocumentFragment();
      well.innerHTML = xmlOrFn;
      for (let len = well.children.length; len--; ) {
        fragment.appendChild(well.firstElementChild);
      }
      const parent = this.parent();
      return outerXML ? this.replace(fragment) && parent : this.add(fragment);
    }
  }
  extend(Dom, {
    attr,
    find,
    findOne
  });
  register(Dom, "Dom");
  class Element extends Dom {
    constructor(node, attrs2) {
      super(node, attrs2);
      this.dom = {};
      this.node.instance = this;
      if (node.hasAttribute("svgjs:data")) {
        this.setData(JSON.parse(node.getAttribute("svgjs:data")) || {});
      }
    }
    // Move element by its center
    center(x2, y2) {
      return this.cx(x2).cy(y2);
    }
    // Move by center over x-axis
    cx(x2) {
      return x2 == null ? this.x() + this.width() / 2 : this.x(x2 - this.width() / 2);
    }
    // Move by center over y-axis
    cy(y2) {
      return y2 == null ? this.y() + this.height() / 2 : this.y(y2 - this.height() / 2);
    }
    // Get defs
    defs() {
      const root2 = this.root();
      return root2 && root2.defs();
    }
    // Relative move over x and y axes
    dmove(x2, y2) {
      return this.dx(x2).dy(y2);
    }
    // Relative move over x axis
    dx(x2 = 0) {
      return this.x(new SVGNumber(x2).plus(this.x()));
    }
    // Relative move over y axis
    dy(y2 = 0) {
      return this.y(new SVGNumber(y2).plus(this.y()));
    }
    getEventHolder() {
      return this;
    }
    // Set height of element
    height(height2) {
      return this.attr("height", height2);
    }
    // Move element to given x and y values
    move(x2, y2) {
      return this.x(x2).y(y2);
    }
    // return array of all ancestors of given type up to the root svg
    parents(until = this.root()) {
      const isSelector = typeof until === "string";
      if (!isSelector) {
        until = makeInstance(until);
      }
      const parents = new List();
      let parent = this;
      while ((parent = parent.parent()) && parent.node !== globals.document && parent.nodeName !== "#document-fragment") {
        parents.push(parent);
        if (!isSelector && parent.node === until.node) {
          break;
        }
        if (isSelector && parent.matches(until)) {
          break;
        }
        if (parent.node === this.root().node) {
          return null;
        }
      }
      return parents;
    }
    // Get referenced element form attribute value
    reference(attr2) {
      attr2 = this.attr(attr2);
      if (!attr2)
        return null;
      const m = (attr2 + "").match(reference);
      return m ? makeInstance(m[1]) : null;
    }
    // Get parent document
    root() {
      const p = this.parent(getClass(root));
      return p && p.root();
    }
    // set given data to the elements data property
    setData(o) {
      this.dom = o;
      return this;
    }
    // Set element size to given width and height
    size(width2, height2) {
      const p = proportionalSize(this, width2, height2);
      return this.width(new SVGNumber(p.width)).height(new SVGNumber(p.height));
    }
    // Set width of element
    width(width2) {
      return this.attr("width", width2);
    }
    // write svgjs data to the dom
    writeDataToDom() {
      this.node.removeAttribute("svgjs:data");
      if (Object.keys(this.dom).length) {
        this.node.setAttribute("svgjs:data", JSON.stringify(this.dom));
      }
      return super.writeDataToDom();
    }
    // Move over x-axis
    x(x2) {
      return this.attr("x", x2);
    }
    // Move over y-axis
    y(y2) {
      return this.attr("y", y2);
    }
  }
  extend(Element, {
    bbox,
    rbox,
    inside,
    point,
    ctm,
    screenCTM
  });
  register(Element, "Element");
  const sugar = {
    stroke: ["color", "width", "opacity", "linecap", "linejoin", "miterlimit", "dasharray", "dashoffset"],
    fill: ["color", "opacity", "rule"],
    prefix: function(t, a) {
      return a === "color" ? t : t + "-" + a;
    }
  };
  ["fill", "stroke"].forEach(function(m) {
    const extension = {};
    let i;
    extension[m] = function(o) {
      if (typeof o === "undefined") {
        return this.attr(m);
      }
      if (typeof o === "string" || o instanceof Color || Color.isRgb(o) || o instanceof Element) {
        this.attr(m, o);
      } else {
        for (i = sugar[m].length - 1; i >= 0; i--) {
          if (o[sugar[m][i]] != null) {
            this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]]);
          }
        }
      }
      return this;
    };
    registerMethods(["Element", "Runner"], extension);
  });
  registerMethods(["Element", "Runner"], {
    // Let the user set the matrix directly
    matrix: function(mat, b, c, d, e, f) {
      if (mat == null) {
        return new Matrix(this);
      }
      return this.attr("transform", new Matrix(mat, b, c, d, e, f));
    },
    // Map rotation to transform
    rotate: function(angle, cx2, cy2) {
      return this.transform({
        rotate: angle,
        ox: cx2,
        oy: cy2
      }, true);
    },
    // Map skew to transform
    skew: function(x2, y2, cx2, cy2) {
      return arguments.length === 1 || arguments.length === 3 ? this.transform({
        skew: x2,
        ox: y2,
        oy: cx2
      }, true) : this.transform({
        skew: [x2, y2],
        ox: cx2,
        oy: cy2
      }, true);
    },
    shear: function(lam, cx2, cy2) {
      return this.transform({
        shear: lam,
        ox: cx2,
        oy: cy2
      }, true);
    },
    // Map scale to transform
    scale: function(x2, y2, cx2, cy2) {
      return arguments.length === 1 || arguments.length === 3 ? this.transform({
        scale: x2,
        ox: y2,
        oy: cx2
      }, true) : this.transform({
        scale: [x2, y2],
        ox: cx2,
        oy: cy2
      }, true);
    },
    // Map translate to transform
    translate: function(x2, y2) {
      return this.transform({
        translate: [x2, y2]
      }, true);
    },
    // Map relative translations to transform
    relative: function(x2, y2) {
      return this.transform({
        relative: [x2, y2]
      }, true);
    },
    // Map flip to transform
    flip: function(direction = "both", origin = "center") {
      if ("xybothtrue".indexOf(direction) === -1) {
        origin = direction;
        direction = "both";
      }
      return this.transform({
        flip: direction,
        origin
      }, true);
    },
    // Opacity
    opacity: function(value) {
      return this.attr("opacity", value);
    }
  });
  registerMethods("radius", {
    // Add x and y radius
    radius: function(x2, y2 = x2) {
      const type = (this._element || this).type;
      return type === "radialGradient" ? this.attr("r", new SVGNumber(x2)) : this.rx(x2).ry(y2);
    }
  });
  registerMethods("Path", {
    // Get path length
    length: function() {
      return this.node.getTotalLength();
    },
    // Get point at length
    pointAt: function(length2) {
      return new Point(this.node.getPointAtLength(length2));
    }
  });
  registerMethods(["Element", "Runner"], {
    // Set font
    font: function(a, v) {
      if (typeof a === "object") {
        for (v in a)
          this.font(v, a[v]);
        return this;
      }
      return a === "leading" ? this.leading(v) : a === "anchor" ? this.attr("text-anchor", v) : a === "size" || a === "family" || a === "weight" || a === "stretch" || a === "variant" || a === "style" ? this.attr("font-" + a, v) : this.attr(a, v);
    }
  });
  const methods = ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mouseout", "mousemove", "mouseenter", "mouseleave", "touchstart", "touchmove", "touchleave", "touchend", "touchcancel"].reduce(function(last, event) {
    const fn = function(f) {
      if (f === null) {
        this.off(event);
      } else {
        this.on(event, f);
      }
      return this;
    };
    last[event] = fn;
    return last;
  }, {});
  registerMethods("Element", methods);
  function untransform() {
    return this.attr("transform", null);
  }
  function matrixify() {
    const matrix = (this.attr("transform") || "").split(transforms).slice(0, -1).map(function(str) {
      const kv = str.trim().split("(");
      return [kv[0], kv[1].split(delimiter).map(function(str2) {
        return parseFloat(str2);
      })];
    }).reverse().reduce(function(matrix2, transform2) {
      if (transform2[0] === "matrix") {
        return matrix2.lmultiply(Matrix.fromArray(transform2[1]));
      }
      return matrix2[transform2[0]].apply(matrix2, transform2[1]);
    }, new Matrix());
    return matrix;
  }
  function toParent(parent, i) {
    if (this === parent)
      return this;
    const ctm2 = this.screenCTM();
    const pCtm = parent.screenCTM().inverse();
    this.addTo(parent, i).untransform().transform(pCtm.multiply(ctm2));
    return this;
  }
  function toRoot(i) {
    return this.toParent(this.root(), i);
  }
  function transform(o, relative) {
    if (o == null || typeof o === "string") {
      const decomposed = new Matrix(this).decompose();
      return o == null ? decomposed : decomposed[o];
    }
    if (!Matrix.isMatrixLike(o)) {
      o = {
        ...o,
        origin: getOrigin(o, this)
      };
    }
    const cleanRelative = relative === true ? this : relative || false;
    const result = new Matrix(cleanRelative).transform(o);
    return this.attr("transform", result);
  }
  registerMethods("Element", {
    untransform,
    matrixify,
    toParent,
    toRoot,
    transform
  });
  class Container extends Element {
    flatten(parent = this, index) {
      this.each(function() {
        if (this instanceof Container) {
          return this.flatten().ungroup();
        }
      });
      return this;
    }
    ungroup(parent = this.parent(), index = parent.index(this)) {
      index = index === -1 ? parent.children().length : index;
      this.each(function(i, children) {
        return children[children.length - i - 1].toParent(parent, index);
      });
      return this.remove();
    }
  }
  register(Container, "Container");
  class Defs extends Container {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("defs", node), attrs2);
    }
    flatten() {
      return this;
    }
    ungroup() {
      return this;
    }
  }
  register(Defs, "Defs");
  class Shape extends Element {
  }
  register(Shape, "Shape");
  function rx(rx2) {
    return this.attr("rx", rx2);
  }
  function ry(ry2) {
    return this.attr("ry", ry2);
  }
  function x$3(x2) {
    return x2 == null ? this.cx() - this.rx() : this.cx(x2 + this.rx());
  }
  function y$3(y2) {
    return y2 == null ? this.cy() - this.ry() : this.cy(y2 + this.ry());
  }
  function cx$1(x2) {
    return this.attr("cx", x2);
  }
  function cy$1(y2) {
    return this.attr("cy", y2);
  }
  function width$2(width2) {
    return width2 == null ? this.rx() * 2 : this.rx(new SVGNumber(width2).divide(2));
  }
  function height$2(height2) {
    return height2 == null ? this.ry() * 2 : this.ry(new SVGNumber(height2).divide(2));
  }
  var circled = {
    __proto__: null,
    rx,
    ry,
    x: x$3,
    y: y$3,
    cx: cx$1,
    cy: cy$1,
    width: width$2,
    height: height$2
  };
  class Ellipse extends Shape {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("ellipse", node), attrs2);
    }
    size(width2, height2) {
      const p = proportionalSize(this, width2, height2);
      return this.rx(new SVGNumber(p.width).divide(2)).ry(new SVGNumber(p.height).divide(2));
    }
  }
  extend(Ellipse, circled);
  registerMethods("Container", {
    // Create an ellipse
    ellipse: wrapWithAttrCheck(function(width2 = 0, height2 = width2) {
      return this.put(new Ellipse()).size(width2, height2).move(0, 0);
    })
  });
  register(Ellipse, "Ellipse");
  class Fragment extends Dom {
    constructor(node = globals.document.createDocumentFragment()) {
      super(node);
    }
    // Import / Export raw xml
    xml(xmlOrFn, outerXML, ns) {
      if (typeof xmlOrFn === "boolean") {
        ns = outerXML;
        outerXML = xmlOrFn;
        xmlOrFn = null;
      }
      if (xmlOrFn == null || typeof xmlOrFn === "function") {
        const wrapper = new Dom(create("wrapper", ns));
        wrapper.add(this.node.cloneNode(true));
        return wrapper.xml(false, ns);
      }
      return super.xml(xmlOrFn, false, ns);
    }
  }
  register(Fragment, "Fragment");
  function from(x2, y2) {
    return (this._element || this).type === "radialGradient" ? this.attr({
      fx: new SVGNumber(x2),
      fy: new SVGNumber(y2)
    }) : this.attr({
      x1: new SVGNumber(x2),
      y1: new SVGNumber(y2)
    });
  }
  function to(x2, y2) {
    return (this._element || this).type === "radialGradient" ? this.attr({
      cx: new SVGNumber(x2),
      cy: new SVGNumber(y2)
    }) : this.attr({
      x2: new SVGNumber(x2),
      y2: new SVGNumber(y2)
    });
  }
  var gradiented = {
    __proto__: null,
    from,
    to
  };
  class Gradient extends Container {
    constructor(type, attrs2) {
      super(nodeOrNew(type + "Gradient", typeof type === "string" ? null : type), attrs2);
    }
    // custom attr to handle transform
    attr(a, b, c) {
      if (a === "transform")
        a = "gradientTransform";
      return super.attr(a, b, c);
    }
    bbox() {
      return new Box();
    }
    targets() {
      return baseFind("svg [fill*=" + this.id() + "]");
    }
    // Alias string conversion to fill
    toString() {
      return this.url();
    }
    // Update gradient
    update(block) {
      this.clear();
      if (typeof block === "function") {
        block.call(this, this);
      }
      return this;
    }
    // Return the fill id
    url() {
      return "url(#" + this.id() + ")";
    }
  }
  extend(Gradient, gradiented);
  registerMethods({
    Container: {
      // Create gradient element in defs
      gradient(...args) {
        return this.defs().gradient(...args);
      }
    },
    // define gradient
    Defs: {
      gradient: wrapWithAttrCheck(function(type, block) {
        return this.put(new Gradient(type)).update(block);
      })
    }
  });
  register(Gradient, "Gradient");
  class Pattern extends Container {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("pattern", node), attrs2);
    }
    // custom attr to handle transform
    attr(a, b, c) {
      if (a === "transform")
        a = "patternTransform";
      return super.attr(a, b, c);
    }
    bbox() {
      return new Box();
    }
    targets() {
      return baseFind("svg [fill*=" + this.id() + "]");
    }
    // Alias string conversion to fill
    toString() {
      return this.url();
    }
    // Update pattern by rebuilding
    update(block) {
      this.clear();
      if (typeof block === "function") {
        block.call(this, this);
      }
      return this;
    }
    // Return the fill id
    url() {
      return "url(#" + this.id() + ")";
    }
  }
  registerMethods({
    Container: {
      // Create pattern element in defs
      pattern(...args) {
        return this.defs().pattern(...args);
      }
    },
    Defs: {
      pattern: wrapWithAttrCheck(function(width2, height2, block) {
        return this.put(new Pattern()).update(block).attr({
          x: 0,
          y: 0,
          width: width2,
          height: height2,
          patternUnits: "userSpaceOnUse"
        });
      })
    }
  });
  register(Pattern, "Pattern");
  class Image extends Shape {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("image", node), attrs2);
    }
    // (re)load image
    load(url, callback) {
      if (!url)
        return this;
      const img = new globals.window.Image();
      on(img, "load", function(e) {
        const p = this.parent(Pattern);
        if (this.width() === 0 && this.height() === 0) {
          this.size(img.width, img.height);
        }
        if (p instanceof Pattern) {
          if (p.width() === 0 && p.height() === 0) {
            p.size(this.width(), this.height());
          }
        }
        if (typeof callback === "function") {
          callback.call(this, e);
        }
      }, this);
      on(img, "load error", function() {
        off(img);
      });
      return this.attr("href", img.src = url, xlink);
    }
  }
  registerAttrHook(function(attr2, val, _this) {
    if (attr2 === "fill" || attr2 === "stroke") {
      if (isImage.test(val)) {
        val = _this.root().defs().image(val);
      }
    }
    if (val instanceof Image) {
      val = _this.root().defs().pattern(0, 0, (pattern) => {
        pattern.add(val);
      });
    }
    return val;
  });
  registerMethods({
    Container: {
      // create image element, load image and set its size
      image: wrapWithAttrCheck(function(source, callback) {
        return this.put(new Image()).size(0, 0).load(source, callback);
      })
    }
  });
  register(Image, "Image");
  class PointArray extends SVGArray {
    // Get bounding box of points
    bbox() {
      let maxX = -Infinity;
      let maxY = -Infinity;
      let minX = Infinity;
      let minY = Infinity;
      this.forEach(function(el) {
        maxX = Math.max(el[0], maxX);
        maxY = Math.max(el[1], maxY);
        minX = Math.min(el[0], minX);
        minY = Math.min(el[1], minY);
      });
      return new Box(minX, minY, maxX - minX, maxY - minY);
    }
    // Move point string
    move(x2, y2) {
      const box = this.bbox();
      x2 -= box.x;
      y2 -= box.y;
      if (!isNaN(x2) && !isNaN(y2)) {
        for (let i = this.length - 1; i >= 0; i--) {
          this[i] = [this[i][0] + x2, this[i][1] + y2];
        }
      }
      return this;
    }
    // Parse point string and flat array
    parse(array2 = [0, 0]) {
      const points = [];
      if (array2 instanceof Array) {
        array2 = Array.prototype.concat.apply([], array2);
      } else {
        array2 = array2.trim().split(delimiter).map(parseFloat);
      }
      if (array2.length % 2 !== 0)
        array2.pop();
      for (let i = 0, len = array2.length; i < len; i = i + 2) {
        points.push([array2[i], array2[i + 1]]);
      }
      return points;
    }
    // Resize poly string
    size(width2, height2) {
      let i;
      const box = this.bbox();
      for (i = this.length - 1; i >= 0; i--) {
        if (box.width)
          this[i][0] = (this[i][0] - box.x) * width2 / box.width + box.x;
        if (box.height)
          this[i][1] = (this[i][1] - box.y) * height2 / box.height + box.y;
      }
      return this;
    }
    // Convert array to line object
    toLine() {
      return {
        x1: this[0][0],
        y1: this[0][1],
        x2: this[1][0],
        y2: this[1][1]
      };
    }
    // Convert array to string
    toString() {
      const array2 = [];
      for (let i = 0, il = this.length; i < il; i++) {
        array2.push(this[i].join(","));
      }
      return array2.join(" ");
    }
    transform(m) {
      return this.clone().transformO(m);
    }
    // transform points with matrix (similar to Point.transform)
    transformO(m) {
      if (!Matrix.isMatrixLike(m)) {
        m = new Matrix(m);
      }
      for (let i = this.length; i--; ) {
        const [x2, y2] = this[i];
        this[i][0] = m.a * x2 + m.c * y2 + m.e;
        this[i][1] = m.b * x2 + m.d * y2 + m.f;
      }
      return this;
    }
  }
  const MorphArray = PointArray;
  function x$2(x2) {
    return x2 == null ? this.bbox().x : this.move(x2, this.bbox().y);
  }
  function y$2(y2) {
    return y2 == null ? this.bbox().y : this.move(this.bbox().x, y2);
  }
  function width$1(width2) {
    const b = this.bbox();
    return width2 == null ? b.width : this.size(width2, b.height);
  }
  function height$1(height2) {
    const b = this.bbox();
    return height2 == null ? b.height : this.size(b.width, height2);
  }
  var pointed = {
    __proto__: null,
    MorphArray,
    x: x$2,
    y: y$2,
    width: width$1,
    height: height$1
  };
  class Line extends Shape {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("line", node), attrs2);
    }
    // Get array
    array() {
      return new PointArray([[this.attr("x1"), this.attr("y1")], [this.attr("x2"), this.attr("y2")]]);
    }
    // Move by left top corner
    move(x2, y2) {
      return this.attr(this.array().move(x2, y2).toLine());
    }
    // Overwrite native plot() method
    plot(x1, y1, x2, y2) {
      if (x1 == null) {
        return this.array();
      } else if (typeof y1 !== "undefined") {
        x1 = {
          x1,
          y1,
          x2,
          y2
        };
      } else {
        x1 = new PointArray(x1).toLine();
      }
      return this.attr(x1);
    }
    // Set element size to given width and height
    size(width2, height2) {
      const p = proportionalSize(this, width2, height2);
      return this.attr(this.array().size(p.width, p.height).toLine());
    }
  }
  extend(Line, pointed);
  registerMethods({
    Container: {
      // Create a line element
      line: wrapWithAttrCheck(function(...args) {
        return Line.prototype.plot.apply(this.put(new Line()), args[0] != null ? args : [0, 0, 0, 0]);
      })
    }
  });
  register(Line, "Line");
  class Marker extends Container {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("marker", node), attrs2);
    }
    // Set height of element
    height(height2) {
      return this.attr("markerHeight", height2);
    }
    orient(orient) {
      return this.attr("orient", orient);
    }
    // Set marker refX and refY
    ref(x2, y2) {
      return this.attr("refX", x2).attr("refY", y2);
    }
    // Return the fill id
    toString() {
      return "url(#" + this.id() + ")";
    }
    // Update marker
    update(block) {
      this.clear();
      if (typeof block === "function") {
        block.call(this, this);
      }
      return this;
    }
    // Set width of element
    width(width2) {
      return this.attr("markerWidth", width2);
    }
  }
  registerMethods({
    Container: {
      marker(...args) {
        return this.defs().marker(...args);
      }
    },
    Defs: {
      // Create marker
      marker: wrapWithAttrCheck(function(width2, height2, block) {
        return this.put(new Marker()).size(width2, height2).ref(width2 / 2, height2 / 2).viewbox(0, 0, width2, height2).attr("orient", "auto").update(block);
      })
    },
    marker: {
      // Create and attach markers
      marker(marker, width2, height2, block) {
        let attr2 = ["marker"];
        if (marker !== "all")
          attr2.push(marker);
        attr2 = attr2.join("-");
        marker = arguments[1] instanceof Marker ? arguments[1] : this.defs().marker(width2, height2, block);
        return this.attr(attr2, marker);
      }
    }
  });
  register(Marker, "Marker");
  function makeSetterGetter(k, f) {
    return function(v) {
      if (v == null)
        return this[k];
      this[k] = v;
      if (f)
        f.call(this);
      return this;
    };
  }
  const easing = {
    "-": function(pos) {
      return pos;
    },
    "<>": function(pos) {
      return -Math.cos(pos * Math.PI) / 2 + 0.5;
    },
    ">": function(pos) {
      return Math.sin(pos * Math.PI / 2);
    },
    "<": function(pos) {
      return -Math.cos(pos * Math.PI / 2) + 1;
    },
    bezier: function(x1, y1, x2, y2) {
      return function(t) {
        if (t < 0) {
          if (x1 > 0) {
            return y1 / x1 * t;
          } else if (x2 > 0) {
            return y2 / x2 * t;
          } else {
            return 0;
          }
        } else if (t > 1) {
          if (x2 < 1) {
            return (1 - y2) / (1 - x2) * t + (y2 - x2) / (1 - x2);
          } else if (x1 < 1) {
            return (1 - y1) / (1 - x1) * t + (y1 - x1) / (1 - x1);
          } else {
            return 1;
          }
        } else {
          return 3 * t * (1 - t) ** 2 * y1 + 3 * t ** 2 * (1 - t) * y2 + t ** 3;
        }
      };
    },
    // see https://www.w3.org/TR/css-easing-1/#step-timing-function-algo
    steps: function(steps, stepPosition = "end") {
      stepPosition = stepPosition.split("-").reverse()[0];
      let jumps = steps;
      if (stepPosition === "none") {
        --jumps;
      } else if (stepPosition === "both") {
        ++jumps;
      }
      return (t, beforeFlag = false) => {
        let step = Math.floor(t * steps);
        const jumping = t * step % 1 === 0;
        if (stepPosition === "start" || stepPosition === "both") {
          ++step;
        }
        if (beforeFlag && jumping) {
          --step;
        }
        if (t >= 0 && step < 0) {
          step = 0;
        }
        if (t <= 1 && step > jumps) {
          step = jumps;
        }
        return step / jumps;
      };
    }
  };
  class Stepper {
    done() {
      return false;
    }
  }
  class Ease extends Stepper {
    constructor(fn = timeline.ease) {
      super();
      this.ease = easing[fn] || fn;
    }
    step(from2, to2, pos) {
      if (typeof from2 !== "number") {
        return pos < 1 ? from2 : to2;
      }
      return from2 + (to2 - from2) * this.ease(pos);
    }
  }
  class Controller extends Stepper {
    constructor(fn) {
      super();
      this.stepper = fn;
    }
    done(c) {
      return c.done;
    }
    step(current, target, dt, c) {
      return this.stepper(current, target, dt, c);
    }
  }
  function recalculate() {
    const duration = (this._duration || 500) / 1e3;
    const overshoot = this._overshoot || 0;
    const eps = 1e-10;
    const pi = Math.PI;
    const os = Math.log(overshoot / 100 + eps);
    const zeta = -os / Math.sqrt(pi * pi + os * os);
    const wn = 3.9 / (zeta * duration);
    this.d = 2 * zeta * wn;
    this.k = wn * wn;
  }
  class Spring extends Controller {
    constructor(duration = 500, overshoot = 0) {
      super();
      this.duration(duration).overshoot(overshoot);
    }
    step(current, target, dt, c) {
      if (typeof current === "string")
        return current;
      c.done = dt === Infinity;
      if (dt === Infinity)
        return target;
      if (dt === 0)
        return current;
      if (dt > 100)
        dt = 16;
      dt /= 1e3;
      const velocity = c.velocity || 0;
      const acceleration = -this.d * velocity - this.k * (current - target);
      const newPosition = current + velocity * dt + acceleration * dt * dt / 2;
      c.velocity = velocity + acceleration * dt;
      c.done = Math.abs(target - newPosition) + Math.abs(velocity) < 2e-3;
      return c.done ? target : newPosition;
    }
  }
  extend(Spring, {
    duration: makeSetterGetter("_duration", recalculate),
    overshoot: makeSetterGetter("_overshoot", recalculate)
  });
  class PID extends Controller {
    constructor(p = 0.1, i = 0.01, d = 0, windup = 1e3) {
      super();
      this.p(p).i(i).d(d).windup(windup);
    }
    step(current, target, dt, c) {
      if (typeof current === "string")
        return current;
      c.done = dt === Infinity;
      if (dt === Infinity)
        return target;
      if (dt === 0)
        return current;
      const p = target - current;
      let i = (c.integral || 0) + p * dt;
      const d = (p - (c.error || 0)) / dt;
      const windup = this._windup;
      if (windup !== false) {
        i = Math.max(-windup, Math.min(i, windup));
      }
      c.error = p;
      c.integral = i;
      c.done = Math.abs(p) < 1e-3;
      return c.done ? target : current + (this.P * p + this.I * i + this.D * d);
    }
  }
  extend(PID, {
    windup: makeSetterGetter("_windup"),
    p: makeSetterGetter("P"),
    i: makeSetterGetter("I"),
    d: makeSetterGetter("D")
  });
  const segmentParameters = {
    M: 2,
    L: 2,
    H: 1,
    V: 1,
    C: 6,
    S: 4,
    Q: 4,
    T: 2,
    A: 7,
    Z: 0
  };
  const pathHandlers = {
    M: function(c, p, p0) {
      p.x = p0.x = c[0];
      p.y = p0.y = c[1];
      return ["M", p.x, p.y];
    },
    L: function(c, p) {
      p.x = c[0];
      p.y = c[1];
      return ["L", c[0], c[1]];
    },
    H: function(c, p) {
      p.x = c[0];
      return ["H", c[0]];
    },
    V: function(c, p) {
      p.y = c[0];
      return ["V", c[0]];
    },
    C: function(c, p) {
      p.x = c[4];
      p.y = c[5];
      return ["C", c[0], c[1], c[2], c[3], c[4], c[5]];
    },
    S: function(c, p) {
      p.x = c[2];
      p.y = c[3];
      return ["S", c[0], c[1], c[2], c[3]];
    },
    Q: function(c, p) {
      p.x = c[2];
      p.y = c[3];
      return ["Q", c[0], c[1], c[2], c[3]];
    },
    T: function(c, p) {
      p.x = c[0];
      p.y = c[1];
      return ["T", c[0], c[1]];
    },
    Z: function(c, p, p0) {
      p.x = p0.x;
      p.y = p0.y;
      return ["Z"];
    },
    A: function(c, p) {
      p.x = c[5];
      p.y = c[6];
      return ["A", c[0], c[1], c[2], c[3], c[4], c[5], c[6]];
    }
  };
  const mlhvqtcsaz = "mlhvqtcsaz".split("");
  for (let i = 0, il = mlhvqtcsaz.length; i < il; ++i) {
    pathHandlers[mlhvqtcsaz[i]] = function(i2) {
      return function(c, p, p0) {
        if (i2 === "H")
          c[0] = c[0] + p.x;
        else if (i2 === "V")
          c[0] = c[0] + p.y;
        else if (i2 === "A") {
          c[5] = c[5] + p.x;
          c[6] = c[6] + p.y;
        } else {
          for (let j = 0, jl = c.length; j < jl; ++j) {
            c[j] = c[j] + (j % 2 ? p.y : p.x);
          }
        }
        return pathHandlers[i2](c, p, p0);
      };
    }(mlhvqtcsaz[i].toUpperCase());
  }
  function makeAbsolut(parser2) {
    const command = parser2.segment[0];
    return pathHandlers[command](parser2.segment.slice(1), parser2.p, parser2.p0);
  }
  function segmentComplete(parser2) {
    return parser2.segment.length && parser2.segment.length - 1 === segmentParameters[parser2.segment[0].toUpperCase()];
  }
  function startNewSegment(parser2, token) {
    parser2.inNumber && finalizeNumber(parser2, false);
    const pathLetter = isPathLetter.test(token);
    if (pathLetter) {
      parser2.segment = [token];
    } else {
      const lastCommand = parser2.lastCommand;
      const small = lastCommand.toLowerCase();
      const isSmall = lastCommand === small;
      parser2.segment = [small === "m" ? isSmall ? "l" : "L" : lastCommand];
    }
    parser2.inSegment = true;
    parser2.lastCommand = parser2.segment[0];
    return pathLetter;
  }
  function finalizeNumber(parser2, inNumber) {
    if (!parser2.inNumber)
      throw new Error("Parser Error");
    parser2.number && parser2.segment.push(parseFloat(parser2.number));
    parser2.inNumber = inNumber;
    parser2.number = "";
    parser2.pointSeen = false;
    parser2.hasExponent = false;
    if (segmentComplete(parser2)) {
      finalizeSegment(parser2);
    }
  }
  function finalizeSegment(parser2) {
    parser2.inSegment = false;
    if (parser2.absolute) {
      parser2.segment = makeAbsolut(parser2);
    }
    parser2.segments.push(parser2.segment);
  }
  function isArcFlag(parser2) {
    if (!parser2.segment.length)
      return false;
    const isArc = parser2.segment[0].toUpperCase() === "A";
    const length2 = parser2.segment.length;
    return isArc && (length2 === 4 || length2 === 5);
  }
  function isExponential(parser2) {
    return parser2.lastToken.toUpperCase() === "E";
  }
  function pathParser(d, toAbsolute = true) {
    let index = 0;
    let token = "";
    const parser2 = {
      segment: [],
      inNumber: false,
      number: "",
      lastToken: "",
      inSegment: false,
      segments: [],
      pointSeen: false,
      hasExponent: false,
      absolute: toAbsolute,
      p0: new Point(),
      p: new Point()
    };
    while (parser2.lastToken = token, token = d.charAt(index++)) {
      if (!parser2.inSegment) {
        if (startNewSegment(parser2, token)) {
          continue;
        }
      }
      if (token === ".") {
        if (parser2.pointSeen || parser2.hasExponent) {
          finalizeNumber(parser2, false);
          --index;
          continue;
        }
        parser2.inNumber = true;
        parser2.pointSeen = true;
        parser2.number += token;
        continue;
      }
      if (!isNaN(parseInt(token))) {
        if (parser2.number === "0" || isArcFlag(parser2)) {
          parser2.inNumber = true;
          parser2.number = token;
          finalizeNumber(parser2, true);
          continue;
        }
        parser2.inNumber = true;
        parser2.number += token;
        continue;
      }
      if (token === " " || token === ",") {
        if (parser2.inNumber) {
          finalizeNumber(parser2, false);
        }
        continue;
      }
      if (token === "-") {
        if (parser2.inNumber && !isExponential(parser2)) {
          finalizeNumber(parser2, false);
          --index;
          continue;
        }
        parser2.number += token;
        parser2.inNumber = true;
        continue;
      }
      if (token.toUpperCase() === "E") {
        parser2.number += token;
        parser2.hasExponent = true;
        continue;
      }
      if (isPathLetter.test(token)) {
        if (parser2.inNumber) {
          finalizeNumber(parser2, false);
        } else if (!segmentComplete(parser2)) {
          throw new Error("parser Error");
        } else {
          finalizeSegment(parser2);
        }
        --index;
      }
    }
    if (parser2.inNumber) {
      finalizeNumber(parser2, false);
    }
    if (parser2.inSegment && segmentComplete(parser2)) {
      finalizeSegment(parser2);
    }
    return parser2.segments;
  }
  function arrayToString(a) {
    let s = "";
    for (let i = 0, il = a.length; i < il; i++) {
      s += a[i][0];
      if (a[i][1] != null) {
        s += a[i][1];
        if (a[i][2] != null) {
          s += " ";
          s += a[i][2];
          if (a[i][3] != null) {
            s += " ";
            s += a[i][3];
            s += " ";
            s += a[i][4];
            if (a[i][5] != null) {
              s += " ";
              s += a[i][5];
              s += " ";
              s += a[i][6];
              if (a[i][7] != null) {
                s += " ";
                s += a[i][7];
              }
            }
          }
        }
      }
    }
    return s + " ";
  }
  class PathArray extends SVGArray {
    // Get bounding box of path
    bbox() {
      parser().path.setAttribute("d", this.toString());
      return new Box(parser.nodes.path.getBBox());
    }
    // Move path string
    move(x2, y2) {
      const box = this.bbox();
      x2 -= box.x;
      y2 -= box.y;
      if (!isNaN(x2) && !isNaN(y2)) {
        for (let l, i = this.length - 1; i >= 0; i--) {
          l = this[i][0];
          if (l === "M" || l === "L" || l === "T") {
            this[i][1] += x2;
            this[i][2] += y2;
          } else if (l === "H") {
            this[i][1] += x2;
          } else if (l === "V") {
            this[i][1] += y2;
          } else if (l === "C" || l === "S" || l === "Q") {
            this[i][1] += x2;
            this[i][2] += y2;
            this[i][3] += x2;
            this[i][4] += y2;
            if (l === "C") {
              this[i][5] += x2;
              this[i][6] += y2;
            }
          } else if (l === "A") {
            this[i][6] += x2;
            this[i][7] += y2;
          }
        }
      }
      return this;
    }
    // Absolutize and parse path to array
    parse(d = "M0 0") {
      if (Array.isArray(d)) {
        d = Array.prototype.concat.apply([], d).toString();
      }
      return pathParser(d);
    }
    // Resize path string
    size(width2, height2) {
      const box = this.bbox();
      let i, l;
      box.width = box.width === 0 ? 1 : box.width;
      box.height = box.height === 0 ? 1 : box.height;
      for (i = this.length - 1; i >= 0; i--) {
        l = this[i][0];
        if (l === "M" || l === "L" || l === "T") {
          this[i][1] = (this[i][1] - box.x) * width2 / box.width + box.x;
          this[i][2] = (this[i][2] - box.y) * height2 / box.height + box.y;
        } else if (l === "H") {
          this[i][1] = (this[i][1] - box.x) * width2 / box.width + box.x;
        } else if (l === "V") {
          this[i][1] = (this[i][1] - box.y) * height2 / box.height + box.y;
        } else if (l === "C" || l === "S" || l === "Q") {
          this[i][1] = (this[i][1] - box.x) * width2 / box.width + box.x;
          this[i][2] = (this[i][2] - box.y) * height2 / box.height + box.y;
          this[i][3] = (this[i][3] - box.x) * width2 / box.width + box.x;
          this[i][4] = (this[i][4] - box.y) * height2 / box.height + box.y;
          if (l === "C") {
            this[i][5] = (this[i][5] - box.x) * width2 / box.width + box.x;
            this[i][6] = (this[i][6] - box.y) * height2 / box.height + box.y;
          }
        } else if (l === "A") {
          this[i][1] = this[i][1] * width2 / box.width;
          this[i][2] = this[i][2] * height2 / box.height;
          this[i][6] = (this[i][6] - box.x) * width2 / box.width + box.x;
          this[i][7] = (this[i][7] - box.y) * height2 / box.height + box.y;
        }
      }
      return this;
    }
    // Convert array to string
    toString() {
      return arrayToString(this);
    }
  }
  const getClassForType = (value) => {
    const type = typeof value;
    if (type === "number") {
      return SVGNumber;
    } else if (type === "string") {
      if (Color.isColor(value)) {
        return Color;
      } else if (delimiter.test(value)) {
        return isPathLetter.test(value) ? PathArray : SVGArray;
      } else if (numberAndUnit.test(value)) {
        return SVGNumber;
      } else {
        return NonMorphable;
      }
    } else if (morphableTypes.indexOf(value.constructor) > -1) {
      return value.constructor;
    } else if (Array.isArray(value)) {
      return SVGArray;
    } else if (type === "object") {
      return ObjectBag;
    } else {
      return NonMorphable;
    }
  };
  class Morphable {
    constructor(stepper) {
      this._stepper = stepper || new Ease("-");
      this._from = null;
      this._to = null;
      this._type = null;
      this._context = null;
      this._morphObj = null;
    }
    at(pos) {
      return this._morphObj.morph(this._from, this._to, pos, this._stepper, this._context);
    }
    done() {
      const complete = this._context.map(this._stepper.done).reduce(function(last, curr) {
        return last && curr;
      }, true);
      return complete;
    }
    from(val) {
      if (val == null) {
        return this._from;
      }
      this._from = this._set(val);
      return this;
    }
    stepper(stepper) {
      if (stepper == null)
        return this._stepper;
      this._stepper = stepper;
      return this;
    }
    to(val) {
      if (val == null) {
        return this._to;
      }
      this._to = this._set(val);
      return this;
    }
    type(type) {
      if (type == null) {
        return this._type;
      }
      this._type = type;
      return this;
    }
    _set(value) {
      if (!this._type) {
        this.type(getClassForType(value));
      }
      let result = new this._type(value);
      if (this._type === Color) {
        result = this._to ? result[this._to[4]]() : this._from ? result[this._from[4]]() : result;
      }
      if (this._type === ObjectBag) {
        result = this._to ? result.align(this._to) : this._from ? result.align(this._from) : result;
      }
      result = result.toConsumable();
      this._morphObj = this._morphObj || new this._type();
      this._context = this._context || Array.apply(null, Array(result.length)).map(Object).map(function(o) {
        o.done = true;
        return o;
      });
      return result;
    }
  }
  class NonMorphable {
    constructor(...args) {
      this.init(...args);
    }
    init(val) {
      val = Array.isArray(val) ? val[0] : val;
      this.value = val;
      return this;
    }
    toArray() {
      return [this.value];
    }
    valueOf() {
      return this.value;
    }
  }
  class TransformBag {
    constructor(...args) {
      this.init(...args);
    }
    init(obj) {
      if (Array.isArray(obj)) {
        obj = {
          scaleX: obj[0],
          scaleY: obj[1],
          shear: obj[2],
          rotate: obj[3],
          translateX: obj[4],
          translateY: obj[5],
          originX: obj[6],
          originY: obj[7]
        };
      }
      Object.assign(this, TransformBag.defaults, obj);
      return this;
    }
    toArray() {
      const v = this;
      return [v.scaleX, v.scaleY, v.shear, v.rotate, v.translateX, v.translateY, v.originX, v.originY];
    }
  }
  TransformBag.defaults = {
    scaleX: 1,
    scaleY: 1,
    shear: 0,
    rotate: 0,
    translateX: 0,
    translateY: 0,
    originX: 0,
    originY: 0
  };
  const sortByKey = (a, b) => {
    return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;
  };
  class ObjectBag {
    constructor(...args) {
      this.init(...args);
    }
    align(other) {
      const values = this.values;
      for (let i = 0, il = values.length; i < il; ++i) {
        if (values[i + 1] === other[i + 1]) {
          if (values[i + 1] === Color && other[i + 7] !== values[i + 7]) {
            const space = other[i + 7];
            const color = new Color(this.values.splice(i + 3, 5))[space]().toArray();
            this.values.splice(i + 3, 0, ...color);
          }
          i += values[i + 2] + 2;
          continue;
        }
        if (!other[i + 1]) {
          return this;
        }
        const defaultObject = new other[i + 1]().toArray();
        const toDelete = values[i + 2] + 3;
        values.splice(i, toDelete, other[i], other[i + 1], other[i + 2], ...defaultObject);
        i += values[i + 2] + 2;
      }
      return this;
    }
    init(objOrArr) {
      this.values = [];
      if (Array.isArray(objOrArr)) {
        this.values = objOrArr.slice();
        return;
      }
      objOrArr = objOrArr || {};
      const entries = [];
      for (const i in objOrArr) {
        const Type = getClassForType(objOrArr[i]);
        const val = new Type(objOrArr[i]).toArray();
        entries.push([i, Type, val.length, ...val]);
      }
      entries.sort(sortByKey);
      this.values = entries.reduce((last, curr) => last.concat(curr), []);
      return this;
    }
    toArray() {
      return this.values;
    }
    valueOf() {
      const obj = {};
      const arr = this.values;
      while (arr.length) {
        const key = arr.shift();
        const Type = arr.shift();
        const num = arr.shift();
        const values = arr.splice(0, num);
        obj[key] = new Type(values);
      }
      return obj;
    }
  }
  const morphableTypes = [NonMorphable, TransformBag, ObjectBag];
  function registerMorphableType(type = []) {
    morphableTypes.push(...[].concat(type));
  }
  function makeMorphable() {
    extend(morphableTypes, {
      to(val) {
        return new Morphable().type(this.constructor).from(this.toArray()).to(val);
      },
      fromArray(arr) {
        this.init(arr);
        return this;
      },
      toConsumable() {
        return this.toArray();
      },
      morph(from2, to2, pos, stepper, context) {
        const mapper = function(i, index) {
          return stepper.step(i, to2[index], pos, context[index], context);
        };
        return this.fromArray(from2.map(mapper));
      }
    });
  }
  class Path extends Shape {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("path", node), attrs2);
    }
    // Get array
    array() {
      return this._array || (this._array = new PathArray(this.attr("d")));
    }
    // Clear array cache
    clear() {
      delete this._array;
      return this;
    }
    // Set height of element
    height(height2) {
      return height2 == null ? this.bbox().height : this.size(this.bbox().width, height2);
    }
    // Move by left top corner
    move(x2, y2) {
      return this.attr("d", this.array().move(x2, y2));
    }
    // Plot new path
    plot(d) {
      return d == null ? this.array() : this.clear().attr("d", typeof d === "string" ? d : this._array = new PathArray(d));
    }
    // Set element size to given width and height
    size(width2, height2) {
      const p = proportionalSize(this, width2, height2);
      return this.attr("d", this.array().size(p.width, p.height));
    }
    // Set width of element
    width(width2) {
      return width2 == null ? this.bbox().width : this.size(width2, this.bbox().height);
    }
    // Move by left top corner over x-axis
    x(x2) {
      return x2 == null ? this.bbox().x : this.move(x2, this.bbox().y);
    }
    // Move by left top corner over y-axis
    y(y2) {
      return y2 == null ? this.bbox().y : this.move(this.bbox().x, y2);
    }
  }
  Path.prototype.MorphArray = PathArray;
  registerMethods({
    Container: {
      // Create a wrapped path element
      path: wrapWithAttrCheck(function(d) {
        return this.put(new Path()).plot(d || new PathArray());
      })
    }
  });
  register(Path, "Path");
  function array() {
    return this._array || (this._array = new PointArray(this.attr("points")));
  }
  function clear() {
    delete this._array;
    return this;
  }
  function move$2(x2, y2) {
    return this.attr("points", this.array().move(x2, y2));
  }
  function plot(p) {
    return p == null ? this.array() : this.clear().attr("points", typeof p === "string" ? p : this._array = new PointArray(p));
  }
  function size$1(width2, height2) {
    const p = proportionalSize(this, width2, height2);
    return this.attr("points", this.array().size(p.width, p.height));
  }
  var poly = {
    __proto__: null,
    array,
    clear,
    move: move$2,
    plot,
    size: size$1
  };
  class Polygon extends Shape {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("polygon", node), attrs2);
    }
  }
  registerMethods({
    Container: {
      // Create a wrapped polygon element
      polygon: wrapWithAttrCheck(function(p) {
        return this.put(new Polygon()).plot(p || new PointArray());
      })
    }
  });
  extend(Polygon, pointed);
  extend(Polygon, poly);
  register(Polygon, "Polygon");
  class Polyline extends Shape {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("polyline", node), attrs2);
    }
  }
  registerMethods({
    Container: {
      // Create a wrapped polygon element
      polyline: wrapWithAttrCheck(function(p) {
        return this.put(new Polyline()).plot(p || new PointArray());
      })
    }
  });
  extend(Polyline, pointed);
  extend(Polyline, poly);
  register(Polyline, "Polyline");
  class Rect extends Shape {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("rect", node), attrs2);
    }
  }
  extend(Rect, {
    rx,
    ry
  });
  registerMethods({
    Container: {
      // Create a rect element
      rect: wrapWithAttrCheck(function(width2, height2) {
        return this.put(new Rect()).size(width2, height2);
      })
    }
  });
  register(Rect, "Rect");
  class Queue {
    constructor() {
      this._first = null;
      this._last = null;
    }
    // Shows us the first item in the list
    first() {
      return this._first && this._first.value;
    }
    // Shows us the last item in the list
    last() {
      return this._last && this._last.value;
    }
    push(value) {
      const item = typeof value.next !== "undefined" ? value : {
        value,
        next: null,
        prev: null
      };
      if (this._last) {
        item.prev = this._last;
        this._last.next = item;
        this._last = item;
      } else {
        this._last = item;
        this._first = item;
      }
      return item;
    }
    // Removes the item that was returned from the push
    remove(item) {
      if (item.prev)
        item.prev.next = item.next;
      if (item.next)
        item.next.prev = item.prev;
      if (item === this._last)
        this._last = item.prev;
      if (item === this._first)
        this._first = item.next;
      item.prev = null;
      item.next = null;
    }
    shift() {
      const remove = this._first;
      if (!remove)
        return null;
      this._first = remove.next;
      if (this._first)
        this._first.prev = null;
      this._last = this._first ? this._last : null;
      return remove.value;
    }
  }
  const Animator = {
    nextDraw: null,
    frames: new Queue(),
    timeouts: new Queue(),
    immediates: new Queue(),
    timer: () => globals.window.performance || globals.window.Date,
    transforms: [],
    frame(fn) {
      const node = Animator.frames.push({
        run: fn
      });
      if (Animator.nextDraw === null) {
        Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw);
      }
      return node;
    },
    timeout(fn, delay) {
      delay = delay || 0;
      const time = Animator.timer().now() + delay;
      const node = Animator.timeouts.push({
        run: fn,
        time
      });
      if (Animator.nextDraw === null) {
        Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw);
      }
      return node;
    },
    immediate(fn) {
      const node = Animator.immediates.push(fn);
      if (Animator.nextDraw === null) {
        Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw);
      }
      return node;
    },
    cancelFrame(node) {
      node != null && Animator.frames.remove(node);
    },
    clearTimeout(node) {
      node != null && Animator.timeouts.remove(node);
    },
    cancelImmediate(node) {
      node != null && Animator.immediates.remove(node);
    },
    _draw(now) {
      let nextTimeout = null;
      const lastTimeout = Animator.timeouts.last();
      while (nextTimeout = Animator.timeouts.shift()) {
        if (now >= nextTimeout.time) {
          nextTimeout.run();
        } else {
          Animator.timeouts.push(nextTimeout);
        }
        if (nextTimeout === lastTimeout)
          break;
      }
      let nextFrame = null;
      const lastFrame = Animator.frames.last();
      while (nextFrame !== lastFrame && (nextFrame = Animator.frames.shift())) {
        nextFrame.run(now);
      }
      let nextImmediate = null;
      while (nextImmediate = Animator.immediates.shift()) {
        nextImmediate();
      }
      Animator.nextDraw = Animator.timeouts.first() || Animator.frames.first() ? globals.window.requestAnimationFrame(Animator._draw) : null;
    }
  };
  const makeSchedule = function(runnerInfo) {
    const start = runnerInfo.start;
    const duration = runnerInfo.runner.duration();
    const end = start + duration;
    return {
      start,
      duration,
      end,
      runner: runnerInfo.runner
    };
  };
  const defaultSource = function() {
    const w = globals.window;
    return (w.performance || w.Date).now();
  };
  class Timeline extends EventTarget {
    // Construct a new timeline on the given element
    constructor(timeSource = defaultSource) {
      super();
      this._timeSource = timeSource;
      this._startTime = 0;
      this._speed = 1;
      this._persist = 0;
      this._nextFrame = null;
      this._paused = true;
      this._runners = [];
      this._runnerIds = [];
      this._lastRunnerId = -1;
      this._time = 0;
      this._lastSourceTime = 0;
      this._lastStepTime = 0;
      this._step = this._stepFn.bind(this, false);
      this._stepImmediate = this._stepFn.bind(this, true);
    }
    active() {
      return !!this._nextFrame;
    }
    finish() {
      this.time(this.getEndTimeOfTimeline() + 1);
      return this.pause();
    }
    // Calculates the end of the timeline
    getEndTime() {
      const lastRunnerInfo = this.getLastRunnerInfo();
      const lastDuration = lastRunnerInfo ? lastRunnerInfo.runner.duration() : 0;
      const lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : this._time;
      return lastStartTime + lastDuration;
    }
    getEndTimeOfTimeline() {
      const endTimes = this._runners.map((i) => i.start + i.runner.duration());
      return Math.max(0, ...endTimes);
    }
    getLastRunnerInfo() {
      return this.getRunnerInfoById(this._lastRunnerId);
    }
    getRunnerInfoById(id) {
      return this._runners[this._runnerIds.indexOf(id)] || null;
    }
    pause() {
      this._paused = true;
      return this._continue();
    }
    persist(dtOrForever) {
      if (dtOrForever == null)
        return this._persist;
      this._persist = dtOrForever;
      return this;
    }
    play() {
      this._paused = false;
      return this.updateTime()._continue();
    }
    reverse(yes) {
      const currentSpeed = this.speed();
      if (yes == null)
        return this.speed(-currentSpeed);
      const positive = Math.abs(currentSpeed);
      return this.speed(yes ? -positive : positive);
    }
    // schedules a runner on the timeline
    schedule(runner, delay, when) {
      if (runner == null) {
        return this._runners.map(makeSchedule);
      }
      let absoluteStartTime = 0;
      const endTime = this.getEndTime();
      delay = delay || 0;
      if (when == null || when === "last" || when === "after") {
        absoluteStartTime = endTime;
      } else if (when === "absolute" || when === "start") {
        absoluteStartTime = delay;
        delay = 0;
      } else if (when === "now") {
        absoluteStartTime = this._time;
      } else if (when === "relative") {
        const runnerInfo2 = this.getRunnerInfoById(runner.id);
        if (runnerInfo2) {
          absoluteStartTime = runnerInfo2.start + delay;
          delay = 0;
        }
      } else if (when === "with-last") {
        const lastRunnerInfo = this.getLastRunnerInfo();
        const lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : this._time;
        absoluteStartTime = lastStartTime;
      } else {
        throw new Error('Invalid value for the "when" parameter');
      }
      runner.unschedule();
      runner.timeline(this);
      const persist = runner.persist();
      const runnerInfo = {
        persist: persist === null ? this._persist : persist,
        start: absoluteStartTime + delay,
        runner
      };
      this._lastRunnerId = runner.id;
      this._runners.push(runnerInfo);
      this._runners.sort((a, b) => a.start - b.start);
      this._runnerIds = this._runners.map((info) => info.runner.id);
      this.updateTime()._continue();
      return this;
    }
    seek(dt) {
      return this.time(this._time + dt);
    }
    source(fn) {
      if (fn == null)
        return this._timeSource;
      this._timeSource = fn;
      return this;
    }
    speed(speed) {
      if (speed == null)
        return this._speed;
      this._speed = speed;
      return this;
    }
    stop() {
      this.time(0);
      return this.pause();
    }
    time(time) {
      if (time == null)
        return this._time;
      this._time = time;
      return this._continue(true);
    }
    // Remove the runner from this timeline
    unschedule(runner) {
      const index = this._runnerIds.indexOf(runner.id);
      if (index < 0)
        return this;
      this._runners.splice(index, 1);
      this._runnerIds.splice(index, 1);
      runner.timeline(null);
      return this;
    }
    // Makes sure, that after pausing the time doesn't jump
    updateTime() {
      if (!this.active()) {
        this._lastSourceTime = this._timeSource();
      }
      return this;
    }
    // Checks if we are running and continues the animation
    _continue(immediateStep = false) {
      Animator.cancelFrame(this._nextFrame);
      this._nextFrame = null;
      if (immediateStep)
        return this._stepImmediate();
      if (this._paused)
        return this;
      this._nextFrame = Animator.frame(this._step);
      return this;
    }
    _stepFn(immediateStep = false) {
      const time = this._timeSource();
      let dtSource = time - this._lastSourceTime;
      if (immediateStep)
        dtSource = 0;
      const dtTime = this._speed * dtSource + (this._time - this._lastStepTime);
      this._lastSourceTime = time;
      if (!immediateStep) {
        this._time += dtTime;
        this._time = this._time < 0 ? 0 : this._time;
      }
      this._lastStepTime = this._time;
      this.fire("time", this._time);
      for (let k = this._runners.length; k--; ) {
        const runnerInfo = this._runners[k];
        const runner = runnerInfo.runner;
        const dtToStart = this._time - runnerInfo.start;
        if (dtToStart <= 0) {
          runner.reset();
        }
      }
      let runnersLeft = false;
      for (let i = 0, len = this._runners.length; i < len; i++) {
        const runnerInfo = this._runners[i];
        const runner = runnerInfo.runner;
        let dt = dtTime;
        const dtToStart = this._time - runnerInfo.start;
        if (dtToStart <= 0) {
          runnersLeft = true;
          continue;
        } else if (dtToStart < dt) {
          dt = dtToStart;
        }
        if (!runner.active())
          continue;
        const finished = runner.step(dt).done;
        if (!finished) {
          runnersLeft = true;
        } else if (runnerInfo.persist !== true) {
          const endTime = runner.duration() - runner.time() + this._time;
          if (endTime + runnerInfo.persist < this._time) {
            runner.unschedule();
            --i;
            --len;
          }
        }
      }
      if (runnersLeft && !(this._speed < 0 && this._time === 0) || this._runnerIds.length && this._speed < 0 && this._time > 0) {
        this._continue();
      } else {
        this.pause();
        this.fire("finished");
      }
      return this;
    }
  }
  registerMethods({
    Element: {
      timeline: function(timeline2) {
        if (timeline2 == null) {
          this._timeline = this._timeline || new Timeline();
          return this._timeline;
        } else {
          this._timeline = timeline2;
          return this;
        }
      }
    }
  });
  class Runner extends EventTarget {
    constructor(options) {
      super();
      this.id = Runner.id++;
      options = options == null ? timeline.duration : options;
      options = typeof options === "function" ? new Controller(options) : options;
      this._element = null;
      this._timeline = null;
      this.done = false;
      this._queue = [];
      this._duration = typeof options === "number" && options;
      this._isDeclarative = options instanceof Controller;
      this._stepper = this._isDeclarative ? options : new Ease();
      this._history = {};
      this.enabled = true;
      this._time = 0;
      this._lastTime = 0;
      this._reseted = true;
      this.transforms = new Matrix();
      this.transformId = 1;
      this._haveReversed = false;
      this._reverse = false;
      this._loopsDone = 0;
      this._swing = false;
      this._wait = 0;
      this._times = 1;
      this._frameId = null;
      this._persist = this._isDeclarative ? true : null;
    }
    static sanitise(duration, delay, when) {
      let times = 1;
      let swing = false;
      let wait = 0;
      duration = duration || timeline.duration;
      delay = delay || timeline.delay;
      when = when || "last";
      if (typeof duration === "object" && !(duration instanceof Stepper)) {
        delay = duration.delay || delay;
        when = duration.when || when;
        swing = duration.swing || swing;
        times = duration.times || times;
        wait = duration.wait || wait;
        duration = duration.duration || timeline.duration;
      }
      return {
        duration,
        delay,
        swing,
        times,
        wait,
        when
      };
    }
    active(enabled) {
      if (enabled == null)
        return this.enabled;
      this.enabled = enabled;
      return this;
    }
    /*
    Private Methods
    ===============
    Methods that shouldn't be used externally
    */
    addTransform(transform2, index) {
      this.transforms.lmultiplyO(transform2);
      return this;
    }
    after(fn) {
      return this.on("finished", fn);
    }
    animate(duration, delay, when) {
      const o = Runner.sanitise(duration, delay, when);
      const runner = new Runner(o.duration);
      if (this._timeline)
        runner.timeline(this._timeline);
      if (this._element)
        runner.element(this._element);
      return runner.loop(o).schedule(o.delay, o.when);
    }
    clearTransform() {
      this.transforms = new Matrix();
      return this;
    }
    // TODO: Keep track of all transformations so that deletion is faster
    clearTransformsFromQueue() {
      if (!this.done || !this._timeline || !this._timeline._runnerIds.includes(this.id)) {
        this._queue = this._queue.filter((item) => {
          return !item.isTransform;
        });
      }
    }
    delay(delay) {
      return this.animate(0, delay);
    }
    duration() {
      return this._times * (this._wait + this._duration) - this._wait;
    }
    during(fn) {
      return this.queue(null, fn);
    }
    ease(fn) {
      this._stepper = new Ease(fn);
      return this;
    }
    /*
    Runner Definitions
    ==================
    These methods help us define the runtime behaviour of the Runner or they
    help us make new runners from the current runner
    */
    element(element2) {
      if (element2 == null)
        return this._element;
      this._element = element2;
      element2._prepareRunner();
      return this;
    }
    finish() {
      return this.step(Infinity);
    }
    loop(times, swing, wait) {
      if (typeof times === "object") {
        swing = times.swing;
        wait = times.wait;
        times = times.times;
      }
      this._times = times || Infinity;
      this._swing = swing || false;
      this._wait = wait || 0;
      if (this._times === true) {
        this._times = Infinity;
      }
      return this;
    }
    loops(p) {
      const loopDuration = this._duration + this._wait;
      if (p == null) {
        const loopsDone = Math.floor(this._time / loopDuration);
        const relativeTime = this._time - loopsDone * loopDuration;
        const position2 = relativeTime / this._duration;
        return Math.min(loopsDone + position2, this._times);
      }
      const whole = Math.floor(p);
      const partial = p % 1;
      const time = loopDuration * whole + this._duration * partial;
      return this.time(time);
    }
    persist(dtOrForever) {
      if (dtOrForever == null)
        return this._persist;
      this._persist = dtOrForever;
      return this;
    }
    position(p) {
      const x2 = this._time;
      const d = this._duration;
      const w = this._wait;
      const t = this._times;
      const s = this._swing;
      const r = this._reverse;
      let position2;
      if (p == null) {
        const f = function(x3) {
          const swinging = s * Math.floor(x3 % (2 * (w + d)) / (w + d));
          const backwards = swinging && !r || !swinging && r;
          const uncliped = Math.pow(-1, backwards) * (x3 % (w + d)) / d + backwards;
          const clipped = Math.max(Math.min(uncliped, 1), 0);
          return clipped;
        };
        const endTime = t * (w + d) - w;
        position2 = x2 <= 0 ? Math.round(f(1e-5)) : x2 < endTime ? f(x2) : Math.round(f(endTime - 1e-5));
        return position2;
      }
      const loopsDone = Math.floor(this.loops());
      const swingForward = s && loopsDone % 2 === 0;
      const forwards = swingForward && !r || r && swingForward;
      position2 = loopsDone + (forwards ? p : 1 - p);
      return this.loops(position2);
    }
    progress(p) {
      if (p == null) {
        return Math.min(1, this._time / this.duration());
      }
      return this.time(p * this.duration());
    }
    /*
    Basic Functionality
    ===================
    These methods allow us to attach basic functions to the runner directly
    */
    queue(initFn, runFn, retargetFn, isTransform) {
      this._queue.push({
        initialiser: initFn || noop,
        runner: runFn || noop,
        retarget: retargetFn,
        isTransform,
        initialised: false,
        finished: false
      });
      const timeline2 = this.timeline();
      timeline2 && this.timeline()._continue();
      return this;
    }
    reset() {
      if (this._reseted)
        return this;
      this.time(0);
      this._reseted = true;
      return this;
    }
    reverse(reverse) {
      this._reverse = reverse == null ? !this._reverse : reverse;
      return this;
    }
    schedule(timeline2, delay, when) {
      if (!(timeline2 instanceof Timeline)) {
        when = delay;
        delay = timeline2;
        timeline2 = this.timeline();
      }
      if (!timeline2) {
        throw Error("Runner cannot be scheduled without timeline");
      }
      timeline2.schedule(this, delay, when);
      return this;
    }
    step(dt) {
      if (!this.enabled)
        return this;
      dt = dt == null ? 16 : dt;
      this._time += dt;
      const position2 = this.position();
      const running = this._lastPosition !== position2 && this._time >= 0;
      this._lastPosition = position2;
      const duration = this.duration();
      const justStarted = this._lastTime <= 0 && this._time > 0;
      const justFinished = this._lastTime < duration && this._time >= duration;
      this._lastTime = this._time;
      if (justStarted) {
        this.fire("start", this);
      }
      const declarative = this._isDeclarative;
      this.done = !declarative && !justFinished && this._time >= duration;
      this._reseted = false;
      let converged = false;
      if (running || declarative) {
        this._initialise(running);
        this.transforms = new Matrix();
        converged = this._run(declarative ? dt : position2);
        this.fire("step", this);
      }
      this.done = this.done || converged && declarative;
      if (justFinished) {
        this.fire("finished", this);
      }
      return this;
    }
    /*
    Runner animation methods
    ========================
    Control how the animation plays
    */
    time(time) {
      if (time == null) {
        return this._time;
      }
      const dt = time - this._time;
      this.step(dt);
      return this;
    }
    timeline(timeline2) {
      if (typeof timeline2 === "undefined")
        return this._timeline;
      this._timeline = timeline2;
      return this;
    }
    unschedule() {
      const timeline2 = this.timeline();
      timeline2 && timeline2.unschedule(this);
      return this;
    }
    // Run each initialise function in the runner if required
    _initialise(running) {
      if (!running && !this._isDeclarative)
        return;
      for (let i = 0, len = this._queue.length; i < len; ++i) {
        const current = this._queue[i];
        const needsIt = this._isDeclarative || !current.initialised && running;
        running = !current.finished;
        if (needsIt && running) {
          current.initialiser.call(this);
          current.initialised = true;
        }
      }
    }
    // Save a morpher to the morpher list so that we can retarget it later
    _rememberMorpher(method, morpher) {
      this._history[method] = {
        morpher,
        caller: this._queue[this._queue.length - 1]
      };
      if (this._isDeclarative) {
        const timeline2 = this.timeline();
        timeline2 && timeline2.play();
      }
    }
    // Try to set the target for a morpher if the morpher exists, otherwise
    // Run each run function for the position or dt given
    _run(positionOrDt) {
      let allfinished = true;
      for (let i = 0, len = this._queue.length; i < len; ++i) {
        const current = this._queue[i];
        const converged = current.runner.call(this, positionOrDt);
        current.finished = current.finished || converged === true;
        allfinished = allfinished && current.finished;
      }
      return allfinished;
    }
    // do nothing and return false
    _tryRetarget(method, target, extra) {
      if (this._history[method]) {
        if (!this._history[method].caller.initialised) {
          const index = this._queue.indexOf(this._history[method].caller);
          this._queue.splice(index, 1);
          return false;
        }
        if (this._history[method].caller.retarget) {
          this._history[method].caller.retarget.call(this, target, extra);
        } else {
          this._history[method].morpher.to(target);
        }
        this._history[method].caller.finished = false;
        const timeline2 = this.timeline();
        timeline2 && timeline2.play();
        return true;
      }
      return false;
    }
  }
  Runner.id = 0;
  class FakeRunner {
    constructor(transforms2 = new Matrix(), id = -1, done = true) {
      this.transforms = transforms2;
      this.id = id;
      this.done = done;
    }
    clearTransformsFromQueue() {
    }
  }
  extend([Runner, FakeRunner], {
    mergeWith(runner) {
      return new FakeRunner(runner.transforms.lmultiply(this.transforms), runner.id);
    }
  });
  const lmultiply = (last, curr) => last.lmultiplyO(curr);
  const getRunnerTransform = (runner) => runner.transforms;
  function mergeTransforms() {
    const runners = this._transformationRunners.runners;
    const netTransform = runners.map(getRunnerTransform).reduce(lmultiply, new Matrix());
    this.transform(netTransform);
    this._transformationRunners.merge();
    if (this._transformationRunners.length() === 1) {
      this._frameId = null;
    }
  }
  class RunnerArray {
    constructor() {
      this.runners = [];
      this.ids = [];
    }
    add(runner) {
      if (this.runners.includes(runner))
        return;
      const id = runner.id + 1;
      this.runners.push(runner);
      this.ids.push(id);
      return this;
    }
    clearBefore(id) {
      const deleteCnt = this.ids.indexOf(id + 1) || 1;
      this.ids.splice(0, deleteCnt, 0);
      this.runners.splice(0, deleteCnt, new FakeRunner()).forEach((r) => r.clearTransformsFromQueue());
      return this;
    }
    edit(id, newRunner) {
      const index = this.ids.indexOf(id + 1);
      this.ids.splice(index, 1, id + 1);
      this.runners.splice(index, 1, newRunner);
      return this;
    }
    getByID(id) {
      return this.runners[this.ids.indexOf(id + 1)];
    }
    length() {
      return this.ids.length;
    }
    merge() {
      let lastRunner = null;
      for (let i = 0; i < this.runners.length; ++i) {
        const runner = this.runners[i];
        const condition = lastRunner && runner.done && lastRunner.done && (!runner._timeline || !runner._timeline._runnerIds.includes(runner.id)) && (!lastRunner._timeline || !lastRunner._timeline._runnerIds.includes(lastRunner.id));
        if (condition) {
          this.remove(runner.id);
          const newRunner = runner.mergeWith(lastRunner);
          this.edit(lastRunner.id, newRunner);
          lastRunner = newRunner;
          --i;
        } else {
          lastRunner = runner;
        }
      }
      return this;
    }
    remove(id) {
      const index = this.ids.indexOf(id + 1);
      this.ids.splice(index, 1);
      this.runners.splice(index, 1);
      return this;
    }
  }
  registerMethods({
    Element: {
      animate(duration, delay, when) {
        const o = Runner.sanitise(duration, delay, when);
        const timeline2 = this.timeline();
        return new Runner(o.duration).loop(o).element(this).timeline(timeline2.play()).schedule(o.delay, o.when);
      },
      delay(by, when) {
        return this.animate(0, by, when);
      },
      // this function searches for all runners on the element and deletes the ones
      // which run before the current one. This is because absolute transformations
      // overwrite anything anyway so there is no need to waste time computing
      // other runners
      _clearTransformRunnersBefore(currentRunner) {
        this._transformationRunners.clearBefore(currentRunner.id);
      },
      _currentTransform(current) {
        return this._transformationRunners.runners.filter((runner) => runner.id <= current.id).map(getRunnerTransform).reduce(lmultiply, new Matrix());
      },
      _addRunner(runner) {
        this._transformationRunners.add(runner);
        Animator.cancelImmediate(this._frameId);
        this._frameId = Animator.immediate(mergeTransforms.bind(this));
      },
      _prepareRunner() {
        if (this._frameId == null) {
          this._transformationRunners = new RunnerArray().add(new FakeRunner(new Matrix(this)));
        }
      }
    }
  });
  const difference = (a, b) => a.filter((x2) => !b.includes(x2));
  extend(Runner, {
    attr(a, v) {
      return this.styleAttr("attr", a, v);
    },
    // Add animatable styles
    css(s, v) {
      return this.styleAttr("css", s, v);
    },
    styleAttr(type, nameOrAttrs, val) {
      if (typeof nameOrAttrs === "string") {
        return this.styleAttr(type, {
          [nameOrAttrs]: val
        });
      }
      let attrs2 = nameOrAttrs;
      if (this._tryRetarget(type, attrs2))
        return this;
      let morpher = new Morphable(this._stepper).to(attrs2);
      let keys = Object.keys(attrs2);
      this.queue(function() {
        morpher = morpher.from(this.element()[type](keys));
      }, function(pos) {
        this.element()[type](morpher.at(pos).valueOf());
        return morpher.done();
      }, function(newToAttrs) {
        const newKeys = Object.keys(newToAttrs);
        const differences = difference(newKeys, keys);
        if (differences.length) {
          const addedFromAttrs = this.element()[type](differences);
          const oldFromAttrs = new ObjectBag(morpher.from()).valueOf();
          Object.assign(oldFromAttrs, addedFromAttrs);
          morpher.from(oldFromAttrs);
        }
        const oldToAttrs = new ObjectBag(morpher.to()).valueOf();
        Object.assign(oldToAttrs, newToAttrs);
        morpher.to(oldToAttrs);
        keys = newKeys;
        attrs2 = newToAttrs;
      });
      this._rememberMorpher(type, morpher);
      return this;
    },
    zoom(level, point2) {
      if (this._tryRetarget("zoom", level, point2))
        return this;
      let morpher = new Morphable(this._stepper).to(new SVGNumber(level));
      this.queue(function() {
        morpher = morpher.from(this.element().zoom());
      }, function(pos) {
        this.element().zoom(morpher.at(pos), point2);
        return morpher.done();
      }, function(newLevel, newPoint) {
        point2 = newPoint;
        morpher.to(newLevel);
      });
      this._rememberMorpher("zoom", morpher);
      return this;
    },
    /**
     ** absolute transformations
     **/
    //
    // M v -----|-----(D M v = F v)------|----->  T v
    //
    // 1. define the final state (T) and decompose it (once)
    //    t = [tx, ty, the, lam, sy, sx]
    // 2. on every frame: pull the current state of all previous transforms
    //    (M - m can change)
    //   and then write this as m = [tx0, ty0, the0, lam0, sy0, sx0]
    // 3. Find the interpolated matrix F(pos) = m + pos * (t - m)
    //   - Note F(0) = M
    //   - Note F(1) = T
    // 4. Now you get the delta matrix as a result: D = F * inv(M)
    transform(transforms2, relative, affine) {
      relative = transforms2.relative || relative;
      if (this._isDeclarative && !relative && this._tryRetarget("transform", transforms2)) {
        return this;
      }
      const isMatrix = Matrix.isMatrixLike(transforms2);
      affine = transforms2.affine != null ? transforms2.affine : affine != null ? affine : !isMatrix;
      const morpher = new Morphable(this._stepper).type(affine ? TransformBag : Matrix);
      let origin;
      let element2;
      let current;
      let currentAngle;
      let startTransform;
      function setup() {
        element2 = element2 || this.element();
        origin = origin || getOrigin(transforms2, element2);
        startTransform = new Matrix(relative ? void 0 : element2);
        element2._addRunner(this);
        if (!relative) {
          element2._clearTransformRunnersBefore(this);
        }
      }
      function run(pos) {
        if (!relative)
          this.clearTransform();
        const {
          x: x2,
          y: y2
        } = new Point(origin).transform(element2._currentTransform(this));
        let target = new Matrix({
          ...transforms2,
          origin: [x2, y2]
        });
        let start = this._isDeclarative && current ? current : startTransform;
        if (affine) {
          target = target.decompose(x2, y2);
          start = start.decompose(x2, y2);
          const rTarget = target.rotate;
          const rCurrent = start.rotate;
          const possibilities = [rTarget - 360, rTarget, rTarget + 360];
          const distances = possibilities.map((a) => Math.abs(a - rCurrent));
          const shortest = Math.min(...distances);
          const index = distances.indexOf(shortest);
          target.rotate = possibilities[index];
        }
        if (relative) {
          if (!isMatrix) {
            target.rotate = transforms2.rotate || 0;
          }
          if (this._isDeclarative && currentAngle) {
            start.rotate = currentAngle;
          }
        }
        morpher.from(start);
        morpher.to(target);
        const affineParameters = morpher.at(pos);
        currentAngle = affineParameters.rotate;
        current = new Matrix(affineParameters);
        this.addTransform(current);
        element2._addRunner(this);
        return morpher.done();
      }
      function retarget(newTransforms) {
        if ((newTransforms.origin || "center").toString() !== (transforms2.origin || "center").toString()) {
          origin = getOrigin(newTransforms, element2);
        }
        transforms2 = {
          ...newTransforms,
          origin
        };
      }
      this.queue(setup, run, retarget, true);
      this._isDeclarative && this._rememberMorpher("transform", morpher);
      return this;
    },
    // Animatable x-axis
    x(x2, relative) {
      return this._queueNumber("x", x2);
    },
    // Animatable y-axis
    y(y2) {
      return this._queueNumber("y", y2);
    },
    dx(x2 = 0) {
      return this._queueNumberDelta("x", x2);
    },
    dy(y2 = 0) {
      return this._queueNumberDelta("y", y2);
    },
    dmove(x2, y2) {
      return this.dx(x2).dy(y2);
    },
    _queueNumberDelta(method, to2) {
      to2 = new SVGNumber(to2);
      if (this._tryRetarget(method, to2))
        return this;
      const morpher = new Morphable(this._stepper).to(to2);
      let from2 = null;
      this.queue(function() {
        from2 = this.element()[method]();
        morpher.from(from2);
        morpher.to(from2 + to2);
      }, function(pos) {
        this.element()[method](morpher.at(pos));
        return morpher.done();
      }, function(newTo) {
        morpher.to(from2 + new SVGNumber(newTo));
      });
      this._rememberMorpher(method, morpher);
      return this;
    },
    _queueObject(method, to2) {
      if (this._tryRetarget(method, to2))
        return this;
      const morpher = new Morphable(this._stepper).to(to2);
      this.queue(function() {
        morpher.from(this.element()[method]());
      }, function(pos) {
        this.element()[method](morpher.at(pos));
        return morpher.done();
      });
      this._rememberMorpher(method, morpher);
      return this;
    },
    _queueNumber(method, value) {
      return this._queueObject(method, new SVGNumber(value));
    },
    // Animatable center x-axis
    cx(x2) {
      return this._queueNumber("cx", x2);
    },
    // Animatable center y-axis
    cy(y2) {
      return this._queueNumber("cy", y2);
    },
    // Add animatable move
    move(x2, y2) {
      return this.x(x2).y(y2);
    },
    // Add animatable center
    center(x2, y2) {
      return this.cx(x2).cy(y2);
    },
    // Add animatable size
    size(width2, height2) {
      let box;
      if (!width2 || !height2) {
        box = this._element.bbox();
      }
      if (!width2) {
        width2 = box.width / box.height * height2;
      }
      if (!height2) {
        height2 = box.height / box.width * width2;
      }
      return this.width(width2).height(height2);
    },
    // Add animatable width
    width(width2) {
      return this._queueNumber("width", width2);
    },
    // Add animatable height
    height(height2) {
      return this._queueNumber("height", height2);
    },
    // Add animatable plot
    plot(a, b, c, d) {
      if (arguments.length === 4) {
        return this.plot([a, b, c, d]);
      }
      if (this._tryRetarget("plot", a))
        return this;
      const morpher = new Morphable(this._stepper).type(this._element.MorphArray).to(a);
      this.queue(function() {
        morpher.from(this._element.array());
      }, function(pos) {
        this._element.plot(morpher.at(pos));
        return morpher.done();
      });
      this._rememberMorpher("plot", morpher);
      return this;
    },
    // Add leading method
    leading(value) {
      return this._queueNumber("leading", value);
    },
    // Add animatable viewbox
    viewbox(x2, y2, width2, height2) {
      return this._queueObject("viewbox", new Box(x2, y2, width2, height2));
    },
    update(o) {
      if (typeof o !== "object") {
        return this.update({
          offset: arguments[0],
          color: arguments[1],
          opacity: arguments[2]
        });
      }
      if (o.opacity != null)
        this.attr("stop-opacity", o.opacity);
      if (o.color != null)
        this.attr("stop-color", o.color);
      if (o.offset != null)
        this.attr("offset", o.offset);
      return this;
    }
  });
  extend(Runner, {
    rx,
    ry,
    from,
    to
  });
  register(Runner, "Runner");
  class Svg extends Container {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("svg", node), attrs2);
      this.namespace();
    }
    // Creates and returns defs element
    defs() {
      if (!this.isRoot())
        return this.root().defs();
      return adopt(this.node.querySelector("defs")) || this.put(new Defs());
    }
    isRoot() {
      return !this.node.parentNode || !(this.node.parentNode instanceof globals.window.SVGElement) && this.node.parentNode.nodeName !== "#document-fragment";
    }
    // Add namespaces
    namespace() {
      if (!this.isRoot())
        return this.root().namespace();
      return this.attr({
        xmlns: svg,
        version: "1.1"
      }).attr("xmlns:xlink", xlink, xmlns).attr("xmlns:svgjs", svgjs, xmlns);
    }
    removeNamespace() {
      return this.attr({
        xmlns: null,
        version: null
      }).attr("xmlns:xlink", null, xmlns).attr("xmlns:svgjs", null, xmlns);
    }
    // Check if this is a root svg
    // If not, call root() from this element
    root() {
      if (this.isRoot())
        return this;
      return super.root();
    }
  }
  registerMethods({
    Container: {
      // Create nested svg document
      nested: wrapWithAttrCheck(function() {
        return this.put(new Svg());
      })
    }
  });
  register(Svg, "Svg", true);
  let Symbol$1 = class Symbol2 extends Container {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("symbol", node), attrs2);
    }
  };
  registerMethods({
    Container: {
      symbol: wrapWithAttrCheck(function() {
        return this.put(new Symbol$1());
      })
    }
  });
  register(Symbol$1, "Symbol");
  function plain(text) {
    if (this._build === false) {
      this.clear();
    }
    this.node.appendChild(globals.document.createTextNode(text));
    return this;
  }
  function length() {
    return this.node.getComputedTextLength();
  }
  function x$1(x2, box = this.bbox()) {
    if (x2 == null) {
      return box.x;
    }
    return this.attr("x", this.attr("x") + x2 - box.x);
  }
  function y$1(y2, box = this.bbox()) {
    if (y2 == null) {
      return box.y;
    }
    return this.attr("y", this.attr("y") + y2 - box.y);
  }
  function move$1(x2, y2, box = this.bbox()) {
    return this.x(x2, box).y(y2, box);
  }
  function cx(x2, box = this.bbox()) {
    if (x2 == null) {
      return box.cx;
    }
    return this.attr("x", this.attr("x") + x2 - box.cx);
  }
  function cy(y2, box = this.bbox()) {
    if (y2 == null) {
      return box.cy;
    }
    return this.attr("y", this.attr("y") + y2 - box.cy);
  }
  function center(x2, y2, box = this.bbox()) {
    return this.cx(x2, box).cy(y2, box);
  }
  function ax(x2) {
    return this.attr("x", x2);
  }
  function ay(y2) {
    return this.attr("y", y2);
  }
  function amove(x2, y2) {
    return this.ax(x2).ay(y2);
  }
  function build(build2) {
    this._build = !!build2;
    return this;
  }
  var textable = {
    __proto__: null,
    plain,
    length,
    x: x$1,
    y: y$1,
    move: move$1,
    cx,
    cy,
    center,
    ax,
    ay,
    amove,
    build
  };
  class Text extends Shape {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("text", node), attrs2);
      this.dom.leading = new SVGNumber(1.3);
      this._rebuild = true;
      this._build = false;
    }
    // Set / get leading
    leading(value) {
      if (value == null) {
        return this.dom.leading;
      }
      this.dom.leading = new SVGNumber(value);
      return this.rebuild();
    }
    // Rebuild appearance type
    rebuild(rebuild) {
      if (typeof rebuild === "boolean") {
        this._rebuild = rebuild;
      }
      if (this._rebuild) {
        const self2 = this;
        let blankLineOffset = 0;
        const leading = this.dom.leading;
        this.each(function(i) {
          const fontSize = globals.window.getComputedStyle(this.node).getPropertyValue("font-size");
          const dy2 = leading * new SVGNumber(fontSize);
          if (this.dom.newLined) {
            this.attr("x", self2.attr("x"));
            if (this.text() === "\n") {
              blankLineOffset += dy2;
            } else {
              this.attr("dy", i ? dy2 + blankLineOffset : 0);
              blankLineOffset = 0;
            }
          }
        });
        this.fire("rebuild");
      }
      return this;
    }
    // overwrite method from parent to set data properly
    setData(o) {
      this.dom = o;
      this.dom.leading = new SVGNumber(o.leading || 1.3);
      return this;
    }
    // Set the text content
    text(text) {
      if (text === void 0) {
        const children = this.node.childNodes;
        let firstLine = 0;
        text = "";
        for (let i = 0, len = children.length; i < len; ++i) {
          if (children[i].nodeName === "textPath") {
            if (i === 0)
              firstLine = 1;
            continue;
          }
          if (i !== firstLine && children[i].nodeType !== 3 && adopt(children[i]).dom.newLined === true) {
            text += "\n";
          }
          text += children[i].textContent;
        }
        return text;
      }
      this.clear().build(true);
      if (typeof text === "function") {
        text.call(this, this);
      } else {
        text = (text + "").split("\n");
        for (let j = 0, jl = text.length; j < jl; j++) {
          this.newLine(text[j]);
        }
      }
      return this.build(false).rebuild();
    }
  }
  extend(Text, textable);
  registerMethods({
    Container: {
      // Create text element
      text: wrapWithAttrCheck(function(text = "") {
        return this.put(new Text()).text(text);
      }),
      // Create plain text element
      plain: wrapWithAttrCheck(function(text = "") {
        return this.put(new Text()).plain(text);
      })
    }
  });
  register(Text, "Text");
  class Tspan extends Shape {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("tspan", node), attrs2);
      this._build = false;
    }
    // Shortcut dx
    dx(dx2) {
      return this.attr("dx", dx2);
    }
    // Shortcut dy
    dy(dy2) {
      return this.attr("dy", dy2);
    }
    // Create new line
    newLine() {
      this.dom.newLined = true;
      const text = this.parent();
      if (!(text instanceof Text)) {
        return this;
      }
      const i = text.index(this);
      const fontSize = globals.window.getComputedStyle(this.node).getPropertyValue("font-size");
      const dy2 = text.dom.leading * new SVGNumber(fontSize);
      return this.dy(i ? dy2 : 0).attr("x", text.x());
    }
    // Set text content
    text(text) {
      if (text == null)
        return this.node.textContent + (this.dom.newLined ? "\n" : "");
      if (typeof text === "function") {
        this.clear().build(true);
        text.call(this, this);
        this.build(false);
      } else {
        this.plain(text);
      }
      return this;
    }
  }
  extend(Tspan, textable);
  registerMethods({
    Tspan: {
      tspan: wrapWithAttrCheck(function(text = "") {
        const tspan = new Tspan();
        if (!this._build) {
          this.clear();
        }
        return this.put(tspan).text(text);
      })
    },
    Text: {
      newLine: function(text = "") {
        return this.tspan(text).newLine();
      }
    }
  });
  register(Tspan, "Tspan");
  class Circle extends Shape {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("circle", node), attrs2);
    }
    radius(r) {
      return this.attr("r", r);
    }
    // Radius x value
    rx(rx2) {
      return this.attr("r", rx2);
    }
    // Alias radius x value
    ry(ry2) {
      return this.rx(ry2);
    }
    size(size2) {
      return this.radius(new SVGNumber(size2).divide(2));
    }
  }
  extend(Circle, {
    x: x$3,
    y: y$3,
    cx: cx$1,
    cy: cy$1,
    width: width$2,
    height: height$2
  });
  registerMethods({
    Container: {
      // Create circle element
      circle: wrapWithAttrCheck(function(size2 = 0) {
        return this.put(new Circle()).size(size2).move(0, 0);
      })
    }
  });
  register(Circle, "Circle");
  class ClipPath extends Container {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("clipPath", node), attrs2);
    }
    // Unclip all clipped elements and remove itself
    remove() {
      this.targets().forEach(function(el) {
        el.unclip();
      });
      return super.remove();
    }
    targets() {
      return baseFind("svg [clip-path*=" + this.id() + "]");
    }
  }
  registerMethods({
    Container: {
      // Create clipping element
      clip: wrapWithAttrCheck(function() {
        return this.defs().put(new ClipPath());
      })
    },
    Element: {
      // Distribute clipPath to svg element
      clipper() {
        return this.reference("clip-path");
      },
      clipWith(element2) {
        const clipper = element2 instanceof ClipPath ? element2 : this.parent().clip().add(element2);
        return this.attr("clip-path", "url(#" + clipper.id() + ")");
      },
      // Unclip element
      unclip() {
        return this.attr("clip-path", null);
      }
    }
  });
  register(ClipPath, "ClipPath");
  class ForeignObject extends Element {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("foreignObject", node), attrs2);
    }
  }
  registerMethods({
    Container: {
      foreignObject: wrapWithAttrCheck(function(width2, height2) {
        return this.put(new ForeignObject()).size(width2, height2);
      })
    }
  });
  register(ForeignObject, "ForeignObject");
  function dmove(dx2, dy2) {
    this.children().forEach((child, i) => {
      let bbox2;
      try {
        bbox2 = child.bbox();
      } catch (e) {
        return;
      }
      const m = new Matrix(child);
      const matrix = m.translate(dx2, dy2).transform(m.inverse());
      const p = new Point(bbox2.x, bbox2.y).transform(matrix);
      child.move(p.x, p.y);
    });
    return this;
  }
  function dx(dx2) {
    return this.dmove(dx2, 0);
  }
  function dy(dy2) {
    return this.dmove(0, dy2);
  }
  function height(height2, box = this.bbox()) {
    if (height2 == null)
      return box.height;
    return this.size(box.width, height2, box);
  }
  function move(x2 = 0, y2 = 0, box = this.bbox()) {
    const dx2 = x2 - box.x;
    const dy2 = y2 - box.y;
    return this.dmove(dx2, dy2);
  }
  function size(width2, height2, box = this.bbox()) {
    const p = proportionalSize(this, width2, height2, box);
    const scaleX = p.width / box.width;
    const scaleY = p.height / box.height;
    this.children().forEach((child, i) => {
      const o = new Point(box).transform(new Matrix(child).inverse());
      child.scale(scaleX, scaleY, o.x, o.y);
    });
    return this;
  }
  function width(width2, box = this.bbox()) {
    if (width2 == null)
      return box.width;
    return this.size(width2, box.height, box);
  }
  function x(x2, box = this.bbox()) {
    if (x2 == null)
      return box.x;
    return this.move(x2, box.y, box);
  }
  function y(y2, box = this.bbox()) {
    if (y2 == null)
      return box.y;
    return this.move(box.x, y2, box);
  }
  var containerGeometry = {
    __proto__: null,
    dmove,
    dx,
    dy,
    height,
    move,
    size,
    width,
    x,
    y
  };
  class G extends Container {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("g", node), attrs2);
    }
  }
  extend(G, containerGeometry);
  registerMethods({
    Container: {
      // Create a group element
      group: wrapWithAttrCheck(function() {
        return this.put(new G());
      })
    }
  });
  register(G, "G");
  class A extends Container {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("a", node), attrs2);
    }
    // Link target attribute
    target(target) {
      return this.attr("target", target);
    }
    // Link url
    to(url) {
      return this.attr("href", url, xlink);
    }
  }
  extend(A, containerGeometry);
  registerMethods({
    Container: {
      // Create a hyperlink element
      link: wrapWithAttrCheck(function(url) {
        return this.put(new A()).to(url);
      })
    },
    Element: {
      unlink() {
        const link = this.linker();
        if (!link)
          return this;
        const parent = link.parent();
        if (!parent) {
          return this.remove();
        }
        const index = parent.index(link);
        parent.add(this, index);
        link.remove();
        return this;
      },
      linkTo(url) {
        let link = this.linker();
        if (!link) {
          link = new A();
          this.wrap(link);
        }
        if (typeof url === "function") {
          url.call(link, link);
        } else {
          link.to(url);
        }
        return this;
      },
      linker() {
        const link = this.parent();
        if (link && link.node.nodeName.toLowerCase() === "a") {
          return link;
        }
        return null;
      }
    }
  });
  register(A, "A");
  class Mask extends Container {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("mask", node), attrs2);
    }
    // Unmask all masked elements and remove itself
    remove() {
      this.targets().forEach(function(el) {
        el.unmask();
      });
      return super.remove();
    }
    targets() {
      return baseFind("svg [mask*=" + this.id() + "]");
    }
  }
  registerMethods({
    Container: {
      mask: wrapWithAttrCheck(function() {
        return this.defs().put(new Mask());
      })
    },
    Element: {
      // Distribute mask to svg element
      masker() {
        return this.reference("mask");
      },
      maskWith(element2) {
        const masker = element2 instanceof Mask ? element2 : this.parent().mask().add(element2);
        return this.attr("mask", "url(#" + masker.id() + ")");
      },
      // Unmask element
      unmask() {
        return this.attr("mask", null);
      }
    }
  });
  register(Mask, "Mask");
  class Stop extends Element {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("stop", node), attrs2);
    }
    // add color stops
    update(o) {
      if (typeof o === "number" || o instanceof SVGNumber) {
        o = {
          offset: arguments[0],
          color: arguments[1],
          opacity: arguments[2]
        };
      }
      if (o.opacity != null)
        this.attr("stop-opacity", o.opacity);
      if (o.color != null)
        this.attr("stop-color", o.color);
      if (o.offset != null)
        this.attr("offset", new SVGNumber(o.offset));
      return this;
    }
  }
  registerMethods({
    Gradient: {
      // Add a color stop
      stop: function(offset, color, opacity) {
        return this.put(new Stop()).update(offset, color, opacity);
      }
    }
  });
  register(Stop, "Stop");
  function cssRule(selector, rule) {
    if (!selector)
      return "";
    if (!rule)
      return selector;
    let ret = selector + "{";
    for (const i in rule) {
      ret += unCamelCase(i) + ":" + rule[i] + ";";
    }
    ret += "}";
    return ret;
  }
  class Style extends Element {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("style", node), attrs2);
    }
    addText(w = "") {
      this.node.textContent += w;
      return this;
    }
    font(name, src, params = {}) {
      return this.rule("@font-face", {
        fontFamily: name,
        src,
        ...params
      });
    }
    rule(selector, obj) {
      return this.addText(cssRule(selector, obj));
    }
  }
  registerMethods("Dom", {
    style(selector, obj) {
      return this.put(new Style()).rule(selector, obj);
    },
    fontface(name, src, params) {
      return this.put(new Style()).font(name, src, params);
    }
  });
  register(Style, "Style");
  class TextPath extends Text {
    // Initialize node
    constructor(node, attrs2 = node) {
      super(nodeOrNew("textPath", node), attrs2);
    }
    // return the array of the path track element
    array() {
      const track = this.track();
      return track ? track.array() : null;
    }
    // Plot path if any
    plot(d) {
      const track = this.track();
      let pathArray = null;
      if (track) {
        pathArray = track.plot(d);
      }
      return d == null ? pathArray : this;
    }
    // Get the path element
    track() {
      return this.reference("href");
    }
  }
  registerMethods({
    Container: {
      textPath: wrapWithAttrCheck(function(text, path) {
        if (!(text instanceof Text)) {
          text = this.text(text);
        }
        return text.path(path);
      })
    },
    Text: {
      // Create path for text to run on
      path: wrapWithAttrCheck(function(track, importNodes = true) {
        const textPath = new TextPath();
        if (!(track instanceof Path)) {
          track = this.defs().path(track);
        }
        textPath.attr("href", "#" + track, xlink);
        let node;
        if (importNodes) {
          while (node = this.node.firstChild) {
            textPath.node.appendChild(node);
          }
        }
        return this.put(textPath);
      }),
      // Get the textPath children
      textPath() {
        return this.findOne("textPath");
      }
    },
    Path: {
      // creates a textPath from this path
      text: wrapWithAttrCheck(function(text) {
        if (!(text instanceof Text)) {
          text = new Text().addTo(this.parent()).text(text);
        }
        return text.path(this);
      }),
      targets() {
        return baseFind("svg textPath").filter((node) => {
          return (node.attr("href") || "").includes(this.id());
        });
      }
    }
  });
  TextPath.prototype.MorphArray = PathArray;
  register(TextPath, "TextPath");
  class Use extends Shape {
    constructor(node, attrs2 = node) {
      super(nodeOrNew("use", node), attrs2);
    }
    // Use element as a reference
    use(element2, file) {
      return this.attr("href", (file || "") + "#" + element2, xlink);
    }
  }
  registerMethods({
    Container: {
      // Create a use element
      use: wrapWithAttrCheck(function(element2, file) {
        return this.put(new Use()).use(element2, file);
      })
    }
  });
  register(Use, "Use");
  const SVG = makeInstance;
  extend([Svg, Symbol$1, Image, Pattern, Marker], getMethodsFor("viewbox"));
  extend([Line, Polyline, Polygon, Path], getMethodsFor("marker"));
  extend(Text, getMethodsFor("Text"));
  extend(Path, getMethodsFor("Path"));
  extend(Defs, getMethodsFor("Defs"));
  extend([Text, Tspan], getMethodsFor("Tspan"));
  extend([Rect, Ellipse, Gradient, Runner], getMethodsFor("radius"));
  extend(EventTarget, getMethodsFor("EventTarget"));
  extend(Dom, getMethodsFor("Dom"));
  extend(Element, getMethodsFor("Element"));
  extend(Shape, getMethodsFor("Shape"));
  extend([Container, Fragment], getMethodsFor("Container"));
  extend(Gradient, getMethodsFor("Gradient"));
  extend(Runner, getMethodsFor("Runner"));
  List.extend(getMethodNames());
  registerMorphableType([SVGNumber, Color, Box, Matrix, SVGArray, PointArray, PathArray, Point]);
  makeMorphable();
  class ChordBox {
    // sel can be a selector or an element.
    constructor(sel, params) {
      this.sel = sel;
      this.params = {
        ...{
          numStrings: 6,
          numFrets: 5,
          x: 0,
          y: 0,
          width: 100,
          height: 120,
          strokeWidth: 1,
          showTuning: true,
          defaultColor: "#666",
          bgColor: "#fff",
          labelColor: "#fff",
          fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
          fontSize: void 0,
          fontStyle: "light",
          fontWeight: "100",
          labelWeight: "100"
        },
        ...params
      };
      ["bridgeColor", "stringColor", "fretColor", "strokeColor", "textColor"].forEach((param) => {
        this.params[param] = this.params[param] || this.params.defaultColor;
      });
      ["stringWidth", "fretWidth"].forEach((param) => {
        this.params[param] = this.params[param] || this.params.strokeWidth;
      });
      this.canvas = SVG().addTo(sel).size(this.params.width, this.params.height);
      this.width = this.params.width * 0.75;
      this.height = this.params.height * 0.75;
      this.x = this.params.x + this.params.width * 0.15;
      this.y = this.params.y + this.params.height * 0.15;
      this.numStrings = this.params.numStrings;
      this.numFrets = this.params.numFrets;
      this.spacing = this.width / this.numStrings;
      this.fretSpacing = this.height / (this.numFrets + 2);
      this.x += this.spacing / 2;
      this.y += this.fretSpacing;
      this.metrics = {
        circleRadius: this.width / 20,
        barreRadius: this.width / 25,
        fontSize: this.params.fontSize || Math.ceil(this.width / 8),
        barShiftX: this.width / 28,
        bridgeStrokeWidth: Math.ceil(this.height / 36)
      };
      this.position = 0;
      this.positionText = 0;
      this.chord = [];
      this.bars = [];
      this.tuning = ["E", "A", "D", "G", "B", "E"];
    }
    setNumFrets(numFrets) {
      this.numFrets = numFrets;
      this.fretSpacing = this.height / (this.numFrets + 1);
      return this;
    }
    setPositionText(position2) {
      this.positionText = position2;
      return this;
    }
    drawText(x2, y2, msg, attrs2) {
      const textAttrs = {
        ...{
          family: this.params.fontFamily,
          size: this.metrics.fontSize,
          style: this.params.fontStyle,
          weight: this.params.fontWeight
        },
        ...attrs2
      };
      const text = this.canvas.text(`${msg}`).stroke(this.params.textColor).fill(this.params.textColor).font(textAttrs);
      return text.move(x2 - text.length() / 2, y2);
    }
    drawLine(x2, y2, newX, newY) {
      return this.canvas.line(0, 0, newX - x2, newY - y2).move(x2, y2);
    }
    draw({
      chord,
      position: position2,
      barres,
      positionText,
      tuning
    }) {
      this.chord = chord;
      this.position = position2 || 0;
      this.positionText = positionText || 0;
      this.barres = barres || [];
      this.tuning = tuning || ["E", "A", "D", "G", "B", "E"];
      if (this.tuning.length === 0) {
        this.fretSpacing = this.height / (this.numFrets + 1);
      }
      const { spacing } = this;
      const { fretSpacing } = this;
      if (this.position <= 1) {
        const fromX = this.x;
        const fromY = this.y - this.metrics.bridgeStrokeWidth;
        this.canvas.rect(this.x + spacing * (this.numStrings - 1) - fromX, this.y - fromY).move(fromX, fromY).stroke({ width: 0 }).fill(this.params.bridgeColor);
      } else {
        this.drawText(this.x - this.spacing / 2 - this.spacing * 0.1, this.y + this.fretSpacing * this.positionText, this.position);
      }
      for (let i = 0; i < this.numStrings; i += 1) {
        this.drawLine(this.x + spacing * i, this.y, this.x + spacing * i, this.y + fretSpacing * this.numFrets).stroke({
          width: this.params.stringWidth,
          color: this.params.stringColor
        });
      }
      for (let i = 0; i < this.numFrets + 1; i += 1) {
        this.drawLine(this.x, this.y + fretSpacing * i, this.x + spacing * (this.numStrings - 1), this.y + fretSpacing * i).stroke({
          width: this.params.fretWidth,
          color: this.params.fretColor
        });
      }
      if (this.params.showTuning && this.tuning.length !== 0) {
        for (let i = 0; i < Math.min(this.numStrings, this.tuning.length); i += 1) {
          this.drawText(this.x + this.spacing * i, this.y + this.numFrets * this.fretSpacing + this.fretSpacing / 12, this.tuning[i]);
        }
      }
      for (let i = 0; i < this.chord.length; i += 1) {
        this.lightUp({
          string: this.chord[i][0],
          fret: this.chord[i][1],
          label: this.chord.length > 2 ? this.chord[i][2] : void 0
        });
      }
      for (let i = 0; i < this.barres.length; i += 1) {
        this.lightBar(this.barres[i].fromString, this.barres[i].toString, this.barres[i].fret);
      }
    }
    lightUp({ string: string2, fret, label }) {
      const stringNum = this.numStrings - string2;
      const shiftPosition = this.position === 1 && this.positionText === 1 ? this.positionText : 0;
      const mute = fret === "x";
      const fretNum = fret === "x" ? 0 : fret - shiftPosition;
      const x2 = this.x + this.spacing * stringNum;
      let y2 = this.y + this.fretSpacing * fretNum;
      if (fretNum === 0) {
        y2 -= this.metrics.bridgeStrokeWidth;
      }
      if (!mute) {
        this.canvas.circle().move(x2, y2 - this.fretSpacing / 2).radius(this.metrics.circleRadius).stroke({ color: this.params.strokeColor, width: this.params.strokeWidth }).fill(fretNum > 0 ? this.params.strokeColor : this.params.bgColor);
      } else {
        this.drawText(x2, y2 - this.fretSpacing, "X");
      }
      if (label) {
        const fontSize = this.metrics.fontSize * 0.55;
        const textYShift = fontSize * 0.66;
        this.drawText(x2, y2 - this.fretSpacing / 2 - textYShift, label, {
          weight: this.params.labelWeight,
          size: fontSize
        }).stroke({
          width: 0.7,
          color: fretNum !== 0 ? this.params.labelColor : this.params.strokeColor
        }).fill(fretNum !== 0 ? this.params.labelColor : this.params.strokeColor);
      }
      return this;
    }
    lightBar(stringFrom, stringTo, theFretNum) {
      let fretNum = theFretNum;
      if (this.position === 1 && this.positionText === 1) {
        fretNum -= this.positionText;
      }
      const stringFromNum = this.numStrings - stringFrom;
      const stringToNum = this.numStrings - stringTo;
      const x2 = this.x + this.spacing * stringFromNum - this.metrics.barShiftX;
      const xTo = this.x + this.spacing * stringToNum + this.metrics.barShiftX;
      const y2 = this.y + this.fretSpacing * (fretNum - 1) + this.fretSpacing / 4;
      const yTo = this.y + this.fretSpacing * (fretNum - 1) + this.fretSpacing / 4 * 3;
      this.canvas.rect(xTo - x2, yTo - y2).move(x2, y2).radius(this.metrics.barreRadius).fill(this.params.strokeColor);
      return this;
    }
  }
  const _hoisted_1$a = {
    key: 0,
    class: "chord-container"
  };
  const _hoisted_2$9 = { class: "chord-name" };
  const _hoisted_3$4 = ["chord-name"];
  const _sfc_main$b = {
    __name: "ChordChart",
    props: {
      chord: String
    },
    setup(__props) {
      const props = __props;
      const chordRef = vue.ref(void 0);
      const chordShapes = getChordShapes();
      const isChordExist = vue.ref(true);
      vue.onMounted(() => {
        var _a;
        const formattedChordKey = convertChordName(props.chord);
        const chordShape = chordShapes[formattedChordKey];
        if (!chordShape) {
          return isChordExist.value = false;
        }
        const chordObject = {
          ...chordShape,
          // position: chordShape.position,
          // positionText: chordShape.position_text,
          barres: (_a = chordShape.bars) == null ? void 0 : _a.map((barre) => {
            return {
              ...barre,
              fromString: barre.from_string,
              toString: barre.to_string
            };
          }),
          chord: chordShape.chord.map(([stringNum, fretNum]) => {
            const raw = [stringNum, fretNum];
            if (isNaN(+fretNum)) {
              return raw;
            }
            let newFretNum = fretNum;
            newFretNum += chordShape.position || 0;
            newFretNum -= chordShape.position_text || 0;
            return [stringNum, newFretNum];
          })
        };
        vue.nextTick(() => {
          const width2 = chordRef.value.clientWidth;
          const chordBoxSelector = `.chord-chart[chord-name="${props.chord}"]`;
          const chordBox = new ChordBox(chordBoxSelector, {
            width: width2,
            height: width2 * 1.25,
            circleRadius: 5,
            numStrings: 6,
            numFrets: 5,
            showTuning: false,
            defaultColor: "#444",
            bgColor: "transparent"
          });
          chordBox.draw(chordObject);
        });
      });
      return (_ctx, _cache) => {
        return isChordExist.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
          vue.createElementVNode("div", _hoisted_2$9, vue.toDisplayString(props.chord), 1),
          vue.createElementVNode("div", {
            class: "chord-chart",
            "chord-name": props.chord,
            ref_key: "chordRef",
            ref: chordRef
          }, null, 8, _hoisted_3$4)
        ])) : vue.createCommentVNode("", true);
      };
    }
  };
  const ChordChart = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-1eb5094e"]]);
  const _withScopeId$1 = (n) => (vue.pushScopeId("data-v-84de48ae"), n = n(), vue.popScopeId(), n);
  const _hoisted_1$9 = { id: "plus91-chord-popup" };
  const _hoisted_2$8 = { class: "banner" };
  const _hoisted_3$3 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ vue.createElementVNode("section", null, "此處的和弦圖示僅供參考,尤其把位部分較常出現錯誤,請注意。", -1));
  const _hoisted_4$2 = { class: "chord-popup-container" };
  const _sfc_main$a = {
    __name: "ChordPopup",
    setup(__props) {
      const store = useStore();
      const chordList = vue.ref([]);
      vue.watch(store.isPopupShow, () => {
        if (!store.isPopupShow.chord) {
          return;
        }
        chordList.value = getChordList();
      });
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide-and-fade" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$9, [
              vue.createElementVNode("div", _hoisted_2$8, [
                vue.createVNode(BootstrapIcon, {
                  icon: "info-circle-fill",
                  color: "inherit",
                  size: "inherit"
                }),
                _hoisted_3$3
              ]),
              vue.createElementVNode("div", _hoisted_4$2, [
                (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(chordList.value, (chord) => {
                  return vue.openBlock(), vue.createBlock(ChordChart, {
                    key: `${chord}_${( new Date()).getTime()}`,
                    chord
                  }, null, 8, ["chord"]);
                }), 128))
              ])
            ], 512), [
              [vue.vShow, vue.unref(store).isPopupShow.chord]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const ChordPopup = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-84de48ae"]]);
  const _hoisted_1$8 = { id: "plus91-font-popup" };
  const _hoisted_2$7 = { class: "font-popup-container" };
  const _sfc_main$9 = {
    __name: "FontSizePopup",
    setup(__props) {
      const store = useStore();
      const getFontSize = vue.computed(() => {
        return store.originalFontSize + store.fontSizeDelta;
      });
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide-and-fade" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$8, [
              vue.createElementVNode("div", _hoisted_2$7, [
                vue.createVNode(AdjustWidget, {
                  "onclick-left": () => {
                    vue.unref(store).fontSizeDelta--;
                  },
                  "onclick-middle": () => {
                    vue.unref(store).fontSizeDelta = 0;
                  },
                  "onclick-right": () => {
                    vue.unref(store).fontSizeDelta++;
                  },
                  "disabled-left": getFontSize.value <= 8,
                  "disabled-right": getFontSize.value >= 30
                }, {
                  default: vue.withCtx(() => [
                    vue.createTextVNode(vue.toDisplayString(getFontSize.value) + "px ", 1)
                  ]),
                  _: 1
                }, 8, ["onclick-left", "onclick-middle", "onclick-right", "disabled-left", "disabled-right"])
              ])
            ], 512), [
              [vue.vShow, vue.unref(store).isPopupShow.font]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const FontSizePopup = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-eff17405"]]);
  const _withScopeId = (n) => (vue.pushScopeId("data-v-e329f5af"), n = n(), vue.popScopeId(), n);
  const _hoisted_1$7 = { id: "plus91-settings-popup" };
  const _hoisted_2$6 = { class: "settings-popup-container" };
  const _hoisted_3$2 = { class: "setting-item" };
  const _hoisted_4$1 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("span", null, "深色模式", -1));
  const _hoisted_5 = { class: "setting-item" };
  const _hoisted_6 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("span", null, "協助測試雲端備份樂譜功能", -1));
  const _sfc_main$8 = {
    __name: "SettingsPopup",
    setup(__props) {
      const store = useStore();
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide-and-fade" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$7, [
              vue.createElementVNode("div", _hoisted_2$6, [
                vue.createElementVNode("label", _hoisted_3$2, [
                  _hoisted_4$1,
                  vue.withDirectives(vue.createElementVNode("input", {
                    type: "checkbox",
                    "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(store).isDarkMode = $event)
                  }, null, 512), [
                    [vue.vModelCheckbox, vue.unref(store).isDarkMode]
                  ])
                ]),
                vue.createElementVNode("label", _hoisted_5, [
                  _hoisted_6,
                  vue.withDirectives(vue.createElementVNode("input", {
                    type: "checkbox",
                    "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(store).agreeToArchiveSheet = $event)
                  }, null, 512), [
                    [vue.vModelCheckbox, vue.unref(store).agreeToArchiveSheet]
                  ])
                ])
              ])
            ], 512), [
              [vue.vShow, vue.unref(store).isPopupShow.settings]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const SettingsPopup = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-e329f5af"]]);
  const _hoisted_1$6 = { class: "icon-button" };
  const _hoisted_2$5 = { class: "button-text" };
  const _sfc_main$7 = {
    __name: "MenuButton",
    props: {
      icon: String,
      name: String,
      color: String
    },
    setup(__props) {
      vue.useCssVars((_ctx) => ({
        "9047bc34": __props.color
      }));
      const props = __props;
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
          vue.createVNode(ToolbarIcon, {
            icon: props.icon,
            color: props.color
          }, null, 8, ["icon", "color"]),
          vue.createElementVNode("div", _hoisted_2$5, vue.toDisplayString(props.name), 1)
        ]);
      };
    }
  };
  const MenuButton = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-e9902592"]]);
  const _hoisted_1$5 = { id: "plus91-menu-popup" };
  const _hoisted_2$4 = { class: "menu-popup-container" };
  const _sfc_main$6 = {
    __name: "MenuPopup",
    setup(__props) {
      const store = useStore();
      const searchOnYoutube = () => {
        const chordSheetDocument = new ChordSheetDocument();
        const title = chordSheetDocument.getTitle();
        const artist = chordSheetDocument.getSinger();
        const url = `https://www.youtube.com/results?search_query=${title}+${artist}`;
        window.open(url, "_blank").focus();
      };
      const goToGithubPage = () => {
        const url = "https://github.com/DonkeyBear/91Plus/blob/main/README.md";
        window.open(url, "_blank").focus();
      };
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide-and-fade" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$5, [
              vue.createElementVNode("div", _hoisted_2$4, [
                vue.createVNode(MenuButton, {
                  icon: "keyboard",
                  name: "快捷鍵",
                  color: "#555",
                  onClick: _cache[0] || (_cache[0] = () => {
                    vue.unref(store).togglePopup("hotkey");
                  })
                }),
                vue.createVNode(MenuButton, {
                  icon: "youtube",
                  name: "搜尋 YouTube",
                  color: "#555",
                  onClick: searchOnYoutube
                }),
                vue.createVNode(MenuButton, {
                  icon: "github",
                  name: "關於 91 Plus",
                  color: "#555",
                  onClick: goToGithubPage
                })
              ])
            ], 512), [
              [vue.vShow, vue.unref(store).isPopupShow.menu]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const MenuPopup = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-d041b049"]]);
  const _hoisted_1$4 = { class: "hotkey-item" };
  const _hoisted_2$3 = {
    key: 0,
    class: "hotkeys"
  };
  const _hoisted_3$1 = {
    key: 1,
    class: "hr"
  };
  const _sfc_main$5 = {
    __name: "HotkeyItem",
    props: {
      hotkey: {
        type: String,
        required: false
      },
      desc: String
    },
    setup(__props) {
      const props = __props;
      const hotkeyList = props.hotkey.split(" ");
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, [
          vue.createElementVNode("div", {
            class: vue.normalizeClass(["desc", { "title": !__props.hotkey }])
          }, vue.toDisplayString(__props.desc), 3),
          __props.hotkey ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$3, [
            (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(hotkeyList), (key) => {
              return vue.openBlock(), vue.createElementBlock("kbd", null, vue.toDisplayString(key), 1);
            }), 256))
          ])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$1))
        ]);
      };
    }
  };
  const HotkeyItem = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-9f1c2e95"]]);
  const hotkeysLeft = [
    {
      hotkey: "空白鍵",
      desc: "開啟 / 關閉功能選單"
    },
    {
      hotkey: "ESC",
      desc: "關閉功能選單"
    },
    {
      hotkey: "/",
      desc: "切換至搜尋框"
    }
  ];
  const hotkeysRight = [
    {
      hotkey: "",
      desc: "移調選單開啟時"
    },
    {
      hotkey: "← →",
      desc: "移調"
    },
    {
      hotkey: "↓",
      desc: "移回初始調"
    },
    {
      hotkey: "",
      desc: "在搜尋框內"
    },
    {
      hotkey: "Enter",
      desc: "搜尋"
    },
    {
      hotkey: "ESC",
      desc: "跳出搜尋框"
    }
  ];
  const hotkeyData = {
    hotkeysLeft,
    hotkeysRight
  };
  const _hoisted_1$3 = { id: "plus91-hotkey-popup" };
  const _hoisted_2$2 = { class: "hotkey-popup-container" };
  const _hoisted_3 = { class: "left-part" };
  const _hoisted_4 = { class: "right-part" };
  const _sfc_main$4 = {
    __name: "HotkeyPopup",
    setup(__props) {
      const store = useStore();
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide-and-fade" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$3, [
              vue.createElementVNode("div", _hoisted_2$2, [
                vue.createElementVNode("section", _hoisted_3, [
                  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(hotkeyData).hotkeysLeft, (item) => {
                    return vue.openBlock(), vue.createBlock(HotkeyItem, {
                      hotkey: item.hotkey,
                      desc: item.desc
                    }, null, 8, ["hotkey", "desc"]);
                  }), 256))
                ]),
                vue.createElementVNode("section", _hoisted_4, [
                  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(hotkeyData).hotkeysRight, (item) => {
                    return vue.openBlock(), vue.createBlock(HotkeyItem, {
                      hotkey: item.hotkey,
                      desc: item.desc
                    }, null, 8, ["hotkey", "desc"]);
                  }), 256))
                ])
              ])
            ], 512), [
              [vue.vShow, vue.unref(store).isPopupShow.hotkey]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const HotkeyPopup = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-a88e7568"]]);
  const _hoisted_1$2 = { id: "plus91-footer" };
  const _hoisted_2$1 = { class: "footer-container" };
  const _sfc_main$3 = {
    __name: "Footer",
    props: {
      active: Boolean
    },
    setup(__props) {
      const store = useStore();
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$2, [
              vue.createElementVNode("div", _hoisted_2$1, [
                vue.createVNode(ToolbarIcon, {
                  icon: "music-note-beamed",
                  stroke: ".05rem",
                  active: vue.unref(store).isPopupShow.sheet,
                  onClick: _cache[0] || (_cache[0] = ($event) => vue.unref(store).togglePopup("sheet"))
                }, null, 8, ["active"]),
                vue.createVNode(ToolbarIcon, {
                  icon: "table",
                  active: vue.unref(store).isPopupShow.chord,
                  onClick: _cache[1] || (_cache[1] = ($event) => vue.unref(store).togglePopup("chord"))
                }, null, 8, ["active"]),
                vue.createVNode(ToolbarIcon, {
                  icon: "type",
                  stroke: ".05rem",
                  active: vue.unref(store).isPopupShow.font,
                  onClick: _cache[2] || (_cache[2] = ($event) => vue.unref(store).togglePopup("font"))
                }, null, 8, ["active"]),
                vue.createVNode(ToolbarIcon, {
                  icon: "gear-wide-connected",
                  active: vue.unref(store).isPopupShow.settings,
                  onClick: _cache[3] || (_cache[3] = ($event) => vue.unref(store).togglePopup("settings"))
                }, null, 8, ["active"]),
                vue.createVNode(ToolbarIcon, {
                  icon: "list",
                  stroke: ".05rem",
                  active: vue.unref(store).isPopupShow.menu,
                  onClick: _cache[4] || (_cache[4] = ($event) => vue.unref(store).togglePopup("menu"))
                }, null, 8, ["active"]),
                vue.createVNode(SheetPopup),
                vue.createVNode(ChordPopup),
                vue.createVNode(FontSizePopup),
                vue.createVNode(SettingsPopup),
                vue.createVNode(MenuPopup),
                vue.createVNode(HotkeyPopup)
              ])
            ], 512), [
              [vue.vShow, __props.active]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const Footer = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-a29224c8"]]);
  const _hoisted_1$1 = { id: "plus91-header" };
  const _hoisted_2 = { class: "header-container" };
  const _sfc_main$2 = {
    __name: "Header",
    props: {
      active: Boolean
    },
    setup(__props) {
      const searchText = vue.ref("");
      const search = () => {
        if (!searchText.value) {
          return;
        }
        const url = `https://www.91pu.com.tw/plus/search.php?keyword=${searchText.value}`;
        window.open(url, "_blank").focus();
      };
      const backToPreviousPage = () => {
        history.back();
      };
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "slide" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1$1, [
              vue.createElementVNode("div", _hoisted_2, [
                vue.createVNode(ToolbarIcon, {
                  icon: "chevron-left",
                  stroke: ".04rem",
                  onClick: backToPreviousPage
                }),
                vue.withDirectives(vue.createElementVNode("input", {
                  type: "text",
                  placeholder: "91 Plus",
                  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchText.value = $event),
                  onKeydown: [
                    vue.withKeys(search, ["enter"]),
                    _cache[1] || (_cache[1] = vue.withKeys((event) => {
                      event.target.blur();
                    }, ["esc"]))
                  ]
                }, null, 544), [
                  [
                    vue.vModelText,
                    searchText.value,
                    void 0,
                    { trim: true }
                  ]
                ]),
                vue.createVNode(ToolbarIcon, {
                  icon: "search",
                  stroke: ".03rem",
                  onClick: _cache[2] || (_cache[2] = ($event) => search())
                })
              ])
            ], 512), [
              [vue.vShow, __props.active]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const Header = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-265bcfd2"]]);
  const _hoisted_1 = { id: "dark-mode-overlay" };
  const _sfc_main$1 = {
    __name: "DarkModeOverlay",
    props: {
      active: Boolean
    },
    setup(__props) {
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "fade" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", _hoisted_1, null, 512), [
              [vue.vShow, __props.active]
            ])
          ]),
          _: 1
        });
      };
    }
  };
  const DarkModeOverlay = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-e9c78cc3"]]);
  const _sfc_main = {
    __name: "App",
    setup(__props) {
      const store = useStore();
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
          vue.createVNode(TriggerOverlay, {
            onClick: vue.unref(store).toggleToolbars
          }, null, 8, ["onClick"]),
          vue.createVNode(Header, {
            active: vue.unref(store).isToolbarsShow
          }, null, 8, ["active"]),
          vue.createVNode(Footer, {
            active: vue.unref(store).isToolbarsShow
          }, null, 8, ["active"]),
          vue.createVNode(DarkModeOverlay, {
            active: vue.unref(store).isDarkMode
          }, null, 8, ["active"])
        ], 64);
      };
    }
  };
  function init() {
    redirect();
    injectGtag();
    initMutationObserver();
    handleEvents();
    const storeHandler = new StoreHandler().start();
    onDomReady(() => {
      changeTitle();
      storeHandler.initState();
      const store = useStore();
      if (store.agreeToArchiveSheet) {
        archiveChordSheet();
      }
    });
  }
  const pinia = createPinia();
  pinia.use(src_default);
  vue.createApp(_sfc_main).use(pinia).mount(
    (() => {
      const app = document.createElement("div");
      app.id = "vue-91plus";
      document.body.append(app);
      return app;
    })()
  );
  init();

})(Vue);