UNPKG

fun-tab

Version:

A mobile touch-swappable tabs component for Vue3

1 lines 35 kB
{"version":3,"file":"index.full.min.cjs","sources":["../../../src/types.ts","../../../build/plugin-vue:export-helper","../../../src/tab-bar.vue","../../../src/tab-item.vue","../../../src/utils/requestAnimationFrame.ts","../../../src/tabs.vue","../../../src/index.ts"],"sourcesContent":["import type { Ref, InjectionKey } from 'vue';\n\ntype name = string | number | undefined;\n\nexport interface TabItemInstance {\n\tname: Ref<name>;\n\tel: Ref<HTMLElement>;\n}\n\nexport interface TabsInjection {\n\tactiveValue: Ref<string | number>;\n\tactiveColor: Ref<string>;\n\taddItem(tabItem: TabItemInstance): void;\n\tremoveItem(tabItem: TabItemInstance): void;\n\tsetActiveValue(name: name): void;\n}\n\nexport interface TabBarInjection {\n\tactiveValue: Ref<string | number>;\n\tactiveColor: Ref<string>;\n\tsetActiveValue(name: name): void;\n}\n\nexport const tabsInjectionKey: InjectionKey<TabsInjection | TabBarInjection> = Symbol();\n","\nexport default (sfc, props) => {\n const target = sfc.__vccOpts || sfc;\n for (const [key, val] of props) {\n target[key] = val;\n }\n return target;\n}\n","<template>\n\t<div class=\"fun-tab-bar\">\n\t\t<div class=\"fun-tab-bar-wrap\">\n\t\t\t<slot />\n\t\t</div>\n\t</div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, toRef, watch, provide } from 'vue';\nimport { tabsInjectionKey } from './types';\n\nexport default defineComponent({\n\tname: 'FunTabBar',\n\tprops: {\n\t\tmodelValue: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\t\tactiveColor: {\n\t\t\ttype: String,\n\t\t\tdefault: '#1677ff',\n\t\t},\n\t},\n\temits: ['update:modelValue', 'change'],\n\tsetup(props, { emit }) {\n\t\tconst activeValue = ref(props.modelValue);\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t(v) => {\n\t\t\t\tactiveValue.value = v;\n\t\t\t}\n\t\t);\n\n\t\t/**\n\t\t * 设置激活值,供 FunTabItem 实例调用\n\t\t * @param {*} value\n\t\t */\n\t\tconst setActiveValue = (value: typeof props.modelValue): void => {\n\t\t\tactiveValue.value = value;\n\t\t\temit('update:modelValue', value);\n\t\t\temit('change', value);\n\t\t};\n\n\t\tprovide(tabsInjectionKey, {\n\t\t\tactiveValue,\n\t\t\tactiveColor: toRef(props, 'activeColor'),\n\t\t\tsetActiveValue,\n\t\t});\n\t},\n});\n</script>\n\n<style>\n.fun-tab-bar-wrap {\n\tdisplay: flex;\n\tflex-wrap: nowrap;\n\talign-items: stretch;\n\tmin-height: 50px;\n\tbackground: #fff;\n}\n.fun-tab-bar .fun-tab-item {\n\tflex: 1 1;\n\tfont-size: 12px;\n}\n.fun-tab-bar .fun-tab-item__badge {\n\ttop: 2px;\n\tright: 0;\n}\n</style>\n","<template>\n\t<div ref=\"el\" :style=\"style\" class=\"fun-tab-item\" @click=\"handleClick\">\n\t\t<div class=\"fun-tab-item__wrap\">\n\t\t\t<slot name=\"icon\" />\n\t\t\t<div class=\"fun-tab-item__label\">\n\t\t\t\t<slot>{{ title }}</slot>\n\t\t\t</div>\n\t\t\t<div v-if=\"badge\" class=\"fun-tab-item__badge\">\n\t\t\t\t{{ badge }}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, computed, inject, onMounted, onUnmounted, toRef } from 'vue';\nimport { TabsInjection, tabsInjectionKey, TabItemInstance } from './types';\n\nexport default defineComponent({\n\tname: 'FunTabItem',\n\tprops: {\n\t\ttitle: String,\n\t\tname: [String, Number],\n\t\tbadge: [String, Number],\n\t},\n\tsetup(props) {\n\t\tconst parent = inject(tabsInjectionKey);\n\n\t\tconst el = ref();\n\t\tconst style = computed(() => {\n\t\t\treturn parent?.activeValue.value === props.name\n\t\t\t\t? {\n\t\t\t\t\t\tcolor: parent?.activeColor.value,\n\t\t\t\t }\n\t\t\t\t: {};\n\t\t});\n\t\tconst handleClick = () => {\n\t\t\tparent?.setActiveValue(props.name);\n\t\t};\n\n\t\tconst instance: TabItemInstance = {\n\t\t\tname: toRef(props, 'name'),\n\t\t\tel,\n\t\t};\n\n\t\tonMounted(() => {\n\t\t\t(parent as TabsInjection).addItem?.(instance);\n\t\t});\n\t\tonUnmounted(() => {\n\t\t\t(parent as TabsInjection).removeItem?.(instance);\n\t\t});\n\n\t\treturn {\n\t\t\tel,\n\t\t\tstyle,\n\t\t\thandleClick,\n\t\t};\n\t},\n});\n</script>\n\n<style>\n.fun-tab-item {\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n}\n.fun-tab-item__wrap {\n\tposition: relative;\n}\n.fun-tab-item__badge {\n\tposition: absolute;\n\ttop: 4px;\n\tright: -10px;\n\tpadding: 0 4px;\n\tmin-width: 8px;\n\theight: 14px;\n\tfont-size: 9px;\n\tline-height: 14px;\n\tcolor: #fff;\n\tbackground: #ff411c;\n\twhite-space: nowrap;\n\tborder-radius: 100px;\n\ttransform: translate(50%, -50%);\n\ttext-align: center;\n}\n</style>\n","interface IndexableWindow {\n\t/* eslint-disable @typescript-eslint/no-explicit-any */\n\t[key: string]: any;\n}\nconst win = window as IndexableWindow;\n\nexport function windowInit() {\n\tlet lastTime = 0;\n\tconst vendors = ['webkit', 'moz'];\n\tfor (let x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {\n\t\twindow.requestAnimationFrame = win[vendors[x] + 'RequestAnimationFrame'];\n\t\twindow.cancelAnimationFrame =\n\t\t\twin[vendors[x] + 'CancelAnimationFrame'] || // name has changed in Webkit\n\t\t\twin[vendors[x] + 'CancelRequestAnimationFrame'];\n\t}\n\n\tif (!window.requestAnimationFrame) {\n\t\twindow.requestAnimationFrame = function (callback) {\n\t\t\tconst currTime = Date.now();\n\t\t\t// 刷新间隔16.7ms(每秒60次刷新)\n\t\t\tconst interval = currTime - lastTime;\n\t\t\tconst timeToCall = Math.max(0, 16.7 - interval);\n\t\t\tconst id = window.setTimeout(function () {\n\t\t\t\tcallback(interval);\n\t\t\t}, timeToCall);\n\t\t\tlastTime = currTime + timeToCall;\n\t\t\treturn id;\n\t\t};\n\t}\n\tif (!window.cancelAnimationFrame) {\n\t\twindow.cancelAnimationFrame = function (id) {\n\t\t\tclearTimeout(id);\n\t\t};\n\t}\n}\n","<template>\n\t<div ref=\"viewAreaRef\" class=\"fun-tabs\">\n\t\t<div ref=\"listRef\" :style=\"listStyle\" class=\"fun-tabs__tab-list\">\n\t\t\t<slot />\n\t\t\t<div :style=\"activeBarStyle\" class=\"fun-tabs__active-line\" />\n\t\t</div>\n\t</div>\n</template>\n\n<script lang=\"ts\">\nimport {\n\tdefineComponent,\n\tprovide,\n\tref,\n\tcomputed,\n\twatch,\n\ttoRef,\n\tonMounted,\n\tonBeforeUnmount,\n\tnextTick,\n\tPropType,\n\tRef,\n} from 'vue';\nimport { TabsInjection, tabsInjectionKey, TabItemInstance } from './types';\nimport { windowInit } from './utils/requestAnimationFrame';\n\nexport default defineComponent({\n\tname: 'FunTabs',\n\tprops: {\n\t\tmodelValue: {\n\t\t\ttype: [String, Number] as PropType<string | number>,\n\t\t\tdefault: '',\n\t\t},\n\t\tlineWidth: {\n\t\t\ttype: [Number, String] as PropType<number | string>,\n\t\t\tdefault: 30,\n\t\t},\n\t\tlineHeight: {\n\t\t\ttype: Number,\n\t\t\tdefault: 3,\n\t\t},\n\t\tactiveColor: {\n\t\t\ttype: String,\n\t\t\tdefault: '#1677ff',\n\t\t},\n\t\t// 近似等于超出边界时最大可拖动距离(px);\n\t\tadditionalX: {\n\t\t\ttype: Number,\n\t\t\tdefault: 50,\n\t\t},\n\t\t// 惯性回弹指数(值越大,幅度越大,惯性回弹距离越长);\n\t\treBoundExponent: {\n\t\t\ttype: Number,\n\t\t\tdefault: 10,\n\t\t\tvalidator(v: number) {\n\t\t\t\treturn v > 0;\n\t\t\t},\n\t\t},\n\t\t// 惯性滑动过程的持续时间,值越小,感知上阻力越大,可近似认为惯性滑动过程速度减为零所需的时间(ms);\n\t\tinertialDuration: {\n\t\t\ttype: Number,\n\t\t\tdefault: 1000,\n\t\t\tvalidator(v: number) {\n\t\t\t\treturn v > 0;\n\t\t\t},\n\t\t},\n\t\t// 回弹过程duration\n\t\treBoundingDuration: {\n\t\t\ttype: Number,\n\t\t\tdefault: 360,\n\t\t},\n\t} as const,\n\temits: ['update:modelValue', 'change'],\n\n\tsetup(props, { emit, expose }) {\n\t\tlet refreshTask: Promise<void> | null = null;\n\t\tconst children: TabItemInstance[] = [];\n\n\t\t// refs\n\t\tconst viewAreaRef = ref<HTMLElement>() as Ref<HTMLElement>;\n\t\tconst listRef = ref<HTMLElement>() as Ref<HTMLElement>;\n\t\tconst activeValue = ref(props.modelValue);\n\t\tconst lineOffset = ref(0);\n\t\tconst activeLineWidth = ref(0);\n\t\t// 可视区宽度;\n\t\tconst viewAreaWidth = ref(0);\n\t\t// 可视区与可滑动元素宽度差值;\n\t\tconst offsetX = ref(0);\n\t\t// 滑动速度(正常滑动时一般不会超过10);\n\t\tconst speed = ref(0);\n\t\t// 是否处于touch状态;\n\t\tconst touching = ref(false);\n\t\t// 是否处于回弹过程;\n\t\tconst reBounding = ref(false);\n\t\tconst translateX = ref(0);\n\t\tconst startX = ref(0);\n\t\tconst lastX = ref(0);\n\t\tconst currentX = ref(0);\n\t\tconst startMoveTime = ref(0);\n\t\tconst endMoveTime = ref(0);\n\t\t// 每个动画帧的ms数\n\t\tconst frameTime = ref(16.7);\n\t\tconst frameStartTime = ref(0);\n\t\tconst frameEndTime = ref(0);\n\t\tconst inertiaFrame = ref(0);\n\t\t// 当speed绝对值小于该值时认为速度为0 (可用于控制惯性滚动结束期的顺滑度)\n\t\tconst zeroSpeed = ref(0.001);\n\t\t// 惯性滑动加速度;\n\t\tconst acceleration = ref(0.001);\n\n\t\tconst listStyle = computed(() => {\n\t\t\tconst duration = reBounding.value && !touching.value ? props.reBoundingDuration : 0;\n\n\t\t\treturn {\n\t\t\t\ttransitionTimingFunction: reBounding.value\n\t\t\t\t\t? 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'\n\t\t\t\t\t: 'cubic-bezier(0.1, 0.57, 0.1, 1)',\n\t\t\t\ttransitionDuration: `${duration}ms`,\n\t\t\t\ttransform: `translate3d(${translateX.value}px, 0px, 0px)`,\n\t\t\t};\n\t\t});\n\n\t\tconst activeBarStyle = computed(() => {\n\t\t\treturn {\n\t\t\t\ttransition: `all 300ms`,\n\t\t\t\twidth: `${activeLineWidth.value}px`,\n\t\t\t\theight: `${props.lineHeight}px`,\n\t\t\t\ttransform: `translate3d(${lineOffset.value}px, 0, 0)`,\n\t\t\t\tbackgroundColor: props.activeColor,\n\t\t\t};\n\t\t});\n\t\t// 是否向左惯性滚动;\n\t\tconst isMoveLeft = computed(() => currentX.value <= startX.value);\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t(v) => {\n\t\t\t\tactiveValue.value = v;\n\t\t\t\trefreshState();\n\t\t\t}\n\t\t);\n\n\t\tconst refreshState = () => {\n\t\t\tif (refreshTask) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// 避免在单次事件循环中重复执行多次计算逻辑,造成不必要的性能浪费\n\t\t\trefreshTask = new Promise((resolve) => {\n\t\t\t\tnextTick(() => {\n\t\t\t\t\tresize();\n\t\t\t\t\tresolve();\n\t\t\t\t\trefreshTask = null;\n\t\t\t\t});\n\t\t\t});\n\t\t};\n\n\t\t/**\n\t\t * 设置激活值,供 FunTabItem 实例调用\n\t\t * @param {*} value\n\t\t */\n\t\tconst setActiveValue = (value: typeof props.modelValue): void => {\n\t\t\tactiveValue.value = value;\n\t\t\temit('update:modelValue', value);\n\t\t\temit('change', value);\n\t\t};\n\n\t\t/**\n\t\t * 供 FunTabItem 实例调用,用于注册 tab item\n\t\t */\n\t\tconst addItem = (tabItem: TabItemInstance): void => {\n\t\t\tchildren.push(tabItem);\n\t\t\trefreshState();\n\t\t};\n\t\t/**\n\t\t * 供 FunTabItem 实例调用,用于移除 tab item\n\t\t */\n\t\tconst removeItem = (tabItem: TabItemInstance): void => {\n\t\t\tconst index = children.findIndex((item) => item.name === tabItem.name);\n\t\t\tif (index === -1) return;\n\n\t\t\tchildren.splice(index, 1);\n\t\t\trefreshState();\n\t\t};\n\n\t\tconst injection: TabsInjection = {\n\t\t\tactiveValue,\n\t\t\tactiveColor: toRef(props, 'activeColor'),\n\t\t\taddItem,\n\t\t\tremoveItem,\n\t\t\tsetActiveValue,\n\t\t};\n\n\t\tprovide(tabsInjectionKey, injection);\n\n\t\t/**\n\t\t * will be exposed\n\t\t */\n\t\tconst resize = () => {\n\t\t\t// 重新计算可视区宽度\n\t\t\tviewAreaWidth.value = viewAreaRef.value.offsetWidth;\n\t\t\toffsetX.value = listRef.value.offsetWidth - viewAreaWidth.value;\n\t\t\tcheckPosition();\n\t\t\tcalcLineOffset();\n\t\t};\n\n\t\t/**\n\t\t * 如果需要回弹则进行回弹操作,并返回true;\n\t\t */\n\t\tconst reboundIfNeeded = () => {\n\t\t\treBounding.value = false;\n\t\t\tif (translateX.value > 0) {\n\t\t\t\treBounding.value = true;\n\t\t\t\ttranslateX.value = 0;\n\t\t\t} else if (translateX.value < -offsetX.value) {\n\t\t\t\treBounding.value = true;\n\t\t\t\ttranslateX.value = -offsetX.value;\n\t\t\t}\n\t\t\treturn reBounding.value;\n\t\t};\n\n\t\t/**\n\t\t * touch拖动\n\t\t */\n\t\tconst moveFollowTouch = () => {\n\t\t\t// 向左拖动\n\t\t\tif (isMoveLeft.value) {\n\t\t\t\tif (\n\t\t\t\t\t(translateX.value <= 0 && translateX.value + offsetX.value > 0) ||\n\t\t\t\t\ttranslateX.value > 0\n\t\t\t\t) {\n\t\t\t\t\ttranslateX.value += currentX.value - lastX.value;\n\t\t\t\t} else if (translateX.value + offsetX.value <= 0) {\n\t\t\t\t\ttranslateX.value +=\n\t\t\t\t\t\t(props.additionalX * (currentX.value - lastX.value)) /\n\t\t\t\t\t\t(viewAreaWidth.value + Math.abs(translateX.value + offsetX.value));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// 向右拖动\n\t\t\t\tif (translateX.value >= 0) {\n\t\t\t\t\ttranslateX.value +=\n\t\t\t\t\t\t(props.additionalX * (currentX.value - lastX.value)) /\n\t\t\t\t\t\t(viewAreaWidth.value + translateX.value);\n\t\t\t\t} else if (\n\t\t\t\t\t(translateX.value <= 0 && translateX.value + offsetX.value >= 0) ||\n\t\t\t\t\ttranslateX.value + offsetX.value <= 0\n\t\t\t\t) {\n\t\t\t\t\ttranslateX.value += currentX.value - lastX.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastX.value = currentX.value;\n\t\t};\n\n\t\t/**\n\t\t * 惯性滑动\n\t\t */\n\t\tconst moveByInertia = () => {\n\t\t\tframeEndTime.value = Date.now();\n\t\t\tframeTime.value = frameEndTime.value - frameStartTime.value;\n\n\t\t\t// 向左惯性滑动;\n\t\t\tif (isMoveLeft.value) {\n\t\t\t\t// 超出边界的阶段;\n\t\t\t\tif (translateX.value <= -offsetX.value) {\n\t\t\t\t\t// 加速度指数变化;\n\t\t\t\t\tacceleration.value *=\n\t\t\t\t\t\t(props.reBoundExponent + Math.abs(translateX.value + offsetX.value)) /\n\t\t\t\t\t\tprops.reBoundExponent;\n\t\t\t\t\t// 为避免减速过程过短,此处加速度没有乘上frameTime;\n\t\t\t\t\tspeed.value = Math.min(speed.value - acceleration.value, 0);\n\t\t\t\t} else {\n\t\t\t\t\tspeed.value = Math.min(speed.value - acceleration.value * frameTime.value, 0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// 向右惯性滑动;\n\t\t\t\tif (translateX.value >= 0) {\n\t\t\t\t\tacceleration.value *= (props.reBoundExponent + translateX.value) / props.reBoundExponent;\n\t\t\t\t\tspeed.value = Math.max(speed.value - acceleration.value, 0);\n\t\t\t\t} else {\n\t\t\t\t\tspeed.value = Math.max(speed.value - acceleration.value * frameTime.value, 0);\n\t\t\t\t}\n\t\t\t}\n\t\t\ttranslateX.value += (speed.value * frameTime.value) / 2;\n\t\t\tif (Math.abs(speed.value) <= zeroSpeed.value) {\n\t\t\t\treboundIfNeeded();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tframeStartTime.value = frameEndTime.value;\n\t\t\tinertiaFrame.value = requestAnimationFrame(moveByInertia);\n\t\t};\n\n\t\t/**\n\t\t * 获取当前激活 item 的 dom 元素 $el\n\t\t */\n\t\tconst getActiveItemEl = () => {\n\t\t\tif (!children.length) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst target = children.find((child) => child.name.value === activeValue.value);\n\t\t\treturn target && target.el.value;\n\t\t};\n\n\t\t/**\n\t\t * 计算activeBar的translateX\n\t\t */\n\t\tconst calcLineOffset = () => {\n\t\t\tconst itemEl = getActiveItemEl();\n\t\t\tif (!itemEl) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst itemWidth = itemEl.offsetWidth;\n\t\t\tconst itemLeft = itemEl.offsetLeft;\n\t\t\tconst { lineWidth } = props;\n\n\t\t\tif (lineWidth === 'auto') {\n\t\t\t\t// 等于当前激活item元素的宽度\n\t\t\t\tactiveLineWidth.value = itemWidth;\n\t\t\t} else if (lineWidth < 1) {\n\t\t\t\t// 0~1表示占当前激活item元素宽度的比例\n\t\t\t\tactiveLineWidth.value = itemWidth * (lineWidth as number);\n\t\t\t} else {\n\t\t\t\tactiveLineWidth.value = lineWidth as number;\n\t\t\t}\n\n\t\t\tlineOffset.value = itemLeft + (itemWidth - activeLineWidth.value) / 2;\n\t\t};\n\n\t\t/**\n\t\t * 点击切换item时,调整位置使当前item尽可能往中间显示\n\t\t */\n\t\tconst checkPosition = () => {\n\t\t\tconst activeItemEl = getActiveItemEl();\n\t\t\tif (!activeItemEl) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst offsetLeft = activeItemEl.offsetLeft;\n\t\t\t// 让 activeItem 展示在正中间时,其距视图左右边距为 half\n\t\t\tconst half = (viewAreaWidth.value - activeItemEl.offsetWidth) / 2;\n\t\t\t// 在当前的translateX基础上需要调整的距离\n\t\t\tlet changeX = 0;\n\t\t\tconst absTransX = Math.abs(translateX.value);\n\n\t\t\t// item偏左,需要往右移(往中间靠)\n\t\t\tif (offsetLeft <= absTransX + half) {\n\t\t\t\t// 这种情况下translateX.value是负数\n\t\t\t\tchangeX = half - (offsetLeft + translateX.value);\n\t\t\t} else {\n\t\t\t\t// item偏右,需要往左移\n\t\t\t\tchangeX = -(offsetLeft - absTransX - half);\n\t\t\t}\n\t\t\tlet targetX = changeX + translateX.value;\n\t\t\t// 左边界\n\t\t\tif (targetX > 0) {\n\t\t\t\ttargetX = 0;\n\t\t\t}\n\t\t\t// 右边界\n\t\t\tif (targetX < -offsetX.value) {\n\t\t\t\ttargetX = -offsetX.value;\n\t\t\t}\n\t\t\treBounding.value = true;\n\t\t\ttranslateX.value = targetX;\n\t\t};\n\n\t\t/**\n\t\t * touchstart\n\t\t */\n\t\tconst handleTouchStart = (event: TouchEvent) => {\n\t\t\tevent.stopPropagation();\n\t\t\tcancelAnimationFrame(inertiaFrame.value);\n\t\t\tlastX.value = event.touches[0].clientX;\n\t\t};\n\n\t\t/**\n\t\t * touchmove\n\t\t */\n\t\tconst handleTouchMove = (event: TouchEvent) => {\n\t\t\tif (offsetX.value <= 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\ttouching.value = true;\n\t\t\tstartMoveTime.value = endMoveTime.value;\n\t\t\tstartX.value = lastX.value;\n\t\t\tcurrentX.value = event.touches[0].clientX;\n\t\t\tmoveFollowTouch();\n\t\t\t// 此次touchmove事件触发的时间戳;\n\t\t\tendMoveTime.value = event.timeStamp;\n\t\t};\n\n\t\t/**\n\t\t * touchend\n\t\t * @param {*} event\n\t\t */\n\t\tconst handleTouchEnd = (event: TouchEvent) => {\n\t\t\ttouching.value = false;\n\t\t\tif (reboundIfNeeded()) {\n\t\t\t\tcancelAnimationFrame(inertiaFrame.value);\n\t\t\t} else {\n\t\t\t\tlet silenceTime = event.timeStamp - endMoveTime.value;\n\t\t\t\tlet timeStamp = endMoveTime.value - startMoveTime.value;\n\t\t\t\ttimeStamp = timeStamp > 0 ? timeStamp : 8;\n\n\t\t\t\t// 停顿时间超过100ms不产生惯性滑动;\n\t\t\t\tif (silenceTime > 100) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tspeed.value = (lastX.value - startX.value) / timeStamp;\n\t\t\t\tacceleration.value = speed.value / props.inertialDuration;\n\t\t\t\tframeStartTime.value = Date.now();\n\t\t\t\tinertiaFrame.value = requestAnimationFrame(moveByInertia);\n\t\t\t}\n\t\t};\n\n\t\tconst bindEvents = () => {\n\t\t\tconst el = viewAreaRef.value;\n\t\t\tel.addEventListener('touchstart', handleTouchStart, false);\n\t\t\tel.addEventListener('touchmove', handleTouchMove, false);\n\t\t\tel.addEventListener('touchend', handleTouchEnd, false);\n\t\t};\n\n\t\tconst removeEvents = () => {\n\t\t\tconst el = viewAreaRef.value;\n\t\t\tel.removeEventListener('touchstart', handleTouchStart);\n\t\t\tel.removeEventListener('touchmove', handleTouchMove);\n\t\t\tel.removeEventListener('touchend', handleTouchEnd);\n\t\t};\n\n\t\tonMounted(() => {\n\t\t\twindowInit();\n\t\t\tbindEvents();\n\t\t\trefreshState();\n\t\t});\n\n\t\tonBeforeUnmount(() => {\n\t\t\tremoveEvents();\n\t\t});\n\n\t\texpose({\n\t\t\tresize,\n\t\t});\n\n\t\treturn {\n\t\t\t// refs\n\t\t\tviewAreaRef,\n\t\t\tlistRef,\n\n\t\t\t// data\n\t\t\tactiveValue,\n\t\t\tlineOffset,\n\t\t\tactiveLineWidth,\n\t\t\tviewAreaWidth,\n\t\t\toffsetX,\n\t\t\tspeed,\n\t\t\ttouching,\n\t\t\treBounding,\n\t\t\ttranslateX,\n\t\t\tstartX,\n\t\t\tlastX,\n\t\t\tcurrentX,\n\t\t\tstartMoveTime,\n\t\t\tendMoveTime,\n\t\t\tframeTime,\n\t\t\tframeStartTime,\n\t\t\tframeEndTime,\n\t\t\tinertiaFrame,\n\t\t\tzeroSpeed,\n\t\t\tacceleration,\n\n\t\t\t// computed\n\t\t\tlistStyle,\n\t\t\tactiveBarStyle,\n\t\t\tisMoveLeft,\n\t\t};\n\t},\n});\n</script>\n\n<style>\n.fun-tabs {\n\toverflow: hidden;\n\tposition: relative;\n\twidth: 100%;\n\tborder-bottom: 1px solid #eee;\n\tbackground: #fff;\n}\n\n.fun-tabs__tab-list {\n\tposition: relative;\n\tdisplay: flex;\n\tflex-wrap: nowrap;\n\tmin-width: 100%;\n\twidth: min-content;\n}\n\n.fun-tabs__active-line {\n\tposition: absolute;\n\tbottom: 3px;\n\tleft: 0;\n\twidth: 30px;\n\theight: 3px;\n\tborder-radius: 4px;\n}\n\n.fun-tabs .fun-tab-item {\n\tpadding: 10px 12px;\n\tflex: 1 1 auto;\n\tfont-size: 14px;\n\ttext-align: center;\n\twhite-space: nowrap;\n}\n</style>\n","import type { App } from 'vue';\n\nimport FunTabBar from './tab-bar.vue';\nimport FunTabItem from './tab-item.vue';\nimport FunTabs from './tabs.vue';\n\nconst install = (app: App) => {\n\tapp.component(FunTabs.name, FunTabs);\n\tapp.component(FunTabItem.name, FunTabItem);\n\tapp.component(FunTabBar.name, FunTabBar);\n};\n\nexport default { install };\n\nexport { FunTabs, FunTabBar, FunTabItem };\n"],"names":["l","n","s","d","i","c","V","p","_","f","u","h","k","g","b","v","m","N","S","C","E","le","A","ue","se","oe","ne","re","ie","ce","ve","me","he","H","q","de"],"mappings":";;;;;;AAAO,MAAM,gBAAgB,CAAC,MAAM,EAAE;;ACCtC,SAAe,CAAC,GAAG,EAAE,KAAK,KAAK;AAC/B,EAAE,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC;AACtC,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,KAAK,EAAE;AAClC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACtB,GAAG;AACH,EAAE,OAAO,MAAM,CAAC;AAChB;;ACEA,MAAA,CAAA,CAAAA,mBAAA,CAAA,CAAA,IAAA,CAAA,WAAA,CAAA,KAAA,CAAA,CAAA,UAAA,CAAA,CAAA,IAAA,CAAA,CAAA,MAAA,CAAA,MAAA,CAAA,CAAA,OAAA,CAAA,EAAA,CAAA,CAAA,WAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,mBAAA,CAAA,QAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAAC,OAAA,CAAA,CAAA,CAAA,UAAA,CAAA,CAAAC,SAAA,CAAA,IAAA,CAAA,CAAA,UAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,EAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,mBAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,QAAA,CAAA,CAAA,EAAA,CAAA,CAAAC,WAAA,CAAAC,gBAAA,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,WAAA,CAAAC,SAAA,CAAA,CAAA,CAAA,aAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,KAAA,CAAA,aAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,kBAAA,CAAA,CAAA,SAAAC,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,OAAAC,aAAA,EAAA,CAAAC,sBAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAAC,sBAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAAC,cAAA,CAAA,CAAA,CAAA,MAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,UAAAC,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,QAAA,CAAAL,GAAA,CAAA,CAAA,CAAA,QAAA,CAAA,aAAA,CAAA,CAAA,CAAA;;ACMA,MAAA,CAAA,CAAAI,mBAAA,CAAA,CAAA,IAAA,CAAA,YAAA,CAAA,KAAA,CAAA,CAAA,KAAA,CAAA,MAAA,CAAA,IAAA,CAAA,CAAA,MAAA,CAAA,MAAA,CAAA,CAAA,KAAA,CAAA,CAAA,MAAA,CAAA,MAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAAH,UAAA,CAAAK,gBAAA,CAAA,CAAA,CAAA,CAAAH,OAAA,EAAA,CAAA,CAAA,CAAAD,YAAA,CAAA,IAAA,CAAA,EAAA,WAAA,CAAA,KAAA,GAAA,CAAA,CAAA,IAAA,CAAA,CAAA,KAAA,CAAA,CAAA,EAAA,WAAA,CAAA,KAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,EAAA,cAAA,CAAA,CAAA,CAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAAK,SAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,OAAAC,aAAA,CAAA,IAAA,CAAA,CAAA,CAAA,OAAA,GAAA,CAAA,EAAA,CAAA,CAAA,CAAAC,eAAA,CAAA,IAAA,CAAA,CAAA,CAAA,UAAA,GAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,KAAA,CAAA,oBAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,qBAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,qBAAA,CAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,OAAAC,aAAA,EAAA,CAAAX,sBAAA,CAAA,KAAA,CAAA,CAAA,GAAA,CAAA,IAAA,CAAA,KAAA,CAAAY,kBAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,KAAA,CAAA,cAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,CAAA,CAAA,WAAA,EAAA,CAAA,CAAA,WAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAb,sBAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAAJ,cAAA,CAAA,CAAA,CAAA,MAAA,CAAA,MAAA,CAAA,CAAAI,sBAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAAJ,cAAA,CAAA,CAAA,CAAA,MAAA,CAAA,SAAA,CAAA,EAAA,CAAA,IAAA,CAAAkB,mBAAA,CAAAhB,mBAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAAc,aAAA,EAAA,CAAAX,sBAAA,CAAA,KAAA,CAAA,CAAA,CAAAH,mBAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,EAAAiB,sBAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,QAAAC,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,CAAA,QAAA,CAAA,cAAA,CAAA,CAAA,CAAA;;ACfA,MAAM,CAAC,CAAC,MAAM,CAAQ,SAAS,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,MAAM,CAAC,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAC,CAAC,EAAC;;ACU5iB,MAAA,EAAA,CAAAC,mBAAA,CAAA,CAAA,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,CAAA,UAAA,CAAA,CAAA,IAAA,CAAA,CAAA,MAAA,CAAA,MAAA,CAAA,CAAA,OAAA,CAAA,EAAA,CAAA,CAAA,SAAA,CAAA,CAAA,IAAA,CAAA,CAAA,MAAA,CAAA,MAAA,CAAA,CAAA,OAAA,CAAA,EAAA,CAAA,CAAA,UAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,WAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,SAAA,CAAA,CAAA,WAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,EAAA,CAAA,CAAA,eAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,EAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,gBAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,GAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,kBAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,mBAAA,CAAA,QAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAArB,OAAA,EAAA,CAAA,CAAA,CAAAA,OAAA,EAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,UAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAAA,OAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAAsB,YAAA,CAAA,IAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,kBAAA,CAAA,CAAA,CAAA,OAAA,CAAA,wBAAA,CAAA,CAAA,CAAA,KAAA,CAAA,sCAAA,CAAA,iCAAA,CAAA,kBAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,SAAA,CAAA,CAAA,YAAA,EAAA,CAAA,CAAA,KAAA,CAAA,aAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,YAAA,CAAA,KAAA,CAAA,UAAA,CAAA,WAAA,CAAA,KAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,EAAA,CAAA,CAAA,MAAA,CAAA,CAAA,EAAA,CAAA,CAAA,UAAA,CAAA,EAAA,CAAA,CAAA,SAAA,CAAA,CAAA,YAAA,EAAA,CAAA,CAAA,KAAA,CAAA,SAAA,CAAA,CAAA,eAAA,CAAA,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAAA,YAAA,CAAA,IAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAAC,SAAA,CAAA,IAAA,CAAA,CAAA,UAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,IAAA,CAAA,CAAA,GAAA,CAAA,CAAA,IAAA,OAAA,CAAA,CAAA,EAAA,CAAAC,YAAA,CAAA,IAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,mBAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,QAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,SAAA,CAAA,CAAA,EAAA,CAAA,CAAA,IAAA,GAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,GAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,WAAA,CAAAC,SAAA,CAAA,CAAA,CAAA,aAAA,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,UAAA,CAAA,CAAA,CAAA,cAAA,CAAA,CAAA,CAAA,CAAAC,WAAA,CAAAC,gBAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,WAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,WAAA,CAAA,CAAA,CAAA,KAAA,CAAA,EAAA,EAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,KAAA,GAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,GAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,WAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,WAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,IAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,KAAA,CAAA,IAAA,CAAA,GAAA,EAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,eAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,EAAA,CAAA,CAAA,eAAA,CAAA,CAAA,CAAA,KAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,EAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,eAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,eAAA,CAAA,CAAA,CAAA,KAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA,C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"}