@vnpn/lucky-canvas-core 1.7.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/utils/polyfill.js","../src/utils/index.ts","../src/observer/dep.ts","../src/observer/utils.ts","../src/observer/array.ts","../src/observer/index.ts","../src/observer/watcher.ts","../src/lib/lucky.ts","../src/utils/math.ts","../src/utils/tween.ts","../src/lib/grid.ts","../src/lib/wheel.ts","../src/lib/slot.ts","../src/utils/image.ts"],"sourcesContent":["/**\n * 由于部分低版本下的某些 app 可能会缺少某些原型方法, 这里增加兼容\n */\n\n// ie11 不兼容 includes 方法\nif (!Array.prototype.includes) {\n Object.defineProperty(Array.prototype, 'includes', {\n value: function(valueToFind, fromIndex) {\n\n if (this == null) {\n throw new TypeError('\"this\" is null or not defined');\n }\n\n // 1. Let O be ? ToObject(this value).\n var o = Object(this);\n\n // 2. Let len be ? ToLength(? Get(O, \"length\")).\n var len = o.length >>> 0;\n\n // 3. If len is 0, return false.\n if (len === 0) {\n return false;\n }\n\n // 4. Let n be ? ToInteger(fromIndex).\n // (If fromIndex is undefined, this step produces the value 0.)\n var n = fromIndex | 0;\n\n // 5. If n ≥ 0, then\n // a. Let k be n.\n // 6. Else n < 0,\n // a. Let k be len + n.\n // b. If k < 0, let k be 0.\n var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);\n\n function sameValueZero(x, y) {\n return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));\n }\n\n // 7. Repeat, while k < len\n while (k < len) {\n // a. Let elementK be the result of ? Get(O, ! ToString(k)).\n // b. If SameValueZero(valueToFind, elementK) is true, return true.\n if (sameValueZero(o[k], valueToFind)) {\n return true;\n }\n // c. Increase k by 1.\n k++;\n }\n\n // 8. Return false\n return false;\n }\n });\n}\n\n// vivo x7 下网易云游戏 app 缺少 includes 方法\nif (!String.prototype.includes) {\n String.prototype.includes = function(search, start) {\n 'use strict';\n if (typeof start !== 'number') {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n } else {\n return this.indexOf(search, start) !== -1;\n }\n };\n}\n\n// vivo x7 下网易云游戏 app 缺少 find 方法\nif (!Array.prototype.find) {\n Object.defineProperty(Array.prototype, 'find', {\n value: function(predicate) {\n // 1. Let O be ? ToObject(this value).\n if (this == null) {\n throw new TypeError('\"this\" is null or not defined');\n }\n var o = Object(this);\n // 2. Let len be ? ToLength(? Get(O, \"length\")).\n var len = o.length >>> 0;\n // 3. If IsCallable(predicate) is false, throw a TypeError exception.\n if (typeof predicate !== 'function') {\n throw new TypeError('predicate must be a function');\n }\n // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.\n var thisArg = arguments[1];\n // 5. Let k be 0.\n var k = 0;\n // 6. Repeat, while k < len\n while (k < len) {\n // a. Let Pk be ! ToString(k).\n // b. Let kValue be ? Get(O, Pk).\n // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).\n // d. If testResult is true, return kValue.\n var kValue = o[k];\n if (predicate.call(thisArg, kValue, k, o)) {\n return kValue;\n }\n // e. Increase k by 1.\n k++;\n }\n // 7. Return undefined.\n return void 0;\n }\n });\n}\n","/**\n * 判断是否是期望的类型\n * @param { unknown } param 将要判断的变量\n * @param { ...string } types 期望的类型\n * @return { boolean } 返回期望是否正确\n */\nexport const isExpectType = (param: unknown, ...types: string[]): boolean => {\n return types.some(type => Object.prototype.toString.call(param).slice(8, -1).toLowerCase() === type)\n}\n\nexport const get = (data: object, strKeys: string) => {\n const keys = strKeys.split('.')\n for (let key of keys) {\n const res = data[key]\n if (!isExpectType(res, 'object', 'array')) return res\n data = res\n }\n return data\n}\n\nexport const has = (data: object, key: string | number): boolean => {\n return Object.prototype.hasOwnProperty.call(data, key)\n}\n\n/**\n * 移除\\n\n * @param { string } str 将要处理的字符串\n * @return { string } 返回新的字符串\n */\nexport const removeEnter = (str: string): string => {\n return [].filter.call(str, s => s !== '\\n').join('')\n}\n\n/**\n * 把任何数据类型转成数字\n * @param num \n */\nexport const getNumber = (num: unknown): number => {\n if (num === null) return 0\n if (typeof num === 'object') return NaN\n if (typeof num === 'number') return num\n if (typeof num === 'string') {\n if (num[num.length - 1] === '%') {\n return Number(num.slice(0, -1)) / 100\n }\n return Number(num)\n }\n return NaN\n}\n\n/**\n * 判断颜色是否有效 (透明色 === 无效)\n * @param color 颜色\n */\nexport const hasBackground = (color: string | undefined | null): boolean => {\n if (typeof color !== 'string') return false\n color = color.toLocaleLowerCase().trim()\n if (color === 'transparent') return false\n if (/^rgba/.test(color)) {\n const alpha = /([^\\s,]+)\\)$/.exec(color)\n if (getNumber(alpha) === 0) return false\n }\n return true\n}\n\n/**\n * 通过padding计算\n * @return { object } block 边框信息\n */\nexport const computePadding = (\n block: { padding?: string },\n getLength: Function\n): [number, number, number, number] => {\n let padding = block.padding?.split(' ').map(n => getLength(n)) || [0],\n paddingTop = 0,\n paddingBottom = 0,\n paddingLeft = 0,\n paddingRight = 0\n switch (padding.length) {\n case 1:\n paddingTop = paddingBottom = paddingLeft = paddingRight = padding[0]\n break\n case 2:\n paddingTop = paddingBottom = padding[0]\n paddingLeft = paddingRight = padding[1]\n break\n case 3:\n paddingTop = padding[0]\n paddingLeft = paddingRight = padding[1]\n paddingBottom = padding[2]\n break\n default:\n paddingTop = padding[0]\n paddingBottom = padding[1]\n paddingLeft = padding[2]\n paddingRight = padding[3]\n }\n // 检查是否单独传入值, 并且不是0\n const res = { paddingTop, paddingBottom, paddingLeft, paddingRight }\n for (let key in res) {\n // 是否含有这个属性, 并且是数字或字符串\n res[key] = has(block, key) && isExpectType(block[key], 'string', 'number')\n ? getLength(block[key])\n : res[key]\n }\n return [paddingTop, paddingBottom, paddingLeft, paddingRight]\n}\n\n/**\n * 节流函数\n * @param fn 将要处理的函数\n * @param wait 时间, 单位为毫秒\n * @returns 包装好的节流函数\n */\nexport const throttle = (fn: Function, wait = 300) => {\n let timeId = null as any\n return function (this: any, ...args: any[]) {\n if (timeId) return\n timeId = setTimeout(() => {\n fn.apply(this, args)\n clearTimeout(timeId)\n timeId = null\n }, wait)\n }\n}\n\n/**\n * 通过概率计算出一个奖品索引\n * @param { Array<number | undefined> } rangeArr 概率\n * @returns { number } 中奖索引\n */\nexport const computeRange = (rangeArr: Array<number | undefined>): number => {\n const ascendingArr: number[] = []\n // 额外增加 map 来优化 ts 的类型推断\n const sum = rangeArr.map(num => Number(num)).reduce((prev, curr) => {\n if (curr > 0) { // 大于0\n const res = prev + curr\n ascendingArr.push(res)\n return res\n } else { // 小于等于0或NaN\n ascendingArr.push(NaN)\n return prev\n }\n }, 0)\n const random = Math.random() * sum\n return ascendingArr.findIndex(num => random <= num)\n}\n\n/**\n * 根据宽度分割字符串, 来达到换行的效果\n * @param text \n * @param maxWidth \n * @returns \n */\nexport const splitText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n getWidth: (lines: string[]) => number,\n lineClamp: number = Infinity\n): string[] => {\n // 如果 lineClamp 设置不正确, 则忽略该属性\n if (lineClamp <= 0) lineClamp = Infinity\n let str = ''\n const lines = []\n const EndWidth = ctx.measureText('...').width\n for (let i = 0; i < text.length; i++) {\n str += text[i]\n let currWidth = ctx.measureText(str).width\n const maxWidth = getWidth(lines)\n // 如果正在计算最后一行, 则加上三个小点的宽度\n if (lineClamp === lines.length + 1) currWidth += EndWidth\n // 如果已经没有宽度了, 就没有必要再计算了\n if (maxWidth < 0) return lines\n // 如果当前一行的宽度不够了, 则处理下一行\n if (currWidth > maxWidth) {\n lines.push(str.slice(0, -1))\n str = text[i]\n }\n // 如果现在是最后一行, 则加上三个小点并跳出\n if (lineClamp === lines.length) {\n lines[lines.length - 1] += '...'\n return lines\n }\n }\n if (str) lines.push(str)\n if (!lines.length) lines.push(text)\n return lines\n}\n\n// 获取一个重新排序的数组\nexport const getSortedArrayByIndex = <T>(arr: T[], order: number[]): T[] => {\n const map: { [key: number]: T } = {}, res = []\n for (let i = 0; i < arr.length; i++) {\n map[i] = arr[i]\n }\n for (let i = 0; i < order.length; i++) {\n const curr = map[order[i]]\n if (curr) (res[i] = curr)\n }\n return res\n}\n","import Watcher from './watcher'\n\nexport default class Dep {\n static target: Watcher | null\n private subs: Array<Watcher>\n\n /**\n * 订阅中心构造器\n */\n constructor () {\n this.subs = []\n }\n\n /**\n * 收集依赖\n * @param {*} sub \n */\n public addSub (sub: Watcher) {\n // 此处临时使用includes防重复添加\n if (!this.subs.includes(sub)) {\n this.subs.push(sub)\n }\n }\n\n /**\n * 派发更新\n */\n public notify () {\n this.subs.forEach(sub => {\n sub.update()\n })\n }\n}\n","\nimport { isExpectType } from '../utils'\n\nexport const hasProto = '__proto__' in {}\n\nexport function def (obj: object, key: string | number, val: any, enumerable?: boolean) {\n Object.defineProperty(obj, key, {\n value: val,\n enumerable: !!enumerable,\n writable: true,\n configurable: true\n })\n}\n\nexport function parsePath (path: string) {\n path += '.'\n let segments: string[] = [], segment = ''\n for (let i = 0; i < path.length; i++) {\n let curr = path[i]\n if (/\\[|\\./.test(curr)) {\n segments.push(segment)\n segment = ''\n } else if (/\\W/.test(curr)) {\n continue\n } else {\n segment += curr\n }\n }\n return function (data: object | any[]) {\n return segments.reduce((data, key) => {\n return data[key]\n }, data)\n }\n}\n\nexport function traverse (value: any) {\n // const seenObjects = new Set()\n const dfs = (data: any) => {\n if (!isExpectType(data, 'array', 'object')) return\n Object.keys(data).forEach(key => {\n const value = data[key]\n dfs(value)\n })\n }\n dfs(value)\n // seenObjects.clear()\n}","/**\n * 重写数组的原型方法\n */\nconst oldArrayProto = Array.prototype\nconst newArrayProto = Object.create(oldArrayProto)\nconst methods = ['push', 'pop', 'shift', 'unshift', 'sort', 'splice', 'reverse']\nmethods.forEach(method => {\n newArrayProto[method] = function (...args: any[]) {\n const res = oldArrayProto[method].apply(this, args)\n const luckyOb = this['__luckyOb__']\n if (['push', 'unshift', 'splice'].includes(method)) luckyOb.walk(this)\n luckyOb.dep.notify()\n return res\n }\n})\n\nexport { newArrayProto }\n","import Dep from './dep'\nimport { hasProto, def } from './utils'\nimport { newArrayProto } from './array'\n\nexport default class Observer {\n value: any\n dep: Dep\n\n /**\n * 观察者构造器\n * @param value \n */\n constructor (value: any) {\n // this.value = value\n this.dep = new Dep()\n // 将响应式对象代理到当前value上面, 并且将当前的enumerable设置为false\n def(value, '__luckyOb__', this)\n if (Array.isArray(value)) { // 如果是数组, 则重写原型方法\n if (hasProto) {\n value['__proto__'] = newArrayProto\n } else {\n Object.getOwnPropertyNames(newArrayProto).forEach(key => {\n def(value, key, newArrayProto[key])\n })\n }\n }\n this.walk(value)\n }\n\n walk (data: object | any[]) {\n Object.keys(data).forEach(key => {\n defineReactive(data, key, data[key])\n })\n }\n}\n\n/**\n * 处理响应式\n * @param { Object | Array } data\n */\nexport function observe (data: any): Observer | void {\n if (!data || typeof data !== 'object') return\n let luckyOb: Observer | void\n if ('__luckyOb__' in data) {\n luckyOb = data['__luckyOb__']\n } else {\n luckyOb = new Observer(data)\n }\n return luckyOb\n}\n\n/**\n * 重写 setter / getter\n * @param {*} data \n * @param {*} key \n * @param {*} val \n */\nexport function defineReactive (data: any, key: string | number, val: any) {\n const dep = new Dep()\n const property = Object.getOwnPropertyDescriptor(data, key)\n if (property && property.configurable === false) {\n return\n }\n const getter = property && property.get\n const setter = property && property.set\n if ((!getter || setter) && arguments.length === 2) {\n val = data[key]\n }\n let childOb = observe(val)\n Object.defineProperty(data, key, {\n get: () => {\n const value = getter ? getter.call(data) : val\n if (Dep.target) {\n dep.addSub(Dep.target)\n if (childOb) {\n childOb.dep.addSub(Dep.target)\n }\n }\n return value\n },\n set: (newVal) => {\n if (newVal === val) return\n val = newVal\n if (getter && !setter) return\n if (setter) {\n setter.call(data, newVal)\n } else {\n val = newVal\n }\n childOb = observe(newVal)\n dep.notify()\n }\n })\n}\n","import Lucky from '../lib/lucky'\nimport Dep from './dep'\nimport { parsePath, traverse } from './utils'\n\nexport interface WatchOptType {\n handler?: () => Function\n immediate?: boolean\n deep?: boolean\n}\n\nlet uid = 0\nexport default class Watcher {\n id: number\n $lucky: Lucky\n expr: string | Function\n cb: Function\n deep: boolean\n getter: Function\n value: any\n\n /**\n * 观察者构造器\n * @param {*} $lucky \n * @param {*} expr \n * @param {*} cb \n */\n constructor ($lucky: Lucky, expr: string | Function, cb: Function, options: WatchOptType = {}) {\n this.id = uid++\n this.$lucky = $lucky\n this.expr = expr\n this.deep = !!options.deep\n if (typeof expr === 'function') {\n this.getter = expr\n } else {\n this.getter = parsePath(expr)\n }\n this.cb = cb\n this.value = this.get()\n }\n\n /**\n * 根据表达式获取新值\n */\n get () {\n Dep.target = this\n const value = this.getter.call(this.$lucky, this.$lucky)\n // 处理深度监听\n if (this.deep) {\n traverse(value)\n }\n Dep.target = null\n return value\n }\n\n /**\n * 触发 watcher 更新\n */\n update () {\n // get获取新值\n const newVal = this.get()\n // 读取之前存储的旧值\n const oldVal = this.value\n this.value = newVal\n // 触发 watch 回调\n this.cb.call(this.$lucky, newVal, oldVal)\n }\n}\n","import '../utils/polyfill'\nimport { has, isExpectType, throttle } from '../utils/index'\nimport { name, version } from '../../package.json'\nimport { ConfigType, UserConfigType, ImgItemType, ImgType, Tuple } from '../types/index'\nimport { defineReactive } from '../observer'\nimport Watcher, { WatchOptType } from '../observer/watcher'\n\nexport default class Lucky {\n static version: string = version\n protected readonly version: string = version\n protected readonly config: ConfigType\n protected readonly ctx: CanvasRenderingContext2D\n protected htmlFontSize: number = 16\n protected rAF: Function = function () {}\n protected boxWidth: number = 0\n protected boxHeight: number = 0\n protected data: {\n width: string | number,\n height: string | number\n }\n\n /**\n * 公共构造器\n * @param config\n */\n constructor (\n config: string | HTMLDivElement | UserConfigType,\n data: {\n width: string | number,\n height: string | number\n }\n ) {\n // 兼容代码开始: 为了处理 v1.0.6 版本在这里传入了一个 dom\n if (typeof config === 'string') config = { el: config } as UserConfigType\n else if (config.nodeType === 1) config = { el: '', divElement: config } as UserConfigType\n // 这里先野蛮的处理, 等待后续优化, 对外暴露的类型是UserConfigType, 但内部期望是ConfigType\n config = config as UserConfigType\n this.config = config as ConfigType\n this.data = data\n // 开始初始化\n if (!config.flag) config.flag = 'WEB'\n if (config.el) config.divElement = document.querySelector(config.el) as HTMLDivElement\n // 如果存在父盒子, 就创建canvas标签\n if (config.divElement) {\n // 无论盒子内有没有canvas都执行覆盖逻辑\n config.canvasElement = document.createElement('canvas')\n config.divElement.appendChild(config.canvasElement)\n }\n // 获取 canvas 上下文\n if (config.canvasElement) {\n config.ctx = config.canvasElement.getContext('2d')!\n // 添加版本信息到标签上, 方便定位版本问题\n config.canvasElement.setAttribute('package', `${name}@${version}`)\n config.canvasElement.addEventListener('click', e => this.handleClick(e))\n }\n this.ctx = config.ctx as CanvasRenderingContext2D\n // 初始化 window 方法\n this.initWindowFunction()\n // 如果最后得不到 canvas 上下文那就无法进行绘制\n if (!this.config.ctx) {\n console.error('无法获取到 CanvasContext2D')\n }\n // 监听 window 触发 resize 时重置\n if (window && typeof window.addEventListener === 'function') {\n window.addEventListener('resize', throttle(() => this.resize(), 300))\n }\n // 监听异步设置 html 的 fontSize 并重新绘制\n if (window && typeof window.MutationObserver === 'function') {\n new window.MutationObserver(() => {\n this.resize()\n }).observe(document.documentElement, { attributes: true })\n }\n }\n\n /**\n * 初始化组件大小/单位\n */\n protected resize(): void {\n this.config.beforeResize?.()\n // 先初始化 fontSize 以防后面有 rem 单位\n this.setHTMLFontSize()\n // 拿到 config 即可设置 dpr\n this.setDpr()\n // 初始化宽高\n this.resetWidthAndHeight()\n // 根据 dpr 来缩放 canvas\n this.zoomCanvas()\n }\n\n /**\n * 初始化方法\n */\n protected initLucky () {\n this.resize()\n if (!this.boxWidth || !this.boxHeight) {\n return console.error('无法获取到宽度或高度')\n }\n }\n\n /**\n * 鼠标点击事件\n * @param e 事件参数\n */\n protected handleClick (e: MouseEvent): void {}\n\n /**\n * 根标签的字体大小\n */\n protected setHTMLFontSize (): void {\n if (!window || !window.getComputedStyle) return\n this.htmlFontSize = +window.getComputedStyle(document.documentElement).fontSize.slice(0, -2)\n }\n\n // 清空画布\n public clearCanvas (): void {\n const [width, height] = [this.boxWidth, this.boxHeight]\n this.ctx.clearRect(-width, -height, width * 2, height * 2)\n }\n\n /**\n * 设备像素比\n * window 环境下自动获取, 其余环境手动传入\n */\n protected setDpr (): void {\n const { config } = this\n if (config.dpr) {\n // 优先使用 config 传入的 dpr\n } else if (window) {\n window['dpr'] = config.dpr = window.devicePixelRatio || 1\n } else if (!config.dpr) {\n console.error(config, '未传入 dpr 可能会导致绘制异常')\n }\n }\n\n /**\n * 重置盒子和canvas的宽高\n */\n private resetWidthAndHeight (): void {\n const { config, data } = this\n // 如果是浏览器环境并且存在盒子\n let boxWidth = 0, boxHeight = 0\n if (config.divElement) {\n boxWidth = config.divElement.offsetWidth\n boxHeight = config.divElement.offsetHeight\n }\n // 先从 data 里取宽高, 如果 config 上面没有, 就从 style 上面取\n this.boxWidth = this.getLength(data.width || config['width']) || boxWidth\n this.boxHeight = this.getLength(data.height || config['height']) || boxHeight\n // 重新把宽高赋给盒子\n if (config.divElement) {\n config.divElement.style.overflow = 'hidden'\n config.divElement.style.width = this.boxWidth + 'px'\n config.divElement.style.height = this.boxHeight + 'px'\n }\n }\n\n /**\n * 根据 dpr 缩放 canvas 并处理位移\n */\n protected zoomCanvas (): void {\n const { config, ctx } = this\n const { canvasElement, dpr } = config\n const [width, height] = [this.boxWidth * dpr, this.boxHeight * dpr]\n if (!canvasElement) return\n canvasElement.width = width\n canvasElement.height = height\n canvasElement.style.width = `${width}px`\n canvasElement.style.height = `${height}px`\n canvasElement.style['transform-origin'] = 'left top'\n canvasElement.style.transform = `scale(${1 / dpr})`\n ctx.scale(dpr, dpr)\n }\n\n /**\n * 从 window 对象上获取一些方法\n */\n private initWindowFunction (): void {\n const { config } = this\n if (window) {\n this.rAF = window.requestAnimationFrame ||\n window['webkitRequestAnimationFrame'] ||\n window['mozRequestAnimationFrame'] ||\n function (callback: Function) {\n window.setTimeout(callback, 1000 / 60)\n }\n config.setTimeout = window.setTimeout\n config.setInterval = window.setInterval\n config.clearTimeout = window.clearTimeout\n config.clearInterval = window.clearInterval\n return\n }\n if (config.rAF) {\n // 优先使用帧动画\n this.rAF = config.rAF\n } else if (config.setTimeout) {\n // 其次使用定时器\n const timeout = config.setTimeout\n this.rAF = (callback: Function): number => timeout(callback, 16.7)\n } else {\n // 如果config里面没有提供, 那就假设全局方法存在setTimeout\n this.rAF = (callback: Function): number => setTimeout(callback, 16.7)\n }\n }\n\n public isWeb () {\n return ['WEB', 'UNI-H5', 'TARO-H5'].includes(this.config.flag)\n }\n\n /**\n * 异步加载图片并返回图片的几何信息\n * @param src 图片路径\n * @param info 图片信息\n */\n protected loadImg (\n src: string,\n info: ImgItemType,\n resolveName = '$resolve'\n ): Promise<ImgType> {\n return new Promise((resolve, reject) => {\n if (!src) reject(`=> '${info.src}' 不能为空或不合法`)\n if (this.config.flag === 'WEB') {\n let imgObj = new Image()\n imgObj['crossorigin'] = 'anonymous'\n imgObj.onload = () => resolve(imgObj)\n imgObj.onerror = () => reject(`=> '${info.src}' 图片加载失败`)\n imgObj.src = src\n } else {\n // 其余平台向外暴露, 交给外部自行处理\n info[resolveName] = resolve\n info['$reject'] = reject\n return\n }\n })\n }\n\n /**\n * 公共绘制图片的方法\n * @param imgObj 图片对象\n * @param rectInfo: [x轴位置, y轴位置, 渲染宽度, 渲染高度] \n */\n protected drawImage(\n ctx: CanvasRenderingContext2D,\n imgObj: ImgType,\n ...rectInfo: [...Tuple<number, 4>, ...Partial<Tuple<number, 4>>]\n ): void {\n let drawImg\n const { flag, dpr } = this.config\n if (['WEB', 'MP-WX'].includes(flag)) {\n // 浏览器和新版小程序中直接绘制即可\n drawImg = imgObj\n } else if (['UNI-H5', 'UNI-MP', 'TARO-H5', 'TARO-MP'].includes(flag)) {\n // 旧版本的小程序需要绘制 path, 这里特殊处理一下\n type OldImageType = ImgType & { path: CanvasImageSource }\n drawImg = (imgObj as OldImageType).path\n } else {\n // 如果传入了未知的标识\n return console.error('意料之外的 flag, 该平台尚未兼容!')\n }\n const miniProgramOffCtx = (drawImg['canvas'] || drawImg).getContext?.('2d')\n if (miniProgramOffCtx && !this.isWeb()) {\n rectInfo = rectInfo.map(val => val! * dpr) as Tuple<number, 8>\n const temp = miniProgramOffCtx.getImageData(...rectInfo.slice(0, 4))\n ctx.putImageData(temp, ...(rectInfo.slice(4, 6) as Tuple<number, 2>))\n } else {\n if (rectInfo.length === 8) {\n rectInfo = rectInfo.map((val, index) => index < 4 ? val! * dpr : val) as Tuple<number, 8>\n }\n // 尝试捕获错误\n try {\n ctx.drawImage(drawImg, ...rectInfo as Tuple<number, 8>)\n } catch (err) {\n /**\n * TODO: safari浏览器下, init() 会出现奇怪的报错\n * IndexSizeError: The index is not in the allowed range\n * 但是这个报错并不影响实际的绘制, 目前先放一放, 等待有缘人\n */\n // console.log(err)\n }\n }\n }\n\n /**\n * 计算图片的渲染宽高\n * @param imgObj 图片标签元素\n * @param imgInfo 图片信息\n * @param maxWidth 最大宽度\n * @param maxHeight 最大高度\n * @return [渲染宽度, 渲染高度]\n */\n protected computedWidthAndHeight (\n imgObj: ImgType,\n imgInfo: ImgItemType,\n maxWidth: number,\n maxHeight: number\n ): [number, number] {\n // 根据配置的样式计算图片的真实宽高\n if (!imgInfo.width && !imgInfo.height) {\n // 如果没有配置宽高, 则使用图片本身的宽高\n return [imgObj.width, imgObj.height]\n } else if (imgInfo.width && !imgInfo.height) {\n // 如果只填写了宽度, 没填写高度\n let trueWidth = this.getLength(imgInfo.width, maxWidth)\n // 那高度就随着宽度进行等比缩放\n return [trueWidth, imgObj.height * (trueWidth / imgObj.width)]\n } else if (!imgInfo.width && imgInfo.height) {\n // 如果只填写了宽度, 没填写高度\n let trueHeight = this.getLength(imgInfo.height, maxHeight)\n // 那宽度就随着高度进行等比缩放\n return [imgObj.width * (trueHeight / imgObj.height), trueHeight]\n }\n // 如果宽度和高度都填写了, 就如实计算\n return [\n this.getLength(imgInfo.width, maxWidth),\n this.getLength(imgInfo.height, maxHeight)\n ]\n }\n\n /**\n * 转换单位\n * @param { string } value 将要转换的值\n * @param { number } denominator 分子\n * @return { number } 返回新的字符串\n */\n protected changeUnits (value: string, denominator = 1): number {\n const { config } = this\n return Number(value.replace(/^([-]*[0-9.]*)([a-z%]*)$/, (val, num, unit) => {\n const handleCssUnit = {\n '%': (n: number) => n * (denominator / 100),\n 'px': (n: number) => n * 1,\n 'rem': (n: number) => n * this.htmlFontSize,\n 'vw': (n: number) => n / 100 * window.innerWidth,\n }[unit]\n if (handleCssUnit) return handleCssUnit(num)\n // 如果找不到默认单位, 就交给外面处理\n const otherHandleCssUnit = config.handleCssUnit || config['unitFunc']\n return otherHandleCssUnit ? otherHandleCssUnit(num, unit) : num\n }))\n }\n\n /**\n * 获取长度\n * @param length 将要转换的长度\n * @param maxLength 最大长度\n * @return 返回长度\n */\n protected getLength (length: string | number | undefined, maxLength?: number): number {\n if (isExpectType(length, 'number')) return length as number\n if (isExpectType(length, 'string')) return this.changeUnits(length as string, maxLength)\n return 0\n }\n\n /**\n * 获取相对(居中)X坐标\n * @param width\n * @param col\n */\n protected getOffsetX (width: number, maxWidth: number = 0): number {\n return (maxWidth - width) / 2\n }\n\n protected getOffscreenCanvas (width: number, height: number): {\n _offscreenCanvas: HTMLCanvasElement,\n _ctx: CanvasRenderingContext2D\n } | void {\n if (!this['_offscreenCanvas']) {\n if (window && window.document && this.config.flag === 'WEB') {\n this['_offscreenCanvas'] = document.createElement('canvas')\n } else {\n this['_offscreenCanvas'] = this.config['offscreenCanvas']\n }\n if (!this['_offscreenCanvas']) return console.error('离屏 Canvas 无法渲染!')\n }\n const dpr = this.config.dpr\n const _offscreenCanvas = this['_offscreenCanvas'] as HTMLCanvasElement\n _offscreenCanvas.width = (width || 300) * dpr\n _offscreenCanvas.height = (height || 150) * dpr\n const _ctx = _offscreenCanvas.getContext('2d')!\n _ctx.clearRect(0, 0, width, height)\n _ctx.scale(dpr, dpr)\n _ctx['dpr'] = dpr\n return { _offscreenCanvas, _ctx }\n }\n\n /**\n * 添加一个新的响应式数据 (临时)\n * @param data 数据\n * @param key 属性\n * @param value 新值\n */\n public $set (data: object, key: string | number, value: any) {\n if (!data || typeof data !== 'object') return\n defineReactive(data, key, value)\n }\n\n /**\n * 添加一个属性计算 (临时)\n * @param data 源数据\n * @param key 属性名\n * @param callback 回调函数\n */\n protected $computed (data: object, key: string, callback: Function) {\n Object.defineProperty(data, key, {\n get: () => {\n return callback.call(this)\n }\n })\n }\n\n /**\n * 添加一个观察者 create user watcher\n * @param expr 表达式\n * @param handler 回调函数\n * @param watchOpt 配置参数\n * @return 卸载当前观察者的函数 (暂未返回)\n */\n protected $watch (\n expr: string | Function,\n handler: Function | WatchOptType,\n watchOpt: WatchOptType = {}\n ): Function {\n if (typeof handler === 'object') {\n watchOpt = handler\n handler = watchOpt.handler!\n }\n // 创建 user watcher\n const watcher = new Watcher(this, expr, handler, watchOpt)\n // 判断是否需要初始化时触发回调\n if (watchOpt.immediate) {\n handler.call(this, watcher.value)\n }\n // 返回一个卸载当前观察者的函数\n return function unWatchFn () {}\n }\n}\n","/**\n * 转换为运算角度\n * @param { number } deg 数学角度\n * @return { number } 运算角度\n */\nexport const getAngle = (deg: number): number => {\n return Math.PI / 180 * deg\n}\n\n/**\n * 根据角度计算圆上的点\n * @param { number } deg 运算角度\n * @param { number } r 半径\n * @return { Array<number> } 坐标[x, y]\n */\nexport const getArcPointerByDeg = (deg: number, r: number): [number, number] => {\n return [+(Math.cos(deg) * r).toFixed(8), +(Math.sin(deg) * r).toFixed(8)]\n}\n\n/**\n * 根据点计算切线方程\n * @param { number } x 横坐标\n * @param { number } y 纵坐标\n * @return { Array<number> } [斜率, 常数]\n */\nexport const getTangentByPointer = (x: number, y: number): Array<number> => {\n let k = - x / y\n let b = -k * x + y\n return [k, b]\n}\n\n// 使用 arc 绘制扇形\nexport const fanShapedByArc = (\n ctx: CanvasRenderingContext2D,\n minRadius: number,\n maxRadius: number,\n start: number,\n end: number,\n gutter: number,\n): void => {\n ctx.beginPath()\n let maxGutter = getAngle(90 / Math.PI / maxRadius * gutter)\n let minGutter = getAngle(90 / Math.PI / minRadius * gutter)\n let maxStart = start + maxGutter\n let maxEnd = end - maxGutter\n let minStart = start + minGutter\n let minEnd = end - minGutter\n ctx.arc(0, 0, maxRadius, maxStart, maxEnd, false)\n // 如果 getter 比按钮短就绘制圆弧, 反之计算新的坐标点\n // if (minEnd > minStart) {\n // ctx.arc(0, 0, minRadius, minEnd, minStart, true)\n // } else {\n ctx.lineTo(\n ...getArcPointerByDeg(\n (start + end) / 2,\n gutter / 2 / Math.abs(Math.sin((start - end) / 2))\n )\n )\n // }\n ctx.closePath()\n}\n\n// 使用 arc 绘制圆角矩形\nexport const roundRectByArc = (\n ctx: CanvasRenderingContext2D,\n ...[x, y, w, h, r]: number[]\n) => {\n const min = Math.min(w, h), PI = Math.PI\n if (r > min / 2) r = min / 2\n ctx.beginPath()\n ctx.moveTo(x + r, y)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x + w - r, y)\n ctx.arc(x + w - r, y + r, r, -PI / 2, 0)\n ctx.lineTo(x + w, y + h - r)\n ctx.arc(x + w - r, y + h - r, r, 0, PI / 2)\n ctx.lineTo(x + r, y + h)\n ctx.arc(x + r, y + h - r, r, PI / 2, PI)\n ctx.lineTo(x, y + r)\n ctx.arc(x + r, y + r, r, PI, -PI / 2)\n ctx.closePath()\n}\n\n/**\n * 创建线性渐变色\n */\nexport const getLinearGradient = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n background: string\n) => {\n const context = (/linear-gradient\\((.+)\\)/.exec(background) as Array<any>)[1]\n .split(',') // 根据逗号分割\n .map((text: string) => text.trim()) // 去除两边空格\n let deg = context.shift(), direction: [number, number, number, number] = [0, 0, 0, 0]\n // 通过起始点和角度计算渐变终点的坐标点, 这里感谢泽宇大神提醒我使用勾股定理....\n if (deg.includes('deg')) {\n deg = deg.slice(0, -3) % 360\n // 根据4个象限定义起点坐标, 根据45度划分8个区域计算终点坐标\n const getLenOfTanDeg = (deg: number) => Math.tan(deg / 180 * Math.PI)\n if (deg >= 0 && deg < 45) direction = [x, y + h, x + w, y + h - w * getLenOfTanDeg(deg - 0)]\n else if (deg >= 45 && deg < 90) direction = [x, y + h, (x + w) - h * getLenOfTanDeg(deg - 45), y]\n else if (deg >= 90 && deg < 135) direction = [x + w, y + h, (x + w) - h * getLenOfTanDeg(deg - 90), y]\n else if (deg >= 135 && deg < 180) direction = [x + w, y + h, x, y + w * getLenOfTanDeg(deg - 135)]\n else if (deg >= 180 && deg < 225) direction = [x + w, y, x, y + w * getLenOfTanDeg(deg - 180)]\n else if (deg >= 225 && deg < 270) direction = [x + w, y, x + h * getLenOfTanDeg(deg - 225), y + h]\n else if (deg >= 270 && deg < 315) direction = [x, y, x + h * getLenOfTanDeg(deg - 270), y + h]\n else if (deg >= 315 && deg < 360) direction = [x, y, x + w, y + h - w * getLenOfTanDeg(deg - 315)]\n }\n // 创建四个简单的方向坐标\n else if (deg.includes('top')) direction = [x, y + h, x, y]\n else if (deg.includes('bottom')) direction = [x, y, x, y + h]\n else if (deg.includes('left')) direction = [x + w, y, x, y]\n else if (deg.includes('right')) direction = [x, y, x + w, y]\n // 创建线性渐变必须使用整数坐标\n const gradient = ctx.createLinearGradient(...(direction.map(n => n >> 0) as typeof direction))\n // 这里后期重构, 先用any代替\n return context.reduce((gradient: any, item: any, index: any) => {\n const info = item.split(' ')\n if (info.length === 1) gradient.addColorStop(index, info[0])\n else if (info.length === 2) gradient.addColorStop(...info)\n return gradient\n }, gradient)\n}\n\n// // 根据三点画圆弧\n// export const drawRadian = (\n// ctx: CanvasRenderingContext2D,\n// r: number,\n// start: number,\n// end: number,\n// direction: boolean = true\n// ) => {\n// // 如果角度大于等于180度, 则分两次绘制, 因为 arcTo 无法绘制180度的圆弧\n// if (Math.abs(end - start).toFixed(8) >= getAngle(180).toFixed(8)) {\n// let middle = (end + start) / 2\n// if (direction) {\n// drawRadian(ctx, r, start, middle, direction)\n// drawRadian(ctx, r, middle, end, direction)\n// } else {\n// drawRadian(ctx, r, middle, end, direction)\n// drawRadian(ctx, r, start, middle, direction)\n// }\n// return false\n// }\n// // 如果方法相反, 则交换起点和终点\n// if (!direction) [start, end] = [end, start]\n// const [x1, y1] = getArcPointerByDeg(start, r)\n// const [x2, y2] = getArcPointerByDeg(end, r)\n// const [k1, b1] = getTangentByPointer(x1, y1)\n// const [k2, b2] = getTangentByPointer(x2, y2)\n// // 计算两条切线的交点\n// let x0 = (b2 - b1) / (k1 - k2)\n// let y0 = (k2 * b1 - k1 * b2) / (k2 - k1)\n// // 如果有任何一条切线垂直于x轴, 则斜率不存在\n// if (isNaN(x0)) {\n// Math.abs(x1) === +r.toFixed(8) && (x0 = x1)\n// Math.abs(x2) === +r.toFixed(8) && (x0 = x2)\n// }\n// if (k1 === Infinity || k1 === -Infinity) {\n// y0 = k2 * x0 + b2\n// }\n// else if (k2 === Infinity || k2 === -Infinity) {\n// y0 = k1 * x0 + b1\n// }\n// ctx.lineTo(x1, y1)\n// // 微信小程序下 arcTo 在安卓真机下绘制有 bug\n// ctx.arcTo(x0, y0, x2, y2, r)\n// }\n\n// // 使用 arcTo 绘制扇形 (弃用)\n// export const drawSectorByArcTo = (\n// ctx: CanvasRenderingContext2D,\n// minRadius: number,\n// maxRadius: number,\n// start: number,\n// end: number,\n// gutter: number,\n// ) => {\n// if (!minRadius) minRadius = gutter\n// // 内外圆弧分别进行等边缩放\n// let maxGutter = getAngle(90 / Math.PI / maxRadius * gutter)\n// let minGutter = getAngle(90 / Math.PI / minRadius * gutter)\n// let maxStart = start + maxGutter\n// let maxEnd = end - maxGutter\n// let minStart = start + minGutter\n// let minEnd = end - minGutter\n// ctx.beginPath()\n// ctx.moveTo(...getArcPointerByDeg(maxStart, maxRadius))\n// drawRadian(ctx, maxRadius, maxStart, maxEnd, true)\n// // 如果 getter 比按钮短就绘制圆弧, 反之计算新的坐标点\n// if (minEnd > minStart) {\n// drawRadian(ctx, minRadius, minStart, minEnd, false)\n// } else {\n// ctx.lineTo(\n// ...getArcPointerByDeg(\n// (start + end) / 2,\n// gutter / 2 / Math.abs(Math.sin((start - end) / 2))\n// )\n// )\n// }\n// ctx.closePath()\n// }\n\n// // 使用 arcTo 绘制圆角矩形 (弃用)\n// export const roundRectByArcTo = (\n// ctx: CanvasRenderingContext2D,\n// ...[x, y, w, h, r]: number[]\n// ) => {\n// let min = Math.min(w, h)\n// if (r > min / 2) r = min / 2\n// ctx.beginPath()\n// ctx.moveTo(x + r, y)\n// ctx.lineTo(x + r, y)\n// ctx.lineTo(x + w - r, y)\n// ctx.arcTo(x + w, y, x + w, y + r, r)\n// ctx.lineTo(x + w, y + h - r)\n// ctx.arcTo(x + w, y + h, x + w - r, y + h, r)\n// ctx.lineTo(x + r, y + h)\n// ctx.arcTo(x, y + h, x, y + h - r, r)\n// ctx.lineTo(x, y + r)\n// ctx.arcTo(x, y, x + r, y, r)\n// }\n","/**\n * 缓动函数\n * t: current time(当前时间)\n * b: beginning value(初始值)\n * c: change in value(变化量)\n * d: duration(持续时间)\n * \n * 感谢张鑫旭大佬 https://github.com/zhangxinxu/Tween\n */\n\ninterface SpeedType {\n easeIn: (...arr: number[]) => number\n easeOut: (...arr: number[]) => number\n}\n\n// 二次方的缓动\nexport const quad: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * (t /= d) * (t - 2) + b\n }\n}\n\n// 三次方的缓动\nexport const cubic: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * ((t = t / d - 1) * t * t + 1) + b\n }\n}\n\n// 四次方的缓动\nexport const quart: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t * t * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * ((t = t / d - 1) * t * t * t - 1) + b\n }\n}\n\n// 五次方的缓动\nexport const quint: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return c * (t /= d) * t * t * t * t + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b\n }\n}\n\n// 正弦曲线的缓动\nexport const sine: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * Math.sin(t / d * (Math.PI / 2)) + b\n }\n}\n\n// 指数曲线的缓动\nexport const expo: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b\n }\n}\n\n// 圆形曲线的缓动\nexport const circ: SpeedType = {\n easeIn: function (t, b, c, d) {\n if (t >= d) t = d\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b\n },\n easeOut: function (t, b, c, d) {\n if (t >= d) t = d\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b\n }\n}\n","import Lucky from './lucky'\nimport { UserConfigType, ImgType } from '../types/index'\nimport LuckyGridConfig, {\n BlockType,\n PrizeType,\n ButtonType,\n CellFontType,\n CellImgType,\n RowsType,\n ColsType,\n CellType,\n DefaultConfigType,\n DefaultStyleType,\n ActiveStyleType,\n StartCallbackType,\n EndCallbackType,\n} from '../types/grid'\nimport {\n has,\n isExpectType,\n removeEnter,\n computePadding,\n hasBackground,\n computeRange,\n splitText\n} from '../utils/index'\nimport { roundRectByArc, getLinearGradient } from '../utils/math'\nimport { quad } from '../utils/tween'\n\nexport default class LuckyGrid extends Lucky {\n private rows: RowsType = 3\n private cols: ColsType = 3\n private blocks: Array<BlockType> = []\n private prizes: Array<PrizeType> = []\n private buttons: Array<ButtonType> = []\n private button?: ButtonType\n private defaultConfig: DefaultConfigType = {}\n private defaultStyle: DefaultStyleType = {}\n private activeStyle: ActiveStyleType = {}\n private _defaultConfig: Required<DefaultConfigType> = {} as Required<DefaultConfigType>\n private _defaultStyle: Required<DefaultStyleType> = {} as Required<DefaultStyleType>\n private _activeStyle: Required<ActiveStyleType> = {} as Required<ActiveStyleType>\n private startCallback?: StartCallbackType\n private endCallback?: EndCallbackType\n private cellWidth = 0 // 格子宽度\n private cellHeight = 0 // 格子高度\n private startTime = 0 // 开始时间戳\n private endTime = 0 // 结束时间戳\n private currIndex = 0 // 当前index累加\n private stopIndex = 0 // 刻舟求剑\n private endIndex = 0 // 停止索引\n private demo = false // 是否自动游走\n private timer = 0 // 游走定时器\n private FPS = 16.6 // 屏幕刷新率\n /**\n * 游戏当前的阶段\n * step = 0 时, 游戏尚未开始\n * step = 1 时, 此时处于加速阶段\n * step = 2 时, 此时处于匀速阶段\n * step = 3 时, 此时处于减速阶段\n */\n private step: 0 | 1 | 2 | 3 = 0\n /**\n * 中奖索引\n * prizeFlag = undefined 时, 处于开始抽奖阶段, 正常旋转\n * prizeFlag >= 0 时, 说明stop方法被调用, 并且传入了中奖索引\n * prizeFlag === -1 时, 说明stop方法被调用, 并且传入了负值, 本次抽奖无效\n */\n private prizeFlag: number | undefined = -1\n // 所有格子\n private cells: CellType<CellFontType, CellImgType>[] = []\n // 奖品区域几何信息\n private prizeArea: { x: number, y: number, w: number, h: number } | undefined\n // 图片缓存\n private ImageCache = new Map()\n\n /**\n * 九宫格构造器\n * @param config 配置项\n * @param data 抽奖数据\n */\n constructor (config: UserConfigType, data: LuckyGridConfig) {\n super(config, {\n width: data.width,\n height: data.height\n })\n this.initData(data)\n this.initWatch()\n this.initComputed()\n // 创建前回调函数\n config.beforeCreate?.call(this)\n // 首次初始化\n this.init()\n }\n\n protected resize(): void {\n super.resize()\n this.draw()\n this.config.afterResize?.()\n }\n\n protected initLucky (): void {\n this.cellWidth = 0\n this.cellHeight = 0\n this.startTime = 0\n this.endTime = 0\n this.currIndex = 0\n this.stopIndex = 0\n this.endIndex = 0\n this.demo = false\n this.timer = 0\n this.FPS = 16.6\n this.prizeFlag = -1\n this.step = 0\n super.initLucky()\n }\n\n /**\n * 初始化数据\n * @param data\n */\n private initData (data: LuckyGridConfig): void {\n this.$set(this, 'width', data.width)\n this.$set(this, 'height', data.height)\n this.$set(this, 'rows', Number(data.rows) || 3)\n this.$set(this, 'cols', Number(data.cols) || 3)\n this.$set(this, 'blocks', data.blocks || [])\n this.$set(this, 'prizes', data.prizes || [])\n this.$set(this, 'buttons', data.buttons || [])\n // 临时过渡代码, 升级到2.x即可删除\n this.$set(this, 'button', data.button)\n this.$set(this, 'defaultConfig', data.defaultConfig || {})\n this.$set(this, 'defaultStyle', data.defaultStyle || {})\n this.$set(this, 'activeStyle', data.activeStyle || {})\n this.$set(this, 'startCallback', data.start)\n this.$set(this, 'endCallback', data.end)\n }\n\n /**\n * 初始化属性计算\n */\n private initComputed (): void {\n // 默认配置\n this.$computed(this, '_defaultConfig', () => {\n const config = {\n gutter: 5,\n speed: 20,\n accelerationTime: 2500,\n decelerationTime: 2500,\n ...this.defaultConfig\n }\n config.gutter = this.getLength(config.gutter)\n config.speed = config.speed / 40\n return config\n })\n // 默认样式\n this.$computed(this, '_defaultStyle', () => {\n return {\n borderRadius: 20,\n fontColor: '#000',\n fontSize: '18px',\n fontStyle: 'sans-serif',\n fontWeight: '400',\n background: 'rgba(0,0,0,0)',\n shadow: '',\n wordWrap: true,\n lengthLimit: '90%',\n ...this.defaultStyle\n }\n })\n // 中奖样式\n this.$computed(this, '_activeStyle', () => {\n return {\n background: '#ffce98',\n shadow: '',\n ...this.activeStyle\n }\n })\n }\n\n /**\n * 初始化观察者\n */\n private initWatch (): void {\n // 重置宽度\n this.$watch('width', (newVal: string | number) => {\n this.data.width = newVal\n this.resize()\n })\n // 重置高度\n this.$watch('height', (newVal: string | number) => {\n this.data.height = newVal\n this.resize()\n })\n // 监听 blocks 数据的变化\n this.$watch('blocks', (newData: Array<BlockType>) => {\n this.initImageCache()\n }, { deep: true })\n // 监听 prizes 数据的变化\n this.$watch('prizes', (newData: Array<PrizeType>) => {\n this.initImageCache()\n }, { deep: true })\n // 监听 button 数据的变化\n this.$watch('buttons', (newData: Array<ButtonType>) => {\n this.initImageCache()\n }, { deep: true })\n this.$watch('rows', () => this.init())\n this.$watch('cols', () => this.init())\n this.$watch('defaultConfig', () => this.draw(), { deep: true })\n this.$watch('defaultStyle', () => this.draw(), { deep: true })\n this.$watch('activeStyle', () => this.draw(), { deep: true })\n this.$watch('startCallback', () => this.init())\n this.$watch('endCallback', () => this.init())\n }\n\n /**\n * 初始化 canvas 抽奖\n */\n public async init (): Promise<void> {\n this.initLucky()\n const { config } = this\n // 初始化前回调函数\n config.beforeInit?.call(this)\n // 先画一次防止闪烁\n this.draw()\n // 异步加载图片\n await this.initImageCache()\n // 初始化后回调函数\n config.afterInit?.call(this)\n }\n\n private initImageCache (): Promise<void> {\n return new Promise((resolve) => {\n const btnImgs = this.buttons.map(btn => btn.imgs)\n if (this.button) btnImgs.push(this.button.imgs)\n const willUpdateImgs = {\n blocks: this.blocks.map(block => block.imgs),\n prizes: this.prizes.map(prize => prize.imgs),\n buttons: btnImgs,\n }\n ;(<(keyof typeof willUpdateImgs)[]>Object.keys(willUpdateImgs)).forEach(imgName => {\n const willUpdate = willUpdateImgs[imgName]\n // 循环遍历所有图片\n const allPromise: Promise<void>[] = []\n willUpdate && willUpdate.forEach((imgs, cellIndex) => {\n imgs && imgs.forEach((imgInfo, imgIndex) => {\n allPromise.push(this.loadAndCacheImg(imgName, cellIndex, imgIndex))\n })\n })\n Promise.all(allPromise).then(() => {\n this.draw()\n resolve()\n })\n })\n })\n }\n\n /**\n * canvas点击事件\n * @param e 事件参数\n */\n protected handleClick (e: MouseEvent): void {\n const { ctx } = this\n ;[\n ...this.buttons,\n this.button\n ].forEach(btn => {\n if (!btn) return\n const [x, y, width, height] = this.getGeometricProperty([\n btn.x, btn.y, btn.col || 1, btn.row || 1\n ])\n ctx.beginPath()\n ctx.rect(x, y, width, height)\n if (!ctx.isPointInPath(e.offsetX, e.offsetY)) return\n if (this.step !== 0) return\n // 如果btn里有单独的回调方法, 优先触发\n if (typeof btn.callback === 'function') btn.callback.call(this, btn)\n // 最后触发公共回调\n this.startCallback?.(e, btn)\n })\n }\n\n /**\n * 根据索引单独加载指定图片并缓存\n * @param cellName 模块名称\n * @param cellIndex 模块索引\n * @param imgName 模块对应的图片缓存\n * @param imgIndex 图片索引\n */\n private async loadAndCacheImg (\n cellName: 'blocks' | 'prizes' | 'buttons',\n cellIndex: number,\n imgIndex: number\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n let cell: BlockType | PrizeType | ButtonType = this[cellName][cellIndex]\n // 临时过渡代码, 升级到2.x即可删除\n if (cellName === 'buttons' && !this.buttons.length && this.button) {\n cell = this.button\n }\n if (!cell || !cell.imgs) return\n const imgInfo = cell.imgs[imgIndex]\n if (!imgInfo) return\n // 异步加载图片\n const request = [\n this.loadImg(imgInfo.src, imgInfo),\n imgInfo['activeSrc'] && this.loadImg(imgInfo['activeSrc'], imgInfo, '$activeResolve')\n ]\n Promise.all(request).then(async ([defaultImg, activeImg]) => {\n const formatter = imgInfo.formatter\n // 对图片进行处理\n if (typeof formatter === 'function') {\n defaultImg = await Promise.resolve(formatter.call(this, defaultImg))\n if (activeImg) {\n activeImg = await Promise.resolve(formatter.call(this, activeImg))\n }\n }\n this.ImageCache.set(imgInfo['src'], defaultImg)\n activeImg && this.ImageCache.set(imgInfo['activeSrc'], activeImg)\n resolve()\n }).catch(err => {\n console.error(`${cellName}[${cellIndex}].imgs[${imgIndex}] ${err}`)\n reject()\n })\n })\n }\n\n /**\n * 绘制九宫格抽奖\n */\n protected draw (): void {\n const { config, ctx, _defaultConfig, _defaultStyle, _activeStyle } = this\n // 触发绘制前回调\n config.beforeDraw?.call(this, ctx)\n // 清空画布\n ctx.clearRect(0, 0, this.boxWidth, this.boxHeight)\n // 合并奖品和按钮\n this.cells = [\n ...this.prizes,\n ...this.buttons\n ]\n if (this.button) this.cells.push(this.button)\n this.cells.forEach(cell => {\n cell.col = cell.col || 1\n cell.row = cell.row || 1\n })\n // 计算获取奖品区域的几何信息\n this.prizeArea = this.blocks.reduce(({x, y, w, h}, block, blockIndex) => {\n const [paddingTop, paddingBottom, paddingLeft, paddingRight] = computePadding(block, this.getLength.bind(this))\n const r = block.borderRadius ? this.getLength(block.borderRadius) : 0\n // 绘制边框\n const background = block.background\n if (hasBackground(background)) {\n ctx.fillStyle = this.handleBackground(x, y, w, h, background!)\n roundRectByArc(ctx, x, y, w, h, r)\n ctx.fill()\n }\n // 绘制图片\n block.imgs && block.imgs.forEach((imgInfo, imgIndex) => {\n const blockImg = this.ImageCache.get(imgInfo.src)\n if (!blockImg) return\n // 绘制图片\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(blockImg, imgInfo, w, h)\n const [xAxis, yAxis] = [\n this.getOffsetX(trueWidth, w) + this.getLength(imgInfo.left, w),\n this.getLength(imgInfo.top, h)\n ]\n this.drawImage(ctx, blockImg, x + xAxis, y + yAxis, trueWidth, trueHeight)\n })\n return {\n x: x + paddingLeft,\n y: y + paddingTop,\n w: w - paddingLeft - paddingRight,\n h: h - paddingTop - paddingBottom\n }\n }, { x: 0, y: 0, w: this.boxWidth, h: this.boxHeight })\n // 计算单一奖品格子的宽度和高度\n this.cellWidth = (this.prizeArea.w - _defaultConfig.gutter * (this.cols - 1)) / this.cols\n this.cellHeight = (this.prizeArea.h - _defaultConfig.gutter * (this.rows - 1)) / this.rows\n // 绘制所有格子\n this.cells.forEach((cell, cellIndex) => {\n let [x, y, width, height] = this.getGeometricProperty([cell.x, cell.y, cell.col!, cell.row!])\n // 默认不显示中奖标识\n let isActive = false\n // 只要 prizeFlag 不是负数, 就显示中奖标识\n if (this.prizeFlag === void 0 || this.prizeFlag > -1) {\n isActive = cellIndex === this.currIndex % this.prizes.length >> 0\n }\n // 绘制背景色\n const background = isActive ? _activeStyle.background : (cell.background || _defaultStyle.background)\n if (hasBackground(background)) {\n // 处理阴影 (暂时先用any, 这里后续要优化)\n const shadow: any = (\n isActive ? _activeStyle.shadow : (cell.shadow || _defaultStyle.shadow)\n )\n .replace(/px/g, '') // 清空px字符串\n .split(',')[0].split(' ') // 防止有人声明多个阴影, 截取第一个阴影\n .map((n, i) => i < 3 ? Number(n) : n) // 把数组的前三个值*像素比\n // 绘制阴影\n if (shadow.length === 4) {\n ctx.shadowColor = shadow[3]\n ctx.shadowOffsetX = shadow[0] * config.dpr\n ctx.shadowOffsetY = shadow[1] * config.dpr\n ctx.shadowBlur = shadow[2]\n // 修正(格子+阴影)的位置, 这里使用逗号运算符\n shadow[0] > 0 ? (width -= shadow[0]) : (width += shadow[0], x -= shadow[0])\n shadow[1] > 0 ? (height -= shadow[1]) : (height += shadow[1], y -= shadow[1])\n }\n // 绘制背景\n ctx.fillStyle = this.handleBackground(x, y, width, height, background)\n const borderRadius = this.getLength(cell.borderRadius ? cell.borderRadius : _defaultStyle.borderRadius)\n roundRectByArc(ctx, x, y, width, height, borderRadius)\n ctx.fill()\n // 清空阴影\n ctx.shadowColor = 'rgba(0, 0, 0, 0)'\n ctx.shadowOffsetX = 0\n ctx.shadowOffsetY = 0\n ctx.shadowBlur = 0\n }\n // 修正图片缓存\n let cellName = 'prizes'\n if (cellIndex >= this.prizes.length) {\n cellName = 'buttons'\n cellIndex -= this.prizes.length\n }\n // 绘制图片\n cell.imgs && cell.imgs.forEach((imgInfo, imgIndex) => {\n const cellImg = this.ImageCache.get(imgInfo.src)\n const activeImg = this.ImageCache.get(imgInfo['activeSrc'])\n if (!cellImg) return\n const renderImg = (isActive && activeImg) || cellImg\n if (!renderImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(renderImg, imgInfo, width, height)\n const [xAxis, yAxis] = [\n x + this.getOffsetX(trueWidth, width) + this.getLength(imgInfo.left, width),\n y + this.getLength(imgInfo.top, height)\n ]\n this.drawImage(ctx, renderImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 绘制文字\n cell.fonts && cell.fonts.forEach(font => {\n // 字体样式\n const style = isActive && _activeStyle.fontStyle\n ? _activeStyle.fontStyle\n : (font.fontStyle || _defaultStyle.fontStyle)\n // 字体加粗\n const fontWeight = isActive && _activeStyle.fontWeight\n ? _activeStyle.fontWeight\n : (font.fontWeight || _defaultStyle.fontWeight)\n // 字体大小\n const size = isActive && _activeStyle.fontSize\n ? this.getLength(_activeStyle.fontSize)\n : this.getLength(font.fontSize || _defaultStyle.fontSize)\n // 字体行高\n const lineHeight = isActive && _activeStyle.lineHeight\n ? _activeStyle.lineHeight\n : font.lineHeight || _defaultStyle.lineHeight || font.fontSize || _defaultStyle.fontSize\n const wordWrap = has(font, 'wordWrap') ? font.wordWrap : _defaultStyle.wordWrap\n const lengthLimit = font.lengthLimit || _defaultStyle.lengthLimit\n const lineClamp = font.lineClamp || _defaultStyle.lineClamp\n ctx.font = `${fontWeight} ${size >> 0}px ${style}`\n ctx.fillStyle = (isActive && _activeStyle.fontColor) ? _activeStyle.fontColor : (font.fontColor || _defaultStyle.fontColor)\n let lines = [], text = String(font.text)\n // 计算文字换行\n if (wordWrap) {\n // 最大宽度\n let maxWidth = this.getLength(lengthLimit, width)\n lines = splitText(ctx, removeEnter(text), () => maxWidth, lineClamp)\n } else {\n lines = text.split('\\n')\n }\n lines.forEach((line, lineIndex) => {\n ctx.fillText(\n line,\n x + this.getOffsetX(ctx.measureText(line).width, width) + this.getLength(font.left, width),\n y + this.getLength(font.top, height) + (lineIndex + 1) * this.getLength(lineHeight)\n )\n })\n })\n })\n // 触发绘制后回调\n config.afterDraw?.call(this, ctx)\n }\n\n /**\n * 处理背景色\n * @param x\n * @param y\n * @param width\n * @param height\n * @param background\n * @param isActive\n */\n private handleBackground (\n x: number,\n y: number,\n width: number,\n height: number,\n background: string,\n ) {\n const { ctx } = this\n // 处理线性渐变\n if (background.includes('linear-gradient')) {\n background = getLinearGradient(ctx, x, y, width, height, background)\n }\n return background\n }\n\n /**\n * 刻舟求剑\n */\n private carveOnGunwaleOfAMovingBoat (): void {\n const { _defaultConfig, prizeFlag, currIndex } = this\n this.endTime = Date.now()\n const stopIndex = this.stopIndex = currIndex\n const speed = _defaultConfig.speed\n let i = 0, prevSpeed = 0, prevIndex = 0\n while (++i) {\n const endIndex = this.prizes.length * i + prizeFlag! - (stopIndex)\n const currSpeed = quad.easeOut(this.FPS, stopIndex, endIndex, _defaultConfig.decelerationTime) - stopIndex\n if (currSpeed > speed) {\n this.endIndex = (speed - prevSpeed > currSpeed - speed) ? endIndex : prevIndex\n break\n }\n prevIndex = endIndex\n prevSpeed = currSpeed\n }\n }\n\n /**\n * 对外暴露: 开始抽奖方法\n */\n public play (): void {\n if (this.step !== 0) return\n // 记录游戏开始的时间\n this.startTime = Date.now()\n // 重置中奖索引\n this.prizeFlag = void 0\n // 开始加速\n this.step = 1\n // 触发回调\n this.config.afterStart?.()\n // 开始运行\n this.run()\n }\n\n /**\n * 对外暴露: 缓慢停止方法\n * @param index 中奖索引\n */\n public stop (index?: number): void {\n if (this.step === 0 || this.step === 3) return\n // 如果没有传递中奖索引, 则通过range属性计算一个\n if (!index && index !== 0) {\n const rangeArr = this.prizes.map(item => item.range)\n index = computeRange(rangeArr)\n }\n // 如果index是负数则停止游戏, 反之则传递中奖索引\n if (index < 0) {\n this.step = 0\n this.prizeFlag = -1\n } else {\n this.step = 2\n this.prizeFlag = index % this.prizes.length\n }\n }\n\n /**\n * 实际开始执行方法\n * @param num 记录帧动画执行多少次\n */\n private run (num: number = 0): void {\n const { rAF, step, prizes, prizeFlag, _defaultConfig } = this\n const { accelerationTime, decelerationTime, speed } = _defaultConfig\n // 结束游戏\n if (step === 0) {\n this.endCallback?.(this.prizes.find((prize, index) => index === prizeFlag) || {})\n return\n }\n // 如果等于 -1 就直接停止游戏\n if (prizeFlag === -1) return\n // 计算结束位置\n if (step === 3 && !this.endIndex) this.carveOnGunwaleOfAMovingBoat()\n // 计算时间间隔\n const startInterval = Date.now() - this.startTime\n const endInterval = Date.now() - this.endTime\n let currIndex = this.currIndex\n // \n if (step === 1 || startInterval < accelerationTime) { // 加速阶段\n // 记录帧率\n this.FPS = startInterval / num\n const currSpeed = quad.easeIn(startInterval, 0.1, speed - 0.1, accelerationTime)\n // 加速到峰值后, 进入匀速阶段\n if (currSpeed === speed) {\n this.step = 2\n }\n currIndex = currIndex + currSpeed % prizes.length\n } else if (step === 2) { // 匀速阶段\n // 速度保持不变\n currIndex = currIndex + speed % prizes.length\n // 如果 prizeFlag 有值, 则进入减速阶段\n if (prizeFlag !== void 0 && prizeFlag >= 0) {\n this.step = 3\n // 清空上一次的位置信息\n this.stopIndex = 0\n this.endIndex = 0\n }\n } else if (step === 3) { // 减速阶段\n // 开始缓慢停止\n currIndex = quad.easeOut(endInterval, this.stopIndex, this.endIndex, decelerationTime)\n if (endInterval >= decelerationTime) {\n this.step = 0\n }\n } else {\n // 出现异常\n this.stop(-1)\n }\n this.currIndex = currIndex\n this.draw()\n rAF(this.run.bind(this, num + 1))\n }\n\n /**\n * 计算奖品格子的几何属性\n * @param { array } [...矩阵坐标, col, row]\n * @return { array } [...真实坐标, width, height]\n */\n private getGeometricProperty ([x, y, col = 1, row = 1]: number[]) {\n const { cellWidth, cellHeight } = this\n const gutter = this._defaultConfig.gutter\n let res = [\n this.prizeArea!.x + (cellWidth + gutter) * x,\n this.prizeArea!.y + (cellHeight + gutter) * y\n ]\n col && row && res.push(\n cellWidth * col + gutter * (col - 1),\n cellHeight * row + gutter * (row - 1),\n )\n return res\n }\n\n /**\n * 换算渲染坐标\n * @param x\n * @param y\n */\n protected conversionAxis (x: number, y: number): [number, number] {\n const { config } = this\n return [x / config.dpr, y / config.dpr]\n }\n}\n","import Lucky from './lucky'\nimport { UserConfigType, FontItemType, ImgType } from '../types/index'\nimport LuckyWheelConfig, {\n BlockType,\n PrizeType,\n ButtonType,\n DefaultConfigType,\n DefaultStyleType,\n StartCallbackType,\n EndCallbackType\n} from '../types/wheel'\nimport {\n removeEnter,\n hasBackground,\n computeRange,\n splitText,\n has,\n} from '../utils/index'\nimport { getAngle, fanShapedByArc } from '../utils/math'\nimport { quad } from '../utils/tween'\n\nexport default class LuckyWheel extends Lucky {\n private blocks: Array<BlockType> = []\n private prizes: Array<PrizeType> = []\n private buttons: Array<ButtonType> = []\n private defaultConfig: DefaultConfigType = {}\n private defaultStyle: DefaultStyleType = {}\n private _defaultConfig: Required<DefaultConfigType> = {} as Required<DefaultConfigType>\n private _defaultStyle: Required<DefaultStyleType> = {} as Required<DefaultStyleType>\n private startCallback?: StartCallbackType\n private endCallback?: EndCallbackType\n private Radius = 0 // 大转盘半径\n private prizeRadius = 0 // 奖品区域半径\n private prizeDeg = 0 // 奖品数学角度\n private prizeAng = 0 // 奖品运算角度\n private rotateDeg = 0 // 转盘旋转角度\n private maxBtnRadius = 0 // 最大按钮半径\n private startTime = 0 // 开始时间戳\n private endTime = 0 // 停止时间戳\n private stopDeg = 0 // 刻舟求剑\n private endDeg = 0 // 停止角度\n private FPS = 16.6 // 屏幕刷新率\n /**\n * 游戏当前的阶段\n * step = 0 时, 游戏尚未开始\n * step = 1 时, 此时处于加速阶段\n * step = 2 时, 此时处于匀速阶段\n * step = 3 时, 此时处于减速阶段\n */\n private step: 0 | 1 | 2 | 3 = 0\n /**\n * 中奖索引\n * prizeFlag = undefined 时, 处于开始抽奖阶段, 正常旋转\n * prizeFlag >= 0 时, 说明stop方法被调用, 并且传入了中奖索引\n * prizeFlag === -1 时, 说明stop方法被调用, 并且传入了负值, 本次抽奖无效\n */\n private prizeFlag: number | undefined\n private ImageCache = new Map()\n\n /**\n * 大转盘构造器\n * @param config 配置项\n * @param data 抽奖数据\n */\n constructor (config: UserConfigType, data: LuckyWheelConfig) {\n super(config, {\n width: data.width,\n height: data.height\n })\n this.initData(data)\n this.initWatch()\n this.initComputed()\n // 创建前回调函数\n config.beforeCreate?.call(this)\n // 首次初始化\n this.init()\n }\n\n protected resize(): void {\n super.resize()\n this.Radius = Math.min(this.boxWidth, this.boxHeight) / 2\n this.ctx.translate(this.Radius, this.Radius)\n this.draw()\n this.config.afterResize?.()\n }\n\n protected initLucky (): void {\n this.Radius = 0\n this.prizeRadius = 0\n this.prizeDeg = 0\n this.prizeAng = 0\n this.rotateDeg = 0\n this.maxBtnRadius = 0\n this.startTime = 0\n this.endTime = 0\n this.stopDeg = 0\n this.endDeg = 0\n this.FPS = 16.6\n this.prizeFlag = -1\n this.step = 0\n super.initLucky()\n }\n\n /**\n * 初始化数据\n * @param data\n */\n private initData (data: LuckyWheelConfig): void {\n this.$set(this, 'width', data.width)\n this.$set(this, 'height', data.height)\n this.$set(this, 'blocks', data.blocks || [])\n this.$set(this, 'prizes', data.prizes || [])\n this.$set(this, 'buttons', data.buttons || [])\n this.$set(this, 'defaultConfig', data.defaultConfig || {})\n this.$set(this, 'defaultStyle', data.defaultStyle || {})\n this.$set(this, 'startCallback', data.start)\n this.$set(this, 'endCallback', data.end)\n }\n\n /**\n * 初始化属性计算\n */\n private initComputed () {\n // 默认配置\n this.$computed(this, '_defaultConfig', () => {\n const config = {\n gutter: '0px',\n offsetDegree: 0,\n speed: 20,\n speedFunction: 'quad',\n accelerationTime: 2500,\n decelerationTime: 2500,\n stopRange: 0,\n ...this.defaultConfig\n }\n return config\n })\n // 默认样式\n this.$computed(this, '_defaultStyle', () => {\n const style = {\n fontSize: '18px',\n fontColor: '#000',\n fontStyle: 'sans-serif',\n fontWeight: '400',\n background: 'rgba(0,0,0,0)',\n wordWrap: true,\n lengthLimit: '90%',\n ...this.defaultStyle\n }\n return style\n })\n }\n\n /**\n * 初始化观察者\n */\n private initWatch () {\n // 重置宽度\n this.$watch('width', (newVal: string | number) => {\n this.data.width = newVal\n this.resize()\n })\n // 重置高度\n this.$watch('height', (newVal: string | number) => {\n this.data.height = newVal\n this.resize()\n })\n // 观察 blocks 变化收集图片\n this.$watch('blocks', (newData: Array<BlockType>) => {\n this.initImageCache()\n }, { deep: true })\n // 观察 prizes 变化收集图片\n this.$watch('prizes', (newData: Array<PrizeType>) => {\n this.initImageCache()\n }, { deep: true })\n // 观察 buttons 变化收集图片\n this.$watch('buttons', (newData: Array<ButtonType>) => {\n this.initImageCache()\n }, { deep: true })\n this.$watch('defaultConfig', () => this.draw(), { deep: true })\n this.$watch('defaultStyle', () => this.draw(), { deep: true })\n this.$watch('startCallback', () => this.init())\n this.$watch('endCallback', () => this.init())\n }\n\n /**\n * 初始化 canvas 抽奖\n */\n public async init (): Promise<void> {\n this.initLucky()\n const { config } = this\n // 初始化前回调函数\n config.beforeInit?.call(this)\n this.draw() // 先画一次, 防止闪烁\n this.draw() // 再画一次, 拿到正确的按钮轮廓\n // 异步加载图片\n await this.initImageCache()\n // 初始化后回调函数\n config.afterInit?.call(this)\n }\n\n private initImageCache (): Promise<void> {\n return new Promise((resolve) => {\n const willUpdateImgs = {\n blocks: this.blocks.map(block => block.imgs),\n prizes: this.prizes.map(prize => prize.imgs),\n buttons: this.buttons.map(btn => btn.imgs),\n }\n ;(<(keyof typeof willUpdateImgs)[]>Object.keys(willUpdateImgs)).forEach(imgName => {\n const willUpdate = willUpdateImgs[imgName]\n // 循环遍历所有图片\n const allPromise: Promise<void>[] = []\n willUpdate && willUpdate.forEach((imgs, cellIndex) => {\n imgs && imgs.forEach((imgInfo, imgIndex) => {\n allPromise.push(this.loadAndCacheImg(imgName, cellIndex, imgIndex))\n })\n })\n Promise.all(allPromise).then(() => {\n this.draw()\n resolve()\n })\n })\n })\n }\n\n /**\n * canvas点击事件\n * @param e 事件参数\n */\n protected handleClick (e: MouseEvent): void {\n const { ctx } = this\n ctx.beginPath()\n ctx.arc(0, 0, this.maxBtnRadius, 0, Math.PI * 2, false)\n if (!ctx.isPointInPath(e.offsetX, e.offsetY)) return\n if (this.step !== 0) return\n this.startCallback?.(e)\n }\n\n /**\n * 根据索引单独加载指定图片并缓存\n * @param cellName 模块名称\n * @param cellIndex 模块索引\n * @param imgName 模块对应的图片缓存\n * @param imgIndex 图片索引\n */\n private async loadAndCacheImg (\n cellName: 'blocks' | 'prizes' | 'buttons',\n cellIndex: number,\n imgIndex: number,\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n // 获取图片信息\n const cell: BlockType | PrizeType | ButtonType = this[cellName][cellIndex]\n if (!cell || !cell.imgs) return\n const imgInfo = cell.imgs[imgIndex]\n if (!imgInfo) return\n // 异步加载图片\n this.loadImg(imgInfo.src, imgInfo).then(async currImg => {\n if (typeof imgInfo.formatter === 'function') {\n currImg = await Promise.resolve(imgInfo.formatter.call(this, currImg))\n }\n this.ImageCache.set(imgInfo['src'], currImg)\n resolve()\n }).catch(err => {\n console.error(`${cellName}[${cellIndex}].imgs[${imgIndex}] ${err}`)\n reject()\n })\n })\n }\n\n private drawBlock (radius: number, block: BlockType, blockIndex: number): void {\n const { ctx } = this\n if (hasBackground(block.background)) {\n ctx.beginPath()\n ctx.fillStyle = block.background!\n ctx.arc(0, 0, radius, 0, Math.PI * 2, false)\n ctx.fill()\n }\n block.imgs && block.imgs.forEach((imgInfo, imgIndex) => {\n const blockImg = this.ImageCache.get(imgInfo.src)\n if (!blockImg) return\n // 绘制图片\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(blockImg, imgInfo, radius * 2, radius * 2)\n const [xAxis, yAxis] = [this.getOffsetX(trueWidth) + this.getLength(imgInfo.left, radius * 2), this.getLength(imgInfo.top, radius * 2) - radius]\n ctx.save()\n imgInfo.rotate && ctx.rotate(getAngle(this.rotateDeg))\n this.drawImage(ctx, blockImg, xAxis, yAxis, trueWidth, trueHeight)\n ctx.restore()\n })\n }\n\n /**\n * 开始绘制\n */\n protected draw (): void {\n const { config, ctx, _defaultConfig, _defaultStyle } = this\n // 触发绘制前回调\n config.beforeDraw?.call(this, ctx)\n // 清空画布\n ctx.clearRect(-this.Radius, -this.Radius, this.Radius * 2, this.Radius * 2)\n // 计算 padding 并绘制 blocks 边框\n this.prizeRadius = this.blocks.reduce((radius, block, blockIndex) => {\n this.drawBlock(radius, block, blockIndex)\n return radius - this.getLength(block.padding && block.padding.split(' ')[0])\n }, this.Radius)\n // 计算起始弧度\n this.prizeDeg = 360 / this.prizes.length\n this.prizeAng = getAngle(this.prizeDeg)\n const shortSide = this.prizeRadius * Math.sin(this.prizeAng / 2) * 2\n // 起始角度调整到正上方, 并且减去半个扇形角度\n let start = getAngle(this.rotateDeg - 90 + this.prizeDeg / 2 + _defaultConfig.offsetDegree)\n // 计算文字横坐标\n const getFontX = (font: FontItemType, line: string) => {\n return this.getOffsetX(ctx.measureText(line).width) + this.getLength(font.left, shortSide)\n }\n // 计算文字纵坐标\n const getFontY = (font: FontItemType, height: number, lineIndex: number) => {\n // 优先使用字体行高, 要么使用默认行高, 其次使用字体大小, 否则使用默认字体大小\n const lineHeight = font.lineHeight || _defaultStyle.lineHeight || font.fontSize || _defaultStyle.fontSize\n return this.getLength(font.top, height) + (lineIndex + 1) * this.getLength(lineHeight)\n }\n ctx.save()\n // 绘制prizes奖品区域\n this.prizes.forEach((prize, prizeIndex) => {\n // 计算当前奖品区域中间坐标点\n let currMiddleDeg = start + prizeIndex * this.prizeAng\n // 奖品区域可见高度\n let prizeHeight = this.prizeRadius - this.maxBtnRadius\n // 绘制背景\n const background = prize.background || _defaultStyle.background\n if (hasBackground(background)) {\n ctx.fillStyle = background\n fanShapedByArc(\n ctx, this.maxBtnRadius, this.prizeRadius,\n currMiddleDeg - this.prizeAng / 2,\n currMiddleDeg + this.prizeAng / 2,\n this.getLength(_defaultConfig.gutter),\n )\n ctx.fill()\n }\n // 计算临时坐标并旋转文字\n let x = Math.cos(currMiddleDeg) * this.prizeRadius\n let y = Math.sin(currMiddleDeg) * this.prizeRadius\n ctx.translate(x, y)\n ctx.rotate(currMiddleDeg + getAngle(90))\n // 绘制图片\n prize.imgs && prize.imgs.forEach((imgInfo, imgIndex) => {\n const prizeImg = this.ImageCache.get(imgInfo.src)\n if (!prizeImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(\n prizeImg,\n imgInfo,\n this.prizeAng * this.prizeRadius,\n prizeHeight\n )\n const [xAxis, yAxis] = [\n this.getOffsetX(trueWidth) + this.getLength(imgInfo.left, shortSide),\n this.getLength(imgInfo.top, prizeHeight)\n ]\n this.drawImage(ctx, prizeImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 逐行绘制文字\n prize.fonts && prize.fonts.forEach(font => {\n const fontColor = font.fontColor || _defaultStyle.fontColor\n const fontWeight = font.fontWeight || _defaultStyle.fontWeight\n const fontSize = this.getLength(font.fontSize || _defaultStyle.fontSize)\n const fontStyle = font.fontStyle || _defaultStyle.fontStyle\n const wordWrap = has(font, 'wordWrap') ? font.wordWrap : _defaultStyle.wordWrap\n const lengthLimit = font.lengthLimit || _defaultStyle.lengthLimit\n const lineClamp = font.lineClamp || _defaultStyle.lineClamp\n ctx.fillStyle = fontColor\n ctx.font = `${fontWeight} ${fontSize >> 0}px ${fontStyle}`\n let lines = [], text = String(font.text)\n if (wordWrap) {\n lines = splitText(ctx, removeEnter(text), (lines) => {\n // 三角形临边\n const adjacentSide = this.prizeRadius - getFontY(font, prizeHeight, lines.length)\n // 三角形短边\n const shortSide = adjacentSide * Math.tan(this.prizeAng / 2)\n // 最大宽度\n let maxWidth = shortSide * 2 - this.getLength(_defaultConfig.gutter)\n return this.getLength(lengthLimit, maxWidth)\n }, lineClamp)\n } else {\n lines = text.split('\\n')\n }\n lines.filter(line => !!line).forEach((line, lineIndex) => {\n ctx.fillText(line, getFontX(font, line), getFontY(font, prizeHeight, lineIndex))\n })\n })\n // 修正旋转角度和原点坐标\n ctx.rotate(getAngle(360) - currMiddleDeg - getAngle(90))\n ctx.translate(-x, -y)\n })\n ctx.restore()\n // 绘制按钮\n this.buttons.forEach((btn, btnIndex) => {\n let radius = this.getLength(btn.radius, this.prizeRadius)\n // 绘制背景颜色\n this.maxBtnRadius = Math.max(this.maxBtnRadius, radius)\n if (hasBackground(btn.background)) {\n ctx.beginPath()\n ctx.fillStyle = btn.background as string\n ctx.arc(0, 0, radius, 0, Math.PI * 2, false)\n ctx.fill()\n }\n // 绘制指针\n if (btn.pointer && hasBackground(btn.background)) {\n ctx.beginPath()\n ctx.fillStyle = btn.background as string\n ctx.moveTo(-radius, 0)\n ctx.lineTo(radius, 0)\n ctx.lineTo(0, -radius * 2)\n ctx.closePath()\n ctx.fill()\n }\n // 绘制按钮图片\n btn.imgs && btn.imgs.forEach((imgInfo, imgIndex) => {\n const btnImg = this.ImageCache.get(imgInfo.src)\n if (!btnImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(btnImg, imgInfo, radius * 2, radius * 2)\n const [xAxis, yAxis] = [this.getOffsetX(trueWidth) + this.getLength(imgInfo.left, radius), this.getLength(imgInfo.top, radius)]\n this.drawImage(ctx, btnImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 绘制按钮文字\n btn.fonts && btn.fonts.forEach(font => {\n let fontColor = font.fontColor || _defaultStyle.fontColor\n let fontWeight = font.fontWeight || _defaultStyle.fontWeight\n let fontSize = this.getLength(font.fontSize || _defaultStyle.fontSize)\n let fontStyle = font.fontStyle || _defaultStyle.fontStyle\n ctx.fillStyle = fontColor\n ctx.font = `${fontWeight} ${fontSize >> 0}px ${fontStyle}`\n String(font.text).split('\\n').forEach((line, lineIndex) => {\n ctx.fillText(line, getFontX(font, line), getFontY(font, radius, lineIndex))\n })\n })\n })\n // 触发绘制后回调\n config.afterDraw?.call(this, ctx)\n }\n\n /**\n * 刻舟求剑\n */\n private carveOnGunwaleOfAMovingBoat (): void {\n const { _defaultConfig, prizeFlag, prizeDeg, rotateDeg } = this\n this.endTime = Date.now()\n const stopDeg = this.stopDeg = rotateDeg\n const speed = _defaultConfig.speed\n const stopRange = (Math.random() * prizeDeg - prizeDeg / 2) * this.getLength(_defaultConfig.stopRange)\n let i = 0, prevSpeed = 0, prevDeg = 0\n while (++i) {\n const endDeg = 360 * i - prizeFlag! * prizeDeg - rotateDeg - _defaultConfig.offsetDegree + stopRange - prizeDeg / 2\n let currSpeed = quad.easeOut(this.FPS, stopDeg, endDeg, _defaultConfig.decelerationTime) - stopDeg\n if (currSpeed > speed) {\n this.endDeg = (speed - prevSpeed > currSpeed - speed) ? endDeg : prevDeg\n break\n }\n prevDeg = endDeg\n prevSpeed = currSpeed\n }\n }\n\n /**\n * 对外暴露: 开始抽奖方法\n */\n public play (): void {\n if (this.step !== 0) return\n // 记录游戏开始时间\n this.startTime = Date.now()\n // 重置中奖索引\n this.prizeFlag = void 0\n // 加速阶段\n this.step = 1\n // 触发回调\n this.config.afterStart?.()\n // 开始游戏\n this.run()\n }\n\n /**\n * 对外暴露: 缓慢停止方法\n * @param index 中奖索引\n */\n public stop (index?: number): void {\n if (this.step === 0 || this.step === 3) return\n // 如果没有传递中奖索引, 则通过range属性计算一个\n if (!index && index !== 0) {\n const rangeArr = this.prizes.map(item => item.range)\n index = computeRange(rangeArr)\n }\n // 如果index是负数则停止游戏, 反之则传递中奖索引\n if (index < 0) {\n this.step = 0\n this.prizeFlag = -1\n } else {\n this.step = 2\n this.prizeFlag = index % this.prizes.length\n }\n }\n\n /**\n * 实际开始执行方法\n * @param num 记录帧动画执行多少次\n */\n private run (num: number = 0): void {\n const { rAF, step, prizeFlag, _defaultConfig } = this\n const { accelerationTime, decelerationTime, speed } = _defaultConfig\n // 游戏结束\n if (step === 0) {\n this.endCallback?.(this.prizes.find((prize, index) => index === prizeFlag) || {})\n return\n }\n // 如果等于 -1 就直接停止游戏\n if (prizeFlag === -1) return\n // 计算结束位置\n if (step === 3 && !this.endDeg) this.carveOnGunwaleOfAMovingBoat()\n // 计算时间间隔\n const startInterval = Date.now() - this.startTime\n const endInterval = Date.now() - this.endTime\n let rotateDeg = this.rotateDeg\n // \n if (step === 1 || startInterval < accelerationTime) { // 加速阶段\n // 记录帧率\n this.FPS = startInterval / num\n const currSpeed = quad.easeIn(startInterval, 0, speed, accelerationTime)\n // 加速到峰值后, 进入匀速阶段\n if (currSpeed === speed) {\n this.step = 2\n }\n rotateDeg = rotateDeg + currSpeed % 360\n } else if (step === 2) { // 匀速阶段\n // 速度保持不变\n rotateDeg = rotateDeg + speed % 360\n // 如果 prizeFlag 有值, 则进入减速阶段\n if (prizeFlag !== void 0 && prizeFlag >= 0) {\n this.step = 3\n // 清空上一次的位置信息\n this.stopDeg = 0\n this.endDeg = 0\n }\n } else if (step === 3) { // 减速阶段\n // 开始缓慢停止\n rotateDeg = quad.easeOut(endInterval, this.stopDeg, this.endDeg, decelerationTime)\n if (endInterval >= decelerationTime) {\n this.step = 0\n }\n } else {\n // 出现异常\n this.stop(-1)\n }\n this.rotateDeg = rotateDeg\n this.draw()\n rAF(this.run.bind(this, num + 1))\n }\n\n /**\n * 换算渲染坐标\n * @param x\n * @param y\n */\n protected conversionAxis (x: number, y: number): [number, number] {\n const { config } = this\n return [x / config.dpr - this.Radius, y / config.dpr - this.Radius]\n }\n}\n","import Lucky from './lucky'\nimport { UserConfigType, ImgType, ImgItemType, Tuple } from '../types/index'\nimport SlotMachineConfig, {\n BlockType,\n PrizeType,\n SlotType,\n DefaultConfigType,\n DefaultStyleType,\n EndCallbackType,\n} from '../types/slot'\nimport {\n get,\n has,\n isExpectType,\n removeEnter,\n computePadding,\n hasBackground,\n computeRange,\n splitText,\n getSortedArrayByIndex,\n} from '../utils/index'\nimport { roundRectByArc } from '../utils/math'\nimport { quad } from '../utils/tween'\n\nexport default class SlotMachine extends Lucky {\n // 背景\n private blocks: Array<BlockType> = []\n // 奖品列表\n private prizes: Array<PrizeType> = []\n // 插槽列表\n private slots: Array<SlotType> = []\n // 默认配置\n private defaultConfig: DefaultConfigType = {}\n private _defaultConfig: Required<DefaultConfigType> =\n {} as Required<DefaultConfigType>\n // 默认样式\n private defaultStyle: DefaultStyleType = {}\n private _defaultStyle: Required<DefaultStyleType> =\n {} as Required<DefaultStyleType>\n private endCallback: EndCallbackType = () => {}\n // 离屏canvas\n private _offscreenCanvas?: HTMLCanvasElement\n private cellWidth = 0 // 格子宽度\n private cellHeight = 0 // 格子高度\n private cellAndSpacing = 0 // 格子+间距\n private widthAndSpacing = 0 // 格子宽度+列间距\n private heightAndSpacing = 0 // 格子高度+行间距\n private FPS = 16.6 // 屏幕刷新率\n private scroll: number[] = [] // 滚动的长度\n private stopScroll: number[] = [] // 刻舟求剑\n private endScroll: number[] = [] // 最终停止的长度\n private startTime = 0 // 开始游戏的时间\n private endTime: number[] = [] // 每一列开始停止的时间\n private slotStep: Array<0 | 1 | 2 | 3> = []\n // 默认顺序由 prizes 生成\n private defaultOrder: number[] = []\n /**\n * 游戏当前的整体阶段\n * step = 0 时, 游戏尚未开始\n * step = 1 时, 此时处于加速阶段\n * step = 2 时, 此时处于运行阶段\n */\n private step: 0 | 1 | 2 = 0\n /**\n * 中奖索引\n * prizeFlag = undefined 时, 处于开始抽奖阶段, 正常旋转\n * prizeFlag >= 0 时, 说明stop方法被调用, 并且传入了中奖索引\n * prizeFlag === -1 时, 说明stop方法被调用, 并且传入了负值, 本次抽奖无效\n */\n private prizeFlag: Array<number | undefined> | undefined = void 0\n // 奖品区域几何信息\n private prizeArea?: { x: number; y: number; w: number; h: number }\n // 图片缓存\n private ImageCache = new Map()\n\n /**\n * 老虎机构造器\n * @param config 配置项\n * @param data 抽奖数据\n */\n constructor(config: UserConfigType, data: SlotMachineConfig) {\n super(config, {\n width: data.width,\n height: data.height,\n })\n this.initData(data)\n this.initWatch()\n this.initComputed()\n // 创建前回调函数\n config.beforeCreate?.call(this)\n // 首次初始化\n this.init()\n }\n\n protected resize(): void {\n super.resize()\n this.redrawOffscreenCanvas()\n this.config.afterResize?.()\n }\n\n protected initLucky(): void {\n this.cellWidth = 0\n this.cellHeight = 0\n this.cellAndSpacing = 0\n this.widthAndSpacing = 0\n this.heightAndSpacing = 0\n this.FPS = 16.6\n this.scroll = []\n this.stopScroll = []\n this.endScroll = []\n this.startTime = 0\n this.endTime = []\n this.slotStep = []\n this.prizeFlag = void 0\n this.step = 0\n super.initLucky()\n }\n\n /**\n * 初始化数据\n * @param data\n */\n private initData(data: SlotMachineConfig): void {\n this.$set(this, 'width', data.width)\n this.$set(this, 'height', data.height)\n this.$set(this, 'blocks', data.blocks || [])\n this.$set(this, 'prizes', data.prizes || [])\n this.$set(this, 'slots', data.slots || [])\n this.$set(this, 'defaultConfig', data.defaultConfig || {})\n this.$set(this, 'defaultStyle', data.defaultStyle || {})\n this.$set(this, 'endCallback', data.end)\n }\n\n /**\n * 初始化属性计算\n */\n private initComputed(): void {\n // 默认配置\n this.$computed(this, '_defaultConfig', () => {\n const config = {\n mode: 'vertical',\n rowSpacing: 0,\n colSpacing: 5,\n speed: 20,\n direction: 1,\n accelerationTime: 2500,\n decelerationTime: 2500,\n ...this.defaultConfig,\n }\n config.rowSpacing = this.getLength(config.rowSpacing)\n config.colSpacing = this.getLength(config.colSpacing)\n return config\n })\n // 默认样式\n this.$computed(this, '_defaultStyle', () => {\n return {\n borderRadius: 0,\n fontColor: '#000',\n fontSize: '18px',\n fontStyle: 'sans-serif',\n fontWeight: '400',\n background: 'rgba(0,0,0,0)',\n wordWrap: true,\n lengthLimit: '90%',\n ...this.defaultStyle,\n }\n })\n }\n\n /**\n * 初始化观察者\n */\n private initWatch(): void {\n // 重置宽度\n this.$watch('width', (newVal: string | number) => {\n this.data.width = newVal\n this.resize()\n })\n // 重置高度\n this.$watch('height', (newVal: string | number) => {\n this.data.height = newVal\n this.resize()\n })\n // 监听 blocks 数据的变化\n this.$watch(\n 'blocks',\n (newData: Array<BlockType>) => {\n this.initImageCache()\n },\n { deep: true },\n )\n // 监听 prizes 数据的变化\n this.$watch(\n 'prizes',\n (newData: Array<PrizeType>) => {\n this.initImageCache()\n },\n { deep: true },\n )\n // 监听 prizes 数据的变化\n this.$watch(\n 'slots',\n (newData: Array<PrizeType>) => {\n this.redrawOffscreenCanvas()\n },\n { deep: true },\n )\n this.$watch('defaultConfig', () => this.redrawOffscreenCanvas(), {\n deep: true,\n })\n this.$watch('defaultStyle', () => this.redrawOffscreenCanvas(), {\n deep: true,\n })\n this.$watch('endCallback', () => this.init())\n }\n\n /**\n * 初始化 canvas 抽奖\n */\n public async init(): Promise<void> {\n this.initLucky()\n const { config } = this\n // 初始化前回调函数\n config.beforeInit?.call(this)\n // 先绘制一次\n this.drawOffscreenCanvas()\n this.draw()\n // 异步加载图片\n await this.initImageCache()\n // 初始化后回调函数\n config.afterInit?.call(this)\n }\n\n private redrawOffscreenCanvas(): void {\n this.drawOffscreenCanvas()\n this.draw()\n }\n\n private initImageCache(): Promise<void> {\n return new Promise((resolve) => {\n const willUpdateImgs = {\n blocks: this.blocks.map((block) => block.imgs),\n prizes: this.prizes.map((prize) => prize.imgs),\n }\n ;(<(keyof typeof willUpdateImgs)[]>Object.keys(willUpdateImgs)).forEach(\n (imgName) => {\n const willUpdate = willUpdateImgs[imgName]\n // 循环遍历所有图片\n const allPromise: Promise<void>[] = []\n willUpdate &&\n willUpdate.forEach((imgs, cellIndex) => {\n imgs &&\n imgs.forEach((imgInfo, imgIndex) => {\n allPromise.push(\n this.loadAndCacheImg(imgName, cellIndex, imgIndex),\n )\n })\n })\n Promise.all(allPromise).then(() => {\n this.drawOffscreenCanvas()\n this.draw()\n resolve()\n })\n },\n )\n })\n }\n\n /**\n * 根据索引单独加载指定图片并缓存\n * @param cellName 模块名称\n * @param cellIndex 模块索引\n * @param imgName 模块对应的图片缓存\n * @param imgIndex 图片索引\n */\n private async loadAndCacheImg(\n cellName: 'blocks' | 'prizes',\n cellIndex: number,\n imgIndex: number,\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n let cell: BlockType | PrizeType = this[cellName][cellIndex]\n if (!cell || !cell.imgs) return\n const imgInfo = cell.imgs[imgIndex]\n if (!imgInfo) return\n // 异步加载图片\n this.loadImg(imgInfo.src, imgInfo)\n .then(async (currImg) => {\n if (typeof imgInfo.formatter === 'function') {\n currImg = await Promise.resolve(\n imgInfo.formatter.call(this, currImg),\n )\n }\n this.ImageCache.set(imgInfo['src'], currImg)\n resolve()\n })\n .catch((err) => {\n console.error(`${cellName}[${cellIndex}].imgs[${imgIndex}] ${err}`)\n reject()\n })\n })\n }\n\n /**\n * 绘制离屏canvas\n */\n protected drawOffscreenCanvas(): void {\n const { _defaultConfig, _defaultStyle } = this\n const { w, h } = this.drawBlocks()!\n // 计算单一奖品格子的宽度和高度\n const prizesLen = this.prizes.length\n const { cellWidth, cellHeight, widthAndSpacing, heightAndSpacing } =\n this.displacementWidthOrHeight()\n this.defaultOrder = new Array(prizesLen).fill(void 0).map((v, i) => i)\n let maxOrderLen = 0,\n maxOffWidth = 0,\n maxOffHeight = 0\n this.slots.forEach((slot, slotIndex) => {\n // 初始化 scroll 的值\n if (this.scroll[slotIndex] === void 0) this.scroll[slotIndex] = 0\n // 如果没有order属性, 就填充prizes\n const order = slot.order || this.defaultOrder\n // 计算最大值\n const currLen = order.length\n maxOrderLen = Math.max(maxOrderLen, currLen)\n maxOffWidth = Math.max(maxOffWidth, w + widthAndSpacing * currLen)\n maxOffHeight = Math.max(maxOffHeight, h + heightAndSpacing * currLen)\n })\n // 创建一个离屏Canvas来存储画布的内容\n const { _offscreenCanvas, _ctx } = this.getOffscreenCanvas(\n maxOffWidth,\n maxOffHeight,\n )!\n this._offscreenCanvas = _offscreenCanvas\n // 绘制插槽\n this.slots.forEach((slot, slotIndex) => {\n const cellX = cellWidth * slotIndex\n const cellY = cellHeight * slotIndex\n let lengthOfCopy = 0\n // 绘制奖品\n const newPrizes = getSortedArrayByIndex(\n this.prizes,\n slot.order || this.defaultOrder,\n )\n // 如果没有奖品则打断逻辑\n if (!newPrizes.length) return\n newPrizes.forEach((cell, cellIndex) => {\n if (!cell) return\n const prizesX =\n widthAndSpacing * cellIndex + _defaultConfig.colSpacing / 2\n const prizesY =\n heightAndSpacing * cellIndex + _defaultConfig.rowSpacing / 2\n const [_x, _y, spacing] = this.displacement(\n [cellX, prizesY, heightAndSpacing],\n [prizesX, cellY, widthAndSpacing],\n )\n lengthOfCopy += spacing\n // 绘制背景\n const background = cell.background || _defaultStyle.background\n if (hasBackground(background)) {\n const borderRadius = this.getLength(\n has(cell, 'borderRadius')\n ? cell.borderRadius\n : _defaultStyle.borderRadius,\n )\n roundRectByArc(_ctx, _x, _y, cellWidth, cellWidth, borderRadius)\n _ctx.fillStyle = background\n _ctx.fill()\n }\n // 绘制图片\n cell.imgs &&\n cell.imgs.forEach((imgInfo, imgIndex) => {\n const cellImg = this.ImageCache.get(imgInfo.src)\n if (!cellImg) return\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(\n cellImg,\n imgInfo,\n cellWidth,\n cellHeight,\n )\n const [xAxis, yAxis] = [\n _x +\n this.getOffsetX(trueWidth, cellWidth) +\n this.getLength(imgInfo.left, cellWidth),\n _y + this.getLength(imgInfo.top, cellHeight),\n ]\n this.drawImage(_ctx, cellImg, xAxis, yAxis, trueWidth, trueHeight)\n })\n // 绘制文字\n cell.fonts &&\n cell.fonts.forEach((font) => {\n // 字体样式\n const style = font.fontStyle || _defaultStyle.fontStyle\n // 字体加粗\n const fontWeight = font.fontWeight || _defaultStyle.fontWeight\n // 字体大小\n const size = this.getLength(font.fontSize || _defaultStyle.fontSize)\n // 字体行高\n const lineHeight =\n font.lineHeight ||\n _defaultStyle.lineHeight ||\n font.fontSize ||\n _defaultStyle.fontSize\n const wordWrap = has(font, 'wordWrap')\n ? font.wordWrap\n : _defaultStyle.wordWrap\n const lengthLimit = font.lengthLimit || _defaultStyle.lengthLimit\n const lineClamp = font.lineClamp || _defaultStyle.lineClamp\n _ctx.font = `${fontWeight} ${size >> 0}px ${style}`\n _ctx.fillStyle = font.fontColor || _defaultStyle.fontColor\n let lines = [],\n text = String(font.text)\n // 计算文字换行\n if (wordWrap) {\n // 最大宽度\n let maxWidth = this.getLength(lengthLimit, cellWidth)\n lines = splitText(\n _ctx,\n removeEnter(text),\n () => maxWidth,\n lineClamp,\n )\n } else {\n lines = text.split('\\n')\n }\n lines.forEach((line, lineIndex) => {\n _ctx.fillText(\n line,\n _x +\n this.getOffsetX(_ctx.measureText(line).width, cellWidth) +\n this.getLength(font.left, cellWidth),\n _y +\n this.getLength(font.top, cellHeight) +\n (lineIndex + 1) * this.getLength(lineHeight),\n )\n })\n })\n })\n const [_x, _y, _w, _h] = this.displacement(\n [cellX, 0, cellWidth, lengthOfCopy],\n [0, cellY, lengthOfCopy, cellHeight],\n )\n let drawLen = lengthOfCopy\n while (drawLen < maxOffHeight + lengthOfCopy) {\n const [drawX, drawY] = this.displacement([_x, drawLen], [drawLen, _y])\n this.drawImage(\n _ctx,\n _offscreenCanvas,\n _x,\n _y,\n _w,\n _h,\n drawX,\n drawY,\n _w,\n _h,\n )\n drawLen += lengthOfCopy\n }\n })\n }\n\n /**\n * 绘制背景区域\n */\n protected drawBlocks(): SlotMachine['prizeArea'] {\n const { config, ctx, _defaultConfig, _defaultStyle } = this\n // 绘制背景区域, 并计算奖品区域\n return (this.prizeArea = this.blocks.reduce(\n ({ x, y, w, h }, block, blockIndex) => {\n const [paddingTop, paddingBottom, paddingLeft, paddingRight] =\n computePadding(block, this.getLength.bind(this))\n const r = block.borderRadius ? this.getLength(block.borderRadius) : 0\n // 绘制边框\n const background = block.background || _defaultStyle.background\n if (hasBackground(background)) {\n roundRectByArc(ctx, x, y, w, h, r)\n ctx.fillStyle = background\n ctx.fill()\n }\n // 绘制图片\n block.imgs &&\n block.imgs.forEach((imgInfo, imgIndex) => {\n const blockImg = this.ImageCache.get(imgInfo.src)\n if (!blockImg) return\n // 绘制图片\n const [trueWidth, trueHeight] = this.computedWidthAndHeight(\n blockImg,\n imgInfo,\n w,\n h,\n )\n const [xAxis, yAxis] = [\n this.getOffsetX(trueWidth, w) + this.getLength(imgInfo.left, w),\n this.getLength(imgInfo.top, h),\n ]\n this.drawImage(\n ctx,\n blockImg,\n x + xAxis,\n y + yAxis,\n trueWidth,\n trueHeight,\n )\n })\n return {\n x: x + paddingLeft,\n y: y + paddingTop,\n w: w - paddingLeft - paddingRight,\n h: h - paddingTop - paddingBottom,\n }\n },\n { x: 0, y: 0, w: this.boxWidth, h: this.boxHeight },\n ))\n }\n\n /**\n * 绘制老虎机抽奖\n */\n protected draw(): void {\n const { config, ctx, _defaultConfig, _defaultStyle } = this\n // 触发绘制前回调\n config.beforeDraw?.call(this, ctx)\n // 清空画布\n ctx.clearRect(0, 0, this.boxWidth, this.boxHeight)\n // 绘制背景\n const { x, y, w, h } = this.drawBlocks()!\n // 绘制插槽\n if (!this._offscreenCanvas) return\n const {\n cellWidth,\n cellHeight,\n cellAndSpacing,\n widthAndSpacing,\n heightAndSpacing,\n } = this\n this.slots.forEach((slot, slotIndex) => {\n const order = slot.order || this.defaultOrder\n // 绘制临界点\n const _p = cellAndSpacing * order.length\n // 调整奖品垂直居中\n const start = this.displacement(\n -(h - heightAndSpacing) / 2,\n -(w - widthAndSpacing) / 2,\n )\n let scroll = this.scroll[slotIndex] + start\n // scroll 会无限累加 1 / -1\n if (scroll < 0) {\n scroll = (scroll % _p) + _p\n }\n if (scroll > _p) {\n scroll = scroll % _p\n }\n const [sx, sy, sw, sh] = this.displacement(\n [cellWidth * slotIndex, scroll, cellWidth, h],\n [scroll, cellHeight * slotIndex, w, cellHeight],\n )\n const [dx, dy, dw, dh] = this.displacement(\n [x + widthAndSpacing * slotIndex, y, cellWidth, h],\n [x, y + heightAndSpacing * slotIndex, w, cellHeight],\n )\n this.drawImage(\n ctx,\n this._offscreenCanvas!,\n sx,\n sy,\n sw,\n sh,\n dx,\n dy,\n dw,\n dh,\n )\n })\n }\n\n /**\n * 刻舟求剑\n */\n private carveOnGunwaleOfAMovingBoat(slotIndex: number): void {\n const { _defaultConfig, prizeFlag, cellAndSpacing } = this\n const slot = this.slots[slotIndex]\n const order = slot.order || this.defaultOrder\n if (!order.length || prizeFlag === void 0) return\n const speed = Math.abs(slot.speed || _defaultConfig.speed)\n const direction = slot.direction || _defaultConfig.direction\n const orderIndex = order.findIndex(\n (prizeIndex) => prizeIndex === prizeFlag[slotIndex],\n )\n const _p = cellAndSpacing * order.length\n const stopScroll = (this.stopScroll[slotIndex] = this.scroll[slotIndex])\n this.endTime[slotIndex] = Date.now()\n let i = 0\n while (++i) {\n const endScroll =\n cellAndSpacing * orderIndex + _p * i * direction - stopScroll\n const currSpeed =\n quad.easeOut(\n this.FPS,\n stopScroll,\n endScroll,\n _defaultConfig.decelerationTime,\n ) - stopScroll\n if (Math.abs(currSpeed) > speed) {\n this.endScroll[slotIndex] = endScroll\n break\n }\n }\n }\n\n private hasAllPrizeFlag(): boolean {\n return !!this.prizeFlag?.length && this.prizeFlag.every((flag) => flag !== void 0)\n }\n\n private isAllSlotStopped(): boolean {\n return this.slots.every((slot, slotIndex) => {\n const order = slot.order || this.defaultOrder\n return !order.length || this.slotStep[slotIndex] === 0\n })\n }\n\n private getEndPrize(): PrizeType | undefined {\n if (!this.hasAllPrizeFlag()) return void 0\n const prizeFlag = this.prizeFlag as number[]\n let flag = prizeFlag[0]\n for (let i = 0; i < this.slots.length; i++) {\n const slot = this.slots[i]\n const currFlag = prizeFlag[i]\n const order = slot.order || this.defaultOrder\n if (!order?.includes(currFlag) || flag !== currFlag) {\n flag = -1\n break\n }\n }\n return this.prizes.find((prize, index) => index === flag) || void 0\n }\n\n /**\n * 对外暴露: 开始抽奖方法\n */\n public play(): void {\n if (this.step !== 0) return\n // 记录开始游戏的时间\n this.startTime = Date.now()\n // 清空中奖索引\n this.prizeFlag = void 0\n this.stopScroll = []\n this.endScroll = []\n this.endTime = []\n this.slotStep = this.slots.map((slot) => {\n const order = slot.order || this.defaultOrder\n return order.length ? 1 : 0\n })\n // 开始加速\n this.step = 1\n // 触发回调\n this.config.afterStart?.()\n // 开始渲染\n this.run()\n }\n\n public stop(index: number | number[], slotIndex?: number): void {\n if (this.step === 0) return\n // 设置中奖索引\n if (typeof slotIndex === 'number') {\n if (!Number.isInteger(slotIndex) || slotIndex < 0 || slotIndex >= this.slots.length) {\n return console.error(`stop(${index}, ${slotIndex}) slotIndex 超出范围`)\n }\n if (typeof index !== 'number') {\n return console.error(`stop(${JSON.stringify(index)}, ${slotIndex}) 参数类型不正确`)\n }\n if (this.prizeFlag === void 0 || !this.prizeFlag.length) {\n this.prizeFlag = new Array(this.slots.length).fill(void 0)\n }\n this.prizeFlag[slotIndex] = index\n } else if (typeof index === 'number') {\n this.prizeFlag = new Array(this.slots.length).fill(index)\n } else if (isExpectType(index, 'array')) {\n if (index.length === this.slots.length) {\n this.prizeFlag = index\n } else {\n this.stop(-1)\n return console.error(`stop([${index}]) 参数长度的不正确`)\n }\n } else {\n this.stop(-1)\n return console.error(`stop() 无法识别的参数类型 ${typeof index}`)\n }\n // 如果包含负数则停止游戏, 反之则继续游戏\n if (this.prizeFlag?.includes(-1)) {\n this.prizeFlag = []\n this.slotStep = this.slotStep.map(() => 0)\n // 停止游戏\n this.step = 0\n } else {\n // 进入匀速\n this.step = 2\n }\n }\n\n /**\n * 让游戏动起来\n * @param num 记录帧动画执行多少次\n */\n private run(num: number = 0): void {\n const { rAF, _defaultConfig, cellAndSpacing, slots } = this\n const { accelerationTime, decelerationTime } = _defaultConfig\n const prizeFlag = this.prizeFlag\n if (this.step === 0) {\n if (this.hasAllPrizeFlag() && this.isAllSlotStopped()) {\n this.endCallback?.(this.getEndPrize())\n }\n return\n }\n // 如果长度为 0 就直接停止游戏\n if (prizeFlag !== void 0 && !prizeFlag.length) return\n // 计算时间间隔\n const startInterval = Date.now() - this.startTime\n if (startInterval >= accelerationTime && this.step === 1) {\n this.step = 2\n }\n // 分别计算对应插槽的加速度\n slots.forEach((slot, slotIndex) => {\n const order = slot.order || this.defaultOrder\n if (!order || !order.length) return\n const _p = cellAndSpacing * order.length\n const speed = Math.abs(slot.speed || _defaultConfig.speed)\n const direction = slot.direction || _defaultConfig.direction\n const slotStep = this.slotStep[slotIndex] || 0\n let scroll = 0,\n prevScroll = this.scroll[slotIndex]\n if (!slotStep) return\n if (slotStep === 1 || startInterval < accelerationTime) {\n // 加速阶段\n // 记录帧率\n this.FPS = startInterval / num\n const currSpeed = quad.easeIn(startInterval, 0, speed, accelerationTime)\n // 加速到最大速度后, 即可进入匀速阶段\n if (currSpeed === speed) {\n this.slotStep[slotIndex] = 2\n }\n scroll = (prevScroll + currSpeed * direction) % _p\n } else if (slotStep === 2) {\n // 匀速阶段\n // 速度保持不变\n scroll = (prevScroll + speed * direction) % _p\n // 当前列已经拿到中奖索引, 则单独进入减速阶段\n if (prizeFlag?.[slotIndex] !== void 0) {\n this.slotStep[slotIndex] = 3\n this.scroll[slotIndex] = scroll\n this.carveOnGunwaleOfAMovingBoat(slotIndex)\n }\n } else if (slotStep === 3) {\n // 减速阶段\n // 开始缓慢停止\n const stopScroll = this.stopScroll[slotIndex]\n const endScroll = this.endScroll[slotIndex]\n const endInterval = Date.now() - this.endTime[slotIndex]\n scroll = quad.easeOut(\n endInterval,\n stopScroll,\n endScroll,\n decelerationTime,\n )\n if (endInterval >= decelerationTime) {\n scroll = stopScroll + endScroll\n this.slotStep[slotIndex] = 0\n }\n }\n this.scroll[slotIndex] = scroll\n })\n this.draw()\n if (this.isAllSlotStopped()) {\n this.step = 0\n if (this.hasAllPrizeFlag()) {\n this.endCallback?.(this.getEndPrize())\n }\n return\n }\n rAF(this.run.bind(this, num + 1))\n }\n\n // 根据mode置换数值\n private displacement<T>(a: T, b: T): T {\n return this._defaultConfig.mode === 'horizontal' ? b : a\n }\n\n // 根据mode计算宽高\n private displacementWidthOrHeight() {\n const mode = this._defaultConfig.mode\n const slotsLen = this.slots.length\n const { colSpacing, rowSpacing } = this._defaultConfig\n const { x, y, w, h } = this.prizeArea || this.drawBlocks()!\n let cellWidth = 0,\n cellHeight = 0,\n widthAndSpacing = 0,\n heightAndSpacing = 0\n if (mode === 'horizontal') {\n cellHeight = this.cellHeight =\n (h - rowSpacing * (slotsLen - 1)) / slotsLen\n cellWidth = this.cellWidth = cellHeight\n } else {\n cellWidth = this.cellWidth = (w - colSpacing * (slotsLen - 1)) / slotsLen\n cellHeight = this.cellHeight = cellWidth\n }\n widthAndSpacing = this.widthAndSpacing = this.cellWidth + colSpacing\n heightAndSpacing = this.heightAndSpacing = this.cellHeight + rowSpacing\n if (mode === 'horizontal') {\n this.cellAndSpacing = widthAndSpacing\n } else {\n this.cellAndSpacing = heightAndSpacing\n }\n return {\n cellWidth,\n cellHeight,\n widthAndSpacing,\n heightAndSpacing,\n }\n }\n}\n","import { ImgType } from '../types/index'\nimport { roundRectByArc } from './math'\n\n/**\n * 根据路径获取图片对象\n * @param { string } src 图片路径\n * @returns { Promise<HTMLImageElement> } 图片标签\n */\nexport const getImage = (src: string): Promise<ImgType> => {\n return new Promise((resolve, reject) => {\n const img = new Image()\n img.onload = () => resolve(img)\n img.onerror = err => reject(err)\n img.src = src\n })\n}\n\n/**\n * 切割圆角\n * @param img 将要裁剪的图片对象\n * @param radius 裁剪的圆角半径\n * @returns 返回一个离屏 canvas 用于渲染\n */\nexport const cutRound = (img: ImgType, radius: number): ImgType => {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')!\n const { width, height } = img\n canvas.width = width\n canvas.height = height\n roundRectByArc(ctx, 0, 0, width, height, radius)\n ctx.clip()\n ctx.drawImage(img, 0, 0, width, height)\n return canvas\n}\n\n/**\n * 透明度\n * @param img 将要处理的图片对象\n * @param opacity 透明度\n * @returns 返回一个离屏 canvas 用于渲染\n */\nexport const opacity = (\n img: ImgType,\n opacity: number\n): ImgType => {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')!\n const { width, height } = img\n canvas.width = width\n canvas.height = height\n // 绘制图片, 部分浏览器不支持 filter 属性, 需要处理兼容\n if (typeof ctx.filter === 'string') {\n ctx.filter = `opacity(${opacity * 100}%)`\n ctx.drawImage(img, 0, 0, width, height)\n } else {\n ctx.drawImage(img, 0, 0, width, height)\n const imageData = ctx.getImageData(0, 0, width, height)\n const { data } = imageData\n const len = data.length\n for (let i = 0; i < len; i += 4) {\n const alpha = data[i + 3]\n if (alpha !== 0) data[i + 3] = alpha * opacity\n }\n ctx.putImageData(imageData, 0, 0)\n }\n return canvas\n}\n\n/**\n * 权重矩阵\n * @param radius 模糊半径\n * @param sigma \n * @returns 返回一个权重和为1的矩阵\n */\nconst getMatrix = (radius: number, sigma?: number): number[] => {\n sigma = sigma || radius / 3\n const r = Math.ceil(radius)\n const sigma_2 = sigma * sigma\n const sigma2_2 = 2 * sigma_2\n const denominator = 1 / (2 * Math.PI * sigma_2)\n const matrix = []\n let total = 0\n // 计算权重矩阵\n for (let x = -r; x <= r; x++) {\n for (let y = -r; y <= r; y++) {\n // 套用二维高斯函数得到每个点的权重\n const res = denominator * Math.exp(-(x * x + y * y) / sigma2_2)\n matrix.push(res)\n total += res\n }\n }\n // 让矩阵中所有权重的和等于1\n for (let i = 0; i < matrix.length; i++) {\n matrix[i] /= total\n }\n return matrix\n}\n\n/**\n * 高斯模糊\n * @param img 将要处理的图片对象\n * @param radius 模糊半径\n * @returns 返回一个离屏 canvas 用于渲染\n */\nexport const blur = (\n img: ImgType,\n radius: number\n): ImgType => {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')!\n const { width, height } = img\n // 设置图片宽高\n canvas.width = width\n canvas.height = height\n ctx.drawImage(img, 0, 0, width, height)\n const ImageData = ctx.getImageData(0, 0, width, height)\n const { data } = ImageData\n const matrix = getMatrix(radius)\n const r = Math.ceil(radius)\n const w = width * 4\n const cols = r * 2 + 1\n const len = data.length, matrixLen = matrix.length\n for (let i = 0; i < len; i += 4) {\n // 处理\n }\n console.log(ImageData)\n ctx.putImageData(ImageData, 0, 0)\n return canvas\n}\n\nexport const getBase64Image = () => {\n\n}\n"],"names":["Array","prototype","includes","Object","defineProperty","value","valueToFind","fromIndex","this","TypeError","o","len","length","n","k","Math","max","abs","sameValueZero","x","y","isNaN","String","search","start","indexOf","find","predicate","thisArg","arguments","kValue","call","isExpectType","param","types","some","type","toString","slice","toLowerCase","has","data","key","hasOwnProperty","removeEnter","str","filter","s","join","hasBackground","color","toLocaleLowerCase","trim","test","alpha","exec","num","NaN","Number","computePadding","block","getLength","_a","padding","split","map","paddingTop","paddingBottom","paddingLeft","paddingRight","res","throttle","fn","wait","timeId","args","setTimeout","apply","clearTimeout","computeRange","rangeArr","ascendingArr","sum","reduce","prev","curr","push","random","findIndex","splitText","ctx","text","getWidth","lineClamp","Infinity","lines","EndWidth","measureText","width","i","currWidth","maxWidth","Dep","constructor","__publicField","subs","addSub","sub","notify","forEach","update","hasProto","def","obj","val","enumerable","writable","configurable","oldArrayProto","newArrayProto","create","method","luckyOb","walk","dep","Observer","isArray","getOwnPropertyNames","keys","defineReactive","observe","property","getOwnPropertyDescriptor","getter","get","setter","set","childOb","target","newVal","uid","Watcher","$lucky","expr","cb","options","id","deep","path","segments","segment","parsePath","dfs","traverse","oldVal","Lucky","config","version","el","nodeType","divElement","flag","document","querySelector","canvasElement","createElement","appendChild","getContext","setAttribute","addEventListener","handleClick","e","initWindowFunction","console","error","window","resize","MutationObserver","documentElement","attributes","_b","beforeResize","setHTMLFontSize","setDpr","resetWidthAndHeight","zoomCanvas","initLucky","boxWidth","boxHeight","getComputedStyle","htmlFontSize","fontSize","clearCanvas","height","clearRect","dpr","devicePixelRatio","offsetWidth","offsetHeight","style","overflow","transform","scale","rAF","requestAnimationFrame","callback","setInterval","clearInterval","timeout","isWeb","loadImg","src","info","resolveName","Promise","resolve","reject","imgObj","Image","onload","onerror","drawImage","rectInfo","drawImg","miniProgramOffCtx","temp","getImageData","putImageData","index","err","computedWidthAndHeight","imgInfo","maxHeight","trueWidth","trueHeight","changeUnits","denominator","replace","unit","handleCssUnit","px","rem","vw","innerWidth","otherHandleCssUnit","maxLength","getOffsetX","getOffscreenCanvas","_offscreenCanvas","_ctx","$set","$computed","$watch","handler","watchOpt","watcher","immediate","getAngle","deg","PI","fanShapedByArc","minRadius","maxRadius","end","gutter","beginPath","maxGutter","maxStart","maxEnd","r","arc","lineTo","sin","cos","toFixed","closePath","roundRectByArc","w","h","min","moveTo","quad","t","b","c","d","super","Map","initData","initWatch","initComputed","beforeCreate","init","draw","afterResize","cellWidth","cellHeight","startTime","endTime","currIndex","stopIndex","endIndex","demo","timer","FPS","prizeFlag","step","rows","cols","blocks","prizes","buttons","button","defaultConfig","defaultStyle","activeStyle","__spreadValues","speed","accelerationTime","decelerationTime","borderRadius","fontColor","fontStyle","fontWeight","background","shadow","wordWrap","lengthLimit","newData","initImageCache","__async","beforeInit","afterInit","btnImgs","btn","imgs","willUpdateImgs","prize","imgName","willUpdate","allPromise","cellIndex","imgIndex","loadAndCacheImg","all","then","getGeometricProperty","col","row","rect","isPointInPath","offsetX","offsetY","startCallback","cellName","cell","request","_0","defaultImg","activeImg","formatter","ImageCache","catch","_defaultConfig","_defaultStyle","_activeStyle","beforeDraw","cells","prizeArea","blockIndex","bind","fillStyle","handleBackground","fill","blockImg","xAxis","yAxis","left","top","isActive","shadowColor","shadowOffsetX","shadowOffsetY","shadowBlur","cellImg","renderImg","fonts","font","size","lineHeight","line","lineIndex","fillText","afterDraw","context","shift","direction","getLenOfTanDeg","tan","gradient","createLinearGradient","item","addColorStop","getLinearGradient","carveOnGunwaleOfAMovingBoat","Date","now","prevSpeed","prevIndex","currSpeed","play","afterStart","run","stop","range","endCallback","startInterval","endInterval","conversionAxis","Radius","translate","prizeRadius","prizeDeg","prizeAng","rotateDeg","maxBtnRadius","stopDeg","endDeg","offsetDegree","speedFunction","stopRange","currImg","drawBlock","radius","save","rotate","restore","shortSide","getFontX","getFontY","prizeIndex","currMiddleDeg","prizeHeight","prizeImg","btnIndex","pointer","btnImg","prevDeg","redrawOffscreenCanvas","cellAndSpacing","widthAndSpacing","heightAndSpacing","scroll","stopScroll","endScroll","slotStep","slots","mode","rowSpacing","colSpacing","drawOffscreenCanvas","drawBlocks","prizesLen","displacementWidthOrHeight","defaultOrder","v","maxOffWidth","maxOffHeight","slot","slotIndex","currLen","order","cellX","cellY","lengthOfCopy","newPrizes","arr","getSortedArrayByIndex","prizesX","prizesY","_x","_y","spacing","displacement","_w","_h","drawLen","drawX","drawY","_p","sx","sy","sw","sh","dx","dy","dw","dh","orderIndex","hasAllPrizeFlag","every","isAllSlotStopped","getEndPrize","currFlag","isInteger","JSON","stringify","prevScroll","a","slotsLen","img","canvas","clip","opacity","imageData"],"mappings":"oEAKKA,MAAMC,UAAUC,UACZC,OAAAC,eAAeJ,MAAMC,UAAW,WAAY,CACjDI,MAAO,SAASC,EAAaC,GAE3B,GAAY,MAARC,KACI,MAAA,IAAIC,UAAU,iCAIlB,IAAAC,EAAIP,OAAOK,MAGXG,EAAMD,EAAEE,SAAW,EAGvB,GAAY,IAARD,EACK,OAAA,EAKT,IAAIE,EAAgB,EAAZN,EAOJO,EAAIC,KAAKC,IAAIH,GAAK,EAAIA,EAAIF,EAAMI,KAAKE,IAAIJ,GAAI,GAExC,SAAAK,EAAcC,EAAGC,GACxB,OAAOD,IAAMC,GAAmB,iBAAND,GAA+B,iBAANC,GAAkBC,MAAMF,IAAME,MAAMD,EACzF,CAGA,KAAON,EAAIH,GAAK,CAGd,GAAIO,EAAcR,EAAEI,GAAIR,GACf,OAAA,EAGTQ,GACF,CAGO,OAAA,CACT,IAKCQ,OAAOrB,UAAUC,WACpBoB,OAAOrB,UAAUC,SAAW,SAASqB,EAAQC,GAK3C,MAHqB,iBAAVA,IACDA,EAAA,KAENA,EAAQD,EAAOX,OAASJ,KAAKI,UAGQ,IAAhCJ,KAAKiB,QAAQF,EAAQC,KAM7BxB,MAAMC,UAAUyB,MACZvB,OAAAC,eAAeJ,MAAMC,UAAW,OAAQ,CAC7CI,MAAO,SAASsB,GAEd,GAAY,MAARnB,KACI,MAAA,IAAIC,UAAU,iCAElB,IAAAC,EAAIP,OAAOK,MAEXG,EAAMD,EAAEE,SAAW,EAEnB,GAAqB,mBAAde,EACH,MAAA,IAAIlB,UAAU,gCAOtB,IAJI,IAAAmB,EAAUC,UAAU,GAEpBf,EAAI,EAEDA,EAAIH,GAAK,CAKV,IAAAmB,EAASpB,EAAEI,GACf,GAAIa,EAAUI,KAAKH,EAASE,EAAQhB,EAAGJ,GAC9B,OAAAoB,EAGThB,GACF,CAGF,ICnGS,MAAAkB,EAAe,CAACC,KAAmBC,IACvCA,EAAMC,KAAaC,GAAAjC,OAAOF,UAAUoC,SAASN,KAAKE,GAAOK,MAAM,GAAG,GAAIC,gBAAkBH,GAapFI,EAAM,CAACC,EAAcC,IACzBvC,OAAOF,UAAU0C,eAAeZ,KAAKU,EAAMC,GAQvCE,EAAeC,GACnB,GAAGC,OAAOf,KAAKc,KAAgB,OAANE,GAAYC,KAAK,IAwBtCC,EAAiBC,IACxB,GAAiB,iBAAVA,EAA2B,OAAA,EAElC,GAAU,iBADNA,EAAAA,EAAMC,oBAAoBC,QACE,OAAA,EAChC,GAAA,QAAQC,KAAKH,GAAQ,CACjB,MAAAI,EAAQ,eAAeC,KAAKL,GAClC,GAAyB,KAtBf,QADYM,EAuBRF,GAtBS,EACN,iBAARE,EAAyBC,IACjB,iBAARD,EAAyBA,EACjB,iBAARA,EACmB,MAAxBA,EAAIA,EAAI5C,OAAS,GACZ8C,OAAOF,EAAIlB,MAAM,GAAG,IAAO,IAE7BoB,OAAOF,GAETC,KAa8B,OAAA,CACrC,CAxBuB,IAACD,EAyBjB,OAAA,GAOIG,EAAiB,CAC5BC,EACAC,KAvEF,IAAAC,EAyEM,IAAAC,GAAU,OAAAD,IAAMC,cAAN,EAAAD,EAAeE,MAAM,KAAKC,OAASJ,EAAUhD,MAAO,CAAC,GACjEqD,EAAa,EACbC,EAAgB,EAChBC,EAAc,EACdC,EAAe,EACjB,OAAQN,EAAQnD,QACd,KAAK,EACHsD,EAAaC,EAAgBC,EAAcC,EAAeN,EAAQ,GAClE,MACF,KAAK,EACUG,EAAAC,EAAgBJ,EAAQ,GACvBK,EAAAC,EAAeN,EAAQ,GACrC,MACF,KAAK,EACHG,EAAaH,EAAQ,GACPK,EAAAC,EAAeN,EAAQ,GACrCI,EAAgBJ,EAAQ,GACxB,MACF,QACEG,EAAaH,EAAQ,GACrBI,EAAgBJ,EAAQ,GACxBK,EAAcL,EAAQ,GACtBM,EAAeN,EAAQ,GAG3B,MAAMO,EAAM,CAAEJ,aAAYC,gBAAeC,cAAaC,gBACtD,IAAA,IAAS3B,KAAO4B,EAEdA,EAAI5B,GAAOF,EAAIoB,EAAOlB,IAAQV,EAAa4B,EAAMlB,GAAM,SAAU,UAC7DmB,EAAUD,EAAMlB,IAChB4B,EAAI5B,GAEV,MAAO,CAACwB,EAAYC,EAAeC,EAAaC,IASrCE,EAAW,CAACC,EAAcC,EAAO,OAC5C,IAAIC,EAAS,KACb,OAAO,YAAwBC,GACzBD,IACJA,EAASE,WAAW,KACfJ,EAAAK,MAAMrE,KAAMmE,GACfG,aAAaJ,GACJA,EAAA,MACRD,GAAI,GASEM,EAAgBC,IAC3B,MAAMC,EAAyB,GAEzBC,EAAMF,EAASf,IAAWT,GAAAE,OAAOF,IAAM2B,OAAO,CAACC,EAAMC,KACzD,GAAIA,EAAO,EAAG,CACZ,MAAMf,EAAMc,EAAOC,EAEZ,OADPJ,EAAaK,KAAKhB,GACXA,CAAA,CAGA,OADPW,EAAaK,KAAK7B,KACX2B,GAER,GACGG,EAASxE,KAAKwE,SAAWL,EAC/B,OAAOD,EAAaO,UAAiBhC,GAAA+B,GAAU/B,IASpCiC,EAAY,CACvBC,EACAC,EACAC,EACAC,EAAoBC,OAGhBD,GAAa,IAAeA,EAAAC,KAChC,IAAIjD,EAAM,GACV,MAAMkD,EAAQ,GACRC,EAAWN,EAAIO,YAAY,OAAOC,MACxC,IAAA,IAASC,EAAI,EAAGA,EAAIR,EAAK/E,OAAQuF,IAAK,CACpCtD,GAAO8C,EAAKQ,GACZ,IAAIC,EAAYV,EAAIO,YAAYpD,GAAKqD,MAC/B,MAAAG,EAAWT,EAASG,GAItB,GAFAF,IAAcE,EAAMnF,OAAS,IAAgBwF,GAAAJ,GAE7CK,EAAW,EAAU,OAAAN,EAOrB,GALAK,EAAYC,IACdN,EAAMT,KAAKzC,EAAIP,MAAM,OACrBO,EAAM8C,EAAKQ,IAGTN,IAAcE,EAAMnF,OAEf,OADDmF,EAAAA,EAAMnF,OAAS,IAAM,MACpBmF,CAEX,CAGO,OAFHlD,GAAWkD,EAAAT,KAAKzC,GACfkD,EAAMnF,QAAQmF,EAAMT,KAAKK,GACvBI,wKCxLT,MAAqBO,EAOnB,WAAAC,GALQC,EAAAhG,KAAA,QAMNA,KAAKiG,KAAO,EACd,CAMO,MAAAC,CAAQC,GAERnG,KAAKiG,KAAKvG,SAASyG,IACjBnG,KAAAiG,KAAKnB,KAAKqB,EAEnB,CAKO,MAAAC,GACApG,KAAAiG,KAAKI,QAAeF,IACvBA,EAAIG,UAER,EA5BAN,EADmBF,EACZ,UCAI,MAAAS,EAAW,aAAe,GAEhC,SAASC,EAAKC,EAAavE,EAAsBwE,EAAUC,GACzDhH,OAAAC,eAAe6G,EAAKvE,EAAK,CAC9BrC,MAAO6G,EACPC,aAAcA,EACdC,UAAU,EACVC,cAAc,GAElB,CCTA,MAAMC,EAAgBtH,MAAMC,UACtBsH,EAAgBpH,OAAOqH,OAAOF,GACpB,CAAC,OAAQ,MAAO,QAAS,UAAW,OAAQ,SAAU,WAC9DT,QAAkBY,IACVF,EAAAE,GAAU,YAAa9C,GACnC,MAAML,EAAMgD,EAAcG,GAAQ5C,MAAMrE,KAAMmE,GACxC+C,EAAUlH,KAAkB,YAG3B,MAFH,CAAC,OAAQ,UAAW,UAAUN,SAASuH,IAAiBC,EAAAC,KAAKnH,MACjEkH,EAAQE,IAAIhB,SACLtC,CAAA,8JCRX,MAAqBuD,EAQnB,WAAAtB,CAAalG,GAPbmG,EAAAhG,KAAA,SACAgG,EAAAhG,KAAA,OAQOA,KAAAoH,IAAM,IAAItB,EAEXU,EAAA3G,EAAO,cAAeG,MACtBR,MAAM8H,QAAQzH,KACZ0G,EACF1G,EAAiB,UAAIkH,EAErBpH,OAAO4H,oBAAoBR,GAAeV,QAAenE,IACvDsE,EAAI3G,EAAOqC,EAAK6E,EAAc7E,OAIpClC,KAAKmH,KAAKtH,EACZ,CAEA,IAAAsH,CAAMlF,GACJtC,OAAO6H,KAAKvF,GAAMoE,QAAenE,IAC/BuF,EAAexF,EAAMC,EAAKD,EAAKC,KAEnC,EAOK,SAASwF,EAASzF,GACvB,IAAKA,GAAwB,iBAATA,EAAmB,OACnC,IAAAiF,EAMG,OAJLA,EADE,gBAAiBjF,EACTA,EAAkB,YAElB,IAAIoF,EAASpF,GAElBiF,CACT,CAQgB,SAAAO,EAAgBxF,EAAWC,EAAsBwE,GACzD,MAAAU,EAAM,IAAItB,EACV6B,EAAWhI,OAAOiI,yBAAyB3F,EAAMC,GACnD,GAAAyF,IAAsC,IAA1BA,EAASd,aACvB,OAEI,MAAAgB,EAASF,GAAYA,EAASG,IAC9BC,EAASJ,GAAYA,EAASK,IAC9BH,IAAUE,GAAgC,IAArB1G,UAAUjB,SACnCsG,EAAMzE,EAAKC,IAET,IAAA+F,EAAUP,EAAQhB,GACf/G,OAAAC,eAAeqC,EAAMC,EAAK,CAC/B4F,IAAK,KACH,MAAMjI,EAAQgI,EAASA,EAAOtG,KAAKU,GAAQyE,EAOpC,OANHZ,EAAIoC,SACFd,EAAAlB,OAAOJ,EAAIoC,QACXD,GACMA,EAAAb,IAAIlB,OAAOJ,EAAIoC,SAGpBrI,GAETmI,IAAMG,IACAA,IAAWzB,IACTA,EAAAyB,EACFN,IAAWE,IACXA,EACKA,EAAAxG,KAAKU,EAAMkG,GAEZzB,EAAAyB,EAERF,EAAUP,EAAQS,GAClBf,EAAIhB,aAGV,2JCnFA,IAAIgC,EAAM,EACV,MAAqBC,EAenB,WAAAtC,CAAauC,EAAeC,EAAyBC,EAAcC,EAAwB,CAAA,GAd3FzC,EAAAhG,KAAA,MACAgG,EAAAhG,KAAA,UACAgG,EAAAhG,KAAA,QACAgG,EAAAhG,KAAA,MACAgG,EAAAhG,KAAA,QACAgG,EAAAhG,KAAA,UACAgG,EAAAhG,KAAA,SASEA,KAAK0I,GAAKN,IACVpI,KAAKsI,OAASA,EACdtI,KAAKuI,KAAOA,EACPvI,KAAA2I,OAASF,EAAQE,KAEpB3I,KAAK6H,OADa,mBAATU,EACKA,EHlBb,SAAoBK,GACjBA,GAAA,IACJ,IAAAC,EAAqB,GAAIC,EAAU,GACvC,IAAA,IAASnD,EAAI,EAAGA,EAAIiD,EAAKxI,OAAQuF,IAAK,CAChC,IAAAd,EAAO+D,EAAKjD,GACZ,GAAA,QAAQ9C,KAAKgC,GACfgE,EAAS/D,KAAKgE,GACJA,EAAA,OACD,IAAA,KAAKjG,KAAKgC,GACnB,SAEWiE,GAAAjE,CACb,CACF,CACA,OAAO,SAAU5C,GACf,OAAO4G,EAASlE,OAAO,CAAC1C,EAAMC,IACrBD,EAAKC,GACXD,EAAI,CAEX,CGCoB8G,CAAUR,GAE1BvI,KAAKwI,GAAKA,EACLxI,KAAAH,MAAQG,KAAK8H,KACpB,CAKA,GAAAA,GACEhC,EAAIoC,OAASlI,KACb,MAAMH,EAAQG,KAAK6H,OAAOtG,KAAKvB,KAAKsI,OAAQtI,KAAKsI,QAM1C,OAJHtI,KAAK2I,MHZN,SAAmB9I,GAElB,MAAAmJ,EAAO/G,IACNT,EAAaS,EAAM,QAAS,WACjCtC,OAAO6H,KAAKvF,GAAMoE,QAAenE,IACzBrC,MAAAA,EAAQoC,EAAKC,GACnB8G,EAAInJ,MAGRmJ,EAAInJ,EAEN,CGEMoJ,CAASpJ,GAEXiG,EAAIoC,OAAS,KACNrI,CACT,CAKA,MAAAyG,GAEQ,MAAA6B,EAASnI,KAAK8H,MAEdoB,EAASlJ,KAAKH,MACpBG,KAAKH,MAAQsI,EAEbnI,KAAKwI,GAAGjH,KAAKvB,KAAKsI,OAAQH,EAAQe,EACpC,4JC1DF,MAAqBC,EAkBnB,WAAApD,CACEqD,EACAnH,GAlBF+D,EAAAhG,KAAmB,UAAkBqJ,GAClBrD,EAAAhG,KAAA,UACAgG,EAAAhG,KAAA,OACnBgG,EAAAhG,KAAU,eAAuB,IACjCgG,EAAAhG,KAAU,MAAgB,WAAY,GACtCgG,EAAAhG,KAAU,WAAmB,GAC7BgG,EAAAhG,KAAU,YAAoB,GACpBgG,EAAAhG,KAAA,QAiBc,iBAAXoJ,EAA8BA,EAAA,CAAEE,GAAIF,GAClB,IAApBA,EAAOG,WAAgBH,EAAS,CAAEE,GAAI,GAAIE,WAAYJ,IAG/DpJ,KAAKoJ,OAASA,EACdpJ,KAAKiC,KAAOA,EAEPmH,EAAOK,OAAML,EAAOK,KAAO,OAC5BL,EAAOE,KAAIF,EAAOI,WAAaE,SAASC,cAAcP,EAAOE,KAE7DF,EAAOI,aAEFJ,EAAAQ,cAAgBF,SAASG,cAAc,UACvCT,EAAAI,WAAWM,YAAYV,EAAOQ,gBAGnCR,EAAOQ,gBACTR,EAAOlE,IAAMkE,EAAOQ,cAAcG,WAAW,MAE7CX,EAAOQ,cAAcI,aAAa,UAAW,2BAAWX,KACxDD,EAAOQ,cAAcK,iBAAiB,WAAcjK,KAAKkK,YAAYC,KAEvEnK,KAAKkF,IAAMkE,EAAOlE,IAElBlF,KAAKoK,qBAEApK,KAAKoJ,OAAOlE,KACfmF,QAAQC,MAAM,yBAGZC,QAA6C,mBAA5BA,OAAON,kBACnBM,OAAAN,iBAAiB,SAAUlG,EAAS,IAAM/D,KAAKwK,SAAU,MAG9DD,QAA6C,mBAA5BA,OAAOE,kBACtB,IAAAF,OAAOE,iBAAiB,KAC1BzK,KAAKwK,WACJ9C,QAAQgC,SAASgB,gBAAiB,CAAEC,YAAY,GAEvD,CAKU,MAAAH,GA7EZ,IAAAlH,EAAAsH,EA8EI,OAAAA,GAAAtH,EAAAtD,KAAKoJ,QAAOyB,eAAZD,EAAArJ,KAAA+B,GAEAtD,KAAK8K,kBAEL9K,KAAK+K,SAEL/K,KAAKgL,sBAELhL,KAAKiL,YACP,CAKU,SAAAC,GAER,GADAlL,KAAKwK,UACAxK,KAAKmL,WAAanL,KAAKoL,UACnB,OAAAf,QAAQC,MAAM,aAEzB,CAMU,WAAAJ,CAAaC,GAAsB,CAKnC,eAAAW,GACLP,QAAWA,OAAOc,mBAChBrL,KAAAsL,cAAgBf,OAAOc,iBAAiB3B,SAASgB,iBAAiBa,SAASzJ,MAAM,GAAK,GAC7F,CAGO,WAAA0J,GACC,MAAC9F,EAAO+F,GAAU,CAACzL,KAAKmL,SAAUnL,KAAKoL,WACxCpL,KAAAkF,IAAIwG,WAAWhG,GAAQ+F,EAAgB,EAAR/F,EAAoB,EAAT+F,EACjD,CAMU,MAAAV,GACF,MAAA3B,OAAEA,GAAWpJ,KACfoJ,EAAOuC,MAEApB,OACTA,OAAY,IAAInB,EAAOuC,IAAMpB,OAAOqB,kBAAoB,EAC9CxC,EAAOuC,KACTtB,QAAAC,MAAMlB,EAAQ,qBAE1B,CAKQ,mBAAA4B,GACA,MAAA5B,OAAEA,EAAQnH,KAAAA,GAASjC,KAErB,IAAAmL,EAAW,EAAGC,EAAY,EAC1BhC,EAAOI,aACT2B,EAAW/B,EAAOI,WAAWqC,YAC7BT,EAAYhC,EAAOI,WAAWsC,cAG3B9L,KAAAmL,SAAWnL,KAAKqD,UAAUpB,EAAKyD,OAAS0D,EAAc,QAAM+B,EAC5DnL,KAAAoL,UAAYpL,KAAKqD,UAAUpB,EAAKwJ,QAAUrC,EAAe,SAAMgC,EAEhEhC,EAAOI,aACFJ,EAAAI,WAAWuC,MAAMC,SAAW,SACnC5C,EAAOI,WAAWuC,MAAMrG,MAAQ1F,KAAKmL,SAAW,KAChD/B,EAAOI,WAAWuC,MAAMN,OAASzL,KAAKoL,UAAY,KAEtD,CAKU,UAAAH,GACF,MAAA7B,OAAEA,EAAQlE,IAAAA,GAAQlF,MAClB4J,cAAEA,EAAe+B,IAAAA,GAAQvC,GACxB1D,EAAO+F,GAAU,CAACzL,KAAKmL,SAAWQ,EAAK3L,KAAKoL,UAAYO,GAC1D/B,IACLA,EAAclE,MAAQA,EACtBkE,EAAc6B,OAASA,EACT7B,EAAAmC,MAAMrG,MAAQ,GAAGA,MACjBkE,EAAAmC,MAAMN,OAAS,GAAGA,MAClB7B,EAAAmC,MAAM,oBAAsB,WAC1CnC,EAAcmC,MAAME,UAAY,SAAS,EAAIN,KACzCzG,EAAAgH,MAAMP,EAAKA,GACjB,CAKQ,kBAAAvB,GACA,MAAAhB,OAAEA,GAAWpJ,KACnB,GAAIuK,OAWF,OAVKvK,KAAAmM,IAAM5B,OAAO6B,uBAChB7B,OAAoC,6BACpCA,OAAiC,0BACjC,SAAU8B,GACD9B,OAAAnG,WAAWiI,EAAU,IAAO,GAAE,EAEzCjD,EAAOhF,WAAamG,OAAOnG,WAC3BgF,EAAOkD,YAAc/B,OAAO+B,YAC5BlD,EAAO9E,aAAeiG,OAAOjG,kBAC7B8E,EAAOmD,cAAgBhC,OAAOgC,eAGhC,GAAInD,EAAO+C,IAETnM,KAAKmM,IAAM/C,EAAO+C,SACpB,GAAW/C,EAAOhF,WAAY,CAE5B,MAAMoI,EAAUpD,EAAOhF,WACvBpE,KAAKmM,IAAOE,GAA+BG,EAAQH,EAAU,KAAI,MAGjErM,KAAKmM,IAAOE,GAA+BjI,WAAWiI,EAAU,KAEpE,CAEO,KAAAI,GACE,MAAA,CAAC,MAAO,SAAU,WAAW/M,SAASM,KAAKoJ,OAAOK,KAC3D,CAOU,OAAAiD,CACRC,EACAC,EACAC,EAAc,YAEd,OAAO,IAAIC,QAAQ,CAACC,EAASC,KAEvB,GADCL,GAAKK,EAAO,OAAOJ,EAAKD,iBACJ,QAArB3M,KAAKoJ,OAAOK,KAUd,OAFAmD,EAAKC,GAAeE,OACpBH,EAAc,QAAII,GATY,CAC1B,IAAAC,EAAS,IAAIC,MACjBD,EAAoB,YAAI,YACjBA,EAAAE,OAAS,IAAMJ,EAAQE,GAC9BA,EAAOG,QAAU,IAAMJ,EAAO,OAAOJ,EAAKD,eAC1CM,EAAON,IAAMA,CAAA,GAQnB,CAOU,SAAAU,CACRnI,EACA+H,KACGK,GAnPP,IAAAhK,EAAAsH,EAqPQ,IAAA2C,EACJ,MAAM9D,KAAEA,EAAAkC,IAAMA,GAAQ3L,KAAKoJ,OAC3B,GAAI,CAAC,MAAO,SAAS1J,SAAS+J,GAElB8D,EAAAN,MACZ,KAAW,CAAC,SAAU,SAAU,UAAW,WAAWvN,SAAS+J,GAMtD,OAAAY,QAAQC,MAAM,wBAHrBiD,EAAWN,EAAwBrE,IAIrC,CACA,MAAM4E,EAAqB,OAAA5C,GAAQtH,EAAAiK,EAAQ,QAAKA,GAASxD,iBAAa,EAAAa,EAAArJ,KAAA+B,EAAA,MACtE,GAAIkK,IAAsBxN,KAAKyM,QAAS,CACtCa,EAAWA,EAAS7J,IAAWiD,GAAAA,EAAOiF,GAChC,MAAA8B,EAAOD,EAAkBE,gBAAgBJ,EAASxL,MAAM,EAAG,IACjEoD,EAAIyI,aAAaF,KAAUH,EAASxL,MAAM,EAAG,GAAuB,KAC/D,CACmB,IAApBwL,EAASlN,SACAkN,EAAAA,EAAS7J,IAAI,CAACiD,EAAKkH,IAAUA,EAAQ,EAAIlH,EAAOiF,EAAMjF,IAG/D,IACExB,EAAAmI,UAAUE,KAAYD,SACnBO,GAOT,CACF,CACF,CAUU,sBAAAC,CACRb,EACAc,EACAlI,EACAmI,GAGA,IAAKD,EAAQrI,QAAUqI,EAAQtC,OAE7B,MAAO,CAACwB,EAAOvH,MAAOuH,EAAOxB,QACpB,GAAAsC,EAAQrI,QAAUqI,EAAQtC,OAAQ,CAE3C,IAAIwC,EAAYjO,KAAKqD,UAAU0K,EAAQrI,MAAOG,GAE9C,MAAO,CAACoI,EAAWhB,EAAOxB,QAAUwC,EAAYhB,EAAOvH,OAC9C,CAAA,IAACqI,EAAQrI,OAASqI,EAAQtC,OAAQ,CAE3C,IAAIyC,EAAalO,KAAKqD,UAAU0K,EAAQtC,OAAQuC,GAEhD,MAAO,CAACf,EAAOvH,OAASwI,EAAajB,EAAOxB,QAASyC,EACvD,CAEO,MAAA,CACLlO,KAAKqD,UAAU0K,EAAQrI,MAAOG,GAC9B7F,KAAKqD,UAAU0K,EAAQtC,OAAQuC,GAEnC,CAQU,WAAAG,CAAatO,EAAeuO,EAAc,GAC5C,MAAAhF,OAAEA,GAAWpJ,KACnB,OAAOkD,OAAOrD,EAAMwO,QAAQ,2BAA4B,CAAC3H,EAAK1D,EAAKsL,KACjE,MAAMC,EAAgB,CACpB,IAAMlO,GAAcA,GAAK+N,EAAc,KACvCI,GAAOnO,GAAkB,EAAJA,EACrBoO,IAAQpO,GAAcA,EAAIL,KAAKsL,aAC/BoD,GAAOrO,GAAcA,EAAI,IAAMkK,OAAOoE,YACtCL,GACE,GAAAC,EAAsB,OAAAA,EAAcvL,GAExC,MAAM4L,EAAqBxF,EAAOmF,eAAiBnF,EAAiB,SACpE,OAAOwF,EAAqBA,EAAmB5L,EAAKsL,GAAQtL,IAEhE,CAQU,SAAAK,CAAWjD,EAAqCyO,GACxD,OAAIrN,EAAapB,EAAQ,UAAkBA,EACvCoB,EAAapB,EAAQ,UAAkBJ,KAAKmO,YAAY/N,EAAkByO,GACvE,CACT,CAOU,UAAAC,CAAYpJ,EAAeG,EAAmB,GACtD,OAAQA,EAAWH,GAAS,CAC9B,CAEU,kBAAAqJ,CAAoBrJ,EAAe+F,GAIvC,IAACzL,KAAuB,mBACtBuK,QAAUA,OAAOb,UAAiC,QAArB1J,KAAKoJ,OAAOK,KAC3CzJ,KAAuB,iBAAI0J,SAASG,cAAc,UAElD7J,KAAuB,iBAAIA,KAAKoJ,OAAwB,iBAErDpJ,KAAuB,kBAAU,OAAAqK,QAAQC,MAAM,mBAEhD,MAAAqB,EAAM3L,KAAKoJ,OAAOuC,IAClBqD,EAAmBhP,KAAuB,iBAC/BgP,EAAAtJ,OAASA,GAAS,KAAOiG,EACzBqD,EAAAvD,QAAUA,GAAU,KAAOE,EACtC,MAAAsD,EAAOD,EAAiBjF,WAAW,MAIlC,OAHPkF,EAAKvD,UAAU,EAAG,EAAGhG,EAAO+F,GACvBwD,EAAA/C,MAAMP,EAAKA,GAChBsD,EAAU,IAAItD,EACP,CAAEqD,mBAAkBC,OAC7B,CAQO,IAAAC,CAAMjN,EAAcC,EAAsBrC,GAC1CoC,GAAwB,iBAATA,GACLwF,EAAAxF,EAAMC,EAAKrC,EAC5B,CAQU,SAAAsP,CAAWlN,EAAcC,EAAamK,GACvC1M,OAAAC,eAAeqC,EAAMC,EAAK,CAC/B4F,IAAK,IACIuE,EAAS9K,KAAKvB,OAG3B,CASU,MAAAoP,CACR7G,EACA8G,EACAC,EAAyB,CAAA,GAEF,iBAAZD,IAETA,GADWC,EAAAD,GACQA,SAGrB,MAAME,EAAU,IAAIlH,EAAQrI,KAAMuI,EAAM8G,EAASC,GAMjD,OAJIA,EAASE,WACHH,EAAA9N,KAAKvB,KAAMuP,EAAQ1P,OAGtB,WAAsB,CAC/B,EAxaAmG,EADmBmD,EACZ,UAAkBE,GCHd,MAAAoG,EAAYC,GAChBnP,KAAKoP,GAAK,IAAMD,EA0BZE,EAAiB,CAC5B1K,EACA2K,EACAC,EACA9O,EACA+O,EACAC,KAEA9K,EAAI+K,YACJ,IAAIC,EAAYT,EAAS,GAAKlP,KAAKoP,GAAKG,EAAYE,GAEhDG,EAAWnP,EAAQkP,EACnBE,EAASL,EAAMG,EA7Ba,IAACR,EAAaW,EAgC9CnL,EAAIoL,IAAI,EAAG,EAAGR,EAAWK,EAAUC,GAAQ,GAKrClL,EAAAqL,WArC2Bb,GAuC1B1O,EAAQ+O,GAAO,EAvCwBM,EAwCxCL,EAAS,EAAIzP,KAAKE,IAAIF,KAAKiQ,KAAKxP,EAAQ+O,GAAO,IAvC9C,GAAGxP,KAAKkQ,IAAIf,GAAOW,GAAGK,QAAQ,KAAMnQ,KAAKiQ,IAAId,GAAOW,GAAGK,QAAQ,MA2CtExL,EAAIyL,aAIOC,EAAiB,CAC5B1L,MACIvE,EAAGC,EAAGiQ,EAAGC,EAAGT,MAEhB,MAAMU,EAAMxQ,KAAKwQ,IAAIF,EAAGC,GAAInB,EAAKpP,KAAKoP,GAClCU,EAAIU,EAAM,IAAGV,EAAIU,EAAM,GAC3B7L,EAAI+K,YACA/K,EAAA8L,OAAOrQ,EAAI0P,EAAGzP,GACdsE,EAAAqL,OAAO5P,EAAI0P,EAAGzP,GAClBsE,EAAIqL,OAAO5P,EAAIkQ,EAAIR,EAAGzP,GAClBsE,EAAAoL,IAAI3P,EAAIkQ,EAAIR,EAAGzP,EAAIyP,EAAGA,GAAIV,EAAK,EAAG,GACtCzK,EAAIqL,OAAO5P,EAAIkQ,EAAGjQ,EAAIkQ,EAAIT,GACtBnL,EAAAoL,IAAI3P,EAAIkQ,EAAIR,EAAGzP,EAAIkQ,EAAIT,EAAGA,EAAG,EAAGV,EAAK,GACzCzK,EAAIqL,OAAO5P,EAAI0P,EAAGzP,EAAIkQ,GAClB5L,EAAAoL,IAAI3P,EAAI0P,EAAGzP,EAAIkQ,EAAIT,EAAGA,EAAGV,EAAK,EAAGA,GACjCzK,EAAAqL,OAAO5P,EAAGC,EAAIyP,GACdnL,EAAAoL,IAAI3P,EAAI0P,EAAGzP,EAAIyP,EAAGA,EAAGV,GAAKA,EAAK,GACnCzK,EAAIyL,aChEOM,EACH,SAAUC,EAAGC,EAAGC,EAAGC,GAElB,OADHH,GAAKG,IAAOH,EAAAG,GACTD,GAAKF,GAAKG,GAAKH,EAAIC,CAC5B,EAJWF,EAKF,SAAUC,EAAGC,EAAGC,EAAGC,GAE1B,OADIH,GAAKG,IAAOH,EAAAG,IACRD,GAAKF,GAAKG,IAAMH,EAAI,GAAKC,CACnC,6tDCKF,cAAuChI,EAoDrC,WAAApD,CAAaqD,EAAwBnH,GAjFvC,IAAAqB,EAkFIgO,MAAMlI,EAAQ,CACZ1D,MAAOzD,EAAKyD,MACZ+F,OAAQxJ,EAAKwJ,SAtDjBzF,EAAAhG,KAAQ,OAAiB,GACzBgG,EAAAhG,KAAQ,OAAiB,GACzBgG,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,UAA6B,IAC7BgG,EAAAhG,KAAA,UACRgG,EAAAhG,KAAQ,gBAAmC,CAAA,GAC3CgG,EAAAhG,KAAQ,eAAiC,CAAA,GACzCgG,EAAAhG,KAAQ,cAA+B,CAAA,GACvCgG,EAAAhG,KAAQ,iBAA8C,CAAA,GACtDgG,EAAAhG,KAAQ,gBAA4C,CAAA,GACpDgG,EAAAhG,KAAQ,eAA0C,CAAA,GAC1CgG,EAAAhG,KAAA,iBACAgG,EAAAhG,KAAA,eACRgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,aAAa,GACrBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,UAAU,GAClBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,WAAW,GACnBgG,EAAAhG,KAAQ,QAAO,GACfgG,EAAAhG,KAAQ,QAAQ,GAChBgG,EAAAhG,KAAQ,MAAM,MAQdgG,EAAAhG,KAAQ,OAAsB,GAO9BgG,EAAAhG,KAAQ,aAAgC,GAExCgG,EAAAhG,KAAQ,QAA+C,IAE/CgG,EAAAhG,KAAA,aAEAgG,EAAAhG,KAAA,iBAAiBuR,KAYvBvR,KAAKwR,SAASvP,GACdjC,KAAKyR,YACLzR,KAAK0R,eAEL,OAAOpO,EAAA8F,EAAAuI,iBAAcpQ,KAAKvB,MAE1BA,KAAK4R,MACP,CAEU,MAAApH,GA/FZ,IAAAlH,EAAAsH,EAgGI0G,MAAM9G,SACNxK,KAAK6R,OACL,OAAAjH,GAAAtH,EAAAtD,KAAKoJ,QAAO0I,cAAZlH,EAAArJ,KAAA+B,EACF,CAEU,SAAA4H,GACRlL,KAAK+R,UAAY,EACjB/R,KAAKgS,WAAa,EAClBhS,KAAKiS,UAAY,EACjBjS,KAAKkS,QAAU,EACflS,KAAKmS,UAAY,EACjBnS,KAAKoS,UAAY,EACjBpS,KAAKqS,SAAW,EAChBrS,KAAKsS,MAAO,EACZtS,KAAKuS,MAAQ,EACbvS,KAAKwS,IAAM,KACXxS,KAAKyS,WAAY,EACjBzS,KAAK0S,KAAO,EACZpB,MAAMpG,WACR,CAMQ,QAAAsG,CAAUvP,GAChBjC,KAAKkP,KAAKlP,KAAM,QAASiC,EAAKyD,OAC9B1F,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAKwJ,QAC/BzL,KAAKkP,KAAKlP,KAAM,OAAQkD,OAAOjB,EAAK0Q,OAAS,GAC7C3S,KAAKkP,KAAKlP,KAAM,OAAQkD,OAAOjB,EAAK2Q,OAAS,GAC7C5S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK4Q,QAAU,IACzC7S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK6Q,QAAU,IACzC9S,KAAKkP,KAAKlP,KAAM,UAAWiC,EAAK8Q,SAAW,IAE3C/S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK+Q,QAC/BhT,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKgR,eAAiB,CAAA,GACvDjT,KAAKkP,KAAKlP,KAAM,eAAgBiC,EAAKiR,cAAgB,CAAA,GACrDlT,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAKkR,aAAe,CAAA,GACnDnT,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKjB,OACtChB,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAK8N,IACtC,CAKQ,YAAA2B,GAED1R,KAAAmP,UAAUnP,KAAM,iBAAkB,KACrC,MAAMoJ,EAASgK,EAAA,CACbpD,OAAQ,EACRqD,MAAO,GACPC,iBAAkB,KAClBC,iBAAkB,MACfvT,KAAKiT,eAIH,OAFP7J,EAAO4G,OAAShQ,KAAKqD,UAAU+F,EAAO4G,QAC/B5G,EAAAiK,MAAQjK,EAAOiK,MAAQ,GACvBjK,IAGJpJ,KAAAmP,UAAUnP,KAAM,gBAAiB,IAC7BoT,EAAA,CACLI,aAAc,GACdC,UAAW,OACXlI,SAAU,OACVmI,UAAW,aACXC,WAAY,MACZC,WAAY,gBACZC,OAAQ,GACRC,UAAU,EACVC,YAAa,OACV/T,KAAKkT,eAIPlT,KAAAmP,UAAUnP,KAAM,eAAgB,IAC5BoT,EAAA,CACLQ,WAAY,UACZC,OAAQ,IACL7T,KAAKmT,aAGd,CAKQ,SAAA1B,GAEDzR,KAAAoP,OAAO,QAAUjH,IACpBnI,KAAKiC,KAAKyD,MAAQyC,EAClBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAWjH,IACrBnI,KAAKiC,KAAKwJ,OAAStD,EACnBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,UAAY4E,IACtBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IACX3I,KAAKoP,OAAO,OAAQ,IAAMpP,KAAK4R,QAC/B5R,KAAKoP,OAAO,OAAQ,IAAMpP,KAAK4R,QAC1B5R,KAAAoP,OAAO,gBAAiB,IAAMpP,KAAK6R,OAAQ,CAAElJ,MAAM,IACnD3I,KAAAoP,OAAO,eAAgB,IAAMpP,KAAK6R,OAAQ,CAAElJ,MAAM,IAClD3I,KAAAoP,OAAO,cAAe,IAAMpP,KAAK6R,OAAQ,CAAElJ,MAAM,IACtD3I,KAAKoP,OAAO,gBAAiB,IAAMpP,KAAK4R,QACxC5R,KAAKoP,OAAO,cAAe,IAAMpP,KAAK4R,OACxC,CAKa,IAAAA,GAAuB,OAAAsC,EAAAlU,KAAA,KAAA,YA1NtC,IAAAsD,EAAAsH,EA2NI5K,KAAKkL,YACC,MAAA9B,OAAEA,GAAWpJ,KAEnB,OAAOsD,EAAA8F,EAAA+K,eAAY5S,KAAKvB,MAExBA,KAAK6R,aAEC7R,KAAKiU,iBAEX,OAAOrJ,EAAAxB,EAAAgL,cAAW7S,KAAKvB,KAAA,EACzB,CAEQ,cAAAiU,GACC,OAAA,IAAInH,QAASC,IAClB,MAAMsH,EAAUrU,KAAK+S,QAAQtP,IAAI6Q,GAAOA,EAAIC,MACxCvU,KAAKgT,QAAQqB,EAAQvP,KAAK9E,KAAKgT,OAAOuB,MAC1C,MAAMC,EAAiB,CACrB3B,OAAQ7S,KAAK6S,OAAOpP,IAAIL,GAASA,EAAMmR,MACvCzB,OAAQ9S,KAAK8S,OAAOrP,IAAIgR,GAASA,EAAMF,MACvCxB,QAASsB,GAEwB1U,OAAO6H,KAAKgN,GAAiBnO,QAAmBqO,IAC3E,MAAAC,EAAaH,EAAeE,GAE5BE,EAA8B,GACpCD,GAAcA,EAAWtO,QAAQ,CAACkO,EAAMM,KACtCN,GAAQA,EAAKlO,QAAQ,CAAC0H,EAAS+G,KAC7BF,EAAW9P,KAAK9E,KAAK+U,gBAAgBL,EAASG,EAAWC,QAG7DhI,QAAQkI,IAAIJ,GAAYK,KAAK,KAC3BjV,KAAK6R,OACG9E,SAIhB,CAMU,WAAA7C,CAAaC,GACf,MAAAjF,IAAEA,GAAQlF,KACf,IACIA,KAAK+S,QACR/S,KAAKgT,QACL3M,QAAeiO,IA1QrB,IAAAhR,EA2QM,IAAKgR,EAAK,OACV,MAAO3T,EAAGC,EAAG8E,EAAO+F,GAAUzL,KAAKkV,qBAAqB,CACtDZ,EAAI3T,EAAG2T,EAAI1T,EAAG0T,EAAIa,KAAO,EAAGb,EAAIc,KAAO,IAEzClQ,EAAI+K,YACJ/K,EAAImQ,KAAK1U,EAAGC,EAAG8E,EAAO+F,GACjBvG,EAAIoQ,cAAcnL,EAAEoL,QAASpL,EAAEqL,UAClB,IAAdxV,KAAK0S,OAEmB,mBAAjB4B,EAAIjI,YAA6BA,SAAS9K,KAAKvB,KAAMsU,GAEhE,OAAKhR,EAAAtD,KAAAyV,4BAAgBtL,EAAGmK,KAE5B,CASc,eAAAS,CACZW,EACAb,EACAC,GACe,OAAAZ,EAAAlU,KAAA,KAAA,YACf,OAAO,IAAI8M,QAAQ,CAACC,EAASC,KAC3B,IAAI2I,EAA2C3V,KAAK0V,GAAUb,GAK9D,GAHiB,YAAba,IAA2B1V,KAAK+S,QAAQ3S,QAAUJ,KAAKgT,SACzD2C,EAAO3V,KAAKgT,SAET2C,IAASA,EAAKpB,KAAM,OACnB,MAAAxG,EAAU4H,EAAKpB,KAAKO,GAC1B,IAAK/G,EAAS,OAEd,MAAM6H,EAAU,CACd5V,KAAK0M,QAAQqB,EAAQpB,IAAKoB,GAC1BA,EAAmB,WAAK/N,KAAK0M,QAAQqB,EAAmB,UAAGA,EAAS,mBAEtEjB,QAAQkI,IAAIY,GAASX,KAAYY,GAA4B3B,EAA5BlU,KAAA,CAAA6V,GAA4B,WAA3BC,EAAYC,IAC5C,MAAMC,EAAYjI,EAAQiI,UAED,mBAAdA,IACTF,QAAmBhJ,QAAQC,QAAQiJ,EAAUzU,KAAKvB,KAAM8V,IACpDC,IACFA,QAAkBjJ,QAAQC,QAAQiJ,EAAUzU,KAAKvB,KAAM+V,MAG3D/V,KAAKiW,WAAWjO,IAAI+F,EAAa,IAAG+H,GACpCC,GAAa/V,KAAKiW,WAAWjO,IAAI+F,EAAmB,UAAGgI,GAC/ChJ,GAAA,IACPmJ,MAAarI,IACNxD,QAAAC,MAAM,GAAGoL,KAAYb,WAAmBC,MAAajH,KACtDb,OAEV,EACH,CAKU,IAAA6E,GA1UZ,IAAAvO,EAAAsH,EA2UI,MAAMxB,OAAEA,EAAQlE,IAAAA,EAAAiR,eAAKA,EAAgBC,cAAAA,EAAAC,aAAeA,GAAiBrW,KAErE,OAAOsD,EAAA8F,EAAAkN,aAAYhT,EAAA/B,KAAKvB,KAAMkF,GAE9BA,EAAIwG,UAAU,EAAG,EAAG1L,KAAKmL,SAAUnL,KAAKoL,WAExCpL,KAAKuW,MAAQ,IACRvW,KAAK8S,UACL9S,KAAK+S,SAEN/S,KAAKgT,QAAQhT,KAAKuW,MAAMzR,KAAK9E,KAAKgT,QACjChT,KAAAuW,MAAMlQ,QAAgBsP,IACpBA,EAAAR,IAAMQ,EAAKR,KAAO,EAClBQ,EAAAP,IAAMO,EAAKP,KAAO,IAGzBpV,KAAKwW,UAAYxW,KAAK6S,OAAOlO,OAAO,EAAEhE,IAAGC,IAAGiQ,IAAGC,KAAI1N,EAAOqT,KACxD,MAAO/S,EAAYC,EAAeC,EAAaC,GAAgBV,EAAeC,EAAOpD,KAAKqD,UAAUqT,KAAK1W,OACnGqQ,EAAIjN,EAAMoQ,aAAexT,KAAKqD,UAAUD,EAAMoQ,cAAgB,EAE9DI,EAAaxQ,EAAMwQ,WAkBlB,OAjBHnR,EAAcmR,KAChB1O,EAAIyR,UAAY3W,KAAK4W,iBAAiBjW,EAAGC,EAAGiQ,EAAGC,EAAG8C,GAClDhD,EAAe1L,EAAKvE,EAAGC,EAAGiQ,EAAGC,EAAGT,GAChCnL,EAAI2R,QAGNzT,EAAMmR,MAAQnR,EAAMmR,KAAKlO,QAAQ,CAAC0H,EAAS+G,KACzC,MAAMgC,EAAW9W,KAAKiW,WAAWnO,IAAIiG,EAAQpB,KAC7C,IAAKmK,EAAU,OAET,MAAC7I,EAAWC,GAAclO,KAAK8N,uBAAuBgJ,EAAU/I,EAAS8C,EAAGC,IAC3EiG,EAAOC,GAAS,CACrBhX,KAAK8O,WAAWb,EAAW4C,GAAK7Q,KAAKqD,UAAU0K,EAAQkJ,KAAMpG,GAC7D7Q,KAAKqD,UAAU0K,EAAQmJ,IAAKpG,IAEzB9Q,KAAAqN,UAAUnI,EAAK4R,EAAUnW,EAAIoW,EAAOnW,EAAIoW,EAAO/I,EAAWC,KAE1D,CACLvN,EAAGA,EAAIiD,EACPhD,EAAGA,EAAI8C,EACPmN,EAAGA,EAAIjN,EAAcC,EACrBiN,EAAGA,EAAIpN,EAAaC,IAErB,CAAEhD,EAAG,EAAGC,EAAG,EAAGiQ,EAAG7Q,KAAKmL,SAAU2F,EAAG9Q,KAAKoL,YAEtCpL,KAAA+R,WAAa/R,KAAKwW,UAAU3F,EAAIsF,EAAenG,QAAUhQ,KAAK4S,KAAO,IAAM5S,KAAK4S,KAChF5S,KAAAgS,YAAchS,KAAKwW,UAAU1F,EAAIqF,EAAenG,QAAUhQ,KAAK2S,KAAO,IAAM3S,KAAK2S,KAEtF3S,KAAKuW,MAAMlQ,QAAQ,CAACsP,EAAMd,KACxB,IAAKlU,EAAGC,EAAG8E,EAAO+F,GAAUzL,KAAKkV,qBAAqB,CAACS,EAAKhV,EAAGgV,EAAK/U,EAAG+U,EAAKR,IAAMQ,EAAKP,MAEnF+B,GAAW,QAEkB,IAA7BnX,KAAKyS,WAAwBzS,KAAKyS,WAAgB,KACpD0E,EAAWtC,KAAc7U,KAAKmS,UAAYnS,KAAK8S,OAAO1S,OAAU,IAGlE,MAAMwT,EAAauD,EAAWd,EAAazC,WAAc+B,EAAK/B,YAAcwC,EAAcxC,WACtF,GAAAnR,EAAcmR,GAAa,CAE7B,MAAMC,GACJsD,EAAWd,EAAaxC,OAAU8B,EAAK9B,QAAUuC,EAAcvC,QAE9DxF,QAAQ,MAAO,IACf7K,MAAM,KAAK,GAAGA,MAAM,KACpBC,IAAI,CAACpD,EAAGsF,IAAMA,EAAI,EAAIzC,OAAO7C,GAAKA,GAEf,IAAlBwT,EAAOzT,SACL8E,EAAAkS,YAAcvD,EAAO,GACzB3O,EAAImS,cAAgBxD,EAAO,GAAKzK,EAAOuC,IACvCzG,EAAIoS,cAAgBzD,EAAO,GAAKzK,EAAOuC,IACnCzG,EAAAqS,WAAa1D,EAAO,GAExBA,EAAO,GAAK,EAAKnO,GAASmO,EAAO,IAAOnO,GAASmO,EAAO,GAAIlT,GAAKkT,EAAO,IACxEA,EAAO,GAAK,EAAKpI,GAAUoI,EAAO,IAAOpI,GAAUoI,EAAO,GAAIjT,GAAKiT,EAAO,KAG5E3O,EAAIyR,UAAY3W,KAAK4W,iBAAiBjW,EAAGC,EAAG8E,EAAO+F,EAAQmI,GACrD,MAAAJ,EAAexT,KAAKqD,UAAUsS,EAAKnC,aAAemC,EAAKnC,aAAe4C,EAAc5C,cAC1F5C,EAAe1L,EAAKvE,EAAGC,EAAG8E,EAAO+F,EAAQ+H,GACzCtO,EAAI2R,OAEJ3R,EAAIkS,YAAc,mBAClBlS,EAAImS,cAAgB,EACpBnS,EAAIoS,cAAgB,EACpBpS,EAAIqS,WAAa,CACnB,CAGI1C,GAAa7U,KAAK8S,OAAO1S,SAE3ByU,GAAa7U,KAAK8S,OAAO1S,QAG3BuV,EAAKpB,MAAQoB,EAAKpB,KAAKlO,QAAQ,CAAC0H,EAAS+G,KACvC,MAAM0C,EAAUxX,KAAKiW,WAAWnO,IAAIiG,EAAQpB,KACtCoJ,EAAY/V,KAAKiW,WAAWnO,IAAIiG,EAAmB,WACzD,IAAKyJ,EAAS,OACR,MAAAC,EAAaN,GAAYpB,GAAcyB,EAC7C,IAAKC,EAAW,OACV,MAACxJ,EAAWC,GAAclO,KAAK8N,uBAAuB2J,EAAW1J,EAASrI,EAAO+F,IAChFsL,EAAOC,GAAS,CACrBrW,EAAIX,KAAK8O,WAAWb,EAAWvI,GAAS1F,KAAKqD,UAAU0K,EAAQkJ,KAAMvR,GACrE9E,EAAIZ,KAAKqD,UAAU0K,EAAQmJ,IAAKzL,IAElCzL,KAAKqN,UAAUnI,EAAKuS,EAAWV,EAAOC,EAAO/I,EAAWC,KAG1DyH,EAAK+B,OAAS/B,EAAK+B,MAAMrR,QAAgBsR,IAEjC,MAAA5L,EAAQoL,GAAYd,EAAa3C,UACnC2C,EAAa3C,UACZiE,EAAKjE,WAAa0C,EAAc1C,UAE/BC,EAAawD,GAAYd,EAAa1C,WACxC0C,EAAa1C,WACZgE,EAAKhE,YAAcyC,EAAczC,WAEhCiE,EAAOT,GAAYd,EAAa9K,SAClCvL,KAAKqD,UAAUgT,EAAa9K,UAC5BvL,KAAKqD,UAAUsU,EAAKpM,UAAY6K,EAAc7K,UAE5CsM,EAAaV,GAAYd,EAAawB,WACxCxB,EAAawB,WACbF,EAAKE,YAAczB,EAAcyB,YAAcF,EAAKpM,UAAY6K,EAAc7K,SAC5EuI,EAAW9R,EAAI2V,EAAM,YAAcA,EAAK7D,SAAWsC,EAActC,SACjEC,EAAc4D,EAAK5D,aAAeqC,EAAcrC,YAChD1O,EAAYsS,EAAKtS,WAAa+Q,EAAc/Q,UAClDH,EAAIyS,KAAO,GAAGhE,KAAciE,EAAQ,OAAO7L,IACvC7G,EAAAyR,UAAaQ,GAAYd,EAAa5C,UAAa4C,EAAa5C,UAAakE,EAAKlE,WAAa2C,EAAc3C,UACjH,IAAIlO,EAAQ,GAAIJ,EAAOrE,OAAO6W,EAAKxS,MAEnC,GAAI2O,EAAU,CAEZ,IAAIjO,EAAW7F,KAAKqD,UAAU0Q,EAAarO,GAC3CH,EAAQN,EAAUC,EAAK9C,EAAY+C,GAAO,IAAMU,EAAUR,EAAS,MAE3DE,EAAAJ,EAAK3B,MAAM,MAEf+B,EAAAc,QAAQ,CAACyR,EAAMC,KACf7S,EAAA8S,SACFF,EACAnX,EAAIX,KAAK8O,WAAW5J,EAAIO,YAAYqS,GAAMpS,MAAOA,GAAS1F,KAAKqD,UAAUsU,EAAKV,KAAMvR,GACpF9E,EAAIZ,KAAKqD,UAAUsU,EAAKT,IAAKzL,IAAWsM,EAAY,GAAK/X,KAAKqD,UAAUwU,UAMhF,OAAOjN,EAAAxB,EAAA6O,YAAWrN,EAAArJ,KAAKvB,KAAMkF,EAC/B,CAWQ,gBAAA0R,CACNjW,EACAC,EACA8E,EACA+F,EACAmI,GAEM,MAAA1O,IAAEA,GAAQlF,KAKT,OAHH4T,EAAWlU,SAAS,qBACtBkU,EFja2B,EAC/B1O,EACAvE,EACAC,EACAiQ,EACAC,EACA8C,KAEA,MAAMsE,EAAW,0BAA0BnV,KAAK6Q,GAA2B,GACxEpQ,MAAM,KACNC,IAAK0B,GAAiBA,EAAKvC,QAC1B,IAAA8M,EAAMwI,EAAQC,QAASC,EAA8C,CAAC,EAAG,EAAG,EAAG,GAE/E,GAAA1I,EAAIhQ,SAAS,OAAQ,CACvBgQ,EAAMA,EAAI5N,MAAM,GAAG,GAAM,IAEnB,MAAAuW,EAAkB3I,GAAgBnP,KAAK+X,IAAI5I,EAAM,IAAMnP,KAAKoP,IAC9DD,GAAO,GAAKA,EAAM,GAAI0I,EAAY,CAACzX,EAAGC,EAAIkQ,EAAGnQ,EAAIkQ,EAAGjQ,EAAIkQ,EAAID,EAAIwH,EAAe3I,EAAM,IAChFA,GAAO,IAAMA,EAAM,GAAI0I,EAAY,CAACzX,EAAGC,EAAIkQ,EAAInQ,EAAIkQ,EAAKC,EAAIuH,EAAe3I,EAAM,IAAK9O,GACtF8O,GAAO,IAAMA,EAAM,IAAK0I,EAAY,CAACzX,EAAIkQ,EAAGjQ,EAAIkQ,EAAInQ,EAAIkQ,EAAKC,EAAIuH,EAAe3I,EAAM,IAAK9O,GAC3F8O,GAAO,KAAOA,EAAM,IAAK0I,EAAY,CAACzX,EAAIkQ,EAAGjQ,EAAIkQ,EAAGnQ,EAAGC,EAAIiQ,EAAIwH,EAAe3I,EAAM,MACpFA,GAAO,KAAOA,EAAM,MAAiB,CAAC/O,EAAIkQ,EAAGjQ,EAAGD,EAAGC,EAAIiQ,EAAIwH,EAAe3I,EAAM,MAChFA,GAAO,KAAOA,EAAM,IAAK0I,EAAY,CAACzX,EAAIkQ,EAAGjQ,EAAGD,EAAImQ,EAAIuH,EAAe3I,EAAM,KAAM9O,EAAIkQ,GACvFpB,GAAO,KAAOA,EAAM,MAAiB,CAAC/O,EAAGC,EAAGD,EAAImQ,EAAIuH,EAAe3I,EAAM,KAAM9O,EAAIkQ,GACnFpB,GAAO,KAAOA,EAAM,MAAK0I,EAAY,CAACzX,EAAGC,EAAGD,EAAIkQ,EAAGjQ,EAAIkQ,EAAID,EAAIwH,EAAe3I,EAAM,MAC/F,MAESA,EAAIhQ,SAAS,OAAoB0Y,EAAA,CAACzX,EAAGC,EAAIkQ,EAAGnQ,EAAGC,GAC/C8O,EAAIhQ,SAAS,UAAW0Y,EAAY,CAACzX,EAAGC,EAAGD,EAAGC,EAAIkQ,GAClDpB,EAAIhQ,SAAS,QAAS0Y,EAAY,CAACzX,EAAIkQ,EAAGjQ,EAAGD,EAAGC,GAChD8O,EAAIhQ,SAAS,WAAU0Y,EAAY,CAACzX,EAAGC,EAAGD,EAAIkQ,EAAGjQ,IAEpD,MAAA2X,EAAWrT,EAAIsT,wBAAyBJ,EAAU3U,IAAIpD,GAAU,EAALA,IAEjE,OAAO6X,EAAQvT,OAAO,CAAC4T,EAAeE,EAAW7K,KACzC,MAAAhB,EAAO6L,EAAKjV,MAAM,KAGjB+U,OAFa,IAAhB3L,EAAKxM,OAAcmY,EAASG,aAAa9K,EAAOhB,EAAK,IAChC,IAAhBA,EAAKxM,QAAcmY,EAASG,gBAAgB9L,GAC9C2L,GACNA,IE0XcI,CAAkBzT,EAAKvE,EAAGC,EAAG8E,EAAO+F,EAAQmI,IAEpDA,CACT,CAKQ,2BAAAgF,GACN,MAAMzC,eAAEA,EAAA1D,UAAgBA,EAAWN,UAAAA,GAAcnS,KAC5CA,KAAAkS,QAAU2G,KAAKC,MACd,MAAA1G,EAAYpS,KAAKoS,UAAYD,EAC7BkB,EAAQ8C,EAAe9C,MAC7B,IAAI1N,EAAI,EAAGoT,EAAY,EAAGC,EAAY,EACtC,OAASrT,GAAG,CACV,MAAM0M,EAAWrS,KAAK8S,OAAO1S,OAASuF,EAAI8M,EAAcL,EAClD6G,EAAYhI,EAAajR,KAAKwS,IAAKJ,EAAWC,EAAU8D,EAAe5C,kBAAoBnB,EACjG,GAAI6G,EAAY5F,EAAO,CACrBrT,KAAKqS,SAAYgB,EAAQ0F,EAAYE,EAAY5F,EAAShB,EAAW2G,EACrE,KACF,CACYA,EAAA3G,EACA0G,EAAAE,CACd,CACF,CAKO,IAAAC,GAphBT,IAAA5V,EAAAsH,EAqhBsB,IAAd5K,KAAK0S,OAEJ1S,KAAAiS,UAAY4G,KAAKC,MAEtB9Y,KAAKyS,eAAY,EAEjBzS,KAAK0S,KAAO,EAEZ,OAAA9H,GAAAtH,EAAAtD,KAAKoJ,QAAO+P,aAAZvO,EAAArJ,KAAA+B,GAEAtD,KAAKoZ,MACP,CAMO,IAAAC,CAAMzL,GACX,GAAkB,IAAd5N,KAAK0S,MAA4B,IAAd1S,KAAK0S,KAA5B,CAEI,IAAC9E,GAAmB,IAAVA,EAAa,CACzB,MAAMpJ,EAAWxE,KAAK8S,OAAOrP,IAAIgV,GAAQA,EAAKa,OAC9C1L,EAAQrJ,EAAaC,EACvB,CAEIoJ,EAAQ,GACV5N,KAAK0S,KAAO,EACZ1S,KAAKyS,WAAY,IAEjBzS,KAAK0S,KAAO,EACP1S,KAAAyS,UAAY7E,EAAQ5N,KAAK8S,OAAO1S,OAZC,CAc1C,CAMQ,GAAAgZ,CAAKpW,EAAc,GA3jB7B,IAAAM,EA4jBI,MAAM6I,IAAEA,EAAKuG,KAAAA,EAAAI,OAAMA,EAAQL,UAAAA,EAAA0D,eAAWA,GAAmBnW,MACnDsT,iBAAEA,EAAAC,iBAAkBA,EAAkBF,MAAAA,GAAU8C,EAEtD,GAAa,IAATzD,EAEF,YADA,OAAKpP,EAAAtD,KAAAuZ,cAAcjW,EAAA/B,KAAAvB,KAAAA,KAAK8S,OAAO5R,KAAK,CAACuT,EAAO7G,IAAUA,IAAU6E,IAAc,CAAA,IAIhF,IAAsB,IAAlBA,EAAkB,OAET,IAATC,GAAe1S,KAAKqS,eAAeuG,8BAEvC,MAAMY,EAAgBX,KAAKC,MAAQ9Y,KAAKiS,UAClCwH,EAAcZ,KAAKC,MAAQ9Y,KAAKkS,QACtC,IAAIC,EAAYnS,KAAKmS,UAEjB,GAAS,IAATO,GAAc8G,EAAgBlG,EAAkB,CAElDtT,KAAKwS,IAAMgH,EAAgBxW,EAC3B,MAAMiW,EAAYhI,EAAYuI,EAAe,GAAKnG,EAAQ,GAAKC,GAE3D2F,IAAc5F,IAChBrT,KAAK0S,KAAO,GAEFP,GAAY8G,EAAYnG,EAAO1S,MAAA,MACzB,IAATsS,GAEGP,GAAYkB,EAAQP,EAAO1S,YAEX,IAAxBqS,GAAwBA,GAAa,IACvCzS,KAAK0S,KAAO,EAEZ1S,KAAKoS,UAAY,EACjBpS,KAAKqS,SAAW,IAEA,IAATK,GAETP,EAAYlB,EAAawI,EAAazZ,KAAKoS,UAAWpS,KAAKqS,SAAUkB,GACjEkG,GAAelG,IACjBvT,KAAK0S,KAAO,IAId1S,KAAKqZ,MAAO,GAEdrZ,KAAKmS,UAAYA,EACjBnS,KAAK6R,OACL1F,EAAInM,KAAKoZ,IAAI1C,KAAK1W,KAAMgD,EAAM,GAChC,CAOQ,oBAAAkS,EAAuBvU,EAAGC,EAAGuU,EAAM,EAAGC,EAAM,IAC5C,MAAArD,UAAEA,EAAWC,WAAAA,GAAehS,KAC5BgQ,EAAShQ,KAAKmW,eAAenG,OACnC,IAAIlM,EAAM,CACR9D,KAAKwW,UAAW7V,GAAKoR,EAAY/B,GAAUrP,EAC3CX,KAAKwW,UAAW5V,GAAKoR,EAAahC,GAAUpP,GAMvC,OAJPuU,GAAOC,GAAOtR,EAAIgB,KAChBiN,EAAYoD,EAAMnF,GAAUmF,EAAM,GAClCnD,EAAaoD,EAAMpF,GAAUoF,EAAM,IAE9BtR,CACT,CAOU,cAAA4V,CAAgB/Y,EAAWC,GAC7B,MAAAwI,OAAEA,GAAWpJ,KACnB,MAAO,CAACW,EAAIyI,EAAOuC,IAAK/K,EAAIwI,EAAOuC,IACrC,sBCpnBF,cAAwCxC,EA2CtC,WAAApD,CAAaqD,EAAwBnH,GAhEvC,IAAAqB,EAiEIgO,MAAMlI,EAAQ,CACZ1D,MAAOzD,EAAKyD,MACZ+F,OAAQxJ,EAAKwJ,SA7CjBzF,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,SAA2B,IACnCgG,EAAAhG,KAAQ,UAA6B,IACrCgG,EAAAhG,KAAQ,gBAAmC,CAAA,GAC3CgG,EAAAhG,KAAQ,eAAiC,CAAA,GACzCgG,EAAAhG,KAAQ,iBAA8C,CAAA,GACtDgG,EAAAhG,KAAQ,gBAA4C,CAAA,GAC5CgG,EAAAhG,KAAA,iBACAgG,EAAAhG,KAAA,eACRgG,EAAAhG,KAAQ,SAAS,GACjBgG,EAAAhG,KAAQ,cAAc,GACtBgG,EAAAhG,KAAQ,WAAW,GACnBgG,EAAAhG,KAAQ,WAAW,GACnBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,eAAe,GACvBgG,EAAAhG,KAAQ,YAAY,GACpBgG,EAAAhG,KAAQ,UAAU,GAClBgG,EAAAhG,KAAQ,UAAU,GAClBgG,EAAAhG,KAAQ,SAAS,GACjBgG,EAAAhG,KAAQ,MAAM,MAQdgG,EAAAhG,KAAQ,OAAsB,GAOtBgG,EAAAhG,KAAA,aACAgG,EAAAhG,KAAA,iBAAiBuR,KAYvBvR,KAAKwR,SAASvP,GACdjC,KAAKyR,YACLzR,KAAK0R,eAEL,OAAOpO,EAAA8F,EAAAuI,iBAAcpQ,KAAKvB,MAE1BA,KAAK4R,MACP,CAEU,MAAApH,GA9EZ,IAAAlH,EAAAsH,EA+EI0G,MAAM9G,SACNxK,KAAK2Z,OAASpZ,KAAKwQ,IAAI/Q,KAAKmL,SAAUnL,KAAKoL,WAAa,EACxDpL,KAAKkF,IAAI0U,UAAU5Z,KAAK2Z,OAAQ3Z,KAAK2Z,QACrC3Z,KAAK6R,OACL,OAAAjH,GAAAtH,EAAAtD,KAAKoJ,QAAO0I,cAAZlH,EAAArJ,KAAA+B,EACF,CAEU,SAAA4H,GACRlL,KAAK2Z,OAAS,EACd3Z,KAAK6Z,YAAc,EACnB7Z,KAAK8Z,SAAW,EAChB9Z,KAAK+Z,SAAW,EAChB/Z,KAAKga,UAAY,EACjBha,KAAKia,aAAe,EACpBja,KAAKiS,UAAY,EACjBjS,KAAKkS,QAAU,EACflS,KAAKka,QAAU,EACfla,KAAKma,OAAS,EACdna,KAAKwS,IAAM,KACXxS,KAAKyS,WAAY,EACjBzS,KAAK0S,KAAO,EACZpB,MAAMpG,WACR,CAMQ,QAAAsG,CAAUvP,GAChBjC,KAAKkP,KAAKlP,KAAM,QAASiC,EAAKyD,OAC9B1F,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAKwJ,QAC/BzL,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK4Q,QAAU,IACzC7S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK6Q,QAAU,IACzC9S,KAAKkP,KAAKlP,KAAM,UAAWiC,EAAK8Q,SAAW,IAC3C/S,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKgR,eAAiB,CAAA,GACvDjT,KAAKkP,KAAKlP,KAAM,eAAgBiC,EAAKiR,cAAgB,CAAA,GACrDlT,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKjB,OACtChB,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAK8N,IACtC,CAKQ,YAAA2B,GAED1R,KAAAmP,UAAUnP,KAAM,iBAAkB,IACtBoT,EAAA,CACbpD,OAAQ,MACRoK,aAAc,EACd/G,MAAO,GACPgH,cAAe,OACf/G,iBAAkB,KAClBC,iBAAkB,KAClB+G,UAAW,GACRta,KAAKiT,gBAKPjT,KAAAmP,UAAUnP,KAAM,gBAAiB,IACtBoT,EAAA,CACZ7H,SAAU,OACVkI,UAAW,OACXC,UAAW,aACXC,WAAY,MACZC,WAAY,gBACZE,UAAU,EACVC,YAAa,OACV/T,KAAKkT,cAId,CAKQ,SAAAzB,GAEDzR,KAAAoP,OAAO,QAAUjH,IACpBnI,KAAKiC,KAAKyD,MAAQyC,EAClBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAWjH,IACrBnI,KAAKiC,KAAKwJ,OAAStD,EACnBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,SAAW4E,IACrBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IAEN3I,KAAAoP,OAAO,UAAY4E,IACtBhU,KAAKiU,kBACJ,CAAEtL,MAAM,IACN3I,KAAAoP,OAAO,gBAAiB,IAAMpP,KAAK6R,OAAQ,CAAElJ,MAAM,IACnD3I,KAAAoP,OAAO,eAAgB,IAAMpP,KAAK6R,OAAQ,CAAElJ,MAAM,IACvD3I,KAAKoP,OAAO,gBAAiB,IAAMpP,KAAK4R,QACxC5R,KAAKoP,OAAO,cAAe,IAAMpP,KAAK4R,OACxC,CAKa,IAAAA,GAAuB,OAAAsC,EAAAlU,KAAA,KAAA,YA5LtC,IAAAsD,EAAAsH,EA6LI5K,KAAKkL,YACC,MAAA9B,OAAEA,GAAWpJ,KAEnB,OAAOsD,EAAA8F,EAAA+K,eAAY5S,KAAKvB,MACxBA,KAAK6R,OACL7R,KAAK6R,aAEC7R,KAAKiU,iBAEX,OAAOrJ,EAAAxB,EAAAgL,cAAW7S,KAAKvB,KAAA,EACzB,CAEQ,cAAAiU,GACC,OAAA,IAAInH,QAASC,IAClB,MAAMyH,EAAiB,CACrB3B,OAAQ7S,KAAK6S,OAAOpP,IAAIL,GAASA,EAAMmR,MACvCzB,OAAQ9S,KAAK8S,OAAOrP,IAAIgR,GAASA,EAAMF,MACvCxB,QAAS/S,KAAK+S,QAAQtP,IAAI6Q,GAAOA,EAAIC,OAEJ5U,OAAO6H,KAAKgN,GAAiBnO,QAAmBqO,IAC3E,MAAAC,EAAaH,EAAeE,GAE5BE,EAA8B,GACpCD,GAAcA,EAAWtO,QAAQ,CAACkO,EAAMM,KACtCN,GAAQA,EAAKlO,QAAQ,CAAC0H,EAAS+G,KAC7BF,EAAW9P,KAAK9E,KAAK+U,gBAAgBL,EAASG,EAAWC,QAG7DhI,QAAQkI,IAAIJ,GAAYK,KAAK,KAC3BjV,KAAK6R,OACG9E,SAIhB,CAMU,WAAA7C,CAAaC,GArOzB,IAAA7G,EAsOU,MAAA4B,IAAEA,GAAQlF,KAChBkF,EAAI+K,YACA/K,EAAAoL,IAAI,EAAG,EAAGtQ,KAAKia,aAAc,EAAa,EAAV1Z,KAAKoP,IAAQ,GAC5CzK,EAAIoQ,cAAcnL,EAAEoL,QAASpL,EAAEqL,UAClB,IAAdxV,KAAK0S,OACT,OAAApP,EAAAtD,KAAKyV,gBAAgBnS,EAAA/B,KAAAvB,KAAAmK,GACvB,CASc,eAAA4K,CACZW,EACAb,EACAC,GACe,OAAAZ,EAAAlU,KAAA,KAAA,YACf,OAAO,IAAI8M,QAAQ,CAACC,EAASC,KAE3B,MAAM2I,EAA2C3V,KAAK0V,GAAUb,GAChE,IAAKc,IAASA,EAAKpB,KAAM,OACnB,MAAAxG,EAAU4H,EAAKpB,KAAKO,GACrB/G,GAEL/N,KAAK0M,QAAQqB,EAAQpB,IAAKoB,GAASkH,KAAWsF,GAAWrG,EAAAlU,KAAA,KAAA,YACtB,mBAAtB+N,EAAQiI,YACPuE,QAAMzN,QAAQC,QAAQgB,EAAQiI,UAAUzU,KAAKvB,KAAMua,KAE/Dva,KAAKiW,WAAWjO,IAAI+F,EAAa,IAAGwM,GAC5BxN,GAAA,IACPmJ,MAAarI,IACNxD,QAAAC,MAAM,GAAGoL,KAAYb,WAAmBC,MAAajH,KACtDb,OAEV,EACH,CAEQ,SAAAwN,CAAWC,EAAgBrX,EAAkBqT,GAC7C,MAAAvR,IAAEA,GAAQlF,KACZyC,EAAcW,EAAMwQ,cACtB1O,EAAI+K,YACJ/K,EAAIyR,UAAYvT,EAAMwQ,WAClB1O,EAAAoL,IAAI,EAAG,EAAGmK,EAAQ,EAAa,EAAVla,KAAKoP,IAAQ,GACtCzK,EAAI2R,QAENzT,EAAMmR,MAAQnR,EAAMmR,KAAKlO,QAAQ,CAAC0H,EAAS+G,KACzC,MAAMgC,EAAW9W,KAAKiW,WAAWnO,IAAIiG,EAAQpB,KAC7C,IAAKmK,EAAU,OAET,MAAC7I,EAAWC,GAAclO,KAAK8N,uBAAuBgJ,EAAU/I,EAAkB,EAAT0M,EAAqB,EAATA,IACpF1D,EAAOC,GAAS,CAAChX,KAAK8O,WAAWb,GAAajO,KAAKqD,UAAU0K,EAAQkJ,KAAe,EAATwD,GAAaza,KAAKqD,UAAU0K,EAAQmJ,IAAc,EAATuD,GAAcA,GACzIvV,EAAIwV,OACJ3M,EAAQ4M,QAAUzV,EAAIyV,OAAOlL,EAASzP,KAAKga,YAC3Cha,KAAKqN,UAAUnI,EAAK4R,EAAUC,EAAOC,EAAO/I,EAAWC,GACvDhJ,EAAI0V,WAER,CAKU,IAAA/I,GAtSZ,IAAAvO,EAAAsH,EAuSI,MAAMxB,OAAEA,EAAAlE,IAAQA,EAAKiR,eAAAA,EAAAC,cAAgBA,GAAkBpW,KAEvD,OAAOsD,EAAA8F,EAAAkN,aAAYhT,EAAA/B,KAAKvB,KAAMkF,GAE9BA,EAAIwG,WAAW1L,KAAK2Z,QAAS3Z,KAAK2Z,OAAsB,EAAd3Z,KAAK2Z,OAA0B,EAAd3Z,KAAK2Z,QAEhE3Z,KAAK6Z,YAAc7Z,KAAK6S,OAAOlO,OAAO,CAAC8V,EAAQrX,EAAOqT,KAC/CzW,KAAAwa,UAAUC,EAAQrX,EAAOqT,GACvBgE,EAASza,KAAKqD,UAAUD,EAAMG,SAAWH,EAAMG,QAAQC,MAAM,KAAK,KACxExD,KAAK2Z,QAEH3Z,KAAA8Z,SAAW,IAAM9Z,KAAK8S,OAAO1S,OAC7BJ,KAAA+Z,SAAWtK,EAASzP,KAAK8Z,UACxB,MAAAe,EAAY7a,KAAK6Z,YAActZ,KAAKiQ,IAAIxQ,KAAK+Z,SAAW,GAAK,EAE/D,IAAA/Y,EAAQyO,EAASzP,KAAKga,UAAY,GAAKha,KAAK8Z,SAAW,EAAI3D,EAAeiE,cAExE,MAAAU,EAAW,CAACnD,EAAoBG,IAC7B9X,KAAK8O,WAAW5J,EAAIO,YAAYqS,GAAMpS,OAAS1F,KAAKqD,UAAUsU,EAAKV,KAAM4D,GAG5EE,EAAW,CAACpD,EAAoBlM,EAAgBsM,KAEpD,MAAMF,EAAaF,EAAKE,YAAczB,EAAcyB,YAAcF,EAAKpM,UAAY6K,EAAc7K,SAC1F,OAAAvL,KAAKqD,UAAUsU,EAAKT,IAAKzL,IAAWsM,EAAY,GAAK/X,KAAKqD,UAAUwU,IAE7E3S,EAAIwV,OAEJ1a,KAAK8S,OAAOzM,QAAQ,CAACoO,EAAOuG,KAEtB,IAAAC,EAAgBja,EAAQga,EAAahb,KAAK+Z,SAE1CmB,EAAclb,KAAK6Z,YAAc7Z,KAAKia,aAEpC,MAAArG,EAAaa,EAAMb,YAAcwC,EAAcxC,WACjDnR,EAAcmR,KAChB1O,EAAIyR,UAAY/C,EAChBhE,EACE1K,EAAKlF,KAAKia,aAAcja,KAAK6Z,YAC7BoB,EAAgBjb,KAAK+Z,SAAW,EAChCkB,EAAgBjb,KAAK+Z,SAAW,EAChC/Z,KAAKqD,UAAU8S,EAAenG,SAEhC9K,EAAI2R,QAGN,IAAIlW,EAAIJ,KAAKkQ,IAAIwK,GAAiBjb,KAAK6Z,YACnCjZ,EAAIL,KAAKiQ,IAAIyK,GAAiBjb,KAAK6Z,YACnC3U,EAAA0U,UAAUjZ,EAAGC,GACjBsE,EAAIyV,OAAOM,EAAgBxL,EAAS,KAEpCgF,EAAMF,MAAQE,EAAMF,KAAKlO,QAAQ,CAAC0H,EAAS+G,KACzC,MAAMqG,EAAWnb,KAAKiW,WAAWnO,IAAIiG,EAAQpB,KAC7C,IAAKwO,EAAU,OACf,MAAOlN,EAAWC,GAAclO,KAAK8N,uBACnCqN,EACApN,EACA/N,KAAK+Z,SAAW/Z,KAAK6Z,YACrBqB,IAEKnE,EAAOC,GAAS,CACrBhX,KAAK8O,WAAWb,GAAajO,KAAKqD,UAAU0K,EAAQkJ,KAAM4D,GAC1D7a,KAAKqD,UAAU0K,EAAQmJ,IAAKgE,IAE9Blb,KAAKqN,UAAUnI,EAAKiW,EAAUpE,EAAOC,EAAO/I,EAAWC,KAGzDuG,EAAMiD,OAASjD,EAAMiD,MAAMrR,QAAgBsR,IACnC,MAAAlE,EAAYkE,EAAKlE,WAAa2C,EAAc3C,UAC5CE,EAAagE,EAAKhE,YAAcyC,EAAczC,WAC9CpI,EAAWvL,KAAKqD,UAAUsU,EAAKpM,UAAY6K,EAAc7K,UACzDmI,EAAYiE,EAAKjE,WAAa0C,EAAc1C,UAC5CI,EAAW9R,EAAI2V,EAAM,YAAcA,EAAK7D,SAAWsC,EAActC,SACjEC,EAAc4D,EAAK5D,aAAeqC,EAAcrC,YAChD1O,EAAYsS,EAAKtS,WAAa+Q,EAAc/Q,UAClDH,EAAIyR,UAAYlD,EAChBvO,EAAIyS,KAAO,GAAGhE,KAAcpI,EAAY,OAAOmI,IAC/C,IAAInO,EAAQ,GAAIJ,EAAOrE,OAAO6W,EAAKxS,MAEjCI,EADEuO,EACM7O,EAAUC,EAAK9C,EAAY+C,GAAQI,IAMzC,IAAIM,EAAuB,IAJN7F,KAAK6Z,YAAckB,EAASpD,EAAMuD,EAAa3V,EAAMnF,SAEzCG,KAAK+X,IAAItY,KAAK+Z,SAAW,IAE3B/Z,KAAKqD,UAAU8S,EAAenG,QACtD,OAAAhQ,KAAKqD,UAAU0Q,EAAalO,IAClCR,GAEKF,EAAK3B,MAAM,MAEf+B,EAAAjD,YAAiBwV,GAAMzR,QAAQ,CAACyR,EAAMC,KACtC7S,EAAA8S,SAASF,EAAMgD,EAASnD,EAAMG,GAAOiD,EAASpD,EAAMuD,EAAanD,QAIzE7S,EAAIyV,OAAOlL,EAAS,KAAOwL,EAAgBxL,EAAS,KACpDvK,EAAI0U,WAAWjZ,GAAIC,KAErBsE,EAAI0V,UAEJ5a,KAAK+S,QAAQ1M,QAAQ,CAACiO,EAAK8G,KACzB,IAAIX,EAASza,KAAKqD,UAAUiR,EAAImG,OAAQza,KAAK6Z,aAE7C7Z,KAAKia,aAAe1Z,KAAKC,IAAIR,KAAKia,aAAcQ,GAC5ChY,EAAc6R,EAAIV,cACpB1O,EAAI+K,YACJ/K,EAAIyR,UAAYrC,EAAIV,WAChB1O,EAAAoL,IAAI,EAAG,EAAGmK,EAAQ,EAAa,EAAVla,KAAKoP,IAAQ,GACtCzK,EAAI2R,QAGFvC,EAAI+G,SAAW5Y,EAAc6R,EAAIV,cACnC1O,EAAI+K,YACJ/K,EAAIyR,UAAYrC,EAAIV,WAChB1O,EAAA8L,QAAQyJ,EAAQ,GAChBvV,EAAAqL,OAAOkK,EAAQ,GACnBvV,EAAIqL,OAAO,EAAa,GAATkK,GACfvV,EAAIyL,YACJzL,EAAI2R,QAGNvC,EAAIC,MAAQD,EAAIC,KAAKlO,QAAQ,CAAC0H,EAAS+G,KACrC,MAAMwG,EAAStb,KAAKiW,WAAWnO,IAAIiG,EAAQpB,KAC3C,IAAK2O,EAAQ,OACP,MAACrN,EAAWC,GAAclO,KAAK8N,uBAAuBwN,EAAQvN,EAAkB,EAAT0M,EAAqB,EAATA,IAClF1D,EAAOC,GAAS,CAAChX,KAAK8O,WAAWb,GAAajO,KAAKqD,UAAU0K,EAAQkJ,KAAMwD,GAASza,KAAKqD,UAAU0K,EAAQmJ,IAAKuD,IACvHza,KAAKqN,UAAUnI,EAAKoW,EAAQvE,EAAOC,EAAO/I,EAAWC,KAGvDoG,EAAIoD,OAASpD,EAAIoD,MAAMrR,QAAgBsR,IACjC,IAAAlE,EAAYkE,EAAKlE,WAAa2C,EAAc3C,UAC5CE,EAAagE,EAAKhE,YAAcyC,EAAczC,WAC9CpI,EAAWvL,KAAKqD,UAAUsU,EAAKpM,UAAY6K,EAAc7K,UACzDmI,EAAYiE,EAAKjE,WAAa0C,EAAc1C,UAChDxO,EAAIyR,UAAYlD,EAChBvO,EAAIyS,KAAO,GAAGhE,KAAcpI,EAAY,OAAOmI,IACxC5S,OAAA6W,EAAKxS,MAAM3B,MAAM,MAAM6C,QAAQ,CAACyR,EAAMC,KACvC7S,EAAA8S,SAASF,EAAMgD,EAASnD,EAAMG,GAAOiD,EAASpD,EAAM8C,EAAQ1C,UAKtE,OAAOnN,EAAAxB,EAAA6O,YAAWrN,EAAArJ,KAAKvB,KAAMkF,EAC/B,CAKQ,2BAAA0T,GACN,MAAMzC,eAAEA,EAAA1D,UAAgBA,EAAWqH,SAAAA,EAAAE,UAAUA,GAAcha,KACtDA,KAAAkS,QAAU2G,KAAKC,MACd,MAAAoB,EAAUla,KAAKka,QAAUF,EACzB3G,EAAQ8C,EAAe9C,MACvBiH,GAAa/Z,KAAKwE,SAAW+U,EAAWA,EAAW,GAAK9Z,KAAKqD,UAAU8S,EAAemE,WAC5F,IAAI3U,EAAI,EAAGoT,EAAY,EAAGwC,EAAU,EACpC,OAAS5V,GAAG,CACJ,MAAAwU,EAAS,IAAMxU,EAAI8M,EAAaqH,EAAWE,EAAY7D,EAAeiE,aAAeE,EAAYR,EAAW,EAC9G,IAAAb,EAAYhI,EAAajR,KAAKwS,IAAK0H,EAASC,EAAQhE,EAAe5C,kBAAoB2G,EAC3F,GAAIjB,EAAY5F,EAAO,CACrBrT,KAAKma,OAAU9G,EAAQ0F,EAAYE,EAAY5F,EAAS8G,EAASoB,EACjE,KACF,CACUA,EAAApB,EACEpB,EAAAE,CACd,CACF,CAKO,IAAAC,GAldT,IAAA5V,EAAAsH,EAmdsB,IAAd5K,KAAK0S,OAEJ1S,KAAAiS,UAAY4G,KAAKC,MAEtB9Y,KAAKyS,eAAY,EAEjBzS,KAAK0S,KAAO,EAEZ,OAAA9H,GAAAtH,EAAAtD,KAAKoJ,QAAO+P,aAAZvO,EAAArJ,KAAA+B,GAEAtD,KAAKoZ,MACP,CAMO,IAAAC,CAAMzL,GACX,GAAkB,IAAd5N,KAAK0S,MAA4B,IAAd1S,KAAK0S,KAA5B,CAEI,IAAC9E,GAAmB,IAAVA,EAAa,CACzB,MAAMpJ,EAAWxE,KAAK8S,OAAOrP,IAAIgV,GAAQA,EAAKa,OAC9C1L,EAAQrJ,EAAaC,EACvB,CAEIoJ,EAAQ,GACV5N,KAAK0S,KAAO,EACZ1S,KAAKyS,WAAY,IAEjBzS,KAAK0S,KAAO,EACP1S,KAAAyS,UAAY7E,EAAQ5N,KAAK8S,OAAO1S,OAZC,CAc1C,CAMQ,GAAAgZ,CAAKpW,EAAc,GAzf7B,IAAAM,EA0fI,MAAM6I,IAAEA,EAAAuG,KAAKA,EAAMD,UAAAA,EAAA0D,eAAWA,GAAmBnW,MAC3CsT,iBAAEA,EAAAC,iBAAkBA,EAAkBF,MAAAA,GAAU8C,EAEtD,GAAa,IAATzD,EAEF,YADA,OAAKpP,EAAAtD,KAAAuZ,cAAcjW,EAAA/B,KAAAvB,KAAAA,KAAK8S,OAAO5R,KAAK,CAACuT,EAAO7G,IAAUA,IAAU6E,IAAc,CAAA,IAIhF,IAAsB,IAAlBA,EAAkB,OAET,IAATC,GAAe1S,KAAKma,aAAavB,8BAErC,MAAMY,EAAgBX,KAAKC,MAAQ9Y,KAAKiS,UAClCwH,EAAcZ,KAAKC,MAAQ9Y,KAAKkS,QACtC,IAAI8H,EAAYha,KAAKga,UAEjB,GAAS,IAATtH,GAAc8G,EAAgBlG,EAAkB,CAElDtT,KAAKwS,IAAMgH,EAAgBxW,EAC3B,MAAMiW,EAAYhI,EAAYuI,EAAe,EAAGnG,EAAOC,GAEnD2F,IAAc5F,IAChBrT,KAAK0S,KAAO,GAEdsH,GAAwBf,EAAY,GAAA,MAClB,IAATvG,GAETsH,GAAwB3G,EAAQ,SAEJ,IAAxBZ,GAAwBA,GAAa,IACvCzS,KAAK0S,KAAO,EAEZ1S,KAAKka,QAAU,EACfla,KAAKma,OAAS,IAEE,IAATzH,GAETsH,EAAY/I,EAAawI,EAAazZ,KAAKka,QAASla,KAAKma,OAAQ5G,GAC7DkG,GAAelG,IACjBvT,KAAK0S,KAAO,IAId1S,KAAKqZ,MAAO,GAEdrZ,KAAKga,UAAYA,EACjBha,KAAK6R,OACL1F,EAAInM,KAAKoZ,IAAI1C,KAAK1W,KAAMgD,EAAM,GAChC,CAOU,cAAA0W,CAAgB/Y,EAAWC,GAC7B,MAAAwI,OAAEA,GAAWpJ,KACZ,MAAA,CAACW,EAAIyI,EAAOuC,IAAM3L,KAAK2Z,OAAQ/Y,EAAIwI,EAAOuC,IAAM3L,KAAK2Z,OAC9D,uBC5hBF,cAAyCxQ,EAwDvC,WAAApD,CAAYqD,EAAwBnH,GAhFtC,IAAAqB,EAiFIgO,MAAMlI,EAAQ,CACZ1D,MAAOzD,EAAKyD,MACZ+F,OAAQxJ,EAAKwJ,SAzDjBzF,GAAAhG,KAAQ,SAA2B,IAEnCgG,GAAAhG,KAAQ,SAA2B,IAEnCgG,GAAAhG,KAAQ,QAAyB,IAEjCgG,GAAAhG,KAAQ,gBAAmC,CAAA,GAC3CgG,GAAAhG,KAAQ,iBACN,CAAA,GAEFgG,GAAAhG,KAAQ,eAAiC,CAAA,GACzCgG,GAAAhG,KAAQ,gBACN,CAAA,GACFgG,GAAAhG,KAAQ,cAA+B,QAE/BgG,GAAAhG,KAAA,oBACRgG,GAAAhG,KAAQ,YAAY,GACpBgG,GAAAhG,KAAQ,aAAa,GACrBgG,GAAAhG,KAAQ,iBAAiB,GACzBgG,GAAAhG,KAAQ,kBAAkB,GAC1BgG,GAAAhG,KAAQ,mBAAmB,GAC3BgG,GAAAhG,KAAQ,MAAM,MACdgG,GAAAhG,KAAQ,SAAmB,IAC3BgG,GAAAhG,KAAQ,aAAuB,IAC/BgG,GAAAhG,KAAQ,YAAsB,IAC9BgG,GAAAhG,KAAQ,YAAY,GACpBgG,GAAAhG,KAAQ,UAAoB,IAC5BgG,GAAAhG,KAAQ,WAAiC,IAEzCgG,GAAAhG,KAAQ,eAAyB,IAOjCgG,GAAAhG,KAAQ,OAAkB,GAOlBgG,GAAAhG,KAAA,aAEAgG,GAAAhG,KAAA,aAEAgG,GAAAhG,KAAA,iBAAiBuR,KAYvBvR,KAAKwR,SAASvP,GACdjC,KAAKyR,YACLzR,KAAK0R,eAEL,OAAOpO,EAAA8F,EAAAuI,iBAAcpQ,KAAKvB,MAE1BA,KAAK4R,MACP,CAEU,MAAApH,GA9FZ,IAAAlH,EAAAsH,EA+FI0G,MAAM9G,SACNxK,KAAKwb,wBACL,OAAA5Q,GAAAtH,EAAAtD,KAAKoJ,QAAO0I,cAAZlH,EAAArJ,KAAA+B,EACF,CAEU,SAAA4H,GACRlL,KAAK+R,UAAY,EACjB/R,KAAKgS,WAAa,EAClBhS,KAAKyb,eAAiB,EACtBzb,KAAK0b,gBAAkB,EACvB1b,KAAK2b,iBAAmB,EACxB3b,KAAKwS,IAAM,KACXxS,KAAK4b,OAAS,GACd5b,KAAK6b,WAAa,GAClB7b,KAAK8b,UAAY,GACjB9b,KAAKiS,UAAY,EACjBjS,KAAKkS,QAAU,GACflS,KAAK+b,SAAW,GAChB/b,KAAKyS,eAAY,EACjBzS,KAAK0S,KAAO,EACZpB,MAAMpG,WACR,CAMQ,QAAAsG,CAASvP,GACfjC,KAAKkP,KAAKlP,KAAM,QAASiC,EAAKyD,OAC9B1F,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAKwJ,QAC/BzL,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK4Q,QAAU,IACzC7S,KAAKkP,KAAKlP,KAAM,SAAUiC,EAAK6Q,QAAU,IACzC9S,KAAKkP,KAAKlP,KAAM,QAASiC,EAAK+Z,OAAS,IACvChc,KAAKkP,KAAKlP,KAAM,gBAAiBiC,EAAKgR,eAAiB,CAAA,GACvDjT,KAAKkP,KAAKlP,KAAM,eAAgBiC,EAAKiR,cAAgB,CAAA,GACrDlT,KAAKkP,KAAKlP,KAAM,cAAeiC,EAAK8N,IACtC,CAKQ,YAAA2B,GAED1R,KAAAmP,UAAUnP,KAAM,iBAAkB,KACrC,MAAMoJ,EAASgK,GAAA,CACb6I,KAAM,WACNC,WAAY,EACZC,WAAY,EACZ9I,MAAO,GACP+E,UAAW,EACX9E,iBAAkB,KAClBC,iBAAkB,MACfvT,KAAKiT,eAIH,OAFP7J,EAAO8S,WAAalc,KAAKqD,UAAU+F,EAAO8S,YAC1C9S,EAAO+S,WAAanc,KAAKqD,UAAU+F,EAAO+S,YACnC/S,IAGJpJ,KAAAmP,UAAUnP,KAAM,gBAAiB,IAC7BoT,GAAA,CACLI,aAAc,EACdC,UAAW,OACXlI,SAAU,OACVmI,UAAW,aACXC,WAAY,MACZC,WAAY,gBACZE,UAAU,EACVC,YAAa,OACV/T,KAAKkT,cAGd,CAKQ,SAAAzB,GAEDzR,KAAAoP,OAAO,QAAUjH,IACpBnI,KAAKiC,KAAKyD,MAAQyC,EAClBnI,KAAKwK,WAGFxK,KAAAoP,OAAO,SAAWjH,IACrBnI,KAAKiC,KAAKwJ,OAAStD,EACnBnI,KAAKwK,WAGFxK,KAAAoP,OACH,SACC4E,IACChU,KAAKiU,kBAEP,CAAEtL,MAAM,IAGL3I,KAAAoP,OACH,SACC4E,IACChU,KAAKiU,kBAEP,CAAEtL,MAAM,IAGL3I,KAAAoP,OACH,QACC4E,IACChU,KAAKwb,yBAEP,CAAE7S,MAAM,IAEV3I,KAAKoP,OAAO,gBAAiB,IAAMpP,KAAKwb,wBAAyB,CAC/D7S,MAAM,IAER3I,KAAKoP,OAAO,eAAgB,IAAMpP,KAAKwb,wBAAyB,CAC9D7S,MAAM,IAER3I,KAAKoP,OAAO,cAAe,IAAMpP,KAAK4R,OACxC,CAKa,IAAAA,GAAsB,OAAAsC,GAAAlU,KAAA,KAAA,YA3NrC,IAAAsD,EAAAsH,EA4NI5K,KAAKkL,YACC,MAAA9B,OAAEA,GAAWpJ,KAEnB,OAAOsD,EAAA8F,EAAA+K,eAAY5S,KAAKvB,MAExBA,KAAKoc,sBACLpc,KAAK6R,aAEC7R,KAAKiU,iBAEX,OAAOrJ,EAAAxB,EAAAgL,cAAW7S,KAAKvB,KAAA,EACzB,CAEQ,qBAAAwb,GACNxb,KAAKoc,sBACLpc,KAAK6R,MACP,CAEQ,cAAAoC,GACC,OAAA,IAAInH,QAASC,IAClB,MAAMyH,EAAiB,CACrB3B,OAAQ7S,KAAK6S,OAAOpP,IAAKL,GAAUA,EAAMmR,MACzCzB,OAAQ9S,KAAK8S,OAAOrP,IAAKgR,GAAUA,EAAMF,OAER5U,OAAO6H,KAAKgN,GAAiBnO,QAC7DqO,IACO,MAAAC,EAAaH,EAAeE,GAE5BE,EAA8B,GACpCD,GACEA,EAAWtO,QAAQ,CAACkO,EAAMM,KACxBN,GACEA,EAAKlO,QAAQ,CAAC0H,EAAS+G,KACVF,EAAA9P,KACT9E,KAAK+U,gBAAgBL,EAASG,EAAWC,QAInDhI,QAAQkI,IAAIJ,GAAYK,KAAK,KAC3BjV,KAAKoc,sBACLpc,KAAK6R,OACG9E,SAKlB,CASc,eAAAgI,CACZW,EACAb,EACAC,GACe,OAAAZ,GAAAlU,KAAA,KAAA,YACf,OAAO,IAAI8M,QAAQ,CAACC,EAASC,KAC3B,IAAI2I,EAA8B3V,KAAK0V,GAAUb,GACjD,IAAKc,IAASA,EAAKpB,KAAM,OACnB,MAAAxG,EAAU4H,EAAKpB,KAAKO,GACrB/G,GAEL/N,KAAK0M,QAAQqB,EAAQpB,IAAKoB,GACvBkH,KAAYsF,GAAYrG,GAAAlU,KAAA,KAAA,YACU,mBAAtB+N,EAAQiI,YACjBuE,QAAgBzN,QAAQC,QACtBgB,EAAQiI,UAAUzU,KAAKvB,KAAMua,KAGjCva,KAAKiW,WAAWjO,IAAI+F,EAAa,IAAGwM,GAC5BxN,GAAA,IAETmJ,MAAOrI,IACExD,QAAAC,MAAM,GAAGoL,KAAYb,WAAmBC,MAAajH,KACtDb,OAEZ,EACH,CAKU,mBAAAoP,GACF,MAAAjG,eAAEA,EAAgBC,cAAAA,GAAkBpW,MACpC6Q,EAAEA,EAAAC,EAAGA,GAAM9Q,KAAKqc,aAEhBC,EAAYtc,KAAK8S,OAAO1S,QACxB2R,UAAEA,EAAWC,WAAAA,EAAA0J,gBAAYA,mBAAiBC,GAC9C3b,KAAKuc,4BACPvc,KAAKwc,aAAe,IAAIhd,MAAM8c,GAAWzF,UAAW,GAAEpT,IAAI,CAACgZ,EAAG9W,IAAMA,GACpE,IACE+W,EAAc,EACdC,EAAe,EACjB3c,KAAKgc,MAAM3V,QAAQ,CAACuW,EAAMC,cAEpB7c,KAAK4b,OAAOiB,KAA4B7c,KAAA4b,OAAOiB,GAAa,GAE1D,MAEAC,GAFQF,EAAKG,OAAS/c,KAAKwc,cAEXpc,OAEtBsc,EAAcnc,KAAKC,IAAIkc,EAAa7L,EAAI6K,EAAkBoB,GAC1DH,EAAepc,KAAKC,IAAImc,EAAc7L,EAAI6K,EAAmBmB,KAG/D,MAAM9N,iBAAEA,EAAAC,KAAkBA,GAASjP,KAAK+O,mBACtC2N,EACAC,GAEF3c,KAAKgP,iBAAmBA,EAExBhP,KAAKgc,MAAM3V,QAAQ,CAACuW,EAAMC,KACxB,MAAMG,EAAQjL,EAAY8K,EACpBI,EAAQjL,EAAa6K,EAC3B,IAAIK,EAAe,EAEnB,MAAMC,EXtJyB,EAAIC,EAAUL,KACjD,MAAMtZ,EAA4B,CAAA,EAAIK,EAAM,GAC5C,IAAA,IAAS6B,EAAI,EAAGA,EAAIyX,EAAIhd,OAAQuF,IAC1BlC,EAAAkC,GAAKyX,EAAIzX,GAEf,IAAA,IAASA,EAAI,EAAGA,EAAIoX,EAAM3c,OAAQuF,IAAK,CACrC,MAAMd,EAAOpB,EAAIsZ,EAAMpX,IACnBd,IAAOf,EAAI6B,GAAKd,EACtB,CACO,OAAAf,GW6IeuZ,CAChBrd,KAAK8S,OACL8J,EAAKG,OAAS/c,KAAKwc,cAGjB,IAACW,EAAU/c,OAAQ,OACb+c,EAAA9W,QAAQ,CAACsP,EAAMd,KACvB,IAAKc,EAAM,OACX,MAAM2H,EACJ5B,EAAkB7G,EAAYsB,EAAegG,WAAa,EACtDoB,EACJ5B,EAAmB9G,EAAYsB,EAAe+F,WAAa,GACtDsB,EAAIC,EAAIC,GAAW1d,KAAK2d,aAC7B,CAACX,EAAOO,EAAS5B,GACjB,CAAC2B,EAASL,EAAOvB,IAEHwB,GAAAQ,EAEV,MAAA9J,EAAa+B,EAAK/B,YAAcwC,EAAcxC,WAChD,GAAAnR,EAAcmR,GAAa,CAC7B,MAAMJ,EAAexT,KAAKqD,UACxBrB,EAAI2T,EAAM,gBACNA,EAAKnC,aACL4C,EAAc5C,cAEpB5C,EAAe3B,EAAMuO,EAAIC,EAAI1L,EAAWA,EAAWyB,GACnDvE,EAAK0H,UAAY/C,EACjB3E,EAAK4H,MACP,CAEAlB,EAAKpB,MACHoB,EAAKpB,KAAKlO,QAAQ,CAAC0H,EAAS+G,KAC1B,MAAM0C,EAAUxX,KAAKiW,WAAWnO,IAAIiG,EAAQpB,KAC5C,IAAK6K,EAAS,OACd,MAAOvJ,EAAWC,GAAclO,KAAK8N,uBACnC0J,EACAzJ,EACAgE,EACAC,IAEK+E,EAAOC,GAAS,CACrBwG,EACExd,KAAK8O,WAAWb,EAAW8D,GAC3B/R,KAAKqD,UAAU0K,EAAQkJ,KAAMlF,GAC/B0L,EAAKzd,KAAKqD,UAAU0K,EAAQmJ,IAAKlF,IAEnChS,KAAKqN,UAAU4B,EAAMuI,EAAST,EAAOC,EAAO/I,EAAWC,KAG3DyH,EAAK+B,OACH/B,EAAK+B,MAAMrR,QAASsR,IAEZ,MAAA5L,EAAQ4L,EAAKjE,WAAa0C,EAAc1C,UAExCC,EAAagE,EAAKhE,YAAcyC,EAAczC,WAE9CiE,EAAO5X,KAAKqD,UAAUsU,EAAKpM,UAAY6K,EAAc7K,UAErDsM,EACJF,EAAKE,YACLzB,EAAcyB,YACdF,EAAKpM,UACL6K,EAAc7K,SACVuI,EAAW9R,EAAI2V,EAAM,YACvBA,EAAK7D,SACLsC,EAActC,SACZC,EAAc4D,EAAK5D,aAAeqC,EAAcrC,YAChD1O,EAAYsS,EAAKtS,WAAa+Q,EAAc/Q,UAClD4J,EAAK0I,KAAO,GAAGhE,KAAciE,EAAQ,OAAO7L,IACvCkD,EAAA0H,UAAYgB,EAAKlE,WAAa2C,EAAc3C,UACjD,IAAIlO,EAAQ,GACVJ,EAAOrE,OAAO6W,EAAKxS,MAErB,GAAI2O,EAAU,CAEZ,IAAIjO,EAAW7F,KAAKqD,UAAU0Q,EAAahC,GACnCxM,EAAAN,EACNgK,EACA7M,EAAY+C,GACZ,IAAMU,EACNR,EACF,MAEQE,EAAAJ,EAAK3B,MAAM,MAEf+B,EAAAc,QAAQ,CAACyR,EAAMC,KACd9I,EAAA+I,SACHF,EACA0F,EACExd,KAAK8O,WAAWG,EAAKxJ,YAAYqS,GAAMpS,MAAOqM,GAC9C/R,KAAKqD,UAAUsU,EAAKV,KAAMlF,GAC5B0L,EACEzd,KAAKqD,UAAUsU,EAAKT,IAAKlF,IACxB+F,EAAY,GAAK/X,KAAKqD,UAAUwU,UAK7C,MAAO2F,EAAIC,EAAIG,EAAIC,GAAM7d,KAAK2d,aAC5B,CAACX,EAAO,EAAGjL,EAAWmL,GACtB,CAAC,EAAGD,EAAOC,EAAclL,IAE3B,IAAI8L,EAAUZ,EACP,KAAAY,EAAUnB,EAAeO,GAAc,CAC5C,MAAOa,EAAOC,GAAShe,KAAK2d,aAAa,CAACH,EAAIM,GAAU,CAACA,EAASL,IAC7Dzd,KAAAqN,UACH4B,EACAD,EACAwO,EACAC,EACAG,EACAC,EACAE,EACAC,EACAJ,EACAC,GAESC,GAAAZ,CACb,GAEJ,CAKU,UAAAb,GACR,MAAMjT,OAAEA,EAAAlE,IAAQA,EAAKiR,eAAAA,EAAAC,cAAgBA,GAAkBpW,KAE/C,OAAAA,KAAKwW,UAAYxW,KAAK6S,OAAOlO,OACnC,EAAGhE,IAAGC,IAAGiQ,IAAGC,KAAK1N,EAAOqT,KACtB,MAAO/S,EAAYC,EAAeC,EAAaC,GAC7CV,EAAeC,EAAOpD,KAAKqD,UAAUqT,KAAK1W,OACtCqQ,EAAIjN,EAAMoQ,aAAexT,KAAKqD,UAAUD,EAAMoQ,cAAgB,EAE9DI,EAAaxQ,EAAMwQ,YAAcwC,EAAcxC,WA+B9C,OA9BHnR,EAAcmR,KAChBhD,EAAe1L,EAAKvE,EAAGC,EAAGiQ,EAAGC,EAAGT,GAChCnL,EAAIyR,UAAY/C,EAChB1O,EAAI2R,QAGNzT,EAAMmR,MACJnR,EAAMmR,KAAKlO,QAAQ,CAAC0H,EAAS+G,KAC3B,MAAMgC,EAAW9W,KAAKiW,WAAWnO,IAAIiG,EAAQpB,KAC7C,IAAKmK,EAAU,OAEf,MAAO7I,EAAWC,GAAclO,KAAK8N,uBACnCgJ,EACA/I,EACA8C,EACAC,IAEKiG,EAAOC,GAAS,CACrBhX,KAAK8O,WAAWb,EAAW4C,GAAK7Q,KAAKqD,UAAU0K,EAAQkJ,KAAMpG,GAC7D7Q,KAAKqD,UAAU0K,EAAQmJ,IAAKpG,IAEzB9Q,KAAAqN,UACHnI,EACA4R,EACAnW,EAAIoW,EACJnW,EAAIoW,EACJ/I,EACAC,KAGC,CACLvN,EAAGA,EAAIiD,EACPhD,EAAGA,EAAI8C,EACPmN,EAAGA,EAAIjN,EAAcC,EACrBiN,EAAGA,EAAIpN,EAAaC,IAGxB,CAAEhD,EAAG,EAAGC,EAAG,EAAGiQ,EAAG7Q,KAAKmL,SAAU2F,EAAG9Q,KAAKoL,WAE5C,CAKU,IAAAyG,GAvgBZ,IAAAvO,EAwgBI,MAAM8F,OAAEA,EAAAlE,IAAQA,EAAKiR,eAAAA,EAAAC,cAAgBA,GAAkBpW,KAEvD,OAAOsD,EAAA8F,EAAAkN,aAAYhT,EAAA/B,KAAKvB,KAAMkF,GAE9BA,EAAIwG,UAAU,EAAG,EAAG1L,KAAKmL,SAAUnL,KAAKoL,WAExC,MAAMzK,EAAEA,EAAGC,EAAAA,EAAAiQ,EAAGA,IAAGC,GAAM9Q,KAAKqc,aAExB,IAACrc,KAAKgP,iBAAkB,OACtB,MAAA+C,UACJA,EAAAC,WACAA,EAAAyJ,eACAA,EAAAC,gBACAA,EAAAC,iBACAA,GACE3b,KACJA,KAAKgc,MAAM3V,QAAQ,CAACuW,EAAMC,KAClB,MAAAE,EAAQH,EAAKG,OAAS/c,KAAKwc,aAE3ByB,EAAKxC,EAAiBsB,EAAM3c,OAE5BY,EAAQhB,KAAK2d,eACf7M,EAAI6K,GAAoB,IACxB9K,EAAI6K,GAAmB,GAE3B,IAAIE,EAAS5b,KAAK4b,OAAOiB,GAAa7b,EAElC4a,EAAS,IACXA,EAAUA,EAASqC,EAAMA,GAEvBrC,EAASqC,IACXrC,GAAkBqC,GAEpB,MAAOC,EAAIC,EAAIC,EAAIC,GAAMre,KAAK2d,aAC5B,CAAC5L,EAAY8K,EAAWjB,EAAQ7J,EAAWjB,GAC3C,CAAC8K,EAAQ5J,EAAa6K,EAAWhM,EAAGmB,KAE/BsM,EAAIC,EAAIC,EAAIC,GAAMze,KAAK2d,aAC5B,CAAChd,EAAI+a,EAAkBmB,EAAWjc,EAAGmR,EAAWjB,GAChD,CAACnQ,EAAGC,EAAI+a,EAAmBkB,EAAWhM,EAAGmB,IAEtChS,KAAAqN,UACHnI,EACAlF,KAAKgP,iBACLkP,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,IAGN,CAKQ,2BAAA7F,CAA4BiE,GAClC,MAAM1G,eAAEA,EAAA1D,UAAgBA,EAAWgJ,eAAAA,GAAmBzb,KAChD4c,EAAO5c,KAAKgc,MAAMa,GAClBE,EAAQH,EAAKG,OAAS/c,KAAKwc,aACjC,IAAKO,EAAM3c,aAAgC,IAAtBqS,EAAsB,OAC3C,MAAMY,EAAQ9S,KAAKE,IAAImc,EAAKvJ,OAAS8C,EAAe9C,OAC9C+E,EAAYwE,EAAKxE,WAAajC,EAAeiC,UAC7CsG,EAAa3B,EAAM/X,UACtBgW,GAAeA,IAAevI,EAAUoK,IAErCoB,EAAKxC,EAAiBsB,EAAM3c,OAC5Byb,EAAc7b,KAAK6b,WAAWgB,GAAa7c,KAAK4b,OAAOiB,GAC7D7c,KAAKkS,QAAQ2K,GAAahE,KAAKC,MAC/B,IAAInT,EAAI,EACR,OAASA,GAAG,CACV,MAAMmW,EACJL,EAAiBiD,EAAaT,EAAKtY,EAAIyS,EAAYyD,EAC/C5C,EACJhI,EACEjR,KAAKwS,IACLqJ,EACAC,EACA3F,EAAe5C,kBACbsI,EACN,GAAItb,KAAKE,IAAIwY,GAAa5F,EAAO,CAC1BrT,KAAA8b,UAAUe,GAAaf,EAC5B,KACF,CACF,CACF,CAEQ,eAAA6C,GAlmBV,IAAArb,EAmmBI,SAAS,OAAAA,EAAKtD,KAAAyS,gBAAW,EAAAnP,EAAAlD,SAAUJ,KAAKyS,UAAUmM,MAAOnV,QAAwB,IAAfA,EACpE,CAEQ,gBAAAoV,GACN,OAAO7e,KAAKgc,MAAM4C,MAAM,CAAChC,EAAMC,MACfD,EAAKG,OAAS/c,KAAKwc,cACnBpc,QAAuC,IAA7BJ,KAAK+b,SAASc,GAE1C,CAEQ,WAAAiC,GACN,IAAK9e,KAAK2e,kBAA0B,OACpC,MAAMlM,EAAYzS,KAAKyS,UACnB,IAAAhJ,EAAOgJ,EAAU,GACrB,IAAA,IAAS9M,EAAI,EAAGA,EAAI3F,KAAKgc,MAAM5b,OAAQuF,IAAK,CACpC,MAAAiX,EAAO5c,KAAKgc,MAAMrW,GAClBoZ,EAAWtM,EAAU9M,GACrBoX,EAAQH,EAAKG,OAAS/c,KAAKwc,aACjC,KAAK,MAAAO,OAAA,EAAAA,EAAOrd,SAASqf,KAAatV,IAASsV,EAAU,CAC5CtV,GAAA,EACP,KACF,CACF,CACO,OAAAzJ,KAAK8S,OAAO5R,KAAK,CAACuT,EAAO7G,IAAUA,IAAUnE,SAAS,CAC/D,CAKO,IAAAyP,GAhoBT,IAAA5V,EAAAsH,EAioBsB,IAAd5K,KAAK0S,OAEJ1S,KAAAiS,UAAY4G,KAAKC,MAEtB9Y,KAAKyS,eAAY,EACjBzS,KAAK6b,WAAa,GAClB7b,KAAK8b,UAAY,GACjB9b,KAAKkS,QAAU,GACflS,KAAK+b,SAAW/b,KAAKgc,MAAMvY,IAAKmZ,IAChBA,EAAKG,OAAS/c,KAAKwc,cACpBpc,OAAS,EAAI,GAG5BJ,KAAK0S,KAAO,EAEZ,OAAA9H,GAAAtH,EAAAtD,KAAKoJ,QAAO+P,aAAZvO,EAAArJ,KAAA+B,GAEAtD,KAAKoZ,MACP,CAEO,IAAAC,CAAKzL,EAA0BiP,GArpBxC,IAAAvZ,EAspBQ,GAAc,IAAdtD,KAAK0S,KAAL,CAEA,GAAqB,iBAAdmK,EAAwB,CAC7B,IAAC3Z,OAAO8b,UAAUnC,IAAcA,EAAY,GAAKA,GAAa7c,KAAKgc,MAAM5b,OAC3E,OAAOiK,QAAQC,MAAM,QAAQsD,MAAUiP,qBAErC,GAAiB,iBAAVjP,EACF,OAAAvD,QAAQC,MAAM,QAAQ2U,KAAKC,UAAUtR,OAAWiP,mBAElC,IAAnB7c,KAAKyS,WAAyBzS,KAAKyS,UAAUrS,SAC1CJ,KAAAyS,UAAY,IAAIjT,MAAMQ,KAAKgc,MAAM5b,QAAQyW,UAAW,IAEtD7W,KAAAyS,UAAUoK,GAAajP,CAAA,MAC9B,GAA4B,iBAAVA,EACX5N,KAAAyS,UAAY,IAAIjT,MAAMQ,KAAKgc,MAAM5b,QAAQyW,KAAKjJ,OAC1C,KAAApM,EAAaoM,EAAO,SAS7B,OADA5N,KAAKqZ,MAAO,GACLhP,QAAQC,MAAM,2BAA2BsD,GARhD,GAAIA,EAAMxN,SAAWJ,KAAKgc,MAAM5b,OAI9B,OADAJ,KAAKqZ,MAAO,GACLhP,QAAQC,MAAM,SAASsD,gBAH9B5N,KAAKyS,UAAY7E,CAQrB,EAEI,OAAAtK,EAAKtD,KAAAyS,gBAAW,EAAAnP,EAAA5D,UAAc,KAChCM,KAAKyS,UAAY,GACjBzS,KAAK+b,SAAW/b,KAAK+b,SAAStY,IAAI,IAAM,GAExCzD,KAAK0S,KAAO,GAGZ1S,KAAK0S,KAAO,CAlCO,CAoCvB,CAMQ,GAAA0G,CAAIpW,EAAc,GAhsB5B,IAAAM,EAAAsH,EAisBI,MAAMuB,IAAEA,EAAAgK,eAAKA,EAAgBsF,eAAAA,EAAAO,MAAgBA,GAAUhc,MACjDsT,iBAAEA,EAAkBC,iBAAAA,GAAqB4C,EACzC1D,EAAYzS,KAAKyS,UACnB,GAAc,IAAdzS,KAAK0S,KAIP,YAHI1S,KAAK2e,mBAAqB3e,KAAK6e,qBACjC,OAAKvb,EAAAtD,KAAAuZ,cAAcjW,EAAA/B,KAAAvB,KAAAA,KAAK8e,iBAK5B,QAAkB,IAAdrM,IAAyBA,EAAUrS,OAAQ,OAE/C,MAAMoZ,EAAgBX,KAAKC,MAAQ9Y,KAAKiS,UAuDpC,GAtDAuH,GAAiBlG,GAAkC,IAAdtT,KAAK0S,OAC5C1S,KAAK0S,KAAO,GAGRsJ,EAAA3V,QAAQ,CAACuW,EAAMC,KACb,MAAAE,EAAQH,EAAKG,OAAS/c,KAAKwc,aACjC,IAAKO,IAAUA,EAAM3c,OAAQ,OACvB,MAAA6d,EAAKxC,EAAiBsB,EAAM3c,OAC5BiT,EAAQ9S,KAAKE,IAAImc,EAAKvJ,OAAS8C,EAAe9C,OAC9C+E,EAAYwE,EAAKxE,WAAajC,EAAeiC,UAC7C2D,EAAW/b,KAAK+b,SAASc,IAAc,EAC7C,IAAIjB,EAAS,EACXuD,EAAanf,KAAK4b,OAAOiB,GAC3B,GAAKd,EAAL,CACI,GAAa,IAAbA,GAAkBvC,EAAgBlG,EAAkB,CAGtDtT,KAAKwS,IAAMgH,EAAgBxW,EAC3B,MAAMiW,EAAYhI,EAAYuI,EAAe,EAAGnG,EAAOC,GAEnD2F,IAAc5F,IACXrT,KAAA+b,SAASc,GAAa,GAEnBjB,GAAAuD,EAAalG,EAAYb,GAAa6F,CAAA,MAClD,GAAwB,IAAblC,EAGCH,GAAAuD,EAAa9L,EAAQ+E,GAAa6F,OAEL,KAAnC,MAAAxL,OAAA,EAAAA,EAAYoK,MACT7c,KAAA+b,SAASc,GAAa,EACtB7c,KAAA4b,OAAOiB,GAAajB,EACzB5b,KAAK4Y,4BAA4BiE,SAErC,GAAwB,IAAbd,EAAgB,CAGnB,MAAAF,EAAa7b,KAAK6b,WAAWgB,GAC7Bf,EAAY9b,KAAK8b,UAAUe,GAC3BpD,EAAcZ,KAAKC,MAAQ9Y,KAAKkS,QAAQ2K,GAC9CjB,EAAS3K,EACPwI,EACAoC,EACAC,EACAvI,GAEEkG,GAAelG,IACjBqI,EAASC,EAAaC,EACjB9b,KAAA+b,SAASc,GAAa,EAE/B,CACK7c,KAAA4b,OAAOiB,GAAajB,CAtCV,IAwCjB5b,KAAK6R,OACD7R,KAAK6e,mBAKP,OAJA7e,KAAK0S,KAAO,OACR1S,KAAK2e,oBACP,OAAK/T,EAAA5K,KAAAuZ,cAAc3O,EAAArJ,KAAAvB,KAAAA,KAAK8e,iBAI5B3S,EAAInM,KAAKoZ,IAAI1C,KAAK1W,KAAMgD,EAAM,GAChC,CAGQ,YAAA2a,CAAgByB,EAAMjO,GAC5B,MAAoC,eAA7BnR,KAAKmW,eAAe8F,KAAwB9K,EAAIiO,CACzD,CAGQ,yBAAA7C,GACA,MAAAN,EAAOjc,KAAKmW,eAAe8F,KAC3BoD,EAAWrf,KAAKgc,MAAM5b,QACtB+b,WAAEA,EAAAD,WAAYA,GAAelc,KAAKmW,gBAClCxV,EAAEA,IAAGC,EAAGiQ,EAAAA,EAAAC,EAAGA,GAAM9Q,KAAKwW,WAAaxW,KAAKqc,aAC9C,IAAItK,EAAY,EACdC,EAAa,EACb0J,EAAkB,EAClBC,EAAmB,EAgBd,MAfM,eAATM,GACFjK,EAAahS,KAAKgS,YACflB,EAAIoL,GAAcmD,EAAW,IAAMA,EACtCtN,EAAY/R,KAAK+R,UAAYC,IAE7BD,EAAY/R,KAAK+R,WAAalB,EAAIsL,GAAckD,EAAW,IAAMA,EACjErN,EAAahS,KAAKgS,WAAaD,GAEf2J,EAAA1b,KAAK0b,gBAAkB1b,KAAK+R,UAAYoK,EACvCR,EAAA3b,KAAK2b,iBAAmB3b,KAAKgS,WAAakK,EAE3Dlc,KAAKyb,eADM,eAATQ,EACoBP,EAEAC,EAEjB,CACL5J,YACAC,aACA0J,kBACAC,mBAEJ,oBC3xBsB,CAAC2D,EAAc7E,KAC/B,MAAA8E,EAAS7V,SAASG,cAAc,UAChC3E,EAAMqa,EAAOxV,WAAW,OACxBrE,MAAEA,EAAO+F,OAAAA,GAAW6T,EAMnB,OALPC,EAAO7Z,MAAQA,EACf6Z,EAAO9T,OAASA,EAChBmF,EAAe1L,EAAK,EAAG,EAAGQ,EAAO+F,EAAQgP,GACzCvV,EAAIsa,OACJta,EAAImI,UAAUiS,EAAK,EAAG,EAAG5Z,EAAO+F,GACzB8T,mBASc,CACrBD,EACAG,KAEM,MAAAF,EAAS7V,SAASG,cAAc,UAChC3E,EAAMqa,EAAOxV,WAAW,OACxBrE,MAAEA,EAAO+F,OAAAA,GAAW6T,EAItB,GAHJC,EAAO7Z,MAAQA,EACf6Z,EAAO9T,OAASA,EAEU,iBAAfvG,EAAI5C,OACT4C,EAAA5C,OAAS,WAAqB,IAAVmd,MACxBva,EAAImI,UAAUiS,EAAK,EAAG,EAAG5Z,EAAO+F,OAC3B,CACLvG,EAAImI,UAAUiS,EAAK,EAAG,EAAG5Z,EAAO+F,GAChC,MAAMiU,EAAYxa,EAAIwI,aAAa,EAAG,EAAGhI,EAAO+F,IAC1CxJ,KAAEA,GAASyd,EACXvf,EAAM8B,EAAK7B,OACjB,IAAA,IAASuF,EAAI,EAAGA,EAAIxF,EAAKwF,GAAK,EAAG,CACzB,MAAA7C,EAAQb,EAAK0D,EAAI,GACT,IAAV7C,IAAab,EAAK0D,EAAI,GAAK7C,EAAQ2c,EACzC,CACIva,EAAAyI,aAAa+R,EAAW,EAAG,EACjC,CACO,OAAAH"}
@@ -0,0 +1,2 @@
1
+ Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(t,e){if(null==this)throw new TypeError('"this" is null or not defined');var i=Object(this),s=i.length>>>0;if(0===s)return!1;var h=0|e,n=Math.max(h>=0?h:s-Math.abs(h),0);function r(t,e){return t===e||"number"==typeof t&&"number"==typeof e&&isNaN(t)&&isNaN(e)}for(;n<s;){if(r(i[n],t))return!0;n++}return!1}}),String.prototype.includes||(String.prototype.includes=function(t,e){return"number"!=typeof e&&(e=0),!(e+t.length>this.length)&&-1!==this.indexOf(t,e)}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(t){if(null==this)throw new TypeError('"this" is null or not defined');var e=Object(this),i=e.length>>>0;if("function"!=typeof t)throw new TypeError("predicate must be a function");for(var s=arguments[1],h=0;h<i;){var n=e[h];if(t.call(s,n,h,e))return n;h++}}});const t=(t,...e)=>e.some(e=>Object.prototype.toString.call(t).slice(8,-1).toLowerCase()===e),e=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i=t=>[].filter.call(t,t=>"\n"!==t).join(""),s=t=>{if("string"!=typeof t)return!1;if("transparent"===(t=t.toLocaleLowerCase().trim()))return!1;if(/^rgba/.test(t)){const i=/([^\s,]+)\)$/.exec(t);if(0===(null===(e=i)?0:"object"==typeof e?NaN:"number"==typeof e?e:"string"==typeof e?"%"===e[e.length-1]?Number(e.slice(0,-1))/100:Number(e):NaN))return!1}var e;return!0},h=(i,s)=>{var h;let n=(null==(h=i.padding)?void 0:h.split(" ").map(t=>s(t)))||[0],r=0,a=0,o=0,l=0;switch(n.length){case 1:r=a=o=l=n[0];break;case 2:r=a=n[0],o=l=n[1];break;case 3:r=n[0],o=l=n[1],a=n[2];break;default:r=n[0],a=n[1],o=n[2],l=n[3]}const c={paddingTop:r,paddingBottom:a,paddingLeft:o,paddingRight:l};for(let h in c)c[h]=e(i,h)&&t(i[h],"string","number")?s(i[h]):c[h];return[r,a,o,l]},n=(t,e=300)=>{let i=null;return function(...s){i||(i=setTimeout(()=>{t.apply(this,s),clearTimeout(i),i=null},e))}},r=t=>{const e=[],i=t.map(t=>Number(t)).reduce((t,i)=>{if(i>0){const s=t+i;return e.push(s),s}return e.push(NaN),t},0),s=Math.random()*i;return e.findIndex(t=>s<=t)},a=(t,e,i,s=1/0)=>{s<=0&&(s=1/0);let h="";const n=[],r=t.measureText("...").width;for(let a=0;a<e.length;a++){h+=e[a];let o=t.measureText(h).width;const l=i(n);if(s===n.length+1&&(o+=r),l<0)return n;if(o>l&&(n.push(h.slice(0,-1)),h=e[a]),s===n.length)return n[n.length-1]+="...",n}return h&&n.push(h),n.length||n.push(e),n};var o="1.7.26",l=Object.defineProperty,c=(t,e,i)=>((t,e,i)=>e in t?l(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);class d{constructor(){c(this,"subs"),this.subs=[]}addSub(t){this.subs.includes(t)||this.subs.push(t)}notify(){this.subs.forEach(t=>{t.update()})}}c(d,"target");const g="__proto__"in{};function f(t,e,i,s){Object.defineProperty(t,e,{value:i,enumerable:!!s,writable:!0,configurable:!0})}const u=Array.prototype,p=Object.create(u);["push","pop","shift","unshift","sort","splice","reverse"].forEach(t=>{p[t]=function(...e){const i=u[t].apply(this,e),s=this.__luckyOb__;return["push","unshift","splice"].includes(t)&&s.walk(this),s.dep.notify(),i}});var m=Object.defineProperty,w=(t,e,i)=>((t,e,i)=>e in t?m(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);class b{constructor(t){w(this,"value"),w(this,"dep"),this.dep=new d,f(t,"__luckyOb__",this),Array.isArray(t)&&(g?t.__proto__=p:Object.getOwnPropertyNames(p).forEach(e=>{f(t,e,p[e])})),this.walk(t)}walk(t){Object.keys(t).forEach(e=>{v(t,e,t[e])})}}function y(t){if(!t||"object"!=typeof t)return;let e;return e="__luckyOb__"in t?t.__luckyOb__:new b(t),e}function v(t,e,i){const s=new d,h=Object.getOwnPropertyDescriptor(t,e);if(h&&!1===h.configurable)return;const n=h&&h.get,r=h&&h.set;n&&!r||2!==arguments.length||(i=t[e]);let a=y(i);Object.defineProperty(t,e,{get:()=>{const e=n?n.call(t):i;return d.target&&(s.addSub(d.target),a&&a.dep.addSub(d.target)),e},set:e=>{e!==i&&(i=e,n&&!r||(r?r.call(t,e):i=e,a=y(e),s.notify()))}})}var S=Object.defineProperty,C=(t,e,i)=>((t,e,i)=>e in t?S(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);let z=0;class x{constructor(t,e,i,s={}){C(this,"id"),C(this,"$lucky"),C(this,"expr"),C(this,"cb"),C(this,"deep"),C(this,"getter"),C(this,"value"),this.id=z++,this.$lucky=t,this.expr=e,this.deep=!!s.deep,this.getter="function"==typeof e?e:function(t){t+=".";let e=[],i="";for(let s=0;s<t.length;s++){let h=t[s];if(/\[|\./.test(h))e.push(i),i="";else{if(/\W/.test(h))continue;i+=h}}return function(t){return e.reduce((t,e)=>t[e],t)}}(e),this.cb=i,this.value=this.get()}get(){d.target=this;const e=this.getter.call(this.$lucky,this.$lucky);return this.deep&&function(e){const i=e=>{t(e,"array","object")&&Object.keys(e).forEach(t=>{const s=e[t];i(s)})};i(e)}(e),d.target=null,e}update(){const t=this.get(),e=this.value;this.value=t,this.cb.call(this.$lucky,t,e)}}var k=Object.defineProperty,$=(t,e,i)=>((t,e,i)=>e in t?k(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i)(t,"symbol"!=typeof e?e+"":e,i);class I{constructor(t,e){$(this,"version",o),$(this,"config"),$(this,"ctx"),$(this,"htmlFontSize",16),$(this,"rAF",function(){}),$(this,"boxWidth",0),$(this,"boxHeight",0),$(this,"data"),"string"==typeof t?t={el:t}:1===t.nodeType&&(t={el:"",divElement:t}),this.config=t,this.data=e,t.flag||(t.flag="WEB"),t.el&&(t.divElement=document.querySelector(t.el)),t.divElement&&(t.canvasElement=document.createElement("canvas"),t.divElement.appendChild(t.canvasElement)),t.canvasElement&&(t.ctx=t.canvasElement.getContext("2d"),t.canvasElement.setAttribute("package",`@vnpn/lucky-canvas-core@${o}`),t.canvasElement.addEventListener("click",t=>this.handleClick(t))),this.ctx=t.ctx,this.initWindowFunction(),this.config.ctx||console.error("无法获取到 CanvasContext2D"),window&&"function"==typeof window.addEventListener&&window.addEventListener("resize",n(()=>this.resize(),300)),window&&"function"==typeof window.MutationObserver&&new window.MutationObserver(()=>{this.resize()}).observe(document.documentElement,{attributes:!0})}resize(){var t,e;null==(e=(t=this.config).beforeResize)||e.call(t),this.setHTMLFontSize(),this.setDpr(),this.resetWidthAndHeight(),this.zoomCanvas()}initLucky(){if(this.resize(),!this.boxWidth||!this.boxHeight)return console.error("无法获取到宽度或高度")}handleClick(t){}setHTMLFontSize(){window&&window.getComputedStyle&&(this.htmlFontSize=+window.getComputedStyle(document.documentElement).fontSize.slice(0,-2))}clearCanvas(){const[t,e]=[this.boxWidth,this.boxHeight];this.ctx.clearRect(-t,-e,2*t,2*e)}setDpr(){const{config:t}=this;t.dpr||(window?window.dpr=t.dpr=window.devicePixelRatio||1:t.dpr||console.error(t,"未传入 dpr 可能会导致绘制异常"))}resetWidthAndHeight(){const{config:t,data:e}=this;let i=0,s=0;t.divElement&&(i=t.divElement.offsetWidth,s=t.divElement.offsetHeight),this.boxWidth=this.getLength(e.width||t.width)||i,this.boxHeight=this.getLength(e.height||t.height)||s,t.divElement&&(t.divElement.style.overflow="hidden",t.divElement.style.width=this.boxWidth+"px",t.divElement.style.height=this.boxHeight+"px")}zoomCanvas(){const{config:t,ctx:e}=this,{canvasElement:i,dpr:s}=t,[h,n]=[this.boxWidth*s,this.boxHeight*s];i&&(i.width=h,i.height=n,i.style.width=`${h}px`,i.style.height=`${n}px`,i.style["transform-origin"]="left top",i.style.transform=`scale(${1/s})`,e.scale(s,s))}initWindowFunction(){const{config:t}=this;if(window)return this.rAF=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)},t.setTimeout=window.setTimeout,t.setInterval=window.setInterval,t.clearTimeout=window.clearTimeout,void(t.clearInterval=window.clearInterval);if(t.rAF)this.rAF=t.rAF;else if(t.setTimeout){const e=t.setTimeout;this.rAF=t=>e(t,16.7)}else this.rAF=t=>setTimeout(t,16.7)}isWeb(){return["WEB","UNI-H5","TARO-H5"].includes(this.config.flag)}loadImg(t,e,i="$resolve"){return new Promise((s,h)=>{if(t||h(`=> '${e.src}' 不能为空或不合法`),"WEB"!==this.config.flag)return e[i]=s,void(e.$reject=h);{let i=new Image;i.crossorigin="anonymous",i.onload=()=>s(i),i.onerror=()=>h(`=> '${e.src}' 图片加载失败`),i.src=t}})}drawImage(t,e,...i){var s,h;let n;const{flag:r,dpr:a}=this.config;if(["WEB","MP-WX"].includes(r))n=e;else{if(!["UNI-H5","UNI-MP","TARO-H5","TARO-MP"].includes(r))return console.error("意料之外的 flag, 该平台尚未兼容!");n=e.path}const o=null==(h=(s=n.canvas||n).getContext)?void 0:h.call(s,"2d");if(o&&!this.isWeb()){i=i.map(t=>t*a);const e=o.getImageData(...i.slice(0,4));t.putImageData(e,...i.slice(4,6))}else{8===i.length&&(i=i.map((t,e)=>e<4?t*a:t));try{t.drawImage(n,...i)}catch(t){}}}computedWidthAndHeight(t,e,i,s){if(!e.width&&!e.height)return[t.width,t.height];if(e.width&&!e.height){let s=this.getLength(e.width,i);return[s,t.height*(s/t.width)]}if(!e.width&&e.height){let i=this.getLength(e.height,s);return[t.width*(i/t.height),i]}return[this.getLength(e.width,i),this.getLength(e.height,s)]}changeUnits(t,e=1){const{config:i}=this;return Number(t.replace(/^([-]*[0-9.]*)([a-z%]*)$/,(t,s,h)=>{const n={"%":t=>t*(e/100),px:t=>1*t,rem:t=>t*this.htmlFontSize,vw:t=>t/100*window.innerWidth}[h];if(n)return n(s);const r=i.handleCssUnit||i.unitFunc;return r?r(s,h):s}))}getLength(e,i){return t(e,"number")?e:t(e,"string")?this.changeUnits(e,i):0}getOffsetX(t,e=0){return(e-t)/2}getOffscreenCanvas(t,e){if(!this._offscreenCanvas&&(window&&window.document&&"WEB"===this.config.flag?this._offscreenCanvas=document.createElement("canvas"):this._offscreenCanvas=this.config.offscreenCanvas,!this._offscreenCanvas))return console.error("离屏 Canvas 无法渲染!");const i=this.config.dpr,s=this._offscreenCanvas;s.width=(t||300)*i,s.height=(e||150)*i;const h=s.getContext("2d");return h.clearRect(0,0,t,e),h.scale(i,i),h.dpr=i,{_offscreenCanvas:s,_ctx:h}}$set(t,e,i){t&&"object"==typeof t&&v(t,e,i)}$computed(t,e,i){Object.defineProperty(t,e,{get:()=>i.call(this)})}$watch(t,e,i={}){"object"==typeof e&&(e=(i=e).handler);const s=new x(this,t,e,i);return i.immediate&&e.call(this,s.value),function(){}}}$(I,"version",o);const O=t=>Math.PI/180*t,A=(t,e,i,s,h,n)=>{t.beginPath();let r=O(90/Math.PI/i*n),a=s+r,o=h-r;var l,c;t.arc(0,0,i,a,o,!1),t.lineTo(...(l=(s+h)/2,c=n/2/Math.abs(Math.sin((s-h)/2)),[+(Math.cos(l)*c).toFixed(8),+(Math.sin(l)*c).toFixed(8)])),t.closePath()},P=(t,...[e,i,s,h,n])=>{const r=Math.min(s,h),a=Math.PI;n>r/2&&(n=r/2),t.beginPath(),t.moveTo(e+n,i),t.lineTo(e+n,i),t.lineTo(e+s-n,i),t.arc(e+s-n,i+n,n,-a/2,0),t.lineTo(e+s,i+h-n),t.arc(e+s-n,i+h-n,n,0,a/2),t.lineTo(e+n,i+h),t.arc(e+n,i+h-n,n,a/2,a),t.lineTo(e,i+n),t.arc(e+n,i+n,n,a,-a/2),t.closePath()},L=function(t,e,i,s){return t>=s&&(t=s),i*(t/=s)*t+e},E=function(t,e,i,s){return t>=s&&(t=s),-i*(t/=s)*(t-2)+e};var T=Object.defineProperty,W=Object.getOwnPropertySymbols,F=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable,R=(t,e,i)=>e in t?T(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,D=(t,e)=>{for(var i in e||(e={}))F.call(e,i)&&R(t,i,e[i]);if(W)for(var i of W(e))_.call(e,i)&&R(t,i,e[i]);return t},H=(t,e,i)=>R(t,"symbol"!=typeof e?e+"":e,i),M=(t,e,i)=>new Promise((s,h)=>{var n=t=>{try{a(i.next(t))}catch(t){h(t)}},r=t=>{try{a(i.throw(t))}catch(t){h(t)}},a=t=>t.done?s(t.value):Promise.resolve(t.value).then(n,r);a((i=i.apply(t,e)).next())});class j extends I{constructor(t,e){var i;super(t,{width:e.width,height:e.height}),H(this,"blocks",[]),H(this,"prizes",[]),H(this,"buttons",[]),H(this,"defaultConfig",{}),H(this,"defaultStyle",{}),H(this,"_defaultConfig",{}),H(this,"_defaultStyle",{}),H(this,"startCallback"),H(this,"endCallback"),H(this,"Radius",0),H(this,"prizeRadius",0),H(this,"prizeDeg",0),H(this,"prizeAng",0),H(this,"rotateDeg",0),H(this,"maxBtnRadius",0),H(this,"startTime",0),H(this,"endTime",0),H(this,"stopDeg",0),H(this,"endDeg",0),H(this,"FPS",16.6),H(this,"step",0),H(this,"prizeFlag"),H(this,"ImageCache",new Map),this.initData(e),this.initWatch(),this.initComputed(),null==(i=t.beforeCreate)||i.call(this),this.init()}resize(){var t,e;super.resize(),this.Radius=Math.min(this.boxWidth,this.boxHeight)/2,this.ctx.translate(this.Radius,this.Radius),this.draw(),null==(e=(t=this.config).afterResize)||e.call(t)}initLucky(){this.Radius=0,this.prizeRadius=0,this.prizeDeg=0,this.prizeAng=0,this.rotateDeg=0,this.maxBtnRadius=0,this.startTime=0,this.endTime=0,this.stopDeg=0,this.endDeg=0,this.FPS=16.6,this.prizeFlag=-1,this.step=0,super.initLucky()}initData(t){this.$set(this,"width",t.width),this.$set(this,"height",t.height),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"buttons",t.buttons||[]),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",()=>D({gutter:"0px",offsetDegree:0,speed:20,speedFunction:"quad",accelerationTime:2500,decelerationTime:2500,stopRange:0},this.defaultConfig)),this.$computed(this,"_defaultStyle",()=>D({fontSize:"18px",fontColor:"#000",fontStyle:"sans-serif",fontWeight:"400",background:"rgba(0,0,0,0)",wordWrap:!0,lengthLimit:"90%"},this.defaultStyle))}initWatch(){this.$watch("width",t=>{this.data.width=t,this.resize()}),this.$watch("height",t=>{this.data.height=t,this.resize()}),this.$watch("blocks",t=>{this.initImageCache()},{deep:!0}),this.$watch("prizes",t=>{this.initImageCache()},{deep:!0}),this.$watch("buttons",t=>{this.initImageCache()},{deep:!0}),this.$watch("defaultConfig",()=>this.draw(),{deep:!0}),this.$watch("defaultStyle",()=>this.draw(),{deep:!0}),this.$watch("startCallback",()=>this.init()),this.$watch("endCallback",()=>this.init())}init(){return M(this,null,function*(){var t,e;this.initLucky();const{config:i}=this;null==(t=i.beforeInit)||t.call(this),this.draw(),this.draw(),yield this.initImageCache(),null==(e=i.afterInit)||e.call(this)})}initImageCache(){return new Promise(t=>{const e={blocks:this.blocks.map(t=>t.imgs),prizes:this.prizes.map(t=>t.imgs),buttons:this.buttons.map(t=>t.imgs)};Object.keys(e).forEach(i=>{const s=e[i],h=[];s&&s.forEach((t,e)=>{t&&t.forEach((t,s)=>{h.push(this.loadAndCacheImg(i,e,s))})}),Promise.all(h).then(()=>{this.draw(),t()})})})}handleClick(t){var e;const{ctx:i}=this;i.beginPath(),i.arc(0,0,this.maxBtnRadius,0,2*Math.PI,!1),i.isPointInPath(t.offsetX,t.offsetY)&&0===this.step&&(null==(e=this.startCallback)||e.call(this,t))}loadAndCacheImg(t,e,i){return M(this,null,function*(){return new Promise((s,h)=>{const n=this[t][e];if(!n||!n.imgs)return;const r=n.imgs[i];r&&this.loadImg(r.src,r).then(t=>M(this,null,function*(){"function"==typeof r.formatter&&(t=yield Promise.resolve(r.formatter.call(this,t))),this.ImageCache.set(r.src,t),s()})).catch(s=>{console.error(`${t}[${e}].imgs[${i}] ${s}`),h()})})})}drawBlock(t,e,i){const{ctx:h}=this;s(e.background)&&(h.beginPath(),h.fillStyle=e.background,h.arc(0,0,t,0,2*Math.PI,!1),h.fill()),e.imgs&&e.imgs.forEach((e,i)=>{const s=this.ImageCache.get(e.src);if(!s)return;const[n,r]=this.computedWidthAndHeight(s,e,2*t,2*t),[a,o]=[this.getOffsetX(n)+this.getLength(e.left,2*t),this.getLength(e.top,2*t)-t];h.save(),e.rotate&&h.rotate(O(this.rotateDeg)),this.drawImage(h,s,a,o,n,r),h.restore()})}draw(){var t,h;const{config:n,ctx:r,_defaultConfig:o,_defaultStyle:l}=this;null==(t=n.beforeDraw)||t.call(this,r),r.clearRect(-this.Radius,-this.Radius,2*this.Radius,2*this.Radius),this.prizeRadius=this.blocks.reduce((t,e,i)=>(this.drawBlock(t,e,i),t-this.getLength(e.padding&&e.padding.split(" ")[0])),this.Radius),this.prizeDeg=360/this.prizes.length,this.prizeAng=O(this.prizeDeg);const c=this.prizeRadius*Math.sin(this.prizeAng/2)*2;let d=O(this.rotateDeg-90+this.prizeDeg/2+o.offsetDegree);const g=(t,e)=>this.getOffsetX(r.measureText(e).width)+this.getLength(t.left,c),f=(t,e,i)=>{const s=t.lineHeight||l.lineHeight||t.fontSize||l.fontSize;return this.getLength(t.top,e)+(i+1)*this.getLength(s)};r.save(),this.prizes.forEach((t,h)=>{let n=d+h*this.prizeAng,u=this.prizeRadius-this.maxBtnRadius;const p=t.background||l.background;s(p)&&(r.fillStyle=p,A(r,this.maxBtnRadius,this.prizeRadius,n-this.prizeAng/2,n+this.prizeAng/2,this.getLength(o.gutter)),r.fill());let m=Math.cos(n)*this.prizeRadius,w=Math.sin(n)*this.prizeRadius;r.translate(m,w),r.rotate(n+O(90)),t.imgs&&t.imgs.forEach((t,e)=>{const i=this.ImageCache.get(t.src);if(!i)return;const[s,h]=this.computedWidthAndHeight(i,t,this.prizeAng*this.prizeRadius,u),[n,a]=[this.getOffsetX(s)+this.getLength(t.left,c),this.getLength(t.top,u)];this.drawImage(r,i,n,a,s,h)}),t.fonts&&t.fonts.forEach(t=>{const s=t.fontColor||l.fontColor,h=t.fontWeight||l.fontWeight,n=this.getLength(t.fontSize||l.fontSize),c=t.fontStyle||l.fontStyle,d=e(t,"wordWrap")?t.wordWrap:l.wordWrap,p=t.lengthLimit||l.lengthLimit,m=t.lineClamp||l.lineClamp;r.fillStyle=s,r.font=`${h} ${n|0}px ${c}`;let w=[],b=String(t.text);w=d?a(r,i(b),e=>{let i=2*((this.prizeRadius-f(t,u,e.length))*Math.tan(this.prizeAng/2))-this.getLength(o.gutter);return this.getLength(p,i)},m):b.split("\n"),w.filter(t=>!!t).forEach((e,i)=>{r.fillText(e,g(t,e),f(t,u,i))})}),r.rotate(O(360)-n-O(90)),r.translate(-m,-w)}),r.restore(),this.buttons.forEach((t,e)=>{let i=this.getLength(t.radius,this.prizeRadius);this.maxBtnRadius=Math.max(this.maxBtnRadius,i),s(t.background)&&(r.beginPath(),r.fillStyle=t.background,r.arc(0,0,i,0,2*Math.PI,!1),r.fill()),t.pointer&&s(t.background)&&(r.beginPath(),r.fillStyle=t.background,r.moveTo(-i,0),r.lineTo(i,0),r.lineTo(0,2*-i),r.closePath(),r.fill()),t.imgs&&t.imgs.forEach((t,e)=>{const s=this.ImageCache.get(t.src);if(!s)return;const[h,n]=this.computedWidthAndHeight(s,t,2*i,2*i),[a,o]=[this.getOffsetX(h)+this.getLength(t.left,i),this.getLength(t.top,i)];this.drawImage(r,s,a,o,h,n)}),t.fonts&&t.fonts.forEach(t=>{let e=t.fontColor||l.fontColor,s=t.fontWeight||l.fontWeight,h=this.getLength(t.fontSize||l.fontSize),n=t.fontStyle||l.fontStyle;r.fillStyle=e,r.font=`${s} ${h|0}px ${n}`,String(t.text).split("\n").forEach((e,s)=>{r.fillText(e,g(t,e),f(t,i,s))})})}),null==(h=n.afterDraw)||h.call(this,r)}carveOnGunwaleOfAMovingBoat(){const{_defaultConfig:t,prizeFlag:e,prizeDeg:i,rotateDeg:s}=this;this.endTime=Date.now();const h=this.stopDeg=s,n=t.speed,r=(Math.random()*i-i/2)*this.getLength(t.stopRange);let a=0,o=0,l=0;for(;++a;){const c=360*a-e*i-s-t.offsetDegree+r-i/2;let d=E(this.FPS,h,c,t.decelerationTime)-h;if(d>n){this.endDeg=n-o>d-n?c:l;break}l=c,o=d}}play(){var t,e;0===this.step&&(this.startTime=Date.now(),this.prizeFlag=void 0,this.step=1,null==(e=(t=this.config).afterStart)||e.call(t),this.run())}stop(t){if(0!==this.step&&3!==this.step){if(!t&&0!==t){const e=this.prizes.map(t=>t.range);t=r(e)}t<0?(this.step=0,this.prizeFlag=-1):(this.step=2,this.prizeFlag=t%this.prizes.length)}}run(t=0){var e;const{rAF:i,step:s,prizeFlag:h,_defaultConfig:n}=this,{accelerationTime:r,decelerationTime:a,speed:o}=n;if(0===s)return void(null==(e=this.endCallback)||e.call(this,this.prizes.find((t,e)=>e===h)||{}));if(-1===h)return;3!==s||this.endDeg||this.carveOnGunwaleOfAMovingBoat();const l=Date.now()-this.startTime,c=Date.now()-this.endTime;let d=this.rotateDeg;if(1===s||l<r){this.FPS=l/t;const e=L(l,0,o,r);e===o&&(this.step=2),d+=e%360}else 2===s?(d+=o%360,void 0!==h&&h>=0&&(this.step=3,this.stopDeg=0,this.endDeg=0)):3===s?(d=E(c,this.stopDeg,this.endDeg,a),c>=a&&(this.step=0)):this.stop(-1);this.rotateDeg=d,this.draw(),i(this.run.bind(this,t+1))}conversionAxis(t,e){const{config:i}=this;return[t/i.dpr-this.Radius,e/i.dpr-this.Radius]}}var B=Object.defineProperty,N=Object.getOwnPropertySymbols,X=Object.prototype.hasOwnProperty,G=Object.prototype.propertyIsEnumerable,U=(t,e,i)=>e in t?B(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,q=(t,e)=>{for(var i in e||(e={}))X.call(e,i)&&U(t,i,e[i]);if(N)for(var i of N(e))G.call(e,i)&&U(t,i,e[i]);return t},Y=(t,e,i)=>U(t,"symbol"!=typeof e?e+"":e,i),J=(t,e,i)=>new Promise((s,h)=>{var n=t=>{try{a(i.next(t))}catch(t){h(t)}},r=t=>{try{a(i.throw(t))}catch(t){h(t)}},a=t=>t.done?s(t.value):Promise.resolve(t.value).then(n,r);a((i=i.apply(t,e)).next())});class K extends I{constructor(t,e){var i;super(t,{width:e.width,height:e.height}),Y(this,"rows",3),Y(this,"cols",3),Y(this,"blocks",[]),Y(this,"prizes",[]),Y(this,"buttons",[]),Y(this,"button"),Y(this,"defaultConfig",{}),Y(this,"defaultStyle",{}),Y(this,"activeStyle",{}),Y(this,"_defaultConfig",{}),Y(this,"_defaultStyle",{}),Y(this,"_activeStyle",{}),Y(this,"startCallback"),Y(this,"endCallback"),Y(this,"cellWidth",0),Y(this,"cellHeight",0),Y(this,"startTime",0),Y(this,"endTime",0),Y(this,"currIndex",0),Y(this,"stopIndex",0),Y(this,"endIndex",0),Y(this,"demo",!1),Y(this,"timer",0),Y(this,"FPS",16.6),Y(this,"step",0),Y(this,"prizeFlag",-1),Y(this,"cells",[]),Y(this,"prizeArea"),Y(this,"ImageCache",new Map),this.initData(e),this.initWatch(),this.initComputed(),null==(i=t.beforeCreate)||i.call(this),this.init()}resize(){var t,e;super.resize(),this.draw(),null==(e=(t=this.config).afterResize)||e.call(t)}initLucky(){this.cellWidth=0,this.cellHeight=0,this.startTime=0,this.endTime=0,this.currIndex=0,this.stopIndex=0,this.endIndex=0,this.demo=!1,this.timer=0,this.FPS=16.6,this.prizeFlag=-1,this.step=0,super.initLucky()}initData(t){this.$set(this,"width",t.width),this.$set(this,"height",t.height),this.$set(this,"rows",Number(t.rows)||3),this.$set(this,"cols",Number(t.cols)||3),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"buttons",t.buttons||[]),this.$set(this,"button",t.button),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"activeStyle",t.activeStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",()=>{const t=q({gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultConfig);return t.gutter=this.getLength(t.gutter),t.speed=t.speed/40,t}),this.$computed(this,"_defaultStyle",()=>q({borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"sans-serif",fontWeight:"400",background:"rgba(0,0,0,0)",shadow:"",wordWrap:!0,lengthLimit:"90%"},this.defaultStyle)),this.$computed(this,"_activeStyle",()=>q({background:"#ffce98",shadow:""},this.activeStyle))}initWatch(){this.$watch("width",t=>{this.data.width=t,this.resize()}),this.$watch("height",t=>{this.data.height=t,this.resize()}),this.$watch("blocks",t=>{this.initImageCache()},{deep:!0}),this.$watch("prizes",t=>{this.initImageCache()},{deep:!0}),this.$watch("buttons",t=>{this.initImageCache()},{deep:!0}),this.$watch("rows",()=>this.init()),this.$watch("cols",()=>this.init()),this.$watch("defaultConfig",()=>this.draw(),{deep:!0}),this.$watch("defaultStyle",()=>this.draw(),{deep:!0}),this.$watch("activeStyle",()=>this.draw(),{deep:!0}),this.$watch("startCallback",()=>this.init()),this.$watch("endCallback",()=>this.init())}init(){return J(this,null,function*(){var t,e;this.initLucky();const{config:i}=this;null==(t=i.beforeInit)||t.call(this),this.draw(),yield this.initImageCache(),null==(e=i.afterInit)||e.call(this)})}initImageCache(){return new Promise(t=>{const e=this.buttons.map(t=>t.imgs);this.button&&e.push(this.button.imgs);const i={blocks:this.blocks.map(t=>t.imgs),prizes:this.prizes.map(t=>t.imgs),buttons:e};Object.keys(i).forEach(e=>{const s=i[e],h=[];s&&s.forEach((t,i)=>{t&&t.forEach((t,s)=>{h.push(this.loadAndCacheImg(e,i,s))})}),Promise.all(h).then(()=>{this.draw(),t()})})})}handleClick(t){const{ctx:e}=this;[...this.buttons,this.button].forEach(i=>{var s;if(!i)return;const[h,n,r,a]=this.getGeometricProperty([i.x,i.y,i.col||1,i.row||1]);e.beginPath(),e.rect(h,n,r,a),e.isPointInPath(t.offsetX,t.offsetY)&&0===this.step&&("function"==typeof i.callback&&i.callback.call(this,i),null==(s=this.startCallback)||s.call(this,t,i))})}loadAndCacheImg(t,e,i){return J(this,null,function*(){return new Promise((s,h)=>{let n=this[t][e];if("buttons"===t&&!this.buttons.length&&this.button&&(n=this.button),!n||!n.imgs)return;const r=n.imgs[i];if(!r)return;const a=[this.loadImg(r.src,r),r.activeSrc&&this.loadImg(r.activeSrc,r,"$activeResolve")];Promise.all(a).then(t=>J(this,[t],function*([t,e]){const i=r.formatter;"function"==typeof i&&(t=yield Promise.resolve(i.call(this,t)),e&&(e=yield Promise.resolve(i.call(this,e)))),this.ImageCache.set(r.src,t),e&&this.ImageCache.set(r.activeSrc,e),s()})).catch(s=>{console.error(`${t}[${e}].imgs[${i}] ${s}`),h()})})})}draw(){var t,n;const{config:r,ctx:o,_defaultConfig:l,_defaultStyle:c,_activeStyle:d}=this;null==(t=r.beforeDraw)||t.call(this,o),o.clearRect(0,0,this.boxWidth,this.boxHeight),this.cells=[...this.prizes,...this.buttons],this.button&&this.cells.push(this.button),this.cells.forEach(t=>{t.col=t.col||1,t.row=t.row||1}),this.prizeArea=this.blocks.reduce(({x:t,y:e,w:i,h:n},r,a)=>{const[l,c,d,g]=h(r,this.getLength.bind(this)),f=r.borderRadius?this.getLength(r.borderRadius):0,u=r.background;return s(u)&&(o.fillStyle=this.handleBackground(t,e,i,n,u),P(o,t,e,i,n,f),o.fill()),r.imgs&&r.imgs.forEach((s,h)=>{const r=this.ImageCache.get(s.src);if(!r)return;const[a,l]=this.computedWidthAndHeight(r,s,i,n),[c,d]=[this.getOffsetX(a,i)+this.getLength(s.left,i),this.getLength(s.top,n)];this.drawImage(o,r,t+c,e+d,a,l)}),{x:t+d,y:e+l,w:i-d-g,h:n-l-c}},{x:0,y:0,w:this.boxWidth,h:this.boxHeight}),this.cellWidth=(this.prizeArea.w-l.gutter*(this.cols-1))/this.cols,this.cellHeight=(this.prizeArea.h-l.gutter*(this.rows-1))/this.rows,this.cells.forEach((t,h)=>{let[n,l,g,f]=this.getGeometricProperty([t.x,t.y,t.col,t.row]),u=!1;(void 0===this.prizeFlag||this.prizeFlag>-1)&&(u=h===(this.currIndex%this.prizes.length|0));const p=u?d.background:t.background||c.background;if(s(p)){const e=(u?d.shadow:t.shadow||c.shadow).replace(/px/g,"").split(",")[0].split(" ").map((t,e)=>e<3?Number(t):t);4===e.length&&(o.shadowColor=e[3],o.shadowOffsetX=e[0]*r.dpr,o.shadowOffsetY=e[1]*r.dpr,o.shadowBlur=e[2],e[0]>0?g-=e[0]:(g+=e[0],n-=e[0]),e[1]>0?f-=e[1]:(f+=e[1],l-=e[1])),o.fillStyle=this.handleBackground(n,l,g,f,p);const i=this.getLength(t.borderRadius?t.borderRadius:c.borderRadius);P(o,n,l,g,f,i),o.fill(),o.shadowColor="rgba(0, 0, 0, 0)",o.shadowOffsetX=0,o.shadowOffsetY=0,o.shadowBlur=0}h>=this.prizes.length&&(h-=this.prizes.length),t.imgs&&t.imgs.forEach((t,e)=>{const i=this.ImageCache.get(t.src),s=this.ImageCache.get(t.activeSrc);if(!i)return;const h=u&&s||i;if(!h)return;const[r,a]=this.computedWidthAndHeight(h,t,g,f),[c,d]=[n+this.getOffsetX(r,g)+this.getLength(t.left,g),l+this.getLength(t.top,f)];this.drawImage(o,h,c,d,r,a)}),t.fonts&&t.fonts.forEach(t=>{const s=u&&d.fontStyle?d.fontStyle:t.fontStyle||c.fontStyle,h=u&&d.fontWeight?d.fontWeight:t.fontWeight||c.fontWeight,r=u&&d.fontSize?this.getLength(d.fontSize):this.getLength(t.fontSize||c.fontSize),p=u&&d.lineHeight?d.lineHeight:t.lineHeight||c.lineHeight||t.fontSize||c.fontSize,m=e(t,"wordWrap")?t.wordWrap:c.wordWrap,w=t.lengthLimit||c.lengthLimit,b=t.lineClamp||c.lineClamp;o.font=`${h} ${r|0}px ${s}`,o.fillStyle=u&&d.fontColor?d.fontColor:t.fontColor||c.fontColor;let y=[],v=String(t.text);if(m){let t=this.getLength(w,g);y=a(o,i(v),()=>t,b)}else y=v.split("\n");y.forEach((e,i)=>{o.fillText(e,n+this.getOffsetX(o.measureText(e).width,g)+this.getLength(t.left,g),l+this.getLength(t.top,f)+(i+1)*this.getLength(p))})})}),null==(n=r.afterDraw)||n.call(this,o)}handleBackground(t,e,i,s,h){const{ctx:n}=this;return h.includes("linear-gradient")&&(h=((t,e,i,s,h,n)=>{const r=/linear-gradient\((.+)\)/.exec(n)[1].split(",").map(t=>t.trim());let a=r.shift(),o=[0,0,0,0];if(a.includes("deg")){a=a.slice(0,-3)%360;const t=t=>Math.tan(t/180*Math.PI);a>=0&&a<45?o=[e,i+h,e+s,i+h-s*t(a-0)]:a>=45&&a<90?o=[e,i+h,e+s-h*t(a-45),i]:a>=90&&a<135?o=[e+s,i+h,e+s-h*t(a-90),i]:a>=135&&a<180?o=[e+s,i+h,e,i+s*t(a-135)]:a>=180&&a<225?o=[e+s,i,e,i+s*t(a-180)]:a>=225&&a<270?o=[e+s,i,e+h*t(a-225),i+h]:a>=270&&a<315?o=[e,i,e+h*t(a-270),i+h]:a>=315&&a<360&&(o=[e,i,e+s,i+h-s*t(a-315)])}else a.includes("top")?o=[e,i+h,e,i]:a.includes("bottom")?o=[e,i,e,i+h]:a.includes("left")?o=[e+s,i,e,i]:a.includes("right")&&(o=[e,i,e+s,i]);const l=t.createLinearGradient(...o.map(t=>0|t));return r.reduce((t,e,i)=>{const s=e.split(" ");return 1===s.length?t.addColorStop(i,s[0]):2===s.length&&t.addColorStop(...s),t},l)})(n,t,e,i,s,h)),h}carveOnGunwaleOfAMovingBoat(){const{_defaultConfig:t,prizeFlag:e,currIndex:i}=this;this.endTime=Date.now();const s=this.stopIndex=i,h=t.speed;let n=0,r=0,a=0;for(;++n;){const i=this.prizes.length*n+e-s,o=E(this.FPS,s,i,t.decelerationTime)-s;if(o>h){this.endIndex=h-r>o-h?i:a;break}a=i,r=o}}play(){var t,e;0===this.step&&(this.startTime=Date.now(),this.prizeFlag=void 0,this.step=1,null==(e=(t=this.config).afterStart)||e.call(t),this.run())}stop(t){if(0!==this.step&&3!==this.step){if(!t&&0!==t){const e=this.prizes.map(t=>t.range);t=r(e)}t<0?(this.step=0,this.prizeFlag=-1):(this.step=2,this.prizeFlag=t%this.prizes.length)}}run(t=0){var e;const{rAF:i,step:s,prizes:h,prizeFlag:n,_defaultConfig:r}=this,{accelerationTime:a,decelerationTime:o,speed:l}=r;if(0===s)return void(null==(e=this.endCallback)||e.call(this,this.prizes.find((t,e)=>e===n)||{}));if(-1===n)return;3!==s||this.endIndex||this.carveOnGunwaleOfAMovingBoat();const c=Date.now()-this.startTime,d=Date.now()-this.endTime;let g=this.currIndex;if(1===s||c<a){this.FPS=c/t;const e=L(c,.1,l-.1,a);e===l&&(this.step=2),g+=e%h.length}else 2===s?(g+=l%h.length,void 0!==n&&n>=0&&(this.step=3,this.stopIndex=0,this.endIndex=0)):3===s?(g=E(d,this.stopIndex,this.endIndex,o),d>=o&&(this.step=0)):this.stop(-1);this.currIndex=g,this.draw(),i(this.run.bind(this,t+1))}getGeometricProperty([t,e,i=1,s=1]){const{cellWidth:h,cellHeight:n}=this,r=this._defaultConfig.gutter;let a=[this.prizeArea.x+(h+r)*t,this.prizeArea.y+(n+r)*e];return i&&s&&a.push(h*i+r*(i-1),n*s+r*(s-1)),a}conversionAxis(t,e){const{config:i}=this;return[t/i.dpr,e/i.dpr]}}var Q=Object.defineProperty,V=Object.getOwnPropertySymbols,Z=Object.prototype.hasOwnProperty,tt=Object.prototype.propertyIsEnumerable,et=(t,e,i)=>e in t?Q(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,it=(t,e)=>{for(var i in e||(e={}))Z.call(e,i)&&et(t,i,e[i]);if(V)for(var i of V(e))tt.call(e,i)&&et(t,i,e[i]);return t},st=(t,e,i)=>et(t,"symbol"!=typeof e?e+"":e,i),ht=(t,e,i)=>new Promise((s,h)=>{var n=t=>{try{a(i.next(t))}catch(t){h(t)}},r=t=>{try{a(i.throw(t))}catch(t){h(t)}},a=t=>t.done?s(t.value):Promise.resolve(t.value).then(n,r);a((i=i.apply(t,e)).next())});class nt extends I{constructor(t,e){var i;super(t,{width:e.width,height:e.height}),st(this,"blocks",[]),st(this,"prizes",[]),st(this,"slots",[]),st(this,"defaultConfig",{}),st(this,"_defaultConfig",{}),st(this,"defaultStyle",{}),st(this,"_defaultStyle",{}),st(this,"endCallback",()=>{}),st(this,"_offscreenCanvas"),st(this,"cellWidth",0),st(this,"cellHeight",0),st(this,"cellAndSpacing",0),st(this,"widthAndSpacing",0),st(this,"heightAndSpacing",0),st(this,"FPS",16.6),st(this,"scroll",[]),st(this,"stopScroll",[]),st(this,"endScroll",[]),st(this,"startTime",0),st(this,"endTime",[]),st(this,"slotStep",[]),st(this,"defaultOrder",[]),st(this,"step",0),st(this,"prizeFlag"),st(this,"prizeArea"),st(this,"ImageCache",new Map),this.initData(e),this.initWatch(),this.initComputed(),null==(i=t.beforeCreate)||i.call(this),this.init()}resize(){var t,e;super.resize(),this.redrawOffscreenCanvas(),null==(e=(t=this.config).afterResize)||e.call(t)}initLucky(){this.cellWidth=0,this.cellHeight=0,this.cellAndSpacing=0,this.widthAndSpacing=0,this.heightAndSpacing=0,this.FPS=16.6,this.scroll=[],this.stopScroll=[],this.endScroll=[],this.startTime=0,this.endTime=[],this.slotStep=[],this.prizeFlag=void 0,this.step=0,super.initLucky()}initData(t){this.$set(this,"width",t.width),this.$set(this,"height",t.height),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"slots",t.slots||[]),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",()=>{const t=it({mode:"vertical",rowSpacing:0,colSpacing:5,speed:20,direction:1,accelerationTime:2500,decelerationTime:2500},this.defaultConfig);return t.rowSpacing=this.getLength(t.rowSpacing),t.colSpacing=this.getLength(t.colSpacing),t}),this.$computed(this,"_defaultStyle",()=>it({borderRadius:0,fontColor:"#000",fontSize:"18px",fontStyle:"sans-serif",fontWeight:"400",background:"rgba(0,0,0,0)",wordWrap:!0,lengthLimit:"90%"},this.defaultStyle))}initWatch(){this.$watch("width",t=>{this.data.width=t,this.resize()}),this.$watch("height",t=>{this.data.height=t,this.resize()}),this.$watch("blocks",t=>{this.initImageCache()},{deep:!0}),this.$watch("prizes",t=>{this.initImageCache()},{deep:!0}),this.$watch("slots",t=>{this.redrawOffscreenCanvas()},{deep:!0}),this.$watch("defaultConfig",()=>this.redrawOffscreenCanvas(),{deep:!0}),this.$watch("defaultStyle",()=>this.redrawOffscreenCanvas(),{deep:!0}),this.$watch("endCallback",()=>this.init())}init(){return ht(this,null,function*(){var t,e;this.initLucky();const{config:i}=this;null==(t=i.beforeInit)||t.call(this),this.drawOffscreenCanvas(),this.draw(),yield this.initImageCache(),null==(e=i.afterInit)||e.call(this)})}redrawOffscreenCanvas(){this.drawOffscreenCanvas(),this.draw()}initImageCache(){return new Promise(t=>{const e={blocks:this.blocks.map(t=>t.imgs),prizes:this.prizes.map(t=>t.imgs)};Object.keys(e).forEach(i=>{const s=e[i],h=[];s&&s.forEach((t,e)=>{t&&t.forEach((t,s)=>{h.push(this.loadAndCacheImg(i,e,s))})}),Promise.all(h).then(()=>{this.drawOffscreenCanvas(),this.draw(),t()})})})}loadAndCacheImg(t,e,i){return ht(this,null,function*(){return new Promise((s,h)=>{let n=this[t][e];if(!n||!n.imgs)return;const r=n.imgs[i];r&&this.loadImg(r.src,r).then(t=>ht(this,null,function*(){"function"==typeof r.formatter&&(t=yield Promise.resolve(r.formatter.call(this,t))),this.ImageCache.set(r.src,t),s()})).catch(s=>{console.error(`${t}[${e}].imgs[${i}] ${s}`),h()})})})}drawOffscreenCanvas(){const{_defaultConfig:t,_defaultStyle:h}=this,{w:n,h:r}=this.drawBlocks(),o=this.prizes.length,{cellWidth:l,cellHeight:c,widthAndSpacing:d,heightAndSpacing:g}=this.displacementWidthOrHeight();this.defaultOrder=new Array(o).fill(void 0).map((t,e)=>e);let f=0,u=0;this.slots.forEach((t,e)=>{void 0===this.scroll[e]&&(this.scroll[e]=0);const i=(t.order||this.defaultOrder).length;f=Math.max(f,n+d*i),u=Math.max(u,r+g*i)});const{_offscreenCanvas:p,_ctx:m}=this.getOffscreenCanvas(f,u);this._offscreenCanvas=p,this.slots.forEach((n,r)=>{const o=l*r,f=c*r;let w=0;const b=((t,e)=>{const i={},s=[];for(let e=0;e<t.length;e++)i[e]=t[e];for(let t=0;t<e.length;t++){const h=i[e[t]];h&&(s[t]=h)}return s})(this.prizes,n.order||this.defaultOrder);if(!b.length)return;b.forEach((n,r)=>{if(!n)return;const u=d*r+t.colSpacing/2,p=g*r+t.rowSpacing/2,[b,y,v]=this.displacement([o,p,g],[u,f,d]);w+=v;const S=n.background||h.background;if(s(S)){const t=this.getLength(e(n,"borderRadius")?n.borderRadius:h.borderRadius);P(m,b,y,l,l,t),m.fillStyle=S,m.fill()}n.imgs&&n.imgs.forEach((t,e)=>{const i=this.ImageCache.get(t.src);if(!i)return;const[s,h]=this.computedWidthAndHeight(i,t,l,c),[n,r]=[b+this.getOffsetX(s,l)+this.getLength(t.left,l),y+this.getLength(t.top,c)];this.drawImage(m,i,n,r,s,h)}),n.fonts&&n.fonts.forEach(t=>{const s=t.fontStyle||h.fontStyle,n=t.fontWeight||h.fontWeight,r=this.getLength(t.fontSize||h.fontSize),o=t.lineHeight||h.lineHeight||t.fontSize||h.fontSize,d=e(t,"wordWrap")?t.wordWrap:h.wordWrap,g=t.lengthLimit||h.lengthLimit,f=t.lineClamp||h.lineClamp;m.font=`${n} ${r|0}px ${s}`,m.fillStyle=t.fontColor||h.fontColor;let u=[],p=String(t.text);if(d){let t=this.getLength(g,l);u=a(m,i(p),()=>t,f)}else u=p.split("\n");u.forEach((e,i)=>{m.fillText(e,b+this.getOffsetX(m.measureText(e).width,l)+this.getLength(t.left,l),y+this.getLength(t.top,c)+(i+1)*this.getLength(o))})})});const[y,v,S,C]=this.displacement([o,0,l,w],[0,f,w,c]);let z=w;for(;z<u+w;){const[t,e]=this.displacement([y,z],[z,v]);this.drawImage(m,p,y,v,S,C,t,e,S,C),z+=w}})}drawBlocks(){const{config:t,ctx:e,_defaultConfig:i,_defaultStyle:n}=this;return this.prizeArea=this.blocks.reduce(({x:t,y:i,w:r,h:a},o,l)=>{const[c,d,g,f]=h(o,this.getLength.bind(this)),u=o.borderRadius?this.getLength(o.borderRadius):0,p=o.background||n.background;return s(p)&&(P(e,t,i,r,a,u),e.fillStyle=p,e.fill()),o.imgs&&o.imgs.forEach((s,h)=>{const n=this.ImageCache.get(s.src);if(!n)return;const[o,l]=this.computedWidthAndHeight(n,s,r,a),[c,d]=[this.getOffsetX(o,r)+this.getLength(s.left,r),this.getLength(s.top,a)];this.drawImage(e,n,t+c,i+d,o,l)}),{x:t+g,y:i+c,w:r-g-f,h:a-c-d}},{x:0,y:0,w:this.boxWidth,h:this.boxHeight})}draw(){var t;const{config:e,ctx:i,_defaultConfig:s,_defaultStyle:h}=this;null==(t=e.beforeDraw)||t.call(this,i),i.clearRect(0,0,this.boxWidth,this.boxHeight);const{x:n,y:r,w:a,h:o}=this.drawBlocks();if(!this._offscreenCanvas)return;const{cellWidth:l,cellHeight:c,cellAndSpacing:d,widthAndSpacing:g,heightAndSpacing:f}=this;this.slots.forEach((t,e)=>{const s=t.order||this.defaultOrder,h=d*s.length,u=this.displacement(-(o-f)/2,-(a-g)/2);let p=this.scroll[e]+u;p<0&&(p=p%h+h),p>h&&(p%=h);const[m,w,b,y]=this.displacement([l*e,p,l,o],[p,c*e,a,c]),[v,S,C,z]=this.displacement([n+g*e,r,l,o],[n,r+f*e,a,c]);this.drawImage(i,this._offscreenCanvas,m,w,b,y,v,S,C,z)})}carveOnGunwaleOfAMovingBoat(t){const{_defaultConfig:e,prizeFlag:i,cellAndSpacing:s}=this,h=this.slots[t],n=h.order||this.defaultOrder;if(!n.length||void 0===i)return;const r=Math.abs(h.speed||e.speed),a=h.direction||e.direction,o=n.findIndex(e=>e===i[t]),l=s*n.length,c=this.stopScroll[t]=this.scroll[t];this.endTime[t]=Date.now();let d=0;for(;++d;){const i=s*o+l*d*a-c,h=E(this.FPS,c,i,e.decelerationTime)-c;if(Math.abs(h)>r){this.endScroll[t]=i;break}}}hasAllPrizeFlag(){var t;return!!(null==(t=this.prizeFlag)?void 0:t.length)&&this.prizeFlag.every(t=>void 0!==t)}isAllSlotStopped(){return this.slots.every((t,e)=>!(t.order||this.defaultOrder).length||0===this.slotStep[e])}getEndPrize(){if(!this.hasAllPrizeFlag())return;const t=this.prizeFlag;let e=t[0];for(let i=0;i<this.slots.length;i++){const s=this.slots[i],h=t[i],n=s.order||this.defaultOrder;if(!(null==n?void 0:n.includes(h))||e!==h){e=-1;break}}return this.prizes.find((t,i)=>i===e)||void 0}play(){var t,e;0===this.step&&(this.startTime=Date.now(),this.prizeFlag=void 0,this.stopScroll=[],this.endScroll=[],this.endTime=[],this.slotStep=this.slots.map(t=>(t.order||this.defaultOrder).length?1:0),this.step=1,null==(e=(t=this.config).afterStart)||e.call(t),this.run())}stop(e,i){var s;if(0!==this.step){if("number"==typeof i){if(!Number.isInteger(i)||i<0||i>=this.slots.length)return console.error(`stop(${e}, ${i}) slotIndex 超出范围`);if("number"!=typeof e)return console.error(`stop(${JSON.stringify(e)}, ${i}) 参数类型不正确`);void 0!==this.prizeFlag&&this.prizeFlag.length||(this.prizeFlag=new Array(this.slots.length).fill(void 0)),this.prizeFlag[i]=e}else if("number"==typeof e)this.prizeFlag=new Array(this.slots.length).fill(e);else{if(!t(e,"array"))return this.stop(-1),console.error("stop() 无法识别的参数类型 "+typeof e);if(e.length!==this.slots.length)return this.stop(-1),console.error(`stop([${e}]) 参数长度的不正确`);this.prizeFlag=e}(null==(s=this.prizeFlag)?void 0:s.includes(-1))?(this.prizeFlag=[],this.slotStep=this.slotStep.map(()=>0),this.step=0):this.step=2}}run(t=0){var e,i;const{rAF:s,_defaultConfig:h,cellAndSpacing:n,slots:r}=this,{accelerationTime:a,decelerationTime:o}=h,l=this.prizeFlag;if(0===this.step)return void(this.hasAllPrizeFlag()&&this.isAllSlotStopped()&&(null==(e=this.endCallback)||e.call(this,this.getEndPrize())));if(void 0!==l&&!l.length)return;const c=Date.now()-this.startTime;if(c>=a&&1===this.step&&(this.step=2),r.forEach((e,i)=>{const s=e.order||this.defaultOrder;if(!s||!s.length)return;const r=n*s.length,d=Math.abs(e.speed||h.speed),g=e.direction||h.direction,f=this.slotStep[i]||0;let u=0,p=this.scroll[i];if(f){if(1===f||c<a){this.FPS=c/t;const e=L(c,0,d,a);e===d&&(this.slotStep[i]=2),u=(p+e*g)%r}else if(2===f)u=(p+d*g)%r,void 0!==(null==l?void 0:l[i])&&(this.slotStep[i]=3,this.scroll[i]=u,this.carveOnGunwaleOfAMovingBoat(i));else if(3===f){const t=this.stopScroll[i],e=this.endScroll[i],s=Date.now()-this.endTime[i];u=E(s,t,e,o),s>=o&&(u=t+e,this.slotStep[i]=0)}this.scroll[i]=u}}),this.draw(),this.isAllSlotStopped())return this.step=0,void(this.hasAllPrizeFlag()&&(null==(i=this.endCallback)||i.call(this,this.getEndPrize())));s(this.run.bind(this,t+1))}displacement(t,e){return"horizontal"===this._defaultConfig.mode?e:t}displacementWidthOrHeight(){const t=this._defaultConfig.mode,e=this.slots.length,{colSpacing:i,rowSpacing:s}=this._defaultConfig,{x:h,y:n,w:r,h:a}=this.prizeArea||this.drawBlocks();let o=0,l=0,c=0,d=0;return"horizontal"===t?(l=this.cellHeight=(a-s*(e-1))/e,o=this.cellWidth=l):(o=this.cellWidth=(r-i*(e-1))/e,l=this.cellHeight=o),c=this.widthAndSpacing=this.cellWidth+i,d=this.heightAndSpacing=this.cellHeight+s,this.cellAndSpacing="horizontal"===t?c:d,{cellWidth:o,cellHeight:l,widthAndSpacing:c,heightAndSpacing:d}}}const rt=(t,e)=>{const i=document.createElement("canvas"),s=i.getContext("2d"),{width:h,height:n}=t;return i.width=h,i.height=n,P(s,0,0,h,n,e),s.clip(),s.drawImage(t,0,0,h,n),i},at=(t,e)=>{const i=document.createElement("canvas"),s=i.getContext("2d"),{width:h,height:n}=t;if(i.width=h,i.height=n,"string"==typeof s.filter)s.filter=`opacity(${100*e}%)`,s.drawImage(t,0,0,h,n);else{s.drawImage(t,0,0,h,n);const i=s.getImageData(0,0,h,n),{data:r}=i,a=r.length;for(let t=0;t<a;t+=4){const i=r[t+3];0!==i&&(r[t+3]=i*e)}s.putImageData(i,0,0)}return i};export{K as LuckyGrid,j as LuckyWheel,nt as SlotMachine,rt as cutRound,at as opacity};
2
+ //# sourceMappingURL=index.esm.js.map