1 Star 0 Fork 34

durandal/outline.js

forked from Yaohaixiao/outline.js 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
chapters.min.js.map 82.61 KB
一键复制 编辑 原始数据 按行查看 历史
{"version":3,"file":"chapters.min.js","sources":["utils/types/isString.js","utils/lang/hasOwn.js","utils/lang/toString.js","utils/types/isFunction.js","utils/types/isObject.js","utils/observer/_subscribers.js","utils/observer/_hasDirectSubscribersFor.js","utils/observer/has.js","utils/observer/_hasSubscribers.js","utils/observer/emit.js","utils/types/isTypedArray.js","utils/lang/guid.js","utils/observer/_removeSubscriber.js","utils/observer/off.js","utils/observer/_removeSubscriberByToken.js","base.js","utils/lang/extend.js","utils/observer/on.js","utils/types/isElement.js","utils/lang/later.js","utils/event/enum.js","utils/event/_off.js","utils/event/_delete.js","utils/event/purgeElement.js","utils/event/getListeners.js","utils/event/off.js","utils/event/at.js","utils/dom/matches.js","utils/dom/getParentOrHost.js","utils/event/on.js","utils/event/getTarget.js","utils/dom/resolveTextNode.js","utils/dom/closest.js","utils/types/isArray.js","utils/types/isDOM.js","utils/types/isHTMLCollection.js","utils/types/isFragment.js","utils/types/isTextNode.js","utils/dom/createElement.js","utils/dom/setAttributes.js","utils/dom/setAttribute.js","utils/lang/easeInQuad.js","utils/dom/_getScrollElement.js","utils/dom/hasClass.js","utils/dom/addClass.js","utils/dom/removeClass.js","utils/lang/trim.js","utils/dom/offsetTop.js","utils/dom/getStyle.js","utils/dom/setProperty.js","utils/lang/cloneDeep.js","utils/lang/timeSlice.js","chapters.js","_paintChapters.js","utils/dom/scrollTo.js","utils/dom/intersection.js","utils/event/stop.js"],"sourcesContent":["/**\n * 检测数据是否为 String 类型\n * ========================================================================\n * @method isArray\n * @param {*} str\n * @returns {boolean}\n */\nconst isString = (str) => {\n return typeof str === 'string'\n}\n\nexport default isString\n","/**\n * 检测对象自身属性中是否具有指定的属性。\n * ========================================================================\n * @method hasOwn\n * @param {Object} obj - (必须)检测的目标对象\n * @param {String} prop - (必须)属性名\n * @returns {Boolean}\n */\nconst hasOwn = (obj, prop) => {\n const hasOwnProperty = Object.prototype.hasOwnProperty\n return obj && hasOwnProperty.call(obj, prop)\n}\n\nexport default hasOwn\n","/**\n * Object 对象原型上的 toString 方法\n * ========================================================================\n * @method toString\n * @param {*} val\n * @returns {string}\n */\nconst toString = (val) => {\n return Object.prototype.toString.apply(val)\n}\n\nexport default toString\n","import toString from '../lang/toString'\n\n/**\n * 检测测试数据是否为 Function 类型\n * ========================================================================\n * @method isFunction\n * @param {*} val - (必须)待检测的数据\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\n */\nconst isFunction = (val) => {\n return typeof val === 'function' || toString(val) === '[object Function]'\n}\n\nexport default isFunction\n","import toString from '../lang/toString'\nimport isFunction from './isFunction'\n\n/**\n * 检测数据是否为 Object 类型\n * ========================================================================\n * @method isObject\n * @param {*} o\n * @returns {boolean}\n */\nconst isObject = (o) => {\n return (\n (toString(o) === '[object Object]' ||\n typeof o === 'object' ||\n isFunction(o)) &&\n o !== null\n )\n}\n\nexport default isObject\n","/**\n * 存储订阅者(主题和处理器的)私有对象\n * ========================================================================\n * @type {{}}\n * @private\n */\nconst _subscribers = {}\n\nexport default _subscribers\n","import _subscribers from './_subscribers'\nimport hasOwn from '../lang/hasOwn'\n\n/**\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\n * ========================================================================\n * @method _hasDirectSubscribersFor\n * @param {String} topic - (必须)订阅主题字符串\n * @returns {Boolean}\n */\nconst _hasDirectSubscribersFor = (topic) => {\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\n}\n\nexport default _hasDirectSubscribersFor\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\nimport _hasSubscribers from './_hasSubscribers'\n\n/**\n * 判断是否存在包含 topic 指定的订阅者信息\n * ========================================================================\n * @method has\n * @param {String} topic - (必须)主题名称\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\n * @returns {Boolean}\n */\nconst has = (topic, isDirect = true) => {\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\n}\n\nexport default has\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\n\n/**\n * 判断是否存在包含给定 topic 相关的订阅者信息\n * ========================================================================\n * @method _hasSubscribers\n * @param {String} topic - (必须)订阅主题字符串\n * @returns {Boolean}\n */\nconst _hasSubscribers = (topic) => {\n let found = _hasDirectSubscribersFor(topic)\n let position = topic.lastIndexOf('.')\n\n while (!found && position !== -1) {\n topic = topic.substring(0, position)\n position = topic.lastIndexOf('.')\n found = _hasDirectSubscribersFor(topic)\n }\n\n return found\n}\n\nexport default _hasSubscribers\n","import isTypedArray from '../types/isTypedArray'\nimport _subscribers from './_subscribers'\nimport has from './has'\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\n\n/**\n * (异步)发布订阅主题信息\n * ========================================================================\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\n * ========================================================================\n * @method emit\n * @param {String} topic - (必须)主题名称\n * @param {Object} [data] - (可选)数据对象\n * @param {Boolean} [async] - (可选) 是否异步发布\n */\nconst emit = (topic, data, async = true) => {\n const execute = (topic) => {\n if (!_hasDirectSubscribersFor(topic)) {\n return false\n }\n\n _subscribers[topic].forEach((subscriber) => {\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\n // 采用 toString() 方法转化为普通(JSON)字符串\n const message = isTypedArray(data) ? data.toString() : data\n\n subscriber.callback.call(subscriber.context || subscriber, message)\n })\n }\n const deliver = () => {\n let subscriber = topic\n let position = topic.lastIndexOf('.')\n\n while (position !== -1) {\n subscriber = subscriber.substring(0, position)\n position = subscriber.lastIndexOf('.')\n\n execute(subscriber)\n }\n\n // 执行 topic 对应的处理器\n execute(topic)\n // 执行特殊 topic:'*'(监听全部消息的发布)\n execute('*')\n }\n\n if (!has(topic)) {\n return false\n }\n\n if (async) {\n setTimeout(deliver, 10)\n } else {\n deliver()\n }\n}\n\nexport default emit\n","import toString from '../lang/toString'\n/**\n * 判断检测数据是否为 Typed Arrays 类型的数据\n * ========================================================================\n * @param {*} val\n * @returns {boolean}\n */\nconst isTypedArray = (val) => {\n const TYPES = [\n '[object Int8Array]',\n '[object Uint8Array]',\n '[object Uint8ClampedArray]',\n '[object Int16Array]',\n '[object Uint16Array]',\n '[object Int32Array]',\n '[object Uint32Array]',\n '[object Float32Array]',\n '[object Float64Array]',\n '[object BigInt64Array]',\n '[object BigUint64Array]'\n ]\n\n return TYPES.indexOf(toString(val)) > -1\n}\n\nexport default isTypedArray\n","/**\n * 生成唯一 id 字符串的函数\n * ========================================================================\n * @method guid\n * @param {String} [prefix] - 生成 id 的前缀字符串\n * @return {String} 返回一个表示唯一 id 的字符串\n */\nconst guid = (() => {\n let uuid = 0\n\n return (prefix) => {\n uuid += 1\n\n return prefix ? prefix + '-' + uuid : 'guid-' + uuid\n }\n})()\n\nexport default guid\n","import _subscribers from './_subscribers'\nimport hasOwn from '../lang/hasOwn'\n\n/**\n * 删除与给定 topic 相同的订阅者信息\n * ========================================================================\n * @method _removeSubscriber\n * @param {String} topic - (必须)订阅主题字符串\n * @returns {Boolean}\n */\nconst _removeSubscriber = (topic) => {\n if (!hasOwn(_subscribers, topic)) {\n return false\n }\n\n delete _subscribers[topic]\n}\n\nexport default _removeSubscriber\n","import has from './has'\nimport _removeSubscriber from './_removeSubscriber'\nimport _removeSubscriberByToken from './_removeSubscriberByToken'\n\n/**\n * 取消订阅主题\n * ========================================================================\n * @method off\n * @param {String} topic - (必须)订阅的主题\n * @param {Function|String} [token] - (可选)订阅主题的处理器函数或者唯一 Id 值\n */\nconst off = (topic, token) => {\n if (!has(topic)) {\n return false\n }\n\n if (token) {\n _removeSubscriberByToken(token)\n } else {\n _removeSubscriber(topic)\n }\n}\n\nexport default off\n","import _subscribers from './_subscribers'\nimport _removeSubscriber from './_removeSubscriber'\n\n/**\n * 通过订阅者 token 值删除订阅者信息\n * ========================================================================\n * @method _removeSubscriberByToken\n * @param {String} token - 订阅者 token 字符串\n * @returns {boolean}\n * @private\n */\nconst _removeSubscriberByToken = (token) => {\n const keys = Object.keys(_subscribers)\n let index = -1\n\n if (!token || keys.length < 1) {\n return false\n }\n\n keys.forEach((subject) => {\n const subscriber = _subscribers[subject]\n let topic\n\n subscriber.forEach((execution, j) => {\n if (execution.callback === token || execution.token === token) {\n topic = execution.topic\n subscriber.splice(index, j)\n }\n })\n\n /* istanbul ignore else */\n if (subscriber.length < 1) {\n _removeSubscriber(topic)\n }\n })\n}\n\nexport default _removeSubscriberByToken\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\nimport publish from './utils/observer/emit'\r\nimport subscribe from './utils/observer/on'\r\nimport unsubscribe from './utils/observer/off'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(options)\r\n return this\r\n }\r\n\r\n $emit(event, data) {\r\n publish(event, data)\r\n return this\r\n }\r\n\r\n $on(event, callback) {\r\n subscribe(event, callback, this)\r\n return this\r\n }\r\n\r\n $off(event, callback) {\r\n unsubscribe(event, callback)\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\n\n/**\n * 扩展对象\n * ========================================================================\n * @method extend\n * @param {Object} origin\n * @param {Object} source\n */\nconst extend = (origin, source) => {\n const keys = Object.keys(source)\n\n keys.forEach((prop) => {\n if (hasOwn(source, prop)) {\n origin[prop] = source[prop]\n }\n })\n}\n\nexport default extend\n","import _subscribers from './_subscribers'\nimport isFunction from '../types/isFunction'\nimport guid from '../lang/guid'\n\n/**\n * 订阅主题,并给出处理器函数\n * ========================================================================\n * @method on\n * @param {String} topic - (必须)主题名称\n * @param {Function} handler - (必须)主题的处理器函数\n * @param {Object} [context] - (可选)指定 this 执行上下文\n * @return {String} - 唯一的 token 字符串,例如:'guid-1'。\n */\nconst on = (topic, handler, context = null) => {\n const token = guid()\n let subject = typeof topic === 'symbol' ? topic.toString() : topic\n\n if (!isFunction(handler)) {\n return ''\n }\n\n /* istanbul ignore else */\n if (!_subscribers[subject]) {\n _subscribers[subject] = []\n }\n\n _subscribers[subject].push({\n topic: subject,\n callback: handler,\n context,\n token\n })\n\n return token\n}\n\nexport default on\n","import isObject from './isObject'\n\n/**\n * 检测数据是否为 HTMLElement DOM 节点\n * ========================================================================\n * @method isElement\n * @param {*} o\n * @returns {boolean}\n */\nconst isElement = (o) => {\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\n}\n\nexport default isElement\n","import isFunction from '../types/isFunction'\n\n/**\n * later - 延迟执行方法\n * ========================================================================\n * @method later\n * @param {Function} fn\n * @param {Number} [delay]\n * @returns {number|boolean}\n */\nconst later = (fn, delay = 300) => {\n if (!isFunction(fn)) {\n return false\n }\n\n return setTimeout(() => {\n fn()\n }, delay)\n}\n\nexport default later\n","export const CAPTURE_EVENTS = [\n 'focusout',\n 'blur',\n 'focusin',\n 'focus',\n 'load',\n 'unload',\n 'mouseenter',\n 'mouseleave'\n]\n","import { CAPTURE_EVENTS } from './enum'\nimport _delete from './_delete'\n\n/**\n * (私有方法)取消 type 类型的代理事件绑定\n * ========================================================================\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\n * ========================================================================\n * @method _off\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\n * @param {String} type - (必须)事件类型\n * @param {Function} fn - (必须)事件处理器回调函数\n * @private\n */\nconst _off = (el, type, fn) => {\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\n\n /* istanbul ignore else */\n if (fn._delegateListener) {\n fn = fn._delegateListener\n delete fn._delegateListener\n }\n\n // 移除缓存的 _listeners 数据\n _delete(el, type, fn)\n\n el.removeEventListener(type, fn, capture)\n}\n\nexport default _off\n","/**\n * 删除 DOM 元素缓存的 _listeners 数据\n * ========================================================================\n * @method _delete\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\n * @param {String} type - 事件类型(名称)\n * @param {Function} [fn] - 事件处理器回调函数\n */\nconst _delete = function (el, type, fn) {\n const listeners = el._listeners\n let index = -1\n\n if (listeners.length < 1) {\n return false\n }\n\n // 移除缓存的 _listeners 数据\n listeners.forEach((listener, i) => {\n const handler = listener.fn\n\n if (type === listener.type) {\n index = i\n\n if (handler === fn) {\n index = i\n }\n }\n })\n\n /* istanbul ignore else */\n if (index > -1) {\n listeners.splice(index, 1)\n }\n}\n\nexport default _delete\n","import isString from '../types/isString'\nimport isElement from '../types/isElement'\nimport getListeners from './getListeners'\nimport _off from './_off'\n\n/**\n * 销毁(type 类型的)代理事件绑定\n * ========================================================================\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\n * ========================================================================\n * @method purgeElement\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\n * @param {String|Boolean} type - (必须)事件类型\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\n */\nconst purgeElement = function (el, type, recurse = false) {\n const $element = isString(el) ? document.querySelector(el) : el\n const $children = $element.childNodes\n const listeners = getListeners($element, type)\n\n listeners.forEach((listener) => {\n _off($element, listener.type, listener.fn)\n })\n\n if (\n (recurse || type === true || arguments.length === 1) &&\n $element &&\n $children\n ) {\n $children.forEach(($child) => {\n if (isElement($child)) {\n purgeElement($child, type, recurse)\n }\n })\n }\n}\n\nexport default purgeElement\n","import isString from '../types/isString'\n\n/**\n * 获取 DOM 元素(type 事件类型)事件绑定信息\n * ========================================================================\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\n * ========================================================================\n * @methods getListeners\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\n * @param {String} [type] - (可选)事件类型\n * @returns {Array} - 已绑定的事件信息\n */\nconst getListeners = (el, type) => {\n let listeners = el._listeners || []\n\n if (isString(type) && type) {\n listeners = listeners.filter((listener) => {\n return listener.type === type\n })\n }\n\n return listeners\n}\n\nexport default getListeners\n","import purgeElement from './purgeElement'\nimport isFunction from '../types/isFunction'\nimport _off from './_off'\n\n/**\n * 取消 type 类型的代理事件绑定\n * ========================================================================\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\n * ========================================================================\n * @method off\n * @param {HTMLElement|Object} el - (必须)取消事件绑定的 DOM 元素\n * @param {String} type - (必须)事件类型\n * @param {Function} [fn] - (可选)事件处理器回调函数\n */\nconst off = (el, type, fn) => {\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\n if (!isFunction(fn)) {\n return purgeElement(el, type)\n }\n\n _off(el, type, fn)\n}\n\nexport default off\n","import isFunction from '../types/isFunction'\nimport off from './off'\n\nimport { CAPTURE_EVENTS } from './enum'\n\n/**\n * 绑定事件\n * ========================================================================\n * @method at\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\n * @param {Boolean} once - (可选)是否仅触发一次\n */\nconst at = (el, type, fn, data, context, once = false) => {\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\n const listener = function (evt) {\n let overrideContext = context || el\n\n // 当设置为 true 时,则事件处理器回调函数的\n // this 上下文指向为 data 对象\n if (context === true) {\n overrideContext = data\n }\n\n // 仅触发一次\n /* istanbul ignore else */\n if (once === true) {\n off(el, type, listener)\n }\n\n fn.call(overrideContext, evt, data)\n }\n\n if (!isFunction(fn)) {\n return false\n }\n\n if (!el._listeners) {\n el._listeners = []\n }\n\n // 缓存 options 元素绑定的事件处理器\n el._listeners.push({\n el,\n type,\n fn: listener,\n data,\n context,\n capture\n })\n\n // 缓存包装后的事件处理器\n fn._delegateListener = listener\n\n el.addEventListener(type, listener, capture)\n}\n\nexport default at\n","/**\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\n * ========================================================================\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\n * 标 DOM 元素是否为事件代理所期望触发的目标。\n * ========================================================================\n * @method matches\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\n * @param {HTMLElement} el - (必须)DOM 元素\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\n * @returns {Boolean}\n */\nconst matches = (el, selector = '') => {\n const sel = selector.replace(/^>/i, '')\n\n if (!selector || !sel || !el) {\n return false\n }\n\n /* istanbul ignore else */\n if (el.matches) {\n return el.matches(sel)\n } else if (el.msMatchesSelector) {\n return el.msMatchesSelector(sel)\n } else {\n return false\n }\n}\n\nexport default matches\n","/**\n * 获取 DOM 元素的父节点\n * ========================================================================\n * @method getParentOrHost\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\n * @returns {*|HTMLElement}\n */\nconst getParentOrHost = (el) => {\n return el.host && el !== document && el.host.nodeType\n ? el.host\n : el.parentNode\n}\n\nexport default getParentOrHost\n","import closest from '../dom/closest'\nimport off from './off'\nimport getTarget from './getTarget'\n\nimport { CAPTURE_EVENTS } from './enum'\n\n/**\n * 绑定代理事件\n * ========================================================================\n * @method on\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\n * @param {Boolean} once - (可选)是否仅触发一次\n */\nconst on = (el, selector, type, fn, data, context, once = false) => {\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\n\n const listener = function (evt) {\n const target = getTarget(evt)\n // 通过 Element.matches 方法获得点击的目标元素\n const delegateTarget = closest(target, selector, el)\n let overrideContext = context || el\n\n evt.delegateTarget = delegateTarget\n\n // 当设置为 true 时,则事件处理器回调函数的\n // this 上下文指向为 data 对象\n if (context === true) {\n overrideContext = data\n }\n\n /* istanbul ignore else */\n if (delegateTarget) {\n // 仅触发一次\n /* istanbul ignore else */\n if (once === true) {\n off(el, type, listener)\n }\n\n fn.call(overrideContext, evt, data)\n }\n }\n\n if (!el._listeners) {\n el._listeners = []\n }\n\n // 缓存 options 元素绑定的事件处理器\n el._listeners.push({\n el,\n selector,\n type,\n fn: listener,\n data,\n context,\n capture\n })\n\n // 缓存包装后的事件处理器\n fn._delegateListener = listener\n\n el.addEventListener(type, listener, capture)\n}\n\nexport default on\n","import resolveTextNode from '../dom/resolveTextNode'\n\n/**\n * 返回触发事件的 target DOM 元素\n * ========================================================================\n * @method getTarget\n * @param {Event} evt - Event 对象\n * @return {HTMLElement} - Event 对象的 target DOM 元素\n */\nconst getTarget = function (evt) {\n const target = evt.target\n\n return resolveTextNode(target)\n}\n\nexport default getTarget\n","/**\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\n * resolveTextNode() 方法则会返回实际的目标节点。\n * ========================================================================\n * @method resolveTextNode\n * @param {HTMLElement|Text} el - 要解析的节点\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\n */\nconst resolveTextNode = function (el) {\n if (el && el.nodeType === 3) {\n return el.parentNode\n }\n\n return el\n}\n\nexport default resolveTextNode\n","import matches from './matches'\nimport getParentOrHost from './getParentOrHost'\n\n/**\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\n * ========================================================================\n * @method closest\n * @param {HTMLElement} el - (必须)DOM 元素\n * @param {String} selector - (必须)DOM 元素的选择其\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\n */\nconst closest = (el, selector, ctx, includeCTX) => {\n const context = ctx || document\n\n if (!el) {\n return null\n }\n\n do {\n /* istanbul ignore else */\n if (\n (selector != null &&\n (selector.startsWith('>')\n ? el.parentNode === context && matches(el, selector)\n : matches(el, selector))) ||\n (includeCTX && el === context)\n ) {\n return el\n }\n\n /* istanbul ignore else */\n if (el === context) {\n break\n }\n\n /* jshint boss:true */\n } while ((el = getParentOrHost(el)))\n}\n\nexport default closest\n","import toString from '../lang/toString'\n\n/**\n * 检测数据是否为 Array 类型\n * ========================================================================\n * @method isArray\n * @param {*} o\n * @returns {boolean}\n */\nconst isArray = (o) => {\n if (Array.isArray) {\n return Array.isArray(o)\n } else {\n return toString(o) === '[object Array]'\n }\n}\n\nexport default isArray\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\nimport isObject from './isObject'\n\nconst isFragment = (fragment) => {\n return !!(\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\n )\n}\n\nexport default isFragment\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","import isObject from '../types/isObject'\nimport isString from '../types/isString'\nimport isArray from '../types/isArray'\nimport isDOM from '../types/isDOM'\nimport setAttributes from './setAttributes'\n\n/**\n * 创建 DOM 节点,并添加属性和子节点\n * ========================================================================\n * @method createElement\n * @param {String} tagName - 标签名称\n * @param {Object|Array|HTMLElement|DocumentFragment|String} attrs - 属性对象或者子节点\n * @param {Array|HTMLElement|DocumentFragment|String} [children] - 子节点数组\n * @returns {HTMLElement}\n */\nconst createElement = (tagName, attrs, children) => {\n const $fragment = document.createDocumentFragment()\n const $el = document.createElement(tagName)\n const isValidChild = (child) => {\n return isDOM(child) || isString(child)\n }\n const append = (child) => {\n let $child\n\n if (!isValidChild(child)) {\n return false\n }\n\n if (isDOM(child)) {\n $child = child\n } else if (isString(child)) {\n $child = document.createTextNode(child)\n }\n\n $fragment.appendChild($child)\n }\n\n if (isObject(attrs)) {\n setAttributes($el, attrs)\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\n attrs.forEach((child) => {\n append(child)\n })\n } else if (isDOM(attrs)) {\n append(attrs)\n } else if (isString(attrs)) {\n append(document.createTextNode(attrs))\n }\n\n if (isArray(children)) {\n children.forEach((child) => {\n append(child)\n })\n } else {\n append(children)\n }\n\n $el.appendChild($fragment)\n\n return $el\n}\n\nexport default createElement\n","import isObject from '../types/isObject'\nimport hasOwn from '../lang/hasOwn'\nimport setAttribute from './setAttribute'\n\nconst setAttributes = (el, attrs) => {\n if (!el || !isObject(attrs)) {\n return false\n }\n\n Object.keys(attrs).forEach((attr) => {\n const value = attrs[attr]\n if (hasOwn(attrs, attr)) {\n setAttribute(el, attr, value)\n }\n })\n}\n\nexport default setAttributes\n","/**\n * 给 DOM 节点设置属性/值\n * ========================================================================\n * @method setAttribute\n * @param {HTMLElement} el - DOM 节点\n * @param {String} attr - 属性名称\n * @param {String|Number|Boolean} value - 属性值\n */\nconst setAttribute = (el, attr, value) => {\n let tagName = el.tagName.toLowerCase()\n\n switch (attr) {\n case 'style':\n el.style.cssText = value\n break\n case 'value':\n if (tagName === 'input' || tagName === 'textarea') {\n el.value = value\n } else {\n el.setAttribute(attr, value)\n }\n break\n case 'htmlFor':\n el.setAttribute('for', value)\n break\n case 'className':\n el.className = value\n break\n case 'innerHTML':\n el.innerHTML = value\n break\n case 'innerText':\n el.innerText = value\n break\n default:\n el.setAttribute(attr, value)\n break\n }\n}\n\nexport default setAttribute\n","/**\n * 返回给定值的平方值\n * ========================================================================\n * @method easeInQuad\n * @param {Number} x\n * @returns {number}\n */\nconst easeInQuad = (x) => {\n return x * x\n}\n\nexport default easeInQuad\n","import isString from '../types/isString'\nimport isElement from '../types/isElement'\n\n/**\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\n * ========================================================================\n * @method _getScrollElement\n * @param {String|HTMLElement} scrollElement\n * @returns {Element}\n * @private\n */\nconst _getScrollElement = (scrollElement = null) => {\n let $rootElements\n let $scrollElement\n\n if (!scrollElement) {\n $rootElements = document.querySelectorAll('html,body')\n $scrollElement =\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\n ? $rootElements[0]\n : $rootElements[1]\n } else {\n if (isString(scrollElement)) {\n $scrollElement = document.querySelector(scrollElement)\n } else if (isElement(scrollElement)) {\n $scrollElement = scrollElement\n }\n }\n\n return $scrollElement\n}\n\nexport default _getScrollElement\n","import isElement from '../types/isElement'\n/**\n * 检测 DOM 节点是否包含名为 className 的样式\n * ========================================================================\n * @method hasClass\n * @param {HTMLElement} el - DOM 节点\n * @param {String} className - 样式名称\n * @returns {Boolean}\n */\nconst hasClass = (el, className) => {\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\n let allClass\n let classList\n\n if (!isElement(el)) {\n return false\n }\n\n allClass = el.className\n\n if (!allClass) {\n return false\n }\n\n classList = el.classList\n\n if (classList?.contains) {\n return el.classList.contains(className)\n }\n\n return !!pattern.exec(allClass)\n}\n\nexport default hasClass\n","import hasClass from './hasClass'\n\n/**\n * 给 DOM 节点添加名为 className 的样式\n * ========================================================================\n * @method addClass\n * @param {HTMLElement} el - DOM 节点\n * @param {String} className - 样式名称\n * @returns {Boolean}\n */\nconst addClass = (el, className) => {\n let classList\n let allClass\n\n if (hasClass(el, className)) {\n return false\n }\n\n classList = el.classList\n\n if (classList?.add) {\n classList.add(className)\n } else {\n allClass = el.className\n allClass += allClass.length > 0 ? ' ' + className : className\n el.className = allClass\n }\n}\n\nexport default addClass\n","import trim from '../lang/trim'\nimport hasClass from './hasClass'\n\n/**\n * 移除 DOM 节点的 className 样式\n * ========================================================================\n * @method removeClass\n * @param {HTMLElement} el - DOM 节点\n * @param {String} className - 样式名称\n * @returns {Boolean}\n */\nconst removeClass = (el, className) => {\n let allClass = el.className\n let classList\n\n if (!allClass || !hasClass(el, className)) {\n return false\n }\n\n classList = el.classList\n\n if (classList?.remove) {\n classList.remove(className)\n } else {\n allClass = trim(allClass.replace(className, ''))\n el.className = allClass\n }\n}\n\nexport default removeClass\n","import isString from '../types/isString'\n\n/**\n * 清楚字符串起始位置所有的空格\n * ========================================================================\n * @method trim\n * @param {string} str\n * @returns {string|Boolean}\n */\nconst trim = (str) => {\n if (!isString(str)) {\n return false\n }\n return str.replace(/(^\\s+)|(\\s+$)/g, '')\n}\n\nexport default trim\n","/**\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\n * ========================================================================\n * @method offsetTop\n * @param {HTMLElement} el - DOM 节点\n * @returns {Number}\n */\nconst offsetTop = (el) => {\n let top = el.offsetTop\n\n if (el.offsetParent !== null) {\n top += offsetTop(el.offsetParent)\n }\n\n return top\n}\n\nexport default offsetTop\n","/**\r\n * 获取HTML元素的某个CSS样式值\r\n * ====================================================\r\n * @param el\r\n * @param ruleName\r\n * @returns {*}\r\n */\r\nconst getStyle = (el, ruleName) => {\r\n return getComputedStyle(el)[ruleName]\r\n}\r\n\r\nexport default getStyle\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","import isObject from '../types/isObject'\r\nimport isArray from '../types/isArray'\r\n\r\n/**\r\n * 深拷贝对象函数\r\n * ========================================================================\r\n * @methods cloneDeep\r\n * @param {Object} obj - 深拷贝的对象\r\n * @returns {Array|Object|*}\r\n *\r\n * @example\r\n * const arr = cloneDeep([2,3,4,6])\r\n * => [2,3,4,6]\r\n */\r\nconst cloneDeep = (obj) => {\r\n let clone = {}\r\n\r\n if (obj === null) {\r\n return null\r\n }\r\n\r\n if (isArray(obj)) {\r\n clone = Array.from(obj)\r\n } else {\r\n clone = Object.assign({}, obj)\r\n Object.keys(clone).forEach((key) => {\r\n return (clone[key] = isObject(obj[key]) ? cloneDeep(obj[key]) : obj[key])\r\n })\r\n }\r\n\r\n return clone\r\n}\r\n\r\nexport default cloneDeep\r\n","/**\n * timeSlice.js 时间切片功能函数\n * ====================================================\n * Created By: Yaohaixiao\n * Update: 2023.09.04\n */\nimport isFunction from '../types/isFunction'\nimport later from './later'\n\nconst queue = []\nlet isHandling\nlet done\n\n// Shim from https://developers.google.com/web/updates/2015/08/using-requestidlecallback\nif (typeof window.requestIdleCallback === 'undefined') {\n window.requestIdleCallback = function (cb) {\n const start = Date.now()\n return later(function () {\n cb({\n didTimeout: false,\n timeRemaining: function () {\n return Math.max(0, 50 - (Date.now() - start))\n }\n })\n }, 10)\n }\n\n window.cancelIdleCallback = function (id) {\n clearTimeout(id)\n }\n}\n\nfunction runIdle(idleDeadline) {\n while (idleDeadline.timeRemaining() > 0 && queue.length) {\n const fn = queue.shift()\n\n if (!isFunction(fn)) {\n return false\n }\n\n fn()\n }\n\n if (queue.length) {\n isHandling = requestIdleCallback(runIdle)\n } else {\n isHandling = 0\n\n if (isFunction(done)) {\n done()\n done = null\n }\n }\n}\n\n/**\n * 时间切片功能函数:主要用于优化长时任务的性能,将长时任务分解成\n * 多个短时间任务\n * ====================================================\n * @param {Function} fn - 需要在空闲时执行的回调函数\n * @param {Function} afterComplete - queen 的\n * @return {(function(): (boolean|undefined))|*|boolean}\n */\nconst timeSlice = (fn, afterComplete = null) => {\n queue.push(fn)\n\n if (isFunction(afterComplete)) {\n done = afterComplete\n }\n\n if (!isHandling) {\n requestIdleCallback(runIdle)\n }\n}\n\nexport default timeSlice\n","import Base from './base'\n\nimport isString from './utils/types/isString'\nimport isFunction from './utils/types/isFunction'\nimport isElement from './utils/types/isElement'\nimport later from './utils/lang/later'\nimport at from './utils/event/at'\nimport on from './utils/event/on'\nimport off from './utils/event/off'\nimport stop from './utils/event/stop'\nimport createElement from './utils/dom/createElement'\nimport scrollTo from './utils/dom/scrollTo'\nimport addClass from './utils/dom/addClass'\nimport intersection from './utils/dom/intersection'\nimport removeClass from './utils/dom/removeClass'\nimport offsetTop from './utils/dom/offsetTop'\nimport getStyle from './utils/dom/getStyle'\nimport setProperty from './utils/dom/setProperty'\nimport _getScrollElement from './utils/dom/_getScrollElement'\nimport cloneDeep from './utils/lang/cloneDeep'\n\nimport _paintChapters from './_paintChapters'\n\nclass Chapters extends Base {\n constructor(options) {\n super()\n\n this.attrs = cloneDeep(Chapters.DEFAULTS)\n\n this._init()\n\n this.scrollTimer = null\n this.resizeTimer = null\n this.observerTimer = null\n this.Observer = null\n\n if (options) {\n this.initialize(options)\n }\n }\n\n _init() {\n this.$el = null\n this.$title = null\n this.$main = null\n this.$list = null\n this.$placeholder = null\n this.$parentElement = null\n this.$scrollElement = null\n this.$active = null\n\n this.chapters = []\n this.active = 0\n this.offsetWidth = 0\n this.offsetTop = 0\n this.playing = false\n this.closed = false\n\n return this\n }\n\n initialize(options) {\n let created\n let parentElement\n let scrollElement\n let $parent\n\n this.attr(options)\n created = this.attr('created')\n parentElement = this.attr('parentElement')\n scrollElement = this.attr('scrollElement')\n\n if (isString(parentElement)) {\n $parent = document.querySelector(parentElement)\n } else if (isElement(parentElement)) {\n $parent = parentElement\n }\n this.$parentElement = $parent\n this.$scrollElement = _getScrollElement(scrollElement)\n\n this.chapters = this.attr('chapters')\n this.closed = this.attr('closed')\n this.active = this.attr('active')\n\n if (isFunction(created)) {\n created.call(this)\n }\n\n if (this.chapters.length < 1) {\n return this\n }\n\n this.render().addListeners()\n\n this.$active = document.querySelector(`#chapter-${this.active}`)\n\n return this\n }\n\n isClosed() {\n return this.closed\n }\n\n isSticky() {\n const position = this.attr('position')\n return position === 'sticky'\n }\n\n isFixed() {\n const position = this.attr('position')\n return position === 'fixed'\n }\n\n isInside() {\n return this.isFixed() || this.isSticky()\n }\n\n isOutside() {\n return !this.isInside()\n }\n\n count() {\n return this.chapters.length\n }\n\n _paintEdge() {\n const $fragment = document.createDocumentFragment()\n const STICKY = 'outline-chapters_sticky'\n const HIDDEN = 'outline-chapters_hidden'\n const title = this.attr('title')\n const animationCurrent = this.attr('animationCurrent')\n const customClass = this.attr('customClass')\n const $parentElement = this.$parentElement\n const children = []\n const contents = []\n let $title = null\n let $el\n let $main\n let $list\n let $placeholder\n\n if (!$parentElement) {\n return this\n }\n\n if (this.isInside() && title) {\n $title = createElement(\n 'h2',\n {\n className: 'outline-chapters__title'\n },\n title\n )\n this.$title = $title\n contents.push($title)\n }\n\n $list = createElement('ul', {\n // 为优化性能,添加了 _fixed 和 _hidden\n // fixed 为了让 $list 脱离流布局\n // hidden 让 $list 不可见\n className: `outline-chapters__list`\n })\n this.$list = $list\n children.push($list)\n\n if (animationCurrent) {\n $placeholder = createElement('div', {\n className: 'outline-chapters__placeholder'\n })\n this.$placeholder = $placeholder\n children.push($placeholder)\n }\n\n $main = createElement(\n 'div',\n {\n className: 'outline-chapters__main'\n },\n children\n )\n this.$main = $main\n contents.push($main)\n\n $el = createElement(\n 'nav',\n {\n id: 'outline-chapters',\n className: `outline-chapters ${HIDDEN}`\n },\n contents\n )\n this.$el = $el\n\n if (this.isSticky()) {\n this.calculateStickyHeight()\n addClass($el, STICKY)\n }\n\n if (customClass) {\n addClass($el, customClass)\n }\n $fragment.appendChild($el)\n $parentElement.appendChild($fragment)\n\n return this\n }\n\n render() {\n const HIDDEN = 'outline-chapters_hidden'\n const showCode = this.attr('showCode')\n const mounted = this.attr('mounted')\n const $parentElement = this.$parentElement\n const chapters = this.chapters\n const count = this.count()\n let $el\n let $list\n\n if (!$parentElement || chapters.length < 1) {\n return this\n }\n\n if (this.isInside()) {\n addClass($parentElement, 'outline-chapters-parent')\n }\n\n this._paintEdge()\n\n $el = this.$el\n $list = this.$list\n _paintChapters($list, chapters, showCode)\n removeClass($el, HIDDEN)\n\n later(() => {\n this.highlight(this.active)\n }, 60)\n\n this.offsetTop = offsetTop($el)\n this.offsetWidth = $el.offsetWidth\n\n if (this.isFixed()) {\n this.sticky()\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\n }\n\n if (isFunction(mounted)) {\n mounted.call(this)\n }\n\n if (count < 400) {\n this.onObserver()\n }\n\n return this\n }\n\n positionPlaceholder(index) {\n const $main = this.$main\n const $list = this.$list\n const $placeholder = this.$placeholder\n const $anchor = $list.querySelector('.outline-chapters__anchor')\n const animationCurrent = this.attr('animationCurrent')\n const mainPaddingTop = parseInt(getStyle($main, 'padding-top'), 10)\n const mainBorderTop = parseInt(getStyle($main, 'border-top-width'), 10)\n const placeholderPaddingTop = parseInt(getStyle($list, 'padding-top'), 10)\n const placeholderMarginTop = parseInt(getStyle($list, 'margin-top'), 10)\n const placeholderBorderTop = parseInt(\n getStyle($list, 'border-top-width'),\n 10\n )\n let height = $anchor.offsetHeight\n let offsetTop = 0\n let top\n\n if (!animationCurrent) {\n return this\n }\n\n if (mainPaddingTop) {\n offsetTop += mainPaddingTop\n }\n\n if (placeholderPaddingTop) {\n offsetTop += placeholderPaddingTop\n }\n\n if (placeholderMarginTop) {\n offsetTop += placeholderMarginTop\n }\n\n if (mainBorderTop) {\n offsetTop += mainBorderTop\n }\n\n if (placeholderBorderTop) {\n offsetTop += placeholderBorderTop\n }\n\n top = height * index\n $placeholder.style.cssText = `transform: translateY(${\n offsetTop + top\n }px);height:${height}px;`\n\n return this\n }\n\n highlight(id) {\n const $el = this.$el\n const animationCurrent = this.attr('animationCurrent')\n const ACTIVE = 'outline-chapters_active'\n const HIGHLIGHT = 'outline-chapters_highlight'\n let $anchor = null\n\n if (!$el) {\n return this\n }\n\n $anchor = $el.querySelector(`#chapter__anchor-${id}`)\n\n if (!$anchor) {\n return this\n }\n\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\n\n if (this.$active) {\n removeClass(this.$active, HIGHLIGHT)\n removeClass(this.$active, ACTIVE)\n }\n\n this.$active = $anchor\n addClass(this.$active, ACTIVE)\n\n if (animationCurrent) {\n this.positionPlaceholder(this.active)\n } else {\n addClass(this.$active, HIGHLIGHT)\n }\n\n return this\n }\n\n sticky() {\n const afterSticky = this.attr('afterSticky')\n const FIXED = 'outline-chapters_fixed'\n const $el = this.$el\n const top = this.offsetTop\n const scrollTop = this.$scrollElement.scrollTop\n let isStickying\n\n if (!this.isFixed()) {\n return this\n }\n\n isStickying = scrollTop >= top\n\n if (isStickying) {\n addClass($el, FIXED)\n } else {\n removeClass($el, FIXED)\n }\n\n if (isFunction(afterSticky)) {\n afterSticky.call(this, this.isClosed(), isStickying)\n }\n\n return this\n }\n\n calculateStickyHeight() {\n const documentElement = document.documentElement\n const height = Math.max(\n documentElement.clientHeight || 0,\n window.innerHeight || 0\n )\n setProperty('--outline-sticky-height', `${height}px`)\n return this\n }\n\n scrollTo(top, after) {\n const el = this.$scrollElement\n\n scrollTo(el, top, after)\n\n return this\n }\n\n show() {\n const FOLDED = 'outline-chapters_folded'\n const HIDDEN = 'outline-chapters_hidden'\n const opened = this.attr('afterOpened')\n const count = this.count()\n const $el = this.$el\n const $parent = this.$parentElement\n\n if (this.isInside()) {\n if (count > 800) {\n removeClass($parent, HIDDEN)\n } else {\n removeClass($parent, HIDDEN)\n later(() => {\n removeClass($parent, FOLDED)\n }, 30)\n }\n } else {\n removeClass($el, HIDDEN)\n }\n this.closed = false\n\n if (isFunction(opened)) {\n opened.call(this)\n }\n\n return this\n }\n\n hide() {\n const FOLDED = 'outline-chapters_folded'\n const HIDDEN = 'outline-chapters_hidden'\n const closed = this.attr('afterClosed')\n const count = this.count()\n const $el = this.$el\n const $parent = this.$parentElement\n\n if (this.isInside()) {\n if (count > 800) {\n addClass($parent, HIDDEN)\n } else {\n addClass($parent, FOLDED)\n later(() => {\n addClass($parent, HIDDEN)\n })\n }\n } else {\n addClass($el, HIDDEN)\n }\n this.closed = true\n\n if (isFunction(closed)) {\n closed.call(this)\n }\n\n return this\n }\n\n toggle() {\n const afterToggle = this.attr('afterToggle')\n const top = this.offsetTop\n const scrollTop = this.$scrollElement.scrollTop\n let isStickying\n\n if (this.isClosed()) {\n this.show()\n } else {\n this.hide()\n }\n\n if (isFunction(afterToggle)) {\n later(() => {\n isStickying = scrollTop >= top\n afterToggle.call(this, this.isClosed(), isStickying)\n })\n }\n\n return this\n }\n\n destroy() {\n const beforeDestroy = this.attr('beforeDestroy')\n const afterDestroy = this.attr('afterDestroy')\n\n if (isFunction(beforeDestroy)) {\n beforeDestroy.call(this)\n }\n\n this.removeListeners()\n this.attr(Chapters.DEFAULTS)\n\n if (this.scrollTimer) {\n clearTimeout(this.scrollTimer)\n this.scrollTimer = null\n }\n\n if (this.resizeTimer) {\n clearTimeout(this.resizeTimer)\n this.resizeTimer = null\n }\n\n if (this.observerTimer) {\n clearTimeout(this.observerTimer)\n this.observerTimer = null\n }\n\n if (this.Observer) {\n this.Observer = null\n }\n\n this.$parentElement.removeChild(this.$el)\n this._init()\n\n if (isFunction(afterDestroy)) {\n afterDestroy.call(this)\n }\n\n return this\n }\n\n onObserver() {\n const selector = this.attr('selector')\n\n this.Observer = intersection(\n ($heading) => {\n const id = $heading.getAttribute('data-id')\n\n if (this.playing) {\n return false\n }\n\n if (this.observerTimer) {\n clearTimeout(this.observerTimer)\n }\n\n this.observerTimer = later(() => {\n this.highlight(id)\n }, 100)\n },\n {\n selector,\n context: this\n }\n )\n\n return this\n }\n\n onSelect(evt) {\n const stickyHeight = this.attr('stickyHeight')\n const $anchor = evt.delegateTarget\n const id = $anchor.getAttribute('data-id')\n const headingId = $anchor.href.split('#')[1]\n const $heading = document.querySelector(`#${headingId}`)\n const top = offsetTop($heading) - (stickyHeight + 10)\n const min = 0\n const max = this.$scrollElement.scrollHeight\n const afterScroll = this.attr('afterScroll')\n const after = () => {\n if (isFunction(afterScroll)) {\n afterScroll.call(this, 'chapter')\n }\n\n later(() => {\n this.playing = false\n this.$emit('toolbar:update', {\n top,\n min,\n max\n })\n })\n }\n\n this.playing = true\n if (this.isFixed()) {\n this.sticky()\n later(() => {\n this.scrollTo(top, after)\n this.highlight(id)\n }, 10)\n } else {\n this.scrollTo(top, after)\n this.highlight(id)\n }\n\n stop(evt)\n\n return this\n }\n\n onScroll() {\n const $scrollElement = this.$scrollElement\n\n if (this.scrollTimer) {\n clearTimeout(this.scrollTimer)\n }\n\n this.scrollTimer = later(() => {\n const top = $scrollElement.scrollTop\n const min = 0\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\n\n if (this.isFixed()) {\n this.sticky()\n }\n\n this.$emit('toolbar:update', {\n top,\n min,\n max\n })\n }, 100)\n\n return this\n }\n\n onResize() {\n if (this.resizeTimer) {\n clearTimeout(this.resizeTimer)\n }\n\n this.resizeTimer = later(() => {\n this.calculateStickyHeight()\n })\n\n return this\n }\n\n addListeners() {\n const $el = this.$el\n const $scrollElement = this.$scrollElement\n const tagName = $scrollElement.tagName.toLowerCase()\n let $element = $scrollElement\n\n if (this.count() < 1) {\n return this\n }\n\n if (tagName === 'html' || tagName === 'body') {\n $element = window\n }\n\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\n at($element, 'scroll', this.onScroll, this, true)\n if (this.isSticky()) {\n at(window, 'resize', this.onResize, this, true)\n }\n this.$on('anchors:all:paint', this.onObserver, this)\n\n return this\n }\n\n removeListeners() {\n const selector = this.attr('selector')\n const $el = this.$el\n const $scrollElement = this.$scrollElement\n const tagName = $scrollElement.tagName.toLowerCase()\n let $element = $scrollElement\n\n if (this.count() < 1) {\n return this\n }\n\n if (tagName === 'html' || tagName === 'body') {\n $element = window\n }\n\n off($el, 'click', this.onSelect)\n off($element, 'scroll', this.onScroll)\n\n if (this.isSticky()) {\n at(window, 'resize', this.onResize)\n }\n\n this.$off('anchors:all:paint')\n\n if (this.Observer) {\n document.querySelectorAll(selector).forEach((section) => {\n this.Observer.unobserve(section)\n })\n }\n\n return this\n }\n}\n\nChapters.DEFAULTS = {\n parentElement: '',\n scrollElement: '',\n selector: '.outline-heading',\n active: 0,\n closed: false,\n showCode: true,\n animationCurrent: true,\n position: 'relative',\n stickyHeight: 0,\n chapters: [],\n created: null,\n mounted: null,\n afterClosed: null,\n afterOpened: null,\n afterScroll: null,\n beforeDestroy: null,\n afterDestroy: null,\n afterSticky: null\n}\n\nexport default Chapters\n","import createElement from './utils/dom/createElement'\nimport timeSlice from './utils/lang/timeSlice'\n\nconst _paintChapters = ($list, chapters, showCode = false) => {\n const LIMIT = 400\n const count = chapters.length\n const clones = [...chapters]\n const paint = (parts) => {\n const byId = (id) => $list.querySelector(`#${id}`)\n parts.forEach((chapter) => {\n const pid = chapter.pid\n const id = chapter.id\n const rel = chapter.rel\n const children = []\n const $text = createElement(\n 'span',\n {\n className: 'outline-chapters__text'\n },\n chapter.text\n )\n let $link\n let $code\n let $li\n let $subject\n let $chapter\n\n if (showCode) {\n $code = createElement(\n 'span',\n {\n className: 'outline-chapters__code',\n 'data-id': id\n },\n chapter.code\n )\n\n children.push($code)\n }\n\n children.push($text)\n\n $link = createElement(\n 'a',\n {\n id: `chapter__anchor-${id}`,\n className: 'outline-chapters__anchor',\n href: '#' + rel,\n rel: rel,\n 'data-id': id\n },\n children\n )\n\n $li = createElement(\n 'li',\n {\n id: `chapter-${id}`,\n className: 'outline-chapters__item',\n 'data-id': id\n },\n $link\n )\n\n if (pid === -1) {\n $list.appendChild($li)\n } else {\n $chapter = byId(`chapter-${pid}`)\n $subject = byId(`subject-${pid}`)\n\n if (!$subject) {\n $subject = createElement(\n 'ul',\n {\n id: 'subject-' + pid,\n className: 'outline-chapters__subject'\n },\n $li\n )\n\n $chapter.appendChild($subject)\n } else {\n $subject.appendChild($li)\n }\n }\n })\n }\n\n if (count > LIMIT) {\n // 同步绘制\n paint(clones.splice(0, LIMIT))\n // 剩余的采用 timeSlice 机制绘制\n while (clones.length > 0) {\n const once = clones.splice(0, LIMIT)\n timeSlice(() => {\n paint(once)\n })\n }\n } else {\n paint(clones)\n }\n}\n\nexport default _paintChapters\n","import easeInQuad from '../lang/easeInQuad'\nimport isFunction from '../types/isFunction'\nimport _getScrollElement from './_getScrollElement'\n\n/**\n * 指定 rootElement DOM 节点滚动到指定 top 位置\n * ========================================================================\n * @method scrollTo\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\n * @param {Number} top - (必须)滚动的 scrollTop 数值\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\n */\nconst scrollTo = (scrollElement, top, afterStop) => {\n const $scrollElement = _getScrollElement(scrollElement)\n let scrollTop = $scrollElement.scrollTop\n let step = 0\n const distance = top - scrollTop\n const MAX_HEIGHT = $scrollElement.scrollHeight\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\n const stop = (top) => {\n if (isFunction(afterStop)) {\n afterStop(top)\n }\n\n return false\n }\n const play = () => {\n step += 1\n\n // 向上滚动\n if (distance < 0) {\n scrollTop -= easeInQuad(step)\n $scrollElement.scrollTop = scrollTop\n\n if (scrollTop <= top) {\n $scrollElement.scrollTop = top\n return stop(top)\n }\n } else {\n scrollTop += easeInQuad(step)\n $scrollElement.scrollTop = scrollTop\n\n if (scrollTop >= MAX_TOP) {\n $scrollElement.scrollTop = MAX_TOP\n return stop(MAX_TOP)\n }\n }\n\n requestAnimationFrame(play)\n }\n\n requestAnimationFrame(play)\n}\n\nexport default scrollTo\n","import isFunction from '../types/isFunction'\nimport isElement from '../types/isElement'\n\n/**\n * 通用的 IntersectionObserver 观察者处理器\n * ========================================================================\n * @method intersection\n * @param {Function} fn\n * @param {Object} [props]\n * @param {Object|HTMLElement} [props.root]\n * @param {String} [props.selector]\n * @param {Object} [props.context]\n * @param {String} [props.attr]\n * @param {String} [props.rootMargin]\n */\nconst intersection = (fn, props = {}) => {\n const root = props.root || null\n const selector = props.selector || '.outline-heading'\n const context = props.context || null\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\n const options = {\n rootMargin: rootMargin\n }\n const Observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n if (entry.intersectionRatio > 0) {\n if (isFunction(fn)) {\n fn.call(context || entry.target, entry.target)\n }\n }\n })\n }, options)\n const $root = isElement(root) ? root : document\n\n if (root) {\n options.root = root\n }\n\n $root.querySelectorAll(selector).forEach((section) => {\n Observer.observe(section)\n })\n\n return Observer\n}\n\nexport default intersection\n","/**\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\n * ========================================================================\n * @method stop\n * @param {Event} evt - 事件对象\n *\n * @example\n * <div id=\"nav\" class=\"nav\">\n * <a id=\"service\" class=\"anchor\" href=\"https://www.yaohaixiao.com/serivce\">Service</a>\n * <a id=\"help\" class=\"anchor\" href=\"https://www.yaohaixiao.com/help\">Help</a>\n * </div>\n *\n * const $nav = document.querySelector('#nav')\n * const $service = document.querySelector('.anchor')\n *\n * on($nav, 'click', function(evt) {\n * console.log('你点击了导航栏')\n * })\n *\n * on($anchor, 'click', function(evt) {\n * console.log('tagName', this.tagName)\n *\n * // 工作台输出:'a'\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\n * stopEvent(evt)\n * })\n */\nconst stop = function (evt) {\n evt.stopPropagation()\n evt.preventDefault()\n}\n\nexport default stop\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","_subscribers","_hasDirectSubscribersFor","topic","length","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","data","async","execute","forEach","subscriber","message","indexOf","callback","context","deliver","setTimeout","guid","uuid","prefix","_removeSubscriber","off","token","keys","subject","execution","j","splice","_removeSubscriberByToken","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","arguments","destroy","removeListeners","reload","$emit","event","publish","$on","handler","push","subscribe","$off","unsubscribe","isElement","nodeName","tagName","nodeType","later","fn","delay","CAPTURE_EVENTS","_off","el","type","capture","_delegateListener","listeners","_listeners","index","listener","i","_delete","removeEventListener","purgeElement","recurse","$element","document","querySelector","$children","childNodes","filter","getListeners","$child","at","once","evt","overrideContext","addEventListener","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","on","target","getTarget","delegateTarget","ctx","includeCTX","startsWith","closest","isArray","Array","isDOM","isHTMLCollection","fragment","isTextNode","createElement","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","toLowerCase","style","cssText","setAttribute","className","innerHTML","innerText","setAttributes","every","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","querySelectorAll","scrollTop","hasClass","pattern","RegExp","allClass","classList","contains","exec","addClass","add","removeClass","remove","offsetTop","top","offsetParent","getStyle","ruleName","getComputedStyle","setProperty","documentElement","cloneDeep","clone","from","assign","key","queue","isHandling","done","runIdle","idleDeadline","timeRemaining","shift","requestIdleCallback","window","cb","start","Date","now","didTimeout","Math","max","cancelIdleCallback","id","clearTimeout","timeSlice","afterComplete","Chapters","super","DEFAULTS","_init","scrollTimer","resizeTimer","observerTimer","Observer","$title","$main","$list","$placeholder","$parentElement","$active","chapters","active","offsetWidth","playing","closed","created","parentElement","$parent","isClosed","isSticky","isFixed","isInside","isOutside","count","_paintEdge","title","animationCurrent","customClass","contents","calculateStickyHeight","showCode","mounted","clones","paint","parts","byId","chapter","pid","rel","$text","text","$link","$code","$li","$subject","$chapter","code","href","_paintChapters","highlight","sticky","onObserver","positionPlaceholder","$anchor","mainPaddingTop","parseInt","mainBorderTop","placeholderPaddingTop","placeholderMarginTop","placeholderBorderTop","height","offsetHeight","ACTIVE","HIGHLIGHT","getAttribute","afterSticky","FIXED","isStickying","clientHeight","innerHeight","scrollTo","after","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","show","HIDDEN","opened","hide","toggle","afterToggle","beforeDestroy","afterDestroy","removeChild","props","root","rootMargin","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","$heading","onSelect","stickyHeight","headingId","split","afterScroll","min","stopPropagation","preventDefault","onScroll","onResize","unobserve","afterClosed","afterOpened"],"mappings":"yOAOA,MAAMA,EAAYC,GACM,iBAARA,ECAVC,EAAS,CAACC,EAAKC,KACnB,MAAMC,EAAiBC,OAAOC,UAAUF,eACxC,OAAOF,GAAOE,EAAeG,KAAKL,EAAKC,EAAI,ECHvCK,EAAYC,GACTJ,OAAOC,UAAUE,SAASE,MAAMD,GCCnCE,EAAcF,GACI,mBAARA,GAAwC,sBAAlBD,EAASC,GCAzCG,EAAYC,IAEG,oBAAhBL,EAASK,IACK,iBAANA,GACPF,EAAWE,KACP,OAANA,ECTEC,EAAe,CAAA,ECIfC,EAA4BC,GACzBf,EAAOa,EAAcE,IAAUF,EAAaE,GAAOC,OAAS,ECA/DC,EAAM,CAACF,EAAOG,GAAW,IACtBA,EAAWJ,EAAyBC,GCHrB,CAACA,IACvB,IAAII,EAAQL,EAAyBC,GACjCK,EAAWL,EAAMM,YAAY,KAEjC,MAAQF,IAAuB,IAAdC,GAEfA,GADAL,EAAQA,EAAMO,UAAU,EAAGF,IACVC,YAAY,KAC7BF,EAAQL,EAAyBC,GAGnC,OAAOI,GDP6CI,CAAgBR,GEGhES,EAAO,CAACT,EAAOU,EAAMC,GAAQ,KACjC,MAAMC,EAAWZ,IACf,IAAKD,EAAyBC,GAC5B,OAAO,EAGTF,EAAaE,GAAOa,SAASC,IAG3B,MAAMC,EChBI,CACZ,qBACA,sBACA,6BACA,sBACA,uBACA,sBACA,uBACA,wBACA,wBACA,yBACA,2BAGWC,QAAQxB,EDEYkB,KCFM,EDEEA,EAAKlB,WAAakB,EAEvDI,EAAWG,SAAS1B,KAAKuB,EAAWI,SAAWJ,EAAYC,EAAQ,GACnE,EAEEI,EAAU,KACd,IAAIL,EAAad,EACbK,EAAWL,EAAMM,YAAY,KAEjC,MAAqB,IAAdD,GACLS,EAAaA,EAAWP,UAAU,EAAGF,GACrCA,EAAWS,EAAWR,YAAY,KAElCM,EAAQE,GAIVF,EAAQZ,GAERY,EAAQ,IAAI,EAGd,IAAKV,EAAIF,GACP,OAAO,EAGLW,EACFS,WAAWD,EAAS,IAEpBA,GACD,EE/CGE,EAAO,MACX,IAAIC,EAAO,EAEX,OAAQC,IACND,GAAQ,EAEDC,EAASA,EAAS,IAAMD,EAAO,QAAUA,EAEnD,EARY,GCGPE,EAAqBxB,IACzB,IAAKf,EAAOa,EAAcE,GACxB,OAAO,SAGFF,EAAaE,EAAM,ECJtByB,EAAM,CAACzB,EAAO0B,KAClB,IAAKxB,EAAIF,GACP,OAAO,EAGL0B,ECL2B,CAACA,IAChC,MAAMC,EAAOtC,OAAOsC,KAAK7B,GAGzB,IAAK4B,GAASC,EAAK1B,OAAS,EAC1B,OAAO,EAGT0B,EAAKd,SAASe,IACZ,MAAMd,EAAahB,EAAa8B,GAChC,IAAI5B,EAEJc,EAAWD,SAAQ,CAACgB,EAAWC,KACzBD,EAAUZ,WAAaS,GAASG,EAAUH,QAAUA,IACtD1B,EAAQ6B,EAAU7B,MAClBc,EAAWiB,QAbL,EAamBD,GAC1B,IAIChB,EAAWb,OAAS,GACtBuB,EAAkBxB,EACnB,GACD,EDjBAgC,CAAyBN,GAEzBF,EAAkBxB,EACnB,EEZH,MAAMiC,EACJC,YAAYC,GACVC,KAAKC,MAAQ,CAAE,EAEXF,GACFC,KAAKE,WAAWH,EAEnB,CAEDG,WAAWH,GAET,OADAC,KAAKG,KAAKJ,GAASK,SAASC,eACrBL,IACR,CAEDG,KAAKpD,EAAMuD,GACT,MAAML,EAAQD,KAAKC,MAEnB,OAAItD,EAASI,GAEPuD,GAASzD,EAAOoD,EAAOlD,IAEzBkD,EAAMlD,GAAQuD,EACPN,MAIFC,EAAMlD,GACJS,EAAST,IC1BRwD,ED4BHN,EC5BWO,ED4BJzD,EC3BLE,OAAOsC,KAAKiB,GAEpB/B,SAAS1B,IACRF,EAAO2D,EAAQzD,KACjBwD,EAAOxD,GAAQyD,EAAOzD,GACvB,IDwBQiD,MACuB,IAArBS,UAAU5C,OAEZoC,EAGFD,KCpCI,IAACO,EAAQC,CDqCrB,CAEDJ,SACE,OAAOJ,IACR,CAEDU,UAEE,OADAV,KAAKW,kBACEX,IACR,CAEDY,OAAOb,GAEL,OADAC,KAAKU,UAAUR,WAAWH,GACnBC,IACR,CAEDa,MAAMC,EAAOxC,GAEX,OADAyC,EAAQD,EAAOxC,GACR0B,IACR,CAEDgB,IAAIF,EAAOjC,GAET,MExDO,EAACjB,EAAOqD,EAASnC,EAAU,QACpC,MAAMQ,EAAQL,IACd,IAAIO,EAA2B,iBAAV5B,EAAqBA,EAAMR,WAAaQ,EAExDL,EAAW0D,KAKXvD,EAAa8B,KAChB9B,EAAa8B,GAAW,IAG1B9B,EAAa8B,GAAS0B,KAAK,CACzBtD,MAAO4B,EACPX,SAAUoC,EACVnC,UACAQ,UAGKA,EFmCL6B,CAAUL,EAAOjC,EAAUmB,MACpBA,IACR,CAEDoB,KAAKN,EAAOjC,GAEV,OADAwC,EAAYP,EAAOjC,GACZmB,IACR,CAEDK,eACE,OAAOL,IACR,CAEDW,kBACE,OAAOX,IACR,EG1EH,MAAMsB,EAAa7D,MACPD,EAASC,IAAMA,EAAE8D,UAAY9D,EAAE+D,SAA0B,IAAf/D,EAAEgE,UCAlDC,EAAQ,CAACC,EAAIC,EAAQ,QACpBrE,EAAWoE,IAIT3C,YAAW,KAChB2C,GAAI,GACHC,GCjBQC,EAAiB,CAC5B,WACA,OACA,UACA,QACA,OACA,SACA,aACA,cCMIC,EAAO,CAACC,EAAIC,EAAML,KACtB,MAAMM,EAAUJ,EAAejD,QAAQoD,IAAS,EAG5CL,EAAGO,0BACLP,EAAKA,EAAGO,mBACEA,kBCZE,SAAUH,EAAIC,EAAML,GAClC,MAAMQ,EAAYJ,EAAGK,WACrB,IAAIC,GAAS,EAEb,GAAIF,EAAUtE,OAAS,EACrB,OAAO,EAITsE,EAAU1D,SAAQ,CAAC6D,EAAUC,KAC3B,MAAMtB,EAAUqB,EAASX,GAErBK,IAASM,EAASN,OACpBK,EAAQE,EAEJtB,IAAYU,IACdU,EAAQE,GAEX,IAICF,GAAS,GACXF,EAAUxC,OAAO0C,EAAO,EAE5B,CDTEG,CAAQT,EAAIC,EAAML,GAElBI,EAAGU,oBAAoBT,EAAML,EAAIM,EAAQ,EEVrCS,EAAe,SAAUX,EAAIC,EAAMW,GAAU,GACjD,MAAMC,EAAWjG,EAASoF,GAAMc,SAASC,cAAcf,GAAMA,EACvDgB,EAAYH,EAASI,WACrBb,ECPa,EAACJ,EAAIC,KACxB,IAAIG,EAAYJ,EAAGK,YAAc,GAQjC,OANIzF,EAASqF,IAASA,IACpBG,EAAYA,EAAUc,QAAQX,GACrBA,EAASN,OAASA,KAItBG,GDFWe,CAAaN,EAAUZ,GAEzCG,EAAU1D,SAAS6D,IACjBR,EAAKc,EAAUN,EAASN,KAAMM,EAASX,GAAG,KAIzCgB,IAAoB,IAATX,GAAsC,IAArBvB,UAAU5C,SACvC+E,GACAG,GAEAA,EAAUtE,SAAS0E,IACb7B,EAAU6B,IACZT,EAAaS,EAAQnB,EAAMW,EAC5B,GAGP,EEtBMtD,EAAM,CAAC0C,EAAIC,EAAML,KAErB,IAAKpE,EAAWoE,GACd,OAAOe,EAAaX,EAAIC,GAG1BF,EAAKC,EAAIC,EAAML,EAAG,ECHdyB,EAAK,CAACrB,EAAIC,EAAML,EAAIrD,EAAMQ,EAASuE,GAAO,KAE9C,MAAMpB,EAAUJ,EAAejD,QAAQoD,IAAS,EAC1CM,EAAW,SAAUgB,GACzB,IAAIC,EAAkBzE,GAAWiD,GAIjB,IAAZjD,IACFyE,EAAkBjF,IAKP,IAAT+E,GACFhE,EAAI0C,EAAIC,EAAMM,GAGhBX,EAAGxE,KAAKoG,EAAiBD,EAAKhF,EAC/B,EAED,IAAKf,EAAWoE,GACd,OAAO,EAGJI,EAAGK,aACNL,EAAGK,WAAa,IAIlBL,EAAGK,WAAWlB,KAAK,CACjBa,KACAC,OACAL,GAAIW,EACJhE,OACAQ,UACAmD,YAIFN,EAAGO,kBAAoBI,EAEvBP,EAAGyB,iBAAiBxB,EAAMM,EAAUL,EAAQ,EC9CxCwB,EAAU,CAAC1B,EAAI2B,EAAW,MAC9B,MAAMC,EAAMD,EAASE,QAAQ,MAAO,IAEpC,SAAKF,GAAaC,GAAQ5B,KAKtBA,EAAG0B,QACE1B,EAAG0B,QAAQE,KACT5B,EAAG8B,mBACL9B,EAAG8B,kBAAkBF,GAG7B,ECpBGG,EAAmB/B,GAChBA,EAAGgC,MAAQhC,IAAOc,UAAYd,EAAGgC,KAAKtC,SACzCM,EAAGgC,KACHhC,EAAGiC,WCSHC,EAAK,CAAClC,EAAI2B,EAAU1B,EAAML,EAAIrD,EAAMQ,EAASuE,GAAO,KAExD,MAAMpB,EAAUJ,EAAejD,QAAQoD,IAAS,EAE1CM,EAAW,SAAUgB,GACzB,MAAMY,ECfQ,SAAUZ,GAC1B,MAAMY,EAASZ,EAAIY,OAEnB,OCJgCnC,EDITmC,ICHG,IAAhBnC,EAAGN,SACJM,EAAGiC,WAGLjC,EALe,IAAUA,CDKlC,CDWmBoC,CAAUb,GAEnBc,EGbM,EAACrC,EAAI2B,EAAUW,EAAKC,KAClC,MAAMxF,EAAUuF,GAAOxB,SAEvB,IAAKd,EACH,OAAO,KAGT,EAAG,CAED,GACe,MAAZ2B,IACEA,EAASa,WAAW,KACjBxC,EAAGiC,aAAelF,GAAW2E,EAAQ1B,EAAI2B,GACzCD,EAAQ1B,EAAI2B,KACjBY,GAAcvC,IAAOjD,EAEtB,OAAOiD,EAIT,GAAIA,IAAOjD,EACT,KAIN,OAAYiD,EAAK+B,EAAgB/B,GAAK,EHZXyC,CAAQN,EAAQR,EAAU3B,GACjD,IAAIwB,EAAkBzE,GAAWiD,EAEjCuB,EAAIc,eAAiBA,GAIL,IAAZtF,IACFyE,EAAkBjF,GAIhB8F,KAGW,IAATf,GACFhE,EAAI0C,EAAIC,EAAMM,GAGhBX,EAAGxE,KAAKoG,EAAiBD,EAAKhF,GAEjC,EAEIyD,EAAGK,aACNL,EAAGK,WAAa,IAIlBL,EAAGK,WAAWlB,KAAK,CACjBa,KACA2B,WACA1B,OACAL,GAAIW,EACJhE,OACAQ,UACAmD,YAIFN,EAAGO,kBAAoBI,EAEvBP,EAAGyB,iBAAiBxB,EAAMM,EAAUL,EAAQ,EI1DxCwC,EAAWhH,GACXiH,MAAMD,QACDC,MAAMD,QAAQhH,GAEE,mBAAhBL,EAASK,GCPdkH,EAAS5C,IACb,SACEvE,EAASuE,MACRT,EAAUS,ICNU,CAACA,MACdvE,EAASuE,IAAwB,sBAAjB3E,EAAS2E,IDKf6C,CAAiB7C,KENnB8C,EFMqC9C,EEJrDvE,EAASqH,IAAoC,8BAAvBzH,EAASyH,KCFhB,CAAC9C,MAEhBvE,EAASuE,MACS,kBAAjB3E,EAAS2E,IAA4BA,EAAGP,SAA2B,IAAhBO,EAAGN,WHGKqD,CAAW/C,KENxD,IAAC8C,CFOjB,EIKGE,EAAgB,CAACvD,EAASvB,EAAO+E,KACrC,MAAMC,EAAYpC,SAASqC,yBACrBC,EAAMtC,SAASkC,cAAcvD,GAC7B4D,EAAgBC,GACbV,EAAMU,IAAU1I,EAAS0I,GAE5BC,EAAUD,IACd,IAAIlC,EAEJ,IAAKiC,EAAaC,GAChB,OAAO,EAGLV,EAAMU,GACRlC,EAASkC,EACA1I,EAAS0I,KAClBlC,EAASN,SAAS0C,eAAeF,IAGnCJ,EAAUO,YAAYrC,EAAO,EAyB/B,OAtBI3F,EAASyC,GCjCO,EAAC8B,EAAI9B,KACzB,IAAK8B,IAAOvE,EAASyC,GACnB,OAAO,EAGThD,OAAOsC,KAAKU,GAAOxB,SAAS0B,IAC1B,MAAMG,EAAQL,EAAME,GAChBtD,EAAOoD,EAAOE,ICHD,EAAC4B,EAAI5B,EAAMG,KAC9B,IAAIkB,EAAUO,EAAGP,QAAQiE,cAEzB,OAAQtF,GACN,IAAK,QACH4B,EAAG2D,MAAMC,QAAUrF,EACnB,MACF,IAAK,QACa,UAAZkB,GAAmC,aAAZA,EACzBO,EAAGzB,MAAQA,EAEXyB,EAAG6D,aAAazF,EAAMG,GAExB,MACF,IAAK,UACHyB,EAAG6D,aAAa,MAAOtF,GACvB,MACF,IAAK,YACHyB,EAAG8D,UAAYvF,EACf,MACF,IAAK,YACHyB,EAAG+D,UAAYxF,EACf,MACF,IAAK,YACHyB,EAAGgE,UAAYzF,EACf,MACF,QACEyB,EAAG6D,aAAazF,EAAMG,GAEzB,EDzBGsF,CAAa7D,EAAI5B,EAAMG,EACxB,GACD,EDwBA0F,CAAcb,EAAKlF,GACVwE,EAAQxE,IAAUA,EAAMgG,OAAO9F,GAASiF,EAAajF,KAC9DF,EAAMxB,SAAS4G,IACbC,EAAOD,EAAM,IAENV,EAAM1E,GACfqF,EAAOrF,GACEtD,EAASsD,IAClBqF,EAAOzC,SAAS0C,eAAetF,IAG7BwE,EAAQO,GACVA,EAASvG,SAAS4G,IAChBC,EAAOD,EAAM,IAGfC,EAAON,GAGTG,EAAIK,YAAYP,GAETE,GGpDHe,EAAcC,GACXA,EAAIA,ECGPC,EAAoB,CAACC,EAAgB,QACzC,IAAIC,EACAC,EAgBJ,OAdKF,EAOC1J,EAAS0J,GACXE,EAAiB1D,SAASC,cAAcuD,GAC/B/E,EAAU+E,KACnBE,EAAiBF,IATnBC,EAAgBzD,SAAS2D,iBAAiB,aAC1CD,EACED,EAAc,GAAGG,UAAYH,EAAc,GAAGG,WAAa,EACvDH,EAAc,GACdA,EAAc,IASfC,GCpBHG,EAAW,CAAC3E,EAAI8D,KACpB,MAAMc,EAAU,IAAIC,OAAO,UAAYf,EAAY,WACnD,IAAIgB,EACAC,EAEJ,QAAKxF,EAAUS,KAIf8E,EAAW9E,EAAG8D,YAETgB,IAILC,EAAY/E,EAAG+E,UAEXA,GAAWC,SACNhF,EAAG+E,UAAUC,SAASlB,KAGtBc,EAAQK,KAAKH,IAAQ,ECpB1BI,EAAW,CAAClF,EAAI8D,KACpB,IAAIiB,EACAD,EAEJ,GAAIH,EAAS3E,EAAI8D,GACf,OAAO,EAGTiB,EAAY/E,EAAG+E,UAEXA,GAAWI,IACbJ,EAAUI,IAAIrB,IAEdgB,EAAW9E,EAAG8D,UACdgB,GAAYA,EAAShJ,OAAS,EAAI,IAAMgI,EAAYA,EACpD9D,EAAG8D,UAAYgB,EAChB,ECfGM,EAAc,CAACpF,EAAI8D,KACvB,IACIiB,EADAD,EAAW9E,EAAG8D,UAGlB,IAAKgB,IAAaH,EAAS3E,EAAI8D,GAC7B,OAAO,ECPE,IAACjJ,EDUZkK,EAAY/E,EAAG+E,UAEXA,GAAWM,OACbN,EAAUM,OAAOvB,ICbPjJ,EDeMiK,EAASjD,QAAQiC,EAAW,IAA5CgB,ICdGlK,EAASC,IAGPA,EAAIgH,QAAQ,iBAAkB,IDYnC7B,EAAG8D,UAAYgB,EAChB,EEnBGQ,EAAatF,IACjB,IAAIuF,EAAMvF,EAAGsF,UAMb,OAJwB,OAApBtF,EAAGwF,eACLD,GAAOD,EAAUtF,EAAGwF,eAGfD,GCPHE,EAAW,CAACzF,EAAI0F,IACbC,iBAAiB3F,GAAI0F,GCRxBE,EAAc,CAAC5K,EAAMuD,KACDuC,SAAS+E,gBACjBlC,MAAMiC,YAAY5K,EAAMuD,EAAM,ECY1CuH,EAAa/K,IACjB,IAAIgL,EAAQ,CAAE,EAEd,OAAY,OAARhL,EACK,MAGL2H,EAAQ3H,GACVgL,EAAQpD,MAAMqD,KAAKjL,IAEnBgL,EAAQ7K,OAAO+K,OAAO,CAAA,EAAIlL,GAC1BG,OAAOsC,KAAKuI,GAAOrJ,SAASwJ,GAClBH,EAAMG,GAAOzK,EAASV,EAAImL,IAAQJ,EAAU/K,EAAImL,IAAQnL,EAAImL,MAIjEH,ICrBHI,EAAQ,GACd,IAAIC,EACAC,EAqBJ,SAASC,EAAQC,GACf,KAAOA,EAAaC,gBAAkB,GAAKL,EAAMrK,QAAQ,CACvD,MAAM8D,EAAKuG,EAAMM,QAEjB,IAAKjL,EAAWoE,GACd,OAAO,EAGTA,GACD,CAEGuG,EAAMrK,OACRsK,EAAaM,oBAAoBJ,IAEjCF,EAAa,EAET5K,EAAW6K,KACbA,IACAA,EAAO,MAGb,MAvC0C,IAA/BM,OAAOD,sBAChBC,OAAOD,oBAAsB,SAAUE,GACrC,MAAMC,EAAQC,KAAKC,MACnB,OAAOpH,GAAM,WACXiH,EAAG,CACDI,YAAY,EACZR,cAAe,WACb,OAAOS,KAAKC,IAAI,EAAG,IAAMJ,KAAKC,MAAQF,GACvC,GAEJ,GAAE,GACJ,EAEDF,OAAOQ,mBAAqB,SAAUC,GACpCC,aAAaD,EACd,GAkCH,MAAME,EAAY,CAAC1H,EAAI2H,EAAgB,QACrCpB,EAAMhH,KAAKS,GAEPpE,EAAW+L,KACblB,EAAOkB,GAGJnB,GACHM,oBAAoBJ,EACrB,ECjDH,MAAMkB,UAAiB1J,EACrBC,YAAYC,GACVyJ,QAEAxJ,KAAKC,MAAQ4H,EAAU0B,EAASE,UAEhCzJ,KAAK0J,QAEL1J,KAAK2J,YAAc,KACnB3J,KAAK4J,YAAc,KACnB5J,KAAK6J,cAAgB,KACrB7J,KAAK8J,SAAW,KAEZ/J,GACFC,KAAKE,WAAWH,EAEnB,CAED2J,QAiBE,OAhBA1J,KAAKmF,IAAM,KACXnF,KAAK+J,OAAS,KACd/J,KAAKgK,MAAQ,KACbhK,KAAKiK,MAAQ,KACbjK,KAAKkK,aAAe,KACpBlK,KAAKmK,eAAiB,KACtBnK,KAAKuG,eAAiB,KACtBvG,KAAKoK,QAAU,KAEfpK,KAAKqK,SAAW,GAChBrK,KAAKsK,OAAS,EACdtK,KAAKuK,YAAc,EACnBvK,KAAKqH,UAAY,EACjBrH,KAAKwK,SAAU,EACfxK,KAAKyK,QAAS,EAEPzK,IACR,CAEDE,WAAWH,GACT,IAAI2K,EACAC,EACAtE,EACAuE,EAuBJ,OArBA5K,KAAKG,KAAKJ,GACV2K,EAAU1K,KAAKG,KAAK,WACpBwK,EAAgB3K,KAAKG,KAAK,iBAC1BkG,EAAgBrG,KAAKG,KAAK,iBAEtBxD,EAASgO,GACXC,EAAU/H,SAASC,cAAc6H,GACxBrJ,EAAUqJ,KACnBC,EAAUD,GAEZ3K,KAAKmK,eAAiBS,EACtB5K,KAAKuG,eAAiBH,EAAkBC,GAExCrG,KAAKqK,SAAWrK,KAAKG,KAAK,YAC1BH,KAAKyK,OAASzK,KAAKG,KAAK,UACxBH,KAAKsK,OAAStK,KAAKG,KAAK,UAEpB5C,EAAWmN,IACbA,EAAQvN,KAAK6C,MAGXA,KAAKqK,SAASxM,OAAS,IAI3BmC,KAAKI,SAASC,eAEdL,KAAKoK,QAAUvH,SAASC,cAAc,YAAY9C,KAAKsK,WAL9CtK,IAQV,CAED6K,WACE,OAAO7K,KAAKyK,MACb,CAEDK,WAEE,MAAoB,WADH9K,KAAKG,KAAK,WAE5B,CAED4K,UAEE,MAAoB,UADH/K,KAAKG,KAAK,WAE5B,CAED6K,WACE,OAAOhL,KAAK+K,WAAa/K,KAAK8K,UAC/B,CAEDG,YACE,OAAQjL,KAAKgL,UACd,CAEDE,QACE,OAAOlL,KAAKqK,SAASxM,MACtB,CAEDsN,aACE,MAAMlG,EAAYpC,SAASqC,yBAGrBkG,EAAQpL,KAAKG,KAAK,SAClBkL,EAAmBrL,KAAKG,KAAK,oBAC7BmL,EAActL,KAAKG,KAAK,eACxBgK,EAAiBnK,KAAKmK,eACtBnF,EAAW,GACXuG,EAAW,GACjB,IACIpG,EACA6E,EACAC,EACAC,EAJAH,EAAS,KAMb,OAAKI,GAIDnK,KAAKgL,YAAcI,IACrBrB,EAAShF,EACP,KACA,CACEc,UAAW,2BAEbuF,GAEFpL,KAAK+J,OAASA,EACdwB,EAASrK,KAAK6I,IAGhBE,EAAQlF,EAAc,KAAM,CAI1Bc,UAAW,2BAEb7F,KAAKiK,MAAQA,EACbjF,EAAS9D,KAAK+I,GAEVoB,IACFnB,EAAenF,EAAc,MAAO,CAClCc,UAAW,kCAEb7F,KAAKkK,aAAeA,EACpBlF,EAAS9D,KAAKgJ,IAGhBF,EAAQjF,EACN,MACA,CACEc,UAAW,0BAEbb,GAEFhF,KAAKgK,MAAQA,EACbuB,EAASrK,KAAK8I,GAEd7E,EAAMJ,EACJ,MACA,CACEoE,GAAI,mBACJtD,UAAW,4CAEb0F,GAEFvL,KAAKmF,IAAMA,EAEPnF,KAAK8K,aACP9K,KAAKwL,wBACLvE,EAAS9B,EArEI,4BAwEXmG,GACFrE,EAAS9B,EAAKmG,GAEhBrG,EAAUO,YAAYL,GACtBgF,EAAe3E,YAAYP,GAEpBjF,MA/DEA,IAgEV,CAEDI,SACE,MACMqL,EAAWzL,KAAKG,KAAK,YACrBuL,EAAU1L,KAAKG,KAAK,WACpBgK,EAAiBnK,KAAKmK,eACtBE,EAAWrK,KAAKqK,SAChBa,EAAQlL,KAAKkL,QACnB,IAAI/F,EACA8E,EAEJ,OAAKE,GAAkBE,EAASxM,OAAS,IAIrCmC,KAAKgL,YACP/D,EAASkD,EAAgB,2BAG3BnK,KAAKmL,aAELhG,EAAMnF,KAAKmF,IACX8E,EAAQjK,KAAKiK,MClOM,EAACA,EAAOI,EAAUoB,GAAW,KAClD,MACMP,EAAQb,EAASxM,OACjB8N,EAAS,IAAItB,GACbuB,EAASC,IACb,MAAMC,EAAQ3C,GAAOc,EAAMnH,cAAc,IAAIqG,KAC7C0C,EAAMpN,SAASsN,IACb,MAAMC,EAAMD,EAAQC,IACd7C,EAAK4C,EAAQ5C,GACb8C,EAAMF,EAAQE,IACdjH,EAAW,GACXkH,EAAQnH,EACZ,OACA,CACEc,UAAW,0BAEbkG,EAAQI,MAEV,IAAIC,EACAC,EACAC,EACAC,EACAC,EAEAf,IACFY,EAAQtH,EACN,OACA,CACEc,UAAW,yBACX,UAAWsD,GAEb4C,EAAQU,MAGVzH,EAAS9D,KAAKmL,IAGhBrH,EAAS9D,KAAKgL,GAEdE,EAAQrH,EACN,IACA,CACEoE,GAAI,mBAAmBA,IACvBtD,UAAW,2BACX6G,KAAM,IAAMT,EACZA,IAAKA,EACL,UAAW9C,GAEbnE,GAGFsH,EAAMvH,EACJ,KACA,CACEoE,GAAI,WAAWA,IACftD,UAAW,yBACX,UAAWsD,GAEbiD,IAGW,IAATJ,EACF/B,EAAMzE,YAAY8G,IAElBE,EAAWV,EAAK,WAAWE,KAC3BO,EAAWT,EAAK,WAAWE,KAEtBO,EAYHA,EAAS/G,YAAY8G,IAXrBC,EAAWxH,EACT,KACA,CACEoE,GAAI,WAAa6C,EACjBnG,UAAW,6BAEbyG,GAGFE,EAAShH,YAAY+G,IAIxB,GACD,EAGJ,GAAIrB,EApFU,IAwFZ,IAFAU,EAAMD,EAAOhM,OAAO,EAtFR,MAwFLgM,EAAO9N,OAAS,GAAG,CACxB,MAAMwF,EAAOsI,EAAOhM,OAAO,EAzFjB,KA0FV0J,GAAU,KACRuC,EAAMvI,EAAK,GAEd,MAEDuI,EAAMD,EACP,EDkICgB,CAAe1C,EAAOI,EAAUoB,GAChCtE,EAAYhC,EAtBG,2BAwBfzD,GAAM,KACJ1B,KAAK4M,UAAU5M,KAAKsK,OAAO,GAC1B,IAEHtK,KAAKqH,UAAYA,EAAUlC,GAC3BnF,KAAKuK,YAAcpF,EAAIoF,YAEnBvK,KAAK+K,YACP/K,KAAK6M,SACLlF,EAAY,2BAA4B,GAAG3H,KAAKuK,kBAG9ChN,EAAWmO,IACbA,EAAQvO,KAAK6C,MAGXkL,EAAQ,KACVlL,KAAK8M,cA/BE9M,IAmCV,CAED+M,oBAAoB1K,GAClB,MAAM2H,EAAQhK,KAAKgK,MACbC,EAAQjK,KAAKiK,MACbC,EAAelK,KAAKkK,aACpB8C,EAAU/C,EAAMnH,cAAc,6BAC9BuI,EAAmBrL,KAAKG,KAAK,oBAC7B8M,EAAiBC,SAAS1F,EAASwC,EAAO,eAAgB,IAC1DmD,EAAgBD,SAAS1F,EAASwC,EAAO,oBAAqB,IAC9DoD,EAAwBF,SAAS1F,EAASyC,EAAO,eAAgB,IACjEoD,EAAuBH,SAAS1F,EAASyC,EAAO,cAAe,IAC/DqD,EAAuBJ,SAC3B1F,EAASyC,EAAO,oBAChB,IAEF,IAEI3C,EAFAiG,EAASP,EAAQQ,aACjBnG,EAAY,EAGhB,OAAKgE,GAID4B,IACF5F,GAAa4F,GAGXG,IACF/F,GAAa+F,GAGXC,IACFhG,GAAagG,GAGXF,IACF9F,GAAa8F,GAGXG,IACFjG,GAAaiG,GAGfhG,EAAMiG,EAASlL,EACf6H,EAAaxE,MAAMC,QAAU,yBAC3B0B,EAAYC,eACAiG,OAEPvN,MA5BEA,IA6BV,CAED4M,UAAUzD,GACR,MAAMhE,EAAMnF,KAAKmF,IACXkG,EAAmBrL,KAAKG,KAAK,oBAC7BsN,EAAS,0BACTC,EAAY,6BAClB,IAAIV,EAAU,KAEd,OAAK7H,GAIL6H,EAAU7H,EAAIrC,cAAc,oBAAoBqG,KAE3C6D,GAILhN,KAAKsK,OAAS4C,SAASF,EAAQW,aAAa,WAAY,IAEpD3N,KAAKoK,UACPjD,EAAYnH,KAAKoK,QAASsD,GAC1BvG,EAAYnH,KAAKoK,QAASqD,IAG5BzN,KAAKoK,QAAU4C,EACf/F,EAASjH,KAAKoK,QAASqD,GAEnBpC,EACFrL,KAAK+M,oBAAoB/M,KAAKsK,QAE9BrD,EAASjH,KAAKoK,QAASsD,GAGlB1N,MAnBEA,MANAA,IA0BV,CAED6M,SACE,MAAMe,EAAc5N,KAAKG,KAAK,eACxB0N,EAAQ,yBACR1I,EAAMnF,KAAKmF,IACXmC,EAAMtH,KAAKqH,UACXZ,EAAYzG,KAAKuG,eAAeE,UACtC,IAAIqH,EAEJ,OAAK9N,KAAK+K,WAIV+C,EAAcrH,GAAaa,EAEvBwG,EACF7G,EAAS9B,EAAK0I,GAEd1G,EAAYhC,EAAK0I,GAGftQ,EAAWqQ,IACbA,EAAYzQ,KAAK6C,KAAMA,KAAK6K,WAAYiD,GAGnC9N,MAfEA,IAgBV,CAEDwL,wBACE,MAAM5D,EAAkB/E,SAAS+E,gBAC3B2F,EAASvE,KAAKC,IAClBrB,EAAgBmG,cAAgB,EAChCrF,OAAOsF,aAAe,GAGxB,OADArG,EAAY,0BAA2B,GAAG4F,OACnCvN,IACR,CAEDiO,SAAS3G,EAAK4G,GAKZ,MEpXa,EAAC7H,EAAeiB,EAAK6G,KACpC,MAAM5H,EAAiBH,EAAkBC,GACzC,IAAII,EAAYF,EAAeE,UAC3B2H,EAAO,EACX,MAAMC,EAAW/G,EAAMb,EACjB6H,EAAa/H,EAAegI,aAC5BC,EAAUlH,EAAMgH,GAAc,EAAIhH,EAAMgH,EACxCG,EAAQnH,IACR/J,EAAW4Q,IACbA,EAAU7G,IAGL,GAEHoH,EAAO,KAIX,GAHAN,GAAQ,EAGJC,EAAW,GAIb,GAHA5H,GAAaP,EAAWkI,GACxB7H,EAAeE,UAAYA,EAEvBA,GAAaa,EAEf,OADAf,EAAeE,UAAYa,EACpBmH,EAAKnH,QAMd,GAHAb,GAAaP,EAAWkI,GACxB7H,EAAeE,UAAYA,EAEvBA,GAAa+H,EAEf,OADAjI,EAAeE,UAAY+H,EACpBC,EAAKD,GAIhBG,sBAAsBD,EAAK,EAG7BC,sBAAsBD,EAAK,EF2UzBT,CAFWjO,KAAKuG,eAEHe,EAAK4G,GAEXlO,IACR,CAED4O,OACE,MACMC,EAAS,0BACTC,EAAS9O,KAAKG,KAAK,eACnB+K,EAAQlL,KAAKkL,QACb/F,EAAMnF,KAAKmF,IACXyF,EAAU5K,KAAKmK,eAoBrB,OAlBInK,KAAKgL,WACHE,EAAQ,IACV/D,EAAYyD,EAASiE,IAErB1H,EAAYyD,EAASiE,GACrBnN,GAAM,KACJyF,EAAYyD,EAbH,0BAamB,GAC3B,KAGLzD,EAAYhC,EAAK0J,GAEnB7O,KAAKyK,QAAS,EAEVlN,EAAWuR,IACbA,EAAO3R,KAAK6C,MAGPA,IACR,CAED+O,OACE,MACMF,EAAS,0BACTpE,EAASzK,KAAKG,KAAK,eACnB+K,EAAQlL,KAAKkL,QACb/F,EAAMnF,KAAKmF,IACXyF,EAAU5K,KAAKmK,eAoBrB,OAlBInK,KAAKgL,WACHE,EAAQ,IACVjE,EAAS2D,EAASiE,IAElB5H,EAAS2D,EAXE,2BAYXlJ,GAAM,KACJuF,EAAS2D,EAASiE,EAAO,KAI7B5H,EAAS9B,EAAK0J,GAEhB7O,KAAKyK,QAAS,EAEVlN,EAAWkN,IACbA,EAAOtN,KAAK6C,MAGPA,IACR,CAEDgP,SACE,MAAMC,EAAcjP,KAAKG,KAAK,eACxBmH,EAAMtH,KAAKqH,UACXZ,EAAYzG,KAAKuG,eAAeE,UACtC,IAAIqH,EAeJ,OAbI9N,KAAK6K,WACP7K,KAAK4O,OAEL5O,KAAK+O,OAGHxR,EAAW0R,IACbvN,GAAM,KACJoM,EAAcrH,GAAaa,EAC3B2H,EAAY9R,KAAK6C,KAAMA,KAAK6K,WAAYiD,EAAY,IAIjD9N,IACR,CAEDU,UACE,MAAMwO,EAAgBlP,KAAKG,KAAK,iBAC1BgP,EAAenP,KAAKG,KAAK,gBAmC/B,OAjCI5C,EAAW2R,IACbA,EAAc/R,KAAK6C,MAGrBA,KAAKW,kBACLX,KAAKG,KAAKoJ,EAASE,UAEfzJ,KAAK2J,cACPP,aAAapJ,KAAK2J,aAClB3J,KAAK2J,YAAc,MAGjB3J,KAAK4J,cACPR,aAAapJ,KAAK4J,aAClB5J,KAAK4J,YAAc,MAGjB5J,KAAK6J,gBACPT,aAAapJ,KAAK6J,eAClB7J,KAAK6J,cAAgB,MAGnB7J,KAAK8J,WACP9J,KAAK8J,SAAW,MAGlB9J,KAAKmK,eAAeiF,YAAYpP,KAAKmF,KACrCnF,KAAK0J,QAEDnM,EAAW4R,IACbA,EAAahS,KAAK6C,MAGbA,IACR,CAED8M,aACE,MAAMpJ,EAAW1D,KAAKG,KAAK,YAwB3B,OAtBAH,KAAK8J,SG/eY,EAACnI,EAAI0N,EAAQ,MAChC,MAAMC,EAAOD,EAAMC,MAAQ,KACrB5L,EAAW2L,EAAM3L,UAAY,mBAC7B5E,EAAUuQ,EAAMvQ,SAAW,KAE3BiB,EAAU,CACdwP,WAFiBF,EAAME,YAAc,oBAIjCzF,EAAW,IAAI0F,sBAAsBC,IACzCA,EAAQhR,SAASiR,IACXA,EAAMC,kBAAoB,GACxBpS,EAAWoE,IACbA,EAAGxE,KAAK2B,GAAW4Q,EAAMxL,OAAQwL,EAAMxL,OAE1C,GACD,GACDnE,GACG6P,EAAQtO,EAAUgO,GAAQA,EAAOzM,SAUvC,OARIyM,IACFvP,EAAQuP,KAAOA,GAGjBM,EAAMpJ,iBAAiB9C,GAAUjF,SAASoR,IACxC/F,EAASgG,QAAQD,EAAQ,IAGpB/F,GHodWiG,EACbC,IACC,MAAM7G,EAAK6G,EAASrC,aAAa,WAEjC,GAAI3N,KAAKwK,QACP,OAAO,EAGLxK,KAAK6J,eACPT,aAAapJ,KAAK6J,eAGpB7J,KAAK6J,cAAgBnI,GAAM,KACzB1B,KAAK4M,UAAUzD,EAAG,GACjB,IAAI,GAET,CACEzF,WACA5E,QAASkB,OAINA,IACR,CAEDiQ,SAAS3M,GACP,MAAM4M,EAAelQ,KAAKG,KAAK,gBACzB6M,EAAU1J,EAAIc,eACd+E,EAAK6D,EAAQW,aAAa,WAC1BwC,EAAYnD,EAAQN,KAAK0D,MAAM,KAAK,GACpCJ,EAAWnN,SAASC,cAAc,IAAIqN,KACtC7I,EAAMD,EAAU2I,IAAaE,EAAe,IAE5CjH,EAAMjJ,KAAKuG,eAAegI,aAC1B8B,EAAcrQ,KAAKG,KAAK,eACxB+N,EAAQ,KACR3Q,EAAW8S,IACbA,EAAYlT,KAAK6C,KAAM,WAGzB0B,GAAM,KACJ1B,KAAKwK,SAAU,EACfxK,KAAKa,MAAM,iBAAkB,CAC3ByG,MACAgJ,IAZM,EAaNrH,OACA,GACF,EAiBJ,OAdAjJ,KAAKwK,SAAU,EACXxK,KAAK+K,WACP/K,KAAK6M,SACLnL,GAAM,KACJ1B,KAAKiO,SAAS3G,EAAK4G,GACnBlO,KAAK4M,UAAUzD,EAAG,GACjB,MAEHnJ,KAAKiO,SAAS3G,EAAK4G,GACnBlO,KAAK4M,UAAUzD,II7hBR,SAAU7F,GACrBA,EAAIiN,kBACJjN,EAAIkN,gBACN,CJ6hBI/B,CAAKnL,GAEEtD,IACR,CAEDyQ,WACE,MAAMlK,EAAiBvG,KAAKuG,eAsB5B,OApBIvG,KAAK2J,aACPP,aAAapJ,KAAK2J,aAGpB3J,KAAK2J,YAAcjI,GAAM,KACvB,MAAM4F,EAAMf,EAAeE,UAErBwC,EAAM1C,EAAegI,aAAehI,EAAewH,aAErD/N,KAAK+K,WACP/K,KAAK6M,SAGP7M,KAAKa,MAAM,iBAAkB,CAC3ByG,MACAgJ,IATU,EAUVrH,OACA,GACD,KAEIjJ,IACR,CAED0Q,WASE,OARI1Q,KAAK4J,aACPR,aAAapJ,KAAK4J,aAGpB5J,KAAK4J,YAAclI,GAAM,KACvB1B,KAAKwL,uBAAuB,IAGvBxL,IACR,CAEDK,eACE,MAAM8E,EAAMnF,KAAKmF,IACXoB,EAAiBvG,KAAKuG,eACtB/E,EAAU+E,EAAe/E,QAAQiE,cACvC,IAAI7C,EAAW2D,EAEf,OAAIvG,KAAKkL,QAAU,IAIH,SAAZ1J,GAAkC,SAAZA,IACxBoB,EAAW8F,QAGbzE,EAAGkB,EAAK,4BAA6B,QAASnF,KAAKiQ,SAAUjQ,MAAM,GACnEoD,EAAGR,EAAU,SAAU5C,KAAKyQ,SAAUzQ,MAAM,GACxCA,KAAK8K,YACP1H,EAAGsF,OAAQ,SAAU1I,KAAK0Q,SAAU1Q,MAAM,GAE5CA,KAAKgB,IAAI,oBAAqBhB,KAAK8M,WAAY9M,OAZtCA,IAeV,CAEDW,kBACE,MAAM+C,EAAW1D,KAAKG,KAAK,YACrBgF,EAAMnF,KAAKmF,IACXoB,EAAiBvG,KAAKuG,eACtB/E,EAAU+E,EAAe/E,QAAQiE,cACvC,IAAI7C,EAAW2D,EAEf,OAAIvG,KAAKkL,QAAU,IAIH,SAAZ1J,GAAkC,SAAZA,IACxBoB,EAAW8F,QAGbrJ,EAAI8F,EAAK,QAASnF,KAAKiQ,UACvB5Q,EAAIuD,EAAU,SAAU5C,KAAKyQ,UAEzBzQ,KAAK8K,YACP1H,EAAGsF,OAAQ,SAAU1I,KAAK0Q,UAG5B1Q,KAAKoB,KAAK,qBAENpB,KAAK8J,UACPjH,SAAS2D,iBAAiB9C,GAAUjF,SAASoR,IAC3C7P,KAAK8J,SAAS6G,UAAUd,EAAQ,KAlB3B7P,IAuBV,SAGHuJ,EAASE,SAAW,CAClBkB,cAAe,GACftE,cAAe,GACf3C,SAAU,mBACV4G,OAAQ,EACRG,QAAQ,EACRgB,UAAU,EACVJ,kBAAkB,EAClBpN,SAAU,WACViS,aAAc,EACd7F,SAAU,GACVK,QAAS,KACTgB,QAAS,KACTkF,YAAa,KACbC,YAAa,KACbR,YAAa,KACbnB,cAAe,KACfC,aAAc,KACdvB,YAAa"}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/ddal/outline.js.git
git@gitee.com:ddal/outline.js.git
ddal
outline.js
outline.js
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385