diff --git a/.eslintrc.js b/.eslintrc.js index dd29e4f6a2a..e0cd82c0807 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -35,7 +35,7 @@ module.exports = { // Packages targeting DOM { files: [ - 'packages/{uni-api,uni-app,uni-components,uni-core,uni-h5,uni-h5-vue,uni-i18n,uni-shared,uni-vue,uni-app-plus}/**', + 'packages/{uni-api,uni-app,uni-components,uni-core,uni-h5,uni-h5-vue,uni-i18n,uni-shared,uni-vue,uni-app-plus,uni-mp-weibo}/**', ], rules: { 'no-restricted-globals': ['error', ...NodeGlobals], diff --git a/package.json b/package.json index afcaa803499..20c3089c349 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "postinstall": "simple-git-hooks", "e2e:ssr:dev": "cd packages/playground/ssr && npm run dev:ssr", "e2e:ssr:open": "cd packages/playground/ssr && npx cypress open", - "release": "node scripts/release.js" + "release": "node scripts/release.js", + "build:weibo": "npm run build:h5 && node scripts/build.js uni-mp-weibo uni-mp-weibo-vite" }, "types": "test-dts/index.d.ts", "tsd": { diff --git a/packages/shims-uni-app.d.ts b/packages/shims-uni-app.d.ts index d5ec2c017be..b7e91ad1832 100644 --- a/packages/shims-uni-app.d.ts +++ b/packages/shims-uni-app.d.ts @@ -197,6 +197,7 @@ declare namespace UniNamespace { 'mp-kuaishou'?: PagesJsonPageStyle 'mp-lark'?: PagesJsonPageStyle 'mp-jd'?: PagesJsonPageStyle + 'mp-weibo'?: PagesJsonPageStyle 'mp-xhs'?: PagesJsonPageStyle 'quickapp-webview'?: PagesJsonPageStyle 'quickapp-webview-huawei'?: PagesJsonPageStyle diff --git a/packages/uni-api/src/helpers/api/index.ts b/packages/uni-api/src/helpers/api/index.ts index a0dd5489cc9..fb8b8da05b1 100644 --- a/packages/uni-api/src/helpers/api/index.ts +++ b/packages/uni-api/src/helpers/api/index.ts @@ -172,6 +172,16 @@ function wrapperSyncApi( options?: ApiOptions ) { return (...args: any[]) => { + try { + // @ts-ignore + if (window.weibo && window.weibo[name]) { + // @ts-ignore + window.currentWeiboApiName = name + // @ts-ignore + var value = window.weibo[name](args) + return value + } + } catch (e2) {} const errMsg = beforeInvokeApi(name, args, protocol, options) if (errMsg) { throw new Error(errMsg) diff --git a/packages/uni-api/src/helpers/api/promise.ts b/packages/uni-api/src/helpers/api/promise.ts index 5ca58f918b3..a23a065bc88 100644 --- a/packages/uni-api/src/helpers/api/promise.ts +++ b/packages/uni-api/src/helpers/api/promise.ts @@ -28,6 +28,18 @@ export function handlePromise(promise: Promise) { export function promisify(name: string, fn: Function) { return (args = {}, ...rest: unknown[]) => { + try { + // @ts-ignore + if (__PLATFORM__ === 'mp-weibo' && window.weibo && window.weibo[name]) { + // @ts-ignore + window.currentWeiboApiName = name + // @ts-ignore + const value = window.weibo[name](args) + if (name !== 'switchTab') { + return value + } + } + } catch (e) {} if (hasCallback(args)) { return wrapperReturnValue(name, invokeApi(name, fn, args, rest)) } diff --git a/packages/uni-api/src/service/base/upx2px.ts b/packages/uni-api/src/service/base/upx2px.ts index f5ff8a8caae..3f740e95f64 100644 --- a/packages/uni-api/src/service/base/upx2px.ts +++ b/packages/uni-api/src/service/base/upx2px.ts @@ -44,7 +44,11 @@ export const upx2px = defineSyncApi( } if (deviceWidth === 0) { checkDeviceWidth() - if (__PLATFORM__ === 'app' || __PLATFORM__ === 'h5') { + if ( + __PLATFORM__ === 'app' || + __PLATFORM__ === 'h5' || + __PLATFORM__ === 'mp-weibo' + ) { checkMaxWidth() } } @@ -54,7 +58,11 @@ export const upx2px = defineSyncApi( return 0 } let width = newDeviceWidth || deviceWidth - if (__PLATFORM__ === 'app' || __PLATFORM__ === 'h5') { + if ( + __PLATFORM__ === 'app' || + __PLATFORM__ === 'h5' || + __PLATFORM__ === 'mp-weibo' + ) { width = number === includeWidth || width <= maxWidth ? width : baseWidth } let result = (number / BASE_DEVICE_WIDTH) * width diff --git a/packages/uni-api/src/service/context/canvas.ts b/packages/uni-api/src/service/context/canvas.ts index 3877aff584a..c15a7a1dfc1 100644 --- a/packages/uni-api/src/service/context/canvas.ts +++ b/packages/uni-api/src/service/context/canvas.ts @@ -442,7 +442,7 @@ export class CanvasContext implements UniApp.CanvasContext { measureText(text: string) { const font = this.state.font let width = 0 - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { width = measureText(text, font) } else { const webview = plus.webview diff --git a/packages/uni-api/src/service/lifecycle/app.ts b/packages/uni-api/src/service/lifecycle/app.ts index d899d0135b0..c97d5087d3a 100644 --- a/packages/uni-api/src/service/lifecycle/app.ts +++ b/packages/uni-api/src/service/lifecycle/app.ts @@ -75,26 +75,62 @@ export function offPageNotFound(hook: UniApp.OnPageNotFoundCallback) { } export function onError(hook: UniApp.OnAppErrorCallback) { + // @ts-ignore + if (window.weibo) { + // @ts-ignore + window.weibo.onError(hook) + return + } onAppHook(ON_ERROR, hook) } export function offError(hook: UniApp.OnAppErrorCallback) { + // @ts-ignore + if (window.weibo) { + // @ts-ignore + window.weibo.offError(hook) + return + } offAppHook(ON_ERROR, hook) } export function onAppShow(hook: AppShowHook) { + // @ts-ignore + if (window.weibo) { + // @ts-ignore + window.weibo.onAppShow(hook) + return + } onAppHook(ON_SHOW, hook) } export function offAppShow(hook: AppShowHook) { + // @ts-ignore + if (window.weibo) { + // @ts-ignore + window.weibo.offAppShow(hook) + return + } offAppHook(ON_SHOW, hook) } export function onAppHide(hook: AppHideHook) { + // @ts-ignore + if (window.weibo) { + // @ts-ignore + window.weibo.onAppHide(hook) + return + } onAppHook(ON_HIDE, hook) } export function offAppHide(hook: AppHideHook) { + // @ts-ignore + if (window.weibo) { + // @ts-ignore + window.weibo.offAppHide(hook) + return + } offAppHook(ON_HIDE, hook) } diff --git a/packages/uni-api/src/service/ui/locale.ts b/packages/uni-api/src/service/ui/locale.ts index 027f946f3f0..4172d80f2ef 100644 --- a/packages/uni-api/src/service/ui/locale.ts +++ b/packages/uni-api/src/service/ui/locale.ts @@ -44,7 +44,7 @@ export const setLocale = defineSyncApi( }) weex.requireModule('plus').setLanguage(locale) } - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { navigator.cookieEnabled && window.localStorage && (localStorage[UNI_STORAGE_LOCALE] = locale) diff --git a/packages/uni-automator/package.json b/packages/uni-automator/package.json index 948e2e53475..ef8c114adb8 100644 --- a/packages/uni-automator/package.json +++ b/packages/uni-automator/package.json @@ -22,7 +22,8 @@ "apply": [ "app", "h5", - "mp-weixin" + "mp-weixin", + "mp-weibo" ], "uvue": true }, diff --git a/packages/uni-cli-shared/src/constants.ts b/packages/uni-cli-shared/src/constants.ts index 524eb12b2ae..fd00dfd9e72 100644 --- a/packages/uni-cli-shared/src/constants.ts +++ b/packages/uni-cli-shared/src/constants.ts @@ -42,6 +42,10 @@ export const H5_API_STYLE_PATH = '@dcloudio/uni-h5/style/api/' export const H5_FRAMEWORK_STYLE_PATH = '@dcloudio/uni-h5/style/framework/' export const H5_COMPONENTS_STYLE_PATH = '@dcloudio/uni-h5/style/' export const BASE_COMPONENTS_STYLE_PATH = '@dcloudio/uni-components/style/' +export const MP_WEIBO_API_STYLE_PATH = '@dcloudio/uni-mp-weibo/style/api/' +export const MP_WEIBO_FRAMEWORK_STYLE_PATH = + '@dcloudio/uni-mp-weibo/style/framework/' +export const MP_WEIBO_COMPONENTS_STYLE_PATH = '@dcloudio/uni-mp-weibo/style/' export const COMMON_EXCLUDE = [ /\/pages\.json\.js$/, diff --git a/packages/uni-cli-shared/src/deps.ts b/packages/uni-cli-shared/src/deps.ts index ba4f0d83cf2..b300eec6f33 100644 --- a/packages/uni-cli-shared/src/deps.ts +++ b/packages/uni-cli-shared/src/deps.ts @@ -1,7 +1,9 @@ import { BASE_COMPONENTS_STYLE_PATH, H5_COMPONENTS_STYLE_PATH, + MP_WEIBO_COMPONENTS_STYLE_PATH, H5_API_STYLE_PATH, + MP_WEIBO_API_STYLE_PATH, } from './constants' const RESIZE_SENSOR_CSS = BASE_COMPONENTS_STYLE_PATH + 'resize-sensor.css' @@ -41,3 +43,23 @@ export const COMPONENT_DEPS_CSS = { `${BASE_COMPONENTS_STYLE_PATH}picker-view-column.css`, ], } + +export const WEIBO_API_DEPS_CSS = { + showModal: [`${MP_WEIBO_API_STYLE_PATH}modal.css`], + showToast: [`${MP_WEIBO_API_STYLE_PATH}toast.css`], + showActionSheet: [`${MP_WEIBO_API_STYLE_PATH}action-sheet.css`], + previewImage: [ + RESIZE_SENSOR_CSS, + `${BASE_COMPONENTS_STYLE_PATH}swiper.css`, + `${BASE_COMPONENTS_STYLE_PATH}swiper-item.css`, + `${BASE_COMPONENTS_STYLE_PATH}movable-area.css`, + `${BASE_COMPONENTS_STYLE_PATH}movable-view.css`, + ], + openLocation: [`${MP_WEIBO_API_STYLE_PATH}location-view.css`], + chooseLocation: [ + `${MP_WEIBO_API_STYLE_PATH}/location-picker.css`, + `${BASE_COMPONENTS_STYLE_PATH}/input.css`, + `${MP_WEIBO_COMPONENTS_STYLE_PATH}/map.css`, + `${BASE_COMPONENTS_STYLE_PATH}/scroll-view.css`, + ], +} diff --git a/packages/uni-cli-shared/src/json/manifest.ts b/packages/uni-cli-shared/src/json/manifest.ts index a77ac907d8c..0a99247fe15 100644 --- a/packages/uni-cli-shared/src/json/manifest.ts +++ b/packages/uni-cli-shared/src/json/manifest.ts @@ -20,7 +20,7 @@ export const parseManifestJsonOnce = once(parseManifestJson) export const parseRpx2UnitOnce = once( (inputDir: string, platform: UniApp.PLATFORM = 'h5') => { const rpx2unit = - platform === 'h5' || platform === 'app' + platform === 'h5' || platform === 'app' || platform === 'mp-weibo' ? defaultRpx2Unit : defaultMiniProgramRpx2Unit const platformOptions = parseManifestJsonOnce(inputDir)[platform] diff --git a/packages/uni-cli-shared/src/json/pages.ts b/packages/uni-cli-shared/src/json/pages.ts index 47359e3849e..2e65da577ae 100644 --- a/packages/uni-cli-shared/src/json/pages.ts +++ b/packages/uni-cli-shared/src/json/pages.ts @@ -259,7 +259,7 @@ function normalizePageStyle( } if (pageStyle) { - if (platform === 'h5') { + if (platform === 'h5' || platform === 'mp-weibo') { extend(pageStyle, pageStyle['app'] || pageStyle['app-plus']) } if (platform === 'app') { @@ -267,7 +267,7 @@ function normalizePageStyle( } else { extend(pageStyle, pageStyle[platform]) } - if (['h5', 'app'].includes(platform)) { + if (['h5', 'app', 'mp-weibo'].includes(platform)) { pageStyle.navigationBar = normalizeNavigationBar(pageStyle) if (isEnablePullDownRefresh(pageStyle)) { pageStyle.enablePullDownRefresh = true diff --git a/packages/uni-cli-shared/src/messages/zh_CN.ts b/packages/uni-cli-shared/src/messages/zh_CN.ts index 47b4308704d..e083d47f4fc 100644 --- a/packages/uni-cli-shared/src/messages/zh_CN.ts +++ b/packages/uni-cli-shared/src/messages/zh_CN.ts @@ -43,6 +43,7 @@ export default { 'prompt.run.devtools.mp-qq': 'QQ小程序开发者工具', 'prompt.run.devtools.mp-toutiao': '字节跳动开发者工具', 'prompt.run.devtools.mp-weixin': '微信开发者工具', + 'prompt.run.devtools.mp-weibo': '微博开发者工具', 'prompt.run.devtools.quickapp-webview': '快应用联盟开发者工具 | 华为快应用开发者工具', 'prompt.run.devtools.quickapp-webview-huawei': '华为快应用开发者工具', diff --git a/packages/uni-cli-shared/src/postcss/plugins/uniapp.ts b/packages/uni-cli-shared/src/postcss/plugins/uniapp.ts index fd62a90cc4e..60493763596 100644 --- a/packages/uni-cli-shared/src/postcss/plugins/uniapp.ts +++ b/packages/uni-cli-shared/src/postcss/plugins/uniapp.ts @@ -128,6 +128,7 @@ const transforms: Record = { h5: rewriteUniH5Tags, app: rewriteUniAppTags, 'mp-baidu': rewriteBaiduTags, + 'mp-weibo': rewriteUniH5Tags, } const uniapp = (opts?: UniAppCssProcessorOptions) => { diff --git a/packages/uni-cli-shared/src/preprocess/context.ts b/packages/uni-cli-shared/src/preprocess/context.ts index b3b75ee2a96..6f603015014 100644 --- a/packages/uni-cli-shared/src/preprocess/context.ts +++ b/packages/uni-cli-shared/src/preprocess/context.ts @@ -18,6 +18,7 @@ const DEFAULT_KEYS = [ 'MP_WEIXIN', 'MP_KUAISHOU', 'MP_JD', + 'MP_WEIBO', 'QUICKAPP_NATIVE', 'QUICKAPP_WEBVIEW', 'QUICKAPP_WEBVIEW_HUAWEI', @@ -79,11 +80,11 @@ export function initPreContext( } else if (utsPlatform === 'app-ios') { uvueContext.APP_IOS = true } - } else if (platform.startsWith('mp-')) { + } else if (platform.startsWith('mp-') && platform !== 'mp-weibo') { defaultContext.MP = true } else if (platform.startsWith('quickapp-webview')) { defaultContext.QUICKAPP_WEBVIEW = true - } else if (platform === 'h5') { + } else if (platform === 'h5' || platform === 'mp-weibo') { defaultContext.WEB = true } diff --git a/packages/uni-components/src/helpers/disable-scroll-bounce.js b/packages/uni-components/src/helpers/disable-scroll-bounce.js index a4962e3a0dc..4742b3fb71d 100644 --- a/packages/uni-components/src/helpers/disable-scroll-bounce.js +++ b/packages/uni-components/src/helpers/disable-scroll-bounce.js @@ -5,7 +5,7 @@ let disabled const lastAction = {} export function disableScrollBounce({ disable }) { - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { // H5 平台空方法 return } diff --git a/packages/uni-components/src/helpers/useField.ts b/packages/uni-components/src/helpers/useField.ts index 99be61693a5..c864a7efb4c 100644 --- a/packages/uni-components/src/helpers/useField.ts +++ b/packages/uni-components/src/helpers/useField.ts @@ -300,7 +300,7 @@ function useAutoFocus(props: Props, fieldRef: Ref) { setTimeout(focus, 100) return } - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { field.focus() } else { const timeout = FOCUS_DELAY - (Date.now() - startTime) diff --git a/packages/uni-components/src/vue/button/index.tsx b/packages/uni-components/src/vue/button/index.tsx index bb482de12af..d49eba701f3 100644 --- a/packages/uni-components/src/vue/button/index.tsx +++ b/packages/uni-components/src/vue/button/index.tsx @@ -48,6 +48,16 @@ export default /*#__PURE__*/ defineBuiltInComponent({ t('uni.button.feedback.send') ) } + if ( + // @ts-ignore + window.weibo && + // @ts-ignore + typeof window.weibo.share === 'function' && + props.openType === 'share' + ) { + // @ts-ignore + window.weibo.share() + } }) const uniLabel = inject( diff --git a/packages/uni-components/src/vue/image/index.tsx b/packages/uni-components/src/vue/image/index.tsx index 5e1093f1f88..b0dbc00c040 100644 --- a/packages/uni-components/src/vue/image/index.tsx +++ b/packages/uni-components/src/vue/image/index.tsx @@ -99,13 +99,25 @@ function useImageState(rootRef: Ref, props: ImageProps) { opts[0] && (position = opts[0]) opts[1] && (size = opts[1]) } + // @ts-ignore + if (window.weibo && props.src.startsWith('Temp')) { + // @ts-ignore + imgSrc.value = `../../${props.src}` + } return `background-image:${ imgSrc.value ? 'url("' + imgSrc.value + '")' : 'none' };background-position:${position};background-size:${size};` }) const state = reactive({ rootEl: rootRef, - src: computed(() => (props.src ? getRealPath(props.src) : '')), + src: computed(function () { + // @ts-ignore + if (window.weibo && props.src.startsWith('Temp')) { + // @ts-ignore + return `../../${props.src}` + } + return props.src ? getRealPath(props.src) : '' + }), origWidth: 0, origHeight: 0, origStyle: { width: '', height: '' }, diff --git a/packages/uni-components/src/vue/swiper/index.tsx b/packages/uni-components/src/vue/swiper/index.tsx index 2f0232692ac..2c0f8123118 100644 --- a/packages/uni-components/src/vue/swiper/index.tsx +++ b/packages/uni-components/src/vue/swiper/index.tsx @@ -724,7 +724,7 @@ export default /*#__PURE__*/ defineBuiltInComponent({ ) let createNavigationTsx: () => JSX.Element | null = () => null - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { createNavigationTsx = useSwiperNavigation( rootRef, props, diff --git a/packages/uni-core/src/helpers/page.ts b/packages/uni-core/src/helpers/page.ts index a41ee088b5e..ad442744d00 100644 --- a/packages/uni-core/src/helpers/page.ts +++ b/packages/uni-core/src/helpers/page.ts @@ -18,7 +18,7 @@ export function useCurrentPageId() { return getCurrentPageId() } // 暂时仅在 h5 平台实现 $pageInstance,避免影响过大 - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { const { $pageInstance } = getCurrentInstance()! return $pageInstance && $pageInstance.proxy!.$page.id } @@ -44,7 +44,7 @@ export function getPageIdByVm( return } // 暂时仅在 h5 平台实现 $pageInstance,避免影响过大 - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { const { $pageInstance } = vm.$ return $pageInstance && $pageInstance.proxy!.$page.id } diff --git a/packages/uni-core/src/i18n/useI18n.ts b/packages/uni-core/src/i18n/useI18n.ts index 6c58bde87bd..b6436d0c204 100644 --- a/packages/uni-core/src/i18n/useI18n.ts +++ b/packages/uni-core/src/i18n/useI18n.ts @@ -88,7 +88,7 @@ export function defineI18nProperty(obj: Record, names: string[]) { export function useI18n() { if (!i18n) { let locale: BuiltInLocale - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { if (__NODE_JS__) { locale = getEnvLocale() as BuiltInLocale } else { diff --git a/packages/uni-core/src/service/plugin/componentInstance.ts b/packages/uni-core/src/service/plugin/componentInstance.ts index 080d33a3c65..5a14661b95b 100644 --- a/packages/uni-core/src/service/plugin/componentInstance.ts +++ b/packages/uni-core/src/service/plugin/componentInstance.ts @@ -4,7 +4,7 @@ import { ComponentPublicInstance } from 'vue' export function getOpenerEventChannel( this: ComponentPublicInstance ): EventChannel | undefined { - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { if (this.$route) { const meta = this.$route.meta if (!meta.eventChannel) { diff --git a/packages/uni-core/src/view/plugin/componentInstance.ts b/packages/uni-core/src/view/plugin/componentInstance.ts index 31a3dfe9756..fe42f1a68be 100644 --- a/packages/uni-core/src/view/plugin/componentInstance.ts +++ b/packages/uni-core/src/view/plugin/componentInstance.ts @@ -27,7 +27,7 @@ export function $nne( } const isHTMLTarget = currentTarget.tagName.indexOf('UNI-') !== 0 // App 平台时不返回原始事件对象 https://github.com/dcloudio/uni-app/issues/3240 - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { if (isHTMLTarget) { return ( wrapperH5WxsEvent( @@ -60,7 +60,7 @@ export function $nne( }) }) } - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { return ( wrapperH5WxsEvent( res, @@ -104,7 +104,7 @@ export function createNativeEvent( ;(event as any).changedTouches = (evt as TouchEvent).changedTouches } - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { wrapperEvent(event, evt) } diff --git a/packages/uni-core/src/view/plugin/componentWxs.ts b/packages/uni-core/src/view/plugin/componentWxs.ts index 83584c01480..3ad6b60eaba 100644 --- a/packages/uni-core/src/view/plugin/componentWxs.ts +++ b/packages/uni-core/src/view/plugin/componentWxs.ts @@ -40,7 +40,7 @@ export class ComponentDescriptor { private $bindStyle: boolean = false constructor(vm: ComponentDescriptorVm) { this.$vm = vm - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { this.$el = resolveOwnerEl((vm as ComponentPublicInstance).$) as WxsElement } else { this.$el = vm.$el @@ -222,7 +222,7 @@ function createComponentDescriptor( vm: ComponentDescriptorVm, isOwnerInstance = true ) { - if (__PLATFORM__ === 'h5') { + if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { if (isOwnerInstance && vm) { vm = resolveOwnerVm((vm as ComponentPublicInstance).$)! } @@ -296,7 +296,7 @@ function getWxsVm(el: WxsElement) { } if (__PLATFORM__ === 'app') { return createComponentDescriptorVm(el) - } else if (__PLATFORM__ === 'h5') { + } else if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'mp-weibo') { return el.__vueParentComponent && el.__vueParentComponent.proxy! } } diff --git a/packages/uni-mp-weibo-vite/LICENSE b/packages/uni-mp-weibo-vite/LICENSE new file mode 100755 index 00000000000..7a4a3ea2424 --- /dev/null +++ b/packages/uni-mp-weibo-vite/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/uni-mp-weibo-vite/dist/index.d.ts b/packages/uni-mp-weibo-vite/dist/index.d.ts new file mode 100644 index 00000000000..bae4cfad058 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/index.d.ts @@ -0,0 +1,2 @@ +declare const _default: import("vite").Plugin[]; +export default _default; diff --git a/packages/uni-mp-weibo-vite/dist/index.js b/packages/uni-mp-weibo-vite/dist/index.js new file mode 100644 index 00000000000..02682a14b2c --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/index.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const plugin_1 = require("./plugin"); +const css_1 = require("./plugins/css"); +const easycom_1 = require("./plugins/easycom"); +const inject_1 = require("./plugins/inject"); +const mainJs_1 = require("./plugins/mainJs"); +const manifestJson_1 = require("./plugins/manifestJson"); +const pagesJson_1 = require("./plugins/pagesJson"); +const postVue_1 = require("./plugins/postVue"); +const renderjs_1 = require("./plugins/renderjs"); +const resolveId_1 = require("./plugins/resolveId"); +const setup_1 = require("./plugins/setup"); +const ssr_1 = require("./plugins/ssr"); +exports.default = [ + (0, easycom_1.uniEasycomPlugin)({ exclude: uni_cli_shared_1.UNI_EASYCOM_EXCLUDE }), + (0, uni_cli_shared_1.uniCssScopedPlugin)({ + filter: (id) => (0, uni_cli_shared_1.isVueSfcFile)(id) && !id.endsWith('App.vue'), + }), + (0, resolveId_1.uniResolveIdPlugin)(), + (0, mainJs_1.uniMainJsPlugin)(), + (0, manifestJson_1.uniManifestJsonPlugin)(), + (0, pagesJson_1.uniPagesJsonPlugin)(), + (0, inject_1.uniInjectPlugin)(), + (0, css_1.uniCssPlugin)(), + (0, ssr_1.uniSSRPlugin)(), + (0, setup_1.uniSetupPlugin)(), + (0, renderjs_1.uniRenderjsPlugin)(), + (0, plugin_1.uniH5Plugin)(), + (0, postVue_1.uniPostVuePlugin)(), +]; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/config.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/config.d.ts new file mode 100644 index 00000000000..c42e9ce249d --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/config.d.ts @@ -0,0 +1,4 @@ +import type { Plugin, ResolvedConfig } from 'vite'; +export declare function createConfig(options: { + resolvedConfig: ResolvedConfig | null; +}): Plugin['config']; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/config.js b/packages/uni-mp-weibo-vite/dist/plugin/config.js new file mode 100644 index 00000000000..f2b1dd83cfb --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/config.js @@ -0,0 +1,102 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createConfig = void 0; +const os_1 = __importDefault(require("os")); +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const utils_1 = require("../utils"); +const esbuildPrePlugin_1 = require("./esbuild/esbuildPrePlugin"); +const ssr_1 = require("./configureServer/ssr"); +const shared_1 = require("@vue/shared"); +function createConfig(options) { + return function config(config, env) { + const inputDir = process.env.UNI_INPUT_DIR; + if ((0, uni_cli_shared_1.isInHBuilderX)()) { + if (!fs_1.default.existsSync(path_1.default.resolve(inputDir, 'index.html'))) { + console.error(`请确认您的项目模板是否支持vue3:根目录缺少 index.html`); + process.exit(); + } + } + const server = { + host: true, + hmr: { + // mac 内置浏览器版本较低不支持 globalThis,而 overlay 使用了 globalThis + overlay: os_1.default.platform() !== 'win32' + ? process.env.UNI_H5_BROWSER !== 'builtin' + : true, + }, + fs: { strict: false }, + watch: { + ignored: [ + '**/uniCloud-aliyun/**', + '**/uniCloud-tcb/**', + '**/uni_modules/uniCloud/**', + (0, uni_cli_shared_1.normalizePath)(path_1.default.join(inputDir, 'unpackage/**')), + (0, uni_cli_shared_1.normalizePath)(path_1.default.join(inputDir, 'dist/**')), + ], + }, + // eslint-disable-next-line no-restricted-syntax + ...(0, uni_cli_shared_1.getDevServerOptions)((0, uni_cli_shared_1.parseManifestJsonOnce)(inputDir)), + }; + if (server.port === '') { + delete server.port; + } + const { server: userServer } = config; + if (userServer) { + if ((0, shared_1.hasOwn)(userServer, 'host')) { + server.host = userServer.host; + } + if ((0, shared_1.hasOwn)(userServer, 'fs')) { + (0, shared_1.extend)(server.fs, userServer.fs); + } + if ((0, shared_1.hasOwn)(userServer, 'watch')) { + (0, shared_1.extend)(server.watch, userServer.watch); + } + } + return { + css: { + postcss: { + plugins: (0, uni_cli_shared_1.initPostcssPlugin)({ + uniApp: (0, uni_cli_shared_1.parseRpx2UnitOnce)(inputDir, process.env.UNI_PLATFORM), + }), + }, + }, + optimizeDeps: { + entries: (0, uni_cli_shared_1.resolveMainPathOnce)(inputDir), + exclude: ssr_1.external, + esbuildOptions: { + plugins: [(0, esbuildPrePlugin_1.esbuildPrePlugin)()], + }, + }, + define: (0, utils_1.createDefine)(env.command, config), + server, + ssr: { + external: ssr_1.external, + }, + build: { + rollupOptions: { + // resolveSSRExternal 会判定package.json,hbx 工程可能没有,通过 rollup 来配置 + external: (0, uni_cli_shared_1.isSsr)(env.command, config) ? ssr_1.external : [], + output: { + chunkFileNames(chunkInfo) { + const { assetsDir } = options.resolvedConfig.build; + if (chunkInfo.facadeModuleId) { + const dirname = path_1.default.relative(inputDir, path_1.default.dirname(chunkInfo.facadeModuleId)); + if (dirname) { + return path_1.default.posix.join(assetsDir, (0, uni_cli_shared_1.normalizePath)(dirname).replace(/\//g, '-') + + '-[name].[hash].js'); + } + } + return path_1.default.posix.join(assetsDir, '[name].[hash].js'); + }, + }, + }, + }, + }; + }; +} +exports.createConfig = createConfig; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/index.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/index.d.ts new file mode 100644 index 00000000000..e5991bf15ff --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/index.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function createConfigureServer(): Plugin['configureServer']; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/index.js b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/index.js new file mode 100644 index 00000000000..85e0ee2e0a7 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createConfigureServer = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const timestamp_1 = require("./middlewares/timestamp"); +const ssr_1 = require("./ssr"); +const static_1 = require("./static"); +function createConfigureServer() { + return function (server) { + (0, ssr_1.initSSR)(server); + const routerOptions = (0, uni_cli_shared_1.getRouterOptions)((0, uni_cli_shared_1.parseManifestJsonOnce)(process.env.UNI_INPUT_DIR)); + if (routerOptions.mode === 'history') { + server.middlewares.use((0, timestamp_1.uniTimestampMiddleware)(server)); + } + return () => { + (0, static_1.initStatic)(server); + }; + }; +} +exports.createConfigureServer = createConfigureServer; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/static.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/static.d.ts new file mode 100644 index 00000000000..76eb3f02051 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/static.d.ts @@ -0,0 +1,9 @@ +/// +import { IncomingMessage, ServerResponse } from 'http'; +interface UniStaticMiddlewareOptions { + etag: boolean; + resolve: (pathname: string) => string | void; +} +export type NextHandler = () => void | Promise; +export declare function uniStaticMiddleware(opts: UniStaticMiddlewareOptions): (req: IncomingMessage, res: ServerResponse, next: NextHandler) => void | Promise | ServerResponse; +export {}; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/static.js b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/static.js new file mode 100644 index 00000000000..84e2a222a62 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/static.js @@ -0,0 +1,81 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniStaticMiddleware = void 0; +const fs_1 = __importDefault(require("fs")); +const url_1 = __importDefault(require("url")); +const lite_1 = __importDefault(require("mime/lite")); +function normalizeFile(filename, isEtag) { + const stats = fs_1.default.statSync(filename); + return { + stats, + headers: normalizeHeaders(filename, stats, isEtag), + }; +} +function normalizeHeaders(filename, stats, isEtag) { + const headers = { + 'Content-Length': stats.size, + 'Content-Type': lite_1.default.getType(filename) || '', + 'Last-Modified': stats.mtime.toUTCString(), + }; + if (isEtag) { + headers['ETag'] = `W/"${stats.size}-${stats.mtime.getTime()}"`; + } + return headers; +} +function send(req, res, filename, stats, headers) { + let code = 200; + // eslint-disable-next-line no-restricted-syntax + headers = { ...headers }; + const opts = {}; + for (const key in headers) { + const value = res.getHeader(key); + if (value) { + headers[key] = value; + } + } + if (res.getHeader('content-type')) { + headers['Content-Type'] = res.getHeader('content-type'); + } + if (req.headers.range) { + code = 206; + const [x, y] = req.headers.range.replace('bytes=', '').split('-'); + const end = (opts.end = parseInt(y, 10) || stats.size - 1); + const start = (opts.start = parseInt(x, 10) || 0); + if (start >= stats.size || end >= stats.size) { + res.setHeader('Content-Range', `bytes */${stats.size}`); + res.statusCode = 416; + return res.end(); + } + headers['Content-Range'] = `bytes ${start}-${end}/${stats.size}`; + headers['Content-Length'] = end - start + 1; + headers['Accept-Ranges'] = 'bytes'; + } + res.writeHead(code, headers); + fs_1.default.createReadStream(filename, opts).pipe(res); +} +function uniStaticMiddleware(opts) { + const isEtag = !!opts.etag; + return function staticMiddleware(req, res, next) { + const pathname = url_1.default.parse(req.url).pathname; + if (!pathname) { + return next(); + } + const filename = opts.resolve(pathname); + if (!filename) { + return next(); + } + const data = normalizeFile(filename, isEtag); + if (!data) { + return next(); + } + if (isEtag && req.headers['if-none-match'] === data.headers['ETag']) { + res.writeHead(304); + return res.end(); + } + return send(req, res, filename, data.stats, data.headers); + }; +} +exports.uniStaticMiddleware = uniStaticMiddleware; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/timestamp.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/timestamp.d.ts new file mode 100644 index 00000000000..d9c160cba41 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/timestamp.d.ts @@ -0,0 +1,4 @@ +import { IncomingMessage, ServerResponse } from 'http'; +import type { ViteDevServer } from 'vite'; +import { NextHandler } from './static'; +export declare function uniTimestampMiddleware(server: ViteDevServer): (req: IncomingMessage, _: ServerResponse, next: NextHandler) => Promise; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/timestamp.js b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/timestamp.js new file mode 100644 index 00000000000..41cb01e518e --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/middlewares/timestamp.js @@ -0,0 +1,36 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniTimestampMiddleware = void 0; +const url_1 = require("url"); +const path_1 = __importDefault(require("path")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +function uniTimestampMiddleware(server) { + return async function timestampMiddleware(req, _, next) { + // 当页面被作为组件引用时,会导致history刷新该页面直接显示js代码,因为该页面已被缓存为了module, + // https://github.com/vitejs/vite/blob/702d50315535c189151c67d33e4a22124f926bed/packages/vite/src/node/server/transformRequest.ts#L52 + // /pages/tabBar/API/API + let { url } = req; + if (url) { + const base = server.config.base; + const parsed = (0, url_1.parse)(url); + let newUrl = url; + if ((parsed.pathname || '/').startsWith(base)) { + newUrl = newUrl.replace(base, '/'); + } + if (!path_1.default.extname(newUrl) && + !newUrl.endsWith('/') && + !newUrl.includes('?')) { + const module = await server.moduleGraph.getModuleByUrl(newUrl); + if (module && module.file && uni_cli_shared_1.EXTNAME_VUE_RE.test(module.file)) { + // /pages/tabBar/API/API => /pages/tabBar/API/API?__t__=time + req.url = url + '?__t__=' + Date.now(); + } + } + } + next(); + }; +} +exports.uniTimestampMiddleware = uniTimestampMiddleware; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/ssr.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/ssr.d.ts new file mode 100644 index 00000000000..7dd5271e273 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/ssr.d.ts @@ -0,0 +1,3 @@ +import type { ViteDevServer } from 'vite'; +export declare const external: string[]; +export declare function initSSR(server: ViteDevServer): void; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/ssr.js b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/ssr.js new file mode 100644 index 00000000000..d7b05593e7a --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/ssr.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.initSSR = exports.external = void 0; +exports.external = [ + '@dcloudio/uni-app', + '@dcloudio/uni-app-plus', + '@dcloudio/uni-cloud', + '@dcloudio/uni-components', + '@dcloudio/uni-mp-webo', + '@dcloudio/uni-h5-vue', + '@dcloudio/uni-i18n', + '@dcloudio/uni-mp-alipay', + '@dcloudio/uni-mp-baidu', + '@dcloudio/uni-mp-kuaishou', + '@dcloudio/uni-mp-lark', + '@dcloudio/uni-mp-qq', + '@dcloudio/uni-mp-toutiao', + '@dcloudio/uni-mp-weixin', + '@dcloudio/uni-quickapp-webview', + '@dcloudio/uni-shared', + '@dcloudio/uni-stat', + '@dcloudio/uni-stacktracey', + '@vue/shared', + 'vue', + 'vue-i18n', + 'vue-router', + 'vuex', + // dev + '@dcloudio/types', + '@dcloudio/uni-automator', + '@dcloudio/uni-cli-shared', + '@dcloudio/vite-plugin-uni', + 'autoprefixer', + 'typescript', + 'vite', +]; +function initSSR(server) { + const { ssrLoadModule } = server; + let added = false; + server.ssrLoadModule = (url) => { + const res = ssrLoadModule(url); + if (!added) { + // HBuilderX项目,根目录可能没有package.json,导致 ssrExternals 不生效 + added = true; + if (server._ssrExternals) { + const { _ssrExternals } = server; + exports.external.forEach((module) => { + if (!_ssrExternals.includes(module)) { + _ssrExternals.push(module); + } + }); + } + } + return res; + }; +} +exports.initSSR = initSSR; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/static.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/static.d.ts new file mode 100644 index 00000000000..83c19047210 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/static.d.ts @@ -0,0 +1,8 @@ +import type { ViteDevServer } from 'vite'; +/** + * devServer时提供static等目录的静态资源服务 + * @param server + * @param param + */ +export declare const initStatic: (server: ViteDevServer) => void; +export declare function createPublicFileFilter(base?: string): (id: unknown) => boolean; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/configureServer/static.js b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/static.js new file mode 100644 index 00000000000..7ad383f15e9 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/configureServer/static.js @@ -0,0 +1,59 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createPublicFileFilter = exports.initStatic = void 0; +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const debug_1 = __importDefault(require("debug")); +const pluginutils_1 = require("@rollup/pluginutils"); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const static_1 = require("./middlewares/static"); +const debugStatic = (0, debug_1.default)('uni:static'); +/** + * devServer时提供static等目录的静态资源服务 + * @param server + * @param param + */ +const initStatic = (server) => { + const filter = createPublicFileFilter(); + const serve = (0, static_1.uniStaticMiddleware)({ + etag: true, + resolve(pathname) { + if (!filter(pathname)) { + return; + } + const filename = path_1.default.join(process.env.UNI_INPUT_DIR, pathname); + if (fs_1.default.existsSync(filename)) { + debugStatic(filename, 'success'); + return filename; + } + else { + debugStatic(filename, 'fail'); + } + }, + }); + const viteServePublicMiddlewareIndex = server.middlewares.stack.findIndex((middleware) => { + return (middleware.handle.name === 'viteServePublicMiddleware'); + }); + // 替换 vite 自带的 public middleware + if (viteServePublicMiddlewareIndex > -1) { + server.middlewares.stack.splice(viteServePublicMiddlewareIndex, 1, { + route: '', + handle: ((req, res, next) => { + if ((0, uni_cli_shared_1.isImportRequest)(req.url) || (0, uni_cli_shared_1.isInternalRequest)(req.url)) { + return next(); + } + return serve(req, res, next); + }), + }); + } +}; +exports.initStatic = initStatic; +function createPublicFileFilter(base = '/') { + const publicDir = (0, uni_cli_shared_1.normalizePath)(path_1.default.join(base, uni_cli_shared_1.PUBLIC_DIR + '/**/*')); + const uniModulesDir = (0, uni_cli_shared_1.normalizePath)(path_1.default.join(base, 'uni_modules/*/' + uni_cli_shared_1.PUBLIC_DIR + '/**/*')); + return (0, pluginutils_1.createFilter)([publicDir, uniModulesDir]); +} +exports.createPublicFileFilter = createPublicFileFilter; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/esbuild/esbuildPrePlugin.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/esbuild/esbuildPrePlugin.d.ts new file mode 100644 index 00000000000..f3530ccf7e6 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/esbuild/esbuildPrePlugin.d.ts @@ -0,0 +1,3 @@ +import type { Plugin } from 'esbuild'; +export declare const JS_TYPES_RE: RegExp; +export declare function esbuildPrePlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/esbuild/esbuildPrePlugin.js b/packages/uni-mp-weibo-vite/dist/plugin/esbuild/esbuildPrePlugin.js new file mode 100644 index 00000000000..b49d7de5e92 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/esbuild/esbuildPrePlugin.js @@ -0,0 +1,31 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.esbuildPrePlugin = exports.JS_TYPES_RE = void 0; +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +exports.JS_TYPES_RE = /\.(?:j|t)sx?$|\.mjs$/; +function esbuildPrePlugin() { + return { + name: 'uni:dep-scan', + setup(build) { + build.onLoad({ filter: exports.JS_TYPES_RE }, ({ path: id }) => { + let ext = path_1.default.extname(id).slice(1); + if (ext === 'mjs') + ext = 'js'; + let contents = fs_1.default.readFileSync(id, 'utf-8'); + if (contents.includes('#endif')) { + contents = (0, uni_cli_shared_1.preJs)(contents); + } + return { + loader: ext, + contents, + }; + }); + }, + }; +} +exports.esbuildPrePlugin = esbuildPrePlugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/handleHotUpdate/index.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/handleHotUpdate/index.d.ts new file mode 100644 index 00000000000..af7927f0dc9 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/handleHotUpdate/index.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function createHandleHotUpdate(): Plugin['handleHotUpdate']; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/handleHotUpdate/index.js b/packages/uni-mp-weibo-vite/dist/plugin/handleHotUpdate/index.js new file mode 100644 index 00000000000..72797848e64 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/handleHotUpdate/index.js @@ -0,0 +1,81 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createHandleHotUpdate = void 0; +const path_1 = __importDefault(require("path")); +const debug_1 = __importDefault(require("debug")); +const shared_1 = require("@vue/shared"); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const debugHmr = (0, debug_1.default)('uni:hmr'); +async function invalidate(file, moduleGraph) { + const mods = await moduleGraph.getModulesByFile((0, uni_cli_shared_1.normalizePath)(file)); + if (mods && mods.size) { + ; + [...mods].forEach((mod) => { + debugHmr('invalidate', mod.id); + moduleGraph.invalidateModule(mod); + }); + } +} +let invalidateFiles; +function createHandleHotUpdate() { + return async function ({ file, server }) { + const inputDir = process.env.UNI_INPUT_DIR; + const platform = process.env.UNI_PLATFORM; + if (!invalidateFiles) { + invalidateFiles = [ + path_1.default.resolve(inputDir, uni_cli_shared_1.PAGES_JSON_JS), + path_1.default.resolve(inputDir, uni_cli_shared_1.MANIFEST_JSON_JS), + (0, uni_cli_shared_1.resolveBuiltIn)('@dcloudio/uni-mp-weibo/dist/uni-mp-weibo.es.js'), + ]; + try { + invalidateFiles.push((0, uni_cli_shared_1.resolveBuiltIn)('vite/dist/client/env.mjs')); + } + catch (e) { } + } + // TODO 目前简单处理,当pages.json,manifest.json发生变化,就直接刷新,理想情况下,应该区分变化的内容,仅必要时做整页面刷新 + const isPagesJson = file.endsWith('pages.json'); + const isManifestJson = file.endsWith('manifest.json'); + if (!isPagesJson && !isManifestJson) { + return; + } + debugHmr(file); + const pagesJson = (0, uni_cli_shared_1.parsePagesJson)(inputDir, platform); + // 更新define + const { define, server: { middlewareMode }, } = server.config; + (0, shared_1.extend)(define, (0, uni_cli_shared_1.initFeatures)({ + inputDir, + command: 'serve', + platform, + pagesJson, + manifestJson: (0, uni_cli_shared_1.parseManifestJson)(inputDir), + ssr: !!middlewareMode, + })); + debugHmr('define', define); + if (isPagesJson) { + const easycom = pagesJson.easycom || {}; + const { options, refresh } = (0, uni_cli_shared_1.initEasycomsOnce)(inputDir, { + dirs: [(0, uni_cli_shared_1.resolveComponentsLibPath)()], + platform, + }); + if (!equal({ autoscan: easycom.autoscan, custom: easycom.custom }, { autoscan: options.autoscan, custom: options.custom })) { + refresh(); + } + } + // 当pages.json,manifest.json发生变化时,作废pages.json.js缓存 + for (const file of invalidateFiles) { + await invalidate(file, server.moduleGraph); + } + server.ws.send({ + type: 'full-reload', + path: '*', + }); + return []; + }; +} +exports.createHandleHotUpdate = createHandleHotUpdate; +function equal(obj1, obj2) { + return JSON.stringify(obj1) === JSON.stringify(obj2); +} diff --git a/packages/uni-mp-weibo-vite/dist/plugin/index.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/index.d.ts new file mode 100644 index 00000000000..098ae2b4e53 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/index.d.ts @@ -0,0 +1,2 @@ +import { UniVitePlugin } from '@dcloudio/uni-cli-shared'; +export declare function uniH5Plugin(): UniVitePlugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/index.js b/packages/uni-mp-weibo-vite/dist/plugin/index.js new file mode 100644 index 00000000000..86609475ca0 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/index.js @@ -0,0 +1,50 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniH5Plugin = void 0; +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const handleHotUpdate_1 = require("./handleHotUpdate"); +const transformIndexHtml_1 = require("./transformIndexHtml"); +const configureServer_1 = require("./configureServer"); +const uni_1 = require("./uni"); +const config_1 = require("./config"); +const shared_1 = require("@vue/shared"); +function uniH5Plugin() { + const configOptions = { + resolvedConfig: null, + }; + rewriteReadFileSync(); + return { + name: 'uni:h5', + uni: (0, uni_1.createUni)(), + config: (0, config_1.createConfig)(configOptions), + configResolved(config) { + configOptions.resolvedConfig = config; + }, + configureServer: (0, configureServer_1.createConfigureServer)(), + handleHotUpdate: (0, handleHotUpdate_1.createHandleHotUpdate)(), + transformIndexHtml: (0, transformIndexHtml_1.createTransformIndexHtml)(), + }; +} +exports.uniH5Plugin = uniH5Plugin; +/** + * 重写 readFileSync + * 目前主要解决 scss 文件被 @import 的条件编译 + */ +function rewriteReadFileSync() { + const { readFileSync } = fs_1.default; + fs_1.default.readFileSync = ((filepath, options) => { + const content = readFileSync(filepath, options); + if ((0, shared_1.isString)(filepath) && + (0, shared_1.isString)(content) && + path_1.default.extname(filepath) === '.scss' && + content.includes('#endif')) { + return (0, uni_cli_shared_1.preCss)(content); + } + return content; + }); +} diff --git a/packages/uni-mp-weibo-vite/dist/plugin/transformIndexHtml/index.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/transformIndexHtml/index.d.ts new file mode 100644 index 00000000000..305e9d4139d --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/transformIndexHtml/index.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function createTransformIndexHtml(): Plugin['transformIndexHtml']; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/transformIndexHtml/index.js b/packages/uni-mp-weibo-vite/dist/plugin/transformIndexHtml/index.js new file mode 100644 index 00000000000..3c9417e4c34 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/transformIndexHtml/index.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createTransformIndexHtml = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +function createTransformIndexHtml() { + return async function (html) { + const manifestJson = (0, uni_cli_shared_1.parseManifestJsonOnce)(process.env.UNI_INPUT_DIR); + const title = manifestJson.h5?.title || manifestJson.name || ''; + return { + html: html.replace(/(.*?)<\/title>/, `<title>${title}`), + tags: process.env.NODE_ENV === 'development' + ? [ + { + tag: 'script', + children: `if (typeof globalThis === 'undefined') { + window.globalThis = window +}`, + injectTo: 'head-prepend', + }, + ] + : [], + }; + }; +} +exports.createTransformIndexHtml = createTransformIndexHtml; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/transforms/transformPageHead.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/transforms/transformPageHead.d.ts new file mode 100644 index 00000000000..1d16440751e --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/transforms/transformPageHead.d.ts @@ -0,0 +1,2 @@ +import { NodeTransform } from '@vue/compiler-core'; +export declare const transformPageHead: NodeTransform; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/transforms/transformPageHead.js b/packages/uni-mp-weibo-vite/dist/plugin/transforms/transformPageHead.js new file mode 100644 index 00000000000..33f3c736966 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/transforms/transformPageHead.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.transformPageHead = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const transformPageHead = (node, context) => { + if ((0, uni_cli_shared_1.checkElementNodeTag)(node, 'page-meta')) { + const headNode = node.children.find((child) => (0, uni_cli_shared_1.checkElementNodeTag)(child, 'head')); + if (headNode) { + headNode.tag = 'page-meta-head'; + } + return; + } + if ((0, uni_cli_shared_1.checkElementNodeTag)(node, 'head') && + (0, uni_cli_shared_1.checkElementNodeTag)(context.parent, 'page-meta')) { + ; + node.tag = 'page-meta-head'; + } +}; +exports.transformPageHead = transformPageHead; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/uni.d.ts b/packages/uni-mp-weibo-vite/dist/plugin/uni.d.ts new file mode 100644 index 00000000000..99c39da3f40 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/uni.d.ts @@ -0,0 +1,4 @@ +import { UniVitePlugin } from '@dcloudio/uni-cli-shared'; +import { CompilerOptions } from '@vue/compiler-core'; +export declare const compilerOptions: CompilerOptions; +export declare function createUni(): UniVitePlugin['uni']; diff --git a/packages/uni-mp-weibo-vite/dist/plugin/uni.js b/packages/uni-mp-weibo-vite/dist/plugin/uni.js new file mode 100644 index 00000000000..9396f1382c5 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugin/uni.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createUni = exports.compilerOptions = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const uni_shared_1 = require("@dcloudio/uni-shared"); +exports.compilerOptions = { + isNativeTag: uni_shared_1.isH5NativeTag, + isCustomElement: uni_shared_1.isH5CustomElement, + nodeTransforms: [ + uni_cli_shared_1.transformH5BuiltInComponents, + uni_cli_shared_1.transformTapToClick, + uni_cli_shared_1.transformMatchMedia, + uni_cli_shared_1.transformPageHead, + ], +}; +function createUni() { + return { + copyOptions: { + assets: ['hybrid/html/**/*', 'uni_modules/*/hybrid/html/**/*'], + }, + compilerOptions: exports.compilerOptions, + jsxOptions: { + babelPlugins: [uni_cli_shared_1.transformUniH5Jsx], + }, + }; +} +exports.createUni = createUni; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/css.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/css.d.ts new file mode 100644 index 00000000000..27c6a93001a --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/css.d.ts @@ -0,0 +1,28 @@ +/// +import { Plugin } from 'vite'; +import { OutputOptions } from 'rollup'; +export declare function uniCssPlugin(): Plugin; +/** + * converts the source filepath of the asset to the output filename based on the assetFileNames option. \ + * this function imitates the behavior of rollup.js. \ + * https://rollupjs.org/guide/en/#outputassetfilenames + * + * @example + * ```ts + * const content = Buffer.from('text'); + * const fileName = assetFileNamesToFileName( + * 'assets/[name].[hash][extname]', + * '/path/to/file.txt', + * getAssetHash(content), + * content + * ) + * // fileName: 'assets/file.982d9e3e.txt' + * ``` + * + * @param assetFileNames filename pattern. e.g. `'assets/[name].[hash][extname]'` + * @param file filepath of the asset + * @param contentHash hash of the asset. used for `'[hash]'` placeholder + * @param content content of the asset. passed to `assetFileNames` if `assetFileNames` is a function + * @returns output filename + */ +export declare function assetFileNamesToFileName(assetFileNames: Exclude, file: string, contentHash: string, content: string | Buffer): string; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/css.js b/packages/uni-mp-weibo-vite/dist/plugins/css.js new file mode 100644 index 00000000000..12e9ccea922 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/css.js @@ -0,0 +1,134 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.assetFileNamesToFileName = exports.uniCssPlugin = void 0; +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const vite_1 = require("vite"); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const shared_1 = require("@vue/shared"); +function isCombineBuiltInCss(config) { + return config.command === 'build' && config.build.cssCodeSplit; +} +function uniCssPlugin() { + let resolvedConfig; + let file = ''; + let fileName = ''; + return { + name: 'uni:h5-css', + apply: 'build', + enforce: 'pre', + configResolved(config) { + resolvedConfig = config; + file = path_1.default.join(process.env.UNI_INPUT_DIR, 'uni.css'); + }, + async generateBundle() { + if (!isCombineBuiltInCss(resolvedConfig) || !uni_cli_shared_1.buildInCssSet.size) { + return; + } + // 生成框架css(需要排序,避免生成不一样的内容) + const content = await (0, uni_cli_shared_1.minifyCSS)(generateBuiltInCssCode([...uni_cli_shared_1.buildInCssSet].sort()), resolvedConfig); + // @ts-ignore 'Buffer' only refers to a type, but is being used as a value here + const contentHash = (0, uni_cli_shared_1.getAssetHash)(Buffer.from(content, 'utf-8')); + const assetFileNames = path_1.default.posix.join(resolvedConfig.build.assetsDir, '[name].[hash][extname]'); + fileName = assetFileNamesToFileName(assetFileNames, file, contentHash, content); + const name = (0, vite_1.normalizePath)(path_1.default.relative(resolvedConfig.root, file)); + this.emitFile({ + name, + fileName, + type: 'asset', + source: content, + }); + }, + transformIndexHtml: { + enforce: 'post', + transform() { + if (!fileName) { + return; + } + // 追加框架css + return [ + { + tag: 'link', + attrs: { + rel: 'stylesheet', + href: toPublicPath(fileName, resolvedConfig), + }, + injectTo: 'head-prepend', + }, + ]; + }, + }, + }; +} +exports.uniCssPlugin = uniCssPlugin; +function toPublicPath(filename, config) { + return (0, uni_cli_shared_1.isExternalUrl)(filename) ? filename : config.base + filename; +} +function generateBuiltInCssCode(cssImports) { + return cssImports + .map((cssImport) => fs_1.default.readFileSync((0, uni_cli_shared_1.resolveBuiltIn)(cssImport), 'utf8')) + .join('\n'); +} +/** + * converts the source filepath of the asset to the output filename based on the assetFileNames option. \ + * this function imitates the behavior of rollup.js. \ + * https://rollupjs.org/guide/en/#outputassetfilenames + * + * @example + * ```ts + * const content = Buffer.from('text'); + * const fileName = assetFileNamesToFileName( + * 'assets/[name].[hash][extname]', + * '/path/to/file.txt', + * getAssetHash(content), + * content + * ) + * // fileName: 'assets/file.982d9e3e.txt' + * ``` + * + * @param assetFileNames filename pattern. e.g. `'assets/[name].[hash][extname]'` + * @param file filepath of the asset + * @param contentHash hash of the asset. used for `'[hash]'` placeholder + * @param content content of the asset. passed to `assetFileNames` if `assetFileNames` is a function + * @returns output filename + */ +function assetFileNamesToFileName(assetFileNames, file, contentHash, content) { + const basename = path_1.default.basename(file); + // placeholders for `assetFileNames` + // `hash` is slightly different from the rollup's one + const extname = path_1.default.extname(basename); + const ext = extname.slice(1); + const name = basename.slice(0, -extname.length); + const hash = contentHash; + if ((0, shared_1.isFunction)(assetFileNames)) { + assetFileNames = assetFileNames({ + name: file, + source: content, + type: 'asset', + }); + if (!(0, shared_1.isString)(assetFileNames)) { + throw new TypeError('assetFileNames must return a string'); + } + } + else if (!(0, shared_1.isString)(assetFileNames)) { + throw new TypeError('assetFileNames must be a string or a function'); + } + const fileName = assetFileNames.replace(/\[\w+\]/g, (placeholder) => { + switch (placeholder) { + case '[ext]': + return ext; + case '[extname]': + return extname; + case '[hash]': + return hash; + case '[name]': + return name; + } + throw new Error(`invalid placeholder ${placeholder} in assetFileNames "${assetFileNames}"`); + }); + return fileName; +} +exports.assetFileNamesToFileName = assetFileNamesToFileName; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/easycom.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/easycom.d.ts new file mode 100644 index 00000000000..e213d532c5f --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/easycom.d.ts @@ -0,0 +1,8 @@ +import type { Plugin } from 'vite'; +import { FilterPattern } from '@rollup/pluginutils'; +interface UniEasycomPluginOptions { + include?: FilterPattern; + exclude?: FilterPattern; +} +export declare function uniEasycomPlugin(options: UniEasycomPluginOptions): Plugin; +export {}; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/easycom.js b/packages/uni-mp-weibo-vite/dist/plugins/easycom.js new file mode 100644 index 00000000000..ff4025b59d3 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/easycom.js @@ -0,0 +1,111 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniEasycomPlugin = void 0; +const path_1 = __importDefault(require("path")); +const pluginutils_1 = require("@rollup/pluginutils"); +const shared_1 = require("@vue/shared"); +const uni_shared_1 = require("@dcloudio/uni-shared"); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const MP_WEIBO_COMPONENTS_PATH = '@dcloudio/uni-mp-weibo'; +const baseComponents = [ + 'audio', + 'button', + 'canvas', + 'checkbox', + 'checkbox-group', + 'editor', + 'form', + 'icon', + 'image', + 'input', + 'label', + 'movable-area', + 'movable-view', + 'navigator', + 'picker-view', + 'picker-view-column', + 'progress', + 'radio', + 'radio-group', + 'resize-sensor', + 'rich-text', + 'scroll-view', + 'slider', + 'swiper', + 'swiper-item', + 'switch', + 'text', + 'textarea', + 'view', +]; +function uniEasycomPlugin(options) { + const filter = (0, pluginutils_1.createFilter)(options.include, options.exclude); + let needCombineBuiltInCss = false; + return { + name: 'uni:h5-easycom', + configResolved(config) { + needCombineBuiltInCss = (0, uni_cli_shared_1.isCombineBuiltInCss)(config); + }, + transform(code, id) { + if (!filter(id)) { + return; + } + const { filename } = (0, uni_cli_shared_1.parseVueRequest)(id); + if (!uni_cli_shared_1.EXTNAME_VUE_TEMPLATE.includes(path_1.default.extname(filename))) { + return; + } + if (!code.includes('_resolveComponent')) { + return; + } + let i = 0; + const importDeclarations = []; + code = code.replace(/_resolveComponent\("(.+?)"(, true)?\)/g, (str, name) => { + if (name && !name.startsWith('_')) { + if ((0, uni_shared_1.isBuiltInComponent)(name)) { + name = name.replace(uni_shared_1.COMPONENT_PREFIX, ''); + const local = `__syscom_${i++}`; + if (needCombineBuiltInCss) { + // 发行模式下,应该将内置组件css输出到入口css中 + resolveBuiltInCssImport(name).forEach((cssImport) => uni_cli_shared_1.buildInCssSet.add(cssImport)); + return (0, uni_cli_shared_1.addImportDeclaration)(importDeclarations, local, MP_WEIBO_COMPONENTS_PATH, (0, shared_1.capitalize)((0, shared_1.camelize)(name))); + } + return addBuiltInImportDeclaration(importDeclarations, local, name); + } + const source = (0, uni_cli_shared_1.matchEasycom)(name); + if (source) { + // 处理easycom组件优先级 + return (0, uni_cli_shared_1.genResolveEasycomCode)(importDeclarations, str, (0, uni_cli_shared_1.addImportDeclaration)(importDeclarations, `__easycom_${i++}`, source)); + } + } + return str; + }); + if (importDeclarations.length) { + code = importDeclarations.join('') + code; + } + return { + code, + map: null, + }; + }, + }; +} +exports.uniEasycomPlugin = uniEasycomPlugin; +function resolveBuiltInCssImport(name) { + const cssImports = []; + if (baseComponents.includes(name)) { + cssImports.push(uni_cli_shared_1.BASE_COMPONENTS_STYLE_PATH + name + '.css'); + } + else { + cssImports.push(uni_cli_shared_1.MP_WEIBO_COMPONENTS_STYLE_PATH + name + '.css'); + } + const deps = uni_cli_shared_1.COMPONENT_DEPS_CSS[name]; + deps && deps.forEach((dep) => cssImports.push(dep)); + return cssImports; +} +function addBuiltInImportDeclaration(importDeclarations, local, name) { + resolveBuiltInCssImport(name).forEach((cssImport) => importDeclarations.push(`import '${cssImport}';`)); + return (0, uni_cli_shared_1.addImportDeclaration)(importDeclarations, local, MP_WEIBO_COMPONENTS_PATH, (0, shared_1.capitalize)((0, shared_1.camelize)(name))); +} diff --git a/packages/uni-mp-weibo-vite/dist/plugins/inject.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/inject.d.ts new file mode 100644 index 00000000000..32448d7dd08 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/inject.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function uniInjectPlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/inject.js b/packages/uni-mp-weibo-vite/dist/plugins/inject.js new file mode 100644 index 00000000000..34c5d77fb59 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/inject.js @@ -0,0 +1,69 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniInjectPlugin = void 0; +const path_1 = __importDefault(require("path")); +const shared_1 = require("@vue/shared"); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +// eslint-disable-next-line no-restricted-globals +const apiJson = require(path_1.default.resolve(__dirname, '../../lib/api.json')); +const uniInjectPluginOptions = { + exclude: [...uni_cli_shared_1.COMMON_EXCLUDE], + 'uni.': [ + '@dcloudio/uni-mp-weibo', + ((method) => apiJson.includes(method)), + ], + // 兼容 wx 对象 + // 'wx.': [ + // '@dcloudio/uni-mp-weibo', + // ((method: string) => apiJson.includes(method)) as any, // API白名单 + // ], + getApp: ['@dcloudio/uni-mp-weibo', 'getApp'], + getCurrentPages: ['@dcloudio/uni-mp-weibo', 'getCurrentPages'], + UniServiceJSBridge: ['@dcloudio/uni-mp-weibo', 'UniServiceJSBridge'], + UniViewJSBridge: ['@dcloudio/uni-mp-weibo', 'UniViewJSBridge'], +}; +function uniInjectPlugin() { + let resolvedConfig; + const callback = function (imports, mod) { + const styles = mod[0] === '@dcloudio/uni-mp-weibo' && + uni_cli_shared_1.WEIBO_API_DEPS_CSS[mod[1]]; + if (!styles) { + return; + } + styles.forEach((style) => { + if ((0, uni_cli_shared_1.isCombineBuiltInCss)(resolvedConfig)) { + uni_cli_shared_1.buildInCssSet.add(style); + } + else { + if (!imports.has(style)) { + imports.set(style, `import '${style}';`); + } + } + }); + }; + let injectPlugin; + return { + name: 'uni:h5-inject', + apply: 'build', + enforce: 'post', + configResolved(config) { + resolvedConfig = config; + const enableTreeShaking = (0, uni_cli_shared_1.isEnableTreeShaking)((0, uni_cli_shared_1.parseManifestJsonOnce)(process.env.UNI_INPUT_DIR)); + if (!enableTreeShaking) { + // 不启用摇树优化,移除 wx、uni 等 API 配置 + delete uniInjectPluginOptions['wx.']; + delete uniInjectPluginOptions['uni.']; + } + injectPlugin = (0, uni_cli_shared_1.uniViteInjectPlugin)('uni:h5-inject', (0, shared_1.extend)(uniInjectPluginOptions, { + callback, + })); + }, + transform(code, id) { + return injectPlugin.transform.call(this, code, id); + }, + }; +} +exports.uniInjectPlugin = uniInjectPlugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/mainJs.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/mainJs.d.ts new file mode 100644 index 00000000000..5ff2015fca3 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/mainJs.d.ts @@ -0,0 +1 @@ +export declare function uniMainJsPlugin(): import("vite").Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/mainJs.js b/packages/uni-mp-weibo-vite/dist/plugins/mainJs.js new file mode 100644 index 00000000000..c272c6d1ea0 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/mainJs.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniMainJsPlugin = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const utils_1 = require("../utils"); +function uniMainJsPlugin() { + return (0, uni_cli_shared_1.defineUniMainJsPlugin)((opts) => { + let runSSR = false; + return { + name: 'uni:h5-main-js', + enforce: 'pre', + configResolved(config) { + runSSR = + (0, uni_cli_shared_1.isSsr)(config.command, config) || (0, utils_1.isSsrManifest)(config.command, config); + }, + transform(code, id, options) { + if (opts.filter(id)) { + if (!runSSR) { + code = code.includes('createSSRApp') + ? createApp(code) + : createLegacyApp(code); + } + else { + code = (0, utils_1.isSSR)(options) + ? createSSRServerApp(code) + : createSSRClientApp(code); + } + code = `import './${uni_cli_shared_1.PAGES_JSON_JS}';${code}`; + return { + code, + map: this.getCombinedSourcemap(), + }; + } + }, + }; + }); +} +exports.uniMainJsPlugin = uniMainJsPlugin; +function createApp(code) { + return `import { plugin as __plugin } from '@dcloudio/uni-mp-weibo';${code.replace('createSSRApp', 'createVueApp as createSSRApp')};createApp().app.use(__plugin).mount("#app");`; +} +function createLegacyApp(code) { + return `import { plugin as __plugin } from '@dcloudio/uni-mp-weibo';function createApp(rootComponent,rootProps){return createVueApp(rootComponent, rootProps).use(__plugin)};${code.replace('createApp', 'createVueApp')}`; +} +function createSSRClientApp(code) { + return `import { plugin as __plugin } from '@dcloudio/uni-mp-weibo';import { UNI_SSR, UNI_SSR_STORE } from '@dcloudio/uni-shared';${code};const { app: __app, store: __store } = createApp();__app.use(__plugin);__store && window[UNI_SSR] && window[UNI_SSR][UNI_SSR_STORE] && __store.replaceState(window[UNI_SSR][UNI_SSR_STORE]);__app.router.isReady().then(() => __app.mount("#app"));`; +} +function createSSRServerApp(code) { + return code; +} diff --git a/packages/uni-mp-weibo-vite/dist/plugins/manifestJson.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/manifestJson.d.ts new file mode 100644 index 00000000000..566dc0015c5 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/manifestJson.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function uniManifestJsonPlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/manifestJson.js b/packages/uni-mp-weibo-vite/dist/plugins/manifestJson.js new file mode 100644 index 00000000000..65ba580b45c --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/manifestJson.js @@ -0,0 +1,102 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniManifestJsonPlugin = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const defaultRouter = { + mode: 'hash', + base: '/', + assets: 'assets', + routerBase: '/', +}; +const defaultAsync = { + loading: 'AsyncLoading', + error: 'AsyncError', + delay: 200, + timeout: 60000, + suspensible: true, +}; +function uniManifestJsonPlugin() { + return (0, uni_cli_shared_1.defineUniManifestJsonPlugin)((opts) => { + let resolvedConfig; + return { + name: 'uni:h5-manifest-json', + enforce: 'pre', + configResolved(config) { + defaultRouter.assets = config.build.assetsDir; + resolvedConfig = config; + }, + transform(code, id) { + if (!opts.filter(id)) { + return; + } + const manifest = (0, uni_cli_shared_1.parseJson)(code); + const { debug, h5 } = manifest; + const router = { + ...defaultRouter, + ...{ base: resolvedConfig.base }, + ...((h5 && h5.router) || {}), + }; + if (!router.base) { + router.base = '/'; + } + /** + * ssr时base和访问域名不一致导致跳到错误链接,其实应该区分server和client的部署路径,后续有需求可以加上 + */ + router.routerBase = new URL(router.base, 'http://localhost').pathname; + const async = { ...defaultAsync, ...((h5 && h5.async) || {}) }; + const networkTimeout = (0, uni_cli_shared_1.normalizeNetworkTimeout)(manifest.networkTimeout); + const sdkConfigs = (h5 && h5.sdkConfigs) || {}; + const qqMapKey = sdkConfigs.maps && sdkConfigs.maps.qqmap && sdkConfigs.maps.qqmap.key; + const googleMapKey = sdkConfigs.maps && + sdkConfigs.maps.google && + sdkConfigs.maps.google.key; + const aMapKey = sdkConfigs.maps && sdkConfigs.maps.amap && sdkConfigs.maps.amap.key; + const aMapSecurityJsCode = sdkConfigs.maps && + sdkConfigs.maps.amap && + sdkConfigs.maps.amap.securityJsCode; + const aMapServiceHost = sdkConfigs.maps && + sdkConfigs.maps.amap && + sdkConfigs.maps.amap.serviceHost; + let locale = manifest.locale; + locale = locale && locale.toUpperCase() !== 'AUTO' ? locale : ''; + const i18nOptions = (0, uni_cli_shared_1.initI18nOptions)(process.env.UNI_PLATFORM, process.env.UNI_INPUT_DIR, false, false); + const fallbackLocale = (i18nOptions && i18nOptions.locale) || ''; + const flexDirection = (manifest['app'] && + manifest['app'].nvue && + manifest['app'].nvue['flex-direction']) || + 'column'; + const platformConfig = manifest[process.env.UNI_PLATFORM === 'app' + ? 'app-plus' + : process.env.UNI_PLATFORM] || {}; + return { + code: `export const appId = ${JSON.stringify(manifest.appid || '')} + export const appName = ${JSON.stringify(manifest.name || '')} + export const appVersion = ${JSON.stringify(manifest.versionName || '')} + export const appVersionCode = ${JSON.stringify(manifest.versionCode || '')} + + export const debug = ${!!debug} + export const nvue = ${JSON.stringify({ + 'flex-direction': flexDirection, + })} + export const networkTimeout = ${JSON.stringify(networkTimeout)} + // h5 + export const router = ${JSON.stringify(router)} + export const async = ${JSON.stringify(async)} + export const qqMapKey = ${JSON.stringify(qqMapKey)} + export const googleMapKey = ${JSON.stringify(googleMapKey)} + export const aMapKey = ${JSON.stringify(aMapKey)} + export const aMapSecurityJsCode = ${JSON.stringify(aMapSecurityJsCode)} + export const aMapServiceHost = ${JSON.stringify(aMapServiceHost)} + export const sdkConfigs = ${JSON.stringify(sdkConfigs)} + export const locale = '${locale}' + export const fallbackLocale = '${fallbackLocale}' + export const darkmode = ${platformConfig.darkmode || 'false'} + export const themeConfig = ${JSON.stringify((0, uni_cli_shared_1.normalizeThemeConfigOnce)(platformConfig))} + `, + map: { mappings: '' }, + }; + }, + }; + }); +} +exports.uniManifestJsonPlugin = uniManifestJsonPlugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/pagesJson.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/pagesJson.d.ts new file mode 100644 index 00000000000..3a1ebd5af2a --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/pagesJson.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function uniPagesJsonPlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/pagesJson.js b/packages/uni-mp-weibo-vite/dist/plugins/pagesJson.js new file mode 100644 index 00000000000..56e5c524c3b --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/pagesJson.js @@ -0,0 +1,225 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniPagesJsonPlugin = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const utils_1 = require("../utils"); +function uniPagesJsonPlugin() { + return (0, uni_cli_shared_1.defineUniPagesJsonPlugin)((opts) => { + return { + name: 'uni:h5-pages-json', + enforce: 'pre', + transform(code, id, opt) { + if (opts.filter(id)) { + const { resolvedConfig } = opts; + const ssr = (0, utils_1.isSSR)(opt); + return { + code: registerGlobalCode(resolvedConfig, ssr) + + generatePagesJsonCode(ssr, code, resolvedConfig), + map: { mappings: '' }, + }; + } + }, + }; + }); +} +exports.uniPagesJsonPlugin = uniPagesJsonPlugin; +function generatePagesJsonCode(ssr, jsonStr, config) { + const globalName = getGlobal(ssr); + const pagesJson = (0, uni_cli_shared_1.normalizePagesJson)(jsonStr, process.env.UNI_PLATFORM); + const { importLayoutComponentsCode, defineLayoutComponentsCode } = generateLayoutComponentsCode(globalName, pagesJson); + const definePagesCode = generatePagesDefineCode(pagesJson, config); + const uniRoutesCode = generateRoutes(globalName, pagesJson, config); + const uniConfigCode = generateConfig(globalName, pagesJson, config); + const cssCode = generateCssCode(config); + return ` +import { defineAsyncComponent, resolveComponent, createVNode, withCtx, openBlock, createBlock } from 'vue' +import { PageComponent, useI18n, setupWindow, setupPage } from '@dcloudio/uni-mp-weibo' +import { appId, appName, appVersion, appVersionCode, debug, networkTimeout, router, async, sdkConfigs, qqMapKey, googleMapKey, aMapKey, aMapSecurityJsCode, aMapServiceHost, nvue, locale, fallbackLocale, darkmode, themeConfig } from './${uni_cli_shared_1.MANIFEST_JSON_JS}' +const locales = import.meta.globEager('./locale/*.json') +${importLayoutComponentsCode} +const extend = Object.assign +${cssCode} +${uniConfigCode} +${defineLayoutComponentsCode} +${definePagesCode} +${uniRoutesCode} +${config.command === 'serve' ? hmrCode : ''} +export {} +`; +} +const hmrCode = `if(import.meta.hot){ + import.meta.hot.on('invalidate', (data) => { + import.meta.hot.invalidate() + }) +}`; +function getGlobal(ssr) { + return ssr ? 'global' : 'window'; +} +// 兼容 wx 对象 +function registerGlobalCode(config, ssr) { + const name = getGlobal(ssr); + const enableTreeShaking = (0, uni_cli_shared_1.isEnableTreeShaking)((0, uni_cli_shared_1.parseManifestJsonOnce)(process.env.UNI_INPUT_DIR)); + if (enableTreeShaking && config.command === 'build' && !ssr) { + // 非 SSR 的发行模式,补充全局 uni 对象 + return `import { upx2px, getApp } from '@dcloudio/uni-mp-weibo';${name}.uni = {};${name}.wx = {};${name}.rpx2px = upx2px`; + } + return ` +import {uni,upx2px,getCurrentPages,getApp,UniServiceJSBridge,UniViewJSBridge} from '@dcloudio/uni-mp-weibo' +${name}.getApp = getApp +${name}.getCurrentPages = getCurrentPages +${name}.wx = uni +${name}.uni = uni +${name}.UniViewJSBridge = UniViewJSBridge +${name}.UniServiceJSBridge = UniServiceJSBridge +${name}.rpx2px = upx2px +${name}.__setupPage = (com)=>setupPage(com) +`; +} +function generateCssCode(config) { + const define = config.define; + const cssFiles = [uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'base.css']; + if (config.isProduction) { + cssFiles.push(uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'shadow.css'); + } + // if (define.__UNI_FEATURE_PAGES__) { + cssFiles.push(uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'async.css'); + // } + if (define.__UNI_FEATURE_RESPONSIVE__) { + cssFiles.push(uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'layout.css'); + } + if (define.__UNI_FEATURE_NAVIGATIONBAR__) { + cssFiles.push(uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'pageHead.css'); + } + if (define.__UNI_FEATURE_TABBAR__) { + cssFiles.push(uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'tabBar.css'); + } + if (define.__UNI_FEATURE_NVUE__) { + cssFiles.push(uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'nvue.css'); + } + if (define.__UNI_FEATURE_PULL_DOWN_REFRESH__) { + cssFiles.push(uni_cli_shared_1.MP_WEIBO_FRAMEWORK_STYLE_PATH + 'pageRefresh.css'); + } + if (define.__UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__) { + cssFiles.push(uni_cli_shared_1.BASE_COMPONENTS_STYLE_PATH + 'input.css'); + } + const enableTreeShaking = (0, uni_cli_shared_1.isEnableTreeShaking)((0, uni_cli_shared_1.parseManifestJsonOnce)(process.env.UNI_INPUT_DIR)); + if (config.command === 'serve' || !enableTreeShaking) { + // 开发模式或禁用摇树优化,自动添加所有API相关css + Object.keys(uni_cli_shared_1.WEIBO_API_DEPS_CSS).forEach((name) => { + const styles = uni_cli_shared_1.WEIBO_API_DEPS_CSS[name]; + styles.forEach((style) => { + if (!cssFiles.includes(style)) { + cssFiles.push(style); + } + }); + }); + } + return cssFiles.map((file) => `import '${file}'`).join('\n'); +} +function generateLayoutComponentsCode(globalName, pagesJson) { + const windowNames = { + topWindow: -1, + leftWindow: -2, + rightWindow: -3, + }; + let importLayoutComponentsCode = ''; + let defineLayoutComponentsCode = `${globalName}.__uniLayout = ${globalName}.__uniLayout || {}\n`; + Object.keys(windowNames).forEach((name) => { + const windowConfig = pagesJson[name]; + if (windowConfig && windowConfig.path) { + importLayoutComponentsCode += `import ${name} from './${windowConfig.path}'\n`; + defineLayoutComponentsCode += `${globalName}.__uniConfig.${name}.component = setupWindow(${name},${windowNames[name]})\n`; + } + }); + return { + importLayoutComponentsCode, + defineLayoutComponentsCode, + }; +} +function generatePageDefineCode(pageOptions) { + let pagePathWithExtname = (0, uni_cli_shared_1.normalizePagePath)(pageOptions.path, 'h5'); + if (!pagePathWithExtname) { + // 不存在时,仍引用,此时编译会报错文件不存在 + pagePathWithExtname = pageOptions.path + '.vue'; + } + const pageIdent = (0, uni_cli_shared_1.normalizeIdentifier)(pageOptions.path); + return `const ${pageIdent}Loader = ()=>import('./${pagePathWithExtname}').then(com => setupPage(com.default || com)) +const ${pageIdent} = defineAsyncComponent(extend({loader:${pageIdent}Loader},AsyncComponentOptions))`; +} +function generatePagesDefineCode(pagesJson, _config) { + const { pages } = pagesJson; + return (`const AsyncComponentOptions = { + delay: async.delay, + timeout: async.timeout, + suspensible: async.suspensible + } + if(async.loading){ + AsyncComponentOptions.loadingComponent = { + name:'SystemAsyncLoading', + render(){ + return createVNode(resolveComponent(async.loading)) + } + } + } + if(async.error){ + AsyncComponentOptions.errorComponent = { + name:'SystemAsyncError', + render(){ + return createVNode(resolveComponent(async.error)) + } + } + } + ` + pages.map((pageOptions) => generatePageDefineCode(pageOptions)).join('\n')); +} +function generatePageRoute({ path, meta }, _config) { + const { isEntry } = meta; + const alias = isEntry ? `\n alias:'/${path}',` : ''; + // 目前单页面未处理 query=>props + return `{ + path:'/${isEntry ? '' : path}',${alias} + component:{setup(){ const app = getApp(); const query = app && app.$route && app.$route.query || {}; return ()=>renderPage(${(0, uni_cli_shared_1.normalizeIdentifier)(path)},query)}}, + loader: ${(0, uni_cli_shared_1.normalizeIdentifier)(path)}Loader, + meta: ${JSON.stringify(meta)} +}`; +} +function generatePagesRoute(pagesRouteOptions, config) { + return pagesRouteOptions.map((pageOptions) => generatePageRoute(pageOptions, config)); +} +function generateRoutes(globalName, pagesJson, config) { + return ` +function renderPage(component,props){ + return (openBlock(), createBlock(PageComponent, null, {page: withCtx(() => [createVNode(component, extend({},props,{ref: "page"}), null, 512 /* NEED_PATCH */)]), _: 1 /* STABLE */})) +} +${globalName}.__uniRoutes=[${[ + ...generatePagesRoute((0, uni_cli_shared_1.normalizePagesRoute)(pagesJson), config), + ].join(',')}].map(uniRoute=>(uniRoute.meta.route = (uniRoute.alias || uniRoute.path).slice(1),uniRoute))`; +} +function generateConfig(globalName, pagesJson, config) { + delete pagesJson.pages; + delete pagesJson.subPackages; + delete pagesJson.subpackages; + pagesJson.compilerVersion = process.env.UNI_COMPILER_VERSION; + return `${globalName}.__uniConfig=extend(${JSON.stringify(pagesJson)},{ + appId, + appName, + appVersion, + appVersionCode, + async, + debug, + networkTimeout, + sdkConfigs, + qqMapKey, + googleMapKey, + aMapKey, + aMapSecurityJsCode, + aMapServiceHost, + nvue, + locale, + fallbackLocale, + locales:Object.keys(locales).reduce((res,name)=>{const locale=name.replace(/\\.\\/locale\\/(uni-app.)?(.*).json/,'$2');extend(res[locale]||(res[locale]={}),locales[name].default);return res},{}), + router, + darkmode, + themeConfig, +}) +`; +} diff --git a/packages/uni-mp-weibo-vite/dist/plugins/postVue.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/postVue.d.ts new file mode 100644 index 00000000000..d41c0a9aa49 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/postVue.d.ts @@ -0,0 +1,2 @@ +import { Plugin } from 'vite'; +export declare function uniPostVuePlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/postVue.js b/packages/uni-mp-weibo-vite/dist/plugins/postVue.js new file mode 100644 index 00000000000..ecc29862671 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/postVue.js @@ -0,0 +1,48 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniPostVuePlugin = void 0; +const path_1 = __importDefault(require("path")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const WXS_RE = /vue&type=(wxs|renderjs)/; +function uniPostVuePlugin() { + return { + name: 'uni:post-vue', + apply: 'serve', + enforce: 'post', + async transform(code, id) { + const { filename, query } = (0, uni_cli_shared_1.parseVueRequest)(id); + if (query.vue) { + return; + } + if (!uni_cli_shared_1.EXTNAME_VUE.includes(path_1.default.extname(filename))) { + return; + } + if (!WXS_RE.test(code)) { + return; + } + const hmrId = parseHmrId(code); + if (!hmrId) { + return; + } + // TODO 内部解决 @vitejs/plugin-vue 自定义块外链热刷的问题 + // https://github.com/vitejs/vite/blob/main/packages/plugin-vue/src/main.ts#L387 + // 没有增加 src=descriptor.id + // 包含外链 wxs,renderjs + code = code.replace(/vue&type=(wxs|renderjs)&index=([0-9]+)&src&/gi, (_, type, index) => { + return `vue&type=${type}&index=${index}&src=${hmrId}&`; + }); + return { + code: code, + map: null, + }; + }, + }; +} +exports.uniPostVuePlugin = uniPostVuePlugin; +function parseHmrId(code) { + const matches = code.match(/_sfc_main.__hmrId = "(.*)"/); + return matches && matches[1]; +} diff --git a/packages/uni-mp-weibo-vite/dist/plugins/renderjs.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/renderjs.d.ts new file mode 100644 index 00000000000..1d54e0d7769 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/renderjs.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function uniRenderjsPlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/renderjs.js b/packages/uni-mp-weibo-vite/dist/plugins/renderjs.js new file mode 100644 index 00000000000..829c75e6595 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/renderjs.js @@ -0,0 +1,45 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniRenderjsPlugin = void 0; +const debug_1 = __importDefault(require("debug")); +const compiler_sfc_1 = require("@vue/compiler-sfc"); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const debugRenderjs = (0, debug_1.default)('uni:h5-renderjs'); +function uniRenderjsPlugin() { + return { + name: 'uni:h5-renderjs', + transform(code, id) { + const { type, name } = (0, uni_cli_shared_1.parseRenderjs)(id); + if (!type) { + return; + } + debugRenderjs(id); + if (!name) { + this.error((0, uni_cli_shared_1.missingModuleName)(type, code)); + } + return `${(0, compiler_sfc_1.rewriteDefault)(code.replace(/module\.exports\s*=/, 'export default '), '_sfc_' + type)} +${type === 'renderjs' ? genRenderjsCode(name) : genWxsCode(name)}`; + }, + }; +} +exports.uniRenderjsPlugin = uniRenderjsPlugin; +function genRenderjsCode(name) { + return `export default Comp => { + if(!Comp.$renderjs){Comp.$renderjs = []} + Comp.$renderjs.push('${name}') + if(!Comp.mixins){Comp.mixins = []} + Comp.mixins.push({beforeCreate(){ this['${name}'] = this },mounted(){ this.$ownerInstance = this.$gcd(this, true) }}) + Comp.mixins.push(_sfc_renderjs) +}`; +} +function genWxsCode(name) { + return `export default Comp => { + if(!Comp.$wxs){Comp.$wxs = []} + Comp.$wxs.push('${name}') + if(!Comp.mixins){Comp.mixins = []} + Comp.mixins.push({beforeCreate(){ this['${name}'] = _sfc_wxs }}) +}`; +} diff --git a/packages/uni-mp-weibo-vite/dist/plugins/resolveId.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/resolveId.d.ts new file mode 100644 index 00000000000..df68c6f8d01 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/resolveId.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function uniResolveIdPlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/resolveId.js b/packages/uni-mp-weibo-vite/dist/plugins/resolveId.js new file mode 100644 index 00000000000..237cbf9dde0 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/resolveId.js @@ -0,0 +1,39 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniResolveIdPlugin = void 0; +const path_1 = __importDefault(require("path")); +const debug_1 = __importDefault(require("debug")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const utils_1 = require("../utils"); +const debugResolve = (0, debug_1.default)('uni:resolve'); +function uniResolveIdPlugin() { + const resolveCache = {}; + return { + name: 'uni:h5-resolve-id', + enforce: 'pre', + config() { + resolveCache[utils_1.ownerModuleName] = (0, uni_cli_shared_1.resolveBuiltIn)(path_1.default.join(utils_1.ownerModuleName, 'dist/uni-mp-weibo.es.js')); + resolveCache['@dcloudio/uni-h5-vue'] = (0, uni_cli_shared_1.resolveBuiltIn)(path_1.default.join('@dcloudio/uni-h5-vue', `dist/vue.runtime.${process.env.VITEST ? 'cjs' : 'esm'}.js`)); + }, + resolveId(id) { + if (id === 'vue') { + id = '@dcloudio/uni-h5-vue'; + } + const cache = resolveCache[id]; + if (cache) { + debugResolve('cache', id, cache); + return cache; + } + if (id.startsWith('@dcloudio/uni-mp-weibo/style')) { + return (resolveCache[id] = (0, uni_cli_shared_1.resolveBuiltIn)(id)); + } + if (id.startsWith('@dcloudio/uni-components/style')) { + return (resolveCache[id] = (0, uni_cli_shared_1.resolveBuiltIn)(id)); + } + }, + }; +} +exports.uniResolveIdPlugin = uniResolveIdPlugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/setup.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/setup.d.ts new file mode 100644 index 00000000000..6521d039f80 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/setup.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function uniSetupPlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/setup.js b/packages/uni-mp-weibo-vite/dist/plugins/setup.js new file mode 100644 index 00000000000..9a721cc6f91 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/setup.js @@ -0,0 +1,35 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniSetupPlugin = void 0; +const path_1 = __importDefault(require("path")); +const debug_1 = __importDefault(require("debug")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const debugSetup = (0, debug_1.default)('uni:setup'); +function uniSetupPlugin() { + let appVuePath; + let resolvedConfig; + return { + name: 'uni:setup', + configResolved(config) { + resolvedConfig = config; + appVuePath = (0, uni_cli_shared_1.normalizePath)(path_1.default.resolve(process.env.UNI_INPUT_DIR, 'App.vue')); + }, + transform(code, id) { + const { filename, query } = (0, uni_cli_shared_1.parseVueRequest)(id); + if (filename === appVuePath && !query.vue) { + debugSetup(filename); + return { + code: code + + `;import { setupApp } from '@dcloudio/uni-mp-weibo';setupApp(_sfc_main);`, + map: (0, uni_cli_shared_1.withSourcemap)(resolvedConfig) + ? this.getCombinedSourcemap() + : null, + }; + } + }, + }; +} +exports.uniSetupPlugin = uniSetupPlugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/ssr.d.ts b/packages/uni-mp-weibo-vite/dist/plugins/ssr.d.ts new file mode 100644 index 00000000000..b3a28005a4c --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/ssr.d.ts @@ -0,0 +1,2 @@ +import type { Plugin } from 'vite'; +export declare function uniSSRPlugin(): Plugin; diff --git a/packages/uni-mp-weibo-vite/dist/plugins/ssr.js b/packages/uni-mp-weibo-vite/dist/plugins/ssr.js new file mode 100644 index 00000000000..aab32371ea7 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/plugins/ssr.js @@ -0,0 +1,67 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.uniSSRPlugin = void 0; +const path_1 = __importDefault(require("path")); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const utils_1 = require("../utils"); +const ENTRY_SERVER_JS = 'entry-server.js'; +function uniSSRPlugin() { + let entryServerJs; + let resolvedConfig; + const entryServerJsCode = (0, utils_1.generateSsrEntryServerCode)(); + return { + name: 'uni:h5-ssr', + config(userConfig, env) { + if ((0, uni_cli_shared_1.isSsr)(env.command, userConfig)) { + (0, utils_1.initSsrAliasOnce)(); + (0, utils_1.rewriteSsrVue)(); + (0, utils_1.rewriteSsrNativeTag)(); + (0, utils_1.rewriteSsrRenderStyle)(process.env.UNI_INPUT_DIR); + return { + resolve: { + alias: [ + { + find: 'vue', + replacement: (0, uni_cli_shared_1.resolveBuiltIn)('@dcloudio/uni-h5-vue/dist/vue.runtime.esm.js'), + }, + { + find: 'vue/server-renderer', + replacement: (0, uni_cli_shared_1.resolveBuiltIn)('@vue/server-renderer'), + }, + ], + }, + }; + } + }, + configResolved(config) { + resolvedConfig = config; + entryServerJs = path_1.default.join(process.env.UNI_INPUT_DIR, ENTRY_SERVER_JS); + if ((0, uni_cli_shared_1.isSsr)(resolvedConfig.command, resolvedConfig)) { + (0, utils_1.initSsrDefine)(resolvedConfig); + } + }, + resolveId(id) { + if (id.endsWith(ENTRY_SERVER_JS)) { + return entryServerJs; + } + }, + load(id) { + if (id.endsWith(ENTRY_SERVER_JS)) { + return entryServerJsCode; + } + }, + generateBundle(_options, bundle) { + const chunk = bundle['entry-server.js']; + if (chunk) { + chunk.code = + (0, utils_1.generateSsrDefineCode)(resolvedConfig, (0, uni_cli_shared_1.parseRpx2UnitOnce)(process.env.UNI_INPUT_DIR, process.env.UNI_PLATFORM)) + + '\n' + + chunk.code; + } + }, + }; +} +exports.uniSSRPlugin = uniSSRPlugin; diff --git a/packages/uni-mp-weibo-vite/dist/utils/constants.d.ts b/packages/uni-mp-weibo-vite/dist/utils/constants.d.ts new file mode 100644 index 00000000000..fd21868f8fe --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/constants.d.ts @@ -0,0 +1 @@ +export declare const ownerModuleName = "@dcloudio/uni-mp-weibo"; diff --git a/packages/uni-mp-weibo-vite/dist/utils/constants.js b/packages/uni-mp-weibo-vite/dist/utils/constants.js new file mode 100644 index 00000000000..4e8f0fc371b --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/constants.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ownerModuleName = void 0; +exports.ownerModuleName = '@dcloudio/uni-mp-weibo'; diff --git a/packages/uni-mp-weibo-vite/dist/utils/features.d.ts b/packages/uni-mp-weibo-vite/dist/utils/features.d.ts new file mode 100644 index 00000000000..8bb85870c7e --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/features.d.ts @@ -0,0 +1,2 @@ +import type { ConfigEnv, UserConfig } from 'vite'; +export declare function createDefine(command: ConfigEnv['command'], config: UserConfig): UserConfig['define']; diff --git a/packages/uni-mp-weibo-vite/dist/utils/features.js b/packages/uni-mp-weibo-vite/dist/utils/features.js new file mode 100644 index 00000000000..3f943766bef --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/features.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createDefine = void 0; +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const ssr_1 = require("./ssr"); +function createDefine(command, config) { + const platform = process.env.UNI_PLATFORM; + const inputDir = process.env.UNI_INPUT_DIR; + return (0, uni_cli_shared_1.initFeatures)({ + inputDir, + command, + platform, + pagesJson: (0, uni_cli_shared_1.parsePagesJsonOnce)(inputDir, platform), + manifestJson: (0, uni_cli_shared_1.parseManifestJsonOnce)(inputDir), + ssr: (0, uni_cli_shared_1.isSsr)(command, config) || (0, ssr_1.isSsrManifest)(command, config), + }); +} +exports.createDefine = createDefine; diff --git a/packages/uni-mp-weibo-vite/dist/utils/index.d.ts b/packages/uni-mp-weibo-vite/dist/utils/index.d.ts new file mode 100644 index 00000000000..dde0501d617 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/index.d.ts @@ -0,0 +1,3 @@ +export * from './ssr'; +export * from './features'; +export * from './constants'; diff --git a/packages/uni-mp-weibo-vite/dist/utils/index.js b/packages/uni-mp-weibo-vite/dist/utils/index.js new file mode 100644 index 00000000000..b73358153a2 --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/index.js @@ -0,0 +1,19 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("./ssr"), exports); +__exportStar(require("./features"), exports); +__exportStar(require("./constants"), exports); diff --git a/packages/uni-mp-weibo-vite/dist/utils/ssr.d.ts b/packages/uni-mp-weibo-vite/dist/utils/ssr.d.ts new file mode 100644 index 00000000000..e378c2bc9ea --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/ssr.d.ts @@ -0,0 +1,16 @@ +import { Rpx2UnitOptions } from '@dcloudio/uni-shared'; +import type { ConfigEnv, ResolvedConfig, UserConfig } from 'vite'; +export declare const isSSR: (opt: { + ssr?: boolean; +} | boolean | undefined) => boolean; +export declare function isSsrManifest(command: ConfigEnv['command'], config: UserConfig | ResolvedConfig): boolean; +export declare const initSsrAliasOnce: () => void; +export declare function initSsrDefine(config: ResolvedConfig): typeof globalThis & { + __IMPORT_META_ENV_BASE_URL__: any; +}; +export declare function generateSsrDefineCode(config: ResolvedConfig, { unit, unitRatio, unitPrecision }: Rpx2UnitOptions): string; +export declare function generateSsrEntryServerCode(): string; +export declare function rewriteSsrVue(): void; +export declare function rewriteSsrResolve(): void; +export declare function rewriteSsrNativeTag(): void; +export declare function rewriteSsrRenderStyle(inputDir: string): void; diff --git a/packages/uni-mp-weibo-vite/dist/utils/ssr.js b/packages/uni-mp-weibo-vite/dist/utils/ssr.js new file mode 100644 index 00000000000..e7ad4db20ae --- /dev/null +++ b/packages/uni-mp-weibo-vite/dist/utils/ssr.js @@ -0,0 +1,171 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rewriteSsrRenderStyle = exports.rewriteSsrNativeTag = exports.rewriteSsrResolve = exports.rewriteSsrVue = exports.generateSsrEntryServerCode = exports.generateSsrDefineCode = exports.initSsrDefine = exports.initSsrAliasOnce = exports.isSsrManifest = exports.isSSR = void 0; +/* eslint-disable no-restricted-globals */ +const path_1 = __importDefault(require("path")); +const fs_1 = __importDefault(require("fs")); +const shared_1 = require("@vue/shared"); +const uni_shared_1 = require("@dcloudio/uni-shared"); +const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); +const transformPageHead_1 = require("../plugin/transforms/transformPageHead"); +// Temporal handling for 2.7 breaking change +const isSSR = (opt) => opt === undefined ? false : typeof opt === 'boolean' ? opt : opt?.ssr === true; +exports.isSSR = isSSR; +function isSsrManifest(command, config) { + if (command === 'build') { + return !!(config.build && config.build.ssrManifest); + } + return false; +} +exports.isSsrManifest = isSsrManifest; +const SSR_ALIAS = { + vue: '@dcloudio/uni-h5-vue', + 'vue/server-renderer': 'vue/server-renderer', + '@vue/server-renderer': '@vue/server-renderer', + '@dcloudio/uni-cloud': '@dcloudio/uni-cloud', + '@dcloudio/uni-mp-weibo': '@dcloudio/uni-mp-weibo', + '@dcloudio/uni-i18n': '@dcloudio/uni-i18n', + '@dcloudio/uni-shared': '@dcloudio/uni-shared', +}; +exports.initSsrAliasOnce = (0, uni_shared_1.once)(() => { + // 重写 package.json 的读取 + const oldJoin = path_1.default.join; + const alias = Object.keys(SSR_ALIAS).reduce((alias, key) => { + const newKey = oldJoin('node_modules', key, 'package.json'); + if (key.endsWith('vue/server-renderer')) { + alias[newKey] = path_1.default.join(path_1.default.dirname((0, uni_cli_shared_1.resolveBuiltIn)(SSR_ALIAS[key])), 'package.json'); + } + else { + alias[newKey] = (0, uni_cli_shared_1.resolveBuiltIn)(SSR_ALIAS[key] + '/package.json'); + } + return alias; + }, {}); + // console.log(alias) + path_1.default.join = (...paths) => { + let res = oldJoin.apply(path_1.default, paths); + if (res.endsWith('package.json')) { + const key = Object.keys(alias).find((key) => res.endsWith(key)); + if (key) { + res = alias[key]; + } + } + return res; + }; +}); +function initSsrDefine(config) { + return (0, shared_1.extend)(globalThis, { + __IMPORT_META_ENV_BASE_URL__: config.env.BASE_URL, + }); +} +exports.initSsrDefine = initSsrDefine; +function serializeDefine(define) { + let res = `{`; + for (const key in define) { + const val = define[key]; + res += `${JSON.stringify(key)}: ${(0, shared_1.isString)(val) ? `(${val})` : JSON.stringify(val)}, `; + } + return res + `}`; +} +function normalizeSsrDefine(config) { + const defines = (0, shared_1.extend)({ + __IMPORT_META_ENV_BASE_URL__: JSON.stringify(config.env.BASE_URL), + }, config.define); + delete defines['import.meta.env.LEGACY']; + return defines; +} +function generateSsrDefineCode(config, { unit, unitRatio, unitPrecision }) { + return fs_1.default + .readFileSync(path_1.default.join(__dirname, '../../lib/ssr/define.js'), 'utf8') + .replace('__DEFINES__', serializeDefine(normalizeSsrDefine(config))) + .replace('__UNIT__', JSON.stringify(unit)) + .replace('__UNIT_RATIO__', JSON.stringify(unitRatio)) + .replace('__UNIT_PRECISION__', JSON.stringify(unitPrecision)); +} +exports.generateSsrDefineCode = generateSsrDefineCode; +function generateSsrEntryServerCode() { + return fs_1.default.readFileSync(path_1.default.join(__dirname, '../../lib/ssr/entry-server.js'), 'utf8'); +} +exports.generateSsrEntryServerCode = generateSsrEntryServerCode; +function rewriteSsrVue() { + // 解决 @vue/server-renderer 中引入 vue 的映射 + require('module-alias').addAliases({ + vue: (0, uni_cli_shared_1.resolveBuiltIn)('@dcloudio/uni-h5-vue/dist/vue.runtime.cjs.js'), + 'vue/package.json': (0, uni_cli_shared_1.resolveBuiltIn)('@dcloudio/uni-h5-vue/package.json'), + }); + // TODO vite 2.7.0 版本会定制 require 的解析,解析后缓存的文件路径会被格式化,导致 windows 平台路径不一致,导致 cache 不生效 + if (require('os').platform() === 'win32') { + require('vue'); + const vuePath = require.resolve('vue'); + require.cache[(0, uni_cli_shared_1.normalizePath)(vuePath)] = require.cache[vuePath]; + } +} +exports.rewriteSsrVue = rewriteSsrVue; +function initResolveSyncOpts(opts) { + if (!opts) { + opts = {}; + } + if (!opts.paths) { + opts.paths = []; + } + if ((0, shared_1.isString)(opts.paths)) { + opts.paths = [opts.paths]; + } + if ((0, shared_1.isArray)(opts.paths)) { + opts.paths.push(...(0, uni_cli_shared_1.getBuiltInPaths)()); + } + return opts; +} +function rewriteSsrResolve() { + // 解决 ssr 时 __vite_ssr_import__("vue") 的映射 + const resolve = require(require.resolve('resolve', { + paths: [ + path_1.default.resolve(require.resolve('vite/package.json'), '../node_modules'), + ], + })); + const oldSync = resolve.sync; + resolve.sync = (id, opts) => { + if (id === 'vue') { + return (0, uni_cli_shared_1.resolveBuiltIn)(`@dcloudio/uni-h5-vue/dist/vue.runtime.cjs.js`); + } + else if (id === 'vue/package.json') { + return (0, uni_cli_shared_1.resolveBuiltIn)(`@dcloudio/uni-h5-vue/package.json`); + } + else if (id === 'vue/server-renderer/package.json') { + return (0, uni_cli_shared_1.resolveBuiltIn)(`@vue/server-renderer/package.json`); + } + return oldSync(id, initResolveSyncOpts(opts)); + }; +} +exports.rewriteSsrResolve = rewriteSsrResolve; +function rewriteSsrNativeTag() { + // @ts-ignore + const compilerDom = require((0, uni_cli_shared_1.resolveBuiltIn)('@vue/compiler-dom')); + // TODO compiler-ssr时,传入的 isNativeTag 会被 @vue/compiler-dom 的 isNativeTag 覆盖 + // https://github.com/vuejs/vue-next/blob/master/packages/compiler-ssr/src/index.ts#L36 + compilerDom.parserOptions.isNativeTag = uni_shared_1.isH5NativeTag; + // ssr 时,ssrTransformComponent 执行时机很早,导致无法正确重写 tag,故通过 resolveComponentType 解决重写 + const oldResolveComponentType = compilerDom.resolveComponentType; + const newResolveComponentType = function (node, context, ssr) { + (0, transformPageHead_1.transformPageHead)(node, context); + (0, uni_cli_shared_1.transformMatchMedia)(node, context); + (0, uni_cli_shared_1.transformH5BuiltInComponents)(node, context); + return oldResolveComponentType(node, context, ssr); + }; + compilerDom.resolveComponentType = newResolveComponentType; +} +exports.rewriteSsrNativeTag = rewriteSsrNativeTag; +function rewriteSsrRenderStyle(inputDir) { + const { unit, unitRatio, unitPrecision } = (0, uni_cli_shared_1.parseRpx2UnitOnce)(inputDir, 'h5'); + const rpx2unit = (0, uni_shared_1.createRpx2Unit)(unit, unitRatio, unitPrecision); + const shared = require('@vue/shared'); + const oldStringifyStyle = shared.stringifyStyle; + shared.stringifyStyle = (styles) => rpx2unit(oldStringifyStyle(styles)); + const serverRender = require('@vue/server-renderer'); + const oldSsrRenderStyle = serverRender.ssrRenderStyle; + // 仅对字符串类型做转换,非字符串类型,通过 stringifyStyle 转换 + serverRender.ssrRenderStyle = (raw) => (0, shared_1.isString)(raw) ? rpx2unit(oldSsrRenderStyle(raw)) : oldSsrRenderStyle(raw); +} +exports.rewriteSsrRenderStyle = rewriteSsrRenderStyle; diff --git a/packages/uni-mp-weibo-vite/lib/api.json b/packages/uni-mp-weibo-vite/lib/api.json new file mode 100644 index 00000000000..93c22cf8298 --- /dev/null +++ b/packages/uni-mp-weibo-vite/lib/api.json @@ -0,0 +1,179 @@ +[ + "$emit", + "$off", + "$on", + "$once", + "API_OFF_KEYBOARD_HEIGHT_CHANGE", + "API_ON_KEYBOARD_HEIGHT_CHANGE", + "addInterceptor", + "addPhoneContact", + "arrayBufferToBase64", + "base64ToArrayBuffer", + "canIUse", + "canvasGetImageData", + "canvasPutImageData", + "canvasToTempFilePath", + "checkSession", + "chooseFile", + "chooseImage", + "chooseLocation", + "chooseVideo", + "clearStorage", + "clearStorageSync", + "closePreviewImage", + "closeSocket", + "connectSocket", + "createAnimation", + "createCameraContext", + "createCanvasContext", + "createInnerAudioContext", + "createIntersectionObserver", + "createLivePlayerContext", + "createMapContext", + "createMediaQueryObserver", + "createSelectorQuery", + "createVideoContext", + "downloadFile", + "getAppBaseInfo", + "getClipboardData", + "getDeviceInfo", + "getEnterOptionsSync", + "getFileInfo", + "getImageInfo", + "getLaunchOptionsSync", + "getLeftWindowStyle", + "getLocale", + "getLocation", + "getNetworkType", + "getProvider", + "getPushClientId", + "getRealPath", + "getRecorderManager", + "getRightWindowStyle", + "getSavedFileInfo", + "getSavedFileList", + "getScreenBrightness", + "getSelectedTextRange", + "getStorage", + "getStorageInfo", + "getStorageInfoSync", + "getStorageSync", + "getSystemInfo", + "getSystemInfoSync", + "getTopWindowStyle", + "getUserInfo", + "getVideoInfo", + "getWindowInfo", + "hideKeyboard", + "hideLeftWindow", + "hideLoading", + "hideNavigationBarLoading", + "hideRightWindow", + "hideTabBar", + "hideTabBarRedDot", + "hideToast", + "hideTopWindow", + "interceptors", + "invokePushCallback", + "loadFontFace", + "login", + "makePhoneCall", + "navigateBack", + "navigateTo", + "offAccelerometerChange", + "offAppHide", + "offAppShow", + "offCompassChange", + "offError", + "offKeyboardHeightChange", + "offLocationChange", + "offLocationChangeError", + "offNetworkStatusChange", + "offPageNotFound", + "offPushMessage", + "offThemeChange", + "offUnhandledRejection", + "offWindowResize", + "onAccelerometerChange", + "onAppHide", + "onAppShow", + "onCompassChange", + "onCreateVueApp", + "onError", + "onGyroscopeChange", + "onKeyboardHeightChange", + "onLocaleChange", + "onLocationChange", + "onLocationChangeError", + "onMemoryWarning", + "onNetworkStatusChange", + "onPageNotFound", + "onPushMessage", + "onSocketClose", + "onSocketError", + "onSocketMessage", + "onSocketOpen", + "onTabBarMidButtonTap", + "onThemeChange", + "onUnhandledRejection", + "onUserCaptureScreen", + "onWindowResize", + "openDocument", + "openLocation", + "pageScrollTo", + "preloadPage", + "previewImage", + "reLaunch", + "redirectTo", + "removeInterceptor", + "removeSavedFile", + "removeStorage", + "removeStorageSync", + "removeTabBarBadge", + "request", + "saveFile", + "saveImageToPhotosAlbum", + "saveVideoToPhotosAlbum", + "scanCode", + "sendSocketMessage", + "setClipboardData", + "setKeepScreenOn", + "setLeftWindowStyle", + "setLocale", + "setNavigationBarColor", + "setNavigationBarTitle", + "setPageMeta", + "setRightWindowStyle", + "setScreenBrightness", + "setStorage", + "setStorageSync", + "setTabBarBadge", + "setTabBarItem", + "setTabBarStyle", + "setTopWindowStyle", + "showActionSheet", + "showLeftWindow", + "showLoading", + "showModal", + "showNavigationBarLoading", + "showRightWindow", + "showTabBar", + "showTabBarRedDot", + "showToast", + "showTopWindow", + "startAccelerometer", + "startCompass", + "startGyroscope", + "startLocationUpdate", + "startPullDownRefresh", + "stopAccelerometer", + "stopCompass", + "stopGyroscope", + "stopLocationUpdate", + "stopPullDownRefresh", + "switchTab", + "uploadFile", + "upx2px", + "vibrateLong", + "vibrateShort" +] \ No newline at end of file diff --git a/packages/uni-mp-weibo-vite/lib/ssr/cloudfunction.js b/packages/uni-mp-weibo-vite/lib/ssr/cloudfunction.js new file mode 100644 index 00000000000..3207d6434aa --- /dev/null +++ b/packages/uni-mp-weibo-vite/lib/ssr/cloudfunction.js @@ -0,0 +1,25 @@ +'use strict' +const fs = require('fs') +const path = require('path') +const template = fs.readFileSync( + path.join(__dirname, './server/index.html'), + 'utf-8' +) +const manifest = require('./server/ssr-manifest.json') +const render = require('./server/entry-server.js').render + +exports.main = async (event) => { + const [appHtml, preloadLinks, appContext] = await render(event.path, manifest) + const html = template + .replace(``, preloadLinks) + .replace(``, appHtml) + .replace(``, appContext) + return { + mpserverlessComposedResponse: true, // 使用阿里云返回集成响应是需要此字段为true + statusCode: 200, + headers: { + 'content-type': 'text/html', + }, + body: html, + } +} diff --git a/packages/uni-mp-weibo-vite/lib/ssr/define.js b/packages/uni-mp-weibo-vite/lib/ssr/define.js new file mode 100644 index 00000000000..d07266ed47e --- /dev/null +++ b/packages/uni-mp-weibo-vite/lib/ssr/define.js @@ -0,0 +1,27 @@ +!(function () { + const defines = __DEFINES__ + Object.keys(defines).forEach((key) => { + const segments = key.split('.') + let target = global + for (let i = 0; i < segments.length; i++) { + const segment = segments[i] + if (i === segments.length - 1) { + target[segment] = defines[key] + } else { + target = target[segment] || (target[segment] = {}) + } + } + }); + const { createRpx2Unit } = require('@dcloudio/uni-shared') + const rpx2unit = createRpx2Unit(__UNIT__, __UNIT_RATIO__, __UNIT_PRECISION__) + const shared = require('@vue/shared') + const oldStringifyStyle = shared.stringifyStyle + shared.stringifyStyle = (styles) => rpx2unit(oldStringifyStyle(styles)) + const serverRender = require('@vue/server-renderer') + const oldSsrRenderStyle = serverRender.ssrRenderStyle + serverRender.ssrRenderStyle = (raw) => + shared.isString(raw) + ? rpx2unit(oldSsrRenderStyle(raw)) + : oldSsrRenderStyle(raw) + +})(); diff --git a/packages/uni-mp-weibo-vite/lib/ssr/entry-server.js b/packages/uni-mp-weibo-vite/lib/ssr/entry-server.js new file mode 100644 index 00000000000..ff17d9423d8 --- /dev/null +++ b/packages/uni-mp-weibo-vite/lib/ssr/entry-server.js @@ -0,0 +1,99 @@ +import { createApp } from './main' +import { renderToString } from '@vue/server-renderer' +import { + UNI_SSR, + UNI_SSR_DATA, + UNI_SSR_STORE, + UNI_SSR_TITLE, + UNI_SSR_GLOBAL_DATA, +} from '@dcloudio/uni-shared' +import { plugin } from '@dcloudio/uni-mp-weibo' +import { getSsrGlobalData } from '@dcloudio/uni-app' + +export async function render(url, manifest = {}) { + const { app, store } = createApp() + app.use(plugin) + const router = app.router + + // set the router to the desired URL before rendering + await router.push(url) + await router.isReady() + + // passing SSR context object which will be available via useSSRContext() + // @vitejs/plugin-vue injects code into a component's setup() that registers + // itself on ctx.modules. After the render, ctx.modules would contain all the + // components that have been instantiated during this render call. + const ctx = {} + const appHtml = await renderToString(app, ctx) + + // the SSR manifest generated by Vite contains module -> chunk/asset mapping + // which we can then use to determine what files need to be preloaded for this + // request. + const preloadLinks = renderPreloadLinks(ctx.modules, manifest) + // the SSR context + const __uniSSR = ctx[UNI_SSR] || (ctx[UNI_SSR] = {}) + if (!__uniSSR[UNI_SSR_DATA]) { + __uniSSR[UNI_SSR_DATA] = {} + } + __uniSSR[UNI_SSR_GLOBAL_DATA] = getSsrGlobalData() + if (store) { + __uniSSR[UNI_SSR_STORE] = store.state + } + const appContext = renderAppContext(ctx) + const title = ctx[UNI_SSR_TITLE] || '' + const headMeta = renderHeadMeta(ctx) + return { + title, + headMeta, + preloadLinks, + appHtml, + appContext, + } +} + +function renderPreloadLinks(modules, manifest) { + let links = '' + const seen = new Set() + modules.forEach((id) => { + const files = manifest[id] + if (files) { + files.forEach((file) => { + if (!seen.has(file)) { + seen.add(file) + links += renderPreloadLink(file) + } + }) + } + }) + return links +} + +function renderPreloadLink(file) { + if (file.endsWith('.js')) { + return '' + } else if (file.endsWith('.css')) { + return '' + } else { + // TODO + return '' + } +} + +function renderAppContext(ctx) { + return `` +} + +function renderHeadMeta(ctx) { + if (!ctx.__teleportBuffers || !ctx.__teleportBuffers.head) { + return '' + } + return ctx.__teleportBuffers.head + .map((buffer) => + buffer + .toString() + .replace(/\s+data-v-[a-f0-9]{8}/gi, '') + .replace('', '') + .replace('', '') + ) + .join('\n') +} diff --git a/packages/uni-mp-weibo-vite/package.json b/packages/uni-mp-weibo-vite/package.json new file mode 100644 index 00000000000..22ac7c20273 --- /dev/null +++ b/packages/uni-mp-weibo-vite/package.json @@ -0,0 +1,44 @@ +{ + "name": "@dcloudio/uni-mp-weibo-vite", + "version": "3.0.0-alpha-3080220230428002", + "description": "uni-mp-weibo-vite", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "lib" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/dcloudio/uni-app.git", + "directory": "packages/uni-mp-weibo-vite" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "license": "Apache-2.0", + "gitHead": "33e807d66e1fe47e2ee08ad9c59247e37b8884da", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-alpha-3080220230428002", + "@dcloudio/uni-shared": "3.0.0-alpha-3080220230428002", + "@rollup/pluginutils": "^4.2.0", + "@vue/compiler-dom": "3.2.47", + "@vue/compiler-sfc": "3.2.47", + "@vue/server-renderer": "3.2.47", + "@vue/shared": "3.2.47", + "debug": "^4.3.3", + "fs-extra": "^10.0.0", + "mime": "^3.0.0", + "module-alias": "^2.2.2" + }, + "devDependencies": { + "@types/debug": "^4.1.7", + "@types/fs-extra": "^9.0.13", + "@types/mime": "^2.0.3", + "@types/module-alias": "^2.0.1", + "@types/resolve": "^1.20.2", + "@vue/compiler-core": "3.2.47", + "esbuild": "^0.17.5", + "vue": "3.2.47" + } +} diff --git a/packages/uni-mp-weibo-vite/src/index.ts b/packages/uni-mp-weibo-vite/src/index.ts new file mode 100644 index 00000000000..ef1f1c1a82b --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/index.ts @@ -0,0 +1,35 @@ +import { + isVueSfcFile, + uniCssScopedPlugin, + UNI_EASYCOM_EXCLUDE, +} from '@dcloudio/uni-cli-shared' +import { uniH5Plugin } from './plugin' +import { uniCssPlugin } from './plugins/css' +import { uniEasycomPlugin } from './plugins/easycom' +import { uniInjectPlugin } from './plugins/inject' +import { uniMainJsPlugin } from './plugins/mainJs' +import { uniManifestJsonPlugin } from './plugins/manifestJson' +import { uniPagesJsonPlugin } from './plugins/pagesJson' +import { uniPostVuePlugin } from './plugins/postVue' +import { uniRenderjsPlugin } from './plugins/renderjs' +import { uniResolveIdPlugin } from './plugins/resolveId' +import { uniSetupPlugin } from './plugins/setup' +import { uniSSRPlugin } from './plugins/ssr' + +export default [ + uniEasycomPlugin({ exclude: UNI_EASYCOM_EXCLUDE }), + uniCssScopedPlugin({ + filter: (id) => isVueSfcFile(id) && !id.endsWith('App.vue'), + }), + uniResolveIdPlugin(), + uniMainJsPlugin(), + uniManifestJsonPlugin(), + uniPagesJsonPlugin(), + uniInjectPlugin(), + uniCssPlugin(), + uniSSRPlugin(), + uniSetupPlugin(), + uniRenderjsPlugin(), + uniH5Plugin(), + uniPostVuePlugin(), +] diff --git a/packages/uni-mp-weibo-vite/src/plugin/config.ts b/packages/uni-mp-weibo-vite/src/plugin/config.ts new file mode 100644 index 00000000000..c4c9a5d32e4 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/config.ts @@ -0,0 +1,118 @@ +import os from 'os' +import fs from 'fs' +import path from 'path' +import type { Plugin, ResolvedConfig, ServerOptions } from 'vite' +import { + isInHBuilderX, + normalizePath, + getDevServerOptions, + resolveMainPathOnce, + parseManifestJsonOnce, + initPostcssPlugin, + parseRpx2UnitOnce, + isSsr, +} from '@dcloudio/uni-cli-shared' +import { createDefine } from '../utils' +import { esbuildPrePlugin } from './esbuild/esbuildPrePlugin' +import { external } from './configureServer/ssr' +import { extend, hasOwn } from '@vue/shared' +export function createConfig(options: { + resolvedConfig: ResolvedConfig | null +}): Plugin['config'] { + return function config(config, env) { + const inputDir = process.env.UNI_INPUT_DIR + if (isInHBuilderX()) { + if (!fs.existsSync(path.resolve(inputDir, 'index.html'))) { + console.error(`请确认您的项目模板是否支持vue3:根目录缺少 index.html`) + process.exit() + } + } + + const server: ServerOptions = { + host: true, + hmr: { + // mac 内置浏览器版本较低不支持 globalThis,而 overlay 使用了 globalThis + overlay: + os.platform() !== 'win32' + ? process.env.UNI_H5_BROWSER !== 'builtin' + : true, + }, + fs: { strict: false }, + watch: { + ignored: [ + '**/uniCloud-aliyun/**', + '**/uniCloud-tcb/**', + '**/uni_modules/uniCloud/**', + normalizePath(path.join(inputDir, 'unpackage/**')), + normalizePath(path.join(inputDir, 'dist/**')), + ], + }, + // eslint-disable-next-line no-restricted-syntax + ...getDevServerOptions(parseManifestJsonOnce(inputDir)), + } + + if ((server.port as unknown as string) === '') { + delete server.port + } + + const { server: userServer } = config + if (userServer) { + if (hasOwn(userServer, 'host')) { + server.host = userServer.host + } + if (hasOwn(userServer, 'fs')) { + extend(server.fs!, userServer.fs) + } + if (hasOwn(userServer, 'watch')) { + extend(server.watch!, userServer.watch) + } + } + + return { + css: { + postcss: { + plugins: initPostcssPlugin({ + uniApp: parseRpx2UnitOnce(inputDir, process.env.UNI_PLATFORM), + }), + }, + }, + optimizeDeps: { + entries: resolveMainPathOnce(inputDir), + exclude: external, + esbuildOptions: { + plugins: [esbuildPrePlugin()], + }, + }, + define: createDefine(env.command, config), + server, + ssr: { + external, + }, + build: { + rollupOptions: { + // resolveSSRExternal 会判定package.json,hbx 工程可能没有,通过 rollup 来配置 + external: isSsr(env.command, config) ? external : [], + output: { + chunkFileNames(chunkInfo) { + const { assetsDir } = options.resolvedConfig!.build + if (chunkInfo.facadeModuleId) { + const dirname = path.relative( + inputDir, + path.dirname(chunkInfo.facadeModuleId) + ) + if (dirname) { + return path.posix.join( + assetsDir, + normalizePath(dirname).replace(/\//g, '-') + + '-[name].[hash].js' + ) + } + } + return path.posix.join(assetsDir, '[name].[hash].js') + }, + }, + }, + }, + } + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/configureServer/index.ts b/packages/uni-mp-weibo-vite/src/plugin/configureServer/index.ts new file mode 100644 index 00000000000..7a87c52e034 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/configureServer/index.ts @@ -0,0 +1,24 @@ +import { + getRouterOptions, + parseManifestJsonOnce, +} from '@dcloudio/uni-cli-shared' +import type { Plugin } from 'vite' +import { uniTimestampMiddleware } from './middlewares/timestamp' +import { initSSR } from './ssr' +import { initStatic } from './static' + +export function createConfigureServer(): Plugin['configureServer'] { + return function (server) { + initSSR(server) + + const routerOptions = getRouterOptions( + parseManifestJsonOnce(process.env.UNI_INPUT_DIR) + ) + if (routerOptions.mode === 'history') { + server.middlewares.use(uniTimestampMiddleware(server)) + } + return () => { + initStatic(server) + } + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/configureServer/middlewares/static.ts b/packages/uni-mp-weibo-vite/src/plugin/configureServer/middlewares/static.ts new file mode 100644 index 00000000000..f23ff2ffcd1 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/configureServer/middlewares/static.ts @@ -0,0 +1,100 @@ +import fs, { Stats } from 'fs' +import url from 'url' + +import mime from 'mime/lite' +import { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from 'http' + +function normalizeFile(filename: string, isEtag: boolean) { + const stats = fs.statSync(filename) + return { + stats, + headers: normalizeHeaders(filename, stats, isEtag), + } +} + +function normalizeHeaders(filename: string, stats: Stats, isEtag: boolean) { + const headers: OutgoingHttpHeaders = { + 'Content-Length': stats.size, + 'Content-Type': mime.getType(filename) || '', + 'Last-Modified': stats.mtime.toUTCString(), + } + if (isEtag) { + headers['ETag'] = `W/"${stats.size}-${stats.mtime.getTime()}"` + } + return headers +} + +function send( + req: IncomingMessage, + res: ServerResponse, + filename: string, + stats: Stats, + headers: OutgoingHttpHeaders +) { + let code = 200 + // eslint-disable-next-line no-restricted-syntax + headers = { ...headers } + const opts: { + end?: number + start?: number + } = {} + for (const key in headers) { + const value = res.getHeader(key) + if (value) { + headers[key] = value + } + } + if (res.getHeader('content-type')) { + headers['Content-Type'] = res.getHeader('content-type') + } + if (req.headers.range) { + code = 206 + const [x, y] = req.headers.range.replace('bytes=', '').split('-') + const end = (opts.end = parseInt(y, 10) || stats.size - 1) + const start = (opts.start = parseInt(x, 10) || 0) + if (start >= stats.size || end >= stats.size) { + res.setHeader('Content-Range', `bytes */${stats.size}`) + res.statusCode = 416 + return res.end() + } + headers['Content-Range'] = `bytes ${start}-${end}/${stats.size}` + headers['Content-Length'] = end - start + 1 + headers['Accept-Ranges'] = 'bytes' + } + res.writeHead(code, headers) + fs.createReadStream(filename, opts).pipe(res) +} + +interface UniStaticMiddlewareOptions { + etag: boolean + resolve: (pathname: string) => string | void +} + +export type NextHandler = () => void | Promise + +export function uniStaticMiddleware(opts: UniStaticMiddlewareOptions) { + const isEtag = !!opts.etag + return function staticMiddleware( + req: IncomingMessage, + res: ServerResponse, + next: NextHandler + ) { + const pathname = url.parse(req.url!).pathname + if (!pathname) { + return next() + } + const filename = opts.resolve(pathname) + if (!filename) { + return next() + } + const data = normalizeFile(filename, isEtag) + if (!data) { + return next() + } + if (isEtag && req.headers['if-none-match'] === data.headers['ETag']) { + res.writeHead(304) + return res.end() + } + return send(req, res, filename, data.stats, data.headers) + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/configureServer/middlewares/timestamp.ts b/packages/uni-mp-weibo-vite/src/plugin/configureServer/middlewares/timestamp.ts new file mode 100644 index 00000000000..785a48cdcd8 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/configureServer/middlewares/timestamp.ts @@ -0,0 +1,39 @@ +import { parse as parseUrl } from 'url' +import { IncomingMessage, ServerResponse } from 'http' +import type { ViteDevServer } from 'vite' +import { NextHandler } from './static' +import path from 'path' +import { EXTNAME_VUE_RE } from '@dcloudio/uni-cli-shared' + +export function uniTimestampMiddleware(server: ViteDevServer) { + return async function timestampMiddleware( + req: IncomingMessage, + _: ServerResponse, + next: NextHandler + ) { + // 当页面被作为组件引用时,会导致history刷新该页面直接显示js代码,因为该页面已被缓存为了module, + // https://github.com/vitejs/vite/blob/702d50315535c189151c67d33e4a22124f926bed/packages/vite/src/node/server/transformRequest.ts#L52 + // /pages/tabBar/API/API + let { url } = req + if (url) { + const base = server.config.base + const parsed = parseUrl(url) + let newUrl = url + if ((parsed.pathname || '/').startsWith(base)) { + newUrl = newUrl.replace(base, '/') + } + if ( + !path.extname(newUrl) && + !newUrl.endsWith('/') && + !newUrl.includes('?') + ) { + const module = await server.moduleGraph.getModuleByUrl(newUrl) + if (module && module.file && EXTNAME_VUE_RE.test(module.file)) { + // /pages/tabBar/API/API => /pages/tabBar/API/API?__t__=time + req.url = url + '?__t__=' + Date.now() + } + } + } + next() + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/configureServer/ssr.ts b/packages/uni-mp-weibo-vite/src/plugin/configureServer/ssr.ts new file mode 100644 index 00000000000..2a89bc8c41d --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/configureServer/ssr.ts @@ -0,0 +1,58 @@ +import type { ViteDevServer } from 'vite' + +export const external = [ + '@dcloudio/uni-app', + '@dcloudio/uni-app-plus', + '@dcloudio/uni-cloud', + '@dcloudio/uni-components', + '@dcloudio/uni-mp-webo', + '@dcloudio/uni-h5-vue', + '@dcloudio/uni-i18n', + '@dcloudio/uni-mp-alipay', + '@dcloudio/uni-mp-baidu', + '@dcloudio/uni-mp-kuaishou', + '@dcloudio/uni-mp-lark', + '@dcloudio/uni-mp-qq', + '@dcloudio/uni-mp-toutiao', + '@dcloudio/uni-mp-weixin', + '@dcloudio/uni-quickapp-webview', + '@dcloudio/uni-shared', + '@dcloudio/uni-stat', + '@dcloudio/uni-stacktracey', + '@vue/shared', + 'vue', + 'vue-i18n', + 'vue-router', + 'vuex', + // dev + '@dcloudio/types', + '@dcloudio/uni-automator', + '@dcloudio/uni-cli-shared', + '@dcloudio/vite-plugin-uni', + 'autoprefixer', + 'typescript', + 'vite', +] + +export function initSSR(server: ViteDevServer) { + const { ssrLoadModule } = server + let added = false + server.ssrLoadModule = (url) => { + const res = ssrLoadModule(url) + if (!added) { + // HBuilderX项目,根目录可能没有package.json,导致 ssrExternals 不生效 + added = true + if ((server as any)._ssrExternals) { + const { _ssrExternals } = server as unknown as { + _ssrExternals: string[] + } + external.forEach((module) => { + if (!_ssrExternals.includes(module)) { + _ssrExternals.push(module) + } + }) + } + } + return res + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/configureServer/static.ts b/packages/uni-mp-weibo-vite/src/plugin/configureServer/static.ts new file mode 100644 index 00000000000..448f3b3f842 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/configureServer/static.ts @@ -0,0 +1,65 @@ +import fs from 'fs' +import path from 'path' +import debug from 'debug' +import type { Connect, ViteDevServer } from 'vite' +import { createFilter } from '@rollup/pluginutils' +import { + isImportRequest, + isInternalRequest, + normalizePath, + PUBLIC_DIR, +} from '@dcloudio/uni-cli-shared' + +import { uniStaticMiddleware } from './middlewares/static' + +const debugStatic = debug('uni:static') +/** + * devServer时提供static等目录的静态资源服务 + * @param server + * @param param + */ +export const initStatic = (server: ViteDevServer) => { + const filter = createPublicFileFilter() + const serve = uniStaticMiddleware({ + etag: true, + resolve(pathname) { + if (!filter(pathname)) { + return + } + const filename = path.join(process.env.UNI_INPUT_DIR, pathname) + if (fs.existsSync(filename)) { + debugStatic(filename, 'success') + return filename + } else { + debugStatic(filename, 'fail') + } + }, + }) + const viteServePublicMiddlewareIndex = server.middlewares.stack.findIndex( + (middleware) => { + return ( + (middleware.handle as Function).name === 'viteServePublicMiddleware' + ) + } + ) + // 替换 vite 自带的 public middleware + if (viteServePublicMiddlewareIndex > -1) { + server.middlewares.stack.splice(viteServePublicMiddlewareIndex, 1, { + route: '', + handle: ((req, res, next) => { + if (isImportRequest(req.url!) || isInternalRequest(req.url!)) { + return next() + } + return serve(req, res, next) + }) as Connect.NextHandleFunction, + }) + } +} + +export function createPublicFileFilter(base: string = '/') { + const publicDir = normalizePath(path.join(base, PUBLIC_DIR + '/**/*')) + const uniModulesDir = normalizePath( + path.join(base, 'uni_modules/*/' + PUBLIC_DIR + '/**/*') + ) + return createFilter([publicDir, uniModulesDir]) +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/esbuild/esbuildPrePlugin.ts b/packages/uni-mp-weibo-vite/src/plugin/esbuild/esbuildPrePlugin.ts new file mode 100644 index 00000000000..435b7cd875a --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/esbuild/esbuildPrePlugin.ts @@ -0,0 +1,27 @@ +import fs from 'fs' +import path from 'path' +import type { Loader, Plugin } from 'esbuild' +import { preJs } from '@dcloudio/uni-cli-shared' + +export const JS_TYPES_RE = /\.(?:j|t)sx?$|\.mjs$/ + +export function esbuildPrePlugin(): Plugin { + return { + name: 'uni:dep-scan', + setup(build) { + build.onLoad({ filter: JS_TYPES_RE }, ({ path: id }) => { + let ext = path.extname(id).slice(1) + if (ext === 'mjs') ext = 'js' + + let contents = fs.readFileSync(id, 'utf-8') + if (contents.includes('#endif')) { + contents = preJs(contents) + } + return { + loader: ext as Loader, + contents, + } + }) + }, + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/handleHotUpdate/index.ts b/packages/uni-mp-weibo-vite/src/plugin/handleHotUpdate/index.ts new file mode 100644 index 00000000000..9520e8e6d6e --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/handleHotUpdate/index.ts @@ -0,0 +1,97 @@ +import path from 'path' +import debug from 'debug' +import type { ModuleGraph, Plugin } from 'vite' +import { extend } from '@vue/shared' +import { + initEasycomsOnce, + initFeatures, + MANIFEST_JSON_JS, + normalizePath, + PAGES_JSON_JS, + parseManifestJson, + parsePagesJson, + resolveBuiltIn, + resolveComponentsLibPath, +} from '@dcloudio/uni-cli-shared' + +const debugHmr = debug('uni:hmr') + +async function invalidate(file: string, moduleGraph: ModuleGraph) { + const mods = await moduleGraph.getModulesByFile(normalizePath(file)) + if (mods && mods.size) { + ;[...mods].forEach((mod) => { + debugHmr('invalidate', mod.id) + moduleGraph.invalidateModule(mod) + }) + } +} +let invalidateFiles: string[] +export function createHandleHotUpdate(): Plugin['handleHotUpdate'] { + return async function ({ file, server }) { + const inputDir = process.env.UNI_INPUT_DIR + const platform = process.env.UNI_PLATFORM + if (!invalidateFiles) { + invalidateFiles = [ + path.resolve(inputDir, PAGES_JSON_JS), + path.resolve(inputDir, MANIFEST_JSON_JS), + resolveBuiltIn('@dcloudio/uni-mp-weibo/dist/uni-mp-weibo.es.js'), + ] + try { + invalidateFiles.push(resolveBuiltIn('vite/dist/client/env.mjs')) + } catch (e) {} + } + // TODO 目前简单处理,当pages.json,manifest.json发生变化,就直接刷新,理想情况下,应该区分变化的内容,仅必要时做整页面刷新 + const isPagesJson = file.endsWith('pages.json') + const isManifestJson = file.endsWith('manifest.json') + if (!isPagesJson && !isManifestJson) { + return + } + debugHmr(file) + const pagesJson = parsePagesJson(inputDir, platform) + // 更新define + const { + define, + server: { middlewareMode }, + } = server.config + extend( + define!, + initFeatures({ + inputDir, + command: 'serve', + platform, + pagesJson, + manifestJson: parseManifestJson(inputDir), + ssr: !!middlewareMode, + }) + ) + debugHmr('define', define) + if (isPagesJson) { + const easycom = pagesJson.easycom || {} + const { options, refresh } = initEasycomsOnce(inputDir, { + dirs: [resolveComponentsLibPath()], + platform, + }) + if ( + !equal( + { autoscan: easycom.autoscan, custom: easycom.custom }, + { autoscan: options.autoscan, custom: options.custom } + ) + ) { + refresh() + } + } + // 当pages.json,manifest.json发生变化时,作废pages.json.js缓存 + for (const file of invalidateFiles) { + await invalidate(file, server.moduleGraph) + } + server.ws.send({ + type: 'full-reload', + path: '*', + }) + return [] + } +} + +function equal(obj1: Record, obj2: Record) { + return JSON.stringify(obj1) === JSON.stringify(obj2) +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/index.ts b/packages/uni-mp-weibo-vite/src/plugin/index.ts new file mode 100644 index 00000000000..949d21c0b26 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/index.ts @@ -0,0 +1,50 @@ +import type { ResolvedConfig } from 'vite' +import fs from 'fs' +import path from 'path' +import { preCss, UniVitePlugin } from '@dcloudio/uni-cli-shared' +import { createHandleHotUpdate } from './handleHotUpdate' +import { createTransformIndexHtml } from './transformIndexHtml' +import { createConfigureServer } from './configureServer' +import { createUni } from './uni' + +import { createConfig } from './config' +import { isString } from '@vue/shared' + +export function uniH5Plugin(): UniVitePlugin { + const configOptions: { + resolvedConfig: ResolvedConfig | null + } = { + resolvedConfig: null, + } + rewriteReadFileSync() + return { + name: 'uni:h5', + uni: createUni(), + config: createConfig(configOptions), + configResolved(config) { + configOptions.resolvedConfig = config + }, + configureServer: createConfigureServer(), + handleHotUpdate: createHandleHotUpdate(), + transformIndexHtml: createTransformIndexHtml(), + } +} +/** + * 重写 readFileSync + * 目前主要解决 scss 文件被 @import 的条件编译 + */ +function rewriteReadFileSync() { + const { readFileSync } = fs + fs.readFileSync = ((filepath, options) => { + const content = readFileSync(filepath, options) + if ( + isString(filepath) && + isString(content) && + path.extname(filepath) === '.scss' && + content.includes('#endif') + ) { + return preCss(content) + } + return content + }) as typeof fs['readFileSync'] +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/transformIndexHtml/index.ts b/packages/uni-mp-weibo-vite/src/plugin/transformIndexHtml/index.ts new file mode 100644 index 00000000000..bbc1de274c7 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/transformIndexHtml/index.ts @@ -0,0 +1,25 @@ +import type { Plugin } from 'vite' + +import { parseManifestJsonOnce } from '@dcloudio/uni-cli-shared' + +export function createTransformIndexHtml(): Plugin['transformIndexHtml'] { + return async function (html) { + const manifestJson = parseManifestJsonOnce(process.env.UNI_INPUT_DIR) + const title = manifestJson.h5?.title || manifestJson.name || '' + return { + html: html.replace(/(.*?)<\/title>/, `<title>${title}`), + tags: + process.env.NODE_ENV === 'development' + ? [ + { + tag: 'script', + children: `if (typeof globalThis === 'undefined') { + window.globalThis = window +}`, + injectTo: 'head-prepend', + }, + ] + : [], + } + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/transforms/transformPageHead.ts b/packages/uni-mp-weibo-vite/src/plugin/transforms/transformPageHead.ts new file mode 100644 index 00000000000..62565bf87cf --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/transforms/transformPageHead.ts @@ -0,0 +1,20 @@ +import { checkElementNodeTag } from '@dcloudio/uni-cli-shared' +import { ElementNode, NodeTransform } from '@vue/compiler-core' + +export const transformPageHead: NodeTransform = (node, context) => { + if (checkElementNodeTag(node, 'page-meta')) { + const headNode = node.children.find((child) => + checkElementNodeTag(child, 'head') + ) as ElementNode + if (headNode) { + headNode.tag = 'page-meta-head' + } + return + } + if ( + checkElementNodeTag(node, 'head') && + checkElementNodeTag(context.parent, 'page-meta') + ) { + ;(node as ElementNode).tag = 'page-meta-head' + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugin/uni.ts b/packages/uni-mp-weibo-vite/src/plugin/uni.ts new file mode 100644 index 00000000000..8bff224b03d --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugin/uni.ts @@ -0,0 +1,33 @@ +import { + transformH5BuiltInComponents, + transformMatchMedia, + transformPageHead, + transformTapToClick, + transformUniH5Jsx, + UniVitePlugin, +} from '@dcloudio/uni-cli-shared' +import { isH5NativeTag, isH5CustomElement } from '@dcloudio/uni-shared' +import { CompilerOptions } from '@vue/compiler-core' + +export const compilerOptions: CompilerOptions = { + isNativeTag: isH5NativeTag, + isCustomElement: isH5CustomElement, + nodeTransforms: [ + transformH5BuiltInComponents, + transformTapToClick, + transformMatchMedia, + transformPageHead, + ], +} + +export function createUni(): UniVitePlugin['uni'] { + return { + copyOptions: { + assets: ['hybrid/html/**/*', 'uni_modules/*/hybrid/html/**/*'], + }, + compilerOptions, + jsxOptions: { + babelPlugins: [transformUniH5Jsx], + }, + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/css.ts b/packages/uni-mp-weibo-vite/src/plugins/css.ts new file mode 100644 index 00000000000..452e1d71446 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/css.ts @@ -0,0 +1,166 @@ +import fs from 'fs' +import path from 'path' +import { normalizePath, Plugin, ResolvedConfig } from 'vite' + +import { + buildInCssSet, + minifyCSS, + getAssetHash, + resolveBuiltIn, + isExternalUrl, +} from '@dcloudio/uni-cli-shared' +import { OutputOptions } from 'rollup' +import { isFunction, isString } from '@vue/shared' + +function isCombineBuiltInCss(config: ResolvedConfig) { + return config.command === 'build' && config.build.cssCodeSplit +} + +export function uniCssPlugin(): Plugin { + let resolvedConfig: ResolvedConfig + let file = '' + let fileName = '' + return { + name: 'uni:h5-css', + apply: 'build', + enforce: 'pre', + configResolved(config) { + resolvedConfig = config + file = path.join(process.env.UNI_INPUT_DIR, 'uni.css') + }, + async generateBundle() { + if (!isCombineBuiltInCss(resolvedConfig) || !buildInCssSet.size) { + return + } + // 生成框架css(需要排序,避免生成不一样的内容) + const content = await minifyCSS( + generateBuiltInCssCode([...buildInCssSet].sort()), + resolvedConfig + ) + // @ts-ignore 'Buffer' only refers to a type, but is being used as a value here + const contentHash = getAssetHash(Buffer.from(content, 'utf-8')) + const assetFileNames = path.posix.join( + resolvedConfig.build.assetsDir, + '[name].[hash][extname]' + ) + fileName = assetFileNamesToFileName( + assetFileNames, + file, + contentHash, + content + ) + const name = normalizePath(path.relative(resolvedConfig.root, file)) + this.emitFile({ + name, + fileName, + type: 'asset', + source: content, + }) + }, + transformIndexHtml: { + enforce: 'post', + transform() { + if (!fileName) { + return + } + // 追加框架css + return [ + { + tag: 'link', + attrs: { + rel: 'stylesheet', + href: toPublicPath(fileName, resolvedConfig), + }, + injectTo: 'head-prepend', + }, + ] + }, + }, + } +} + +function toPublicPath(filename: string, config: ResolvedConfig) { + return isExternalUrl(filename) ? filename : config.base + filename +} + +function generateBuiltInCssCode(cssImports: string[]) { + return cssImports + .map((cssImport) => fs.readFileSync(resolveBuiltIn(cssImport), 'utf8')) + .join('\n') +} + +/** + * converts the source filepath of the asset to the output filename based on the assetFileNames option. \ + * this function imitates the behavior of rollup.js. \ + * https://rollupjs.org/guide/en/#outputassetfilenames + * + * @example + * ```ts + * const content = Buffer.from('text'); + * const fileName = assetFileNamesToFileName( + * 'assets/[name].[hash][extname]', + * '/path/to/file.txt', + * getAssetHash(content), + * content + * ) + * // fileName: 'assets/file.982d9e3e.txt' + * ``` + * + * @param assetFileNames filename pattern. e.g. `'assets/[name].[hash][extname]'` + * @param file filepath of the asset + * @param contentHash hash of the asset. used for `'[hash]'` placeholder + * @param content content of the asset. passed to `assetFileNames` if `assetFileNames` is a function + * @returns output filename + */ +export function assetFileNamesToFileName( + assetFileNames: Exclude, + file: string, + contentHash: string, + content: string | Buffer +): string { + const basename = path.basename(file) + + // placeholders for `assetFileNames` + // `hash` is slightly different from the rollup's one + const extname = path.extname(basename) + const ext = extname.slice(1) + const name = basename.slice(0, -extname.length) + const hash = contentHash + + if (isFunction(assetFileNames)) { + assetFileNames = assetFileNames({ + name: file, + source: content, + type: 'asset', + }) + if (!isString(assetFileNames)) { + throw new TypeError('assetFileNames must return a string') + } + } else if (!isString(assetFileNames)) { + throw new TypeError('assetFileNames must be a string or a function') + } + + const fileName = assetFileNames.replace( + /\[\w+\]/g, + (placeholder: string): string => { + switch (placeholder) { + case '[ext]': + return ext + + case '[extname]': + return extname + + case '[hash]': + return hash + + case '[name]': + return name + } + throw new Error( + `invalid placeholder ${placeholder} in assetFileNames "${assetFileNames}"` + ) + } + ) + + return fileName +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/easycom.ts b/packages/uni-mp-weibo-vite/src/plugins/easycom.ts new file mode 100644 index 00000000000..c0127cc10a4 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/easycom.ts @@ -0,0 +1,159 @@ +import path from 'path' +import type { Plugin } from 'vite' +import { createFilter, FilterPattern } from '@rollup/pluginutils' +import { camelize, capitalize } from '@vue/shared' + +import { COMPONENT_PREFIX, isBuiltInComponent } from '@dcloudio/uni-shared' +import { + MP_WEIBO_COMPONENTS_STYLE_PATH, + BASE_COMPONENTS_STYLE_PATH, + COMPONENT_DEPS_CSS, + parseVueRequest, + buildInCssSet, + isCombineBuiltInCss, + matchEasycom, + addImportDeclaration, + genResolveEasycomCode, + EXTNAME_VUE_TEMPLATE, +} from '@dcloudio/uni-cli-shared' + +const MP_WEIBO_COMPONENTS_PATH = '@dcloudio/uni-mp-weibo' + +const baseComponents = [ + 'audio', + 'button', + 'canvas', + 'checkbox', + 'checkbox-group', + 'editor', + 'form', + 'icon', + 'image', + 'input', + 'label', + 'movable-area', + 'movable-view', + 'navigator', + 'picker-view', + 'picker-view-column', + 'progress', + 'radio', + 'radio-group', + 'resize-sensor', + 'rich-text', + 'scroll-view', + 'slider', + 'swiper', + 'swiper-item', + 'switch', + 'text', + 'textarea', + 'view', +] + +interface UniEasycomPluginOptions { + include?: FilterPattern + exclude?: FilterPattern +} + +export function uniEasycomPlugin(options: UniEasycomPluginOptions): Plugin { + const filter = createFilter(options.include, options.exclude) + let needCombineBuiltInCss = false + return { + name: 'uni:h5-easycom', + configResolved(config) { + needCombineBuiltInCss = isCombineBuiltInCss(config) + }, + transform(code, id) { + if (!filter(id)) { + return + } + const { filename } = parseVueRequest(id) + if (!EXTNAME_VUE_TEMPLATE.includes(path.extname(filename))) { + return + } + if (!code.includes('_resolveComponent')) { + return + } + let i = 0 + const importDeclarations: string[] = [] + code = code.replace( + /_resolveComponent\("(.+?)"(, true)?\)/g, + (str, name) => { + if (name && !name.startsWith('_')) { + if (isBuiltInComponent(name)) { + name = name.replace(COMPONENT_PREFIX, '') + const local = `__syscom_${i++}` + if (needCombineBuiltInCss) { + // 发行模式下,应该将内置组件css输出到入口css中 + resolveBuiltInCssImport(name).forEach((cssImport) => + buildInCssSet.add(cssImport) + ) + return addImportDeclaration( + importDeclarations, + local, + MP_WEIBO_COMPONENTS_PATH, + capitalize(camelize(name)) + ) + } + return addBuiltInImportDeclaration( + importDeclarations, + local, + name + ) + } + const source = matchEasycom(name) + if (source) { + // 处理easycom组件优先级 + return genResolveEasycomCode( + importDeclarations, + str, + addImportDeclaration( + importDeclarations, + `__easycom_${i++}`, + source + ) + ) + } + } + return str + } + ) + if (importDeclarations.length) { + code = importDeclarations.join('') + code + } + return { + code, + map: null, + } + }, + } +} + +function resolveBuiltInCssImport(name: string) { + const cssImports: string[] = [] + if (baseComponents.includes(name)) { + cssImports.push(BASE_COMPONENTS_STYLE_PATH + name + '.css') + } else { + cssImports.push(MP_WEIBO_COMPONENTS_STYLE_PATH + name + '.css') + } + const deps = COMPONENT_DEPS_CSS[name as keyof typeof COMPONENT_DEPS_CSS] + deps && deps.forEach((dep) => cssImports.push(dep)) + return cssImports +} + +function addBuiltInImportDeclaration( + importDeclarations: string[], + local: string, + name: string +) { + resolveBuiltInCssImport(name).forEach((cssImport) => + importDeclarations.push(`import '${cssImport}';`) + ) + return addImportDeclaration( + importDeclarations, + local, + MP_WEIBO_COMPONENTS_PATH, + capitalize(camelize(name)) + ) +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/inject.ts b/packages/uni-mp-weibo-vite/src/plugins/inject.ts new file mode 100644 index 00000000000..1eaab68beea --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/inject.ts @@ -0,0 +1,82 @@ +import path from 'path' +import type { Plugin, ResolvedConfig } from 'vite' + +import { extend } from '@vue/shared' + +import { + WEIBO_API_DEPS_CSS, + COMMON_EXCLUDE, + InjectOptions, + buildInCssSet, + uniViteInjectPlugin, + isCombineBuiltInCss, + isEnableTreeShaking, + parseManifestJsonOnce, +} from '@dcloudio/uni-cli-shared' + +// eslint-disable-next-line no-restricted-globals +const apiJson = require(path.resolve(__dirname, '../../lib/api.json')) +const uniInjectPluginOptions: Partial = { + exclude: [...COMMON_EXCLUDE], + 'uni.': [ + '@dcloudio/uni-mp-weibo', + ((method: string) => apiJson.includes(method)) as any, // API白名单 + ], + // 兼容 wx 对象 + // 'wx.': [ + // '@dcloudio/uni-mp-weibo', + // ((method: string) => apiJson.includes(method)) as any, // API白名单 + // ], + getApp: ['@dcloudio/uni-mp-weibo', 'getApp'], + getCurrentPages: ['@dcloudio/uni-mp-weibo', 'getCurrentPages'], + UniServiceJSBridge: ['@dcloudio/uni-mp-weibo', 'UniServiceJSBridge'], + UniViewJSBridge: ['@dcloudio/uni-mp-weibo', 'UniViewJSBridge'], +} + +export function uniInjectPlugin(): Plugin { + let resolvedConfig: ResolvedConfig + const callback: InjectOptions['callback'] = function (imports, mod) { + const styles = + mod[0] === '@dcloudio/uni-mp-weibo' && + WEIBO_API_DEPS_CSS[mod[1] as keyof typeof WEIBO_API_DEPS_CSS] + if (!styles) { + return + } + styles.forEach((style) => { + if (isCombineBuiltInCss(resolvedConfig)) { + buildInCssSet.add(style) + } else { + if (!imports.has(style)) { + imports.set(style, `import '${style}';`) + } + } + }) + } + let injectPlugin: Plugin + + return { + name: 'uni:h5-inject', + apply: 'build', + enforce: 'post', + configResolved(config) { + resolvedConfig = config + const enableTreeShaking = isEnableTreeShaking( + parseManifestJsonOnce(process.env.UNI_INPUT_DIR) + ) + if (!enableTreeShaking) { + // 不启用摇树优化,移除 wx、uni 等 API 配置 + delete uniInjectPluginOptions['wx.'] + delete uniInjectPluginOptions['uni.'] + } + injectPlugin = uniViteInjectPlugin( + 'uni:h5-inject', + extend(uniInjectPluginOptions, { + callback, + }) + ) + }, + transform(code, id) { + return (injectPlugin.transform as Function).call(this, code, id) + }, + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/mainJs.ts b/packages/uni-mp-weibo-vite/src/plugins/mainJs.ts new file mode 100644 index 00000000000..c2897fe059a --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/mainJs.ts @@ -0,0 +1,60 @@ +import { + defineUniMainJsPlugin, + isSsr, + PAGES_JSON_JS, +} from '@dcloudio/uni-cli-shared' +import { isSSR, isSsrManifest } from '../utils' + +export function uniMainJsPlugin() { + return defineUniMainJsPlugin((opts) => { + let runSSR = false + return { + name: 'uni:h5-main-js', + enforce: 'pre', + configResolved(config) { + runSSR = + isSsr(config.command, config) || isSsrManifest(config.command, config) + }, + transform(code, id, options) { + if (opts.filter(id)) { + if (!runSSR) { + code = code.includes('createSSRApp') + ? createApp(code) + : createLegacyApp(code) + } else { + code = isSSR(options) + ? createSSRServerApp(code) + : createSSRClientApp(code) + } + code = `import './${PAGES_JSON_JS}';${code}` + return { + code, + map: this.getCombinedSourcemap(), + } + } + }, + } + }) +} + +function createApp(code: string) { + return `import { plugin as __plugin } from '@dcloudio/uni-mp-weibo';${code.replace( + 'createSSRApp', + 'createVueApp as createSSRApp' + )};createApp().app.use(__plugin).mount("#app");` +} + +function createLegacyApp(code: string) { + return `import { plugin as __plugin } from '@dcloudio/uni-mp-weibo';function createApp(rootComponent,rootProps){return createVueApp(rootComponent, rootProps).use(__plugin)};${code.replace( + 'createApp', + 'createVueApp' + )}` +} + +function createSSRClientApp(code: string) { + return `import { plugin as __plugin } from '@dcloudio/uni-mp-weibo';import { UNI_SSR, UNI_SSR_STORE } from '@dcloudio/uni-shared';${code};const { app: __app, store: __store } = createApp();__app.use(__plugin);__store && window[UNI_SSR] && window[UNI_SSR][UNI_SSR_STORE] && __store.replaceState(window[UNI_SSR][UNI_SSR_STORE]);__app.router.isReady().then(() => __app.mount("#app"));` +} + +function createSSRServerApp(code: string) { + return code +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/manifestJson.ts b/packages/uni-mp-weibo-vite/src/plugins/manifestJson.ts new file mode 100644 index 00000000000..5b530cf8ffc --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/manifestJson.ts @@ -0,0 +1,140 @@ +/* eslint-disable no-restricted-syntax */ +import type { Plugin, ResolvedConfig } from 'vite' + +import { + defineUniManifestJsonPlugin, + normalizeNetworkTimeout, + parseJson, + initI18nOptions, + normalizeThemeConfigOnce, +} from '@dcloudio/uni-cli-shared' + +const defaultRouter = { + mode: 'hash', + base: '/', + assets: 'assets', + routerBase: '/', +} + +const defaultAsync = { + loading: 'AsyncLoading', + error: 'AsyncError', + delay: 200, + timeout: 60000, + suspensible: true, +} + +export function uniManifestJsonPlugin(): Plugin { + return defineUniManifestJsonPlugin((opts) => { + let resolvedConfig: ResolvedConfig + return { + name: 'uni:h5-manifest-json', + enforce: 'pre', + configResolved(config) { + defaultRouter.assets = config.build.assetsDir + resolvedConfig = config + }, + transform(code, id) { + if (!opts.filter(id)) { + return + } + const manifest = parseJson(code) + const { debug, h5 } = manifest + const router = { + ...defaultRouter, + ...{ base: resolvedConfig.base }, + ...((h5 && h5.router) || {}), + } + if (!router.base) { + router.base = '/' + } + + /** + * ssr时base和访问域名不一致导致跳到错误链接,其实应该区分server和client的部署路径,后续有需求可以加上 + */ + router.routerBase = new URL(router.base, 'http://localhost').pathname + + const async = { ...defaultAsync, ...((h5 && h5.async) || {}) } + + const networkTimeout = normalizeNetworkTimeout(manifest.networkTimeout) + + const sdkConfigs = (h5 && h5.sdkConfigs) || {} + + const qqMapKey = + sdkConfigs.maps && sdkConfigs.maps.qqmap && sdkConfigs.maps.qqmap.key + + const googleMapKey = + sdkConfigs.maps && + sdkConfigs.maps.google && + sdkConfigs.maps.google.key + + const aMapKey = + sdkConfigs.maps && sdkConfigs.maps.amap && sdkConfigs.maps.amap.key + + const aMapSecurityJsCode = + sdkConfigs.maps && + sdkConfigs.maps.amap && + sdkConfigs.maps.amap.securityJsCode + + const aMapServiceHost = + sdkConfigs.maps && + sdkConfigs.maps.amap && + sdkConfigs.maps.amap.serviceHost + + let locale: string | null | undefined = manifest.locale + locale = locale && locale.toUpperCase() !== 'AUTO' ? locale : '' + + const i18nOptions = initI18nOptions( + process.env.UNI_PLATFORM, + process.env.UNI_INPUT_DIR, + false, + false + ) + const fallbackLocale = (i18nOptions && i18nOptions.locale) || '' + + const flexDirection = + (manifest['app'] && + manifest['app'].nvue && + manifest['app'].nvue['flex-direction']) || + 'column' + + const platformConfig = + manifest[ + process.env.UNI_PLATFORM === 'app' + ? 'app-plus' + : process.env.UNI_PLATFORM + ] || {} + + return { + code: `export const appId = ${JSON.stringify(manifest.appid || '')} + export const appName = ${JSON.stringify(manifest.name || '')} + export const appVersion = ${JSON.stringify(manifest.versionName || '')} + export const appVersionCode = ${JSON.stringify(manifest.versionCode || '')} + + export const debug = ${!!debug} + export const nvue = ${JSON.stringify({ + 'flex-direction': flexDirection, + })} + export const networkTimeout = ${JSON.stringify(networkTimeout)} + // h5 + export const router = ${JSON.stringify(router)} + export const async = ${JSON.stringify(async)} + export const qqMapKey = ${JSON.stringify(qqMapKey)} + export const googleMapKey = ${JSON.stringify(googleMapKey)} + export const aMapKey = ${JSON.stringify(aMapKey)} + export const aMapSecurityJsCode = ${JSON.stringify(aMapSecurityJsCode)} + export const aMapServiceHost = ${JSON.stringify(aMapServiceHost)} + export const sdkConfigs = ${JSON.stringify(sdkConfigs)} + export const locale = '${locale}' + export const fallbackLocale = '${fallbackLocale}' + export const darkmode = ${platformConfig.darkmode || 'false'} + export const themeConfig = ${JSON.stringify( + normalizeThemeConfigOnce(platformConfig) + )} + `, + map: { mappings: '' }, + } + }, + } + }) +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/pagesJson.ts b/packages/uni-mp-weibo-vite/src/plugins/pagesJson.ts new file mode 100644 index 00000000000..1314261f4ee --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/pagesJson.ts @@ -0,0 +1,291 @@ +import type { Plugin, ResolvedConfig } from 'vite' +import { + WEIBO_API_DEPS_CSS, + FEATURE_DEFINES, + MP_WEIBO_FRAMEWORK_STYLE_PATH, + BASE_COMPONENTS_STYLE_PATH, + normalizeIdentifier, + normalizePagesJson, + defineUniPagesJsonPlugin, + normalizePagesRoute, + normalizePagePath, + isEnableTreeShaking, + parseManifestJsonOnce, + MANIFEST_JSON_JS, +} from '@dcloudio/uni-cli-shared' +import { isSSR } from '../utils' + +export function uniPagesJsonPlugin(): Plugin { + return defineUniPagesJsonPlugin((opts) => { + return { + name: 'uni:h5-pages-json', + enforce: 'pre', + transform(code, id, opt) { + if (opts.filter(id)) { + const { resolvedConfig } = opts + const ssr = isSSR(opt) + return { + code: + registerGlobalCode(resolvedConfig, ssr) + + generatePagesJsonCode(ssr, code, resolvedConfig), + map: { mappings: '' }, + } + } + }, + } + }) +} + +function generatePagesJsonCode( + ssr: boolean | undefined, + jsonStr: string, + config: ResolvedConfig +) { + const globalName = getGlobal(ssr) + const pagesJson = normalizePagesJson(jsonStr, process.env.UNI_PLATFORM) + const { importLayoutComponentsCode, defineLayoutComponentsCode } = + generateLayoutComponentsCode(globalName, pagesJson) + const definePagesCode = generatePagesDefineCode(pagesJson, config) + const uniRoutesCode = generateRoutes(globalName, pagesJson, config) + const uniConfigCode = generateConfig(globalName, pagesJson, config) + const cssCode = generateCssCode(config) + + return ` +import { defineAsyncComponent, resolveComponent, createVNode, withCtx, openBlock, createBlock } from 'vue' +import { PageComponent, useI18n, setupWindow, setupPage } from '@dcloudio/uni-mp-weibo' +import { appId, appName, appVersion, appVersionCode, debug, networkTimeout, router, async, sdkConfigs, qqMapKey, googleMapKey, aMapKey, aMapSecurityJsCode, aMapServiceHost, nvue, locale, fallbackLocale, darkmode, themeConfig } from './${MANIFEST_JSON_JS}' +const locales = import.meta.globEager('./locale/*.json') +${importLayoutComponentsCode} +const extend = Object.assign +${cssCode} +${uniConfigCode} +${defineLayoutComponentsCode} +${definePagesCode} +${uniRoutesCode} +${config.command === 'serve' ? hmrCode : ''} +export {} +` +} + +const hmrCode = `if(import.meta.hot){ + import.meta.hot.on('invalidate', (data) => { + import.meta.hot.invalidate() + }) +}` + +function getGlobal(ssr?: boolean) { + return ssr ? 'global' : 'window' +} +// 兼容 wx 对象 +function registerGlobalCode(config: ResolvedConfig, ssr?: boolean) { + const name = getGlobal(ssr) + const enableTreeShaking = isEnableTreeShaking( + parseManifestJsonOnce(process.env.UNI_INPUT_DIR) + ) + + if (enableTreeShaking && config.command === 'build' && !ssr) { + // 非 SSR 的发行模式,补充全局 uni 对象 + return `import { upx2px, getApp } from '@dcloudio/uni-mp-weibo';${name}.uni = {};${name}.wx = {};${name}.rpx2px = upx2px` + } + + return ` +import {uni,upx2px,getCurrentPages,getApp,UniServiceJSBridge,UniViewJSBridge} from '@dcloudio/uni-mp-weibo' +${name}.getApp = getApp +${name}.getCurrentPages = getCurrentPages +${name}.wx = uni +${name}.uni = uni +${name}.UniViewJSBridge = UniViewJSBridge +${name}.UniServiceJSBridge = UniServiceJSBridge +${name}.rpx2px = upx2px +${name}.__setupPage = (com)=>setupPage(com) +` +} + +function generateCssCode(config: ResolvedConfig) { + const define = config.define! as FEATURE_DEFINES + const cssFiles = [MP_WEIBO_FRAMEWORK_STYLE_PATH + 'base.css'] + if (config.isProduction) { + cssFiles.push(MP_WEIBO_FRAMEWORK_STYLE_PATH + 'shadow.css') + } + // if (define.__UNI_FEATURE_PAGES__) { + cssFiles.push(MP_WEIBO_FRAMEWORK_STYLE_PATH + 'async.css') + // } + if (define.__UNI_FEATURE_RESPONSIVE__) { + cssFiles.push(MP_WEIBO_FRAMEWORK_STYLE_PATH + 'layout.css') + } + if (define.__UNI_FEATURE_NAVIGATIONBAR__) { + cssFiles.push(MP_WEIBO_FRAMEWORK_STYLE_PATH + 'pageHead.css') + } + if (define.__UNI_FEATURE_TABBAR__) { + cssFiles.push(MP_WEIBO_FRAMEWORK_STYLE_PATH + 'tabBar.css') + } + if (define.__UNI_FEATURE_NVUE__) { + cssFiles.push(MP_WEIBO_FRAMEWORK_STYLE_PATH + 'nvue.css') + } + if (define.__UNI_FEATURE_PULL_DOWN_REFRESH__) { + cssFiles.push(MP_WEIBO_FRAMEWORK_STYLE_PATH + 'pageRefresh.css') + } + if (define.__UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__) { + cssFiles.push(BASE_COMPONENTS_STYLE_PATH + 'input.css') + } + const enableTreeShaking = isEnableTreeShaking( + parseManifestJsonOnce(process.env.UNI_INPUT_DIR) + ) + if (config.command === 'serve' || !enableTreeShaking) { + // 开发模式或禁用摇树优化,自动添加所有API相关css + Object.keys(WEIBO_API_DEPS_CSS).forEach((name) => { + const styles = WEIBO_API_DEPS_CSS[name as keyof typeof WEIBO_API_DEPS_CSS] + styles.forEach((style) => { + if (!cssFiles.includes(style)) { + cssFiles.push(style) + } + }) + }) + } + return cssFiles.map((file) => `import '${file}'`).join('\n') +} + +function generateLayoutComponentsCode( + globalName: string, + pagesJson: UniApp.PagesJson +) { + const windowNames = { + topWindow: -1, + leftWindow: -2, + rightWindow: -3, + } + let importLayoutComponentsCode = '' + let defineLayoutComponentsCode = `${globalName}.__uniLayout = ${globalName}.__uniLayout || {}\n` + Object.keys(windowNames).forEach((name) => { + const windowConfig = pagesJson[name as keyof typeof windowNames] + if (windowConfig && windowConfig.path) { + importLayoutComponentsCode += `import ${name} from './${windowConfig.path}'\n` + defineLayoutComponentsCode += `${globalName}.__uniConfig.${name}.component = setupWindow(${name},${ + windowNames[name as keyof typeof windowNames] + })\n` + } + }) + + return { + importLayoutComponentsCode, + defineLayoutComponentsCode, + } +} + +function generatePageDefineCode(pageOptions: UniApp.PagesJsonPageOptions) { + let pagePathWithExtname = normalizePagePath(pageOptions.path, 'h5') + if (!pagePathWithExtname) { + // 不存在时,仍引用,此时编译会报错文件不存在 + pagePathWithExtname = pageOptions.path + '.vue' + } + const pageIdent = normalizeIdentifier(pageOptions.path) + return `const ${pageIdent}Loader = ()=>import('./${pagePathWithExtname}').then(com => setupPage(com.default || com)) +const ${pageIdent} = defineAsyncComponent(extend({loader:${pageIdent}Loader},AsyncComponentOptions))` +} + +function generatePagesDefineCode( + pagesJson: UniApp.PagesJson, + _config: ResolvedConfig +) { + const { pages } = pagesJson + return ( + `const AsyncComponentOptions = { + delay: async.delay, + timeout: async.timeout, + suspensible: async.suspensible + } + if(async.loading){ + AsyncComponentOptions.loadingComponent = { + name:'SystemAsyncLoading', + render(){ + return createVNode(resolveComponent(async.loading)) + } + } + } + if(async.error){ + AsyncComponentOptions.errorComponent = { + name:'SystemAsyncError', + render(){ + return createVNode(resolveComponent(async.error)) + } + } + } + ` + pages.map((pageOptions) => generatePageDefineCode(pageOptions)).join('\n') + ) +} + +function generatePageRoute( + { path, meta }: UniApp.UniRoute, + _config: ResolvedConfig +) { + const { isEntry } = meta + const alias = isEntry ? `\n alias:'/${path}',` : '' + // 目前单页面未处理 query=>props + return `{ + path:'/${isEntry ? '' : path}',${alias} + component:{setup(){ const app = getApp(); const query = app && app.$route && app.$route.query || {}; return ()=>renderPage(${normalizeIdentifier( + path + )},query)}}, + loader: ${normalizeIdentifier(path)}Loader, + meta: ${JSON.stringify(meta)} +}` +} + +function generatePagesRoute( + pagesRouteOptions: UniApp.UniRoute[], + config: ResolvedConfig +) { + return pagesRouteOptions.map((pageOptions) => + generatePageRoute(pageOptions, config) + ) +} + +function generateRoutes( + globalName: string, + pagesJson: UniApp.PagesJson, + config: ResolvedConfig +) { + return ` +function renderPage(component,props){ + return (openBlock(), createBlock(PageComponent, null, {page: withCtx(() => [createVNode(component, extend({},props,{ref: "page"}), null, 512 /* NEED_PATCH */)]), _: 1 /* STABLE */})) +} +${globalName}.__uniRoutes=[${[ + ...generatePagesRoute(normalizePagesRoute(pagesJson), config), + ].join( + ',' + )}].map(uniRoute=>(uniRoute.meta.route = (uniRoute.alias || uniRoute.path).slice(1),uniRoute))` +} + +function generateConfig( + globalName: string, + pagesJson: Record, + config: ResolvedConfig +) { + delete pagesJson.pages + delete pagesJson.subPackages + delete pagesJson.subpackages + pagesJson.compilerVersion = process.env.UNI_COMPILER_VERSION + return `${globalName}.__uniConfig=extend(${JSON.stringify(pagesJson)},{ + appId, + appName, + appVersion, + appVersionCode, + async, + debug, + networkTimeout, + sdkConfigs, + qqMapKey, + googleMapKey, + aMapKey, + aMapSecurityJsCode, + aMapServiceHost, + nvue, + locale, + fallbackLocale, + locales:Object.keys(locales).reduce((res,name)=>{const locale=name.replace(/\\.\\/locale\\/(uni-app.)?(.*).json/,'$2');extend(res[locale]||(res[locale]={}),locales[name].default);return res},{}), + router, + darkmode, + themeConfig, +}) +` +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/postVue.ts b/packages/uni-mp-weibo-vite/src/plugins/postVue.ts new file mode 100644 index 00000000000..9d804d6240b --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/postVue.ts @@ -0,0 +1,48 @@ +import path from 'path' +import { Plugin } from 'vite' + +import { EXTNAME_VUE, parseVueRequest } from '@dcloudio/uni-cli-shared' + +const WXS_RE = /vue&type=(wxs|renderjs)/ +export function uniPostVuePlugin(): Plugin { + return { + name: 'uni:post-vue', + apply: 'serve', + enforce: 'post', + async transform(code, id) { + const { filename, query } = parseVueRequest(id) + if (query.vue) { + return + } + if (!EXTNAME_VUE.includes(path.extname(filename))) { + return + } + if (!WXS_RE.test(code)) { + return + } + const hmrId = parseHmrId(code) + if (!hmrId) { + return + } + // TODO 内部解决 @vitejs/plugin-vue 自定义块外链热刷的问题 + // https://github.com/vitejs/vite/blob/main/packages/plugin-vue/src/main.ts#L387 + // 没有增加 src=descriptor.id + // 包含外链 wxs,renderjs + code = code.replace( + /vue&type=(wxs|renderjs)&index=([0-9]+)&src&/gi, + (_, type, index) => { + return `vue&type=${type}&index=${index}&src=${hmrId}&` + } + ) + return { + code: code, // 暂不提供sourcemap,意义不大 + map: null, + } + }, + } +} + +function parseHmrId(code: string) { + const matches = code.match(/_sfc_main.__hmrId = "(.*)"/) + return matches && matches[1] +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/renderjs.ts b/packages/uni-mp-weibo-vite/src/plugins/renderjs.ts new file mode 100644 index 00000000000..17265468c35 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/renderjs.ts @@ -0,0 +1,47 @@ +import debug from 'debug' +import type { Plugin } from 'vite' +import { rewriteDefault } from '@vue/compiler-sfc' + +import { missingModuleName, parseRenderjs } from '@dcloudio/uni-cli-shared' + +const debugRenderjs = debug('uni:h5-renderjs') + +export function uniRenderjsPlugin(): Plugin { + return { + name: 'uni:h5-renderjs', + transform(code, id) { + const { type, name } = parseRenderjs(id) + if (!type) { + return + } + debugRenderjs(id) + if (!name) { + this.error(missingModuleName(type, code)) + } + return `${rewriteDefault( + code.replace(/module\.exports\s*=/, 'export default '), + '_sfc_' + type + )} +${type === 'renderjs' ? genRenderjsCode(name) : genWxsCode(name)}` + }, + } +} + +function genRenderjsCode(name: string) { + return `export default Comp => { + if(!Comp.$renderjs){Comp.$renderjs = []} + Comp.$renderjs.push('${name}') + if(!Comp.mixins){Comp.mixins = []} + Comp.mixins.push({beforeCreate(){ this['${name}'] = this },mounted(){ this.$ownerInstance = this.$gcd(this, true) }}) + Comp.mixins.push(_sfc_renderjs) +}` +} + +function genWxsCode(name: string) { + return `export default Comp => { + if(!Comp.$wxs){Comp.$wxs = []} + Comp.$wxs.push('${name}') + if(!Comp.mixins){Comp.mixins = []} + Comp.mixins.push({beforeCreate(){ this['${name}'] = _sfc_wxs }}) +}` +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/resolveId.ts b/packages/uni-mp-weibo-vite/src/plugins/resolveId.ts new file mode 100644 index 00000000000..e07176ec156 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/resolveId.ts @@ -0,0 +1,43 @@ +import path from 'path' +import debug from 'debug' +import type { Plugin } from 'vite' + +import { resolveBuiltIn } from '@dcloudio/uni-cli-shared' +import { ownerModuleName } from '../utils' + +const debugResolve = debug('uni:resolve') + +export function uniResolveIdPlugin(): Plugin { + const resolveCache: Record = {} + return { + name: 'uni:h5-resolve-id', + enforce: 'pre', + config() { + resolveCache[ownerModuleName] = resolveBuiltIn( + path.join(ownerModuleName, 'dist/uni-mp-weibo.es.js') + ) + resolveCache['@dcloudio/uni-h5-vue'] = resolveBuiltIn( + path.join( + '@dcloudio/uni-h5-vue', + `dist/vue.runtime.${process.env.VITEST ? 'cjs' : 'esm'}.js` + ) + ) + }, + resolveId(id) { + if (id === 'vue') { + id = '@dcloudio/uni-h5-vue' + } + const cache = resolveCache[id] + if (cache) { + debugResolve('cache', id, cache) + return cache + } + if (id.startsWith('@dcloudio/uni-mp-weibo/style')) { + return (resolveCache[id] = resolveBuiltIn(id)) + } + if (id.startsWith('@dcloudio/uni-components/style')) { + return (resolveCache[id] = resolveBuiltIn(id)) + } + }, + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/setup.ts b/packages/uni-mp-weibo-vite/src/plugins/setup.ts new file mode 100644 index 00000000000..98d4a9f4d77 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/setup.ts @@ -0,0 +1,38 @@ +import path from 'path' +import debug from 'debug' +import type { Plugin, ResolvedConfig } from 'vite' +import { + normalizePath, + parseVueRequest, + withSourcemap, +} from '@dcloudio/uni-cli-shared' + +const debugSetup = debug('uni:setup') + +export function uniSetupPlugin(): Plugin { + let appVuePath: string + let resolvedConfig: ResolvedConfig + return { + name: 'uni:setup', + configResolved(config) { + resolvedConfig = config + appVuePath = normalizePath( + path.resolve(process.env.UNI_INPUT_DIR, 'App.vue') + ) + }, + transform(code, id) { + const { filename, query } = parseVueRequest(id) + if (filename === appVuePath && !query.vue) { + debugSetup(filename) + return { + code: + code + + `;import { setupApp } from '@dcloudio/uni-mp-weibo';setupApp(_sfc_main);`, + map: withSourcemap(resolvedConfig) + ? this.getCombinedSourcemap() + : null, + } + } + }, + } +} diff --git a/packages/uni-mp-weibo-vite/src/plugins/ssr.ts b/packages/uni-mp-weibo-vite/src/plugins/ssr.ts new file mode 100644 index 00000000000..caf2e5eafa6 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/plugins/ssr.ts @@ -0,0 +1,87 @@ +import path from 'path' +import type { Plugin, ResolvedConfig } from 'vite' + +import { OutputChunk } from 'rollup' + +import { + isSsr, + parseRpx2UnitOnce, + resolveBuiltIn, +} from '@dcloudio/uni-cli-shared' + +import { + initSsrAliasOnce, + initSsrDefine, + rewriteSsrVue, + rewriteSsrNativeTag, + rewriteSsrRenderStyle, + generateSsrDefineCode, + generateSsrEntryServerCode, +} from '../utils' + +const ENTRY_SERVER_JS = 'entry-server.js' + +export function uniSSRPlugin(): Plugin { + let entryServerJs: string + let resolvedConfig: ResolvedConfig + const entryServerJsCode = generateSsrEntryServerCode() + return { + name: 'uni:h5-ssr', + config(userConfig, env) { + if (isSsr(env.command, userConfig)) { + initSsrAliasOnce() + rewriteSsrVue() + rewriteSsrNativeTag() + rewriteSsrRenderStyle(process.env.UNI_INPUT_DIR) + return { + resolve: { + alias: [ + { + find: 'vue', + replacement: resolveBuiltIn( + '@dcloudio/uni-h5-vue/dist/vue.runtime.esm.js' + ), + }, + { + find: 'vue/server-renderer', + replacement: resolveBuiltIn('@vue/server-renderer'), + }, + ], + }, + } + } + }, + configResolved(config: ResolvedConfig) { + resolvedConfig = config + entryServerJs = path.join(process.env.UNI_INPUT_DIR, ENTRY_SERVER_JS) + if (isSsr(resolvedConfig.command, resolvedConfig)) { + initSsrDefine(resolvedConfig) + } + }, + resolveId(id) { + if (id.endsWith(ENTRY_SERVER_JS)) { + return entryServerJs + } + }, + load(id) { + if (id.endsWith(ENTRY_SERVER_JS)) { + return entryServerJsCode + } + }, + generateBundle(_options, bundle) { + const chunk = bundle['entry-server.js'] as OutputChunk + if (chunk) { + chunk.code = + generateSsrDefineCode( + resolvedConfig, + parseRpx2UnitOnce( + process.env.UNI_INPUT_DIR, + process.env.UNI_PLATFORM + ) + ) + + '\n' + + chunk.code + } + }, + } +} diff --git a/packages/uni-mp-weibo-vite/src/utils/constants.ts b/packages/uni-mp-weibo-vite/src/utils/constants.ts new file mode 100644 index 00000000000..bd0b3aeb806 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/utils/constants.ts @@ -0,0 +1 @@ +export const ownerModuleName = '@dcloudio/uni-mp-weibo' diff --git a/packages/uni-mp-weibo-vite/src/utils/features.ts b/packages/uni-mp-weibo-vite/src/utils/features.ts new file mode 100644 index 00000000000..269ea98f53c --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/utils/features.ts @@ -0,0 +1,24 @@ +import type { ConfigEnv, UserConfig } from 'vite' +import { + parsePagesJsonOnce, + parseManifestJsonOnce, + initFeatures, + isSsr, +} from '@dcloudio/uni-cli-shared' +import { isSsrManifest } from './ssr' + +export function createDefine( + command: ConfigEnv['command'], + config: UserConfig +): UserConfig['define'] { + const platform = process.env.UNI_PLATFORM + const inputDir = process.env.UNI_INPUT_DIR + return initFeatures({ + inputDir, + command, + platform, + pagesJson: parsePagesJsonOnce(inputDir, platform), + manifestJson: parseManifestJsonOnce(inputDir), + ssr: isSsr(command, config) || isSsrManifest(command, config), + }) +} diff --git a/packages/uni-mp-weibo-vite/src/utils/index.ts b/packages/uni-mp-weibo-vite/src/utils/index.ts new file mode 100644 index 00000000000..d7a5289a4d7 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/utils/index.ts @@ -0,0 +1,3 @@ +export * from './ssr' +export * from './features' +export * from './constants' diff --git a/packages/uni-mp-weibo-vite/src/utils/ssr.ts b/packages/uni-mp-weibo-vite/src/utils/ssr.ts new file mode 100644 index 00000000000..0f183b27855 --- /dev/null +++ b/packages/uni-mp-weibo-vite/src/utils/ssr.ts @@ -0,0 +1,206 @@ +/* eslint-disable no-restricted-globals */ +import path from 'path' +import fs from 'fs' +import { extend, isArray, isString, NormalizedStyle } from '@vue/shared' +import { + once, + isH5NativeTag, + createRpx2Unit, + Rpx2UnitOptions, +} from '@dcloudio/uni-shared' +import { + parseRpx2UnitOnce, + resolveBuiltIn, + getBuiltInPaths, + transformMatchMedia, + normalizePath, + transformH5BuiltInComponents, +} from '@dcloudio/uni-cli-shared' +import type { ConfigEnv, ResolvedConfig, UserConfig } from 'vite' +import resolve from 'resolve' +import { resolveComponentType } from '@vue/compiler-dom' +import { transformPageHead } from '../plugin/transforms/transformPageHead' + +// Temporal handling for 2.7 breaking change +export const isSSR = (opt: { ssr?: boolean } | boolean | undefined) => + opt === undefined ? false : typeof opt === 'boolean' ? opt : opt?.ssr === true + +export function isSsrManifest( + command: ConfigEnv['command'], + config: UserConfig | ResolvedConfig +) { + if (command === 'build') { + return !!(config.build && config.build.ssrManifest) + } + return false +} + +const SSR_ALIAS: Record = { + vue: '@dcloudio/uni-h5-vue', + 'vue/server-renderer': 'vue/server-renderer', + '@vue/server-renderer': '@vue/server-renderer', + '@dcloudio/uni-cloud': '@dcloudio/uni-cloud', + '@dcloudio/uni-mp-weibo': '@dcloudio/uni-mp-weibo', + '@dcloudio/uni-i18n': '@dcloudio/uni-i18n', + '@dcloudio/uni-shared': '@dcloudio/uni-shared', +} +export const initSsrAliasOnce = once(() => { + // 重写 package.json 的读取 + const oldJoin = path.join + const alias = Object.keys(SSR_ALIAS).reduce((alias, key) => { + const newKey = oldJoin('node_modules', key, 'package.json') + if (key.endsWith('vue/server-renderer')) { + alias[newKey] = path.join( + path.dirname(resolveBuiltIn(SSR_ALIAS[key])), + 'package.json' + ) + } else { + alias[newKey] = resolveBuiltIn(SSR_ALIAS[key] + '/package.json') + } + return alias + }, {} as Record) + // console.log(alias) + path.join = (...paths: string[]): string => { + let res = oldJoin.apply(path, paths) + if (res.endsWith('package.json')) { + const key = Object.keys(alias).find((key) => res.endsWith(key)) + if (key) { + res = alias[key] + } + } + return res + } +}) + +export function initSsrDefine(config: ResolvedConfig) { + return extend(globalThis, { + __IMPORT_META_ENV_BASE_URL__: config.env.BASE_URL, + }) +} + +function serializeDefine(define: Record): string { + let res = `{` + for (const key in define) { + const val = define[key] + res += `${JSON.stringify(key)}: ${ + isString(val) ? `(${val})` : JSON.stringify(val) + }, ` + } + return res + `}` +} + +function normalizeSsrDefine(config: ResolvedConfig) { + const defines = extend( + { + __IMPORT_META_ENV_BASE_URL__: JSON.stringify(config.env.BASE_URL), + }, + config.define! + ) + delete defines['import.meta.env.LEGACY'] + return defines +} +export function generateSsrDefineCode( + config: ResolvedConfig, + { unit, unitRatio, unitPrecision }: Rpx2UnitOptions +): string { + return fs + .readFileSync(path.join(__dirname, '../../lib/ssr/define.js'), 'utf8') + .replace('__DEFINES__', serializeDefine(normalizeSsrDefine(config))) + .replace('__UNIT__', JSON.stringify(unit)) + .replace('__UNIT_RATIO__', JSON.stringify(unitRatio)) + .replace('__UNIT_PRECISION__', JSON.stringify(unitPrecision)) +} + +export function generateSsrEntryServerCode() { + return fs.readFileSync( + path.join(__dirname, '../../lib/ssr/entry-server.js'), + 'utf8' + ) +} + +export function rewriteSsrVue() { + // 解决 @vue/server-renderer 中引入 vue 的映射 + require('module-alias').addAliases({ + vue: resolveBuiltIn('@dcloudio/uni-h5-vue/dist/vue.runtime.cjs.js'), + 'vue/package.json': resolveBuiltIn('@dcloudio/uni-h5-vue/package.json'), + }) + // TODO vite 2.7.0 版本会定制 require 的解析,解析后缓存的文件路径会被格式化,导致 windows 平台路径不一致,导致 cache 不生效 + if (require('os').platform() === 'win32') { + require('vue') + const vuePath = require.resolve('vue') + require.cache[normalizePath(vuePath)] = require.cache[vuePath] + } +} + +function initResolveSyncOpts(opts?: resolve.SyncOpts) { + if (!opts) { + opts = {} + } + if (!opts.paths) { + opts.paths = [] + } + if (isString(opts.paths)) { + opts.paths = [opts.paths] + } + if (isArray(opts.paths)) { + opts.paths.push(...getBuiltInPaths()) + } + return opts +} + +export function rewriteSsrResolve() { + // 解决 ssr 时 __vite_ssr_import__("vue") 的映射 + const resolve = require(require.resolve('resolve', { + paths: [ + path.resolve(require.resolve('vite/package.json'), '../node_modules'), + ], + })) + const oldSync = resolve.sync + resolve.sync = (id: string, opts?: resolve.SyncOpts) => { + if (id === 'vue') { + return resolveBuiltIn(`@dcloudio/uni-h5-vue/dist/vue.runtime.cjs.js`) + } else if (id === 'vue/package.json') { + return resolveBuiltIn(`@dcloudio/uni-h5-vue/package.json`) + } else if (id === 'vue/server-renderer/package.json') { + return resolveBuiltIn(`@vue/server-renderer/package.json`) + } + return oldSync(id, initResolveSyncOpts(opts)) + } +} + +export function rewriteSsrNativeTag() { + // @ts-ignore + const compilerDom = require(resolveBuiltIn('@vue/compiler-dom')) + // TODO compiler-ssr时,传入的 isNativeTag 会被 @vue/compiler-dom 的 isNativeTag 覆盖 + // https://github.com/vuejs/vue-next/blob/master/packages/compiler-ssr/src/index.ts#L36 + compilerDom.parserOptions.isNativeTag = isH5NativeTag + + // ssr 时,ssrTransformComponent 执行时机很早,导致无法正确重写 tag,故通过 resolveComponentType 解决重写 + const oldResolveComponentType = + compilerDom.resolveComponentType as typeof resolveComponentType + const newResolveComponentType: typeof resolveComponentType = function ( + node, + context, + ssr + ) { + transformPageHead(node, context) + transformMatchMedia(node, context) + transformH5BuiltInComponents(node, context) + return oldResolveComponentType(node, context, ssr) + } + compilerDom.resolveComponentType = newResolveComponentType +} + +export function rewriteSsrRenderStyle(inputDir: string) { + const { unit, unitRatio, unitPrecision } = parseRpx2UnitOnce(inputDir, 'h5') + const rpx2unit = createRpx2Unit(unit, unitRatio, unitPrecision) + const shared = require('@vue/shared') + const oldStringifyStyle = shared.stringifyStyle + shared.stringifyStyle = (styles: NormalizedStyle | undefined) => + rpx2unit(oldStringifyStyle(styles)) + const serverRender = require('@vue/server-renderer') + const oldSsrRenderStyle = serverRender.ssrRenderStyle + // 仅对字符串类型做转换,非字符串类型,通过 stringifyStyle 转换 + serverRender.ssrRenderStyle = (raw: unknown) => + isString(raw) ? rpx2unit(oldSsrRenderStyle(raw)) : oldSsrRenderStyle(raw) +} diff --git a/packages/uni-mp-weibo-vite/tsconfig.json b/packages/uni-mp-weibo-vite/tsconfig.json new file mode 100644 index 00000000000..7de50e34ab8 --- /dev/null +++ b/packages/uni-mp-weibo-vite/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["src", "../shims-node.d.ts", "../shims-uni-app.d.ts"] +} diff --git a/packages/uni-mp-weibo/LICENSE b/packages/uni-mp-weibo/LICENSE new file mode 100755 index 00000000000..7a4a3ea2424 --- /dev/null +++ b/packages/uni-mp-weibo/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/uni-mp-weibo/api.ts b/packages/uni-mp-weibo/api.ts new file mode 100644 index 00000000000..7af0a8d2811 --- /dev/null +++ b/packages/uni-mp-weibo/api.ts @@ -0,0 +1,78 @@ +import fs from 'fs' +import path from 'path' +import { parse } from 'acorn-loose' +import { simple } from 'acorn-walk' +import { hyphenate } from '@vue/shared' +import { isBuiltInComponent } from '@dcloudio/uni-shared' +import type { ExportNamedDeclaration } from 'estree' + +const BLACKLIST = [ + 'AsyncErrorComponent', + 'AsyncLoadingComponent', + 'LayoutComponent', + 'PageComponent', + 'ResizeSensor', + 'UniServiceJSBridge', + 'UniViewJSBridge', + 'getApp', + 'getCurrentPages', + 'uni', + 'useTabBar', + 'setupApp', + 'setupPage', + 'setupWindow', + 'plugin', + 'cssBackdropFilter', + 'cssConstant', + 'cssEnv', + 'cssVar', + 'useI18n', +] + +export function genApiJson(code: string) { + const apiNames: string[] = [] + simple( + parse(code, { + sourceType: 'module', + ecmaVersion: 2020, + }), + { + ExportNamedDeclaration(node) { + ;(node as unknown as ExportNamedDeclaration).specifiers.forEach( + ({ exported: { name } }) => { + if (isApi(name)) { + apiNames.push(name) + } + } + ) + }, + } + ) + const apiJsonPath = path.resolve( + __dirname, + '../uni-mp-weibo-vite/lib/api.json' + ) + const oldApiJson = fs.readFileSync(apiJsonPath, 'utf8').replace(/\r\n/g, '\n') + const newApiJson = JSON.stringify(apiNames.sort(), null, 2) + if (oldApiJson !== newApiJson) { + fs.writeFileSync( + path.resolve(__dirname, '../uni-mp-weibo-vite/lib/api.new.json'), + newApiJson + ) + throw new Error(`${apiJsonPath} 发生变化,请手动确认`) + } else { + console.log() + console.log(`generate api.json`) + console.log() + } +} + +function isApi(name) { + if (BLACKLIST.includes(name)) { + return false + } + if (isBuiltInComponent(hyphenate(name))) { + return false + } + return true +} diff --git a/packages/uni-mp-weibo/build.json b/packages/uni-mp-weibo/build.json new file mode 100644 index 00000000000..85d136790c9 --- /dev/null +++ b/packages/uni-mp-weibo/build.json @@ -0,0 +1,11 @@ +[ + { + "input": { + "src/compiler/index.ts": "dist/uni.compiler.js" + }, + "output": { + "format": "cjs" + }, + "external": ["@dcloudio/uni-mp-weibo-vite"] + } +] diff --git a/packages/uni-mp-weibo/dist/uni-mp-weibo.cjs.js b/packages/uni-mp-weibo/dist/uni-mp-weibo.cjs.js new file mode 100644 index 00000000000..bb9515591e7 --- /dev/null +++ b/packages/uni-mp-weibo/dist/uni-mp-weibo.cjs.js @@ -0,0 +1,12400 @@ +"use strict"; +Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); +const vue = require("vue"); +const shared = require("@vue/shared"); +const uniShared = require("@dcloudio/uni-shared"); +const uniI18n = require("@dcloudio/uni-i18n"); +const vueRouter = require("vue-router"); +const isEnableLocale = /* @__PURE__ */ uniShared.once( + () => typeof __uniConfig !== "undefined" && __uniConfig.locales && !!Object.keys(__uniConfig.locales).length +); +let i18n; +function getLocaleMessage() { + const locale = uni.getLocale(); + const locales = __uniConfig.locales; + return locales[locale] || locales[__uniConfig.fallbackLocale] || locales.en || {}; +} +function formatI18n(message) { + if (uniI18n.isI18nStr(message, uniShared.I18N_JSON_DELIMITERS)) { + return useI18n().f(message, getLocaleMessage(), uniShared.I18N_JSON_DELIMITERS); + } + return message; +} +function resolveJsonObj(jsonObj, names) { + if (names.length === 1) { + if (jsonObj) { + const _isI18nStr = (value2) => shared.isString(value2) && uniI18n.isI18nStr(value2, uniShared.I18N_JSON_DELIMITERS); + const _name = names[0]; + let filterJsonObj = []; + if (shared.isArray(jsonObj) && (filterJsonObj = jsonObj.filter((item) => _isI18nStr(item[_name]))).length) { + return filterJsonObj; + } + const value = jsonObj[names[0]]; + if (_isI18nStr(value)) { + return jsonObj; + } + } + return; + } + const name = names.shift(); + return resolveJsonObj(jsonObj && jsonObj[name], names); +} +function defineI18nProperties(obj, names) { + return names.map((name) => defineI18nProperty(obj, name)); +} +function defineI18nProperty(obj, names) { + const jsonObj = resolveJsonObj(obj, names); + if (!jsonObj) { + return false; + } + const prop = names[names.length - 1]; + if (shared.isArray(jsonObj)) { + jsonObj.forEach((item) => defineI18nProperty(item, [prop])); + } else { + let value = jsonObj[prop]; + Object.defineProperty(jsonObj, prop, { + get() { + return formatI18n(value); + }, + set(v2) { + value = v2; + } + }); + } + return true; +} +function useI18n() { + if (!i18n) { + let locale; + { + { + locale = uniShared.getEnvLocale(); + } + } + i18n = uniI18n.initVueI18n(locale); + if (isEnableLocale()) { + const localeKeys = Object.keys(__uniConfig.locales || {}); + if (localeKeys.length) { + localeKeys.forEach( + (locale2) => i18n.add(locale2, __uniConfig.locales[locale2]) + ); + } + i18n.setLocale(locale); + } + } + return i18n; +} +function normalizeMessages(module2, keys, values) { + return keys.reduce((res, name, index2) => { + res[module2 + name] = values[index2]; + return res; + }, {}); +} +const initI18nAsyncMsgsOnce = /* @__PURE__ */ uniShared.once(() => { + const name = "uni.async."; + const keys = ["error"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + uniI18n.LOCALE_EN, + normalizeMessages(name, keys, [ + "The connection timed out, click the screen to try again." + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + uniI18n.LOCALE_ES, + normalizeMessages(name, keys, [ + "Se agotó el tiempo de conexión, haga clic en la pantalla para volver a intentarlo." + ]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + uniI18n.LOCALE_FR, + normalizeMessages(name, keys, [ + "La connexion a expiré, cliquez sur l'écran pour réessayer." + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + uniI18n.LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["连接服务器超时,点击屏幕重试"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + uniI18n.LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["連接服務器超時,點擊屏幕重試"]), + false + ); + } +}); +const initI18nPickerMsgsOnce = /* @__PURE__ */ uniShared.once(() => { + const name = "uni.picker."; + const keys = ["done", "cancel"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + uniI18n.LOCALE_EN, + normalizeMessages(name, keys, ["Done", "Cancel"]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + uniI18n.LOCALE_ES, + normalizeMessages(name, keys, ["OK", "Cancelar"]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + uniI18n.LOCALE_FR, + normalizeMessages(name, keys, ["OK", "Annuler"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + uniI18n.LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["完成", "取消"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + uniI18n.LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["完成", "取消"]), + false + ); + } +}); +const initI18nVideoMsgsOnce = /* @__PURE__ */ uniShared.once(() => { + const name = "uni.video."; + const keys = ["danmu", "volume"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + uniI18n.LOCALE_EN, + normalizeMessages(name, keys, ["Danmu", "Volume"]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + uniI18n.LOCALE_ES, + normalizeMessages(name, keys, ["Danmu", "Volumen"]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + uniI18n.LOCALE_FR, + normalizeMessages(name, keys, ["Danmu", "Le Volume"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + uniI18n.LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["弹幕", "音量"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + uniI18n.LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["彈幕", "音量"]), + false + ); + } +}); +function initNavigationBarI18n(navigationBar) { + if (isEnableLocale()) { + return defineI18nProperties(navigationBar, [ + ["titleText"], + ["searchInput", "placeholder"], + ["buttons", "text"] + ]); + } +} +function initTabBarI18n(tabBar2) { + if (isEnableLocale() && tabBar2.list) { + tabBar2.list.forEach((item) => { + defineI18nProperty(item, ["text"]); + }); + } + return tabBar2; +} +function initBridge(subscribeNamespace) { + const emitter = new uniShared.Emitter(); + return { + on(event, callback) { + return emitter.on(event, callback); + }, + once(event, callback) { + return emitter.once(event, callback); + }, + off(event, callback) { + return emitter.off(event, callback); + }, + emit(event, ...args) { + return emitter.emit(event, ...args); + }, + subscribe(event, callback, once = false) { + emitter[once ? "once" : "on"](`${subscribeNamespace}.${event}`, callback); + }, + unsubscribe(event, callback) { + emitter.off(`${subscribeNamespace}.${event}`, callback); + }, + subscribeHandler(event, args, pageId) { + emitter.emit(`${subscribeNamespace}.${event}`, args, pageId); + } + }; +} +const INVOKE_VIEW_API = "invokeViewApi"; +const INVOKE_SERVICE_API = "invokeServiceApi"; +let invokeServiceMethodId = 1; +const invokeServiceMethod = (name, args, callback) => { + const { subscribe, publishHandler } = UniViewJSBridge; + const id = callback ? invokeServiceMethodId++ : 0; + callback && subscribe(INVOKE_SERVICE_API + "." + id, callback, true); + publishHandler(INVOKE_SERVICE_API, { id, name, args }); +}; +const viewMethods = /* @__PURE__ */ Object.create(null); +function normalizeViewMethodName(pageId, name) { + return pageId + "." + name; +} +function registerViewMethod(pageId, name, fn) { + name = normalizeViewMethodName(pageId, name); + if (!viewMethods[name]) { + viewMethods[name] = fn; + } +} +const ViewJSBridge = /* @__PURE__ */ shared.extend( + /* @__PURE__ */ initBridge("service"), + { + invokeServiceMethod + } +); +const onEventPrevent = /* @__PURE__ */ vue.withModifiers(() => { +}, ["prevent"]); +const onEventStop = /* @__PURE__ */ vue.withModifiers(() => { +}, ["stop"]); +function updateCssVar(cssVars) { + const style = document.documentElement.style; + Object.keys(cssVars).forEach((name) => { + style.setProperty(name, cssVars[name]); + }); +} +function updatePageCssVar(cssVars) { + return updateCssVar(cssVars); +} +function PolySymbol(name) { + return Symbol(process.env.NODE_ENV !== "production" ? "[uni-app]: " + name : name); +} +function rpx2px(str, replace = false) { + if (replace) { + return rpx2pxWithReplace(str); + } + { + return parseInt(str + ""); + } +} +function rpx2pxWithReplace(str) { + { + return str; + } +} +const ICON_PATH_CANCEL = "M20.928 10.176l-4.928 4.928-4.928-4.928-0.896 0.896 4.928 4.928-4.928 4.928 0.896 0.896 4.928-4.928 4.928 4.928 0.896-0.896-4.928-4.928 4.928-4.928-0.896-0.896zM16 2.080q-3.776 0-7.040 1.888-3.136 1.856-4.992 4.992-1.888 3.264-1.888 7.040t1.888 7.040q1.856 3.136 4.992 4.992 3.264 1.888 7.040 1.888t7.040-1.888q3.136-1.856 4.992-4.992 1.888-3.264 1.888-7.040t-1.888-7.040q-1.856-3.136-4.992-4.992-3.264-1.888-7.040-1.888zM16 28.64q-3.424 0-6.4-1.728-2.848-1.664-4.512-4.512-1.728-2.976-1.728-6.4t1.728-6.4q1.664-2.848 4.512-4.512 2.976-1.728 6.4-1.728t6.4 1.728q2.848 1.664 4.512 4.512 1.728 2.976 1.728 6.4t-1.728 6.4q-1.664 2.848-4.512 4.512-2.976 1.728-6.4 1.728z"; +const ICON_PATH_CLEAR = "M16 0q-4.352 0-8.064 2.176-3.616 2.144-5.76 5.76-2.176 3.712-2.176 8.064t2.176 8.064q2.144 3.616 5.76 5.76 3.712 2.176 8.064 2.176t8.064-2.176q3.616-2.144 5.76-5.76 2.176-3.712 2.176-8.064t-2.176-8.064q-2.144-3.616-5.76-5.76-3.712-2.176-8.064-2.176zM22.688 21.408q0.32 0.32 0.304 0.752t-0.336 0.736-0.752 0.304-0.752-0.32l-5.184-5.376-5.376 5.184q-0.32 0.32-0.752 0.304t-0.736-0.336-0.304-0.752 0.32-0.752l5.376-5.184-5.184-5.376q-0.32-0.32-0.304-0.752t0.336-0.752 0.752-0.304 0.752 0.336l5.184 5.376 5.376-5.184q0.32-0.32 0.752-0.304t0.752 0.336 0.304 0.752-0.336 0.752l-5.376 5.184 5.184 5.376z"; +const ICON_PATH_DOWNLOAD = "M15.808 1.696q-3.776 0-7.072 1.984-3.2 1.888-5.088 5.152-1.952 3.392-1.952 7.36 0 3.776 1.952 7.072 1.888 3.2 5.088 5.088 3.296 1.952 7.072 1.952 3.968 0 7.36-1.952 3.264-1.888 5.152-5.088 1.984-3.296 1.984-7.072 0-4-1.984-7.36-1.888-3.264-5.152-5.152-3.36-1.984-7.36-1.984zM20.864 18.592l-3.776 4.928q-0.448 0.576-1.088 0.576t-1.088-0.576l-3.776-4.928q-0.448-0.576-0.24-0.992t0.944-0.416h2.976v-8.928q0-0.256 0.176-0.432t0.4-0.176h1.216q0.224 0 0.4 0.176t0.176 0.432v8.928h2.976q0.736 0 0.944 0.416t-0.24 0.992z"; +const ICON_PATH_INFO = "M15.808 0.128q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.176 3.776-2.176 8.16 0 4.224 2.176 7.872 2.080 3.552 5.632 5.632 3.648 2.176 7.872 2.176 4.384 0 8.16-2.176 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.416-2.176-8.16-2.112-3.616-5.728-5.728-3.744-2.176-8.16-2.176zM16.864 23.776q0 0.064-0.064 0.064h-1.568q-0.096 0-0.096-0.064l-0.256-11.328q0-0.064 0.064-0.064h2.112q0.096 0 0.064 0.064l-0.256 11.328zM16 10.88q-0.576 0-0.976-0.4t-0.4-0.96 0.4-0.96 0.976-0.4 0.976 0.4 0.4 0.96-0.4 0.96-0.976 0.4z"; +const ICON_PATH_SEARCH = "M20.928 22.688q-1.696 1.376-3.744 2.112-2.112 0.768-4.384 0.768-3.488 0-6.464-1.728-2.88-1.696-4.576-4.608-1.76-2.976-1.76-6.464t1.76-6.464q1.696-2.88 4.576-4.576 2.976-1.76 6.464-1.76t6.464 1.76q2.912 1.696 4.608 4.576 1.728 2.976 1.728 6.464 0 2.272-0.768 4.384-0.736 2.048-2.112 3.744l9.312 9.28-1.824 1.824-9.28-9.312zM12.8 23.008q2.784 0 5.184-1.376 2.304-1.376 3.68-3.68 1.376-2.4 1.376-5.184t-1.376-5.152q-1.376-2.336-3.68-3.68-2.4-1.408-5.184-1.408t-5.152 1.408q-2.336 1.344-3.68 3.68-1.408 2.368-1.408 5.152t1.408 5.184q1.344 2.304 3.68 3.68 2.368 1.376 5.152 1.376zM12.8 23.008v0z"; +const ICON_PATH_SUCCESS_NO_CIRCLE = "M1.952 18.080q-0.32-0.352-0.416-0.88t0.128-0.976l0.16-0.352q0.224-0.416 0.64-0.528t0.8 0.176l6.496 4.704q0.384 0.288 0.912 0.272t0.88-0.336l17.312-14.272q0.352-0.288 0.848-0.256t0.848 0.352l-0.416-0.416q0.32 0.352 0.32 0.816t-0.32 0.816l-18.656 18.912q-0.32 0.352-0.8 0.352t-0.8-0.32l-7.936-8.064z"; +const ICON_PATH_SUCCESS = "M15.808 0.16q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.144 3.744-2.144 8.128 0 4.192 2.144 7.872 2.112 3.52 5.632 5.632 3.68 2.144 7.872 2.144 4.384 0 8.128-2.144 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.384-2.176-8.128-2.112-3.616-5.728-5.728-3.744-2.176-8.128-2.176zM24.832 11.328l-11.264 11.104q-0.032 0.032-0.112 0.032t-0.112-0.032l-5.216-5.376q-0.096-0.128 0-0.288l0.704-0.96q0.032-0.064 0.112-0.064t0.112 0.032l4.256 3.264q0.064 0.032 0.144 0.032t0.112-0.032l10.336-8.608q0.064-0.064 0.144-0.064t0.112 0.064l0.672 0.672q0.128 0.128 0 0.224z"; +const ICON_PATH_WAITING = "M15.84 0.096q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.144 3.744-2.144 8.128 0 4.192 2.144 7.872 2.112 3.52 5.632 5.632 3.68 2.144 7.872 2.144 4.384 0 8.128-2.144 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.384-2.176-8.128-2.112-3.616-5.728-5.728-3.744-2.176-8.128-2.176zM23.008 21.92l-0.512 0.896q-0.096 0.128-0.224 0.064l-8-3.808q-0.096-0.064-0.16-0.128-0.128-0.096-0.128-0.288l0.512-12.096q0-0.064 0.048-0.112t0.112-0.048h1.376q0.064 0 0.112 0.048t0.048 0.112l0.448 10.848 6.304 4.256q0.064 0.064 0.080 0.128t-0.016 0.128z"; +const ICON_PATH_WARN = "M15.808 0.16q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.144 3.744-2.144 8.128 0 4.192 2.144 7.872 2.112 3.52 5.632 5.632 3.68 2.144 7.872 2.144 4.384 0 8.128-2.144 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.384-2.176-8.128-2.112-3.616-5.728-5.728-3.744-2.176-8.128-2.176zM15.136 8.672h1.728q0.128 0 0.224 0.096t0.096 0.256l-0.384 10.24q0 0.064-0.048 0.112t-0.112 0.048h-1.248q-0.096 0-0.144-0.048t-0.048-0.112l-0.384-10.24q0-0.16 0.096-0.256t0.224-0.096zM16 23.328q-0.48 0-0.832-0.352t-0.352-0.848 0.352-0.848 0.832-0.352 0.832 0.352 0.352 0.848-0.352 0.848-0.832 0.352z"; +const ICON_PATH_BACK = "M21.781 7.844l-9.063 8.594 9.063 8.594q0.25 0.25 0.25 0.609t-0.25 0.578q-0.25 0.25-0.578 0.25t-0.578-0.25l-9.625-9.125q-0.156-0.125-0.203-0.297t-0.047-0.359q0-0.156 0.047-0.328t0.203-0.297l9.625-9.125q0.25-0.25 0.578-0.25t0.578 0.25q0.25 0.219 0.25 0.578t-0.25 0.578z"; +const ICON_PATH_CLOSE = "M17.25 16.156l7.375-7.313q0.281-0.281 0.281-0.641t-0.281-0.641q-0.25-0.25-0.625-0.25t-0.625 0.25l-7.375 7.344-7.313-7.344q-0.25-0.25-0.625-0.25t-0.625 0.25q-0.281 0.25-0.281 0.625t0.281 0.625l7.313 7.344-7.375 7.344q-0.281 0.25-0.281 0.625t0.281 0.625q0.125 0.125 0.281 0.188t0.344 0.063q0.156 0 0.328-0.063t0.297-0.188l7.375-7.344 7.375 7.406q0.125 0.156 0.297 0.219t0.328 0.063q0.188 0 0.344-0.078t0.281-0.203q0.281-0.25 0.281-0.609t-0.281-0.641l-7.375-7.406z"; +function createSvgIconVNode(path, color = "#000", size = 27) { + return vue.createVNode( + "svg", + { + width: size, + height: size, + viewBox: "0 0 32 32" + }, + [ + vue.createVNode( + "path", + { + d: path, + fill: color + }, + null, + 8, + ["d", "fill"] + ) + ], + 8, + ["width", "height"] + ); +} +function useCurrentPageId() { + { + const { $pageInstance } = vue.getCurrentInstance(); + return $pageInstance && $pageInstance.proxy.$page.id; + } +} +function getCurrentPage() { + const pages = getCurrentPages(); + const len = pages.length; + if (len) { + return pages[len - 1]; + } +} +function getCurrentPageMeta() { + const page = getCurrentPage(); + if (page) { + return page.$page.meta; + } +} +function getCurrentPageId() { + const meta = getCurrentPageMeta(); + if (meta) { + return meta.id; + } + return -1; +} +function getCurrentPageVm() { + const page = getCurrentPage(); + if (page) { + return page.$vm; + } +} +const PAGE_META_KEYS = ["navigationBar", "pullToRefresh"]; +function initGlobalStyle() { + return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {})); +} +function initRouteMeta(pageMeta, id) { + const globalStyle = initGlobalStyle(); + const res = shared.extend({ id }, globalStyle, pageMeta); + PAGE_META_KEYS.forEach((name) => { + res[name] = shared.extend({}, globalStyle[name], pageMeta[name]); + }); + const { navigationBar } = res; + navigationBar.titleText && navigationBar.titleImage && (navigationBar.titleText = ""); + return res; +} +function normalizePullToRefreshRpx(pullToRefresh) { + if (pullToRefresh.offset) { + pullToRefresh.offset = rpx2px(pullToRefresh.offset); + } + if (pullToRefresh.height) { + pullToRefresh.height = rpx2px(pullToRefresh.height); + } + if (pullToRefresh.range) { + pullToRefresh.range = rpx2px(pullToRefresh.range); + } + return pullToRefresh; +} +function initPageInternalInstance(openType, url, pageQuery, meta, eventChannel, themeMode) { + const { id, route } = meta; + const titleColor = uniShared.normalizeStyles( + meta.navigationBar, + __uniConfig.themeConfig, + themeMode + ).titleColor; + return { + id, + path: uniShared.addLeadingSlash(route), + route, + fullPath: url, + options: pageQuery, + meta, + openType, + eventChannel, + statusBarStyle: titleColor === "#ffffff" ? "light" : "dark" + }; +} +function invokeHook(vm, name, args) { + if (shared.isString(vm)) { + args = name; + name = vm; + vm = getCurrentPageVm(); + } else if (typeof vm === "number") { + const page = getCurrentPages().find((page2) => page2.$page.id === vm); + if (page) { + vm = page.$vm; + } else { + vm = getCurrentPageVm(); + } + } + if (!vm) { + return; + } + const hooks = vm.$[name]; + return hooks && uniShared.invokeArrayFns(hooks, args); +} +function getRealRoute(fromRoute, toRoute) { + if (toRoute.indexOf("/") === 0) { + return toRoute; + } + if (toRoute.indexOf("./") === 0) { + return getRealRoute(fromRoute, toRoute.slice(2)); + } + const toRouteArray = toRoute.split("/"); + const toRouteLength = toRouteArray.length; + let i = 0; + for (; i < toRouteLength && toRouteArray[i] === ".."; i++) { + } + toRouteArray.splice(0, i); + toRoute = toRouteArray.join("/"); + const fromRouteArray = fromRoute.length > 0 ? fromRoute.split("/") : []; + fromRouteArray.splice(fromRouteArray.length - i - 1, i + 1); + return uniShared.addLeadingSlash(fromRouteArray.concat(toRouteArray).join("/")); +} +function getRouteOptions(path, alias = false) { + if (alias) { + return __uniRoutes.find( + (route) => route.path === path || route.alias === path + ); + } + return __uniRoutes.find((route) => route.path === path); +} +function findUniTarget(target) { + while (target && target.tagName.indexOf("UNI-") !== 0) { + target = target.parentElement; + } + return target; +} +function createNativeEvent(evt, htmlElement = false) { + const { type, timeStamp, target, currentTarget } = evt; + const event = { + type, + timeStamp, + target: uniShared.normalizeTarget( + htmlElement ? target : findUniTarget(target) + ), + detail: {}, + currentTarget: uniShared.normalizeTarget(currentTarget) + }; + if (evt._stopped) { + event._stopped = true; + } + if (evt.type.startsWith("touch")) { + event.touches = evt.touches; + event.changedTouches = evt.changedTouches; + } + { + wrapperEvent(event, evt); + } + return event; +} +function wrapperEvent(event, evt) { + shared.extend(event, { + preventDefault() { + return evt.preventDefault(); + }, + stopPropagation() { + return evt.stopPropagation(); + } + }); +} +const invokeOnCallback = (name, res) => UniServiceJSBridge.emit("api." + name, res); +let invokeViewMethodId = 1; +function publishViewMethodName(pageId) { + return (pageId || getCurrentPageId()) + "." + INVOKE_VIEW_API; +} +const invokeViewMethod = (name, args, pageId, callback) => { + const { subscribe, publishHandler } = UniServiceJSBridge; + const id = callback ? invokeViewMethodId++ : 0; + callback && subscribe(INVOKE_VIEW_API + "." + id, callback, true); + publishHandler(publishViewMethodName(pageId), { id, name, args }, pageId); +}; +const invokeViewMethodKeepAlive = (name, args, callback, pageId) => { + const { subscribe, unsubscribe, publishHandler } = UniServiceJSBridge; + const id = invokeViewMethodId++; + const subscribeName = INVOKE_VIEW_API + "." + id; + subscribe(subscribeName, callback); + publishHandler(publishViewMethodName(pageId), { id, name, args }, pageId); + return () => { + unsubscribe(subscribeName); + }; +}; +const ServiceJSBridge = /* @__PURE__ */ shared.extend( + /* @__PURE__ */ initBridge( + "view" + /* view 指的是 service 层订阅的是 view 层事件 */ + ), + { + invokeOnCallback, + invokeViewMethod, + invokeViewMethodKeepAlive + } +); +function initAppVm(appVm2) { + appVm2.$vm = appVm2; + appVm2.$mpType = "app"; + const locale = vue.ref(useI18n().getLocale()); + Object.defineProperty(appVm2, "$locale", { + get() { + return locale.value; + }, + set(v2) { + locale.value = v2; + } + }); +} +function initPageVm(pageVm, page) { + pageVm.route = page.route; + pageVm.$vm = pageVm; + pageVm.$page = page; + pageVm.$mpType = "page"; + if (page.meta.isTabBar) { + pageVm.$.__isTabBar = true; + pageVm.$.__isActive = true; + } +} +function defineGlobalData(app, defaultGlobalData) { + const options = app.$options || {}; + options.globalData = shared.extend(options.globalData || {}, defaultGlobalData); + Object.defineProperty(app, "globalData", { + get() { + return options.globalData; + }, + set(newGlobalData) { + options.globalData = newGlobalData; + } + }); +} +function converPx(value) { + if (/^-?\d+[ur]px$/i.test(value)) { + return value.replace(/(^-?\d+)[ur]px$/i, (text, num) => { + return `${uni.upx2px(parseFloat(num))}px`; + }); + } else if (/^-?[\d\.]+$/.test(value)) { + return `${value}px`; + } + return value || ""; +} +function converType(type) { + return type.replace(/[A-Z]/g, (text) => { + return `-${text.toLowerCase()}`; + }).replace("webkit", "-webkit"); +} +function getStyle(action) { + const animateTypes1 = [ + "matrix", + "matrix3d", + "scale", + "scale3d", + "rotate3d", + "skew", + "translate", + "translate3d" + ]; + const animateTypes2 = [ + "scaleX", + "scaleY", + "scaleZ", + "rotate", + "rotateX", + "rotateY", + "rotateZ", + "skewX", + "skewY", + "translateX", + "translateY", + "translateZ" + ]; + const animateTypes3 = ["opacity", "background-color"]; + const animateTypes4 = ["width", "height", "left", "right", "top", "bottom"]; + const animates = action.animates; + const option = action.option; + const transition = option.transition; + const style = {}; + const transform = []; + animates.forEach((animate) => { + let type = animate.type; + let args = [...animate.args]; + if (animateTypes1.concat(animateTypes2).includes(type)) { + if (type.startsWith("rotate") || type.startsWith("skew")) { + args = args.map((value) => parseFloat(value) + "deg"); + } else if (type.startsWith("translate")) { + args = args.map(converPx); + } + if (animateTypes2.indexOf(type) >= 0) { + args.length = 1; + } + transform.push(`${type}(${args.join(",")})`); + } else if (animateTypes3.concat(animateTypes4).includes(args[0])) { + type = args[0]; + const value = args[1]; + style[type] = animateTypes4.includes(type) ? converPx(value) : value; + } + }); + style.transform = style.webkitTransform = transform.join(" "); + style.transition = style.webkitTransition = Object.keys(style).map( + (type) => `${converType(type)} ${transition.duration}ms ${transition.timingFunction} ${transition.delay}ms` + ).join(","); + style.transformOrigin = style.webkitTransformOrigin = option.transformOrigin; + return style; +} +function startAnimation(context) { + const animation2 = context.animation; + if (!animation2 || !animation2.actions || !animation2.actions.length) { + return; + } + let index2 = 0; + const actions = animation2.actions; + const length = animation2.actions.length; + function animate() { + const action = actions[index2]; + const transition = action.option.transition; + const style = getStyle(action); + Object.keys(style).forEach((key) => { + context.$el.style[key] = style[key]; + }); + index2 += 1; + if (index2 < length) { + setTimeout(animate, transition.duration + transition.delay); + } + } + setTimeout(() => { + animate(); + }, 0); +} +const animation = { + props: ["animation"], + watch: { + animation: { + deep: true, + handler() { + startAnimation(this); + } + } + }, + mounted() { + startAnimation(this); + } +}; +const defineBuiltInComponent = (options) => { + options.__reserved = true; + const { props: props2, mixins } = options; + if (!props2 || !props2.animation) { + (mixins || (options.mixins = [])).push(animation); + } + return defineSystemComponent(options); +}; +const defineSystemComponent = (options) => { + options.__reserved = true; + options.compatConfig = { + MODE: 3 + // 标记为vue3 + }; + return vue.defineComponent(options); +}; +const defineUnsupportedComponent = (name) => { + return defineBuiltInComponent({ + name: shared.capitalize(shared.camelize(name)), + setup() { + return () => (vue.openBlock(), vue.createElementBlock("uni-" + name, null, name + " is unsupported")); + } + }); +}; +const hoverProps = { + hoverClass: { + type: String, + default: "none" + }, + hoverStopPropagation: { + type: Boolean, + default: false + }, + hoverStartTime: { + type: [Number, String], + default: 50 + }, + hoverStayTime: { + type: [Number, String], + default: 400 + } +}; +function useHover(props2) { + const hovering = vue.ref(false); + let hoverTouch = false; + let hoverStartTimer; + let hoverStayTimer; + function hoverReset() { + requestAnimationFrame(() => { + clearTimeout(hoverStayTimer); + hoverStayTimer = setTimeout(() => { + hovering.value = false; + }, parseInt(props2.hoverStayTime)); + }); + } + function onTouchstartPassive(evt) { + if (evt.touches.length > 1) { + return; + } + handleHoverStart(evt); + } + function onMousedown(evt) { + if (hoverTouch) { + return; + } + handleHoverStart(evt); + window.addEventListener("mouseup", handlePCHoverEnd); + } + function handleHoverStart(evt) { + if (evt._hoverPropagationStopped) { + return; + } + if (!props2.hoverClass || props2.hoverClass === "none" || props2.disabled) { + return; + } + if (props2.hoverStopPropagation) { + evt._hoverPropagationStopped = true; + } + hoverTouch = true; + hoverStartTimer = setTimeout(() => { + hovering.value = true; + if (!hoverTouch) { + hoverReset(); + } + }, parseInt(props2.hoverStartTime)); + } + function onTouchend() { + handleHoverEnd(); + } + function onMouseup() { + if (!hoverTouch) { + return; + } + handlePCHoverEnd(); + } + function handleHoverEnd() { + hoverTouch = false; + if (hovering.value) { + hoverReset(); + } + } + function handlePCHoverEnd() { + handleHoverEnd(); + window.removeEventListener("mouseup", handlePCHoverEnd); + } + function onTouchcancel() { + hoverTouch = false; + hovering.value = false; + clearTimeout(hoverStartTimer); + } + return { + hovering, + binding: { + onTouchstartPassive, + onMousedown, + onTouchend, + onMouseup, + onTouchcancel + } + }; +} +function useBooleanAttr(props2, keys) { + if (shared.isString(keys)) { + keys = [keys]; + } + return keys.reduce((res, key) => { + if (props2[key]) { + res[key] = true; + } + return res; + }, /* @__PURE__ */ Object.create(null)); +} +function withWebEvent(fn) { + return fn.__wwe = true, fn; +} +function useCustomEvent(ref, emit2) { + return (name, evt, detail) => { + if (ref.value) { + emit2(name, normalizeCustomEvent(name, evt, ref.value, detail || {})); + } + }; +} +function useNativeEvent(emit2) { + return (name, evt) => { + emit2(name, createNativeEvent(evt)); + }; +} +function normalizeCustomEvent(name, domEvt, el, detail) { + const target = uniShared.normalizeTarget(el); + return { + type: detail.type || name, + timeStamp: domEvt.timeStamp || 0, + target, + currentTarget: target, + detail + }; +} +const uniFormKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniForm" : "uf"); +const index$C = /* @__PURE__ */ defineBuiltInComponent({ + name: "Form", + emits: ["submit", "reset"], + setup(_props, { + slots, + emit: emit2 + }) { + const rootRef = vue.ref(null); + provideForm(useCustomEvent(rootRef, emit2)); + return () => vue.createVNode("uni-form", { + "ref": rootRef + }, [vue.createVNode("span", null, [slots.default && slots.default()])], 512); + } +}); +function provideForm(trigger) { + const fields2 = []; + vue.provide(uniFormKey, { + addField(field) { + fields2.push(field); + }, + removeField(field) { + fields2.splice(fields2.indexOf(field), 1); + }, + submit(evt) { + trigger("submit", evt, { + value: fields2.reduce((res, field) => { + if (field.submit) { + const [name, value] = field.submit(); + name && (res[name] = value); + } + return res; + }, /* @__PURE__ */ Object.create(null)) + }); + }, + reset(evt) { + fields2.forEach((field) => field.reset && field.reset()); + trigger("reset", evt); + } + }); + return fields2; +} +const labelProps = { + for: { + type: String, + default: "" + } +}; +const uniLabelKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniLabel" : "ul"); +function useProvideLabel() { + const handlers = []; + vue.provide(uniLabelKey, { + addHandler(handler) { + handlers.push(handler); + }, + removeHandler(handler) { + handlers.splice(handlers.indexOf(handler), 1); + } + }); + return handlers; +} +const index$B = /* @__PURE__ */ defineBuiltInComponent({ + name: "Label", + props: labelProps, + setup(props2, { + slots + }) { + const pageId = useCurrentPageId(); + const handlers = useProvideLabel(); + const pointer = vue.computed(() => props2.for || slots.default && slots.default.length); + const _onClick = withWebEvent(($event) => { + const EventTarget = $event.target; + let stopPropagation = /^uni-(checkbox|radio|switch)-/.test(EventTarget.className); + if (!stopPropagation) { + stopPropagation = /^uni-(checkbox|radio|switch|button)$|^(svg|path)$/i.test(EventTarget.tagName); + } + if (stopPropagation) { + return; + } + if (props2.for) { + UniViewJSBridge.emit("uni-label-click-" + pageId + "-" + props2.for, $event, true); + } else { + handlers.length && handlers[0]($event, true); + } + }); + return () => vue.createVNode("uni-label", { + "class": { + "uni-label-pointer": pointer + }, + "onClick": _onClick + }, [slots.default && slots.default()], 10, ["onClick"]); + } +}); +const buttonProps = { + id: { + type: String, + default: "" + }, + hoverClass: { + type: String, + default: "button-hover" + }, + hoverStartTime: { + type: [Number, String], + default: 20 + }, + hoverStayTime: { + type: [Number, String], + default: 70 + }, + hoverStopPropagation: { + type: Boolean, + default: false + }, + disabled: { + type: [Boolean, String], + default: false + }, + formType: { + type: String, + default: "" + }, + openType: { + type: String, + default: "" + }, + loading: { + type: [Boolean, String], + default: false + }, + plain: { + type: [Boolean, String], + default: false + } +}; +const index$A = /* @__PURE__ */ defineBuiltInComponent({ + name: "Button", + props: buttonProps, + setup(props2, { + slots + }) { + const rootRef = vue.ref(null); + const uniForm = vue.inject(uniFormKey, false); + const { + hovering, + binding + } = useHover(props2); + useI18n(); + const onClick = withWebEvent((e2, isLabelClick) => { + if (props2.disabled) { + return e2.stopImmediatePropagation(); + } + if (isLabelClick) { + rootRef.value.click(); + } + const formType = props2.formType; + if (formType) { + if (!uniForm) { + return; + } + if (formType === "submit") { + uniForm.submit(e2); + } else if (formType === "reset") { + uniForm.reset(e2); + } + return; + } + if ( + // @ts-ignore + window.weibo && // @ts-ignore + typeof window.weibo.share === "function" && props2.openType === "share" + ) { + window.weibo.share(); + } + }); + const uniLabel = vue.inject(uniLabelKey, false); + if (uniLabel) { + uniLabel.addHandler(onClick); + } + return () => { + const hoverClass = props2.hoverClass; + const booleanAttrs = useBooleanAttr(props2, "disabled"); + const loadingAttrs = useBooleanAttr(props2, "loading"); + const plainAttrs = useBooleanAttr(props2, "plain"); + const hasHoverClass = hoverClass && hoverClass !== "none"; + return vue.createVNode("uni-button", vue.mergeProps({ + "ref": rootRef, + "onClick": onClick, + "class": hasHoverClass && hovering.value ? hoverClass : "" + }, hasHoverClass && binding, booleanAttrs, loadingAttrs, plainAttrs), [slots.default && slots.default()], 16, ["onClick"]); + }; + } +}); +function addBase(filePath) { + const { base: baseUrl } = __uniConfig.router; + if (uniShared.addLeadingSlash(filePath).indexOf(baseUrl) === 0) { + return uniShared.addLeadingSlash(filePath); + } + return baseUrl + filePath; +} +function getRealPath(filePath) { + const { base, assets } = __uniConfig.router; + if (base === "./") { + if (filePath.indexOf("./static/") === 0 || assets && filePath.indexOf("./" + assets + "/") === 0) { + filePath = filePath.slice(1); + } + } + if (filePath.indexOf("/") === 0) { + if (filePath.indexOf("//") === 0) { + filePath = "https:" + filePath; + } else { + return addBase(filePath.slice(1)); + } + } + if (uniShared.SCHEME_RE.test(filePath) || uniShared.DATA_RE.test(filePath) || filePath.indexOf("blob:") === 0) { + return filePath; + } + const pages = getCurrentPages(); + if (pages.length) { + return addBase( + getRealRoute(pages[pages.length - 1].$page.route, filePath).slice(1) + ); + } + return filePath; +} +const HTTP_METHODS = [ + "GET", + "OPTIONS", + "HEAD", + "POST", + "PUT", + "DELETE", + "TRACE", + "CONNECT", + "PATCH" +]; +function elemInArray(str, arr) { + if (!str || arr.indexOf(str) === -1) { + return arr[0]; + } + return str; +} +function validateProtocolFail(name, msg) { + console.warn(`${name}: ${msg}`); +} +function validateProtocol(name, data, protocol, onFail) { + if (!onFail) { + onFail = validateProtocolFail; + } + for (const key in protocol) { + const errMsg = validateProp( + key, + data[key], + protocol[key], + !shared.hasOwn(data, key) + ); + if (shared.isString(errMsg)) { + onFail(name, errMsg); + } + } +} +function validateProtocols(name, args, protocol, onFail) { + if (!protocol) { + return; + } + if (!shared.isArray(protocol)) { + return validateProtocol( + name, + args[0] || /* @__PURE__ */ Object.create(null), + protocol, + onFail + ); + } + const len = protocol.length; + const argsLen = args.length; + for (let i = 0; i < len; i++) { + const opts = protocol[i]; + const data = /* @__PURE__ */ Object.create(null); + if (argsLen > i) { + data[opts.name] = args[i]; + } + validateProtocol(name, data, { [opts.name]: opts }, onFail); + } +} +function validateProp(name, value, prop, isAbsent) { + if (!shared.isPlainObject(prop)) { + prop = { type: prop }; + } + const { type, required, validator } = prop; + if (required && isAbsent) { + return 'Missing required args: "' + name + '"'; + } + if (value == null && !required) { + return; + } + if (type != null) { + let isValid = false; + const types = shared.isArray(type) ? type : [type]; + const expectedTypes = []; + for (let i = 0; i < types.length && !isValid; i++) { + const { valid, expectedType } = assertType(value, types[i]); + expectedTypes.push(expectedType || ""); + isValid = valid; + } + if (!isValid) { + return getInvalidTypeMessage(name, value, expectedTypes); + } + } + if (validator) { + return validator(value); + } +} +const isSimpleType = /* @__PURE__ */ shared.makeMap( + "String,Number,Boolean,Function,Symbol" +); +function assertType(value, type) { + let valid; + const expectedType = getType(type); + if (isSimpleType(expectedType)) { + const t2 = typeof value; + valid = t2 === expectedType.toLowerCase(); + if (!valid && t2 === "object") { + valid = value instanceof type; + } + } else if (expectedType === "Object") { + valid = shared.isObject(value); + } else if (expectedType === "Array") { + valid = shared.isArray(value); + } else { + { + valid = value instanceof type; + } + } + return { + valid, + expectedType + }; +} +function getInvalidTypeMessage(name, value, expectedTypes) { + let message = `Invalid args: type check failed for args "${name}". Expected ${expectedTypes.map(shared.capitalize).join(", ")}`; + const expectedType = expectedTypes[0]; + const receivedType = shared.toRawType(value); + const expectedValue = styleValue(value, expectedType); + const receivedValue = styleValue(value, receivedType); + if (expectedTypes.length === 1 && isExplicable(expectedType) && !isBoolean(expectedType, receivedType)) { + message += ` with value ${expectedValue}`; + } + message += `, got ${receivedType} `; + if (isExplicable(receivedType)) { + message += `with value ${receivedValue}.`; + } + return message; +} +function getType(ctor) { + const match = ctor && ctor.toString().match(/^\s*function (\w+)/); + return match ? match[1] : ""; +} +function styleValue(value, type) { + if (type === "String") { + return `"${value}"`; + } else if (type === "Number") { + return `${Number(value)}`; + } else { + return `${value}`; + } +} +function isExplicable(type) { + const explicitTypes = ["string", "number", "boolean"]; + return explicitTypes.some((elem) => type.toLowerCase() === elem); +} +function isBoolean(...args) { + return args.some((elem) => elem.toLowerCase() === "boolean"); +} +function tryCatch(fn) { + return function() { + try { + return fn.apply(fn, arguments); + } catch (e2) { + console.error(e2); + } + }; +} +let invokeCallbackId = 1; +const invokeCallbacks = {}; +function addInvokeCallback(id, name, callback, keepAlive = false) { + invokeCallbacks[id] = { + name, + keepAlive, + callback + }; + return id; +} +function invokeCallback(id, res, extras) { + if (typeof id === "number") { + const opts = invokeCallbacks[id]; + if (opts) { + if (!opts.keepAlive) { + delete invokeCallbacks[id]; + } + return opts.callback(res, extras); + } + } + return res; +} +const API_SUCCESS = "success"; +const API_FAIL = "fail"; +const API_COMPLETE = "complete"; +function getApiCallbacks(args) { + const apiCallbacks = {}; + for (const name in args) { + const fn = args[name]; + if (shared.isFunction(fn)) { + apiCallbacks[name] = tryCatch(fn); + delete args[name]; + } + } + return apiCallbacks; +} +function normalizeErrMsg$1(errMsg, name) { + if (!errMsg || errMsg.indexOf(":fail") === -1) { + return name + ":ok"; + } + return name + errMsg.substring(errMsg.indexOf(":fail")); +} +function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = {}) { + if (!shared.isPlainObject(args)) { + args = {}; + } + const { success, fail, complete } = getApiCallbacks(args); + const hasSuccess = shared.isFunction(success); + const hasFail = shared.isFunction(fail); + const hasComplete = shared.isFunction(complete); + const callbackId = invokeCallbackId++; + addInvokeCallback(callbackId, name, (res) => { + res = res || {}; + res.errMsg = normalizeErrMsg$1(res.errMsg, name); + shared.isFunction(beforeAll) && beforeAll(res); + if (res.errMsg === name + ":ok") { + shared.isFunction(beforeSuccess) && beforeSuccess(res, args); + hasSuccess && success(res); + } else { + hasFail && fail(res); + } + hasComplete && complete(res); + }); + return callbackId; +} +const HOOK_SUCCESS = "success"; +const HOOK_FAIL = "fail"; +const HOOK_COMPLETE = "complete"; +const globalInterceptors = {}; +const scopedInterceptors = {}; +function wrapperHook(hook, params) { + return function(data) { + return hook(data, params) || data; + }; +} +function queue(hooks, data, params) { + let promise = false; + for (let i = 0; i < hooks.length; i++) { + const hook = hooks[i]; + if (promise) { + promise = Promise.resolve(wrapperHook(hook, params)); + } else { + const res = hook(data, params); + if (shared.isPromise(res)) { + promise = Promise.resolve(res); + } + if (res === false) { + return { + then() { + }, + catch() { + } + }; + } + } + } + return promise || { + then(callback) { + return callback(data); + }, + catch() { + } + }; +} +function wrapperOptions(interceptors, options = {}) { + [HOOK_SUCCESS, HOOK_FAIL, HOOK_COMPLETE].forEach((name) => { + const hooks = interceptors[name]; + if (!shared.isArray(hooks)) { + return; + } + const oldCallback = options[name]; + options[name] = function callbackInterceptor(res) { + queue(hooks, res, options).then((res2) => { + return shared.isFunction(oldCallback) && oldCallback(res2) || res2; + }); + }; + }); + return options; +} +function wrapperReturnValue(method, returnValue) { + const returnValueHooks = []; + if (shared.isArray(globalInterceptors.returnValue)) { + returnValueHooks.push(...globalInterceptors.returnValue); + } + const interceptor = scopedInterceptors[method]; + if (interceptor && shared.isArray(interceptor.returnValue)) { + returnValueHooks.push(...interceptor.returnValue); + } + returnValueHooks.forEach((hook) => { + returnValue = hook(returnValue) || returnValue; + }); + return returnValue; +} +function getApiInterceptorHooks(method) { + const interceptor = /* @__PURE__ */ Object.create(null); + Object.keys(globalInterceptors).forEach((hook) => { + if (hook !== "returnValue") { + interceptor[hook] = globalInterceptors[hook].slice(); + } + }); + const scopedInterceptor = scopedInterceptors[method]; + if (scopedInterceptor) { + Object.keys(scopedInterceptor).forEach((hook) => { + if (hook !== "returnValue") { + interceptor[hook] = (interceptor[hook] || []).concat( + scopedInterceptor[hook] + ); + } + }); + } + return interceptor; +} +function invokeApi(method, api2, options, params) { + const interceptor = getApiInterceptorHooks(method); + if (interceptor && Object.keys(interceptor).length) { + if (shared.isArray(interceptor.invoke)) { + const res = queue(interceptor.invoke, options); + return res.then((options2) => { + return api2( + wrapperOptions(getApiInterceptorHooks(method), options2), + ...params + ); + }); + } else { + return api2(wrapperOptions(interceptor, options), ...params); + } + } + return api2(options, ...params); +} +function hasCallback(args) { + if (shared.isPlainObject(args) && [API_SUCCESS, API_FAIL, API_COMPLETE].find( + (cb) => shared.isFunction(args[cb]) + )) { + return true; + } + return false; +} +function handlePromise(promise) { + return promise; +} +function promisify(name, fn) { + return (args = {}, ...rest) => { + try { + if (window.weibo && window.weibo[name]) { + window.currentWeiboApiName = name; + const value = window.weibo[name](args); + if (name !== "switchTab") { + return value; + } + } + } catch (e2) { + } + if (hasCallback(args)) { + return wrapperReturnValue(name, invokeApi(name, fn, args, rest)); + } + return wrapperReturnValue( + name, + handlePromise( + new Promise((resolve, reject) => { + invokeApi( + name, + fn, + shared.extend(args, { success: resolve, fail: reject }), + rest + ); + }) + ) + ); + }; +} +function formatApiArgs(args, options) { + const params = args[0]; + if (!options || !shared.isPlainObject(options.formatArgs) && shared.isPlainObject(params)) { + return; + } + const formatArgs = options.formatArgs; + const keys = Object.keys(formatArgs); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + const formatterOrDefaultValue = formatArgs[name]; + if (shared.isFunction(formatterOrDefaultValue)) { + const errMsg = formatterOrDefaultValue(args[0][name], params); + if (shared.isString(errMsg)) { + return errMsg; + } + } else { + if (!shared.hasOwn(params, name)) { + params[name] = formatterOrDefaultValue; + } + } + } +} +function invokeSuccess(id, name, res) { + return invokeCallback( + id, + shared.extend(res || {}, { errMsg: name + ":ok" }) + ); +} +function invokeFail(id, name, errMsg, errRes) { + return invokeCallback( + id, + shared.extend({ errMsg: name + ":fail" + (errMsg ? " " + errMsg : "") }, errRes) + ); +} +function beforeInvokeApi(name, args, protocol, options) { + if (process.env.NODE_ENV !== "production") { + validateProtocols(name, args, protocol); + } + if (options && options.beforeInvoke) { + const errMsg2 = options.beforeInvoke(args); + if (shared.isString(errMsg2)) { + return errMsg2; + } + } + const errMsg = formatApiArgs(args, options); + if (errMsg) { + return errMsg; + } +} +function normalizeErrMsg(errMsg) { + if (!errMsg || shared.isString(errMsg)) { + return errMsg; + } + if (errMsg.stack) { + console.error(errMsg.message + uniShared.LINEFEED + errMsg.stack); + return errMsg.message; + } + return errMsg; +} +function wrapperTaskApi(name, fn, protocol, options) { + return (args) => { + const id = createAsyncApiCallback(name, args, options); + const errMsg = beforeInvokeApi(name, [args], protocol, options); + if (errMsg) { + return invokeFail(id, name, errMsg); + } + return fn(args, { + resolve: (res) => invokeSuccess(id, name, res), + reject: (errMsg2, errRes) => invokeFail(id, name, normalizeErrMsg(errMsg2), errRes) + }); + }; +} +function wrapperSyncApi(name, fn, protocol, options) { + return (...args) => { + try { + if (window.weibo && window.weibo[name]) { + window.currentWeiboApiName = name; + var value = window.weibo[name](args); + return value; + } + } catch (e2) { + } + const errMsg = beforeInvokeApi(name, args, protocol, options); + if (errMsg) { + throw new Error(errMsg); + } + return fn.apply(null, args); + }; +} +function wrapperAsyncApi(name, fn, protocol, options) { + return wrapperTaskApi(name, fn, protocol, options); +} +function defineTaskApi(name, fn, protocol, options) { + return promisify( + name, + wrapperTaskApi(name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options) + ); +} +function defineSyncApi(name, fn, protocol, options) { + return wrapperSyncApi( + name, + fn, + process.env.NODE_ENV !== "production" ? protocol : void 0, + options + ); +} +function defineAsyncApi(name, fn, protocol, options) { + return promisify( + name, + wrapperAsyncApi(name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options) + ); +} +const API_ON_TAB_BAR_MID_BUTTON_TAP = "onTabBarMidButtonTap"; +const API_GET_LOCALE = "getLocale"; +const getLocale = /* @__PURE__ */ defineSyncApi( + API_GET_LOCALE, + () => { + const app = getApp({ allowDefault: true }); + if (app && app.$vm) { + return app.$vm.$locale; + } + return useI18n().getLocale(); + } +); +const API_GET_STORAGE = "getStorage"; +const GetStorageProtocol = { + key: { + type: String, + required: true + } +}; +const API_GET_STORAGE_SYNC = "getStorageSync"; +const GetStorageSyncProtocol = [ + { + name: "key", + type: String, + required: true + } +]; +const API_SET_STORAGE = "setStorage"; +const SetStorageProtocol = { + key: { + type: String, + required: true + }, + data: { + required: true + } +}; +const API_SET_STORAGE_SYNC = "setStorageSync"; +const SetStorageSyncProtocol = [ + { + name: "key", + type: String, + required: true + }, + { + name: "data", + required: true + } +]; +const API_REMOVE_STORAGE = "removeStorage"; +const RemoveStorageProtocol = GetStorageProtocol; +const RemoveStorageSyncProtocol = GetStorageSyncProtocol; +const API_REQUEST = "request"; +const dataType = { + JSON: "json" +}; +const RESPONSE_TYPE = ["text", "arraybuffer"]; +const DEFAULT_RESPONSE_TYPE = "text"; +const encode = encodeURIComponent; +function stringifyQuery(url, data) { + let str = url.split("#"); + const hash = str[1] || ""; + str = str[0].split("?"); + let query = str[1] || ""; + url = str[0]; + const search = query.split("&").filter((item) => item); + const params = {}; + search.forEach((item) => { + const part = item.split("="); + params[part[0]] = part[1]; + }); + for (const key in data) { + if (shared.hasOwn(data, key)) { + let v2 = data[key]; + if (typeof v2 === "undefined" || v2 === null) { + v2 = ""; + } else if (shared.isPlainObject(v2)) { + v2 = JSON.stringify(v2); + } + params[encode(key)] = encode(v2); + } + } + query = Object.keys(params).map((item) => `${item}=${params[item]}`).join("&"); + return url + (query ? "?" + query : "") + (hash ? "#" + hash : ""); +} +const RequestProtocol = { + method: String, + data: [Object, String, Array, ArrayBuffer], + url: { + type: String, + required: true + }, + header: Object, + dataType: String, + responseType: String, + withCredentials: Boolean +}; +const RequestOptions = { + formatArgs: { + method(value, params) { + params.method = elemInArray( + (value || "").toUpperCase(), + HTTP_METHODS + ); + }, + data(value, params) { + params.data = value || ""; + }, + url(value, params) { + if (params.method === HTTP_METHODS[0] && shared.isPlainObject(params.data) && Object.keys(params.data).length) { + params.url = stringifyQuery(value, params.data); + } + }, + header(value, params) { + const header = params.header = value || {}; + if (params.method !== HTTP_METHODS[0]) { + if (!Object.keys(header).find( + (key) => key.toLowerCase() === "content-type" + )) { + header["Content-Type"] = "application/json"; + } + } + }, + dataType(value, params) { + params.dataType = (value || dataType.JSON).toLowerCase(); + }, + responseType(value, params) { + params.responseType = (value || "").toLowerCase(); + if (RESPONSE_TYPE.indexOf(params.responseType) === -1) { + params.responseType = DEFAULT_RESPONSE_TYPE; + } + } + } +}; +const API_SET_NAVIGATION_BAR_COLOR = "setNavigationBarColor"; +const API_SET_NAVIGATION_BAR_TITLE = "setNavigationBarTitle"; +const SetNavigationBarTitleProtocol = { + title: { + type: String, + required: true + } +}; +const API_SHOW_NAVIGATION_BAR_LOADING = "showNavigationBarLoading"; +const API_HIDE_NAVIGATION_BAR_LOADING = "hideNavigationBarLoading"; +function saveImage(base64, dirname, callback) { + callback(null, base64); +} +const files = {}; +function urlToFile(url, local) { + const file = files[url]; + if (file) { + return Promise.resolve(file); + } + if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) { + return Promise.resolve(base64ToFile(url)); + } + if (local) { + return Promise.reject(new Error("not find")); + } + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.responseType = "blob"; + xhr.onload = function() { + resolve(this.response); + }; + xhr.onerror = reject; + xhr.send(); + }); +} +function base64ToFile(base64) { + const base64Array = base64.split(","); + const res = base64Array[0].match(/:(.*?);/); + const type = res ? res[1] : ""; + const str = atob(base64Array[1]); + let n = str.length; + const array = new Uint8Array(n); + while (n--) { + array[n] = str.charCodeAt(n); + } + return blobToFile(array, type); +} +function getExtname(type) { + const extname = type.split("/")[1]; + return extname ? `.${extname}` : ""; +} +function blobToFile(blob, type) { + let file; + if (blob instanceof File) { + file = blob; + } else { + type = type || blob.type || ""; + const filename = `${Date.now()}${getExtname(type)}`; + try { + file = new File([blob], filename, { type }); + } catch (error) { + blob = blob instanceof Blob ? blob : new Blob([blob], { type }); + file = blob; + file.name = file.name || filename; + } + } + return file; +} +function fileToUrl(file) { + for (const key in files) { + if (shared.hasOwn(files, key)) { + const oldFile = files[key]; + if (oldFile === file) { + return key; + } + } + } + var url = (window.URL || window.webkitURL).createObjectURL(file); + files[url] = file; + return url; +} +function getSameOriginUrl(url) { + const a = document.createElement("a"); + a.href = url; + if (a.origin === location.origin) { + return Promise.resolve(url); + } + return urlToFile(url).then(fileToUrl); +} +const inflateRaw = (...args) => { +}; +const deflateRaw = (...args) => { +}; +const ResizeSensor = /* @__PURE__ */ defineBuiltInComponent({ + name: "ResizeSensor", + props: { + initial: { + type: Boolean, + default: false + } + }, + emits: ["resize"], + setup(props2, { + emit: emit2 + }) { + const rootRef = vue.ref(null); + const reset = useResizeSensorReset(rootRef); + const update = useResizeSensorUpdate(rootRef, emit2, reset); + return () => vue.createVNode("uni-resize-sensor", { + "ref": rootRef, + "onAnimationstartOnce": update + }, [vue.createVNode("div", { + "onScroll": update + }, [vue.createVNode("div", null, null)], 40, ["onScroll"]), vue.createVNode("div", { + "onScroll": update + }, [vue.createVNode("div", null, null)], 40, ["onScroll"])], 40, ["onAnimationstartOnce"]); + } +}); +function useResizeSensorUpdate(rootRef, emit2, reset) { + const size = vue.reactive({ + width: -1, + height: -1 + }); + vue.watch(() => shared.extend({}, size), (value) => emit2("resize", value)); + return () => { + const rootEl = rootRef.value; + size.width = rootEl.offsetWidth; + size.height = rootEl.offsetHeight; + reset(); + }; +} +function useResizeSensorReset(rootRef) { + return () => { + const { + firstElementChild, + lastElementChild + } = rootRef.value; + firstElementChild.scrollLeft = 1e5; + firstElementChild.scrollTop = 1e5; + lastElementChild.scrollLeft = 1e5; + lastElementChild.scrollTop = 1e5; + }; +} +const pixelRatio = 1; +function wrapper(canvas, hidpi = true) { + canvas.width = canvas.offsetWidth * (hidpi ? pixelRatio : 1); + canvas.height = canvas.offsetHeight * (hidpi ? pixelRatio : 1); + canvas.getContext("2d").__hidpi__ = hidpi; +} +const initHidpiOnce = /* @__PURE__ */ uniShared.once(() => { + return void 0; +}); +function $getRealPath(src) { + return src ? getRealPath(src) : src; +} +function resolveColor(color) { + color = color.slice(0); + color[3] = color[3] / 255; + return "rgba(" + color.join(",") + ")"; +} +function processTouches(rect, touches) { + Array.from(touches).forEach((touch) => { + touch.x = touch.clientX - rect.left; + touch.y = touch.clientY - rect.top; + }); +} +let tempCanvas; +function getTempCanvas(width = 0, height = 0) { + if (!tempCanvas) { + tempCanvas = document.createElement("canvas"); + } + tempCanvas.width = width; + tempCanvas.height = height; + return tempCanvas; +} +const props$q = { + canvasId: { + type: String, + default: "" + }, + disableScroll: { + type: [Boolean, String], + default: false + }, + hidpi: { + type: Boolean, + default: true + } +}; +const index$z = /* @__PURE__ */ defineBuiltInComponent({ + inheritAttrs: false, + name: "Canvas", + compatConfig: { + MODE: 3 + }, + props: props$q, + computed: { + id() { + return this.canvasId; + } + }, + setup(props2, { + emit: emit2, + slots + }) { + initHidpiOnce(); + const canvas = vue.ref(null); + const sensor = vue.ref(null); + const actionsWaiting = vue.ref(false); + const trigger = useNativeEvent(emit2); + const { + $attrs, + $excludeAttrs, + $listeners + } = useAttrs({ + excludeListeners: true + }); + const { + _listeners + } = useListeners(props2, $listeners, trigger); + const { + _handleSubscribe, + _resize + } = useMethods(props2, canvas, actionsWaiting); + useSubscribe(_handleSubscribe, useContextInfo(props2.canvasId)); + return () => { + const { + canvasId, + disableScroll + } = props2; + return vue.createVNode("uni-canvas", vue.mergeProps({ + "canvas-id": canvasId, + "disable-scroll": disableScroll + }, $attrs.value, $excludeAttrs.value, _listeners.value), [vue.createVNode("canvas", { + "ref": canvas, + "class": "uni-canvas-canvas", + "width": "300", + "height": "150" + }, null, 512), vue.createVNode("div", { + "style": "position: absolute;top: 0;left: 0;width: 100%;height: 100%;overflow: hidden;" + }, [slots.default && slots.default()]), vue.createVNode(ResizeSensor, { + "ref": sensor, + "onResize": _resize + }, null, 8, ["onResize"])], 16, ["canvas-id", "disable-scroll"]); + }; + } +}); +function useListeners(props2, Listeners, trigger) { + const _listeners = vue.computed(() => { + let events = ["onTouchstart", "onTouchmove", "onTouchend"]; + let _$listeners = Listeners.value; + let $listeners = shared.extend({}, (() => { + let obj = {}; + for (const key in _$listeners) { + if (shared.hasOwn(_$listeners, key)) { + const event = _$listeners[key]; + obj[key] = event; + } + } + return obj; + })()); + events.forEach((event) => { + let existing = $listeners[event]; + let eventHandler = []; + if (existing) { + eventHandler.push(withWebEvent(($event) => { + const rect = $event.currentTarget.getBoundingClientRect(); + processTouches(rect, $event.touches); + processTouches(rect, $event.changedTouches); + trigger(event.replace("on", "").toLocaleLowerCase(), $event); + })); + } + if (props2.disableScroll && event === "onTouchmove") { + eventHandler.push(onEventPrevent); + } + $listeners[event] = eventHandler; + }); + return $listeners; + }); + return { + _listeners + }; +} +function useMethods(props2, canvasRef, actionsWaiting) { + let _actionsDefer = []; + let _images = {}; + const _pixelRatio = vue.computed(() => props2.hidpi ? pixelRatio : 1); + function _resize(size) { + let canvas = canvasRef.value; + var hasChanged = !size || canvas.width !== Math.floor(size.width * _pixelRatio.value) || canvas.height !== Math.floor(size.height * _pixelRatio.value); + if (!hasChanged) + return; + if (canvas.width > 0 && canvas.height > 0) { + let context = canvas.getContext("2d"); + let imageData = context.getImageData(0, 0, canvas.width, canvas.height); + wrapper(canvas, props2.hidpi); + context.putImageData(imageData, 0, 0); + } else { + wrapper(canvas, props2.hidpi); + } + } + function actionsChanged({ + actions, + reserve + }, resolve) { + if (!actions) { + return; + } + if (actionsWaiting.value) { + _actionsDefer.push([actions, reserve]); + return; + } + let canvas = canvasRef.value; + let c2d = canvas.getContext("2d"); + if (!reserve) { + c2d.fillStyle = "#000000"; + c2d.strokeStyle = "#000000"; + c2d.shadowColor = "#000000"; + c2d.shadowBlur = 0; + c2d.shadowOffsetX = 0; + c2d.shadowOffsetY = 0; + c2d.setTransform(1, 0, 0, 1, 0, 0); + c2d.clearRect(0, 0, canvas.width, canvas.height); + } + preloadImage(actions); + for (let index2 = 0; index2 < actions.length; index2++) { + const action = actions[index2]; + let method = action.method; + const data = action.data; + const actionType = data[0]; + if (/^set/.test(method) && method !== "setTransform") { + const method1 = method[3].toLowerCase() + method.slice(4); + let color; + if (method1 === "fillStyle" || method1 === "strokeStyle") { + if (actionType === "normal") { + color = resolveColor(data[1]); + } else if (actionType === "linear") { + const LinearGradient = c2d.createLinearGradient(...data[1]); + data[2].forEach(function(data2) { + const offset = data2[0]; + const color2 = resolveColor(data2[1]); + LinearGradient.addColorStop(offset, color2); + }); + color = LinearGradient; + } else if (actionType === "radial") { + let _data = data[1]; + const x = _data[0]; + const y = _data[1]; + const r = _data[2]; + const LinearGradient = c2d.createRadialGradient(x, y, 0, x, y, r); + data[2].forEach(function(data2) { + const offset = data2[0]; + const color2 = resolveColor(data2[1]); + LinearGradient.addColorStop(offset, color2); + }); + color = LinearGradient; + } else if (actionType === "pattern") { + const loaded = checkImageLoaded(data[1], actions.slice(index2 + 1), resolve, function(image) { + if (image) { + c2d[method1] = c2d.createPattern(image, data[2]); + } + }); + if (!loaded) { + break; + } + continue; + } + c2d[method1] = color; + } else if (method1 === "globalAlpha") { + c2d[method1] = Number(actionType) / 255; + } else if (method1 === "shadow") { + let shadowArray = ["shadowOffsetX", "shadowOffsetY", "shadowBlur", "shadowColor"]; + data.forEach(function(color_, method_) { + c2d[shadowArray[method_]] = shadowArray[method_] === "shadowColor" ? resolveColor(color_) : color_; + }); + } else if (method1 === "fontSize") { + const font = c2d.__font__ || c2d.font; + c2d.__font__ = c2d.font = font.replace(/\d+\.?\d*px/, actionType + "px"); + } else if (method1 === "lineDash") { + c2d.setLineDash(actionType); + c2d.lineDashOffset = data[1] || 0; + } else if (method1 === "textBaseline") { + if (actionType === "normal") { + data[0] = "alphabetic"; + } + c2d[method1] = actionType; + } else if (method1 === "font") { + c2d.__font__ = c2d.font = actionType; + } else { + c2d[method1] = actionType; + } + } else if (method === "fillPath" || method === "strokePath") { + method = method.replace(/Path/, ""); + c2d.beginPath(); + data.forEach(function(data_) { + c2d[data_.method].apply(c2d, data_.data); + }); + c2d[method](); + } else if (method === "fillText") { + c2d.fillText.apply(c2d, data); + } else if (method === "drawImage") { + let drawImage = function() { + let dataArray = [...data]; + let url = dataArray[0]; + let otherData = dataArray.slice(1); + _images = _images || {}; + if (!checkImageLoaded(url, actions.slice(index2 + 1), resolve, function(image) { + if (image) { + c2d.drawImage.apply( + c2d, + // @ts-ignore + [image].concat( + // @ts-ignore + [...otherData.slice(4, 8)], + [...otherData.slice(0, 4)] + ) + ); + } + })) + return "break"; + }(); + if (drawImage === "break") { + break; + } + } else { + if (method === "clip") { + data.forEach(function(data_) { + c2d[data_.method].apply(c2d, data_.data); + }); + c2d.clip(); + } else { + c2d[method].apply(c2d, data); + } + } + } + if (!actionsWaiting.value) { + resolve({ + errMsg: "drawCanvas:ok" + }); + } + } + function preloadImage(actions) { + actions.forEach(function(action) { + let method = action.method; + let data = action.data; + let src = ""; + if (method === "drawImage") { + src = data[0]; + src = $getRealPath(src); + data[0] = src; + } else if (method === "setFillStyle" && data[0] === "pattern") { + src = data[1]; + src = $getRealPath(src); + data[1] = src; + } + if (src && !_images[src]) { + loadImage(); + } + function loadImage() { + const image = _images[src] = new Image(); + image.onload = function() { + image.ready = true; + }; + getSameOriginUrl(src).then((src2) => { + image.src = src2; + }).catch(() => { + image.src = src; + }); + } + }); + } + function checkImageLoaded(src, actions, resolve, fn) { + let image = _images[src]; + if (image.ready) { + fn(image); + return true; + } else { + _actionsDefer.unshift([actions, true]); + actionsWaiting.value = true; + image.onload = function() { + image.ready = true; + fn(image); + actionsWaiting.value = false; + let actions2 = _actionsDefer.slice(0); + _actionsDefer = []; + for (let action = actions2.shift(); action; ) { + actionsChanged({ + actions: action[0], + reserve: action[1] + }, resolve); + action = actions2.shift(); + } + }; + return false; + } + } + function getImageData({ + x = 0, + y = 0, + width, + height, + destWidth, + destHeight, + hidpi = true, + dataType: dataType2, + quality = 1, + type = "png" + }, resolve) { + const canvas = canvasRef.value; + let data; + const maxWidth = canvas.offsetWidth - x; + width = width ? Math.min(width, maxWidth) : maxWidth; + const maxHeight = canvas.offsetHeight - y; + height = height ? Math.min(height, maxHeight) : maxHeight; + if (!hidpi) { + if (!destWidth && !destHeight) { + destWidth = Math.round(width * _pixelRatio.value); + destHeight = Math.round(height * _pixelRatio.value); + } else if (!destWidth) { + destWidth = Math.round(width / height * destHeight); + } else if (!destHeight) { + destHeight = Math.round(height / width * destWidth); + } + } else { + destWidth = width; + destHeight = height; + } + const newCanvas = getTempCanvas(destWidth, destHeight); + const context = newCanvas.getContext("2d"); + if (type === "jpeg" || type === "jpg") { + type = "jpeg"; + context.fillStyle = "#fff"; + context.fillRect(0, 0, destWidth, destHeight); + } + context.__hidpi__ = true; + context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false); + let result; + try { + let compressed; + if (dataType2 === "base64") { + data = newCanvas.toDataURL(`image/${type}`, quality); + } else { + const imgData = context.getImageData(0, 0, destWidth, destHeight); + if (false) + ; + else { + data = Array.prototype.slice.call(imgData.data); + } + } + result = { + data, + compressed, + width: destWidth, + height: destHeight + }; + } catch (error) { + result = { + errMsg: `canvasGetImageData:fail ${error}` + }; + } + newCanvas.height = newCanvas.width = 0; + context.__hidpi__ = false; + if (!resolve) { + return result; + } else { + resolve(result); + } + } + function putImageData({ + data, + x, + y, + width, + height, + compressed + }, resolve) { + try { + if (false) + ; + if (!height) { + height = Math.round(data.length / 4 / width); + } + const canvas = getTempCanvas(width, height); + const context = canvas.getContext("2d"); + context.putImageData(new ImageData(new Uint8ClampedArray(data), width, height), 0, 0); + canvasRef.value.getContext("2d").drawImage(canvas, x, y, width, height); + canvas.height = canvas.width = 0; + } catch (error) { + resolve({ + errMsg: "canvasPutImageData:fail" + }); + return; + } + resolve({ + errMsg: "canvasPutImageData:ok" + }); + } + function toTempFilePath({ + x = 0, + y = 0, + width, + height, + destWidth, + destHeight, + fileType, + quality, + dirname + }, resolve) { + const res = getImageData({ + x, + y, + width, + height, + destWidth, + destHeight, + hidpi: false, + dataType: "base64", + type: fileType, + quality + }); + if (!res.data || !res.data.length) { + resolve({ + errMsg: res.errMsg.replace("canvasPutImageData", "toTempFilePath") + }); + return; + } + saveImage(res.data, dirname, (error, tempFilePath) => { + let errMsg = `toTempFilePath:${error ? "fail" : "ok"}`; + if (error) { + errMsg += ` ${error.message}`; + } + resolve({ + errMsg, + tempFilePath + }); + }); + } + const methods = { + actionsChanged, + getImageData, + putImageData, + toTempFilePath + }; + function _handleSubscribe(type, data, resolve) { + let method = methods[type]; + if (type.indexOf("_") !== 0 && shared.isFunction(method)) { + method(data, resolve); + } + } + return shared.extend(methods, { + _resize, + _handleSubscribe + }); +} +const uniCheckGroupKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniCheckGroup" : "ucg"); +const props$p = { + name: { + type: String, + default: "" + } +}; +const index$y = /* @__PURE__ */ defineBuiltInComponent({ + name: "CheckboxGroup", + props: props$p, + emits: ["change"], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + useProvideCheckGroup(props2, trigger); + return () => { + return vue.createVNode("uni-checkbox-group", { + "ref": rootRef + }, [slots.default && slots.default()], 512); + }; + } +}); +function useProvideCheckGroup(props2, trigger) { + const fields2 = []; + const getFieldsValue = () => fields2.reduce((res, field) => { + if (field.value.checkboxChecked) { + res.push(field.value.value); + } + return res; + }, new Array()); + vue.provide(uniCheckGroupKey, { + addField(field) { + fields2.push(field); + }, + removeField(field) { + fields2.splice(fields2.indexOf(field), 1); + }, + checkboxChange($event) { + trigger("change", $event, { + value: getFieldsValue() + }); + } + }); + const uniForm = vue.inject(uniFormKey, false); + if (uniForm) { + uniForm.addField({ + submit: () => { + let data = ["", null]; + if (props2.name !== "") { + data[0] = props2.name; + data[1] = getFieldsValue(); + } + return data; + } + }); + } + return getFieldsValue; +} +const props$o = { + checked: { + type: [Boolean, String], + default: false + }, + id: { + type: String, + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "#007aff" + }, + value: { + type: String, + default: "" + } +}; +const index$x = /* @__PURE__ */ defineBuiltInComponent({ + name: "Checkbox", + props: props$o, + setup(props2, { + slots + }) { + const checkboxChecked = vue.ref(props2.checked); + const checkboxValue = vue.ref(props2.value); + vue.watch([() => props2.checked, () => props2.value], ([newChecked, newModelValue]) => { + checkboxChecked.value = newChecked; + checkboxValue.value = newModelValue; + }); + const reset = () => { + checkboxChecked.value = false; + }; + const { + uniCheckGroup, + uniLabel + } = useCheckboxInject(checkboxChecked, checkboxValue, reset); + const _onClick = ($event) => { + if (props2.disabled) { + return; + } + checkboxChecked.value = !checkboxChecked.value; + uniCheckGroup && uniCheckGroup.checkboxChange($event); + $event.stopPropagation(); + }; + if (!!uniLabel) { + uniLabel.addHandler(_onClick); + } + return () => { + const booleanAttrs = useBooleanAttr(props2, "disabled"); + return vue.createVNode("uni-checkbox", vue.mergeProps(booleanAttrs, { + "onClick": _onClick + }), [vue.createVNode("div", { + "class": "uni-checkbox-wrapper" + }, [vue.createVNode("div", { + "class": ["uni-checkbox-input", { + "uni-checkbox-input-disabled": props2.disabled + }] + }, [checkboxChecked.value ? createSvgIconVNode(ICON_PATH_SUCCESS_NO_CIRCLE, props2.color, 22) : ""], 2), slots.default && slots.default()])], 16, ["onClick"]); + }; + } +}); +function useCheckboxInject(checkboxChecked, checkboxValue, reset) { + const field = vue.computed(() => ({ + checkboxChecked: Boolean(checkboxChecked.value), + value: checkboxValue.value + })); + const formField = { + reset + }; + const uniCheckGroup = vue.inject(uniCheckGroupKey, false); + if (!!uniCheckGroup) { + uniCheckGroup.addField(field); + } + const uniForm = vue.inject(uniFormKey, false); + if (!!uniForm) { + uniForm.addField(formField); + } + const uniLabel = vue.inject(uniLabelKey, false); + return { + uniCheckGroup, + uniForm, + uniLabel + }; +} +let resetTimer; +function iosHideKeyboard() { +} +const props$n = { + cursorSpacing: { + type: [Number, String], + default: 0 + }, + showConfirmBar: { + type: [Boolean, String], + default: "auto" + }, + adjustPosition: { + type: [Boolean, String], + default: true + }, + autoBlur: { + type: [Boolean, String], + default: false + } +}; +const emit$1 = ["keyboardheightchange"]; +function useKeyboard$1(props2, elRef, trigger) { + function initKeyboard(el) { + const isApple = vue.computed( + () => String(navigator.vendor).indexOf("Apple") === 0 + ); + el.addEventListener("focus", () => { + clearTimeout(resetTimer); + document.addEventListener("click", iosHideKeyboard, false); + }); + const onKeyboardHide = () => { + document.removeEventListener("click", iosHideKeyboard, false); + if (isApple.value) { + document.documentElement.scrollTo( + document.documentElement.scrollLeft, + document.documentElement.scrollTop + ); + } + }; + el.addEventListener("blur", () => { + if (isApple.value) { + el.blur(); + } + onKeyboardHide(); + }); + } + vue.watch( + () => elRef.value, + (el) => el && initKeyboard(el) + ); +} +var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; +var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; +var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; +var empty = /* @__PURE__ */ makeMap( + "area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr" +); +var block = /* @__PURE__ */ makeMap( + "a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video" +); +var inline = /* @__PURE__ */ makeMap( + "abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var" +); +var closeSelf = /* @__PURE__ */ makeMap( + "colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr" +); +var fillAttrs = /* @__PURE__ */ makeMap( + "checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected" +); +var special = /* @__PURE__ */ makeMap("script,style"); +function HTMLParser(html, handler) { + var index2; + var chars; + var match; + var stack = []; + var last = html; + stack.last = function() { + return this[this.length - 1]; + }; + while (html) { + chars = true; + if (!stack.last() || !special[stack.last()]) { + if (html.indexOf(""); + if (index2 >= 0) { + if (handler.comment) { + handler.comment(html.substring(4, index2)); + } + html = html.substring(index2 + 3); + chars = false; + } + } else if (html.indexOf("]*>"), + function(all, text2) { + text2 = text2.replace( + /|/g, + "$1$2" + ); + if (handler.chars) { + handler.chars(text2); + } + return ""; + } + ); + parseEndTag("", stack.last()); + } + if (html == last) { + throw "Parse Error: " + html; + } + last = html; + } + parseEndTag(); + function parseStartTag(tag, tagName, rest, unary) { + tagName = tagName.toLowerCase(); + if (block[tagName]) { + while (stack.last() && inline[stack.last()]) { + parseEndTag("", stack.last()); + } + } + if (closeSelf[tagName] && stack.last() == tagName) { + parseEndTag("", tagName); + } + unary = empty[tagName] || !!unary; + if (!unary) { + stack.push(tagName); + } + if (handler.start) { + var attrs = []; + rest.replace(attr, function(match2, name) { + var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : ""; + attrs.push({ + name, + value, + escaped: value.replace(/(^|[^\\])"/g, '$1\\"') + // " + }); + }); + if (handler.start) { + handler.start(tagName, attrs, unary); + } + } + } + function parseEndTag(tag, tagName) { + if (!tagName) { + var pos = 0; + } else { + for (var pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos] == tagName) { + break; + } + } + } + if (pos >= 0) { + for (var i = stack.length - 1; i >= pos; i--) { + if (handler.end) { + handler.end(stack[i]); + } + } + stack.length = pos; + } + } +} +function makeMap(str) { + var obj = {}; + var items = str.split(","); + for (var i = 0; i < items.length; i++) { + obj[items[i]] = true; + } + return obj; +} +function useQuill(props2, rootRef, trigger) { + vue.watch( + () => props2.readOnly, + (value) => { + } + ); + vue.watch( + () => props2.placeholder, + (value) => { + } + ); + useContextInfo(); + useSubscribe(); +} +const props$m = /* @__PURE__ */ shared.extend({}, props$n, { + id: { + type: String, + default: "" + }, + readOnly: { + type: [Boolean, String], + default: false + }, + placeholder: { + type: String, + default: "" + }, + showImgSize: { + type: [Boolean, String], + default: false + }, + showImgToolbar: { + type: [Boolean, String], + default: false + }, + showImgResize: { + type: [Boolean, String], + default: false + } +}); +const index$w = /* @__PURE__ */ defineBuiltInComponent({ + name: "Editor", + props: props$m, + emit: ["ready", "focus", "blur", "input", "statuschange", ...emit$1], + setup(props2, { + emit: emit2 + }) { + const rootRef = vue.ref(null); + useQuill(props2); + useKeyboard$1(props2, rootRef); + return () => { + return vue.createVNode("uni-editor", { + "ref": rootRef, + "id": props2.id, + "class": "ql-container" + }, null, 8, ["id"]); + }; + } +}); +const INFO_COLOR = "#10aeff"; +const WARN_COLOR = "#f76260"; +const GREY_COLOR = "#b2b2b2"; +const CANCEL_COLOR = "#f43530"; +const ICONS = { + success: { + d: ICON_PATH_SUCCESS, + c: uniShared.PRIMARY_COLOR + }, + success_no_circle: { + d: ICON_PATH_SUCCESS_NO_CIRCLE, + c: uniShared.PRIMARY_COLOR + }, + info: { + d: ICON_PATH_INFO, + c: INFO_COLOR + }, + warn: { + d: ICON_PATH_WARN, + c: WARN_COLOR + }, + waiting: { + d: ICON_PATH_WAITING, + c: INFO_COLOR + }, + cancel: { + d: ICON_PATH_CANCEL, + c: CANCEL_COLOR + }, + download: { + d: ICON_PATH_DOWNLOAD, + c: uniShared.PRIMARY_COLOR + }, + search: { + d: ICON_PATH_SEARCH, + c: GREY_COLOR + }, + clear: { + d: ICON_PATH_CLEAR, + c: GREY_COLOR + } +}; +const index$v = /* @__PURE__ */ defineBuiltInComponent({ + name: "Icon", + props: { + type: { + type: String, + required: true, + default: "" + }, + size: { + type: [String, Number], + default: 23 + }, + color: { + type: String, + default: "" + } + }, + setup(props2) { + const path = vue.computed(() => ICONS[props2.type]); + return () => { + const { + value + } = path; + return vue.createVNode("uni-icon", null, [value && value.d && createSvgIconVNode(value.d, props2.color || value.c, rpx2px(props2.size))]); + }; + } +}); +const props$l = { + src: { + type: String, + default: "" + }, + mode: { + type: String, + default: "scaleToFill" + }, + lazyLoad: { + type: [Boolean, String], + default: false + }, + draggable: { + type: Boolean, + default: false + } +}; +const FIX_MODES = { + widthFix: ["offsetWidth", "height", (value, ratio) => value / ratio], + heightFix: ["offsetHeight", "width", (value, ratio) => value * ratio] +}; +const IMAGE_MODES = { + aspectFit: ["center center", "contain"], + aspectFill: ["center center", "cover"], + widthFix: [, "100% 100%"], + heightFix: [, "100% 100%"], + top: ["center top"], + bottom: ["center bottom"], + center: ["center center"], + left: ["left center"], + right: ["right center"], + "top left": ["left top"], + "top right": ["right top"], + "bottom left": ["left bottom"], + "bottom right": ["right bottom"] +}; +const index$u = /* @__PURE__ */ defineBuiltInComponent({ + name: "Image", + props: props$l, + setup(props2, { + emit: emit2 + }) { + const rootRef = vue.ref(null); + const state = useImageState(rootRef, props2); + const trigger = useCustomEvent(rootRef, emit2); + const { + fixSize + } = useImageSize(rootRef, props2, state); + useImageLoader(state, props2, rootRef, fixSize, trigger); + return () => { + return vue.createVNode("uni-image", { + "ref": rootRef + }, [vue.createVNode("div", { + "style": state.modeStyle + }, null, 4), FIX_MODES[props2.mode] ? ( + // @ts-ignore + vue.createVNode(ResizeSensor, { + "onResize": fixSize + }, null, 8, ["onResize"]) + ) : vue.createVNode("span", null, null)], 512); + }; + } +}); +function useImageState(rootRef, props2) { + const imgSrc = vue.ref(""); + const modeStyleRef = vue.computed(() => { + let size = "auto"; + let position = ""; + const opts = IMAGE_MODES[props2.mode]; + if (!opts) { + position = "0% 0%"; + size = "100% 100%"; + } else { + opts[0] && (position = opts[0]); + opts[1] && (size = opts[1]); + } + if (window.weibo && props2.src.startsWith("Temp")) { + imgSrc.value = `../../${props2.src}`; + } + return `background-image:${imgSrc.value ? 'url("' + imgSrc.value + '")' : "none"};background-position:${position};background-size:${size};`; + }); + const state = vue.reactive({ + rootEl: rootRef, + src: vue.computed(function() { + if (window.weibo && props2.src.startsWith("Temp")) { + return `../../${props2.src}`; + } + return props2.src ? getRealPath(props2.src) : ""; + }), + origWidth: 0, + origHeight: 0, + origStyle: { + width: "", + height: "" + }, + modeStyle: modeStyleRef, + imgSrc + }); + return state; +} +function useImageLoader(state, props2, rootRef, fixSize, trigger) { + let img; + let draggableImg; + const setState = (width = 0, height = 0, imgSrc = "") => { + state.origWidth = width; + state.origHeight = height; + state.imgSrc = imgSrc; + }; + const loadImage = (src) => { + if (!src) { + resetImage(); + setState(); + return; + } + img = img || new Image(); + img.onload = (evt) => { + const { + width, + height + } = img; + setState(width, height, src); + fixSize(); + img.draggable = props2.draggable; + if (draggableImg) { + draggableImg.remove(); + } + draggableImg = img; + rootRef.value.appendChild(img); + resetImage(); + trigger("load", evt, { + width, + height + }); + }; + img.onerror = (evt) => { + setState(); + resetImage(); + trigger("error", evt, { + errMsg: `GET ${state.src} 404 (Not Found)` + }); + }; + img.src = src; + }; + const resetImage = () => { + if (img) { + img.onload = null; + img.onerror = null; + img = null; + } + }; + vue.watch(() => state.src, (value) => loadImage(value)); + vue.watch(() => state.imgSrc, (value) => { + if (!value && draggableImg) { + draggableImg.remove(); + draggableImg = null; + } + }); +} +function fixNumber(num) { + return num; +} +function useImageSize(rootRef, props2, state) { + const fixSize = () => { + const { + mode: mode2 + } = props2; + const names = FIX_MODES[mode2]; + if (!names) { + return; + } + const { + origWidth, + origHeight + } = state; + const ratio = origWidth && origHeight ? origWidth / origHeight : 0; + if (!ratio) { + return; + } + const rootEl = rootRef.value; + const value = rootEl[names[0]]; + if (value) { + rootEl.style[names[1]] = fixNumber(names[2](value, ratio)) + "px"; + } + }; + const resetSize = () => { + const { + style + } = rootRef.value; + const { + origStyle: { + width, + height + } + } = state; + style.width = width; + style.height = height; + }; + vue.watch(() => props2.mode, (value, oldValue) => { + if (FIX_MODES[oldValue]) { + resetSize(); + } + if (FIX_MODES[value]) { + fixSize(); + } + }); + return { + fixSize, + resetSize + }; +} +function throttle(fn, wait) { + let last = 0; + let timeout; + let waitCallback; + const newFn = function(...arg) { + const now = Date.now(); + clearTimeout(timeout); + waitCallback = () => { + waitCallback = null; + last = now; + fn.apply(this, arg); + }; + if (now - last < wait) { + timeout = setTimeout(waitCallback, wait - (now - last)); + return; + } + waitCallback(); + }; + newFn.cancel = function() { + clearTimeout(timeout); + waitCallback = null; + }; + newFn.flush = function() { + clearTimeout(timeout); + waitCallback && waitCallback(); + }; + return newFn; +} +function useUserAction() { + const state = vue.reactive({ + /** + * 是否用户激活 + */ + userAction: false + }); + return { + state + }; +} +function useScopedAttrs() { + const state = vue.reactive({ + attrs: {} + }); + return { + state + }; +} +function useFormField(nameKey, value) { + const uniForm = vue.inject( + uniFormKey, + false + // remove warning + ); + if (!uniForm) { + return; + } + const instance = vue.getCurrentInstance(); + const ctx = { + submit() { + const proxy = instance.proxy; + return [ + proxy[nameKey], + shared.isString(value) ? proxy[value] : value.value + ]; + }, + reset() { + if (shared.isString(value)) { + instance.proxy[value] = ""; + } else { + value.value = ""; + } + } + }; + uniForm.addField(ctx); +} +function getSelectedTextRange(_, resolve) { + const activeElement = document.activeElement; + if (!activeElement) { + return resolve({}); + } + const data = {}; + if (["input", "textarea"].includes(activeElement.tagName.toLowerCase())) { + data.start = activeElement.selectionStart; + data.end = activeElement.selectionEnd; + } + resolve(data); +} +const UniViewJSBridgeSubscribe = function() { + registerViewMethod( + getCurrentPageId(), + "getSelectedTextRange", + getSelectedTextRange + ); +}; +function getValueString(value, type) { + if (type === "number" && isNaN(Number(value))) { + value = ""; + } + return value === null ? "" : String(value); +} +const INPUT_MODES = [ + "none", + "text", + "decimal", + "numeric", + "tel", + "search", + "email", + "url" +]; +const props$k = /* @__PURE__ */ shared.extend( + {}, + { + name: { + type: String, + default: "" + }, + modelValue: { + type: [String, Number], + default: "" + }, + value: { + type: [String, Number], + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + /** + * 已废弃属性,用于历史兼容 + */ + autoFocus: { + type: [Boolean, String], + default: false + }, + focus: { + type: [Boolean, String], + default: false + }, + cursor: { + type: [Number, String], + default: -1 + }, + selectionStart: { + type: [Number, String], + default: -1 + }, + selectionEnd: { + type: [Number, String], + default: -1 + }, + type: { + type: String, + default: "text" + }, + password: { + type: [Boolean, String], + default: false + }, + placeholder: { + type: String, + default: "" + }, + placeholderStyle: { + type: String, + default: "" + }, + placeholderClass: { + type: String, + default: "" + }, + maxlength: { + type: [Number, String], + default: 140 + }, + confirmType: { + type: String, + default: "done" + }, + confirmHold: { + type: Boolean, + default: false + }, + ignoreCompositionEvent: { + type: Boolean, + default: true + }, + step: { + type: String, + default: "0.000000000000000001" + }, + inputmode: { + type: String, + default: void 0, + validator: (value) => !!~INPUT_MODES.indexOf(value) + } + }, + props$n +); +const emit = [ + "input", + "focus", + "blur", + "update:value", + "update:modelValue", + "update:focus", + "compositionstart", + "compositionupdate", + "compositionend", + ...emit$1 +]; +function useBase(props2, rootRef, emit2) { + const fieldRef = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const selectionStart = vue.computed(() => { + const selectionStart2 = Number(props2.selectionStart); + return isNaN(selectionStart2) ? -1 : selectionStart2; + }); + const selectionEnd = vue.computed(() => { + const selectionEnd2 = Number(props2.selectionEnd); + return isNaN(selectionEnd2) ? -1 : selectionEnd2; + }); + const cursor = vue.computed(() => { + const cursor2 = Number(props2.cursor); + return isNaN(cursor2) ? -1 : cursor2; + }); + const maxlength = vue.computed(() => { + var maxlength2 = Number(props2.maxlength); + return isNaN(maxlength2) ? 140 : maxlength2; + }); + const value = getValueString(props2.modelValue, props2.type) || getValueString(props2.value, props2.type); + const state = vue.reactive({ + value, + valueOrigin: value, + maxlength, + focus: props2.focus, + composing: false, + selectionStart, + selectionEnd, + cursor + }); + vue.watch( + () => state.focus, + (val) => emit2("update:focus", val) + ); + vue.watch( + () => state.maxlength, + (val) => state.value = state.value.slice(0, val) + ); + return { + fieldRef, + state, + trigger + }; +} +function useValueSync(props2, state, emit2, trigger) { + const valueChangeFn = uniShared.debounce( + (val) => { + state.value = getValueString(val, props2.type); + }, + 100, + { setTimeout, clearTimeout } + ); + vue.watch(() => props2.modelValue, valueChangeFn); + vue.watch(() => props2.value, valueChangeFn); + const triggerInputFn = throttle((event, detail) => { + valueChangeFn.cancel(); + emit2("update:modelValue", detail.value); + emit2("update:value", detail.value); + trigger("input", event, detail); + }, 100); + const triggerInput = (event, detail, force) => { + valueChangeFn.cancel(); + triggerInputFn(event, detail); + if (force) { + triggerInputFn.flush(); + } + }; + return { + trigger, + triggerInput + }; +} +function useAutoFocus(props2, fieldRef) { + useUserAction(); + const needFocus = vue.computed(() => props2.autoFocus || props2.focus); + function focus() { + if (!needFocus.value) { + return; + } + const field = fieldRef.value; + if (!field || false) { + setTimeout(focus, 100); + return; + } + { + field.focus(); + } + } + function blur() { + const field = fieldRef.value; + if (field) { + field.blur(); + } + } + vue.watch( + () => props2.focus, + (value) => { + if (value) { + focus(); + } else { + blur(); + } + } + ); +} +function useEvent(fieldRef, state, props2, trigger, triggerInput, beforeInput) { + function checkSelection() { + const field = fieldRef.value; + if (field && state.focus && state.selectionStart > -1 && state.selectionEnd > -1 && field.type !== "number") { + field.selectionStart = state.selectionStart; + field.selectionEnd = state.selectionEnd; + } + } + function checkCursor() { + const field = fieldRef.value; + if (field && state.focus && state.selectionStart < 0 && state.selectionEnd < 0 && state.cursor > -1 && field.type !== "number") { + field.selectionEnd = field.selectionStart = state.cursor; + } + } + function getFieldSelectionEnd(field) { + if (field.type === "number") { + return null; + } else { + return field.selectionEnd; + } + } + function initField() { + const field = fieldRef.value; + if (!field) + return; + const onFocus = function(event) { + state.focus = true; + trigger("focus", event, { + value: state.value + }); + checkSelection(); + checkCursor(); + }; + const onInput = function(event, force) { + event.stopPropagation(); + if (shared.isFunction(beforeInput) && beforeInput(event, state) === false) { + return; + } + state.value = field.value; + if (!state.composing || !props2.ignoreCompositionEvent) { + triggerInput( + event, + { + value: field.value, + cursor: getFieldSelectionEnd(field) + }, + force + ); + } + }; + const onBlur = function(event) { + if (state.composing) { + state.composing = false; + onInput(event, true); + } + state.focus = false; + trigger("blur", event, { + value: state.value, + cursor: getFieldSelectionEnd(event.target) + }); + }; + field.addEventListener("change", (event) => event.stopPropagation()); + field.addEventListener("focus", onFocus); + field.addEventListener("blur", onBlur); + field.addEventListener("input", onInput); + field.addEventListener("compositionstart", (event) => { + event.stopPropagation(); + state.composing = true; + _onComposition(event); + }); + field.addEventListener("compositionend", (event) => { + event.stopPropagation(); + if (state.composing) { + state.composing = false; + onInput(event); + } + _onComposition(event); + }); + field.addEventListener("compositionupdate", _onComposition); + function _onComposition(event) { + if (!props2.ignoreCompositionEvent) { + trigger(event.type, event, { + value: event.data + }); + } + } + } + vue.watch([() => state.selectionStart, () => state.selectionEnd], checkSelection); + vue.watch(() => state.cursor, checkCursor); + vue.watch(() => fieldRef.value, initField); +} +function useField(props2, rootRef, emit2, beforeInput) { + UniViewJSBridgeSubscribe(); + const { fieldRef, state, trigger } = useBase(props2, rootRef, emit2); + const { triggerInput } = useValueSync(props2, state, emit2, trigger); + useAutoFocus(props2, fieldRef); + useKeyboard$1(props2, fieldRef); + const { state: scopedAttrsState } = useScopedAttrs(); + useFormField("name", state); + useEvent(fieldRef, state, props2, trigger, triggerInput, beforeInput); + const fixDisabledColor = false; + return { + fieldRef, + state, + scopedAttrsState, + fixDisabledColor, + trigger + }; +} +const props$j = /* @__PURE__ */ shared.extend({}, props$k, { + placeholderClass: { + type: String, + default: "input-placeholder" + }, + textContentType: { + type: String, + default: "" + } +}); +const Input = /* @__PURE__ */ defineBuiltInComponent({ + name: "Input", + props: props$j, + emits: ["confirm", ...emit], + setup(props2, { + emit: emit2 + }) { + const INPUT_TYPES = ["text", "number", "idcard", "digit", "password", "tel"]; + const AUTOCOMPLETES = ["off", "one-time-code"]; + const type = vue.computed(() => { + let type2 = ""; + switch (props2.type) { + case "text": + if (props2.confirmType === "search") { + type2 = "search"; + } + break; + case "idcard": + type2 = "text"; + break; + case "digit": + type2 = "number"; + break; + default: + type2 = ~INPUT_TYPES.includes(props2.type) ? props2.type : "text"; + break; + } + return props2.password ? "password" : type2; + }); + const autocomplete = vue.computed(() => { + const camelizeIndex = AUTOCOMPLETES.indexOf(props2.textContentType); + const kebabCaseIndex = AUTOCOMPLETES.indexOf(shared.hyphenate(props2.textContentType)); + const index2 = camelizeIndex !== -1 ? camelizeIndex : kebabCaseIndex !== -1 ? kebabCaseIndex : 0; + return AUTOCOMPLETES[index2]; + }); + let cache = vue.ref(""); + let resetCache; + const rootRef = vue.ref(null); + const { + fieldRef, + state, + scopedAttrsState, + fixDisabledColor, + trigger + } = useField(props2, rootRef, emit2, (event, state2) => { + const input = event.target; + if (type.value === "number") { + if (resetCache) { + input.removeEventListener("blur", resetCache); + resetCache = null; + } + if (input.validity && !input.validity.valid) { + if ((!cache.value || !input.value) && event.data === "-" || cache.value[0] === "-" && event.inputType === "deleteContentBackward") { + cache.value = "-"; + state2.value = ""; + resetCache = () => { + cache.value = input.value = ""; + }; + input.addEventListener("blur", resetCache); + return false; + } + if (cache.value) { + if (cache.value.indexOf(".") !== -1) { + if (event.data !== "." && event.inputType === "deleteContentBackward") { + const dotIndex = cache.value.indexOf("."); + cache.value = input.value = state2.value = cache.value.slice(0, dotIndex); + return true; + } + } else if (event.data === ".") { + cache.value += "."; + resetCache = () => { + cache.value = input.value = cache.value.slice(0, -1); + }; + input.addEventListener("blur", resetCache); + return false; + } + } + cache.value = state2.value = input.value = cache.value === "-" ? "" : cache.value; + return false; + } else { + cache.value = input.value; + } + const maxlength = state2.maxlength; + if (maxlength > 0 && input.value.length > maxlength) { + input.value = input.value.slice(0, maxlength); + state2.value = input.value; + return false; + } + } + }); + vue.watch(() => state.value, (value) => { + if (props2.type === "number" && !(cache.value === "-" && value === "")) { + cache.value = value; + } + }); + const NUMBER_TYPES = ["number", "digit"]; + const step = vue.computed(() => NUMBER_TYPES.includes(props2.type) ? props2.step : ""); + function onKeyUpEnter(event) { + if (event.key !== "Enter") { + return; + } + const input = event.target; + event.stopPropagation(); + trigger("confirm", event, { + value: input.value + }); + !props2.confirmHold && input.blur(); + } + return () => { + let inputNode = props2.disabled && fixDisabledColor ? vue.createVNode("input", { + "key": "disabled-input", + "ref": fieldRef, + "value": state.value, + "tabindex": "-1", + "readonly": !!props2.disabled, + "type": type.value, + "maxlength": state.maxlength, + "step": step.value, + "class": "uni-input-input", + "onFocus": (event) => event.target.blur() + }, null, 40, ["value", "readonly", "type", "maxlength", "step", "onFocus"]) : vue.withDirectives(vue.createVNode("input", { + "key": "input", + "ref": fieldRef, + "onUpdate:modelValue": ($event) => state.value = $event, + "disabled": !!props2.disabled, + "type": type.value, + "maxlength": state.maxlength, + "step": step.value, + "enterkeyhint": props2.confirmType, + "pattern": props2.type === "number" ? "[0-9]*" : void 0, + "class": "uni-input-input", + "autocomplete": autocomplete.value, + "onKeyup": onKeyUpEnter, + "inputmode": props2.inputmode + }, null, 40, ["onUpdate:modelValue", "disabled", "type", "maxlength", "step", "enterkeyhint", "pattern", "autocomplete", "onKeyup", "inputmode"]), [[vue.vModelDynamic, state.value]]); + return vue.createVNode("uni-input", { + "ref": rootRef + }, [vue.createVNode("div", { + "class": "uni-input-wrapper" + }, [vue.withDirectives(vue.createVNode("div", vue.mergeProps(scopedAttrsState.attrs, { + "style": props2.placeholderStyle, + "class": ["uni-input-placeholder", props2.placeholderClass] + }), [props2.placeholder], 16), [[vue.vShow, !(state.value.length || cache.value === "-")]]), props2.confirmType === "search" ? vue.createVNode("form", { + "action": "", + "onSubmit": (event) => event.preventDefault(), + "class": "uni-input-form" + }, [inputNode], 40, ["onSubmit"]) : inputNode])], 512); + }; + } +}); +function entries(obj) { + return Object.keys(obj).map((key) => [key, obj[key]]); +} +const DEFAULT_EXCLUDE_KEYS = ["class", "style"]; +const LISTENER_PREFIX = /^on[A-Z]+/; +const useAttrs = (params = {}) => { + const { excludeListeners = false, excludeKeys = [] } = params; + const instance = vue.getCurrentInstance(); + const attrs = vue.shallowRef({}); + const listeners = vue.shallowRef({}); + const excludeAttrs = vue.shallowRef({}); + const allExcludeKeys = excludeKeys.concat(DEFAULT_EXCLUDE_KEYS); + instance.attrs = vue.reactive(instance.attrs); + vue.watchEffect(() => { + const res = entries(instance.attrs).reduce( + (acc, [key, val]) => { + if (allExcludeKeys.includes(key)) { + acc.exclude[key] = val; + } else if (LISTENER_PREFIX.test(key)) { + if (!excludeListeners) { + acc.attrs[key] = val; + } + acc.listeners[key] = val; + } else { + acc.attrs[key] = val; + } + return acc; + }, + { + exclude: {}, + attrs: {}, + listeners: {} + } + ); + attrs.value = res.attrs; + listeners.value = res.listeners; + excludeAttrs.value = res.exclude; + }); + return { $attrs: attrs, $listeners: listeners, $excludeAttrs: excludeAttrs }; +}; +function flatVNode(nodes) { + const array = []; + if (shared.isArray(nodes)) { + nodes.forEach((vnode) => { + if (vue.isVNode(vnode)) { + if (vnode.type === vue.Fragment) { + array.push(...flatVNode(vnode.children)); + } else { + array.push(vnode); + } + } else if (shared.isArray(vnode)) { + array.push(...flatVNode(vnode)); + } + }); + } + return array; +} +const movableAreaProps = { + scaleArea: { + type: Boolean, + default: false + } +}; +const index$t = /* @__PURE__ */ defineBuiltInComponent({ + inheritAttrs: false, + name: "MovableArea", + props: movableAreaProps, + setup(props2, { + slots + }) { + const rootRef = vue.ref(null); + const _isMounted = vue.ref(false); + let { + setContexts, + events: movableAreaEvents + } = useMovableAreaState(props2, rootRef); + const { + $listeners, + $attrs, + $excludeAttrs + } = useAttrs(); + const _listeners = $listeners.value; + let events = ["onTouchstart", "onTouchmove", "onTouchend"]; + events.forEach((event) => { + let existing = _listeners[event]; + let ours = movableAreaEvents[`_${event}`]; + _listeners[event] = existing ? [].concat(existing, ours) : ours; + }); + let movableViewItems = []; + const originMovableViewContexts = []; + function updateMovableViewContexts() { + const contexts = []; + for (let index2 = 0; index2 < movableViewItems.length; index2++) { + let movableViewItem = movableViewItems[index2]; + { + movableViewItem = movableViewItem.el; + } + const movableViewContext = originMovableViewContexts.find((context) => movableViewItem === context.rootRef.value); + if (movableViewContext) { + contexts.push(vue.markRaw(movableViewContext)); + } + } + setContexts(contexts); + } + const addMovableViewContext = (movableViewContext) => { + originMovableViewContexts.push(movableViewContext); + updateMovableViewContexts(); + }; + const removeMovableViewContext = (movableViewContext) => { + const index2 = originMovableViewContexts.indexOf(movableViewContext); + if (index2 >= 0) { + originMovableViewContexts.splice(index2, 1); + updateMovableViewContexts(); + } + }; + vue.provide("_isMounted", _isMounted); + vue.provide("movableAreaRootRef", rootRef); + vue.provide("addMovableViewContext", addMovableViewContext); + vue.provide("removeMovableViewContext", removeMovableViewContext); + return () => { + const defaultSlots = slots.default && slots.default(); + { + movableViewItems = flatVNode(defaultSlots); + } + return vue.createVNode("uni-movable-area", vue.mergeProps({ + "ref": rootRef + }, $attrs.value, $excludeAttrs.value, _listeners), [vue.createVNode(ResizeSensor, { + "onResize": movableAreaEvents._resize + }, null, 8, ["onResize"]), movableViewItems], 16); + }; + } +}); +function calc(e2) { + return Math.sqrt(e2.x * e2.x + e2.y * e2.y); +} +function useMovableAreaState(props2, rootRef) { + const width = vue.ref(0); + const height = vue.ref(0); + const gapV = vue.reactive({ + x: null, + y: null + }); + const pinchStartLen = vue.ref(null); + let _scaleMovableView = null; + let movableViewContexts = []; + function _updateScale(e2) { + if (e2 && e2 !== 1) { + if (props2.scaleArea) { + movableViewContexts.forEach(function(item) { + item._setScale(e2); + }); + } else { + if (_scaleMovableView) { + _scaleMovableView._setScale(e2); + } + } + } + } + function _find(target, items = movableViewContexts) { + let root = rootRef.value; + function get(node) { + for (let i = 0; i < items.length; i++) { + const item = items[i]; + if (node === item.rootRef.value) { + return item; + } + } + if (node === root || node === document.body || node === document) { + return null; + } + return get(node.parentNode); + } + return get(target); + } + const _onTouchstart = withWebEvent((t2) => { + let i = t2.touches; + if (i) { + if (i.length > 1) { + let r = { + x: i[1].pageX - i[0].pageX, + y: i[1].pageY - i[0].pageY + }; + pinchStartLen.value = calc(r); + gapV.x = r.x; + gapV.y = r.y; + if (!props2.scaleArea) { + let touch0 = _find(i[0].target); + let touch1 = _find(i[1].target); + _scaleMovableView = touch0 && touch0 === touch1 ? touch0 : null; + } + } + } + }); + const _onTouchmove = withWebEvent((t2) => { + let n = t2.touches; + if (n) { + if (n.length > 1) { + t2.preventDefault(); + let i = { + x: n[1].pageX - n[0].pageX, + y: n[1].pageY - n[0].pageY + }; + if (gapV.x !== null && pinchStartLen.value && pinchStartLen.value > 0) { + let r = calc(i) / pinchStartLen.value; + _updateScale(r); + } + gapV.x = i.x; + gapV.y = i.y; + } + } + }); + const _onTouchend = withWebEvent((e2) => { + let t2 = e2.touches; + if (!(t2 && t2.length)) { + if (e2.changedTouches) { + gapV.x = 0; + gapV.y = 0; + pinchStartLen.value = null; + if (props2.scaleArea) { + movableViewContexts.forEach(function(item) { + item._endScale(); + }); + } else { + if (_scaleMovableView) { + _scaleMovableView._endScale(); + } + } + } + } + }); + function _resize() { + _getWH(); + movableViewContexts.forEach(function(item, index2) { + item.setParent(); + }); + } + function _getWH() { + let style = window.getComputedStyle(rootRef.value); + let rect = rootRef.value.getBoundingClientRect(); + width.value = rect.width - ["Left", "Right"].reduce(function(all, item) { + const LEFT = "border" + item + "Width"; + const RIGHT = "padding" + item; + return all + parseFloat(style[LEFT]) + parseFloat(style[RIGHT]); + }, 0); + height.value = rect.height - ["Top", "Bottom"].reduce(function(all, item) { + const TOP = "border" + item + "Width"; + const BOTTOM = "padding" + item; + return all + parseFloat(style[TOP]) + parseFloat(style[BOTTOM]); + }, 0); + } + vue.provide("movableAreaWidth", width); + vue.provide("movableAreaHeight", height); + return { + setContexts(contexts) { + movableViewContexts = contexts; + }, + events: { + _onTouchstart, + _onTouchmove, + _onTouchend, + _resize + } + }; +} +function e(e2, t2, n) { + return e2 > t2 - n && e2 < t2 + n; +} +function t(t2, n) { + return e(t2, 0, n); +} +function Friction(e2, t2) { + this._m = e2; + this._f = 1e3 * t2; + this._startTime = 0; + this._v = 0; +} +Friction.prototype.setV = function(x, y) { + const n = Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5); + this._x_v = x; + this._y_v = y; + this._x_a = -this._f * this._x_v / n; + this._y_a = -this._f * this._y_v / n; + this._t = Math.abs(x / this._x_a) || Math.abs(y / this._y_a); + this._lastDt = null; + this._startTime = (/* @__PURE__ */ new Date()).getTime(); +}; +Friction.prototype.setS = function(x, y) { + this._x_s = x; + this._y_s = y; +}; +Friction.prototype.s = function(t2) { + if (void 0 === t2) { + t2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + if (t2 > this._t) { + t2 = this._t; + this._lastDt = t2; + } + let x = this._x_v * t2 + 0.5 * this._x_a * Math.pow(t2, 2) + this._x_s; + let y = this._y_v * t2 + 0.5 * this._y_a * Math.pow(t2, 2) + this._y_s; + if (this._x_a > 0 && x < this._endPositionX || this._x_a < 0 && x > this._endPositionX) { + x = this._endPositionX; + } + if (this._y_a > 0 && y < this._endPositionY || this._y_a < 0 && y > this._endPositionY) { + y = this._endPositionY; + } + return { + x, + y + }; +}; +Friction.prototype.ds = function(t2) { + if (void 0 === t2) { + t2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + if (t2 > this._t) { + t2 = this._t; + } + return { + dx: this._x_v + this._x_a * t2, + dy: this._y_v + this._y_a * t2 + }; +}; +Friction.prototype.delta = function() { + return { + x: -1.5 * Math.pow(this._x_v, 2) / this._x_a || 0, + y: -1.5 * Math.pow(this._y_v, 2) / this._y_a || 0 + }; +}; +Friction.prototype.dt = function() { + return -this._x_v / this._x_a; +}; +Friction.prototype.done = function() { + const t2 = e(this.s().x, this._endPositionX) || e(this.s().y, this._endPositionY) || this._lastDt === this._t; + this._lastDt = null; + return t2; +}; +Friction.prototype.setEnd = function(x, y) { + this._endPositionX = x; + this._endPositionY = y; +}; +Friction.prototype.reconfigure = function(m, f2) { + this._m = m; + this._f = 1e3 * f2; +}; +function Spring(m, k, c) { + this._m = m; + this._k = k; + this._c = c; + this._solution = null; + this._endPosition = 0; + this._startTime = 0; +} +Spring.prototype._solve = function(e2, t2) { + const n = this._c; + const i = this._m; + const r = this._k; + const o = n * n - 4 * i * r; + if (o === 0) { + const a = -n / (2 * i); + const s = e2; + const l = t2 / (a * e2); + return { + x: function(e3) { + return (s + l * e3) * Math.pow(Math.E, a * e3); + }, + dx: function(e3) { + const t3 = Math.pow(Math.E, a * e3); + return a * (s + l * e3) * t3 + l * t3; + } + }; + } + if (o > 0) { + const c = (-n - Math.sqrt(o)) / (2 * i); + const u = (-n + Math.sqrt(o)) / (2 * i); + const d = (t2 - c * e2) / (u - c); + const h = e2 - d; + return { + x: function(e3) { + let t3; + let n2; + if (e3 === this._t) { + t3 = this._powER1T; + n2 = this._powER2T; + } + this._t = e3; + if (!t3) { + t3 = this._powER1T = Math.pow(Math.E, c * e3); + } + if (!n2) { + n2 = this._powER2T = Math.pow(Math.E, u * e3); + } + return h * t3 + d * n2; + }, + dx: function(e3) { + let t3; + let n2; + if (e3 === this._t) { + t3 = this._powER1T; + n2 = this._powER2T; + } + this._t = e3; + if (!t3) { + t3 = this._powER1T = Math.pow(Math.E, c * e3); + } + if (!n2) { + n2 = this._powER2T = Math.pow(Math.E, u * e3); + } + return h * c * t3 + d * u * n2; + } + }; + } + const p2 = Math.sqrt(4 * i * r - n * n) / (2 * i); + const f2 = -n / 2 * i; + const v2 = e2; + const g2 = (t2 - f2 * e2) / p2; + return { + x: function(e3) { + return Math.pow(Math.E, f2 * e3) * (v2 * Math.cos(p2 * e3) + g2 * Math.sin(p2 * e3)); + }, + dx: function(e3) { + const t3 = Math.pow(Math.E, f2 * e3); + const n2 = Math.cos(p2 * e3); + const i2 = Math.sin(p2 * e3); + return t3 * (g2 * p2 * n2 - v2 * p2 * i2) + f2 * t3 * (g2 * i2 + v2 * n2); + } + }; +}; +Spring.prototype.x = function(e2) { + if (void 0 === e2) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + return this._solution ? this._endPosition + this._solution.x(e2) : 0; +}; +Spring.prototype.dx = function(e2) { + if (void 0 === e2) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + return this._solution ? this._solution.dx(e2) : 0; +}; +Spring.prototype.setEnd = function(e2, n, i) { + if (!i) { + i = (/* @__PURE__ */ new Date()).getTime(); + } + if (e2 !== this._endPosition || !t(n, 0.1)) { + n = n || 0; + let r = this._endPosition; + if (this._solution) { + if (t(n, 0.1)) { + n = this._solution.dx((i - this._startTime) / 1e3); + } + r = this._solution.x((i - this._startTime) / 1e3); + if (t(n, 0.1)) { + n = 0; + } + if (t(r, 0.1)) { + r = 0; + } + r += this._endPosition; + } + if (!(this._solution && t(r - e2, 0.1) && t(n, 0.1))) { + this._endPosition = e2; + this._solution = this._solve(r - this._endPosition, n); + this._startTime = i; + } + } +}; +Spring.prototype.snap = function(e2) { + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + this._endPosition = e2; + this._solution = { + x: function() { + return 0; + }, + dx: function() { + return 0; + } + }; +}; +Spring.prototype.done = function(n) { + if (!n) { + n = (/* @__PURE__ */ new Date()).getTime(); + } + return e(this.x(), this._endPosition, 0.1) && t(this.dx(), 0.1); +}; +Spring.prototype.reconfigure = function(m, t2, c) { + this._m = m; + this._k = t2; + this._c = c; + if (!this.done()) { + this._solution = this._solve(this.x() - this._endPosition, this.dx()); + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + } +}; +Spring.prototype.springConstant = function() { + return this._k; +}; +Spring.prototype.damping = function() { + return this._c; +}; +Spring.prototype.configuration = function() { + function e2(e3, t3) { + e3.reconfigure(1, t3, e3.damping()); + } + function t2(e3, t3) { + e3.reconfigure(1, e3.springConstant(), t3); + } + return [ + { + label: "Spring Constant", + read: this.springConstant.bind(this), + write: e2.bind(this, this), + min: 100, + max: 1e3 + }, + { + label: "Damping", + read: this.damping.bind(this), + write: t2.bind(this, this), + min: 1, + max: 500 + } + ]; +}; +function STD(e2, t2, n) { + this._springX = new Spring(e2, t2, n); + this._springY = new Spring(e2, t2, n); + this._springScale = new Spring(e2, t2, n); + this._startTime = 0; +} +STD.prototype.setEnd = function(e2, t2, n, i) { + const r = (/* @__PURE__ */ new Date()).getTime(); + this._springX.setEnd(e2, i, r); + this._springY.setEnd(t2, i, r); + this._springScale.setEnd(n, i, r); + this._startTime = r; +}; +STD.prototype.x = function() { + const e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + return { + x: this._springX.x(e2), + y: this._springY.x(e2), + scale: this._springScale.x(e2) + }; +}; +STD.prototype.done = function() { + const e2 = (/* @__PURE__ */ new Date()).getTime(); + return this._springX.done(e2) && this._springY.done(e2) && this._springScale.done(e2); +}; +STD.prototype.reconfigure = function(e2, t2, n) { + this._springX.reconfigure(e2, t2, n); + this._springY.reconfigure(e2, t2, n); + this._springScale.reconfigure(e2, t2, n); +}; +const movableViewProps = { + direction: { + type: String, + default: "none" + }, + inertia: { + type: [Boolean, String], + default: false + }, + outOfBounds: { + type: [Boolean, String], + default: false + }, + x: { + type: [Number, String], + default: 0 + }, + y: { + type: [Number, String], + default: 0 + }, + damping: { + type: [Number, String], + default: 20 + }, + friction: { + type: [Number, String], + default: 2 + }, + disabled: { + type: [Boolean, String], + default: false + }, + scale: { + type: [Boolean, String], + default: false + }, + scaleMin: { + type: [Number, String], + default: 0.5 + }, + scaleMax: { + type: [Number, String], + default: 10 + }, + scaleValue: { + type: [Number, String], + default: 1 + }, + animation: { + type: [Boolean, String], + default: true + } +}; +function v(a, b) { + return +((1e3 * a - 1e3 * b) / 1e3).toFixed(1); +} +const index$s = /* @__PURE__ */ defineBuiltInComponent({ + name: "MovableView", + props: movableViewProps, + emits: ["change", "scale"], + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const { + setParent + } = useMovableViewState(props2, trigger, rootRef); + return () => { + return vue.createVNode("uni-movable-view", { + "ref": rootRef + }, [vue.createVNode(ResizeSensor, { + "onResize": setParent + }, null, 8, ["onResize"]), slots.default && slots.default()], 512); + }; + } +}); +let requesting = false; +function _requestAnimationFrame(e2) { + if (!requesting) { + requesting = true; + requestAnimationFrame(function() { + e2(); + requesting = false; + }); + } +} +function p(t2, n) { + if (t2 === n) { + return 0; + } + let i = t2.offsetLeft; + return t2.offsetParent ? i += p(t2.offsetParent, n) : 0; +} +function f(t2, n) { + if (t2 === n) { + return 0; + } + let i = t2.offsetTop; + return t2.offsetParent ? i += f(t2.offsetParent, n) : 0; +} +function g(friction, execute, endCallback) { + let record = { + id: 0, + cancelled: false + }; + let cancel = function(record2) { + if (record2 && record2.id) { + cancelAnimationFrame(record2.id); + } + if (record2) { + record2.cancelled = true; + } + }; + function fn(record2, friction2, execute2, endCallback2) { + if (!record2 || !record2.cancelled) { + execute2(friction2); + let isDone = friction2.done(); + if (!isDone) { + if (!record2.cancelled) { + record2.id = requestAnimationFrame(fn.bind(null, record2, friction2, execute2, endCallback2)); + } + } + if (isDone && endCallback2) { + endCallback2(friction2); + } + } + } + fn(record, friction, execute, endCallback); + return { + cancel: cancel.bind(null, record), + model: friction + }; +} +function _getPx(val) { + if (/\d+[ur]px$/i.test(val)) { + return uni.upx2px(parseFloat(val)); + } + return Number(val) || 0; +} +function useMovableViewLayout(rootRef, _scale, _adjustScale) { + const movableAreaWidth = vue.inject("movableAreaWidth", vue.ref(0)); + const movableAreaHeight = vue.inject("movableAreaHeight", vue.ref(0)); + const movableAreaRootRef = vue.inject("movableAreaRootRef"); + const _offset = { + x: 0, + y: 0 + }; + const _scaleOffset = { + x: 0, + y: 0 + }; + const width = vue.ref(0); + const height = vue.ref(0); + const minX = vue.ref(0); + const minY = vue.ref(0); + const maxX = vue.ref(0); + const maxY = vue.ref(0); + function _updateBoundary() { + let x = 0 - _offset.x + _scaleOffset.x; + let _width = movableAreaWidth.value - width.value - _offset.x - _scaleOffset.x; + minX.value = Math.min(x, _width); + maxX.value = Math.max(x, _width); + let y = 0 - _offset.y + _scaleOffset.y; + let _height = movableAreaHeight.value - height.value - _offset.y - _scaleOffset.y; + minY.value = Math.min(y, _height); + maxY.value = Math.max(y, _height); + } + function _updateOffset() { + _offset.x = p(rootRef.value, movableAreaRootRef.value); + _offset.y = f(rootRef.value, movableAreaRootRef.value); + } + function _updateWH(scale) { + scale = scale || _scale.value; + scale = _adjustScale(scale); + let rect = rootRef.value.getBoundingClientRect(); + height.value = rect.height / _scale.value; + width.value = rect.width / _scale.value; + let _height = height.value * scale; + let _width = width.value * scale; + _scaleOffset.x = (_width - width.value) / 2; + _scaleOffset.y = (_height - height.value) / 2; + } + return { + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY + }; +} +function useMovableViewTransform(rootRef, props2, _scaleOffset, _scale, maxX, maxY, minX, minY, _translateX, _translateY, _SFA, _FA, _adjustScale, trigger) { + const dampingNumber = vue.computed(() => { + let val = Number(props2.damping); + return isNaN(val) ? 20 : val; + }); + const xMove = vue.computed(() => props2.direction === "all" || props2.direction === "horizontal"); + const yMove = vue.computed(() => props2.direction === "all" || props2.direction === "vertical"); + const xSync = vue.ref(_getPx(props2.x)); + const ySync = vue.ref(_getPx(props2.y)); + vue.watch(() => props2.x, (val) => { + xSync.value = _getPx(val); + }); + vue.watch(() => props2.y, (val) => { + ySync.value = _getPx(val); + }); + vue.watch(xSync, (val) => { + _setX(val); + }); + vue.watch(ySync, (val) => { + _setY(val); + }); + const _STD = new STD(1, 9 * Math.pow(dampingNumber.value, 2) / 40, dampingNumber.value); + function _getLimitXY(x, y) { + let outOfBounds = false; + if (x > maxX.value) { + x = maxX.value; + outOfBounds = true; + } else { + if (x < minX.value) { + x = minX.value; + outOfBounds = true; + } + } + if (y > maxY.value) { + y = maxY.value; + outOfBounds = true; + } else { + if (y < minY.value) { + y = minY.value; + outOfBounds = true; + } + } + return { + x, + y, + outOfBounds + }; + } + function FAandSFACancel() { + if (_FA) { + _FA.cancel(); + } + if (_SFA) { + _SFA.cancel(); + } + } + function _animationTo(x, y, scale, source, r, o) { + FAandSFACancel(); + if (!xMove.value) { + x = _translateX.value; + } + if (!yMove.value) { + y = _translateY.value; + } + if (!props2.scale) { + scale = _scale.value; + } + let limitXY = _getLimitXY(x, y); + x = limitXY.x; + y = limitXY.y; + if (!props2.animation) { + _setTransform(x, y, scale, source, r, o); + return; + } + _STD._springX._solution = null; + _STD._springY._solution = null; + _STD._springScale._solution = null; + _STD._springX._endPosition = _translateX.value; + _STD._springY._endPosition = _translateY.value; + _STD._springScale._endPosition = _scale.value; + _STD.setEnd(x, y, scale, 1); + _SFA = g(_STD, function() { + let data = _STD.x(); + let x2 = data.x; + let y2 = data.y; + let scale2 = data.scale; + _setTransform(x2, y2, scale2, source, r, o); + }, function() { + _SFA.cancel(); + }); + } + function _setTransform(x, y, scale, source = "", r, o) { + if (!(x !== null && x.toString() !== "NaN" && typeof x === "number")) { + x = _translateX.value || 0; + } + if (!(y !== null && y.toString() !== "NaN" && typeof y === "number")) { + y = _translateY.value || 0; + } + x = Number(x.toFixed(1)); + y = Number(y.toFixed(1)); + scale = Number(scale.toFixed(1)); + if (!(_translateX.value === x && _translateY.value === y)) { + if (!r) { + trigger("change", {}, { + x: v(x, _scaleOffset.x), + y: v(y, _scaleOffset.y), + source + }); + } + } + if (!props2.scale) { + scale = _scale.value; + } + scale = _adjustScale(scale); + scale = +scale.toFixed(3); + if (o && scale !== _scale.value) { + trigger("scale", {}, { + x, + y, + scale + }); + } + let transform = "translateX(" + x + "px) translateY(" + y + "px) translateZ(0px) scale(" + scale + ")"; + if (rootRef.value) { + rootRef.value.style.transform = transform; + rootRef.value.style.webkitTransform = transform; + _translateX.value = x; + _translateY.value = y; + _scale.value = scale; + } + } + function _revise(source) { + let limitXY = _getLimitXY(_translateX.value, _translateY.value); + let x = limitXY.x; + let y = limitXY.y; + let outOfBounds = limitXY.outOfBounds; + if (outOfBounds) { + _animationTo(x, y, _scale.value, source); + } + return outOfBounds; + } + function _setX(val) { + if (xMove.value) { + if (val + _scaleOffset.x === _translateX.value) { + return _translateX; + } else { + if (_SFA) { + _SFA.cancel(); + } + _animationTo(val + _scaleOffset.x, ySync.value + _scaleOffset.y, _scale.value); + } + } + return val; + } + function _setY(val) { + if (yMove.value) { + if (val + _scaleOffset.y === _translateY.value) { + return _translateY; + } else { + if (_SFA) { + _SFA.cancel(); + } + _animationTo(xSync.value + _scaleOffset.x, val + _scaleOffset.y, _scale.value); + } + } + return val; + } + return { + FAandSFACancel, + _getLimitXY, + _animationTo, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + }; +} +function useMovableViewInit(props2, rootRef, trigger, _scale, _oldScale, _isScaling, _translateX, _translateY, _SFA, _FA) { + const scaleMinNumber = vue.computed(() => { + let val = Number(props2.scaleMin); + return isNaN(val) ? 0.5 : val; + }); + const scaleMaxNumber = vue.computed(() => { + let val = Number(props2.scaleMax); + return isNaN(val) ? 10 : val; + }); + const scaleValueSync = vue.ref(Number(props2.scaleValue) || 1); + vue.watch(scaleValueSync, (val) => { + _setScaleValue(val); + }); + vue.watch(scaleMinNumber, () => { + _setScaleMinOrMax(); + }); + vue.watch(scaleMaxNumber, () => { + _setScaleMinOrMax(); + }); + vue.watch(() => props2.scaleValue, (val) => { + scaleValueSync.value = Number(val) || 0; + }); + const { + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY + } = useMovableViewLayout(rootRef, _scale, _adjustScale); + const { + FAandSFACancel, + _getLimitXY, + _animationTo, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + } = useMovableViewTransform(rootRef, props2, _scaleOffset, _scale, maxX, maxY, minX, minY, _translateX, _translateY, _SFA, _FA, _adjustScale, trigger); + function _updateScale(scale, animat) { + if (props2.scale) { + scale = _adjustScale(scale); + _updateWH(scale); + _updateBoundary(); + const limitXY = _getLimitXY(_translateX.value, _translateY.value); + const x = limitXY.x; + const y = limitXY.y; + if (animat) { + _animationTo(x, y, scale, "", true, true); + } else { + _requestAnimationFrame(function() { + _setTransform(x, y, scale, "", true, true); + }); + } + } + } + function _beginScale() { + _isScaling.value = true; + } + function _updateOldScale(scale) { + _oldScale.value = scale; + } + function _adjustScale(scale) { + scale = Math.max(0.5, scaleMinNumber.value, scale); + scale = Math.min(10, scaleMaxNumber.value, scale); + return scale; + } + function _setScaleMinOrMax() { + if (!props2.scale) { + return false; + } + _updateScale(_scale.value, true); + _updateOldScale(_scale.value); + } + function _setScaleValue(scale) { + if (!props2.scale) { + return false; + } + scale = _adjustScale(scale); + _updateScale(scale, true); + _updateOldScale(scale); + return scale; + } + function _endScale() { + _isScaling.value = false; + _updateOldScale(_scale.value); + } + function _setScale(scale) { + if (scale) { + scale = _oldScale.value * scale; + _beginScale(); + _updateScale(scale); + } + } + return { + // scale + _updateOldScale, + _endScale, + _setScale, + scaleValueSync, + // layout + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY, + // transform + FAandSFACancel, + _getLimitXY, + _animationTo, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + }; +} +function useMovableViewState(props2, trigger, rootRef) { + const _isMounted = vue.inject("_isMounted", vue.ref(false)); + vue.inject("addMovableViewContext", () => { + }); + vue.inject("removeMovableViewContext", () => { + }); + let _scale = vue.ref(1); + let _oldScale = vue.ref(1); + let _isScaling = vue.ref(false); + let _translateX = vue.ref(0); + let _translateY = vue.ref(0); + let _SFA = null; + let _FA = null; + const frictionNumber = vue.computed(() => { + let val = Number(props2.friction); + return isNaN(val) || val <= 0 ? 2 : val; + }); + new Friction(1, frictionNumber.value); + vue.watch(() => props2.disabled, () => { + __handleTouchStart(); + }); + const { + // scale + _updateOldScale, + _endScale, + _setScale, + scaleValueSync, + // layout + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY, + // transform + FAandSFACancel, + _getLimitXY, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + } = useMovableViewInit(props2, rootRef, trigger, _scale, _oldScale, _isScaling, _translateX, _translateY, _SFA, _FA); + function __handleTouchStart() { + if (!_isScaling.value) { + if (!props2.disabled) { + FAandSFACancel(); + if (xMove.value) { + _translateX.value; + } + if (yMove.value) { + _translateY.value; + } + rootRef.value.style.willChange = "transform"; + } + } + } + function setParent() { + if (!_isMounted.value) { + return; + } + FAandSFACancel(); + let scale = props2.scale ? scaleValueSync.value : 1; + _updateOffset(); + _updateWH(scale); + _updateBoundary(); + let limitXY = _getLimitXY(xSync.value + _scaleOffset.x, ySync.value + _scaleOffset.y); + let x = limitXY.x; + let y = limitXY.y; + _setTransform(x, y, scale, "", true); + _updateOldScale(scale); + } + return { + setParent + }; +} +const OPEN_TYPES = [ + "navigate", + "redirect", + "switchTab", + "reLaunch", + "navigateBack" +]; +const ANIMATION_IN = [ + "slide-in-right", + "slide-in-left", + "slide-in-top", + "slide-in-bottom", + "fade-in", + "zoom-out", + "zoom-fade-out", + "pop-in", + "none" +]; +const ANIMATION_OUT = [ + "slide-out-right", + "slide-out-left", + "slide-out-top", + "slide-out-bottom", + "fade-out", + "zoom-in", + "zoom-fade-in", + "pop-out", + "none" +]; +const navigatorProps = { + hoverClass: { + type: String, + default: "navigator-hover" + }, + url: { + type: String, + default: "" + }, + openType: { + type: String, + default: "navigate", + validator(value) { + return Boolean(~OPEN_TYPES.indexOf(value)); + } + }, + delta: { + type: Number, + default: 1 + }, + hoverStartTime: { + type: [Number, String], + default: 50 + }, + hoverStayTime: { + type: [Number, String], + default: 600 + }, + exists: { + type: String, + default: "" + }, + hoverStopPropagation: { + type: Boolean, + default: false + }, + animationType: { + type: String, + default: "", + validator(value) { + return !value || ANIMATION_IN.concat(ANIMATION_OUT).includes(value); + } + }, + animationDuration: { + type: [String, Number], + default: 300 + } +}; +function createNavigatorOnClick(props2) { + return () => { + if (props2.openType !== "navigateBack" && !props2.url) { + console.error( + " should have url attribute when using navigateTo, redirectTo, reLaunch or switchTab" + ); + return; + } + const animationDuration = parseInt(props2.animationDuration); + switch (props2.openType) { + case "navigate": + uni.navigateTo({ + url: props2.url, + animationType: props2.animationType || "pop-in", + animationDuration + }); + break; + case "redirect": + uni.redirectTo({ + url: props2.url, + // @ts-ignore + exists: props2.exists + }); + break; + case "switchTab": + uni.switchTab({ + url: props2.url + }); + break; + case "reLaunch": + uni.reLaunch({ + url: props2.url + }); + break; + case "navigateBack": + uni.navigateBack({ + delta: props2.delta, + animationType: props2.animationType || "pop-out", + animationDuration + }); + break; + } + }; +} +const index$r = /* @__PURE__ */ defineBuiltInComponent({ + name: "Navigator", + inheritAttrs: false, + compatConfig: { + MODE: 3 + }, + props: shared.extend({}, navigatorProps, { + renderLink: { + type: Boolean, + default: true + } + }), + setup(props2, { + slots + }) { + const vm = vue.getCurrentInstance(); + const __scopeId = vm && vm.vnode.scopeId || ""; + const { + hovering, + binding + } = useHover(props2); + const onClick = createNavigatorOnClick(props2); + return () => { + const { + hoverClass, + url + } = props2; + const hasHoverClass = props2.hoverClass && props2.hoverClass !== "none"; + const navigatorTsx = vue.createVNode("uni-navigator", vue.mergeProps({ + "class": hasHoverClass && hovering.value ? hoverClass : "" + }, hasHoverClass && binding, vm ? vm.attrs : {}, { + [__scopeId]: "" + }, { + "onClick": onClick + }), [slots.default && slots.default()], 16, ["onClick"]); + return props2.renderLink ? vue.createVNode("a", { + "class": "navigator-wrap", + "href": url, + "onClick": onEventPrevent, + "onMousedown": onEventPrevent + }, [navigatorTsx], 40, ["href", "onClick", "onMousedown"]) : navigatorTsx; + }; + } +}); +const pickerViewProps = { + value: { + type: Array, + default() { + return []; + }, + validator: function(val) { + return shared.isArray(val) && val.filter((val2) => typeof val2 === "number").length === val.length; + } + }, + indicatorStyle: { + type: String, + default: "" + }, + indicatorClass: { + type: String, + default: "" + }, + maskStyle: { + type: String, + default: "" + }, + maskClass: { + type: String, + default: "" + } +}; +function useState$2(props2) { + const value = vue.reactive([...props2.value]); + const state = vue.reactive({ + value, + height: 34 + }); + vue.watch(() => props2.value, (val, oldVal) => { + { + state.value.length = val.length; + val.forEach((val2, index2) => { + if (val2 !== state.value[index2]) { + state.value.splice(index2, 1, val2); + } + }); + } + }); + return state; +} +const PickerView = /* @__PURE__ */ defineBuiltInComponent({ + name: "PickerView", + props: pickerViewProps, + emits: ["change", "pickstart", "pickend", "update:value"], + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = vue.ref(null); + const wrapperRef = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const state = useState$2(props2); + const resizeSensorRef = vue.ref(null); + let ColumnsPreRef = vue.ref([]); + let columnsRef = vue.ref([]); + function getItemIndex(vnode) { + let columnVNodes = columnsRef.value; + { + columnVNodes = columnVNodes.filter((vnode2) => vnode2.type !== vue.Comment); + } + let index2 = columnVNodes.indexOf(vnode); + return index2 !== -1 ? index2 : ColumnsPreRef.value.indexOf(vnode); + } + const getPickerViewColumn = function(columnInstance) { + const ref = vue.computed({ + get() { + const index2 = getItemIndex(columnInstance.vnode); + return state.value[index2] || 0; + }, + set(current) { + const index2 = getItemIndex(columnInstance.vnode); + if (index2 < 0) { + return; + } + const oldCurrent = state.value[index2]; + if (oldCurrent !== current) { + state.value[index2] = current; + const value = state.value.map((val) => val); + emit2("update:value", value); + trigger("change", {}, { + value + }); + } + } + }); + return ref; + }; + vue.provide("getPickerViewColumn", getPickerViewColumn); + vue.provide("pickerViewProps", props2); + vue.provide("pickerViewState", state); + return () => { + const defaultSlots = slots.default && slots.default(); + { + const vnode = flatVNode(defaultSlots); + ColumnsPreRef.value = vnode; + vue.nextTick(() => { + columnsRef.value = vnode; + }); + } + return vue.createVNode("uni-picker-view", { + "ref": rootRef + }, [vue.createVNode(ResizeSensor, { + "ref": resizeSensorRef, + "onResize": ({ + height + }) => state.height = height + }, null, 8, ["onResize"]), vue.createVNode("div", { + "ref": wrapperRef, + "class": "uni-picker-view-wrapper" + }, [defaultSlots], 512)], 512); + }; + } +}); +let scopedIndex = 0; +function useScopedClass(indicatorHeightRef) { + const className = `uni-picker-view-content-${scopedIndex++}`; + function updateStyle() { + const style = document.createElement("style"); + style.innerText = `.uni-picker-view-content.${className}>*{height: ${indicatorHeightRef.value}px;overflow: hidden;}`; + document.head.appendChild(style); + } + vue.watch(() => indicatorHeightRef.value, updateStyle); + return className; +} +const PickerViewColumn = /* @__PURE__ */ defineBuiltInComponent({ + name: "PickerViewColumn", + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = vue.ref(null); + const contentRef = vue.ref(null); + const getPickerViewColumn = vue.inject("getPickerViewColumn"); + const instance = vue.getCurrentInstance(); + const currentRef = getPickerViewColumn ? getPickerViewColumn(instance) : vue.ref(0); + const pickerViewProps2 = vue.inject("pickerViewProps"); + const pickerViewState = vue.inject("pickerViewState"); + const indicatorHeight = vue.ref(34); + const resizeSensorRef = vue.ref(null); + const maskSize = vue.computed(() => (pickerViewState.height - indicatorHeight.value) / 2); + const { + state: scopedAttrsState + } = useScopedAttrs(); + const className = useScopedClass(indicatorHeight); + let scroller; + const state = vue.reactive({ + current: currentRef.value, + length: 0 + }); + function updatesScroller() { + } + vue.watch(() => currentRef.value, (current) => { + if (current !== state.current) { + state.current = current; + } + }); + vue.watch(() => state.current, (current) => currentRef.value = current); + vue.watch([() => indicatorHeight.value, () => state.length, () => pickerViewState.height], updatesScroller); + let oldDeltaY = 0; + function handleWheel(event) { + const deltaY = oldDeltaY + event.deltaY; + if (Math.abs(deltaY) > 10) { + oldDeltaY = 0; + let current = Math.min(state.current + (deltaY < 0 ? -1 : 1), state.length - 1); + state.current = current = Math.max(current, 0); + scroller.scrollTo(current * indicatorHeight.value); + } else { + oldDeltaY = deltaY; + } + event.preventDefault(); + } + function handleTap({ + clientY + }) { + const el = rootRef.value; + if (!scroller.isScrolling()) { + const rect = el.getBoundingClientRect(); + const r = clientY - rect.top - pickerViewState.height / 2; + const o = indicatorHeight.value / 2; + if (!(Math.abs(r) <= o)) { + const a = Math.ceil((Math.abs(r) - o) / indicatorHeight.value); + const s = r < 0 ? -a : a; + let current = Math.min(state.current + s, state.length - 1); + state.current = current = Math.max(current, 0); + scroller.scrollTo(current * indicatorHeight.value); + } + } + } + return () => { + const defaultSlots = slots.default && slots.default(); + { + state.length = flatVNode(defaultSlots).length; + } + const padding = `${maskSize.value}px 0`; + return vue.createVNode("uni-picker-view-column", { + "ref": rootRef + }, [vue.createVNode("div", { + "onWheel": handleWheel, + "onClick": handleTap, + "class": "uni-picker-view-group" + }, [vue.createVNode("div", vue.mergeProps(scopedAttrsState.attrs, { + "class": ["uni-picker-view-mask", pickerViewProps2.maskClass], + "style": `background-size: 100% ${maskSize.value}px;${pickerViewProps2.maskStyle}` + }), null, 16), vue.createVNode("div", vue.mergeProps(scopedAttrsState.attrs, { + "class": ["uni-picker-view-indicator", pickerViewProps2.indicatorClass], + "style": pickerViewProps2.indicatorStyle + }), [vue.createVNode(ResizeSensor, { + "ref": resizeSensorRef, + "onResize": ({ + height + }) => indicatorHeight.value = height + }, null, 8, ["onResize"])], 16), vue.createVNode("div", { + "ref": contentRef, + "class": ["uni-picker-view-content", className], + "style": { + padding + } + }, [defaultSlots], 6)], 40, ["onWheel", "onClick"])], 512); + }; + } +}); +const FONT_SIZE = 16; +const PROGRESS_VALUES = { + activeColor: uniShared.PRIMARY_COLOR, + backgroundColor: "#EBEBEB", + activeMode: "backwards" +}; +const progressProps = { + percent: { + type: [Number, String], + default: 0, + validator(value) { + return !isNaN(parseFloat(value)); + } + }, + fontSize: { + type: [String, Number], + default: FONT_SIZE + }, + showInfo: { + type: [Boolean, String], + default: false + }, + strokeWidth: { + type: [Number, String], + default: 6, + validator(value) { + return !isNaN(parseFloat(value)); + } + }, + color: { + type: String, + default: PROGRESS_VALUES.activeColor + }, + activeColor: { + type: String, + default: PROGRESS_VALUES.activeColor + }, + backgroundColor: { + type: String, + default: PROGRESS_VALUES.backgroundColor + }, + active: { + type: [Boolean, String], + default: false + }, + activeMode: { + type: String, + default: PROGRESS_VALUES.activeMode + }, + duration: { + type: [Number, String], + default: 30, + validator(value) { + return !isNaN(parseFloat(value)); + } + }, + borderRadius: { + type: [Number, String], + default: 0 + } +}; +const index$q = /* @__PURE__ */ defineBuiltInComponent({ + name: "Progress", + props: progressProps, + setup(props2) { + const state = useProgressState(props2); + _activeAnimation(state, props2); + vue.watch(() => state.realPercent, (newValue, oldValue) => { + state.strokeTimer && clearInterval(state.strokeTimer); + state.lastPercent = oldValue || 0; + _activeAnimation(state, props2); + }); + return () => { + const { + showInfo + } = props2; + const { + outerBarStyle, + innerBarStyle, + currentPercent + } = state; + return vue.createVNode("uni-progress", { + "class": "uni-progress" + }, [vue.createVNode("div", { + "style": outerBarStyle, + "class": "uni-progress-bar" + }, [vue.createVNode("div", { + "style": innerBarStyle, + "class": "uni-progress-inner-bar" + }, null, 4)], 4), showInfo ? ( + // {currentPercent}% 的写法会影响 SSR Hydration (tsx插件的问题) + vue.createVNode("p", { + "class": "uni-progress-info" + }, [currentPercent + "%"]) + ) : ""]); + }; + } +}); +function useProgressState(props2) { + const currentPercent = vue.ref(0); + const outerBarStyle = vue.computed(() => `background-color: ${props2.backgroundColor}; height: ${props2.strokeWidth}px;`); + const innerBarStyle = vue.computed(() => { + const backgroundColor = props2.color !== PROGRESS_VALUES.activeColor && props2.activeColor === PROGRESS_VALUES.activeColor ? props2.color : props2.activeColor; + return `width: ${currentPercent.value}%;background-color: ${backgroundColor}`; + }); + const realPercent = vue.computed(() => { + let realValue = parseFloat(props2.percent); + realValue < 0 && (realValue = 0); + realValue > 100 && (realValue = 100); + return realValue; + }); + const state = vue.reactive({ + outerBarStyle, + innerBarStyle, + realPercent, + currentPercent, + strokeTimer: 0, + lastPercent: 0 + }); + return state; +} +function _activeAnimation(state, props2) { + if (props2.active) { + state.currentPercent = props2.activeMode === PROGRESS_VALUES.activeMode ? 0 : state.lastPercent; + state.strokeTimer = setInterval(() => { + if (state.currentPercent + 1 > state.realPercent) { + state.currentPercent = state.realPercent; + state.strokeTimer && clearInterval(state.strokeTimer); + } else { + state.currentPercent += 1; + } + }, parseFloat(props2.duration)); + } else { + state.currentPercent = state.realPercent; + } +} +const uniRadioGroupKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniCheckGroup" : "ucg"); +const props$i = { + name: { + type: String, + default: "" + } +}; +const index$p = /* @__PURE__ */ defineBuiltInComponent({ + name: "RadioGroup", + props: props$i, + // emits: ['change'], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + useProvideRadioGroup(props2, trigger); + return () => { + return vue.createVNode("uni-radio-group", { + "ref": rootRef + }, [slots.default && slots.default()], 512); + }; + } +}); +function useProvideRadioGroup(props2, trigger) { + const fields2 = []; + const getFieldsValue = () => { + var _a; + return (_a = fields2.find((field) => field.value.radioChecked)) == null ? void 0 : _a.value.value; + }; + vue.provide(uniRadioGroupKey, { + addField(field) { + fields2.push(field); + }, + removeField(field) { + fields2.splice(fields2.indexOf(field), 1); + }, + radioChange($event, field) { + const index2 = fields2.indexOf(field); + _resetRadioGroupValue(index2, true); + trigger("change", $event, { + value: getFieldsValue() + }); + } + }); + const uniForm = vue.inject(uniFormKey, false); + const formField = { + submit: () => { + let data = ["", null]; + if (props2.name !== "") { + data[0] = props2.name; + data[1] = getFieldsValue(); + } + return data; + } + }; + if (uniForm) { + uniForm.addField(formField); + } + function setFieldChecked(field, radioChecked) { + field.value = { + radioChecked, + value: field.value.value + }; + } + function _resetRadioGroupValue(key, change) { + fields2.forEach((value, index2) => { + if (index2 === key) { + return; + } + if (change) { + setFieldChecked(fields2[index2], false); + } else { + fields2.forEach((v2, i) => { + if (index2 >= i) { + return; + } + if (fields2[i].value.radioChecked) { + setFieldChecked(fields2[index2], false); + } + }); + } + }); + } + return fields2; +} +const props$h = { + checked: { + type: [Boolean, String], + default: false + }, + id: { + type: String, + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "#007aff" + }, + value: { + type: String, + default: "" + } +}; +const index$o = /* @__PURE__ */ defineBuiltInComponent({ + name: "Radio", + props: props$h, + setup(props2, { + slots + }) { + const radioChecked = vue.ref(props2.checked); + const radioValue = vue.ref(props2.value); + const checkedStyle = vue.computed(() => { + if (props2.disabled) + return "background-color: #E1E1E1;border-color: ##D1D1D1;"; + return `background-color: ${props2.color};border-color: ${props2.color};`; + }); + vue.watch([() => props2.checked, () => props2.value], ([newChecked, newModelValue]) => { + radioChecked.value = newChecked; + radioValue.value = newModelValue; + }); + const reset = () => { + radioChecked.value = false; + }; + const { + uniCheckGroup, + uniLabel, + field + } = useRadioInject(radioChecked, radioValue, reset); + const _onClick = ($event) => { + if (props2.disabled || radioChecked.value) { + return; + } + radioChecked.value = true; + uniCheckGroup && uniCheckGroup.radioChange($event, field); + $event.stopPropagation(); + }; + if (!!uniLabel) { + uniLabel.addHandler(_onClick); + } + return () => { + const booleanAttrs = useBooleanAttr(props2, "disabled"); + return vue.createVNode("uni-radio", vue.mergeProps(booleanAttrs, { + "onClick": _onClick + }), [vue.createVNode("div", { + "class": "uni-radio-wrapper" + }, [vue.createVNode("div", { + "class": ["uni-radio-input", { + "uni-radio-input-disabled": props2.disabled + }], + "style": radioChecked.value ? checkedStyle.value : "" + }, [radioChecked.value ? createSvgIconVNode(ICON_PATH_SUCCESS_NO_CIRCLE, props2.disabled ? "#ADADAD" : "#fff", 18) : ""], 6), slots.default && slots.default()])], 16, ["onClick"]); + }; + } +}); +function useRadioInject(radioChecked, radioValue, reset) { + const field = vue.computed({ + get: () => ({ + radioChecked: Boolean(radioChecked.value), + value: radioValue.value + }), + set: ({ + radioChecked: checked + }) => { + radioChecked.value = checked; + } + }); + const formField = { + reset + }; + const uniCheckGroup = vue.inject(uniRadioGroupKey, false); + if (!!uniCheckGroup) { + uniCheckGroup.addField(field); + } + const uniForm = vue.inject(uniFormKey, false); + if (!!uniForm) { + uniForm.addField(formField); + } + const uniLabel = vue.inject(uniLabelKey, false); + return { + uniCheckGroup, + uniForm, + uniLabel, + field + }; +} +const TAGS = { + a: "", + abbr: "", + address: "", + article: "", + aside: "", + b: "", + bdi: "", + bdo: ["dir"], + big: "", + blockquote: "", + br: "", + caption: "", + center: "", + cite: "", + code: "", + col: ["span", "width"], + colgroup: ["span", "width"], + dd: "", + del: "", + div: "", + dl: "", + dt: "", + em: "", + fieldset: "", + font: "", + footer: "", + h1: "", + h2: "", + h3: "", + h4: "", + h5: "", + h6: "", + header: "", + hr: "", + i: "", + img: ["alt", "src", "height", "width"], + ins: "", + label: "", + legend: "", + li: "", + mark: "", + nav: "", + ol: ["start", "type"], + p: "", + pre: "", + q: "", + rt: "", + ruby: "", + s: "", + section: "", + small: "", + span: "", + strong: "", + sub: "", + sup: "", + table: ["width"], + tbody: "", + td: ["colspan", "height", "rowspan", "width"], + tfoot: "", + th: ["colspan", "height", "rowspan", "width"], + thead: "", + tr: ["colspan", "height", "rowspan", "width"], + tt: "", + u: "", + ul: "" +}; +const CHARS = { + amp: "&", + gt: ">", + lt: "<", + nbsp: " ", + quot: '"', + apos: "'", + ldquo: "“", + rdquo: "”", + yen: "¥", + radic: "√", + lceil: "⌈", + rceil: "⌉", + lfloor: "⌊", + rfloor: "⌋", + hellip: "…" +}; +function decodeEntities(htmlString) { + return htmlString.replace( + /&(([a-zA-Z]+)|(#x{0,1}[\da-zA-Z]+));/gi, + function(match, stage) { + if (shared.hasOwn(CHARS, stage) && CHARS[stage]) { + return CHARS[stage]; + } + if (/^#[0-9]{1,4}$/.test(stage)) { + return String.fromCharCode(stage.slice(1)); + } + if (/^#x[0-9a-f]{1,4}$/i.test(stage)) { + return String.fromCharCode(0 + stage.slice(1)); + } + return match; + } + ); +} +function processClickEvent(node, triggerItemClick) { + if (["a", "img"].includes(node.name) && triggerItemClick) { + return { + onClick: (e2) => { + triggerItemClick(e2, { node }); + e2.stopPropagation(); + e2.preventDefault(); + e2.returnValue = false; + } + }; + } +} +function normalizeAttrs(tagName, attrs) { + if (!shared.isPlainObject(attrs)) + return; + for (const key in attrs) { + if (shared.hasOwn(attrs, key)) { + const value = attrs[key]; + if (tagName === "img" && key === "src") + attrs[key] = getRealPath(value); + } + } +} +const nodeList2VNode = (scopeId, triggerItemClick, nodeList) => { + if (!nodeList || shared.isArray(nodeList) && !nodeList.length) + return []; + return nodeList.map((node) => { + if (!shared.isPlainObject(node)) { + return; + } + if (!shared.hasOwn(node, "type") || node.type === "node") { + let nodeProps = { [scopeId]: "" }; + const tagName = node.name.toLowerCase(); + if (!shared.hasOwn(TAGS, tagName)) { + return; + } + normalizeAttrs(tagName, node.attrs); + nodeProps = shared.extend( + nodeProps, + processClickEvent(node, triggerItemClick), + node.attrs + ); + return vue.h( + node.name, + nodeProps, + nodeList2VNode(scopeId, triggerItemClick, node.children) + ); + } + if (node.type === "text" && shared.isString(node.text) && node.text !== "") + return vue.createTextVNode(decodeEntities(node.text || "")); + }); +}; +function removeDOCTYPE(html) { + return html.replace(/<\?xml.*\?>\n/, "").replace(/\n/, "").replace(/\n/, ""); +} +function parseAttrs(attrs) { + return attrs.reduce(function(pre, attr2) { + let value = attr2.value; + const name = attr2.name; + if (value.match(/ /) && ["style", "src"].indexOf(name) === -1) { + value = value.split(" "); + } + if (pre[name]) { + if (Array.isArray(pre[name])) { + pre[name].push(value); + } else { + pre[name] = [pre[name], value]; + } + } else { + pre[name] = value; + } + return pre; + }, {}); +} +function parseHtml(html) { + html = removeDOCTYPE(html); + const stacks = []; + const results = { + node: "root", + children: [] + }; + HTMLParser(html, { + start: function(tag, attrs, unary) { + const node = { + name: tag + }; + if (attrs.length !== 0) { + node.attrs = parseAttrs(attrs); + } + if (unary) { + const parent = stacks[0] || results; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } else { + stacks.unshift(node); + } + }, + end: function(tag) { + const node = stacks.shift(); + if (node.name !== tag) + console.error("invalid state: mismatch end tag"); + if (stacks.length === 0) { + results.children.push(node); + } else { + const parent = stacks[0]; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } + }, + chars: function(text) { + const node = { + type: "text", + text + }; + if (stacks.length === 0) { + results.children.push(node); + } else { + const parent = stacks[0]; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } + }, + comment: function(text) { + const node = { + node: "comment", + text + }; + const parent = stacks[0]; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } + }); + return results.children; +} +const props$g = { + nodes: { + type: [Array, String], + default: function() { + return []; + } + } +}; +const index$n = /* @__PURE__ */ defineBuiltInComponent({ + name: "RichText", + compatConfig: { + MODE: 3 + }, + props: props$g, + emits: ["click", "touchstart", "touchmove", "touchcancel", "touchend", "longpress", "itemclick"], + setup(props2, { + emit: emit2 + }) { + const vm = vue.getCurrentInstance(); + const scopeId = vm && vm.vnode.scopeId || ""; + const rootRef = vue.ref(null); + const _vnode = vue.ref([]); + const trigger = useCustomEvent(rootRef, emit2); + function triggerItemClick(e2, detail = {}) { + trigger("itemclick", e2, detail); + } + function renderVNode() { + let nodeList = props2.nodes; + if (shared.isString(nodeList)) { + nodeList = parseHtml(props2.nodes); + } + _vnode.value = nodeList2VNode(scopeId, triggerItemClick, nodeList); + } + vue.watch(() => props2.nodes, renderVNode, { + immediate: true + }); + return () => vue.h("uni-rich-text", { + ref: rootRef + }, vue.h("div", {}, _vnode.value)); + } +}); +const props$f = { + scrollX: { + type: [Boolean, String], + default: false + }, + scrollY: { + type: [Boolean, String], + default: false + }, + upperThreshold: { + type: [Number, String], + default: 50 + }, + lowerThreshold: { + type: [Number, String], + default: 50 + }, + scrollTop: { + type: [Number, String], + default: 0 + }, + scrollLeft: { + type: [Number, String], + default: 0 + }, + scrollIntoView: { + type: String, + default: "" + }, + scrollWithAnimation: { + type: [Boolean, String], + default: false + }, + enableBackToTop: { + type: [Boolean, String], + default: false + }, + refresherEnabled: { + type: [Boolean, String], + default: false + }, + refresherThreshold: { + type: Number, + default: 45 + }, + refresherDefaultStyle: { + type: String, + default: "back" + }, + refresherBackground: { + type: String, + default: "#fff" + }, + refresherTriggered: { + type: [Boolean, String], + default: false + } +}; +const index$m = /* @__PURE__ */ defineBuiltInComponent({ + name: "ScrollView", + compatConfig: { + MODE: 3 + }, + props: props$f, + emits: ["scroll", "scrolltoupper", "scrolltolower", "refresherrefresh", "refresherrestore", "refresherpulling", "refresherabort", "update:refresherTriggered"], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = vue.ref(null); + const main = vue.ref(null); + const wrap = vue.ref(null); + const content = vue.ref(null); + const refresherinner = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const { + state, + scrollTopNumber, + scrollLeftNumber + } = useScrollViewState(props2); + useScrollViewLoader(props2, state, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2); + const mainStyle = vue.computed(() => { + let style = ""; + props2.scrollX ? style += "overflow-x:auto;" : style += "overflow-x:hidden;"; + props2.scrollY ? style += "overflow-y:auto;" : style += "overflow-y:hidden;"; + return style; + }); + return () => { + const { + refresherEnabled, + refresherBackground, + refresherDefaultStyle + } = props2; + const { + refresherHeight, + refreshState, + refreshRotate + } = state; + return vue.createVNode("uni-scroll-view", { + "ref": rootRef + }, [vue.createVNode("div", { + "ref": wrap, + "class": "uni-scroll-view" + }, [vue.createVNode("div", { + "ref": main, + "style": mainStyle.value, + "class": "uni-scroll-view" + }, [vue.createVNode("div", { + "ref": content, + "class": "uni-scroll-view-content" + }, [refresherEnabled ? vue.createVNode("div", { + "ref": refresherinner, + "style": { + backgroundColor: refresherBackground, + height: refresherHeight + "px" + }, + "class": "uni-scroll-view-refresher" + }, [refresherDefaultStyle !== "none" ? vue.createVNode("div", { + "class": "uni-scroll-view-refresh" + }, [vue.createVNode("div", { + "class": "uni-scroll-view-refresh-inner" + }, [refreshState == "pulling" ? vue.createVNode("svg", { + "key": "refresh__icon", + "style": { + transform: "rotate(" + refreshRotate + "deg)" + }, + "fill": "#2BD009", + "class": "uni-scroll-view-refresh__icon", + "width": "24", + "height": "24", + "viewBox": "0 0 24 24" + }, [vue.createVNode("path", { + "d": "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" + }, null), vue.createVNode("path", { + "d": "M0 0h24v24H0z", + "fill": "none" + }, null)], 4) : null, refreshState == "refreshing" ? vue.createVNode("svg", { + "key": "refresh__spinner", + "class": "uni-scroll-view-refresh__spinner", + "width": "24", + "height": "24", + "viewBox": "25 25 50 50" + }, [vue.createVNode("circle", { + "cx": "50", + "cy": "50", + "r": "20", + "fill": "none", + "style": "color: #2bd009", + "stroke-width": "3" + }, null)]) : null])]) : null, refresherDefaultStyle == "none" ? slots.refresher && slots.refresher() : null], 4) : null, slots.default && slots.default()], 512)], 4)], 512)], 512); + }; + } +}); +function useScrollViewState(props2) { + const scrollTopNumber = vue.computed(() => { + return Number(props2.scrollTop) || 0; + }); + const scrollLeftNumber = vue.computed(() => { + return Number(props2.scrollLeft) || 0; + }); + const state = vue.reactive({ + lastScrollTop: scrollTopNumber.value, + lastScrollLeft: scrollLeftNumber.value, + lastScrollToUpperTime: 0, + lastScrollToLowerTime: 0, + refresherHeight: 0, + refreshRotate: 0, + refreshState: "" + }); + return { + state, + scrollTopNumber, + scrollLeftNumber + }; +} +function useScrollViewLoader(props2, state, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2) { + let beforeRefreshing = false; + let triggerAbort = false; + let __transitionEnd = () => { + }; + vue.computed(() => { + let val = Number(props2.upperThreshold); + return isNaN(val) ? 50 : val; + }); + vue.computed(() => { + let val = Number(props2.lowerThreshold); + return isNaN(val) ? 50 : val; + }); + function scrollTo(scrollToValue, direction) { + const container = main.value; + let transformValue = 0; + let transform = ""; + scrollToValue < 0 ? scrollToValue = 0 : direction === "x" && scrollToValue > container.scrollWidth - container.offsetWidth ? scrollToValue = container.scrollWidth - container.offsetWidth : direction === "y" && scrollToValue > container.scrollHeight - container.offsetHeight && (scrollToValue = container.scrollHeight - container.offsetHeight); + direction === "x" ? transformValue = container.scrollLeft - scrollToValue : direction === "y" && (transformValue = container.scrollTop - scrollToValue); + if (transformValue === 0) + return; + let _content = content.value; + _content.style.transition = "transform .3s ease-out"; + _content.style.webkitTransition = "-webkit-transform .3s ease-out"; + if (direction === "x") { + transform = "translateX(" + transformValue + "px) translateZ(0)"; + } else { + direction === "y" && (transform = "translateY(" + transformValue + "px) translateZ(0)"); + } + _content.removeEventListener("transitionend", __transitionEnd); + _content.removeEventListener("webkitTransitionEnd", __transitionEnd); + __transitionEnd = () => _transitionEnd(scrollToValue, direction); + _content.addEventListener("transitionend", __transitionEnd); + _content.addEventListener("webkitTransitionEnd", __transitionEnd); + if (direction === "x") { + container.style.overflowX = "hidden"; + } else if (direction === "y") { + container.style.overflowY = "hidden"; + } + _content.style.transform = transform; + _content.style.webkitTransform = transform; + } + function _scrollTopChanged(val) { + if (props2.scrollY) { + { + if (props2.scrollWithAnimation) { + scrollTo(val, "y"); + } else { + main.value.scrollTop = val; + } + } + } + } + function _scrollLeftChanged(val) { + if (props2.scrollX) { + { + if (props2.scrollWithAnimation) { + scrollTo(val, "x"); + } else { + main.value.scrollLeft = val; + } + } + } + } + function _scrollIntoViewChanged(val) { + if (val) { + if (!/^[_a-zA-Z][-_a-zA-Z0-9:]*$/.test(val)) { + console.error(`id error: scroll-into-view=${val}`); + return; + } + let element = rootRef.value.querySelector("#" + val); + if (element) { + let mainRect = main.value.getBoundingClientRect(); + let elRect = element.getBoundingClientRect(); + if (props2.scrollX) { + let left = elRect.left - mainRect.left; + let scrollLeft = main.value.scrollLeft; + let x = scrollLeft + left; + if (props2.scrollWithAnimation) { + scrollTo(x, "x"); + } else { + main.value.scrollLeft = x; + } + } + if (props2.scrollY) { + let top = elRect.top - mainRect.top; + let scrollTop = main.value.scrollTop; + let y = scrollTop + top; + if (props2.scrollWithAnimation) { + scrollTo(y, "y"); + } else { + main.value.scrollTop = y; + } + } + } + } + } + function _transitionEnd(val, direction) { + content.value.style.transition = ""; + content.value.style.webkitTransition = ""; + content.value.style.transform = ""; + content.value.style.webkitTransform = ""; + let _main = main.value; + if (direction === "x") { + _main.style.overflowX = props2.scrollX ? "auto" : "hidden"; + _main.scrollLeft = val; + } else if (direction === "y") { + _main.style.overflowY = props2.scrollY ? "auto" : "hidden"; + _main.scrollTop = val; + } + content.value.removeEventListener("transitionend", __transitionEnd); + content.value.removeEventListener("webkitTransitionEnd", __transitionEnd); + } + function _setRefreshState(_state) { + if (!props2.refresherEnabled) + return; + switch (_state) { + case "refreshing": + state.refresherHeight = props2.refresherThreshold; + if (!beforeRefreshing) { + beforeRefreshing = true; + trigger("refresherrefresh", {}, {}); + emit2("update:refresherTriggered", true); + } + break; + case "restore": + case "refresherabort": + beforeRefreshing = false; + state.refresherHeight = 0; + if (_state === "restore") { + triggerAbort = false; + trigger("refresherrestore", {}, {}); + } + if (_state === "refresherabort" && triggerAbort) { + triggerAbort = false; + trigger("refresherabort", {}, {}); + } + break; + } + state.refreshState = _state; + } + vue.watch(scrollTopNumber, (val) => { + _scrollTopChanged(val); + }); + vue.watch(scrollLeftNumber, (val) => { + _scrollLeftChanged(val); + }); + vue.watch(() => props2.scrollIntoView, (val) => { + _scrollIntoViewChanged(val); + }); + vue.watch(() => props2.refresherTriggered, (val) => { + if (val === true) { + _setRefreshState("refreshing"); + } else if (val === false) { + _setRefreshState("restore"); + } + }); +} +const props$e = { + name: { + type: String, + default: "" + }, + min: { + type: [Number, String], + default: 0 + }, + max: { + type: [Number, String], + default: 100 + }, + value: { + type: [Number, String], + default: 0 + }, + step: { + type: [Number, String], + default: 1 + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "#e9e9e9" + }, + backgroundColor: { + type: String, + default: "#e9e9e9" + }, + activeColor: { + type: String, + default: "#007aff" + }, + selectedColor: { + type: String, + default: "#007aff" + }, + blockColor: { + type: String, + default: "#ffffff" + }, + blockSize: { + type: [Number, String], + default: 28 + }, + showValue: { + type: [Boolean, String], + default: false + } +}; +const index$l = /* @__PURE__ */ defineBuiltInComponent({ + name: "Slider", + props: props$e, + emits: ["changing", "change"], + setup(props2, { + emit: emit2 + }) { + const sliderRef = vue.ref(null); + const sliderValueRef = vue.ref(null); + const sliderHandleRef = vue.ref(null); + const sliderValue = vue.ref(Number(props2.value)); + vue.watch(() => props2.value, (val) => { + sliderValue.value = Number(val); + }); + const trigger = useCustomEvent(sliderRef, emit2); + const state = useSliderState(props2, sliderValue); + const { + _onClick, + _onTrack + } = useSliderLoader(props2, sliderValue, sliderRef, sliderValueRef, trigger); + return () => { + const { + setBgColor, + setBlockBg, + setActiveColor, + setBlockStyle + } = state; + return vue.createVNode("uni-slider", { + "ref": sliderRef, + "onClick": withWebEvent(_onClick) + }, [vue.createVNode("div", { + "class": "uni-slider-wrapper" + }, [vue.createVNode("div", { + "class": "uni-slider-tap-area" + }, [vue.createVNode("div", { + "style": setBgColor.value, + "class": "uni-slider-handle-wrapper" + }, [vue.createVNode("div", { + "ref": sliderHandleRef, + "style": setBlockBg.value, + "class": "uni-slider-handle" + }, null, 4), vue.createVNode("div", { + "style": setBlockStyle.value, + "class": "uni-slider-thumb" + }, null, 4), vue.createVNode("div", { + "style": setActiveColor.value, + "class": "uni-slider-track" + }, null, 4)], 4)]), vue.withDirectives(vue.createVNode("span", { + "ref": sliderValueRef, + "class": "uni-slider-value" + }, [sliderValue.value], 512), [[vue.vShow, props2.showValue]])]), vue.createVNode("slot", null, null)], 8, ["onClick"]); + }; + } +}); +function useSliderState(props2, sliderValue) { + const _getValueWidth = () => { + const max = Number(props2.max); + const min = Number(props2.min); + return 100 * (sliderValue.value - min) / (max - min) + "%"; + }; + const _getBgColor = () => { + return props2.backgroundColor !== "#e9e9e9" ? props2.backgroundColor : props2.color !== "#007aff" ? props2.color : "#007aff"; + }; + const _getActiveColor = () => { + return props2.activeColor !== "#007aff" ? props2.activeColor : props2.selectedColor !== "#e9e9e9" ? props2.selectedColor : "#e9e9e9"; + }; + const state = { + setBgColor: vue.computed(() => ({ + backgroundColor: _getBgColor() + })), + setBlockBg: vue.computed(() => ({ + left: _getValueWidth() + })), + setActiveColor: vue.computed(() => ({ + backgroundColor: _getActiveColor(), + width: _getValueWidth() + })), + setBlockStyle: vue.computed(() => ({ + width: props2.blockSize + "px", + height: props2.blockSize + "px", + marginLeft: -props2.blockSize / 2 + "px", + marginTop: -props2.blockSize / 2 + "px", + left: _getValueWidth(), + backgroundColor: props2.blockColor + })) + }; + return state; +} +function useSliderLoader(props2, sliderValue, sliderRef, sliderValueRef, trigger) { + const _onClick = ($event) => { + if (props2.disabled) { + return; + } + _onUserChangedValue($event); + trigger("change", $event, { + value: sliderValue.value + }); + }; + const _filterValue = (e2) => { + const max = Number(props2.max); + const min = Number(props2.min); + const step = Number(props2.step); + return e2 < min ? min : e2 > max ? max : computeController.mul.call(Math.round((e2 - min) / step), step) + min; + }; + const _onUserChangedValue = (e2) => { + const max = Number(props2.max); + const min = Number(props2.min); + const sliderRightBox = sliderValueRef.value; + const sliderRightBoxLeft = getComputedStyle(sliderRightBox, null).marginLeft; + let sliderRightBoxWidth = sliderRightBox.offsetWidth; + sliderRightBoxWidth = sliderRightBoxWidth + parseInt(sliderRightBoxLeft); + const slider = sliderRef.value; + const offsetWidth = slider.offsetWidth - (props2.showValue ? sliderRightBoxWidth : 0); + const boxLeft = slider.getBoundingClientRect().left; + const value = (e2.x - boxLeft) * (max - min) / offsetWidth + min; + sliderValue.value = _filterValue(value); + }; + const _onTrack = (e2) => { + if (!props2.disabled) { + return e2.detail.state === "move" ? (_onUserChangedValue({ + x: e2.detail.x + }), trigger("changing", e2, { + value: sliderValue.value + }), false) : e2.detail.state === "end" && trigger("change", e2, { + value: sliderValue.value + }); + } + }; + const uniForm = vue.inject(uniFormKey, false); + if (!!uniForm) { + const field = { + reset: () => sliderValue.value = Number(props2.min), + submit: () => { + const data = ["", null]; + if (props2.name !== "") { + data[0] = props2.name; + data[1] = sliderValue.value; + } + return data; + } + }; + uniForm.addField(field); + } + return { + _onClick, + _onTrack + }; +} +var computeController = { + mul: function(arg) { + let m = 0; + let s1 = this.toString(); + let s2 = arg.toString(); + try { + m += s1.split(".")[1].length; + } catch (e2) { + } + try { + m += s2.split(".")[1].length; + } catch (e2) { + } + return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); + } +}; +const props$d = { + indicatorDots: { + type: [Boolean, String], + default: false + }, + vertical: { + type: [Boolean, String], + default: false + }, + autoplay: { + type: [Boolean, String], + default: false + }, + circular: { + type: [Boolean, String], + default: false + }, + interval: { + type: [Number, String], + default: 5e3 + }, + duration: { + type: [Number, String], + default: 500 + }, + current: { + type: [Number, String], + default: 0 + }, + indicatorColor: { + type: String, + default: "" + }, + indicatorActiveColor: { + type: String, + default: "" + }, + previousMargin: { + type: String, + default: "" + }, + nextMargin: { + type: String, + default: "" + }, + currentItemId: { + type: String, + default: "" + }, + skipHiddenItemLayout: { + type: [Boolean, String], + default: false + }, + displayMultipleItems: { + type: [Number, String], + default: 1 + }, + disableTouch: { + type: [Boolean, String], + default: false + }, + navigation: { + type: [Boolean, String], + default: false + }, + navigationColor: { + type: String, + default: "#fff" + }, + navigationActiveColor: { + type: String, + default: "rgba(53, 53, 53, 0.6)" + } +}; +function useState$1(props2) { + const interval = vue.computed(() => { + const interval2 = Number(props2.interval); + return isNaN(interval2) ? 5e3 : interval2; + }); + const duration = vue.computed(() => { + const duration2 = Number(props2.duration); + return isNaN(duration2) ? 500 : duration2; + }); + const displayMultipleItems = vue.computed(() => { + const displayMultipleItems2 = Math.round(props2.displayMultipleItems); + return isNaN(displayMultipleItems2) ? 1 : displayMultipleItems2; + }); + const state = vue.reactive({ + interval, + duration, + displayMultipleItems, + current: Math.round(props2.current) || 0, + currentItemId: props2.currentItemId, + userTracking: false + }); + return state; +} +function useLayout(props2, state, swiperContexts, slideFrameRef, emit2, trigger) { + function cancelSchedule() { + if (timer) { + clearTimeout(timer); + timer = null; + } + } + let timer = null; + let invalid = true; + let viewportPosition = 0; + let viewportMoveRatio = 1; + let animating = null; + let requestedAnimation = false; + let contentTrackViewport = 0; + let transitionStart; + let currentChangeSource = ""; + const swiperEnabled = vue.computed(() => swiperContexts.value.length > state.displayMultipleItems); + const circularEnabled = vue.computed(() => props2.circular && swiperEnabled.value); + function checkCircularLayout(index2) { + if (!invalid) { + for (let items = swiperContexts.value, n = items.length, i = index2 + state.displayMultipleItems, r = 0; r < n; r++) { + const item = items[r]; + const s = Math.floor(index2 / n) * n + r; + const l = s + n; + const c = s - n; + const u = Math.max(index2 - (s + 1), s - i, 0); + const d = Math.max(index2 - (l + 1), l - i, 0); + const h = Math.max(index2 - (c + 1), c - i, 0); + const p2 = Math.min(u, d, h); + const position = [s, l, c][[u, d, h].indexOf(p2)]; + item.updatePosition(position, props2.vertical); + } + } + } + function updateViewport(index2) { + if (!(Math.floor(2 * viewportPosition) === Math.floor(2 * index2) && Math.ceil(2 * viewportPosition) === Math.ceil(2 * index2))) { + if (circularEnabled.value) { + checkCircularLayout(index2); + } + } + const x = props2.vertical ? "0" : 100 * -index2 * viewportMoveRatio + "%"; + const y = props2.vertical ? 100 * -index2 * viewportMoveRatio + "%" : "0"; + const transform = "translate(" + x + ", " + y + ") translateZ(0)"; + const slideFrame = slideFrameRef.value; + if (slideFrame) { + slideFrame.style.webkitTransform = transform; + slideFrame.style.transform = transform; + } + viewportPosition = index2; + if (!transitionStart) { + if (index2 % 1 === 0) { + return; + } + transitionStart = index2; + } + index2 -= Math.floor(transitionStart); + const items = swiperContexts.value; + if (index2 <= -(items.length - 1)) { + index2 += items.length; + } else if (index2 >= items.length) { + index2 -= items.length; + } + index2 = transitionStart % 1 > 0.5 || transitionStart < 0 ? index2 - 1 : index2; + trigger("transition", {}, { + dx: props2.vertical ? 0 : index2 * slideFrame.offsetWidth, + dy: props2.vertical ? index2 * slideFrame.offsetHeight : 0 + }); + } + function endViewportAnimation() { + if (animating) { + updateViewport(animating.toPos); + animating = null; + } + } + function normalizeCurrentValue(current) { + const length = swiperContexts.value.length; + if (!length) { + return -1; + } + const index2 = (Math.round(current) % length + length) % length; + if (circularEnabled.value) { + if (length <= state.displayMultipleItems) { + return 0; + } + } else if (index2 > length - state.displayMultipleItems) { + return length - state.displayMultipleItems; + } + return index2; + } + function cancelViewportAnimation() { + animating = null; + } + function animateFrameFuncProto() { + if (!animating) { + requestedAnimation = false; + return; + } + const _animating = animating; + const toPos = _animating.toPos; + const acc = _animating.acc; + const endTime = _animating.endTime; + const source = _animating.source; + const time = endTime - Date.now(); + if (time <= 0) { + updateViewport(toPos); + animating = null; + requestedAnimation = false; + transitionStart = null; + const item = swiperContexts.value[state.current]; + if (item) { + const currentItemId = item.getItemId(); + trigger("animationfinish", {}, { + current: state.current, + currentItemId, + source + }); + } + return; + } + const s = acc * time * time / 2; + const l = toPos + s; + updateViewport(l); + requestAnimationFrame(animateFrameFuncProto); + } + function animateViewport(current, source, n) { + cancelViewportAnimation(); + const duration = state.duration; + const length = swiperContexts.value.length; + let position = viewportPosition; + if (circularEnabled.value) { + if (n < 0) { + for (; position < current; ) { + position += length; + } + for (; position - length > current; ) { + position -= length; + } + } else if (n > 0) { + for (; position > current; ) { + position -= length; + } + for (; position + length < current; ) { + position += length; + } + if (position + length - current < current - position) { + position += length; + } + } else { + for (; position + length < current; ) { + position += length; + } + for (; position - length > current; ) { + position -= length; + } + if (position + length - current < current - position) { + position += length; + } + } + } else if (source === "click") { + current = current + state.displayMultipleItems - 1 < length ? current : 0; + } + animating = { + toPos: current, + acc: 2 * (position - current) / (duration * duration), + endTime: Date.now() + duration, + source + }; + if (!requestedAnimation) { + requestedAnimation = true; + requestAnimationFrame(animateFrameFuncProto); + } + } + function scheduleAutoplay() { + cancelSchedule(); + const items = swiperContexts.value; + const callback = function() { + timer = null; + currentChangeSource = "autoplay"; + if (circularEnabled.value) { + state.current = normalizeCurrentValue(state.current + 1); + } else { + state.current = state.current + state.displayMultipleItems < items.length ? state.current + 1 : 0; + } + animateViewport(state.current, "autoplay", circularEnabled.value ? 1 : 0); + timer = setTimeout(callback, state.interval); + }; + if (!(invalid || items.length <= state.displayMultipleItems)) { + timer = setTimeout(callback, state.interval); + } + } + function resetLayout() { + cancelSchedule(); + endViewportAnimation(); + const items = swiperContexts.value; + for (let i = 0; i < items.length; i++) { + items[i].updatePosition(i, props2.vertical); + } + viewportMoveRatio = 1; + const slideFrameEl = slideFrameRef.value; + if (state.displayMultipleItems === 1 && items.length) { + const itemRect = items[0].getBoundingClientRect(); + const slideFrameRect = slideFrameEl.getBoundingClientRect(); + viewportMoveRatio = itemRect.width / slideFrameRect.width; + if (!(viewportMoveRatio > 0 && viewportMoveRatio < 1)) { + viewportMoveRatio = 1; + } + } + const position = viewportPosition; + viewportPosition = -2; + const current = state.current; + if (current >= 0) { + invalid = false; + if (state.userTracking) { + updateViewport(position + current - contentTrackViewport); + contentTrackViewport = current; + } else { + updateViewport(current); + if (props2.autoplay) { + scheduleAutoplay(); + } + } + } else { + invalid = true; + updateViewport(-state.displayMultipleItems - 1); + } + } + vue.watch([() => props2.current, () => props2.currentItemId, () => [...swiperContexts.value]], () => { + let current = -1; + if (props2.currentItemId) { + for (let i = 0, items = swiperContexts.value; i < items.length; i++) { + const itemId = items[i].getItemId(); + if (itemId === props2.currentItemId) { + current = i; + break; + } + } + } + if (current < 0) { + current = Math.round(props2.current) || 0; + } + current = current < 0 ? 0 : current; + if (state.current !== current) { + currentChangeSource = ""; + state.current = current; + } + }); + vue.watch([() => props2.vertical, () => circularEnabled.value, () => state.displayMultipleItems, () => [...swiperContexts.value]], resetLayout); + vue.watch(() => state.interval, () => { + if (timer) { + cancelSchedule(); + scheduleAutoplay(); + } + }); + function currentChanged(current, history) { + const source = currentChangeSource; + currentChangeSource = ""; + const items = swiperContexts.value; + if (!source) { + const length = items.length; + animateViewport(current, "", circularEnabled.value && history + (length - current) % length > length / 2 ? 1 : 0); + } + const item = items[current]; + if (item) { + const currentItemId = state.currentItemId = item.getItemId(); + trigger("change", {}, { + current: state.current, + currentItemId, + source + }); + } + } + vue.watch(() => state.current, (val, oldVal) => { + currentChanged(val, oldVal); + emit2("update:current", val); + }); + vue.watch(() => state.currentItemId, (val) => { + emit2("update:currentItemId", val); + }); + function inintAutoplay(enable) { + if (enable) { + scheduleAutoplay(); + } else { + cancelSchedule(); + } + } + vue.watch(() => props2.autoplay && !state.userTracking, inintAutoplay); + inintAutoplay(props2.autoplay && !state.userTracking); + function onSwiperDotClick(index2) { + animateViewport(state.current = index2, currentChangeSource = "click", circularEnabled.value ? 1 : 0); + } + return { + onSwiperDotClick, + circularEnabled, + swiperEnabled + }; +} +const index$k = /* @__PURE__ */ defineBuiltInComponent({ + name: "Swiper", + props: props$d, + emits: ["change", "transition", "animationfinish", "update:current", "update:currentItemId"], + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const slidesWrapperRef = vue.ref(null); + const slideFrameRef = vue.ref(null); + const state = useState$1(props2); + const slidesStyle = vue.computed(() => { + let style = {}; + if (props2.nextMargin || props2.previousMargin) { + style = props2.vertical ? { + left: 0, + right: 0, + top: rpx2px(props2.previousMargin, true), + bottom: rpx2px(props2.nextMargin, true) + } : { + top: 0, + bottom: 0, + left: rpx2px(props2.previousMargin, true), + right: rpx2px(props2.nextMargin, true) + }; + } + return style; + }); + const slideFrameStyle = vue.computed(() => { + const value = Math.abs(100 / state.displayMultipleItems) + "%"; + return { + width: props2.vertical ? "100%" : value, + height: !props2.vertical ? "100%" : value + }; + }); + let swiperItems = []; + const originSwiperContexts = []; + const swiperContexts = vue.ref([]); + function updateSwiperContexts() { + const contexts = []; + for (let index2 = 0; index2 < swiperItems.length; index2++) { + let swiperItem = swiperItems[index2]; + if (!(swiperItem instanceof Element)) { + swiperItem = swiperItem.el; + } + const swiperContext = originSwiperContexts.find((context) => swiperItem === context.rootRef.value); + if (swiperContext) { + contexts.push(vue.markRaw(swiperContext)); + } + } + swiperContexts.value = contexts; + } + const addSwiperContext = function(swiperContext) { + originSwiperContexts.push(swiperContext); + updateSwiperContexts(); + }; + vue.provide("addSwiperContext", addSwiperContext); + const removeSwiperContext = function(swiperContext) { + const index2 = originSwiperContexts.indexOf(swiperContext); + if (index2 >= 0) { + originSwiperContexts.splice(index2, 1); + updateSwiperContexts(); + } + }; + vue.provide("removeSwiperContext", removeSwiperContext); + const { + onSwiperDotClick, + circularEnabled, + swiperEnabled + } = useLayout(props2, state, swiperContexts, slideFrameRef, emit2, trigger); + let createNavigationTsx = () => null; + { + createNavigationTsx = useSwiperNavigation(rootRef, props2, state, onSwiperDotClick, swiperContexts, circularEnabled, swiperEnabled); + } + return () => { + const defaultSlots = slots.default && slots.default(); + swiperItems = flatVNode(defaultSlots); + return vue.createVNode("uni-swiper", { + "ref": rootRef + }, [vue.createVNode("div", { + "ref": slidesWrapperRef, + "class": "uni-swiper-wrapper" + }, [vue.createVNode("div", { + "class": "uni-swiper-slides", + "style": slidesStyle.value + }, [vue.createVNode("div", { + "ref": slideFrameRef, + "class": "uni-swiper-slide-frame", + "style": slideFrameStyle.value + }, [defaultSlots], 4)], 4), props2.indicatorDots && vue.createVNode("div", { + "class": ["uni-swiper-dots", props2.vertical ? "uni-swiper-dots-vertical" : "uni-swiper-dots-horizontal"] + }, [swiperContexts.value.map((_, index2, array) => vue.createVNode("div", { + "onClick": () => onSwiperDotClick(index2), + "class": { + "uni-swiper-dot": true, + "uni-swiper-dot-active": index2 < state.current + state.displayMultipleItems && index2 >= state.current || index2 < state.current + state.displayMultipleItems - array.length + }, + "style": { + background: index2 === state.current ? props2.indicatorActiveColor : props2.indicatorColor + } + }, null, 14, ["onClick"]))], 2), createNavigationTsx()], 512)], 512); + }; + } +}); +const useSwiperNavigation = (rootRef, props2, state, onSwiperDotClick, swiperContext, circularEnabled, swiperEnabled) => { + let isNavigationAuto = false; + let prevDisabled = false; + let nextDisabled = false; + let hideNavigation = vue.ref(false); + vue.watchEffect(() => { + isNavigationAuto = props2.navigation === "auto"; + hideNavigation.value = props2.navigation !== true || isNavigationAuto; + swiperAddMouseEvent(); + }); + vue.watchEffect(() => { + const swiperItemLength = swiperContext.value.length; + const notCircular = !circularEnabled.value; + prevDisabled = state.current === 0 && notCircular; + nextDisabled = state.current === swiperItemLength - 1 && notCircular || notCircular && state.current + state.displayMultipleItems >= swiperItemLength; + if (!swiperEnabled.value) { + prevDisabled = true; + nextDisabled = true; + isNavigationAuto && (hideNavigation.value = true); + } + }); + function navigationHover(event, type) { + const target = event.currentTarget; + if (!target) + return; + target.style.backgroundColor = type === "over" ? props2.navigationActiveColor : ""; + } + const navigationAttr = { + onMouseover: (event) => navigationHover(event, "over"), + onMouseout: (event) => navigationHover(event, "out") + }; + function navigationClick($event, type, disabled) { + $event.stopPropagation(); + if (disabled) + return; + const swiperItemLength = swiperContext.value.length; + let _current = state.current; + switch (type) { + case "prev": + _current--; + if (_current < 0 && circularEnabled.value) { + _current = swiperItemLength - 1; + } + break; + case "next": + _current++; + if (_current >= swiperItemLength && circularEnabled.value) { + _current = 0; + } + break; + } + onSwiperDotClick(_current); + } + const createNavigationSVG = () => createSvgIconVNode(ICON_PATH_BACK, props2.navigationColor, 26); + let setHideNavigationTimer; + const _mousemove = (e2) => { + clearTimeout(setHideNavigationTimer); + const { + clientX, + clientY + } = e2; + const { + left, + right, + top, + bottom, + width, + height + } = rootRef.value.getBoundingClientRect(); + let hide = false; + if (props2.vertical) { + hide = !(clientY - top < height / 3 || bottom - clientY < height / 3); + } else { + hide = !(clientX - left < width / 3 || right - clientX < width / 3); + } + if (hide) { + return setHideNavigationTimer = setTimeout(() => { + hideNavigation.value = hide; + }, 300); + } + hideNavigation.value = hide; + }; + const _mouseleave = () => { + hideNavigation.value = true; + }; + function swiperAddMouseEvent() { + if (rootRef.value) { + rootRef.value.removeEventListener("mousemove", _mousemove); + rootRef.value.removeEventListener("mouseleave", _mouseleave); + if (isNavigationAuto) { + rootRef.value.addEventListener("mousemove", _mousemove); + rootRef.value.addEventListener("mouseleave", _mouseleave); + } + } + } + function createNavigationTsx() { + const navigationClass = { + "uni-swiper-navigation-hide": hideNavigation.value, + "uni-swiper-navigation-vertical": props2.vertical + }; + if (props2.navigation) { + return vue.createVNode(vue.Fragment, null, [vue.createVNode("div", vue.mergeProps({ + "class": ["uni-swiper-navigation uni-swiper-navigation-prev", shared.extend({ + "uni-swiper-navigation-disabled": prevDisabled + }, navigationClass)], + "onClick": (e2) => navigationClick(e2, "prev", prevDisabled) + }, navigationAttr), [createNavigationSVG()], 16, ["onClick"]), vue.createVNode("div", vue.mergeProps({ + "class": ["uni-swiper-navigation uni-swiper-navigation-next", shared.extend({ + "uni-swiper-navigation-disabled": nextDisabled + }, navigationClass)], + "onClick": (e2) => navigationClick(e2, "next", nextDisabled) + }, navigationAttr), [createNavigationSVG()], 16, ["onClick"])]); + } + return null; + } + return createNavigationTsx; +}; +const props$c = { + itemId: { + type: String, + default: "" + } +}; +const index$j = /* @__PURE__ */ defineBuiltInComponent({ + name: "SwiperItem", + props: props$c, + setup(props2, { + slots + }) { + const rootRef = vue.ref(null); + return () => { + return vue.createVNode("uni-swiper-item", { + "ref": rootRef, + "style": { + position: "absolute", + width: "100%", + height: "100%" + } + }, [slots.default && slots.default()], 512); + }; + } +}); +const props$b = { + name: { + type: String, + default: "" + }, + checked: { + type: [Boolean, String], + default: false + }, + type: { + type: String, + default: "switch" + }, + id: { + type: String, + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "" + } +}; +const index$i = /* @__PURE__ */ defineBuiltInComponent({ + name: "Switch", + props: props$b, + emits: ["change"], + setup(props2, { + emit: emit2 + }) { + const rootRef = vue.ref(null); + const switchChecked = vue.ref(props2.checked); + const uniLabel = useSwitchInject(props2, switchChecked); + const trigger = useCustomEvent(rootRef, emit2); + vue.watch(() => props2.checked, (val) => { + switchChecked.value = val; + }); + const _onClick = ($event) => { + if (props2.disabled) { + return; + } + switchChecked.value = !switchChecked.value; + trigger("change", $event, { + value: switchChecked.value + }); + }; + if (!!uniLabel) { + uniLabel.addHandler(_onClick); + } + return () => { + const { + color, + type + } = props2; + const booleanAttrs = useBooleanAttr(props2, "disabled"); + const switchInputStyle = {}; + if (color && switchChecked.value) { + switchInputStyle["backgroundColor"] = color; + switchInputStyle["borderColor"] = color; + } + return vue.createVNode("uni-switch", vue.mergeProps({ + "ref": rootRef + }, booleanAttrs, { + "onClick": _onClick + }), [vue.createVNode("div", { + "class": "uni-switch-wrapper" + }, [vue.withDirectives(vue.createVNode("div", { + "class": ["uni-switch-input", [switchChecked.value ? "uni-switch-input-checked" : ""]], + "style": switchInputStyle + }, null, 6), [[vue.vShow, type === "switch"]]), vue.withDirectives(vue.createVNode("div", { + "class": "uni-checkbox-input" + }, [switchChecked.value ? createSvgIconVNode(ICON_PATH_SUCCESS_NO_CIRCLE, props2.color, 22) : ""], 512), [[vue.vShow, type === "checkbox"]])])], 16, ["onClick"]); + }; + } +}); +function useSwitchInject(props2, switchChecked) { + const uniForm = vue.inject(uniFormKey, false); + const uniLabel = vue.inject(uniLabelKey, false); + const formField = { + submit: () => { + const data = ["", null]; + if (props2.name) { + data[0] = props2.name; + data[1] = switchChecked.value; + } + return data; + }, + reset: () => { + switchChecked.value = false; + } + }; + if (!!uniForm) { + uniForm.addField(formField); + } + return uniLabel; +} +const SPACE_UNICODE = { + ensp: " ", + emsp: " ", + nbsp: " " +}; +function parseText(text, options) { + return text.replace(/\\n/g, uniShared.LINEFEED).split(uniShared.LINEFEED).map((text2) => { + return normalizeText(text2, options); + }); +} +function normalizeText(text, { space, decode }) { + if (!text) { + return text; + } + if (space && SPACE_UNICODE[space]) { + text = text.replace(/ /g, SPACE_UNICODE[space]); + } + if (!decode) { + return text; + } + return text.replace(/ /g, SPACE_UNICODE.nbsp).replace(/ /g, SPACE_UNICODE.ensp).replace(/ /g, SPACE_UNICODE.emsp).replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'"); +} +const index$h = /* @__PURE__ */ defineBuiltInComponent({ + name: "Text", + props: { + selectable: { + type: [Boolean, String], + default: false + }, + space: { + type: String, + default: "" + }, + decode: { + type: [Boolean, String], + default: false + } + }, + setup(props2, { + slots + }) { + return () => { + const children = []; + if (slots.default) { + slots.default().forEach((vnode) => { + if (vnode.shapeFlag & 8 && vnode.type !== vue.Comment) { + const lines = parseText(vnode.children, { + space: props2.space, + decode: props2.decode + }); + const len = lines.length - 1; + lines.forEach((line, index2) => { + if (index2 === 0 && !line) + ; + else { + children.push(vue.createTextVNode(line)); + } + if (index2 !== len) { + children.push(vue.createVNode("br")); + } + }); + } else { + if (process.env.NODE_ENV !== "production" && vnode.shapeFlag & 6 && vnode.type.name !== "Text") { + console.warn("Do not nest other components in the text component, as there may be display differences on different platforms."); + } + children.push(vnode); + } + }); + } + return vue.createVNode("uni-text", { + "selectable": props2.selectable ? true : null + }, [vue.createVNode("span", null, children)], 8, ["selectable"]); + }; + } +}); +const props$a = /* @__PURE__ */ shared.extend({}, props$k, { + placeholderClass: { + type: String, + default: "input-placeholder" + }, + autoHeight: { + type: [Boolean, String], + default: false + }, + confirmType: { + type: String, + default: "return", + validator(val) { + return ConfirmTypes.concat("return").includes(val); + } + } +}); +let fixMargin = false; +const ConfirmTypes = ["done", "go", "next", "search", "send"]; +const index$g = /* @__PURE__ */ defineBuiltInComponent({ + name: "Textarea", + props: props$a, + emits: ["confirm", "linechange", ...emit], + setup(props2, { + emit: emit2 + }) { + const rootRef = vue.ref(null); + const wrapperRef = vue.ref(null); + const { + fieldRef, + state, + scopedAttrsState, + fixDisabledColor, + trigger + } = useField(props2, rootRef, emit2); + const valueCompute = vue.computed(() => state.value.split(uniShared.LINEFEED)); + const isDone = vue.computed(() => ConfirmTypes.includes(props2.confirmType)); + const heightRef = vue.ref(0); + const lineRef = vue.ref(null); + vue.watch(() => heightRef.value, (height) => { + const el = rootRef.value; + const lineEl = lineRef.value; + const wrapper2 = wrapperRef.value; + let lineHeight = parseFloat(getComputedStyle(el).lineHeight); + if (isNaN(lineHeight)) { + lineHeight = lineEl.offsetHeight; + } + var lineCount = Math.round(height / lineHeight); + trigger("linechange", {}, { + height, + heightRpx: 750 / window.innerWidth * height, + lineCount + }); + if (props2.autoHeight) { + el.style.height = "auto"; + wrapper2.style.height = height + "px"; + } + }); + function onResize({ + height + }) { + heightRef.value = height; + } + function confirm(event) { + trigger("confirm", event, { + value: state.value + }); + } + function onKeyDownEnter(event) { + if (event.key !== "Enter") { + return; + } + if (isDone.value) { + event.preventDefault(); + } + } + function onKeyUpEnter(event) { + if (event.key !== "Enter") { + return; + } + if (isDone.value) { + confirm(event); + const textarea = event.target; + !props2.confirmHold && textarea.blur(); + } + } + return () => { + let textareaNode = props2.disabled && fixDisabledColor ? vue.createVNode("textarea", { + "key": "disabled-textarea", + "ref": fieldRef, + "value": state.value, + "tabindex": "-1", + "readonly": !!props2.disabled, + "maxlength": state.maxlength, + "class": { + "uni-textarea-textarea": true, + "uni-textarea-textarea-fix-margin": fixMargin + }, + "style": { + overflowY: props2.autoHeight ? "hidden" : "auto" + }, + "onFocus": (event) => event.target.blur() + }, null, 46, ["value", "readonly", "maxlength", "onFocus"]) : vue.createVNode("textarea", { + "key": "textarea", + "ref": fieldRef, + "value": state.value, + "disabled": !!props2.disabled, + "maxlength": state.maxlength, + "enterkeyhint": props2.confirmType, + "inputmode": props2.inputmode, + "class": { + "uni-textarea-textarea": true, + "uni-textarea-textarea-fix-margin": fixMargin + }, + "style": { + overflowY: props2.autoHeight ? "hidden" : "auto" + }, + "onKeydown": onKeyDownEnter, + "onKeyup": onKeyUpEnter + }, null, 46, ["value", "disabled", "maxlength", "enterkeyhint", "inputmode", "onKeydown", "onKeyup"]); + return vue.createVNode("uni-textarea", { + "ref": rootRef + }, [vue.createVNode("div", { + "ref": wrapperRef, + "class": "uni-textarea-wrapper" + }, [vue.withDirectives(vue.createVNode("div", vue.mergeProps(scopedAttrsState.attrs, { + "style": props2.placeholderStyle, + "class": ["uni-textarea-placeholder", props2.placeholderClass] + }), [props2.placeholder], 16), [[vue.vShow, !state.value.length]]), vue.createVNode("div", { + "ref": lineRef, + "class": "uni-textarea-line" + }, [" "], 512), vue.createVNode("div", { + "class": "uni-textarea-compute" + }, [valueCompute.value.map((item) => vue.createVNode("div", null, [item.trim() ? item : "."])), vue.createVNode(ResizeSensor, { + "initial": true, + "onResize": onResize + }, null, 8, ["initial", "onResize"])]), props2.confirmType === "search" ? vue.createVNode("form", { + "action": "", + "onSubmit": () => false, + "class": "uni-input-form" + }, [textareaNode], 40, ["onSubmit"]) : textareaNode], 512)], 512); + }; + } +}); +const index$f = /* @__PURE__ */ defineBuiltInComponent({ + name: "View", + props: shared.extend({}, hoverProps), + setup(props2, { + slots + }) { + const { + hovering, + binding + } = useHover(props2); + return () => { + const hoverClass = props2.hoverClass; + if (hoverClass && hoverClass !== "none") { + return vue.createVNode("uni-view", vue.mergeProps({ + "class": hovering.value ? hoverClass : "" + }, binding), [slots.default && slots.default()], 16); + } + return vue.createVNode("uni-view", null, [slots.default && slots.default()]); + }; + } +}); +function useSubscribe(callback, name, multiple, pageId) { + const instance = vue.getCurrentInstance(); + instance.proxy; +} +let index$e = 0; +function useContextInfo(_id) { + useCurrentPageId(); + const instance = vue.getCurrentInstance(); + const vm = instance.proxy; + const type = vm.$options.name.toLowerCase(); + const id = _id || vm.id || `context${index$e++}`; + return `${type}.${id}`; +} +function injectLifecycleHook(name, hook, publicThis, instance) { + if (shared.isFunction(hook)) { + vue.injectHook(name, hook.bind(publicThis), instance); + } +} +function initHooks(options, instance, publicThis) { + var _a; + const mpType = options.mpType || publicThis.$mpType; + if (!mpType || mpType === "component") { + return; + } + Object.keys(options).forEach((name) => { + if (uniShared.isUniLifecycleHook(name, options[name], false)) { + const hooks = options[name]; + if (shared.isArray(hooks)) { + hooks.forEach( + (hook) => injectLifecycleHook(name, hook, publicThis, instance) + ); + } else { + injectLifecycleHook(name, hooks, publicThis, instance); + } + } + }); + if (mpType === "page") { + instance.__isVisible = true; + try { + invokeHook(publicThis, uniShared.ON_LOAD, instance.attrs.__pageQuery); + delete instance.attrs.__pageQuery; + if (((_a = publicThis.$page) == null ? void 0 : _a.openType) !== "preloadPage") { + invokeHook(publicThis, uniShared.ON_SHOW); + } + } catch (e2) { + console.error(e2.message + uniShared.LINEFEED + e2.stack); + } + } +} +function applyOptions(options, instance, publicThis) { + initHooks(options, instance, publicThis); +} +function set(target, key, val) { + return target[key] = val; +} +function createErrorHandler(app) { + return function errorHandler(err, instance, _info) { + if (!instance) { + throw err; + } + const appInstance = app._instance; + if (!appInstance || !appInstance.proxy) { + throw err; + } + { + appInstance.proxy.$callHook(uniShared.ON_ERROR, err); + } + }; +} +function mergeAsArray(to, from) { + return to ? [...new Set([].concat(to, from))] : from; +} +function initOptionMergeStrategies(optionMergeStrategies) { + uniShared.UniLifecycleHooks.forEach((name) => { + optionMergeStrategies[name] = mergeAsArray; + }); +} +let realAtob; +const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; +const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; +if (typeof atob !== "function") { + realAtob = function(str) { + str = String(str).replace(/[\t\n\f\r ]+/g, ""); + if (!b64re.test(str)) { + throw new Error( + "Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded." + ); + } + str += "==".slice(2 - (str.length & 3)); + var bitmap; + var result = ""; + var r1; + var r2; + var i = 0; + for (; i < str.length; ) { + bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 | (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++))); + result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) : String.fromCharCode( + bitmap >> 16 & 255, + bitmap >> 8 & 255, + bitmap & 255 + ); + } + return result; + }; +} else { + realAtob = atob; +} +function b64DecodeUnicode(str) { + return decodeURIComponent( + realAtob(str).split("").map(function(c) { + return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); + }).join("") + ); +} +function getCurrentUserInfo() { + const token = uni.getStorageSync("uni_id_token") || ""; + const tokenArr = token.split("."); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0 + }; + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } catch (error) { + throw new Error("获取当前用户信息出错,详细错误信息为:" + error.message); + } + userInfo.tokenExpired = userInfo.exp * 1e3; + delete userInfo.exp; + delete userInfo.iat; + return userInfo; +} +function uniIdMixin(globalProperties) { + globalProperties.uniIDHasRole = function(roleId) { + const { role } = getCurrentUserInfo(); + return role.indexOf(roleId) > -1; + }; + globalProperties.uniIDHasPermission = function(permissionId) { + const { permission } = getCurrentUserInfo(); + return this.uniIDHasRole("admin") || permission.indexOf(permissionId) > -1; + }; + globalProperties.uniIDTokenValid = function() { + const { tokenExpired } = getCurrentUserInfo(); + return tokenExpired > Date.now(); + }; +} +function initApp$1(app) { + const appConfig = app._context.config; + appConfig.errorHandler = uniShared.invokeCreateErrorHandler(app, createErrorHandler); + initOptionMergeStrategies(appConfig.optionMergeStrategies); + const globalProperties = appConfig.globalProperties; + { + if (__UNI_FEATURE_UNI_CLOUD__) { + uniIdMixin(globalProperties); + } + } + { + globalProperties.$set = set; + globalProperties.$applyOptions = applyOptions; + } + { + uniShared.invokeCreateVueAppHook(app); + } +} +const pageMetaKey = PolySymbol(process.env.NODE_ENV !== "production" ? "UniPageMeta" : "upm"); +function usePageMeta() { + return vue.inject(pageMetaKey); +} +function providePageMeta(id) { + const pageMeta = initPageMeta(id); + vue.provide(pageMetaKey, pageMeta); + return pageMeta; +} +function usePageRoute() { + if (__UNI_FEATURE_PAGES__) { + return vueRouter.useRoute(); + } + const url = location.href; + const searchPos = url.indexOf("?"); + const hashPos = url.indexOf("#", searchPos > -1 ? searchPos : 0); + let query = {}; + if (searchPos > -1) { + query = uniShared.parseQuery( + url.slice(searchPos + 1, hashPos > -1 ? hashPos : url.length) + ); + } + const { meta } = __uniRoutes[0]; + const path = uniShared.addLeadingSlash(meta.route); + return { + meta, + query, + path, + matched: [{ path }] + }; +} +function initPageMeta(id) { + if (__UNI_FEATURE_PAGES__) { + return vue.reactive( + normalizePageMeta( + JSON.parse( + JSON.stringify( + initRouteMeta( + vueRouter.useRoute().meta, + id + ) + ) + ) + ) + ); + } + return vue.reactive( + normalizePageMeta( + JSON.parse(JSON.stringify(initRouteMeta(__uniRoutes[0].meta, id))) + ) + ); +} +function normalizePageMeta(pageMeta) { + if (__UNI_FEATURE_PULL_DOWN_REFRESH__) { + const { enablePullDownRefresh, navigationBar } = pageMeta; + if (enablePullDownRefresh) { + const pullToRefresh = normalizePullToRefreshRpx( + shared.extend( + { + support: true, + color: "#2BD009", + style: "circle", + height: 70, + range: 150, + offset: 0 + }, + pageMeta.pullToRefresh + ) + ); + const { type, style } = navigationBar; + if (style !== "custom" && type !== "transparent") { + pullToRefresh.offset += uniShared.NAVBAR_HEIGHT + 0; + } + pageMeta.pullToRefresh = pullToRefresh; + } + } + if (__UNI_FEATURE_NAVIGATIONBAR__) { + const { navigationBar } = pageMeta; + const { titleSize, titleColor, backgroundColor } = navigationBar; + navigationBar.titleText = navigationBar.titleText || ""; + navigationBar.type = navigationBar.type || "default"; + navigationBar.titleSize = titleSize || "16px"; + navigationBar.titleColor = titleColor || "#ffffff"; + navigationBar.backgroundColor = backgroundColor || "#F7F7F7"; + __UNI_FEATURE_I18N_LOCALE__ && initNavigationBarI18n(navigationBar); + } + return pageMeta; +} +function getStateId() { + { + return 1; + } +} +let tabBar; +function useTabBar() { + if (!tabBar) { + tabBar = __uniConfig.tabBar && vue.reactive(initTabBarI18n(__uniConfig.tabBar)); + } + return tabBar; +} +const envMethod = /* @__PURE__ */ (() => "env")(); +function normalizeWindowBottom(windowBottom) { + return envMethod ? `calc(${windowBottom}px + ${envMethod}(safe-area-inset-bottom))` : `${windowBottom}px`; +} +const SEP = "$$"; +const currentPagesMap = /* @__PURE__ */ new Map(); +function pruneCurrentPages() { + currentPagesMap.forEach((page, id2) => { + if (page.$.isUnmounted) { + currentPagesMap.delete(id2); + } + }); +} +function getCurrentPages$1() { + const curPages = []; + const pages = currentPagesMap.values(); + for (const page of pages) { + if (page.$.__isTabBar) { + if (page.$.__isActive) { + curPages.push(page); + } + } else { + curPages.push(page); + } + } + return curPages; +} +function initPublicPage(route) { + const meta = usePageMeta(); + if (!__UNI_FEATURE_PAGES__) { + return initPageInternalInstance("navigateTo", __uniRoutes[0].path, {}, meta); + } + let fullPath = route.fullPath; + if (route.meta.isEntry && fullPath.indexOf(route.meta.route) === -1) { + fullPath = "/" + route.meta.route + fullPath.replace("/", ""); + } + return initPageInternalInstance("navigateTo", fullPath, {}, meta); +} +function initPage(vm) { + const route = vm.$route; + const page = initPublicPage(route); + initPageVm(vm, page); + currentPagesMap.set(normalizeRouteKey(page.path, page.id), vm); +} +function normalizeRouteKey(path, id2) { + return path + SEP + id2; +} +function useKeepAliveRoute() { + const route = vueRouter.useRoute(); + const routeKey = vue.computed( + () => normalizeRouteKey("/" + route.meta.route, getStateId()) + ); + const isTabBar = vue.computed(() => route.meta.isTabBar); + return { + routeKey, + isTabBar, + routeCache + }; +} +const pageCacheMap = /* @__PURE__ */ new Map(); +const routeCache = { + get(key) { + return pageCacheMap.get(key); + }, + set(key, value) { + pruneRouteCache(key); + pageCacheMap.set(key, value); + }, + delete(key) { + const vnode = pageCacheMap.get(key); + if (!vnode) { + return; + } + pageCacheMap.delete(key); + }, + forEach(fn) { + pageCacheMap.forEach(fn); + } +}; +function isTabBarVNode(vnode) { + return vnode.props.type === "tabBar"; +} +function pruneRouteCache(key) { + const pageId = parseInt(key.split(SEP)[1]); + if (!pageId) { + return; + } + routeCache.forEach((vnode, key2) => { + const cPageId = parseInt(key2.split(SEP)[1]); + if (cPageId && cPageId > pageId) { + if (__UNI_FEATURE_TABBAR__ && isTabBarVNode(vnode)) { + return; + } + routeCache.delete(key2); + routeCache.pruneCacheEntry(vnode); + vue.nextTick(() => pruneCurrentPages()); + } + }); +} +function initRouter(app) { + const router = vueRouter.createRouter(createRouterOptions()); + app.router = router; + app.use(router); +} +const scrollBehavior = (_to, _from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } +}; +function createRouterOptions() { + return { + history: initHistory(), + strict: !!__uniConfig.router.strict, + routes: __uniRoutes, + scrollBehavior + }; +} +function initHistory() { + let { routerBase } = __uniConfig.router; + if (routerBase === "/") { + routerBase = ""; + } + { + return vueRouter.createMemoryHistory(routerBase); + } +} +const index$d = { + install(app) { + initApp$1(app); + if (!app.config.warnHandler) { + app.config.warnHandler = warnHandler; + } + if (__UNI_FEATURE_PAGES__) { + initRouter(app); + } + } +}; +function warnHandler(msg, instance, trace) { + if (instance) { + const name = instance.$.type.name; + if ("PageMetaHead" === name) { + return; + } + const parent = instance.$.parent; + if (parent && parent.type.name === "PageMeta") { + return; + } + } + const warnArgs = [`[Vue warn]: ${msg}`]; + if (trace.length) { + warnArgs.push(` +`, trace); + } + console.warn(...warnArgs); +} +const clazz = { class: "uni-async-loading" }; +const loadingVNode = /* @__PURE__ */ vue.createVNode( + "i", + { class: "uni-loading" }, + null, + -1 + /* HOISTED */ +); +const AsyncLoadingComponent = /* @__PURE__ */ defineSystemComponent({ + name: "AsyncLoading", + render() { + return vue.openBlock(), vue.createBlock("div", clazz, [loadingVNode]); + } +}); +function reload() { + window.location.reload(); +} +const AsyncErrorComponent = /* @__PURE__ */ defineSystemComponent({ + name: "AsyncError", + setup() { + initI18nAsyncMsgsOnce(); + const { + t: t2 + } = useI18n(); + return () => vue.createVNode("div", { + "class": "uni-async-error", + "onClick": reload + }, [t2("uni.async.error")], 8, ["onClick"]); + } +}); +let appVm; +function getApp$1() { + return appVm; +} +function initApp(vm) { + appVm = vm; + Object.defineProperty(appVm.$.ctx, "$children", { + get() { + return getCurrentPages().map((page) => page.$vm); + } + }); + const app = appVm.$.appContext.app; + if (!app.component(AsyncLoadingComponent.name)) { + app.component(AsyncLoadingComponent.name, AsyncLoadingComponent); + } + if (!app.component(AsyncErrorComponent.name)) { + app.component(AsyncErrorComponent.name, AsyncErrorComponent); + } + initAppVm(appVm); + defineGlobalData(appVm); +} +function wrapperComponentSetup(comp, { clone, init, setup, before }) { + if (clone) { + comp = shared.extend({}, comp); + } + before && before(comp); + const oldSetup = comp.setup; + comp.setup = (props2, ctx) => { + const instance = vue.getCurrentInstance(); + init(instance.proxy); + const query = setup(instance); + if (oldSetup) { + return oldSetup(query || props2, ctx); + } + }; + return comp; +} +function setupComponent(comp, options) { + if (comp && (comp.__esModule || comp[Symbol.toStringTag] === "Module")) { + return wrapperComponentSetup(comp.default, options); + } + return wrapperComponentSetup(comp, options); +} +function setupWindow(comp, id) { + return setupComponent(comp, { + init: (vm) => { + vm.$page = { + id + }; + }, + setup(instance) { + instance.$pageInstance = instance; + } + }); +} +function setupPage(comp) { + const weiboMixin = { + onShow() { + let onShareAppMessage = this.$options.onShareAppMessage; + if (onShareAppMessage && typeof onShareAppMessage === "function") { + window.weibo.sendShareMessage({ + data: onShareAppMessage.call(this) + }); + } else { + window.weibo.sendShareMessage({ + data: null + }); + } + } + }; + if (window.weibo && typeof window.weibo.sendShareMessage === "function") { + comp.mixins = [weiboMixin]; + } + if (process.env.NODE_ENV !== "production") { + comp.__mpType = "page"; + } + return setupComponent(comp, { + clone: true, + // 页面组件可能会被其他地方手动引用,比如 windows 等,需要 clone 一份新的作为页面组件 + init: initPage, + setup(instance) { + instance.$pageInstance = instance; + const route = usePageRoute(); + const query = uniShared.decodedQuery(route.query); + instance.attrs.__pageQuery = query; + instance.proxy.$page.options = query; + { + return query; + } + } + }); +} +function setupApp(comp) { + if (process.env.NODE_ENV !== "production") { + comp.__mpType = "app"; + } + return setupComponent(comp, { + init: initApp, + setup(instance) { + const route = usePageRoute(); + { + return route.query; + } + }, + before(comp2) { + comp2.mpType = "app"; + const { setup } = comp2; + const render = () => { + return vue.openBlock(), vue.createBlock(LayoutComponent); + }; + comp2.setup = (props2, ctx) => { + const res = setup && setup(props2, ctx); + return shared.isFunction(res) ? render : res; + }; + comp2.render = render; + } + }); +} +function formatTime(val) { + val = val > 0 && val < Infinity ? val : 0; + const h = Math.floor(val / 3600); + const m = Math.floor(val % 3600 / 60); + const s = Math.floor(val % 3600 % 60); + const hStr = (h < 10 ? "0" : "") + h; + const mStr = (m < 10 ? "0" : "") + m; + const sStr = (s < 10 ? "0" : "") + s; + let str = mStr + ":" + sStr; + if (hStr !== "00") { + str = hStr + ":" + str; + } + return str; +} +function useGesture(props2, videoRef, fullscreenState) { + const state = vue.reactive({ + gestureType: "none", + volumeOld: 0, + volumeNew: 0, + currentTimeOld: 0, + currentTimeNew: 0 + }); + const touchStartOrigin = { + x: 0, + y: 0 + }; + function onTouchstart(event) { + const toucher = event.targetTouches[0]; + touchStartOrigin.x = toucher.pageX; + touchStartOrigin.y = toucher.pageY; + state.gestureType = "none"; + state.volumeOld = 0; + state.currentTimeOld = state.currentTimeNew = 0; + } + function onTouchmove(event) { + function stop() { + event.stopPropagation(); + event.preventDefault(); + } + if (fullscreenState.fullscreen) { + stop(); + } + const gestureType = state.gestureType; + if (gestureType === "stop") { + return; + } + const toucher = event.targetTouches[0]; + const pageX = toucher.pageX; + const pageY = toucher.pageY; + const origin = touchStartOrigin; + const video = videoRef.value; + if (gestureType === "progress") { + changeProgress(pageX - origin.x); + } else if (gestureType === "volume") { + changeVolume(pageY - origin.y); + } + if (gestureType !== "none") { + return; + } + if (Math.abs(pageX - origin.x) > Math.abs(pageY - origin.y)) { + if (!props2.enableProgressGesture) { + state.gestureType = "stop"; + return; + } + state.gestureType = "progress"; + state.currentTimeOld = state.currentTimeNew = video.currentTime; + if (!fullscreenState.fullscreen) { + stop(); + } + } else { + if (!props2.pageGesture) { + state.gestureType = "stop"; + return; + } + state.gestureType = "volume"; + state.volumeOld = video.volume; + if (!fullscreenState.fullscreen) { + stop(); + } + } + } + function onTouchend(event) { + const video = videoRef.value; + if (state.gestureType !== "none" && state.gestureType !== "stop") { + event.stopPropagation(); + event.preventDefault(); + } + if (state.gestureType === "progress" && state.currentTimeOld !== state.currentTimeNew) { + video.currentTime = state.currentTimeNew; + } + state.gestureType = "none"; + } + function changeProgress(x) { + const video = videoRef.value; + const duration = video.duration; + let currentTimeNew = x / 600 * duration + state.currentTimeOld; + if (currentTimeNew < 0) { + currentTimeNew = 0; + } else if (currentTimeNew > duration) { + currentTimeNew = duration; + } + state.currentTimeNew = currentTimeNew; + } + function changeVolume(y) { + const video = videoRef.value; + const valueOld = state.volumeOld; + let value; + if (typeof valueOld === "number") { + value = valueOld - y / 200; + if (value < 0) { + value = 0; + } else if (value > 1) { + value = 1; + } + video.volume = value; + state.volumeNew = value; + } + } + return { + state, + onTouchstart, + onTouchmove, + onTouchend + }; +} +function useFullscreen(trigger, containerRef, videoRef, userActionState, rootRef) { + const state = vue.reactive({ + fullscreen: false + }); + const isSafari = /^Apple/.test(navigator.vendor); + function onFullscreenChange($event, webkit) { + if (webkit && document.fullscreenEnabled) { + return; + } + emitFullscreenChange(!!(document.fullscreenElement || document.webkitFullscreenElement)); + } + function emitFullscreenChange(val) { + state.fullscreen = val; + trigger("fullscreenchange", {}, { + fullScreen: val, + direction: "vertical" + }); + } + function toggleFullscreen(val) { + const root = rootRef.value; + const container = containerRef.value; + const video = videoRef.value; + let mockFullScreen; + if (val) { + if ((document.fullscreenEnabled || document.webkitFullscreenEnabled) && (!isSafari || userActionState.userAction)) { + container[document.fullscreenEnabled ? "requestFullscreen" : "webkitRequestFullscreen"](); + } else if (video.webkitEnterFullScreen) { + video.webkitEnterFullScreen(); + } else { + mockFullScreen = true; + container.remove(); + container.classList.add("uni-video-type-fullscreen"); + document.body.appendChild(container); + } + } else { + if (document.fullscreenEnabled || document.webkitFullscreenEnabled) { + if (document.fullscreenElement) { + document.exitFullscreen(); + } else if (document.webkitFullscreenElement) { + document.webkitExitFullscreen(); + } + } else if (video.webkitExitFullScreen) { + video.webkitExitFullScreen(); + } else { + mockFullScreen = true; + container.remove(); + container.classList.remove("uni-video-type-fullscreen"); + root.appendChild(container); + } + } + if (mockFullScreen) { + emitFullscreenChange(val); + } + } + function requestFullScreen() { + toggleFullscreen(true); + } + function exitFullScreen() { + toggleFullscreen(false); + } + return { + state, + onFullscreenChange, + emitFullscreenChange, + toggleFullscreen, + requestFullScreen, + exitFullScreen + }; +} +function useVideo(props2, attrs, trigger) { + const videoRef = vue.ref(null); + const src = vue.computed(() => getRealPath(props2.src)); + const state = vue.reactive({ + start: false, + src, + playing: false, + currentTime: 0, + duration: 0, + progress: 0, + buffered: 0 + }); + vue.watch(() => src.value, () => { + state.playing = false; + state.currentTime = 0; + }); + vue.watch(() => state.buffered, (buffered) => { + trigger("progress", {}, { + buffered + }); + }); + function onDurationChange({ + target + }) { + state.duration = target.duration; + } + function onLoadedMetadata($event) { + const initialTime = Number(props2.initialTime) || 0; + const video = $event.target; + if (initialTime > 0) { + video.currentTime = initialTime; + } + trigger("loadedmetadata", $event, { + width: video.videoWidth, + height: video.videoHeight, + duration: video.duration + }); + onProgress($event); + } + function onProgress($event) { + const video = $event.target; + const buffered = video.buffered; + if (buffered.length) { + state.buffered = buffered.end(buffered.length - 1) / video.duration * 100; + } + } + function onWaiting($event) { + trigger("waiting", $event, {}); + } + function onVideoError($event) { + state.playing = false; + trigger("error", $event, {}); + } + function onPlay($event) { + state.start = true; + state.playing = true; + trigger("play", $event, {}); + } + function onPause($event) { + state.playing = false; + trigger("pause", $event, {}); + } + function onEnded($event) { + state.playing = false; + trigger("ended", $event, {}); + } + function onTimeUpdate($event) { + const video = $event.target; + const currentTime = state.currentTime = video.currentTime; + trigger("timeupdate", $event, { + currentTime, + duration: video.duration + }); + } + function toggle() { + const video = videoRef.value; + if (state.playing) { + video.pause(); + } else { + video.play(); + } + } + function play() { + const video = videoRef.value; + state.start = true; + video.play(); + } + function pause() { + const video = videoRef.value; + video.pause(); + } + function seek(position) { + const video = videoRef.value; + position = Number(position); + if (typeof position === "number" && !isNaN(position)) { + video.currentTime = position; + } + } + function playbackRate(rate) { + const video = videoRef.value; + video.playbackRate = rate; + } + return { + videoRef, + state, + play, + pause, + seek, + playbackRate, + toggle, + onDurationChange, + onLoadedMetadata, + onProgress, + onWaiting, + onVideoError, + onPlay, + onPause, + onEnded, + onTimeUpdate + }; +} +function useControls(props2, videoState, seek) { + const progressRef = vue.ref(null); + const ballRef = vue.ref(null); + const centerPlayBtnShow = vue.computed(() => props2.showCenterPlayBtn && !videoState.start); + const controlsVisible = vue.ref(true); + const controlsShow = vue.computed(() => !centerPlayBtnShow.value && props2.controls && controlsVisible.value); + const state = vue.reactive({ + touching: false, + controlsTouching: false, + centerPlayBtnShow, + controlsShow, + controlsVisible + }); + function clickProgress(event) { + const $progress = progressRef.value; + let element = event.target; + let x = event.offsetX; + while (element && element !== $progress) { + x += element.offsetLeft; + element = element.parentNode; + } + const w = $progress.offsetWidth; + let progress = 0; + if (x >= 0 && x <= w) { + progress = x / w; + seek(videoState.duration * progress); + } + } + function toggleControls() { + state.controlsVisible = !state.controlsVisible; + } + let hideTiming; + function autoHideStart() { + hideTiming = setTimeout(() => { + state.controlsVisible = false; + }, 3e3); + } + function autoHideEnd() { + if (hideTiming) { + clearTimeout(hideTiming); + hideTiming = null; + } + } + vue.watch(() => state.controlsShow && videoState.playing && !state.controlsTouching, (val) => { + if (val) { + autoHideStart(); + } else { + autoHideEnd(); + } + }); + vue.watch([() => videoState.currentTime, () => { + props2.duration; + }], function updateProgress() { + if (!state.touching) { + videoState.progress = videoState.currentTime / videoState.duration * 100; + } + }); + return { + state, + progressRef, + ballRef, + clickProgress, + toggleControls, + autoHideStart, + autoHideEnd + }; +} +function useDanmu(props2, videoState) { + const danmuRef = vue.ref(null); + const state = vue.reactive({ + enable: Boolean(props2.enableDanmu) + }); + let danmuIndex = { + time: 0, + index: -1 + }; + const danmuList = shared.isArray(props2.danmuList) ? JSON.parse(JSON.stringify(props2.danmuList)) : []; + danmuList.sort(function(a, b) { + return (a.time || 0) - (b.time || 0); + }); + function toggleDanmu() { + state.enable = !state.enable; + } + function updateDanmu(event) { + const video = event.target; + const currentTime = video.currentTime; + const oldDanmuIndex = danmuIndex; + const newDanmuIndex = { + time: currentTime, + index: oldDanmuIndex.index + }; + if (currentTime > oldDanmuIndex.time) { + for (let index2 = oldDanmuIndex.index + 1; index2 < danmuList.length; index2++) { + const element = danmuList[index2]; + if (currentTime >= (element.time || 0)) { + newDanmuIndex.index = index2; + if (videoState.playing && state.enable) { + playDanmu(element); + } + } else { + break; + } + } + } else if (currentTime < oldDanmuIndex.time) { + for (let index2 = oldDanmuIndex.index - 1; index2 > -1; index2--) { + const element = danmuList[index2]; + if (currentTime <= (element.time || 0)) { + newDanmuIndex.index = index2 - 1; + } else { + break; + } + } + } + danmuIndex = newDanmuIndex; + } + function playDanmu(danmu) { + const p2 = document.createElement("p"); + p2.className = "uni-video-danmu-item"; + p2.innerText = danmu.text; + let style = `bottom: ${Math.random() * 100}%;color: ${danmu.color};`; + p2.setAttribute("style", style); + const danmuEl = danmuRef.value; + danmuEl.appendChild(p2); + setTimeout(function() { + style += "left: 0;-webkit-transform: translateX(-100%);transform: translateX(-100%);"; + p2.setAttribute("style", style); + setTimeout(function() { + p2.remove(); + }, 4e3); + }, 17); + } + function sendDanmu(danmu) { + danmuList.splice(danmuIndex.index + 1, 0, { + text: String(danmu.text), + color: danmu.color, + time: videoState.currentTime || 0 + }); + } + return { + state, + danmuRef, + updateDanmu, + toggleDanmu, + sendDanmu + }; +} +function useContext(play, pause, seek, sendDanmu, playbackRate, requestFullScreen, exitFullScreen) { + useContextInfo(); + useSubscribe(); +} +const props$9 = { + id: { + type: String, + default: "" + }, + src: { + type: String, + default: "" + }, + duration: { + type: [Number, String], + default: "" + }, + controls: { + type: [Boolean, String], + default: true + }, + danmuList: { + type: Array, + default() { + return []; + } + }, + danmuBtn: { + type: [Boolean, String], + default: false + }, + enableDanmu: { + type: [Boolean, String], + default: false + }, + autoplay: { + type: [Boolean, String], + default: false + }, + loop: { + type: [Boolean, String], + default: false + }, + muted: { + type: [Boolean, String], + default: false + }, + objectFit: { + type: String, + default: "contain" + }, + poster: { + type: String, + default: "" + }, + direction: { + type: [String, Number], + default: "" + }, + showProgress: { + type: Boolean, + default: true + }, + initialTime: { + type: [String, Number], + default: 0 + }, + showFullscreenBtn: { + type: [Boolean, String], + default: true + }, + pageGesture: { + type: [Boolean, String], + default: false + }, + enableProgressGesture: { + type: [Boolean, String], + default: true + }, + showPlayBtn: { + type: [Boolean, String], + default: true + }, + showCenterPlayBtn: { + type: [Boolean, String], + default: true + } +}; +const index$c = /* @__PURE__ */ defineBuiltInComponent({ + name: "Video", + props: props$9, + emits: ["fullscreenchange", "progress", "loadedmetadata", "waiting", "error", "play", "pause", "ended", "timeupdate"], + setup(props2, { + emit: emit2, + attrs, + slots + }) { + const rootRef = vue.ref(null); + const containerRef = vue.ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const { + state: userActionState + } = useUserAction(); + const { + $attrs: videoAttrs + } = useAttrs({ + excludeListeners: true + }); + const { + t: t2 + } = useI18n(); + initI18nVideoMsgsOnce(); + const { + videoRef, + state: videoState, + play, + pause, + seek, + playbackRate, + toggle, + onDurationChange, + onLoadedMetadata, + onProgress, + onWaiting, + onVideoError, + onPlay, + onPause, + onEnded, + onTimeUpdate + } = useVideo(props2, attrs, trigger); + const { + state: danmuState, + danmuRef, + updateDanmu, + toggleDanmu, + sendDanmu + } = useDanmu(props2, videoState); + const { + state: fullscreenState, + onFullscreenChange, + emitFullscreenChange, + toggleFullscreen, + requestFullScreen, + exitFullScreen + } = useFullscreen(trigger, containerRef, videoRef, userActionState, rootRef); + const { + state: gestureState, + onTouchstart, + onTouchend, + onTouchmove + } = useGesture(props2, videoRef, fullscreenState); + const { + state: controlsState, + progressRef, + ballRef, + clickProgress, + toggleControls + } = useControls(props2, videoState, seek); + useContext(); + return () => { + return vue.createVNode("uni-video", { + "ref": rootRef, + "id": props2.id + }, [vue.createVNode("div", { + "ref": containerRef, + "class": "uni-video-container", + "onTouchstart": onTouchstart, + "onTouchend": onTouchend, + "onTouchmove": onTouchmove, + "onFullscreenchange": vue.withModifiers(onFullscreenChange, ["stop"]), + "onWebkitfullscreenchange": vue.withModifiers(($event) => onFullscreenChange($event, true), ["stop"]) + }, [vue.createVNode("video", vue.mergeProps({ + "ref": videoRef, + "style": { + "object-fit": props2.objectFit + }, + "muted": !!props2.muted, + "loop": !!props2.loop, + "src": videoState.src, + "poster": props2.poster, + "autoplay": !!props2.autoplay + }, videoAttrs.value, { + "class": "uni-video-video", + "webkit-playsinline": true, + "playsinline": true, + "onClick": toggleControls, + "onDurationchange": onDurationChange, + "onLoadedmetadata": onLoadedMetadata, + "onProgress": onProgress, + "onWaiting": onWaiting, + "onError": onVideoError, + "onPlay": onPlay, + "onPause": onPause, + "onEnded": onEnded, + "onTimeupdate": (event) => { + onTimeUpdate(event); + updateDanmu(event); + }, + "onWebkitbeginfullscreen": () => emitFullscreenChange(true), + "onX5videoenterfullscreen": () => emitFullscreenChange(true), + "onWebkitendfullscreen": () => emitFullscreenChange(false), + "onX5videoexitfullscreen": () => emitFullscreenChange(false) + }), null, 16, ["muted", "loop", "src", "poster", "autoplay", "webkit-playsinline", "playsinline", "onClick", "onDurationchange", "onLoadedmetadata", "onProgress", "onWaiting", "onError", "onPlay", "onPause", "onEnded", "onTimeupdate", "onWebkitbeginfullscreen", "onX5videoenterfullscreen", "onWebkitendfullscreen", "onX5videoexitfullscreen"]), vue.withDirectives(vue.createVNode("div", { + "class": "uni-video-bar uni-video-bar-full", + "onClick": vue.withModifiers(() => { + }, ["stop"]) + }, [vue.createVNode("div", { + "class": "uni-video-controls" + }, [vue.withDirectives(vue.createVNode("div", { + "class": { + "uni-video-control-button": true, + "uni-video-control-button-play": !videoState.playing, + "uni-video-control-button-pause": videoState.playing + }, + "onClick": vue.withModifiers(toggle, ["stop"]) + }, null, 10, ["onClick"]), [[vue.vShow, props2.showPlayBtn]]), vue.withDirectives(vue.createVNode("div", { + "class": "uni-video-current-time" + }, [formatTime(videoState.currentTime)], 512), [[vue.vShow, props2.showProgress]]), vue.withDirectives(vue.createVNode("div", { + "ref": progressRef, + "class": "uni-video-progress-container", + "onClick": vue.withModifiers(clickProgress, ["stop"]) + }, [vue.createVNode("div", { + "class": "uni-video-progress" + }, [vue.createVNode("div", { + "style": { + width: videoState.buffered + "%" + }, + "class": "uni-video-progress-buffered" + }, null, 4), vue.createVNode("div", { + "ref": ballRef, + "style": { + left: videoState.progress + "%" + }, + "class": "uni-video-ball" + }, [vue.createVNode("div", { + "class": "uni-video-inner" + }, null)], 4)])], 8, ["onClick"]), [[vue.vShow, props2.showProgress]]), vue.withDirectives(vue.createVNode("div", { + "class": "uni-video-duration" + }, [formatTime(Number(props2.duration) || videoState.duration)], 512), [[vue.vShow, props2.showProgress]])]), vue.withDirectives(vue.createVNode("div", { + "class": { + "uni-video-danmu-button": true, + "uni-video-danmu-button-active": danmuState.enable + }, + "onClick": vue.withModifiers(toggleDanmu, ["stop"]) + }, [t2("uni.video.danmu")], 10, ["onClick"]), [[vue.vShow, props2.danmuBtn]]), vue.withDirectives(vue.createVNode("div", { + "class": { + "uni-video-fullscreen": true, + "uni-video-type-fullscreen": fullscreenState.fullscreen + }, + "onClick": vue.withModifiers(() => toggleFullscreen(!fullscreenState.fullscreen), ["stop"]) + }, null, 10, ["onClick"]), [[vue.vShow, props2.showFullscreenBtn]])], 8, ["onClick"]), [[vue.vShow, controlsState.controlsShow]]), vue.withDirectives(vue.createVNode("div", { + "ref": danmuRef, + "style": "z-index: 0;", + "class": "uni-video-danmu" + }, null, 512), [[vue.vShow, videoState.start && danmuState.enable]]), controlsState.centerPlayBtnShow && vue.createVNode("div", { + "class": "uni-video-cover", + "onClick": vue.withModifiers(() => { + }, ["stop"]) + }, [vue.createVNode("div", { + "class": "uni-video-cover-play-button", + "onClick": vue.withModifiers(play, ["stop"]) + }, null, 8, ["onClick"]), vue.createVNode("p", { + "class": "uni-video-cover-duration" + }, [formatTime(Number(props2.duration) || videoState.duration)])], 8, ["onClick"]), vue.createVNode("div", { + "class": { + "uni-video-toast": true, + "uni-video-toast-volume": gestureState.gestureType === "volume" + } + }, [vue.createVNode("div", { + "class": "uni-video-toast-title" + }, [t2("uni.video.volume")]), vue.createVNode("svg", { + "class": "uni-video-toast-icon", + "width": "200px", + "height": "200px", + "viewBox": "0 0 1024 1024", + "version": "1.1", + "xmlns": "http://www.w3.org/2000/svg" + }, [vue.createVNode("path", { + "d": "M475.400704 201.19552l0 621.674496q0 14.856192-10.856448 25.71264t-25.71264 10.856448-25.71264-10.856448l-190.273536-190.273536-149.704704 0q-14.856192 0-25.71264-10.856448t-10.856448-25.71264l0-219.414528q0-14.856192 10.856448-25.71264t25.71264-10.856448l149.704704 0 190.273536-190.273536q10.856448-10.856448 25.71264-10.856448t25.71264 10.856448 10.856448 25.71264zm219.414528 310.837248q0 43.425792-24.28416 80.851968t-64.2816 53.425152q-5.71392 2.85696-14.2848 2.85696-14.856192 0-25.71264-10.570752t-10.856448-25.998336q0-11.999232 6.856704-20.284416t16.570368-14.2848 19.427328-13.142016 16.570368-20.284416 6.856704-32.569344-6.856704-32.569344-16.570368-20.284416-19.427328-13.142016-16.570368-14.2848-6.856704-20.284416q0-15.427584 10.856448-25.998336t25.71264-10.570752q8.57088 0 14.2848 2.85696 39.99744 15.427584 64.2816 53.139456t24.28416 81.137664zm146.276352 0q0 87.422976-48.56832 161.41824t-128.5632 107.707392q-7.428096 2.85696-14.2848 2.85696-15.427584 0-26.284032-10.856448t-10.856448-25.71264q0-22.284288 22.284288-33.712128 31.997952-16.570368 43.425792-25.141248 42.283008-30.855168 65.995776-77.423616t23.712768-99.136512-23.712768-99.136512-65.995776-77.423616q-11.42784-8.57088-43.425792-25.141248-22.284288-11.42784-22.284288-33.712128 0-14.856192 10.856448-25.71264t25.71264-10.856448q7.428096 0 14.856192 2.85696 79.99488 33.712128 128.5632 107.707392t48.56832 161.41824zm146.276352 0q0 131.42016-72.566784 241.41312t-193.130496 161.989632q-7.428096 2.85696-14.856192 2.85696-14.856192 0-25.71264-10.856448t-10.856448-25.71264q0-20.570112 22.284288-33.712128 3.999744-2.285568 12.85632-5.999616t12.85632-5.999616q26.284032-14.2848 46.854144-29.140992 70.281216-51.996672 109.707264-129.705984t39.426048-165.132288-39.426048-165.132288-109.707264-129.705984q-20.570112-14.856192-46.854144-29.140992-3.999744-2.285568-12.85632-5.999616t-12.85632-5.999616q-22.284288-13.142016-22.284288-33.712128 0-14.856192 10.856448-25.71264t25.71264-10.856448q7.428096 0 14.856192 2.85696 120.563712 51.996672 193.130496 161.989632t72.566784 241.41312z" + }, null)]), vue.createVNode("div", { + "class": "uni-video-toast-value" + }, [vue.createVNode("div", { + "style": { + width: gestureState.volumeNew * 100 + "%" + }, + "class": "uni-video-toast-value-content" + }, [vue.createVNode("div", { + "class": "uni-video-toast-volume-grids" + }, [vue.renderList(10, () => vue.createVNode("div", { + "class": "uni-video-toast-volume-grids-item" + }, null))])], 4)])], 2), vue.createVNode("div", { + "class": { + "uni-video-toast": true, + "uni-video-toast-progress": gestureState.gestureType === "progress" + } + }, [vue.createVNode("div", { + "class": "uni-video-toast-title" + }, [formatTime(gestureState.currentTimeNew), " / ", formatTime(videoState.duration)])], 2), vue.createVNode("div", { + "class": "uni-video-slots" + }, [slots.default && slots.default()])], 40, ["onTouchstart", "onTouchend", "onTouchmove", "onFullscreenchange", "onWebkitfullscreenchange"])], 8, ["id"]); + }; + } +}); +const onWebInvokeAppService = ({ name, arg }) => { + if (name === "postMessage") + ; + else { + uni[name](arg); + } +}; +const Invoke = /* @__PURE__ */ uniShared.once(() => UniServiceJSBridge.on(uniShared.ON_WEB_INVOKE_APP_SERVICE, onWebInvokeAppService)); +const props$8 = { + src: { + type: String, + default: "" + }, + fullscreen: { + type: Boolean, + default: true + } +}; +const index$b = /* @__PURE__ */ defineBuiltInComponent({ + inheritAttrs: false, + name: "WebView", + props: props$8, + setup(props2) { + Invoke(); + const rootRef = vue.ref(null); + vue.ref(null); + const { + $attrs, + $excludeAttrs, + $listeners + } = useAttrs({ + excludeListeners: true + }); + let _resize; + return () => { + return vue.createVNode(vue.Fragment, null, [vue.createVNode("uni-web-view", vue.mergeProps({ + "class": props2.fullscreen ? "uni-webview--fullscreen" : "" + }, $listeners.value, $excludeAttrs.value, { + "ref": rootRef + }), [vue.createVNode(ResizeSensor, { + "onResize": _resize + }, null, 8, ["onResize"])], 16)]); + }; + } +}); +const ICON_PATH_ORIGIN = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAACECAMAAABmmnOVAAAC01BMVEUAAAAAef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef96quGStdqStdpbnujMzMzCyM7Gyc7Ky83MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMwAef8GfP0yjfNWnOp0qOKKsdyYt9mju9aZt9mMstx1qeJYnekyjvIIfP0qivVmouaWttnMzMyat9lppOUujPQKffxhoOfNzc3Y2Njh4eHp6enu7u7y8vL19fXv7+/i4uLZ2dnOzs6auNgOf/sKff15quHR0dHx8fH9/f3////j4+N6quFdn+iywdPb29vw8PD+/v7c3NyywtLa2tr29vbS0tLd3d38/Pzf39/o6Ojc7f+q0v+HwP9rsf9dqv9Hnv9Vpv/q6urj8P+Vx/9Am/8Pgf8Iff/z8/OAvP95uf/n5+c5l//V6f+52v+y1//7+/vt7e0rkP/09PTQ0NDq9P8Whf+cy//W1tbe3t7A3v/m5ubs7OxOov/r6+vk5OQiaPjKAAAAknRSTlMACBZ9oB71/jiqywJBZATT6hBukRXv+zDCAVrkDIf4JbQsTb7eVeJLbwfa8Rh4G/OlPS/6/kxQ9/xdmZudoJxNVhng7B6wtWdzAtQOipcF1329wS44doK/BAkyP1pvgZOsrbnGXArAg34G2IsD1eMRe7bi7k5YnqFT9V0csyPedQyYD3p/Fje+hDpskq/MwpRBC6yKp2MAAAQdSURBVHja7Zn1exMxGIAPHbrhDsPdneHuNtzd3d3dIbjLh93o2o4i7TpgG1Jk0g0mMNwd/gTa5rq129reHnK5e/bk/TFNk/dJ7r5894XjGAwGg8GgTZasCpDIll1+hxw5vXLJLpEboTx5ZXbIhyzkl9fB28cqUaCgrBKFkI3CcjoUKYolihWXUSI7EihRUjaHXF52CVRKLoe8eZIdUOkyMknkRw6UlcehYAFHiXK+skgURk6Ul8OhQjFnCVRRBolKqRxQ5SzUHaqgNGSj7VCmalqJnDkoS5RF6ZCbroNvufQkUD6qEuXTdUA+3hQdqiEXVKfnUKOmK4latalJ1EEuoZZ6162HJ9x/4OChw0eOHj12/MTJU6dxG7XUu751tjNnz4ET5y9ctLZTSr0beKFLl89bpuUDrqgC1RqNWqsKuqqzNFw7e51S6u3tc+OmZUJ9kCHY6ECwOkRvab51iUrqXej2HYDQsHBjWgx3Ae7dppB6N2wEcF9jdMGDUIDGTaR2aNoM9FqjG7QmaN5CWgc/gIePjG559BigpZQOrYB/4jBfRGRUtDkmJjY6KjLCofkpD62lc2gDfMpWPIuLdwyV8XEpHgaddBZ+wBuSFcwJqSN2ovmZ/dfnOvCTxqGtwzq8SEjv4EhISn48eWgnhUP7DvDSvgzxrs6vV6+FLiro2EkCic4QKkzwJsH1KYreCp0eQhfyDl1B/w4P/xa5JVJ4U03QjbRD9x7wXlgH5IE3wmMBHXoSlugFAcI6f/AkkSi8q6HQm6xDn77wEQ8djTwSj3tqAMguRTe4ikeOQyJ4YV+KfkQl+oNW5GbY4gWOWgbwJ+kwAD6Fi90MK2ZsrIeBBCUGwRXbqJ+/iJMQliIEBhOU6AJhtlG/IpHE2bqrYQg5h6HA4yQiRqwEfkGCdTCMmMRw+IbPDCQaHCsCYAQxiZHw3TbmD/ESOHgHwShiEqPhp/gggYkSztIxxCRawy/bmEniJaJtfwiEscQkxkFgRqJESqQwwHhiEuMBp3Vm8RK/cZoHEzKXhCK2QxEPpiJe0YlKCFaKCNv/cYBNUsBRPlkJSc0U+dM7E9H0ThGJbgZT/iR7yj+VqMS06Qr4+OFm2JdCxIa8lugzkJs5K6MfxAaYPUcBpYG5khZJEkUUSb7DPCnKRfPBXj6M8FwuegoLpCgXcQszVjhbJFUJUee2hBhLoYTIcYtB57KY+opSMdVqwatSlZVj05aV//CwJLMX2DluaUcwhXm4ali2XOoLjxUrPV26zFtF4f5p0Gp310+z13BUWNvbehEXona6iAtX/zVZmtfN4WixfsNky4S6gCCVVq3RPLdfSfpv3MRRZfPoLc6Xs/5bt3EyMGzE9h07/Xft2t15z6i9+zgGg8FgMBgMBoPBYDAYDAYj8/APG67Rie8pUDsAAAAASUVORK5CYII="; +var MapType = /* @__PURE__ */ ((MapType2) => { + MapType2["QQ"] = "qq"; + MapType2["GOOGLE"] = "google"; + MapType2["AMAP"] = "AMap"; + MapType2["UNKNOWN"] = ""; + return MapType2; +})(MapType || {}); +function getMapInfo() { + if (__uniConfig.qqMapKey) { + return { + type: "qq", + key: __uniConfig.qqMapKey + }; + } + if (__uniConfig.googleMapKey) { + return { + type: "google", + key: __uniConfig.googleMapKey + }; + } + if (__uniConfig.aMapKey) { + return { + type: "AMap", + key: __uniConfig.aMapKey, + securityJsCode: __uniConfig.aMapSecurityJsCode, + serviceHost: __uniConfig.aMapServiceHost + }; + } + return { + type: "", + key: "" + }; +} +let IS_AMAP = false; +let hasGetIsAMap = false; +const getIsAMap = () => { + if (hasGetIsAMap) { + return IS_AMAP; + } else { + hasGetIsAMap = true; + return IS_AMAP = getMapInfo().type === "AMap"; + } +}; +const props$7 = { + id: { + type: [Number, String], + default: "" + }, + latitude: { + type: [Number, String], + require: true + }, + longitude: { + type: [Number, String], + require: true + }, + title: { + type: String, + default: "" + }, + iconPath: { + type: String, + require: true + }, + rotate: { + type: [Number, String], + default: 0 + }, + alpha: { + type: [Number, String], + default: 1 + }, + width: { + type: [Number, String], + default: "" + }, + height: { + type: [Number, String], + default: "" + }, + callout: { + type: Object, + default: null + }, + label: { + type: Object, + default: null + }, + anchor: { + type: Object, + default: null + }, + clusterId: { + type: [Number, String], + default: "" + }, + customCallout: { + type: Object, + default: null + }, + ariaLabel: { + type: String, + default: "" + } +}; +function useMarkerLabelStyle(id) { + const className = "uni-map-marker-label-" + id; + const styleEl = document.createElement("style"); + styleEl.id = className; + document.head.appendChild(styleEl); + return function updateMarkerLabelStyle(style) { + const newStyle = Object.assign({}, style, { + position: "absolute", + top: "70px", + borderStyle: "solid" + }); + const div = document.createElement("div"); + Object.keys(newStyle).forEach((key) => { + div.style[key] = newStyle[key] || ""; + }); + styleEl.innerText = `.${className}{${div.getAttribute("style")}}`; + return className; + }; +} +const MapMarker = /* @__PURE__ */ defineSystemComponent({ + name: "MapMarker", + props: props$7, + setup(props2) { + const id = String(!isNaN(Number(props2.id)) ? props2.id : ""); + const onMapReady = vue.inject("onMapReady"); + const updateMarkerLabelStyle = useMarkerLabelStyle(id); + let marker; + function removeMarkerCallout(callout) { + if (getIsAMap()) { + callout.removeAMapText(); + } else { + callout.setMap(null); + } + } + onMapReady((map, maps, trigger) => { + function updateMarker(option) { + const title = option.title; + const position = getIsAMap() ? new maps.LngLat(option.longitude, option.latitude) : new maps.LatLng(option.latitude, option.longitude); + const img = new Image(); + let imgHeight = 0; + img.onload = () => { + const anchor = option.anchor || {}; + let icon; + let w; + let h; + let top; + let x = typeof anchor.x === "number" ? anchor.x : 0.5; + let y = typeof anchor.y === "number" ? anchor.y : 1; + if (option.iconPath && (option.width || option.height)) { + w = option.width || img.width / img.height * option.height; + h = option.height || img.height / img.width * option.width; + } else { + w = img.width / 2; + h = img.height / 2; + } + imgHeight = h; + top = h - (h - y * h); + if ("MarkerImage" in maps) { + icon = new maps.MarkerImage(img.src, null, null, new maps.Point(x * w, y * h), new maps.Size(w, h)); + } else if ("Icon" in maps) { + icon = new maps.Icon({ + image: img.src, + size: new maps.Size(w, h), + imageSize: new maps.Size(w, h), + imageOffset: new maps.Pixel(x * w, y * h) + }); + } else { + icon = { + url: img.src, + anchor: new maps.Point(x, y), + size: new maps.Size(w, h) + }; + } + marker.setPosition(position); + marker.setIcon(icon); + if ("setRotation" in marker) { + marker.setRotation(option.rotate || 0); + } + const labelOpt = option.label || {}; + if ("label" in marker) { + marker.label.setMap(null); + delete marker.label; + } + let label; + if (labelOpt.content) { + const labelStyle = { + borderColor: labelOpt.borderColor, + borderWidth: (Number(labelOpt.borderWidth) || 0) + "px", + padding: (Number(labelOpt.padding) || 0) + "px", + borderRadius: (Number(labelOpt.borderRadius) || 0) + "px", + backgroundColor: labelOpt.bgColor, + color: labelOpt.color, + fontSize: (labelOpt.fontSize || 14) + "px", + lineHeight: (labelOpt.fontSize || 14) + "px", + marginLeft: (Number(labelOpt.anchorX || labelOpt.x) || 0) + "px", + marginTop: (Number(labelOpt.anchorY || labelOpt.y) || 0) + "px" + }; + if ("Label" in maps) { + label = new maps.Label({ + position, + map, + clickable: false, + content: labelOpt.content, + style: labelStyle + }); + marker.label = label; + } else if ("setLabel" in marker) { + if (getIsAMap()) { + const content = `
+ ${labelOpt.content} +
`; + marker.setLabel({ + content, + direction: "bottom-right" + }); + } else { + const className = updateMarkerLabelStyle(labelStyle); + marker.setLabel({ + text: labelOpt.content, + color: labelStyle.color, + fontSize: labelStyle.fontSize, + className + }); + } + } + } + const calloutOpt = option.callout || {}; + let callout = marker.callout; + let calloutStyle; + if (calloutOpt.content || title) { + if (getIsAMap() && calloutOpt.content) { + calloutOpt.content = calloutOpt.content.replaceAll("\n", "
"); + } + const boxShadow = "0px 0px 3px 1px rgba(0,0,0,0.5)"; + let offsetY = -imgHeight / 2; + if (option.width || option.height) { + offsetY += 14 - imgHeight / 2; + } + calloutStyle = calloutOpt.content ? { + position, + map, + top, + // handle AMap callout offset + offsetY, + content: calloutOpt.content, + color: calloutOpt.color, + fontSize: calloutOpt.fontSize, + borderRadius: calloutOpt.borderRadius, + bgColor: calloutOpt.bgColor, + padding: calloutOpt.padding, + boxShadow: calloutOpt.boxShadow || boxShadow, + display: calloutOpt.display + } : { + position, + map, + top, + // handle AMap callout offset + offsetY, + content: title, + boxShadow + }; + if (callout) { + callout.setOption(calloutStyle); + } else { + if (getIsAMap()) { + const callback = (id2) => { + if (id2 !== "") { + trigger("callouttap", {}, { + markerId: Number(id2) + }); + } + }; + callout = marker.callout = new maps.Callout(calloutStyle, callback); + } else { + callout = marker.callout = new maps.Callout(calloutStyle); + callout.div.onclick = function($event) { + if (id !== "") { + trigger("callouttap", $event, { + markerId: Number(id) + }); + } + $event.stopPropagation(); + $event.preventDefault(); + }; + if (getMapInfo().type === MapType.GOOGLE) { + callout.div.ontouchstart = function($event) { + $event.stopPropagation(); + }; + callout.div.onpointerdown = function($event) { + $event.stopPropagation(); + }; + } + } + } + } else { + if (callout) { + removeMarkerCallout(callout); + delete marker.callout; + } + } + }; + if (option.iconPath) { + img.src = getRealPath(option.iconPath); + } else { + console.error("Marker.iconPath is required."); + } + } + function addMarker(props3) { + marker = new maps.Marker({ + map, + flat: true, + autoRotation: false + }); + updateMarker(props3); + const MapsEvent = maps.event || maps.Event; + MapsEvent.addListener(marker, "click", () => { + const callout = marker.callout; + if (callout && !callout.alwaysVisible) { + if (getIsAMap()) { + callout.visible = !callout.visible; + if (callout.visible) { + marker.callout.createAMapText(); + } else { + marker.callout.removeAMapText(); + } + } else { + callout.set("visible", !callout.visible); + if (callout.visible) { + const div = callout.div; + const parent = div.parentNode; + parent.removeChild(div); + parent.appendChild(div); + } + } + } + if (id) { + trigger("markertap", {}, { + markerId: Number(id), + latitude: props3.latitude, + longitude: props3.longitude + }); + } + }); + } + addMarker(props2); + vue.watch(props2, updateMarker); + }); + if (id) { + const addMapChidlContext = vue.inject("addMapChidlContext"); + vue.inject("removeMapChidlContext"); + const context = { + id, + translate(data) { + onMapReady((map, maps, trigger) => { + const destination = data.destination; + const duration = data.duration; + const autoRotate = !!data.autoRotate; + let rotate = Number(data.rotate) || 0; + let rotation = 0; + if ("getRotation" in marker) { + rotation = marker.getRotation(); + } + const a = marker.getPosition(); + const b = new maps.LatLng(destination.latitude, destination.longitude); + const distance = maps.geometry.spherical.computeDistanceBetween(a, b) / 1e3; + const time = (typeof duration === "number" ? duration : 1e3) / (1e3 * 60 * 60); + const speed = distance / time; + const MapsEvent = maps.event || maps.Event; + const movingEvent = MapsEvent.addListener(marker, "moving", (e2) => { + const latLng = e2.latLng; + const label = marker.label; + if (label) { + label.setPosition(latLng); + } + const callout = marker.callout; + if (callout) { + callout.setPosition(latLng); + } + }); + const event = MapsEvent.addListener(marker, "moveend", () => { + event.remove(); + movingEvent.remove(); + marker.lastPosition = a; + marker.setPosition(b); + const label = marker.label; + if (label) { + label.setPosition(b); + } + const callout = marker.callout; + if (callout) { + callout.setPosition(b); + } + const cb = data.animationEnd; + if (shared.isFunction(cb)) { + cb(); + } + }); + let lastRtate = 0; + if (autoRotate) { + if (marker.lastPosition) { + lastRtate = maps.geometry.spherical.computeHeading(marker.lastPosition, a); + } + rotate = maps.geometry.spherical.computeHeading(a, b) - lastRtate; + } + if ("setRotation" in marker) { + marker.setRotation(rotation + rotate); + } + if ("moveTo" in marker) { + marker.moveTo(b, speed); + } else { + marker.setPosition(b); + MapsEvent.trigger(marker, "moveend", {}); + } + }); + } + }; + addMapChidlContext(context); + } + return () => { + return null; + }; + } +}); +function hexToRgba(hex) { + if (!hex) { + return { + r: 0, + g: 0, + b: 0, + a: 0 + }; + } + let tmpHex = hex.slice(1); + const tmpHexLen = tmpHex.length; + if (![3, 4, 6, 8].includes(tmpHexLen)) { + return { + r: 0, + g: 0, + b: 0, + a: 0 + }; + } + if (tmpHexLen === 3 || tmpHexLen === 4) { + tmpHex = tmpHex.replace(/(\w{1})/g, "$1$1"); + } + let [sr, sg, sb, sa] = tmpHex.match(/(\w{2})/g); + const r = parseInt(sr, 16), g2 = parseInt(sg, 16), b = parseInt(sb, 16); + if (!sa) { + return { r, g: g2, b, a: 1 }; + } + return { + r, + g: g2, + b, + a: (`0x100${sa}` - 65536) / 255 + }; +} +const props$6 = { + points: { + type: Array, + require: true + }, + color: { + type: String, + default: "#000000" + }, + width: { + type: [Number, String], + default: "" + }, + dottedLine: { + type: [Boolean, String], + default: false + }, + arrowLine: { + type: [Boolean, String], + default: false + }, + arrowIconPath: { + type: String, + default: "" + }, + borderColor: { + type: String, + default: "#000000" + }, + borderWidth: { + type: [Number, String], + default: "" + }, + colorList: { + type: Array, + default() { + return []; + } + }, + level: { + type: String, + default: "" + } +}; +const MapPolyline = /* @__PURE__ */ defineSystemComponent({ + name: "MapPolyline", + props: props$6, + setup(props2) { + const onMapReady = vue.inject("onMapReady"); + let polyline; + let polylineBorder; + function removePolyline() { + if (polyline) { + polyline.setMap(null); + } + if (polylineBorder) { + polylineBorder.setMap(null); + } + } + onMapReady((map, maps) => { + function updatePolyline(option) { + removePolyline(); + addPolyline(option); + } + function addPolyline(option) { + const path = []; + option.points.forEach((point) => { + const pointPosition = getIsAMap() ? [point.longitude, point.latitude] : new maps.LatLng(point.latitude, point.longitude); + path.push(pointPosition); + }); + const strokeWeight = Number(option.width) || 1; + const { + r: sr, + g: sg, + b: sb, + a: sa + } = hexToRgba(option.color); + const { + r: br, + g: bg, + b: bb, + a: ba + } = hexToRgba(option.borderColor); + const polylineOptions = { + map, + clickable: false, + path, + strokeWeight, + strokeColor: option.color || void 0, + strokeDashStyle: option.dottedLine ? "dash" : "solid" + }; + const borderWidth = Number(option.borderWidth) || 0; + const polylineBorderOptions = { + map, + clickable: false, + path, + strokeWeight: strokeWeight + borderWidth * 2, + strokeColor: option.borderColor || void 0, + strokeDashStyle: option.dottedLine ? "dash" : "solid" + }; + if ("Color" in maps) { + polylineOptions.strokeColor = new maps.Color(sr, sg, sb, sa); + polylineBorderOptions.strokeColor = new maps.Color(br, bg, bb, ba); + } else { + polylineOptions.strokeColor = `rgb(${sr}, ${sg}, ${sb})`; + polylineOptions.strokeOpacity = sa; + polylineBorderOptions.strokeColor = `rgb(${br}, ${bg}, ${bb})`; + polylineBorderOptions.strokeOpacity = ba; + } + if (borderWidth) { + polylineBorder = new maps.Polyline(polylineBorderOptions); + } + polyline = new maps.Polyline(polylineOptions); + } + addPolyline(props2); + vue.watch(props2, updatePolyline); + }); + return () => { + return null; + }; + } +}); +const props$5 = { + latitude: { + type: [Number, String], + require: true + }, + longitude: { + type: [Number, String], + require: true + }, + color: { + type: String, + default: "#000000" + }, + fillColor: { + type: String, + default: "#00000000" + }, + radius: { + type: [Number, String], + require: true + }, + strokeWidth: { + type: [Number, String], + default: "" + }, + level: { + type: String, + default: "" + } +}; +const MapCircle = /* @__PURE__ */ defineSystemComponent({ + name: "MapCircle", + props: props$5, + setup(props2) { + const onMapReady = vue.inject("onMapReady"); + let circle; + function removeCircle() { + if (circle) { + circle.setMap(null); + } + } + onMapReady((map, maps) => { + function updateCircle(option) { + removeCircle(); + addCircle(option); + } + function addCircle(option) { + const center = getIsAMap() ? [option.longitude, option.latitude] : new maps.LatLng(option.latitude, option.longitude); + const circleOptions = { + map, + center, + clickable: false, + radius: option.radius, + strokeWeight: Number(option.strokeWidth) || 1, + strokeDashStyle: "solid" + }; + if (getIsAMap()) { + circleOptions.strokeColor = option.color; + circleOptions.fillColor = option.fillColor || "#000"; + circleOptions.fillOpacity = 1; + } else { + const { + r: fr, + g: fg, + b: fb, + a: fa + } = hexToRgba(option.fillColor); + const { + r: sr, + g: sg, + b: sb, + a: sa + } = hexToRgba(option.color); + if ("Color" in maps) { + circleOptions.fillColor = new maps.Color(fr, fg, fb, fa); + circleOptions.strokeColor = new maps.Color(sr, sg, sb, sa); + } else { + circleOptions.fillColor = `rgb(${fr}, ${fg}, ${fb})`; + circleOptions.fillOpacity = fa; + circleOptions.strokeColor = `rgb(${sr}, ${sg}, ${sb})`; + circleOptions.strokeOpacity = sa; + } + } + circle = new maps.Circle(circleOptions); + if (getIsAMap()) { + map.add(circle); + } + } + addCircle(props2); + vue.watch(props2, updateCircle); + }); + return () => { + return null; + }; + } +}); +const props$4 = { + id: { + type: [Number, String], + default: "" + }, + position: { + type: Object, + required: true + }, + iconPath: { + type: String, + required: true + }, + clickable: { + type: [Boolean, String], + default: "" + }, + trigger: { + type: Function, + required: true + } +}; +const MapControl = /* @__PURE__ */ defineSystemComponent({ + name: "MapControl", + props: props$4, + setup(props2) { + const imgPath = vue.computed(() => getRealPath(props2.iconPath)); + const positionStyle = vue.computed(() => { + let positionStyle2 = `top:${props2.position.top || 0}px;left:${props2.position.left || 0}px;`; + if (props2.position.width) { + positionStyle2 += `width:${props2.position.width}px;`; + } + if (props2.position.height) { + positionStyle2 += `height:${props2.position.height}px;`; + } + return positionStyle2; + }); + const handleClick = ($event) => { + if (props2.clickable) { + props2.trigger("controltap", $event, { + controlId: props2.id + }); + } + }; + return () => { + return vue.createVNode("div", { + "class": "uni-map-control" + }, [vue.createVNode("img", { + "src": imgPath.value, + "style": positionStyle.value, + "class": "uni-map-control-icon", + "onClick": handleClick + }, null, 12, ["src", "onClick"])]); + }; + } +}); +const CONTEXT_ID = "MAP_LOCATION"; +const MapLocation = /* @__PURE__ */ defineSystemComponent({ + name: "MapLocation", + setup() { + const state = vue.reactive({ + latitude: 0, + longitude: 0, + rotate: 0 + }); + return () => { + return state.latitude ? vue.createVNode(MapMarker, vue.mergeProps({ + "anchor": { + x: 0.5, + y: 0.5 + }, + "width": "44", + "height": "44", + "iconPath": ICON_PATH_ORIGIN + }, state), null, 16, ["iconPath"]) : null; + }; + } +}); +const props$3 = { + // 边框虚线,腾讯地图支持,google 高德 地图不支持,默认值为[0, 0] 为实线,非 [0, 0] 为虚线,H5 端无法像微信小程序一样控制虚线的间隔像素大小 + dashArray: { + type: Array, + default: () => [0, 0] + }, + // 经纬度数组,[{latitude: 0, longitude: 0}] + points: { + type: Array, + required: true + }, + // 描边的宽度 + strokeWidth: { + type: Number, + default: 1 + }, + // 描边的颜色,十六进制 + strokeColor: { + type: String, + default: "#000000" + }, + // 填充颜色,十六进制 + fillColor: { + type: String, + default: "#00000000" + }, + // 设置多边形 Z 轴数值 + zIndex: { + type: Number, + default: 0 + } +}; +const MapPolygon = /* @__PURE__ */ defineSystemComponent({ + name: "MapPolygon", + props: props$3, + setup(props2) { + let polygonIns; + const onMapReady = vue.inject("onMapReady"); + onMapReady((map, maps, trigger) => { + function drawPolygon() { + const { + points, + strokeWidth, + strokeColor, + dashArray, + fillColor, + zIndex + } = props2; + const path = points.map((item) => { + const { + latitude, + longitude + } = item; + return getIsAMap() ? [longitude, latitude] : new maps.LatLng(latitude, longitude); + }); + const { + r: fcR, + g: fcG, + b: fcB, + a: fcA + } = hexToRgba(fillColor); + const { + r: scR, + g: scG, + b: scB, + a: scA + } = hexToRgba(strokeColor); + const polygonOptions = { + //多边形是否可点击。 + clickable: true, + //鼠标在多边形内的光标样式。 + cursor: "crosshair", + //多边形是否可编辑。 + editable: false, + // 地图实例,即要显示多边形的地图 + // @ts-ignore + map, + // 区域填充色 + fillColor: "", + //多边形的路径,以经纬度坐标数组构成。 + path, + // 区域边框 + strokeColor: "", + //多边形的边框样式。实线是solid,虚线是dash。 + strokeDashStyle: dashArray.some((item) => item > 0) ? "dash" : "solid", + //多边形的边框线宽。 + strokeWeight: strokeWidth, + //多边形是否可见。 + visible: true, + //多边形的zIndex值。 + zIndex + }; + if (maps.Color) { + polygonOptions.fillColor = new maps.Color(fcR, fcG, fcB, fcA); + polygonOptions.strokeColor = new maps.Color(scR, scG, scB, scA); + } else { + polygonOptions.fillColor = `rgb(${fcR}, ${fcG}, ${fcB})`; + polygonOptions.fillOpacity = fcA; + polygonOptions.strokeColor = `rgb(${scR}, ${scG}, ${scB})`; + polygonOptions.strokeOpacity = scA; + } + if (polygonIns) { + polygonIns.setOptions(polygonOptions); + return; + } + polygonIns = new maps.Polygon(polygonOptions); + } + drawPolygon(); + vue.watch(props2, drawPolygon); + }); + return () => null; + } +}); +const props$2 = { + id: { + type: String, + default: "" + }, + latitude: { + type: [String, Number], + default: 0 + }, + longitude: { + type: [String, Number], + default: 0 + }, + scale: { + type: [String, Number], + default: 16 + }, + markers: { + type: Array, + default() { + return []; + } + }, + includePoints: { + type: Array, + default() { + return []; + } + }, + polyline: { + type: Array, + default() { + return []; + } + }, + circles: { + type: Array, + default() { + return []; + } + }, + controls: { + type: Array, + default() { + return []; + } + }, + showLocation: { + type: [Boolean, String], + default: false + }, + libraries: { + type: Array, + default() { + return []; + } + }, + polygons: { + type: Array, + default: () => [] + } +}; +function getPoints(points) { + const newPoints = []; + if (shared.isArray(points)) { + points.forEach((point) => { + if (point && point.latitude && point.longitude) { + newPoints.push({ + latitude: point.latitude, + longitude: point.longitude + }); + } + }); + } + return newPoints; +} +function getAMapPosition(maps, latitude, longitude) { + return new maps.LngLat(longitude, latitude); +} +function getGoogleOrQQMapPosition(maps, latitude, longitude) { + return new maps.LatLng(latitude, longitude); +} +function getMapPosition(maps, latitude, longitude) { + return getIsAMap() ? getAMapPosition(maps, latitude, longitude) : getGoogleOrQQMapPosition(maps, latitude, longitude); +} +function getLat(latLng) { + if ("getLat" in latLng) { + return latLng.getLat(); + } else { + return latLng.lat(); + } +} +function getLng(latLng) { + if ("getLng" in latLng) { + return latLng.getLng(); + } else { + return latLng.lng(); + } +} +function useMap(props2, rootRef, emit2) { + const trigger = useCustomEvent(rootRef, emit2); + const mapRef = vue.ref(null); + let maps; + let map; + const state = vue.reactive({ + latitude: Number(props2.latitude), + longitude: Number(props2.longitude), + includePoints: getPoints(props2.includePoints) + }); + function onMapReady(callback) { + } + let isBoundsReady; + function onBoundsReady(callback) { + } + const contexts = {}; + function addMapChidlContext(context) { + contexts[context.id] = context; + } + function removeMapChidlContext(context) { + delete contexts[context.id]; + } + vue.watch([() => props2.latitude, () => props2.longitude], ([latitudeVlaue, longitudeVlaue]) => { + const latitude = Number(latitudeVlaue); + const longitude = Number(longitudeVlaue); + if (latitude !== state.latitude || longitude !== state.longitude) { + state.latitude = latitude; + state.longitude = longitude; + } + }); + vue.watch(() => props2.includePoints, (points) => { + state.includePoints = getPoints(points); + }, { + deep: true + }); + function updateBounds() { + if (getIsAMap()) { + const points = []; + state.includePoints.forEach((point) => { + points.push([point.longitude, point.latitude]); + }); + const bounds = new maps.Bounds(...points); + map.setBounds(bounds); + } else { + const bounds = new maps.LatLngBounds(); + state.includePoints.forEach(({ + latitude, + longitude + }) => { + const latLng = new maps.LatLng(latitude, longitude); + bounds.extend(latLng); + }); + map.fitBounds(bounds); + } + } + try { + const id = useContextInfo(); + useSubscribe((type, data = {}) => { + switch (type) { + case "getCenterLocation": + onMapReady(() => { + const center = map.getCenter(); + uniShared.callOptions(data, { + latitude: getLat(center), + longitude: getLng(center), + errMsg: `${type}:ok` + }); + }); + break; + case "moveToLocation": + { + let latitude = Number(data.latitude); + let longitude = Number(data.longitude); + if (!latitude || !longitude) { + const context = contexts[CONTEXT_ID]; + if (context) { + latitude = context.state.latitude; + longitude = context.state.longitude; + } + } + if (latitude && longitude) { + state.latitude = latitude; + state.longitude = longitude; + if (map) + ; + onMapReady(() => { + uniShared.callOptions(data, `${type}:ok`); + }); + } else { + uniShared.callOptions(data, `${type}:fail`); + } + } + break; + case "translateMarker": + onMapReady(() => { + const context = contexts[data.markerId]; + if (context) { + try { + context.translate(data); + } catch (error) { + uniShared.callOptions(data, `${type}:fail ${error.message}`); + } + uniShared.callOptions(data, `${type}:ok`); + } else { + uniShared.callOptions(data, `${type}:fail not found`); + } + }); + break; + case "includePoints": + state.includePoints = getPoints(data.includePoints); + if (isBoundsReady || getIsAMap()) { + updateBounds(); + } + onBoundsReady(() => { + uniShared.callOptions(data, `${type}:ok`); + }); + break; + case "getRegion": + onBoundsReady(() => { + const latLngBounds = map.getBounds(); + const southwest = latLngBounds.getSouthWest(); + const northeast = latLngBounds.getNorthEast(); + uniShared.callOptions(data, { + southwest: { + latitude: getLat(southwest), + longitude: getLng(southwest) + }, + northeast: { + latitude: getLat(northeast), + longitude: getLng(northeast) + }, + errMsg: `${type}:ok` + }); + }); + break; + case "getScale": + onMapReady(() => { + uniShared.callOptions(data, { + scale: map.getZoom(), + errMsg: `${type}:ok` + }); + }); + break; + } + }, id, true); + } catch (error) { + } + vue.provide("onMapReady", onMapReady); + vue.provide("addMapChidlContext", addMapChidlContext); + vue.provide("removeMapChidlContext", removeMapChidlContext); + return { + state, + mapRef, + trigger + }; +} +const index$a = /* @__PURE__ */ defineBuiltInComponent({ + name: "Map", + props: props$2, + emits: ["markertap", "labeltap", "callouttap", "controltap", "regionchange", "tap", "click", "updated", "update:scale", "update:latitude", "update:longitude"], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = vue.ref(null); + const { + mapRef, + trigger + } = useMap(props2, rootRef, emit2); + return () => { + return vue.createVNode("uni-map", { + "ref": rootRef, + "id": props2.id + }, [vue.createVNode("div", { + "ref": mapRef, + "style": "width: 100%; height: 100%; position: relative; overflow: hidden" + }, null, 512), props2.markers.map((item) => vue.createVNode(MapMarker, vue.mergeProps({ + "key": item.id + }, item), null, 16)), props2.polyline.map((item) => vue.createVNode(MapPolyline, item, null, 16)), props2.circles.map((item) => vue.createVNode(MapCircle, item, null, 16)), props2.controls.map((item) => vue.createVNode(MapControl, vue.mergeProps(item, { + "trigger": trigger + }), null, 16, ["trigger"])), props2.showLocation && vue.createVNode(MapLocation, null, null), props2.polygons.map((item) => vue.createVNode(MapPolygon, item, null, 16)), vue.createVNode("div", { + "style": "position: absolute;top: 0;width: 100%;height: 100%;overflow: hidden;pointer-events: none;" + }, [slots.default && slots.default()])], 8, ["id"]); + }; + } +}); +const props$1 = { + scrollTop: { + type: [String, Number], + default: 0 + } +}; +const index$9 = /* @__PURE__ */ defineBuiltInComponent({ + name: "CoverView", + compatConfig: { + MODE: 3 + }, + props: props$1, + setup(props2, { + slots + }) { + const content = vue.ref(null); + vue.watch(() => props2.scrollTop, (val) => { + setScrollTop(val); + }); + function setScrollTop(val) { + let _content = content.value; + if (getComputedStyle(_content).overflowY === "scroll") { + _content.scrollTop = _upx2pxNum(val); + } + } + function _upx2pxNum(val) { + let _val = String(val); + if (/\d+[ur]px$/i.test(_val)) { + _val.replace(/\d+[ur]px$/i, (text) => { + return String(uni.upx2px(parseFloat(text))); + }); + } + return parseFloat(_val) || 0; + } + return () => { + return vue.createVNode("uni-cover-view", { + "scroll-top": props2.scrollTop + }, [vue.createVNode("div", { + "ref": content, + "class": "uni-cover-view" + }, [slots.default && slots.default()], 512)], 8, ["scroll-top"]); + }; + } +}); +const index$8 = /* @__PURE__ */ defineBuiltInComponent({ + name: "CoverImage", + compatConfig: { + MODE: 3 + }, + props: { + src: { + type: String, + default: "" + } + }, + emits: ["load", "error"], + setup(props2, { + emit: emit2 + }) { + const root = vue.ref(null); + const trigger = useCustomEvent(root, emit2); + function load($event) { + trigger("load", $event); + } + function error($event) { + trigger("error", $event); + } + return () => { + const { + src + } = props2; + return vue.createVNode("uni-cover-image", { + "ref": root, + "src": src + }, [vue.createVNode("div", { + "class": "uni-cover-image" + }, [src ? vue.createVNode("img", { + "src": getRealPath(src), + "onLoad": load, + "onError": error + }, null, 40, ["src", "onLoad", "onError"]) : null])], 8, ["src"]); + }; + } +}); +function usePopupStyle(props2) { + const popupWidth = vue.ref(0); + const popupHeight = vue.ref(0); + const isDesktop = vue.computed( + () => popupWidth.value >= 500 && popupHeight.value >= 500 + ); + const popupStyle = vue.computed(() => { + const style = { + content: { + transform: "", + left: "", + top: "", + bottom: "" + }, + triangle: { + left: "", + top: "", + bottom: "", + "border-width": "", + "border-color": "" + } + }; + const contentStyle = style.content; + const triangleStyle = style.triangle; + const popover = props2.popover; + function getNumber(value) { + return Number(value) || 0; + } + if (isDesktop.value && popover) { + shared.extend(triangleStyle, { + position: "absolute", + width: "0", + height: "0", + "margin-left": "-6px", + "border-style": "solid" + }); + const popoverLeft = getNumber(popover.left); + const popoverWidth = getNumber(popover.width); + const popoverTop = getNumber(popover.top); + const popoverHeight = getNumber(popover.height); + const center = popoverLeft + popoverWidth / 2; + contentStyle.transform = "none !important"; + const contentLeft = Math.max(0, center - 300 / 2); + contentStyle.left = `${contentLeft}px`; + let triangleLeft = Math.max(12, center - contentLeft); + triangleLeft = Math.min(300 - 12, triangleLeft); + triangleStyle.left = `${triangleLeft}px`; + const vcl = popupHeight.value / 2; + if (popoverTop + popoverHeight - vcl > vcl - popoverTop) { + contentStyle.top = "auto"; + contentStyle.bottom = `${popupHeight.value - popoverTop + 6}px`; + triangleStyle.bottom = "-6px"; + triangleStyle["border-width"] = "6px 6px 0 6px"; + triangleStyle["border-color"] = "#fcfcfd transparent transparent transparent"; + } else { + contentStyle.top = `${popoverTop + popoverHeight + 6}px`; + triangleStyle.top = "-6px"; + triangleStyle["border-width"] = "0 6px 6px 6px"; + triangleStyle["border-color"] = "transparent transparent #fcfcfd transparent"; + } + } + return style; + }); + return { + isDesktop, + popupStyle + }; +} +function useKeyboard() { + const key = vue.ref(""); + const disable = vue.ref(false); + return { + key, + disable + }; +} +function _isSlot(s) { + return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !vue.isVNode(s); +} +function getDefaultStartValue(props2) { + if (props2.mode === mode.TIME) { + return "00:00"; + } + if (props2.mode === mode.DATE) { + const year = (/* @__PURE__ */ new Date()).getFullYear() - 150; + switch (props2.fields) { + case fields.YEAR: + return year.toString(); + case fields.MONTH: + return year + "-01"; + default: + return year + "-01-01"; + } + } + return ""; +} +function getDefaultEndValue(props2) { + if (props2.mode === mode.TIME) { + return "23:59"; + } + if (props2.mode === mode.DATE) { + const year = (/* @__PURE__ */ new Date()).getFullYear() + 150; + switch (props2.fields) { + case fields.YEAR: + return year.toString(); + case fields.MONTH: + return year + "-12"; + default: + return year + "-12-31"; + } + } + return ""; +} +function getDateValueArray(props2, state, valueStr, defaultValue) { + const splitStr = props2.mode === mode.DATE ? "-" : ":"; + const array = props2.mode === mode.DATE ? state.dateArray : state.timeArray; + let max; + if (props2.mode === mode.TIME) { + max = 2; + } else { + switch (props2.fields) { + case fields.YEAR: + max = 1; + break; + case fields.MONTH: + max = 2; + break; + default: + max = 3; + break; + } + } + const inputArray = String(valueStr).split(splitStr); + let value = []; + for (let i = 0; i < max; i++) { + const val = inputArray[i]; + value.push(array[i].indexOf(val)); + } + if (value.indexOf(-1) >= 0) { + value = defaultValue ? getDateValueArray(props2, state, defaultValue) : value.map(() => 0); + } + return value; +} +const mode = { + SELECTOR: "selector", + MULTISELECTOR: "multiSelector", + TIME: "time", + DATE: "date" + // 暂不支持城市选择 + // REGION: 'region' +}; +const fields = { + YEAR: "year", + MONTH: "month", + DAY: "day" +}; +const selectorType = { + PICKER: "picker", + SELECT: "select" +}; +const props = { + name: { + type: String, + default: "" + }, + range: { + type: Array, + default() { + return []; + } + }, + rangeKey: { + type: String, + default: "" + }, + value: { + type: [Number, String, Array], + default: 0 + }, + mode: { + type: String, + default: mode.SELECTOR, + validator(val) { + return Object.values(mode).includes(val); + } + }, + fields: { + type: String, + default: "" + }, + start: { + type: String, + default: (props2) => { + return getDefaultStartValue(props2); + } + }, + end: { + type: String, + default: (props2) => { + return getDefaultEndValue(props2); + } + }, + disabled: { + type: [Boolean, String], + default: false + }, + selectorType: { + type: String, + default: "" + } +}; +const index$7 = /* @__PURE__ */ defineBuiltInComponent({ + name: "Picker", + compatConfig: { + MODE: 3 + }, + props, + emits: ["change", "cancel", "columnchange"], + setup(props2, { + emit: emit2, + slots + }) { + initI18nPickerMsgsOnce(); + const { + t: t2 + } = useI18n(); + const rootRef = vue.ref(null); + const pickerRef = vue.ref(null); + const selectRef = vue.ref(null); + const inputRef = vue.ref(null); + const pickerRender = vue.ref(false); + const { + state, + rangeArray + } = usePickerState(props2); + const trigger = useCustomEvent(rootRef, emit2); + const { + system, + selectorTypeComputed, + _show, + _l10nColumn, + _l10nItem, + _input, + _fixInputPosition, + _pickerViewChange, + _cancel, + _change, + _resetFormData, + _getFormData, + _createTime, + _createDate, + _setValueSync + } = usePickerMethods(props2, state, trigger, rootRef, pickerRef, selectRef, inputRef); + usePickerWatch(state, _cancel, _change); + usePickerForm(_resetFormData, _getFormData); + _createTime(); + _createDate(); + _setValueSync(); + const popup = usePopupStyle(state); + vue.watchEffect(() => { + state.isDesktop = popup.isDesktop.value; + state.popupStyle = popup.popupStyle.value; + }); + return () => { + let _slot2; + const { + visible, + contentVisible, + valueArray, + popupStyle, + valueSync + } = state; + const { + rangeKey, + mode: mode2, + start, + end + } = props2; + const booleanAttrs = useBooleanAttr(props2, "disabled"); + return vue.createVNode("uni-picker", vue.mergeProps({ + "ref": rootRef + }, booleanAttrs, { + "onClick": withWebEvent(_show) + }), [pickerRender.value ? vue.createVNode("div", { + "ref": pickerRef, + "class": ["uni-picker-container", `uni-${mode2}-${selectorTypeComputed.value}`], + "onWheel": onEventPrevent, + "onTouchmove": onEventPrevent + }, [vue.createVNode(vue.Transition, { + "name": "uni-fade" + }, { + default: () => [vue.withDirectives(vue.createVNode("div", { + "class": "uni-mask uni-picker-mask", + "onClick": withWebEvent(_cancel), + "onMousemove": _fixInputPosition + }, null, 40, ["onClick", "onMousemove"]), [[vue.vShow, visible]])] + }), !system.value ? vue.createVNode("div", { + "class": [{ + "uni-picker-toggle": visible + }, "uni-picker-custom"], + "style": popupStyle.content + }, [vue.createVNode("div", { + "class": "uni-picker-header", + "onClick": onEventStop + }, [vue.createVNode("div", { + "class": "uni-picker-action uni-picker-action-cancel", + "onClick": withWebEvent(_cancel) + }, [t2("uni.picker.cancel")], 8, ["onClick"]), vue.createVNode("div", { + "class": "uni-picker-action uni-picker-action-confirm", + "onClick": _change + }, [t2("uni.picker.done")], 8, ["onClick"])], 8, ["onClick"]), contentVisible ? vue.createVNode(PickerView, { + "value": _l10nColumn(valueArray), + "class": "uni-picker-content", + "onChange": _pickerViewChange + }, _isSlot(_slot2 = vue.renderList(_l10nColumn(rangeArray.value), (rangeItem, index0) => { + let _slot; + return vue.createVNode(PickerViewColumn, { + "key": index0 + }, _isSlot(_slot = vue.renderList(rangeItem, (item, index2) => vue.createVNode("div", { + "key": index2, + "class": "uni-picker-item" + }, [typeof item === "object" ? item[rangeKey] || "" : _l10nItem(item, index0)]))) ? _slot : { + default: () => [_slot], + _: 1 + }); + })) ? _slot2 : { + default: () => [_slot2], + _: 1 + }, 8, ["value", "onChange"]) : null, vue.createVNode("div", { + "ref": selectRef, + "class": "uni-picker-select", + "onWheel": onEventStop, + "onTouchmove": onEventStop + }, [vue.renderList(rangeArray.value[0], (item, index2) => vue.createVNode("div", { + "key": index2, + "class": ["uni-picker-item", { + selected: valueArray[0] === index2 + }], + "onClick": () => { + valueArray[0] = index2; + _change(); + } + }, [typeof item === "object" ? item[rangeKey] || "" : item], 10, ["onClick"]))], 40, ["onWheel", "onTouchmove"]), vue.createVNode("div", { + "style": popupStyle.triangle + }, null, 4)], 6) : null], 40, ["onWheel", "onTouchmove"]) : null, vue.createVNode("div", null, [slots.default && slots.default()]), system.value ? vue.createVNode("div", { + "class": "uni-picker-system", + "onMousemove": withWebEvent(_fixInputPosition) + }, [vue.createVNode("input", { + "class": ["uni-picker-system_input", system.value], + "ref": inputRef, + "value": valueSync, + "type": mode2, + "tabindex": "-1", + "min": start, + "max": end, + "onChange": ($event) => { + _input($event); + onEventStop($event); + } + }, null, 42, ["value", "type", "min", "max", "onChange"])], 40, ["onMousemove"]) : null], 16, ["onClick"]); + }; + } +}); +function usePickerState(props2) { + const state = vue.reactive({ + valueSync: void 0, + visible: false, + contentVisible: false, + popover: null, + valueChangeSource: "", + timeArray: [], + dateArray: [], + valueArray: [], + oldValueArray: [], + isDesktop: false, + popupStyle: { + content: {}, + triangle: {} + } + }); + const rangeArray = vue.computed(() => { + let val = props2.range; + switch (props2.mode) { + case mode.SELECTOR: + return [val]; + case mode.MULTISELECTOR: + return val; + case mode.TIME: + return state.timeArray; + case mode.DATE: { + const dateArray = state.dateArray; + switch (props2.fields) { + case fields.YEAR: + return [dateArray[0]]; + case fields.MONTH: + return [dateArray[0], dateArray[1]]; + default: + return [dateArray[0], dateArray[1], dateArray[2]]; + } + } + } + return []; + }); + return { + state, + rangeArray + }; +} +function useIsiPad() { + const isiPad = vue.ref(false); + return isiPad; +} +function useSystem() { + const _system = vue.ref(""); + return _system; +} +let __contentVisibleDelay; +function usePickerMethods(props2, state, trigger, rootRef, pickerRef, selectRef, inputRef) { + const isiPad = useIsiPad(); + const _system = useSystem(); + const selectorTypeComputed = vue.computed(() => { + const type = props2.selectorType; + if (Object.values(selectorType).includes(type)) { + return type; + } + return isiPad.value ? selectorType.PICKER : selectorType.SELECT; + }); + const system = vue.computed(() => { + if (props2.mode === mode.DATE && !Object.values(fields).includes(props2.fields) && state.isDesktop) { + return _system.value; + } + return ""; + }); + const startArray = vue.computed(() => { + return getDateValueArray(props2, state, props2.start, getDefaultStartValue(props2)); + }); + const endArray = vue.computed(() => { + return getDateValueArray(props2, state, props2.end, getDefaultEndValue(props2)); + }); + function _show(event) { + if (props2.disabled) { + return; + } + state.valueChangeSource = ""; + let $picker = pickerRef.value; + let _currentTarget = event.currentTarget; + $picker.remove(); + (document.querySelector("uni-app") || document.body).appendChild($picker); + $picker.style.display = "block"; + const rect = _currentTarget.getBoundingClientRect(); + state.popover = { + top: rect.top, + left: rect.left, + width: rect.width, + height: rect.height + }; + setTimeout(() => { + state.visible = true; + }, 20); + } + function _getFormData() { + return { + value: state.valueSync, + key: props2.name + }; + } + function _resetFormData() { + switch (props2.mode) { + case mode.SELECTOR: + state.valueSync = 0; + break; + case mode.MULTISELECTOR: + state.valueSync = props2.value.map((val) => 0); + break; + case mode.DATE: + case mode.TIME: + state.valueSync = ""; + break; + } + } + function _createTime() { + let hours = []; + let minutes = []; + for (let i = 0; i < 24; i++) { + hours.push((i < 10 ? "0" : "") + i); + } + for (let i = 0; i < 60; i++) { + minutes.push((i < 10 ? "0" : "") + i); + } + state.timeArray.push(hours, minutes); + } + function getYearStartEnd() { + let year = (/* @__PURE__ */ new Date()).getFullYear(); + let start = year - 150; + let end = year + 150; + if (props2.start) { + const _year = new Date(props2.start).getFullYear(); + if (!isNaN(_year) && _year < start) { + start = _year; + } + } + if (props2.end) { + const _year = new Date(props2.end).getFullYear(); + if (!isNaN(_year) && _year > end) { + end = _year; + } + } + return { + start, + end + }; + } + function _createDate() { + let years = []; + const year = getYearStartEnd(); + for (let i = year.start, end = year.end; i <= end; i++) { + years.push(String(i)); + } + let months = []; + for (let i = 1; i <= 12; i++) { + months.push((i < 10 ? "0" : "") + i); + } + let days = []; + for (let i = 1; i <= 31; i++) { + days.push((i < 10 ? "0" : "") + i); + } + state.dateArray.push(years, months, days); + } + function _getTimeValue(val) { + return val[0] * 60 + val[1]; + } + function _getDateValue(val) { + const DAY = 31; + return val[0] * DAY * 12 + (val[1] || 0) * DAY + (val[2] || 0); + } + function _cloneArray(val1, val2) { + for (let i = 0; i < val1.length && i < val2.length; i++) { + val1[i] = val2[i]; + } + } + function _setValueSync() { + let val = props2.value; + switch (props2.mode) { + case mode.MULTISELECTOR: + { + if (!shared.isArray(val)) { + val = state.valueArray; + } + if (!shared.isArray(state.valueSync)) { + state.valueSync = []; + } + const length = state.valueSync.length = Math.max(val.length, props2.range.length); + for (let index2 = 0; index2 < length; index2++) { + const val0 = Number(val[index2]); + const val1 = Number(state.valueSync[index2]); + const val2 = isNaN(val0) ? isNaN(val1) ? 0 : val1 : val0; + const maxVal = props2.range[index2] ? props2.range[index2].length - 1 : 0; + state.valueSync.splice(index2, 1, val2 < 0 || val2 > maxVal ? 0 : val2); + } + } + break; + case mode.TIME: + case mode.DATE: + state.valueSync = String(val); + break; + default: { + const valueSync = Number(val); + state.valueSync = valueSync < 0 ? 0 : valueSync; + break; + } + } + } + function _setValueArray() { + let val = state.valueSync; + let valueArray; + switch (props2.mode) { + case mode.MULTISELECTOR: + valueArray = [...val]; + break; + case mode.TIME: + valueArray = getDateValueArray(props2, state, val, uniShared.formatDateTime({ + mode: mode.TIME + })); + break; + case mode.DATE: + valueArray = getDateValueArray(props2, state, val, uniShared.formatDateTime({ + mode: mode.DATE + })); + break; + default: + valueArray = [val]; + break; + } + state.oldValueArray = [...valueArray]; + state.valueArray = [...valueArray]; + } + function _getValue() { + let val = state.valueArray; + switch (props2.mode) { + case mode.SELECTOR: + return val[0]; + case mode.MULTISELECTOR: + return val.map((val2) => val2); + case mode.TIME: + return state.valueArray.map((val2, i) => state.timeArray[i][val2]).join(":"); + case mode.DATE: + return state.valueArray.map((val2, i) => state.dateArray[i][val2]).join("-"); + } + } + function _change() { + _close(); + state.valueChangeSource = "click"; + const value = _getValue(); + state.valueSync = shared.isArray(value) ? value.map((val) => val) : value; + trigger("change", {}, { + value + }); + } + function _cancel($event) { + if (system.value === "firefox" && $event) { + const { + top, + left, + width, + height + } = state.popover; + const { + pageX, + pageY + } = $event; + if (pageX > left && pageX < left + width && pageY > top && pageY < top + height) { + return; + } + } + _close(); + trigger("cancel", {}, {}); + } + function _close() { + state.visible = false; + setTimeout(() => { + let $picker = pickerRef.value; + $picker.remove(); + rootRef.value.prepend($picker); + $picker.style.display = "none"; + }, 260); + } + function _select() { + if (props2.mode === mode.SELECTOR && selectorTypeComputed.value === selectorType.SELECT) { + selectRef.value.scrollTop = state.valueArray[0] * 34; + } + } + function _input($event) { + const EventTarget = $event.target; + state.valueSync = EventTarget.value; + vue.nextTick(() => { + _change(); + }); + } + function _fixInputPosition($event) { + if (system.value === "chrome") { + const rect = rootRef.value.getBoundingClientRect(); + const fontSize = 32; + inputRef.value.style.left = `${$event.clientX - rect.left - fontSize * 1.5}px`; + inputRef.value.style.top = `${$event.clientY - rect.top - fontSize * 0.5}px`; + } + } + function _pickerViewChange(event) { + state.valueArray = _l10nColumn(event.detail.value, true); + } + function _l10nColumn(array, normalize) { + const { + getLocale: getLocale2 + } = useI18n(); + if (props2.mode === mode.DATE) { + const locale = getLocale2(); + if (!locale.startsWith("zh")) { + switch (props2.fields) { + case fields.YEAR: + return array; + case fields.MONTH: + return [array[1], array[0]]; + default: + switch (locale) { + case "es": + case "fr": + return [array[2], array[1], array[0]]; + default: + return normalize ? [array[2], array[0], array[1]] : [array[1], array[2], array[0]]; + } + } + } + } + return array; + } + function _l10nItem(item, index2) { + const { + getLocale: getLocale2 + } = useI18n(); + if (props2.mode === mode.DATE) { + const locale = getLocale2(); + if (locale.startsWith("zh")) { + const array = ["年", "月", "日"]; + return item + array[index2]; + } else if (props2.fields !== fields.YEAR && index2 === (props2.fields !== fields.MONTH && (locale === "es" || locale === "fr") ? 1 : 0)) { + let array; + switch (locale) { + case "es": + array = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "​​julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]; + break; + case "fr": + array = ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; + break; + default: + array = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + break; + } + return array[Number(item) - 1]; + } + } + return item; + } + vue.watch(() => state.visible, (val) => { + if (val) { + clearTimeout(__contentVisibleDelay); + state.contentVisible = val; + _select(); + } else { + __contentVisibleDelay = setTimeout(() => { + state.contentVisible = val; + }, 300); + } + }); + vue.watch([() => props2.mode, () => props2.value, () => props2.range], _setValueSync, { + deep: true + }); + vue.watch(() => state.valueSync, _setValueArray, { + deep: true + }); + vue.watch(() => state.valueArray, (val) => { + if (props2.mode === mode.TIME || props2.mode === mode.DATE) { + const getValue = props2.mode === mode.TIME ? _getTimeValue : _getDateValue; + const valueArray = state.valueArray; + const _startArray = startArray.value; + const _endArray = endArray.value; + if (props2.mode === mode.DATE) { + const dateArray = state.dateArray; + const max = dateArray[2].length; + const day = Number(dateArray[2][valueArray[2]]) || 1; + const realDay = (/* @__PURE__ */ new Date(`${dateArray[0][valueArray[0]]}/${dateArray[1][valueArray[1]]}/${day}`)).getDate(); + if (realDay < day) { + valueArray[2] -= realDay + max - day; + } + } + if (getValue(valueArray) < getValue(_startArray)) { + _cloneArray(valueArray, _startArray); + } else if (getValue(valueArray) > getValue(_endArray)) { + _cloneArray(valueArray, _endArray); + } + } + val.forEach((value, column) => { + if (value !== state.oldValueArray[column]) { + state.oldValueArray[column] = value; + if (props2.mode === mode.MULTISELECTOR) { + trigger("columnchange", {}, { + column, + value + }); + } + } + }); + }); + return { + selectorTypeComputed, + system, + _show, + _cancel, + _change, + _l10nColumn, + _l10nItem, + _input, + _resetFormData, + _getFormData, + _createTime, + _createDate, + _setValueSync, + _fixInputPosition, + _pickerViewChange + }; +} +function usePickerWatch(state, _cancel, _change) { + const { + key, + disable + } = useKeyboard(); + vue.watchEffect(() => { + disable.value = !state.visible; + }); + vue.watch(key, (value) => { + if (value === "esc") { + _cancel(); + } else if (value === "enter") { + _change(); + } + }); +} +function usePickerForm(_resetFormData, _getFormData) { + const uniForm = vue.inject(uniFormKey, false); + if (uniForm) { + const field = { + reset: _resetFormData, + submit: () => { + const data = ["", null]; + const { + key, + value + } = _getFormData(); + if (key !== "") { + data[0] = key; + data[1] = value; + } + return data; + } + }; + uniForm.addField(field); + } +} +const index$6 = /* @__PURE__ */ defineUnsupportedComponent("ad"); +const index$5 = /* @__PURE__ */ defineUnsupportedComponent("ad-content-page"); +const index$4 = /* @__PURE__ */ defineUnsupportedComponent("ad-draw"); +const index$3 = /* @__PURE__ */ defineUnsupportedComponent("camera"); +const index$2 = /* @__PURE__ */ defineUnsupportedComponent("live-player"); +const index$1 = /* @__PURE__ */ defineUnsupportedComponent("live-pusher"); +const UniViewJSBridge$1 = /* @__PURE__ */ shared.extend(ViewJSBridge, { + publishHandler(event, args, pageId) { + UniServiceJSBridge.subscribeHandler(event, args, pageId); + } +}); +const request = /* @__PURE__ */ defineTaskApi( + API_REQUEST, + ({ + url, + data, + header, + method, + dataType: dataType2, + responseType, + withCredentials, + timeout = __uniConfig.networkTimeout.request + }, { resolve, reject }) => { + let body = null; + const contentType = normalizeContentType(header); + if (method !== "GET") { + if (shared.isString(data) || data instanceof ArrayBuffer) { + body = data; + } else { + if (contentType === "json") { + try { + body = JSON.stringify(data); + } catch (error) { + body = data.toString(); + } + } else if (contentType === "urlencoded") { + const bodyArray = []; + for (const key in data) { + if (shared.hasOwn(data, key)) { + bodyArray.push( + encodeURIComponent(key) + "=" + encodeURIComponent(data[key]) + ); + } + } + body = bodyArray.join("&"); + } else { + body = data.toString(); + } + } + } + const xhr = new XMLHttpRequest(); + const requestTask = new RequestTask(xhr); + xhr.open(method, url); + for (const key in header) { + if (shared.hasOwn(header, key)) { + xhr.setRequestHeader(key, header[key]); + } + } + const timer = setTimeout(function() { + xhr.onload = xhr.onabort = xhr.onerror = null; + requestTask.abort(); + reject("timeout"); + }, timeout); + xhr.responseType = responseType; + xhr.onload = function() { + clearTimeout(timer); + const statusCode = xhr.status; + let res = responseType === "text" ? xhr.responseText : xhr.response; + if (responseType === "text" && dataType2 === "json") { + try { + res = JSON.parse(res); + } catch (error) { + } + } + resolve({ + data: res, + statusCode, + header: parseHeaders(xhr.getAllResponseHeaders()), + cookies: [] + }); + }; + xhr.onabort = function() { + clearTimeout(timer); + reject("abort"); + }; + xhr.onerror = function() { + clearTimeout(timer); + reject(); + }; + xhr.withCredentials = withCredentials; + xhr.send(body); + return requestTask; + }, + RequestProtocol, + RequestOptions +); +function normalizeContentType(header) { + const name = Object.keys(header).find( + (name2) => name2.toLowerCase() === "content-type" + ); + if (!name) { + return; + } + const contentType = header[name]; + if (name !== "Content-Type") { + header["Content-Type"] = header[name]; + delete header[name]; + } + if (contentType.indexOf("application/json") === 0) { + return "json"; + } else if (contentType.indexOf("application/x-www-form-urlencoded") === 0) { + return "urlencoded"; + } + return "string"; +} +class RequestTask { + constructor(xhr) { + this._xhr = xhr; + } + abort() { + if (this._xhr) { + this._xhr.abort(); + delete this._xhr; + } + } + onHeadersReceived(callback) { + throw new Error("Method not implemented."); + } + offHeadersReceived(callback) { + throw new Error("Method not implemented."); + } +} +function parseHeaders(headers) { + const headersObject = {}; + headers.split(uniShared.LINEFEED).forEach((header) => { + const find = header.match(/(\S+\s*):\s*(.*)/); + if (!find || find.length !== 3) { + return; + } + headersObject[find[1]] = find[2]; + }); + return headersObject; +} +const STORAGE_KEYS = "uni-storage-keys"; +function parseValue(value) { + const types = ["object", "string", "number", "boolean", "undefined"]; + try { + const object = shared.isString(value) ? JSON.parse(value) : value; + const type = object.type; + if (types.indexOf(type) >= 0) { + const keys = Object.keys(object); + if (keys.length === 2 && "data" in object) { + if (typeof object.data === type) { + return object.data; + } + if (type === "object" && /^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z$/.test(object.data)) { + return new Date(object.data); + } + } else if (keys.length === 1) { + return ""; + } + } + } catch (error) { + } +} +const setStorageSync = /* @__PURE__ */ defineSyncApi( + API_SET_STORAGE_SYNC, + (key, data) => { + const type = typeof data; + const value = type === "string" ? data : JSON.stringify({ + type, + data + }); + localStorage.setItem(key, value); + }, + SetStorageSyncProtocol +); +const setStorage = /* @__PURE__ */ defineAsyncApi( + API_SET_STORAGE, + ({ key, data }, { resolve, reject }) => { + try { + setStorageSync(key, data); + resolve(); + } catch (error) { + reject(error.message); + } + }, + SetStorageProtocol +); +function getStorageOrigin(key) { + const value = localStorage && localStorage.getItem(key); + if (!shared.isString(value)) { + throw new Error("data not found"); + } + let data = value; + try { + const object = JSON.parse(value); + const result = parseValue(object); + if (result !== void 0) { + data = result; + } + } catch (error) { + } + return data; +} +const getStorageSync = /* @__PURE__ */ defineSyncApi( + API_GET_STORAGE_SYNC, + (key) => { + try { + return getStorageOrigin(key); + } catch (error) { + return ""; + } + }, + GetStorageSyncProtocol +); +const getStorage = /* @__PURE__ */ defineAsyncApi( + API_GET_STORAGE, + ({ key }, { resolve, reject }) => { + try { + const data = getStorageOrigin(key); + resolve({ + data + }); + } catch (error) { + reject(error.message); + } + }, + GetStorageProtocol +); +const removeStorageSync = /* @__PURE__ */ defineSyncApi( + API_REMOVE_STORAGE, + (key) => { + if (localStorage) { + localStorage.removeItem(key); + } + }, + RemoveStorageSyncProtocol +); +const removeStorage = /* @__PURE__ */ defineAsyncApi( + API_REMOVE_STORAGE, + ({ key }, { resolve }) => { + removeStorageSync(key); + resolve(); + }, + RemoveStorageProtocol +); +const clearStorageSync = /* @__PURE__ */ defineSyncApi( + "clearStorageSync", + () => { + if (localStorage) { + localStorage.clear(); + } + } +); +const clearStorage = /* @__PURE__ */ defineAsyncApi( + "clearStorage", + (_, { resolve }) => { + clearStorageSync(); + resolve(); + } +); +const getStorageInfoSync = /* @__PURE__ */ defineSyncApi( + "getStorageInfoSync", + () => { + const length = localStorage && localStorage.length || 0; + const keys = []; + let currentSize = 0; + for (let index2 = 0; index2 < length; index2++) { + const key = localStorage.key(index2); + const value = localStorage.getItem(key) || ""; + currentSize += key.length + value.length; + if (key !== STORAGE_KEYS) { + keys.push(key); + } + } + return { + keys, + currentSize: Math.ceil(currentSize * 2 / 1024), + limitSize: Number.MAX_VALUE + }; + } +); +const getStorageInfo = /* @__PURE__ */ defineAsyncApi( + "getStorageInfo", + (_, { resolve }) => { + resolve(getStorageInfoSync()); + } +); +function getTheme() { + if (__uniConfig.darkmode !== true) + return shared.isString(__uniConfig.darkmode) ? __uniConfig.darkmode : "light"; + try { + return window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark"; + } catch (error) { + return "light"; + } +} +let browserInfo; +function initBrowserInfo() { + { + return browserInfo = {}; + } +} +const getDeviceInfo = /* @__PURE__ */ defineSyncApi( + "getDeviceInfo", + () => { + initBrowserInfo(); + const { + deviceBrand, + deviceModel, + brand, + model, + platform, + system, + deviceOrientation, + deviceType + } = browserInfo; + return { + brand, + deviceBrand, + deviceModel, + devicePixelRatio: 1, + deviceId: Date.now() + "" + Math.floor(Math.random() * 1e7), + deviceOrientation, + deviceType, + model, + platform, + system + }; + } +); +const getAppBaseInfo = /* @__PURE__ */ defineSyncApi( + "getAppBaseInfo", + () => { + initBrowserInfo(); + const { theme, language, browserName, browserVersion } = browserInfo; + return { + appId: __uniConfig.appId, + appName: __uniConfig.appName, + appVersion: __uniConfig.appVersion, + appVersionCode: __uniConfig.appVersionCode, + appLanguage: getLocale ? getLocale() : language, + enableDebug: false, + hostSDKVersion: void 0, + hostPackageName: void 0, + hostFontSizeSetting: void 0, + hostName: browserName, + hostVersion: browserVersion, + hostTheme: theme, + hostLanguage: language, + language, + SDKVersion: "", + theme, + version: "" + }; + } +); +const getSystemInfoSync = /* @__PURE__ */ defineSyncApi( + "getSystemInfoSync", + () => { + { + return { + deviceId: Date.now() + "" + Math.floor(Math.random() * 1e7), + platform: "nodejs" + }; + } + } +); +function updateDocumentTitle(title) { + { + const ssrContext = getApp$1().$.appContext.provides[vue.ssrContextKey]; + if (ssrContext) { + ssrContext[uniShared.UNI_SSR_TITLE] = title; + } + } + UniServiceJSBridge.emit(uniShared.ON_NAVIGATION_BAR_CHANGE, { titleText: title }); +} +function useDocumentTitle(pageMeta) { + function update() { + updateDocumentTitle(pageMeta.navigationBar.titleText); + } + vue.watchEffect(update); +} +function setNavigationBar(pageMeta, type, args, resolve, reject) { + if (!pageMeta) { + return reject("page not found"); + } + const { navigationBar } = pageMeta; + switch (type) { + case API_SET_NAVIGATION_BAR_COLOR: + const { frontColor, backgroundColor, animation: animation2 } = args; + const { duration, timingFunc } = animation2; + if (frontColor) { + navigationBar.titleColor = frontColor === "#000000" ? "#000000" : "#ffffff"; + } + if (backgroundColor) { + navigationBar.backgroundColor = backgroundColor; + } + navigationBar.duration = duration + "ms"; + navigationBar.timingFunc = timingFunc; + break; + case API_SHOW_NAVIGATION_BAR_LOADING: + navigationBar.loading = true; + break; + case API_HIDE_NAVIGATION_BAR_LOADING: + navigationBar.loading = false; + break; + case API_SET_NAVIGATION_BAR_TITLE: + const { title } = args; + navigationBar.titleText = title; + { + updateDocumentTitle(args.title); + } + break; + } + resolve(); +} +const setNavigationBarTitle = /* @__PURE__ */ defineAsyncApi( + API_SET_NAVIGATION_BAR_TITLE, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_SET_NAVIGATION_BAR_TITLE, + args, + resolve, + reject + ); + }, + SetNavigationBarTitleProtocol +); +require("localstorage-polyfill"); +global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; +const api = /* @__PURE__ */ Object.defineProperty({ + __proto__: null, + clearStorage, + clearStorageSync, + getAppBaseInfo, + getDeviceInfo, + getStorage, + getStorageInfo, + getStorageInfoSync, + getStorageSync, + getSystemInfoSync, + removeStorage, + removeStorageSync, + request, + setNavigationBarTitle, + setStorage, + setStorageSync +}, Symbol.toStringTag, { value: "Module" }); +const uni$1 = api; +const UniServiceJSBridge$1 = /* @__PURE__ */ shared.extend(ServiceJSBridge, { + publishHandler(event, args, pageId) { + UniViewJSBridge.subscribeHandler(event, args, pageId); + } +}); +function onThemeChange(callback) { + if (__uniConfig.darkmode) { + UniServiceJSBridge.on(uniShared.ON_THEME_CHANGE, callback); + } +} +function parseTheme(pageStyle) { + let parsedStyle = {}; + if (__uniConfig.darkmode) { + parsedStyle = uniShared.normalizeStyles( + pageStyle, + __uniConfig.themeConfig, + getTheme() + ); + } + return __uniConfig.darkmode ? parsedStyle : pageStyle; +} +const _middleButton = { + width: "50px", + height: "50px", + iconWidth: "24px" +}; +const TabBar = /* @__PURE__ */ defineSystemComponent({ + name: "TabBar", + setup() { + const visibleList = vue.ref([]); + const _tabBar = useTabBar(); + const tabBar2 = vue.reactive(parseTheme(_tabBar)); + useVisibleList(tabBar2, visibleList); + useTabBarCssVar(tabBar2); + const onSwitchTab = useSwitchTab(vueRouter.useRoute(), tabBar2, visibleList); + const { + style, + borderStyle, + placeholderStyle + } = useTabBarStyle(tabBar2); + onThemeChange(() => { + const tabBarStyle = parseTheme(_tabBar); + tabBar2.backgroundColor = tabBarStyle.backgroundColor; + tabBar2.borderStyle = tabBarStyle.borderStyle; + tabBar2.color = tabBarStyle.color; + tabBar2.selectedColor = tabBarStyle.selectedColor; + tabBar2.blurEffect = tabBarStyle.blurEffect; + if (tabBarStyle.list && tabBarStyle.list.length) { + tabBarStyle.list.forEach((item, index2) => { + tabBar2.list[index2].iconPath = item.iconPath; + tabBar2.list[index2].selectedIconPath = item.selectedIconPath; + }); + } + }); + return () => { + const tabBarItemsTsx = createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList); + return vue.createVNode("uni-tabbar", { + "class": "uni-tabbar-" + tabBar2.position + }, [vue.createVNode("div", { + "class": "uni-tabbar", + "style": style.value + }, [vue.createVNode("div", { + "class": "uni-tabbar-border", + "style": borderStyle.value + }, null, 4), tabBarItemsTsx], 4), vue.createVNode("div", { + "class": "uni-placeholder", + "style": placeholderStyle.value + }, null, 4)], 2); + }; + } +}); +function useTabBarCssVar(tabBar2) { + vue.watch(() => tabBar2.shown, (value) => { + updatePageCssVar({ + "--window-bottom": normalizeWindowBottom(value ? parseInt(tabBar2.height) : 0) + }); + }); +} +function useVisibleList(tabBar2, visibleList) { + const internalMidButton = vue.ref(shared.extend({ + type: "midButton" + }, tabBar2.midButton)); + function setVisibleList() { + let tempList = []; + tempList = tabBar2.list.filter((item) => item.visible !== false); + if (__UNI_FEATURE_TABBAR_MIDBUTTON__ && tabBar2.midButton) { + internalMidButton.value = shared.extend({}, _middleButton, internalMidButton.value, tabBar2.midButton); + tempList = tempList.filter((item) => !isMidButton(item)); + if (tempList.length % 2 === 0) { + tempList.splice(Math.floor(tempList.length / 2), 0, internalMidButton.value); + } + } + visibleList.value = tempList; + } + vue.watchEffect(setVisibleList); +} +function useSwitchTab(route, tabBar2, visibleList) { + vue.watchEffect(() => { + const meta = route.meta; + if (meta.isTabBar) { + const pagePath = meta.route; + const index2 = visibleList.value.findIndex((item) => item.pagePath === pagePath); + tabBar2.selectedIndex = index2; + } + }); + return (tabBarItem, index2) => { + const { + type + } = tabBarItem; + return () => { + if (__UNI_FEATURE_TABBAR_MIDBUTTON__ && type === "midButton") { + return UniServiceJSBridge.invokeOnCallback(API_ON_TAB_BAR_MID_BUTTON_TAP); + } + const { + pagePath, + text + } = tabBarItem; + let url = uniShared.addLeadingSlash(pagePath); + if (url === __uniRoutes[0].alias) { + url = "/"; + } + if (route.path !== url) { + uni.switchTab({ + from: "tabBar", + url, + tabBarText: text + }); + } else { + invokeHook("onTabItemTap", { + index: index2, + text, + pagePath + }); + } + }; + }; +} +const DEFAULT_BG_COLOR = "#f7f7fa"; +const BLUR_EFFECT_COLOR_DARK = "rgb(0, 0, 0, 0.8)"; +const BLUR_EFFECT_COLOR_LIGHT = "rgb(250, 250, 250, 0.8)"; +const BLUR_EFFECT_COLORS = { + dark: BLUR_EFFECT_COLOR_DARK, + light: BLUR_EFFECT_COLOR_LIGHT, + extralight: BLUR_EFFECT_COLOR_LIGHT +}; +const BORDER_COLORS = { + white: "rgba(255, 255, 255, 0.33)", + black: "rgba(0, 0, 0, 0.33)" +}; +function useTabBarStyle(tabBar2) { + const style = vue.computed(() => { + let backgroundColor = tabBar2.backgroundColor; + const blurEffect = tabBar2.blurEffect; + if (!backgroundColor) { + if (blurEffect && blurEffect !== "none") { + backgroundColor = BLUR_EFFECT_COLORS[blurEffect]; + } + } + return { + backgroundColor: backgroundColor || DEFAULT_BG_COLOR, + backdropFilter: blurEffect !== "none" ? "blur(10px)" : blurEffect + }; + }); + const borderStyle = vue.computed(() => { + const { + borderStyle: borderStyle2 + } = tabBar2; + return { + backgroundColor: BORDER_COLORS[borderStyle2] || borderStyle2 + }; + }); + const placeholderStyle = vue.computed(() => { + return { + height: tabBar2.height + }; + }); + return { + style, + borderStyle, + placeholderStyle + }; +} +function isMidButton(item) { + return item.type === "midButton"; +} +function createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList) { + const { + selectedIndex, + selectedColor, + color + } = tabBar2; + return visibleList.value.map((item, index2) => { + const selected = selectedIndex === index2; + const textColor = selected ? selectedColor : color; + const iconPath = (selected ? item.selectedIconPath || item.iconPath : item.iconPath) || ""; + const iconfontText = item.iconfont ? selected ? item.iconfont.selectedText || item.iconfont.text : item.iconfont.text : void 0; + const iconfontColor = item.iconfont ? selected ? item.iconfont.selectedColor || item.iconfont.color : item.iconfont.color : void 0; + if (!__UNI_FEATURE_TABBAR_MIDBUTTON__) { + return createTabBarItemTsx(textColor, iconPath, iconfontText, iconfontColor, item, tabBar2, index2, onSwitchTab); + } + return isMidButton(item) ? createTabBarMidButtonTsx(textColor, iconPath, iconfontText, iconfontColor, item, tabBar2, index2, onSwitchTab) : createTabBarItemTsx(textColor, iconPath, iconfontText, iconfontColor, item, tabBar2, index2, onSwitchTab); + }); +} +function createTabBarItemTsx(color, iconPath, iconfontText, iconfontColor, tabBarItem, tabBar2, index2, onSwitchTab) { + return vue.createVNode("div", { + "key": index2, + "class": "uni-tabbar__item", + "onClick": onSwitchTab(tabBarItem, index2) + }, [createTabBarItemBdTsx(color, iconPath || "", iconfontText, iconfontColor, tabBarItem, tabBar2)], 8, ["onClick"]); +} +function createTabBarItemBdTsx(color, iconPath, iconfontText, iconfontColor, tabBarItem, tabBar2) { + const { + height + } = tabBar2; + return vue.createVNode("div", { + "class": "uni-tabbar__bd", + "style": { + height + } + }, [iconfontText ? createTabBarItemIconfontTsx(iconfontText, iconfontColor || BLUR_EFFECT_COLOR_DARK, tabBarItem, tabBar2) : iconPath && createTabBarItemIconTsx(iconPath, tabBarItem, tabBar2), tabBarItem.text && createTabBarItemTextTsx(color, tabBarItem, tabBar2), tabBarItem.redDot && createTabBarItemRedDotTsx(tabBarItem.badge)], 4); +} +function createTabBarItemIconTsx(iconPath, tabBarItem, tabBar2) { + const { + type, + text + } = tabBarItem; + const { + iconWidth + } = tabBar2; + const clazz2 = "uni-tabbar__icon" + (text ? " uni-tabbar__icon__diff" : ""); + const style = { + width: iconWidth, + height: iconWidth + }; + return vue.createVNode("div", { + "class": clazz2, + "style": style + }, [type !== "midButton" && vue.createVNode("img", { + "src": getRealPath(iconPath) + }, null, 8, ["src"])], 6); +} +function createTabBarItemIconfontTsx(iconfontText, iconfontColor, tabBarItem, tabBar2) { + var _a; + const { + type, + text + } = tabBarItem; + const { + iconWidth + } = tabBar2; + const clazz2 = "uni-tabbar__icon" + (text ? " uni-tabbar__icon__diff" : ""); + const style = { + width: iconWidth, + height: iconWidth + }; + const iconfontStyle = { + fontSize: ((_a = tabBarItem.iconfont) == null ? void 0 : _a.fontSize) || iconWidth, + color: iconfontColor + }; + return vue.createVNode("div", { + "class": clazz2, + "style": style + }, [type !== "midButton" && vue.createVNode("div", { + "class": "uni-tabbar__iconfont", + "style": iconfontStyle + }, [iconfontText], 4)], 6); +} +function createTabBarItemTextTsx(color, tabBarItem, tabBar2) { + const { + iconPath, + text + } = tabBarItem; + const { + fontSize, + spacing + } = tabBar2; + const style = { + color, + fontSize, + lineHeight: !iconPath ? 1.8 : "normal", + marginTop: !iconPath ? "inherit" : spacing + }; + return vue.createVNode("div", { + "class": "uni-tabbar__label", + "style": style + }, [text], 4); +} +function createTabBarItemRedDotTsx(badge) { + const clazz2 = "uni-tabbar__reddot" + (badge ? " uni-tabbar__badge" : ""); + return vue.createVNode("div", { + "class": clazz2 + }, [badge], 2); +} +function createTabBarMidButtonTsx(color, iconPath, iconfontText, iconfontColor, midButton, tabBar2, index2, onSwitchTab) { + const { + width, + height, + backgroundImage, + iconWidth + } = midButton; + return vue.createVNode("div", { + "key": "midButton", + "class": "uni-tabbar__item", + "style": { + flex: "0 0 " + width, + position: "relative" + }, + "onClick": onSwitchTab(midButton, index2) + }, [vue.createVNode("div", { + "class": "uni-tabbar__mid", + "style": { + width, + height, + backgroundImage: backgroundImage ? "url('" + getRealPath(backgroundImage) + "')" : "none" + } + }, [iconPath && vue.createVNode("img", { + "style": { + width: iconWidth, + height: iconWidth + }, + "src": getRealPath(iconPath) + }, null, 12, ["src"])], 4), createTabBarItemBdTsx(color, iconPath, iconfontText, iconfontColor, midButton, tabBar2)], 12, ["onClick"]); +} +const LayoutComponent = /* @__PURE__ */ defineSystemComponent({ + name: "Layout", + setup(_props, { + emit: emit2 + }) { + const rootRef = vue.ref(null); + const keepAliveRoute = __UNI_FEATURE_PAGES__ && useKeepAliveRoute(); + const { + layoutState, + windowState + } = useState(); + useMaxWidth(layoutState, rootRef); + const topWindow = __UNI_FEATURE_TOPWINDOW__ && useTopWindow(layoutState); + const leftWindow = __UNI_FEATURE_LEFTWINDOW__ && useLeftWindow(layoutState); + const rightWindow = __UNI_FEATURE_RIGHTWINDOW__ && useRightWindow(layoutState); + const showTabBar = __UNI_FEATURE_TABBAR__ && useShowTabBar(); + const clazz2 = useAppClass(showTabBar); + return () => { + const layoutTsx = createLayoutTsx(keepAliveRoute, layoutState, windowState, topWindow, leftWindow, rightWindow); + const tabBarTsx = __UNI_FEATURE_TABBAR__ && createTabBarTsx(showTabBar); + return vue.createVNode("uni-app", { + "ref": rootRef, + "class": clazz2.value + }, [layoutTsx, tabBarTsx], 2); + }; + } +}); +function useAppClass(showTabBar) { + const showMaxWidth = vue.ref(false); + return vue.computed(() => { + return { + "uni-app--showtabbar": showTabBar && showTabBar.value, + "uni-app--maxwidth": showMaxWidth.value + }; + }); +} +function initMediaQuery(minWidth, callback) { + { + return false; + } +} +function useMaxWidth(layoutState, rootRef) { + const route = usePageRoute(); + function checkMaxWidth() { + const windowWidth = document.body.clientWidth; + const pages = getCurrentPages(); + let meta = {}; + if (pages.length > 0) { + const curPage = pages[pages.length - 1]; + meta = curPage.$page.meta; + } else { + const routeOptions = getRouteOptions(route.path, true); + if (routeOptions) { + meta = routeOptions.meta; + } + } + const maxWidth = parseInt(String((shared.hasOwn(meta, "maxWidth") ? meta.maxWidth : __uniConfig.globalStyle.maxWidth) || Number.MAX_SAFE_INTEGER)); + let showMaxWidth = false; + if (windowWidth > maxWidth) { + showMaxWidth = true; + } else { + showMaxWidth = false; + } + if (showMaxWidth && maxWidth) { + layoutState.marginWidth = (windowWidth - maxWidth) / 2; + vue.nextTick(() => { + const rootEl = rootRef.value; + if (rootEl) { + rootEl.setAttribute("style", "max-width:" + maxWidth + "px;margin:0 auto;"); + } + }); + } else { + layoutState.marginWidth = 0; + vue.nextTick(() => { + const rootEl = rootRef.value; + if (rootEl) { + rootEl.removeAttribute("style"); + } + }); + } + } + vue.watch([() => route.path], checkMaxWidth); +} +function useState() { + const route = usePageRoute(); + if (!__UNI_FEATURE_RESPONSIVE__) { + const layoutState2 = vue.reactive({ + marginWidth: 0, + leftWindowWidth: 0, + rightWindowWidth: 0 + }); + vue.watch(() => layoutState2.marginWidth, (value) => updateCssVar({ + "--window-margin": value + "px" + })); + vue.watch(() => layoutState2.leftWindowWidth + layoutState2.marginWidth, (value) => { + updateCssVar({ + "--window-left": value + "px" + }); + }); + vue.watch(() => layoutState2.rightWindowWidth + layoutState2.marginWidth, (value) => { + updateCssVar({ + "--window-right": value + "px" + }); + }); + return { + layoutState: layoutState2, + windowState: vue.computed(() => ({})) + }; + } + const topWindowMediaQuery = vue.ref(false); + const leftWindowMediaQuery = vue.ref(false); + const rightWindowMediaQuery = vue.ref(false); + const showTopWindow = vue.computed(() => __UNI_FEATURE_TOPWINDOW__ && route.meta.topWindow !== false && topWindowMediaQuery.value); + const showLeftWindow = vue.computed(() => __UNI_FEATURE_LEFTWINDOW__ && route.meta.leftWindow !== false && leftWindowMediaQuery.value); + const showRightWindow = vue.computed(() => __UNI_FEATURE_RIGHTWINDOW__ && route.meta.rightWindow !== false && rightWindowMediaQuery.value); + const layoutState = vue.reactive({ + topWindowMediaQuery, + showTopWindow, + apiShowTopWindow: false, + leftWindowMediaQuery, + showLeftWindow, + apiShowLeftWindow: false, + rightWindowMediaQuery, + showRightWindow, + apiShowRightWindow: false, + topWindowHeight: 0, + marginWidth: 0, + leftWindowWidth: 0, + rightWindowWidth: 0, + navigationBarTitleText: "", + topWindowStyle: {}, + leftWindowStyle: {}, + rightWindowStyle: {} + }); + const props2 = ["topWindow", "leftWindow", "rightWindow"]; + props2.forEach((prop) => { + var _a; + const matchMedia = (_a = __uniConfig[prop]) == null ? void 0 : _a.matchMedia; + if (matchMedia && shared.hasOwn(matchMedia, "minWidth")) { + matchMedia.minWidth; + } + const matches = initMediaQuery(); + layoutState[`${prop}MediaQuery`] = matches; + }); + vue.watch(() => layoutState.topWindowHeight, (value) => updateCssVar({ + "--top-window-height": value + "px" + })); + vue.watch(() => layoutState.marginWidth, (value) => updateCssVar({ + "--window-margin": value + "px" + })); + vue.watch(() => layoutState.leftWindowWidth + layoutState.marginWidth, (value) => { + updateCssVar({ + "--window-left": value + "px" + }); + }); + vue.watch(() => layoutState.rightWindowWidth + layoutState.marginWidth, (value) => { + updateCssVar({ + "--window-right": value + "px" + }); + }); + UniServiceJSBridge.on(uniShared.ON_NAVIGATION_BAR_CHANGE, (navigationBar) => { + layoutState.navigationBarTitleText = navigationBar.titleText; + }); + const windowState = vue.computed(() => ({ + matchTopWindow: layoutState.topWindowMediaQuery, + showTopWindow: layoutState.showTopWindow || layoutState.apiShowTopWindow, + matchLeftWindow: layoutState.leftWindowMediaQuery, + showLeftWindow: layoutState.showLeftWindow || layoutState.apiShowLeftWindow, + matchRightWindow: layoutState.rightWindowMediaQuery, + showRightWindow: layoutState.showRightWindow || layoutState.apiShowRightWindow + })); + return { + layoutState, + windowState + }; +} +function createLayoutTsx(keepAliveRoute, layoutState, windowState, topWindow, leftWindow, rightWindow) { + const routerVNode = __UNI_FEATURE_PAGES__ ? createRouterViewVNode(keepAliveRoute) : createPageVNode(); + if (!__UNI_FEATURE_RESPONSIVE__) { + return routerVNode; + } + const topWindowTsx = __UNI_FEATURE_TOPWINDOW__ ? createTopWindowTsx(topWindow, layoutState, windowState.value) : null; + const leftWindowTsx = __UNI_FEATURE_LEFTWINDOW__ ? createLeftWindowTsx(leftWindow, layoutState, windowState.value) : null; + const rightWindowTsx = __UNI_FEATURE_RIGHTWINDOW__ ? createRightWindowTsx(rightWindow, layoutState, windowState.value) : null; + return vue.createVNode("uni-layout", { + "class": { + "uni-app--showtopwindow": __UNI_FEATURE_TOPWINDOW__ && layoutState.showTopWindow, + "uni-app--showleftwindow": __UNI_FEATURE_LEFTWINDOW__ && layoutState.showLeftWindow, + "uni-app--showrightwindow": __UNI_FEATURE_RIGHTWINDOW__ && layoutState.showRightWindow + } + }, [topWindowTsx, vue.createVNode("uni-content", null, [vue.createVNode("uni-main", null, [routerVNode]), leftWindowTsx, rightWindowTsx])], 2); +} +function useShowTabBar(emit2) { + const route = usePageRoute(); + const tabBar2 = useTabBar(); + const showTabBar = vue.computed(() => route.meta.isTabBar && tabBar2.shown); + return showTabBar; +} +function createTabBarTsx(showTabBar) { + return vue.withDirectives(vue.createVNode(TabBar, null, null, 512), [[vue.vShow, showTabBar.value]]); +} +function createPageVNode() { + return vue.createVNode(__uniRoutes[0].component); +} +function createRouterViewVNode({ + routeKey, + isTabBar, + routeCache: routeCache2 +}) { + return vue.createVNode(vueRouter.RouterView, null, { + default: vue.withCtx(({ + Component + }) => [(vue.openBlock(), vue.createBlock(vue.KeepAlive, { + matchBy: "key", + cache: routeCache2 + }, [(vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(Component), { + type: isTabBar.value ? "tabBar" : "", + key: routeKey.value + }))], 1032, ["cache"]))]), + _: 1 + /* STABLE */ + }); +} +function useTopWindow(layoutState) { + const { + component, + style + } = __uniConfig.topWindow; + const windowRef = vue.ref(null); + function updateWindow() { + const instance = windowRef.value; + const el = uniShared.resolveOwnerEl(instance.$); + const height = el.getBoundingClientRect().height; + layoutState.topWindowHeight = height; + } + vue.watch(() => layoutState.showTopWindow || layoutState.apiShowTopWindow, () => vue.nextTick(updateWindow)); + layoutState.topWindowStyle = style; + return { + component, + windowRef + }; +} +function useLeftWindow(layoutState) { + const { + component, + style + } = __uniConfig.leftWindow; + const windowRef = vue.ref(null); + function updateWindow() { + const instance = windowRef.value; + const el = uniShared.resolveOwnerEl(instance.$); + const width = el.getBoundingClientRect().width; + layoutState.leftWindowWidth = width; + } + vue.watch(() => layoutState.showLeftWindow || layoutState.apiShowLeftWindow, () => vue.nextTick(updateWindow)); + layoutState.leftWindowStyle = style; + return { + component, + windowRef + }; +} +function useRightWindow(layoutState) { + const { + component, + style + } = __uniConfig.rightWindow; + const windowRef = vue.ref(null); + function updateWindow() { + const instance = windowRef.value; + const el = uniShared.resolveOwnerEl(instance.$); + const width = el.getBoundingClientRect().width; + layoutState.rightWindowWidth = width; + } + vue.watch(() => layoutState.showRightWindow || layoutState.apiShowRightWindow, () => vue.nextTick(updateWindow)); + layoutState.rightWindowStyle = style; + return { + component, + windowRef + }; +} +function createTopWindowTsx(topWindow, layoutState, windowState) { + if (topWindow) { + const { + component: TopWindow, + windowRef + } = topWindow; + return vue.withDirectives(vue.createVNode("uni-top-window", null, [vue.createVNode("div", { + "class": "uni-top-window", + "style": layoutState.topWindowStyle + }, [vue.createVNode(TopWindow, vue.mergeProps({ + "ref": windowRef, + "navigation-bar-title-text": layoutState.navigationBarTitleText + }, windowState), null, 16, ["navigation-bar-title-text"])], 4), vue.createVNode("div", { + "class": "uni-top-window--placeholder", + "style": { + height: layoutState.topWindowHeight + "px" + } + }, null, 4)], 512), [[vue.vShow, layoutState.showTopWindow || layoutState.apiShowTopWindow]]); + } +} +function createLeftWindowTsx(leftWindow, layoutState, windowState) { + if (leftWindow) { + const { + component: LeftWindow, + windowRef + } = leftWindow; + return vue.withDirectives(vue.createVNode("uni-left-window", { + "data-show": layoutState.apiShowLeftWindow || void 0, + "style": layoutState.leftWindowStyle + }, [layoutState.apiShowLeftWindow ? vue.createVNode("div", { + "class": "uni-mask", + "onClick": () => layoutState.apiShowLeftWindow = false + }, null, 8, ["onClick"]) : null, vue.createVNode("div", { + "class": "uni-left-window" + }, [vue.createVNode(LeftWindow, vue.mergeProps({ + "ref": windowRef + }, windowState), null, 16)])], 12, ["data-show"]), [[vue.vShow, layoutState.showLeftWindow || layoutState.apiShowLeftWindow]]); + } +} +function createRightWindowTsx(rightWindow, layoutState, windowState) { + if (rightWindow) { + const { + component: RightWindow, + windowRef + } = rightWindow; + return vue.withDirectives(vue.createVNode("uni-right-window", { + "data-show": layoutState.apiShowRightWindow || void 0, + "style": layoutState.rightWindowStyle + }, [layoutState.apiShowRightWindow ? vue.createVNode("div", { + "class": "uni-mask", + "onClick": () => layoutState.apiShowRightWindow = false + }, null, 8, ["onClick"]) : null, vue.createVNode("div", { + "class": "uni-right-window" + }, [vue.createVNode(RightWindow, vue.mergeProps({ + "ref": windowRef + }, windowState), null, 16)])], 12, ["data-show"]), [[vue.vShow, layoutState.showRightWindow || layoutState.apiShowRightWindow]]); + } +} +function usePageHeadTransparentBackgroundColor(backgroundColor) { + const { r, g: g2, b } = hexToRgba(backgroundColor); + return `rgba(${r},${g2},${b},0)`; +} +function usePageHeadTransparent(headRef, { + id, + navigationBar: { titleColor, coverage, backgroundColor } +}) { + vue.computed(() => hexToRgba(backgroundColor)); +} +const ICON_PATHS = { + none: "", + forward: "M11 7.844q-0.25-0.219-0.25-0.578t0.25-0.578q0.219-0.25 0.563-0.25t0.563 0.25l9.656 9.125q0.125 0.125 0.188 0.297t0.063 0.328q0 0.188-0.063 0.359t-0.188 0.297l-9.656 9.125q-0.219 0.25-0.563 0.25t-0.563-0.25q-0.25-0.219-0.25-0.578t0.25-0.609l9.063-8.594-9.063-8.594z", + back: ICON_PATH_BACK, + select: ICON_PATH_BACK, + share: "M26.563 24.844q0 0.125-0.109 0.234t-0.234 0.109h-17.938q-0.125 0-0.219-0.109t-0.094-0.234v-13.25q0-0.156 0.094-0.25t0.219-0.094h5.5v-1.531h-6q-0.531 0-0.906 0.391t-0.375 0.922v14.375q0 0.531 0.375 0.922t0.906 0.391h18.969q0.531 0 0.891-0.391t0.359-0.953v-5.156h-1.438v4.625zM29.813 10.969l-5.125-5.375-1.031 1.094 3.438 3.594-3.719 0.031q-2.313 0.188-4.344 1.125t-3.578 2.422-2.5 3.453-1.109 4.188l-0.031 0.25h1.469v-0.219q0.156-1.875 1-3.594t2.25-3.063 3.234-2.125 3.828-0.906l0.188-0.031 3.313-0.031-3.438 3.625 1.031 1.063 5.125-5.375-0.031-0.063 0.031-0.063z", + favorite: "M27.594 13.375q-0.063-0.188-0.219-0.313t-0.344-0.156l-7.094-0.969-3.219-6.406q-0.094-0.188-0.25-0.281t-0.375-0.094q-0.188 0-0.344 0.094t-0.25 0.281l-3.125 6.438-7.094 1.094q-0.188 0.031-0.344 0.156t-0.219 0.313q-0.031 0.188 0.016 0.375t0.172 0.313l5.156 4.969-1.156 7.063q-0.031 0.188 0.047 0.375t0.234 0.313q0.094 0.063 0.188 0.094t0.219 0.031q0.063 0 0.141-0.031t0.172-0.063l6.313-3.375 6.375 3.313q0.063 0.031 0.141 0.047t0.172 0.016q0.188 0 0.344-0.094t0.25-0.281q0.063-0.094 0.078-0.234t-0.016-0.234q0-0.031 0-0.063l-1.25-6.938 5.094-5.031q0.156-0.156 0.203-0.344t-0.016-0.375zM11.469 19.063q0.031-0.188-0.016-0.344t-0.172-0.281l-4.406-4.25 6.063-0.906q0.156-0.031 0.297-0.125t0.203-0.25l2.688-5.531 2.75 5.5q0.063 0.156 0.203 0.25t0.297 0.125l6.094 0.844-4.375 4.281q-0.125 0.125-0.172 0.297t-0.016 0.328l1.063 6.031-5.438-2.813q-0.156-0.094-0.328-0.078t-0.297 0.078l-5.438 2.875 1-6.031z", + home: "M23.719 16.5q-0.313 0-0.531 0.219t-0.219 0.5v7.063q0 0.219-0.172 0.391t-0.391 0.172h-12.344q-0.25 0-0.422-0.172t-0.172-0.391v-7.063q0-0.281-0.219-0.5t-0.531-0.219q-0.281 0-0.516 0.219t-0.234 0.5v7.063q0.031 0.844 0.625 1.453t1.438 0.609h12.375q0.844 0 1.453-0.609t0.609-1.453v-7.063q0-0.125-0.063-0.266t-0.156-0.234q-0.094-0.125-0.234-0.172t-0.297-0.047zM26.5 14.875l-8.813-8.813q-0.313-0.313-0.688-0.453t-0.781-0.141-0.781 0.141-0.656 0.422l-8.813 8.844q-0.188 0.219-0.188 0.516t0.219 0.484q0.094 0.125 0.234 0.172t0.297 0.047q0.125 0 0.25-0.047t0.25-0.141l8.781-8.781q0.156-0.156 0.406-0.156t0.406 0.156l8.813 8.781q0.219 0.188 0.516 0.188t0.516-0.219q0.188-0.188 0.203-0.484t-0.172-0.516z", + menu: "M8.938 18.313q0.875 0 1.484-0.609t0.609-1.453-0.609-1.453-1.484-0.609q-0.844 0-1.453 0.609t-0.609 1.453 0.609 1.453 1.453 0.609zM16.188 18.313q0.875 0 1.484-0.609t0.609-1.453-0.609-1.453-1.484-0.609q-0.844 0-1.453 0.609t-0.609 1.453 0.609 1.453 1.453 0.609zM23.469 18.313q0.844 0 1.453-0.609t0.609-1.453-0.609-1.453-1.453-0.609q-0.875 0-1.484 0.609t-0.609 1.453 0.609 1.453 1.484 0.609z", + close: ICON_PATH_CLOSE +}; +const PageHead = /* @__PURE__ */ defineSystemComponent({ + name: "PageHead", + setup() { + if (window.weibo) { + return; + } + const headRef = vue.ref(null); + const pageMeta = usePageMeta(); + const navigationBar = vue.reactive(parseTheme(pageMeta.navigationBar)); + const { + clazz: clazz2, + style + } = usePageHead(navigationBar); + onThemeChange(() => { + const _navigationBar = parseTheme(pageMeta.navigationBar); + navigationBar.backgroundColor = _navigationBar.backgroundColor; + navigationBar.titleColor = _navigationBar.titleColor; + }); + const buttons = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ && usePageHeadButtons(pageMeta); + const searchInput = __UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__ && navigationBar.searchInput && usePageHeadSearchInput(pageMeta); + __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ && navigationBar.type === "transparent" && usePageHeadTransparent(headRef, pageMeta); + return () => { + const backButtonTsx = __UNI_FEATURE_PAGES__ ? createBackButtonTsx(navigationBar, pageMeta.isQuit) : null; + const leftButtonsTsx = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ ? createButtonsTsx(buttons.left) : []; + const rightButtonsTsx = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ ? createButtonsTsx(buttons.right) : []; + const type = navigationBar.type || "default"; + const placeholderTsx = type !== "transparent" && type !== "float" && vue.createVNode("div", { + "class": { + "uni-placeholder": true, + "uni-placeholder-titlePenetrate": navigationBar.titlePenetrate + } + }, null, 2); + return vue.createVNode("uni-page-head", { + "uni-page-head-type": type + }, [vue.createVNode("div", { + "ref": headRef, + "class": clazz2.value, + "style": style.value + }, [vue.createVNode("div", { + "class": "uni-page-head-hd" + }, [backButtonTsx, ...leftButtonsTsx]), createPageHeadBdTsx(navigationBar, searchInput), vue.createVNode("div", { + "class": "uni-page-head-ft" + }, [...rightButtonsTsx])], 6), placeholderTsx], 8, ["uni-page-head-type"]); + }; + } +}); +function createBackButtonTsx(navigationBar, isQuit) { + if (!isQuit) { + return vue.createVNode("div", { + "class": "uni-page-head-btn", + "onClick": onPageHeadBackButton + }, [createSvgIconVNode(ICON_PATH_BACK, navigationBar.type === "transparent" ? "#fff" : navigationBar.titleColor, 27)], 8, ["onClick"]); + } +} +function createButtonsTsx(btns) { + return btns.map(({ + onClick, + btnClass, + btnStyle, + btnText, + btnIconPath, + badgeText, + iconStyle, + btnSelect + }, index2) => { + return vue.createVNode("div", { + "key": index2, + "class": btnClass, + "style": btnStyle, + "onClick": onClick, + "badge-text": badgeText + }, [btnIconPath ? createSvgIconVNode(btnIconPath, iconStyle.color, iconStyle.fontSize) : btnSelect ? vue.createVNode("span", { + "style": iconStyle + }, [vue.createVNode("i", { + "class": "uni-btn-icon", + "innerHTML": btnText + }, null, 8, ["innerHTML"]), createSvgIconVNode(ICON_PATHS["select"], "#000", 14)], 4) : vue.createVNode("i", { + "class": "uni-btn-icon", + "style": iconStyle, + "innerHTML": btnText + }, null, 12, ["innerHTML"])], 14, ["onClick", "badge-text"]); + }); +} +function createPageHeadBdTsx(navigationBar, searchInput) { + if (!__UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__ || !navigationBar.searchInput) { + return createPageHeadTitleTextTsx(navigationBar); + } + return createPageHeadSearchInputTsx(navigationBar, searchInput); +} +function createPageHeadTitleTextTsx({ + type, + loading, + titleSize, + titleText, + titleImage +}) { + return vue.createVNode("div", { + "class": "uni-page-head-bd" + }, [vue.createVNode("div", { + "style": { + fontSize: titleSize, + opacity: type === "transparent" ? 0 : 1 + }, + "class": "uni-page-head__title" + }, [loading ? vue.createVNode("i", { + "class": "uni-loading" + }, null) : titleImage ? vue.createVNode("img", { + "src": titleImage, + "class": "uni-page-head__title_image" + }, null, 8, ["src"]) : titleText], 4)]); +} +function createPageHeadSearchInputTsx(navigationBar, { + text, + focus, + composing, + onBlur, + onFocus, + onInput, + onConfirm, + onClick +}) { + const { + color, + align, + autoFocus, + disabled, + borderRadius, + backgroundColor, + placeholder, + placeholderColor + } = navigationBar.searchInput; + const searchStyle = { + borderRadius, + backgroundColor + }; + const placeholderClass = ["uni-page-head-search-placeholder", `uni-page-head-search-placeholder-${focus.value || text.value ? "left" : align}`]; + return vue.createVNode("div", { + "class": "uni-page-head-search", + "style": searchStyle + }, [vue.createVNode("div", { + "style": { + color: placeholderColor + }, + "class": placeholderClass + }, [vue.createVNode("div", { + "class": "uni-page-head-search-icon" + }, [createSvgIconVNode(ICON_PATH_SEARCH, placeholderColor, 20)]), text.value || composing.value ? "" : placeholder], 6), disabled ? vue.createVNode(Input, { + "disabled": true, + "style": { + color + }, + "placeholder-style": "color: " + placeholderColor, + "class": "uni-page-head-search-input", + "confirm-type": "search", + "onClick": onClick + }, null, 8, ["style", "placeholder-style", "onClick"]) : vue.createVNode(Input, { + "focus": autoFocus, + "style": { + color + }, + "placeholder-style": "color: " + placeholderColor, + "class": "uni-page-head-search-input", + "confirm-type": "search", + "onFocus": onFocus, + "onBlur": onBlur, + "onInput": onInput, + "onConfirm": onConfirm + }, null, 8, ["focus", "style", "placeholder-style", "onFocus", "onBlur", "onInput", "onConfirm"])], 4); +} +function onPageHeadBackButton() { + if (getCurrentPages().length === 1) { + uni.reLaunch({ + url: "/" + }); + } else { + uni.navigateBack({ + from: "backbutton", + success() { + } + // 传入空方法,避免返回Promise,因为onBackPress可能导致fail + }); + } +} +function usePageHead(navigationBar) { + const clazz2 = vue.computed(() => { + const { + type, + titlePenetrate, + shadowColorType + } = navigationBar; + const clazz3 = { + "uni-page-head": true, + "uni-page-head-transparent": type === "transparent", + "uni-page-head-titlePenetrate": titlePenetrate === "YES", + "uni-page-head-shadow": !!shadowColorType + }; + if (shadowColorType) { + clazz3[`uni-page-head-shadow-${shadowColorType}`] = true; + } + return clazz3; + }); + const style = vue.computed(() => { + const backgroundColor = __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ && navigationBar.type === "transparent" ? usePageHeadTransparentBackgroundColor(navigationBar.backgroundColor) : navigationBar.backgroundColor; + return { + backgroundColor, + color: navigationBar.titleColor, + transitionDuration: navigationBar.duration, + transitionTimingFunction: navigationBar.timingFunc + }; + }); + return { + clazz: clazz2, + style + }; +} +function usePageHeadButtons({ + id, + navigationBar +}) { + const left = []; + const right = []; + const { + buttons + } = navigationBar; + if (shared.isArray(buttons)) { + const { + type + } = navigationBar; + const isTransparent = type === "transparent"; + const fonts = /* @__PURE__ */ Object.create(null); + buttons.forEach((btn, index2) => { + if (btn.fontSrc && !btn.fontFamily) { + const fontSrc = getRealPath(btn.fontSrc); + let fontFamily = fonts[fontSrc]; + if (!fontFamily) { + fontFamily = `font${Date.now()}`; + fonts[fontSrc] = fontFamily; + } + btn.fontFamily = fontFamily; + } + const pageHeadBtn = usePageHeadButton(id, index2, btn, isTransparent); + if (btn.float === "left") { + left.push(pageHeadBtn); + } else { + right.push(pageHeadBtn); + } + }); + } + return { + left, + right + }; +} +function usePageHeadButton(pageId, index2, btn, isTransparent) { + const iconStyle = { + color: btn.color, + fontSize: btn.fontSize, + fontWeight: btn.fontWeight + }; + if (btn.fontFamily) { + iconStyle.fontFamily = btn.fontFamily; + } + return new Proxy({ + btnClass: { + // 类似这样的大量重复的字符串,会在gzip时压缩大小,无需在代码层考虑优化相同字符串 + "uni-page-head-btn": true, + "uni-page-head-btn-red-dot": !!(btn.redDot || btn.badgeText), + "uni-page-head-btn-select": !!btn.select + }, + btnStyle: { + backgroundColor: isTransparent ? btn.background : "transparent", + width: btn.width + }, + btnText: "", + btnIconPath: ICON_PATHS[btn.type], + badgeText: btn.badgeText, + iconStyle, + onClick() { + invokeHook(pageId, uniShared.ON_NAVIGATION_BAR_BUTTON_TAP, shared.extend({ + index: index2 + }, btn)); + }, + btnSelect: btn.select + }, { + get(target, key, receiver) { + if (["btnText"].includes(key)) { + return btn.fontSrc && btn.fontFamily ? btn.text.replace("\\u", "&#x") : btn.text; + } else { + return Reflect.get(target, key, receiver); + } + } + }); +} +function usePageHeadSearchInput({ + id, + navigationBar: { + searchInput + } +}) { + const focus = vue.ref(false); + const text = vue.ref(""); + const composing = vue.ref(false); + const { + disabled + } = searchInput; + if (disabled) { + const onClick = () => { + invokeHook(id, uniShared.ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED); + }; + return { + focus, + text, + composing, + onClick + }; + } + const onFocus = () => { + focus.value = true; + invokeHook(id, uniShared.ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, { + focus: true + }); + }; + const onBlur = () => { + focus.value = false; + invokeHook(id, uniShared.ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, { + focus: false + }); + }; + const onInput = (evt) => { + text.value = evt.detail.value; + invokeHook(id, uniShared.ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, { + text: text.value + }); + }; + const onConfirm = (evt) => { + invokeHook(id, uniShared.ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, { + text: text.value + }); + }; + return { + focus, + text, + composing, + onFocus, + onBlur, + onInput, + onConfirm + }; +} +const _sfc_main = { + name: "PageRefresh", + setup() { + const { pullToRefresh } = usePageMeta(); + return { + offset: pullToRefresh.offset, + color: pullToRefresh.color + }; + } +}; +const _export_sfc = (sfc, props2) => { + const target = sfc.__vccOpts || sfc; + for (const [key, val] of props2) { + target[key] = val; + } + return target; +}; +const _hoisted_1 = { class: "uni-page-refresh-inner" }; +const _hoisted_2 = ["fill"]; +const _hoisted_3 = /* @__PURE__ */ vue.createElementVNode("path", { d: "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" }, null, -1); +const _hoisted_4 = /* @__PURE__ */ vue.createElementVNode("path", { + d: "M0 0h24v24H0z", + fill: "none" +}, null, -1); +const _hoisted_5 = [ + _hoisted_3, + _hoisted_4 +]; +const _hoisted_6 = { + class: "uni-page-refresh__spinner", + width: "24", + height: "24", + viewBox: "25 25 50 50" +}; +const _hoisted_7 = ["stroke"]; +function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { + return vue.openBlock(), vue.createElementBlock("uni-page-refresh", null, [ + vue.createElementVNode("div", { + style: vue.normalizeStyle({ "margin-top": $setup.offset + "px" }), + class: "uni-page-refresh" + }, [ + vue.createElementVNode("div", _hoisted_1, [ + (vue.openBlock(), vue.createElementBlock("svg", { + fill: $setup.color, + class: "uni-page-refresh__icon", + width: "24", + height: "24", + viewBox: "0 0 24 24" + }, _hoisted_5, 8, _hoisted_2)), + (vue.openBlock(), vue.createElementBlock("svg", _hoisted_6, [ + vue.createElementVNode("circle", { + stroke: $setup.color, + class: "uni-page-refresh__path", + cx: "50", + cy: "50", + r: "20", + fill: "none", + "stroke-width": "4", + "stroke-miterlimit": "10" + }, null, 8, _hoisted_7) + ])) + ]) + ], 4) + ]); +} +const PageRefresh = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); +const PageBody = defineSystemComponent({ + name: "PageBody", + setup(props2, ctx) { + const pageMeta = __UNI_FEATURE_PULL_DOWN_REFRESH__ && usePageMeta(); + const refreshRef = __UNI_FEATURE_PULL_DOWN_REFRESH__ && vue.ref(null); + const pageRefresh = null; + return () => { + const pageRefreshTsx = __UNI_FEATURE_PULL_DOWN_REFRESH__ && createPageRefreshTsx(refreshRef, pageMeta); + return vue.createVNode(vue.Fragment, null, [pageRefreshTsx, vue.createVNode("uni-page-wrapper", pageRefresh, [vue.createVNode("uni-page-body", null, [vue.renderSlot(ctx.slots, "default")])], 16)]); + }; + } +}); +function createPageRefreshTsx(refreshRef, pageMeta) { + if (!__UNI_FEATURE_PULL_DOWN_REFRESH__ || !pageMeta.enablePullDownRefresh) { + return null; + } + return vue.createVNode(PageRefresh, { + "ref": refreshRef + }, null, 512); +} +const index = defineSystemComponent({ + name: "Page", + setup(_props, ctx) { + const pageMeta = providePageMeta(getStateId()); + const navigationBar = pageMeta.navigationBar; + useDocumentTitle(pageMeta); + return () => vue.createVNode( + "uni-page", + { "data-page": pageMeta.route }, + __UNI_FEATURE_NAVIGATIONBAR__ && navigationBar.style !== "custom" ? [vue.createVNode(PageHead), createPageBodyVNode(ctx)] : [createPageBodyVNode(ctx)] + ); + } +}); +function createPageBodyVNode(ctx) { + return vue.openBlock(), vue.createBlock( + PageBody, + { key: 0 }, + { + default: vue.withCtx(() => [vue.renderSlot(ctx.slots, "page")]), + _: 3 + } + ); +} +exports.Ad = index$6; +exports.AdContentPage = index$5; +exports.AdDraw = index$4; +exports.AsyncErrorComponent = AsyncErrorComponent; +exports.AsyncLoadingComponent = AsyncLoadingComponent; +exports.Button = index$A; +exports.Camera = index$3; +exports.Canvas = index$z; +exports.Checkbox = index$x; +exports.CheckboxGroup = index$y; +exports.CoverImage = index$8; +exports.CoverView = index$9; +exports.Editor = index$w; +exports.Form = index$C; +exports.Icon = index$v; +exports.Image = index$u; +exports.Input = Input; +exports.Label = index$B; +exports.LayoutComponent = LayoutComponent; +exports.LivePlayer = index$2; +exports.LivePusher = index$1; +exports.Map = index$a; +exports.MovableArea = index$t; +exports.MovableView = index$s; +exports.Navigator = index$r; +exports.PageComponent = index; +exports.Picker = index$7; +exports.PickerView = PickerView; +exports.PickerViewColumn = PickerViewColumn; +exports.Progress = index$q; +exports.Radio = index$o; +exports.RadioGroup = index$p; +exports.ResizeSensor = ResizeSensor; +exports.RichText = index$n; +exports.ScrollView = index$m; +exports.Slider = index$l; +exports.Swiper = index$k; +exports.SwiperItem = index$j; +exports.Switch = index$i; +exports.Text = index$h; +exports.Textarea = index$g; +exports.UniServiceJSBridge = UniServiceJSBridge$1; +exports.UniViewJSBridge = UniViewJSBridge$1; +exports.Video = index$c; +exports.View = index$f; +exports.WebView = index$b; +exports.clearStorage = clearStorage; +exports.clearStorageSync = clearStorageSync; +exports.getApp = getApp$1; +exports.getAppBaseInfo = getAppBaseInfo; +exports.getCurrentPages = getCurrentPages$1; +exports.getDeviceInfo = getDeviceInfo; +exports.getRealPath = getRealPath; +exports.getStorage = getStorage; +exports.getStorageInfo = getStorageInfo; +exports.getStorageInfoSync = getStorageInfoSync; +exports.getStorageSync = getStorageSync; +exports.getSystemInfoSync = getSystemInfoSync; +exports.plugin = index$d; +exports.removeStorage = removeStorage; +exports.removeStorageSync = removeStorageSync; +exports.request = request; +exports.setNavigationBarTitle = setNavigationBarTitle; +exports.setStorage = setStorage; +exports.setStorageSync = setStorageSync; +exports.setupApp = setupApp; +exports.setupPage = setupPage; +exports.setupWindow = setupWindow; +exports.uni = uni$1; +exports.useI18n = useI18n; +exports.useTabBar = useTabBar; diff --git a/packages/uni-mp-weibo/dist/uni-mp-weibo.es.js b/packages/uni-mp-weibo/dist/uni-mp-weibo.es.js new file mode 100644 index 00000000000..ca10f3414eb --- /dev/null +++ b/packages/uni-mp-weibo/dist/uni-mp-weibo.es.js @@ -0,0 +1,25535 @@ +import { withModifiers, createVNode, getCurrentInstance, ref, defineComponent, openBlock, createElementBlock, provide, computed, watch, onUnmounted, inject, onBeforeUnmount, mergeProps, injectHook, reactive, onActivated, onMounted, nextTick, onBeforeMount, withDirectives, vModelDynamic, vShow, shallowRef, watchEffect, isVNode, Fragment, markRaw, Comment, h, createTextVNode, createBlock, onBeforeActivate, onBeforeDeactivate, renderList, onDeactivated, createApp, Transition, effectScope, withCtx, KeepAlive, resolveDynamicComponent, createElementVNode, normalizeStyle, renderSlot } from "vue"; +import { isArray, isString, extend, remove, stringifyStyle, parseStringStyle, isPlainObject, isFunction, capitalize, camelize, hasOwn, isObject, toRawType, makeMap as makeMap$1, isPromise, hyphenate, invokeArrayFns as invokeArrayFns$1 } from "@vue/shared"; +import { once, UNI_STORAGE_LOCALE, I18N_JSON_DELIMITERS, Emitter, passive, initCustomDatasetOnce, resolveComponentInstance, normalizeStyles, addLeadingSlash, invokeArrayFns, removeLeadingSlash, resolveOwnerVm, resolveOwnerEl, ON_WXS_INVOKE_CALL_METHOD, normalizeTarget, ON_RESIZE, ON_APP_ENTER_FOREGROUND, ON_APP_ENTER_BACKGROUND, ON_SHOW, ON_HIDE, ON_PAGE_SCROLL, ON_REACH_BOTTOM, EventChannel, SCHEME_RE, DATA_RE, getCustomDataset, LINEFEED, ON_ERROR, callOptions, ON_UNHANDLE_REJECTION, ON_PAGE_NOT_FOUND, PRIMARY_COLOR, getLen, debounce, isUniLifecycleHook, ON_LOAD, UniLifecycleHooks, invokeCreateErrorHandler, invokeCreateVueAppHook, parseQuery, NAVBAR_HEIGHT, ON_UNLOAD, ON_REACH_BOTTOM_DISTANCE, decodedQuery, WEB_INVOKE_APPSERVICE, ON_WEB_INVOKE_APP_SERVICE, ON_THEME_CHANGE, updateElementStyle, sortObject, OFF_THEME_CHANGE, ON_BACK_PRESS, parseUrl, addFont, ON_NAVIGATION_BAR_CHANGE, scrollTo, RESPONSIVE_MIN_WIDTH, onCreateVueApp, formatDateTime, ON_NAVIGATION_BAR_BUTTON_TAP, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, ON_PULL_DOWN_REFRESH } from "@dcloudio/uni-shared"; +import { onCreateVueApp as onCreateVueApp2 } from "@dcloudio/uni-shared"; +import { initVueI18n, isI18nStr, LOCALE_EN, LOCALE_ES, LOCALE_FR, LOCALE_ZH_HANS, LOCALE_ZH_HANT } from "@dcloudio/uni-i18n"; +import { useRoute, createRouter, createWebHistory, createWebHashHistory, useRouter, isNavigationFailure, RouterView } from "vue-router"; +const isEnableLocale = /* @__PURE__ */ once( + () => typeof __uniConfig !== "undefined" && __uniConfig.locales && !!Object.keys(__uniConfig.locales).length +); +let i18n; +function getLocaleMessage() { + const locale = uni.getLocale(); + const locales = __uniConfig.locales; + return locales[locale] || locales[__uniConfig.fallbackLocale] || locales.en || {}; +} +function formatI18n(message) { + if (isI18nStr(message, I18N_JSON_DELIMITERS)) { + return useI18n().f(message, getLocaleMessage(), I18N_JSON_DELIMITERS); + } + return message; +} +function resolveJsonObj(jsonObj, names) { + if (names.length === 1) { + if (jsonObj) { + const _isI18nStr = (value2) => isString(value2) && isI18nStr(value2, I18N_JSON_DELIMITERS); + const _name = names[0]; + let filterJsonObj = []; + if (isArray(jsonObj) && (filterJsonObj = jsonObj.filter((item) => _isI18nStr(item[_name]))).length) { + return filterJsonObj; + } + const value = jsonObj[names[0]]; + if (_isI18nStr(value)) { + return jsonObj; + } + } + return; + } + const name = names.shift(); + return resolveJsonObj(jsonObj && jsonObj[name], names); +} +function defineI18nProperties(obj, names) { + return names.map((name) => defineI18nProperty(obj, name)); +} +function defineI18nProperty(obj, names) { + const jsonObj = resolveJsonObj(obj, names); + if (!jsonObj) { + return false; + } + const prop = names[names.length - 1]; + if (isArray(jsonObj)) { + jsonObj.forEach((item) => defineI18nProperty(item, [prop])); + } else { + let value = jsonObj[prop]; + Object.defineProperty(jsonObj, prop, { + get() { + return formatI18n(value); + }, + set(v2) { + value = v2; + } + }); + } + return true; +} +function useI18n() { + if (!i18n) { + let locale; + { + { + locale = navigator.cookieEnabled && window.localStorage && localStorage[UNI_STORAGE_LOCALE] || __uniConfig.locale || navigator.language; + } + } + i18n = initVueI18n(locale); + if (isEnableLocale()) { + const localeKeys = Object.keys(__uniConfig.locales || {}); + if (localeKeys.length) { + localeKeys.forEach( + (locale2) => i18n.add(locale2, __uniConfig.locales[locale2]) + ); + } + i18n.setLocale(locale); + } + } + return i18n; +} +function normalizeMessages(module, keys, values) { + return keys.reduce((res, name, index2) => { + res[module + name] = values[index2]; + return res; + }, {}); +} +const initI18nAsyncMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.async."; + const keys = ["error"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, [ + "The connection timed out, click the screen to try again." + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, [ + "Se agotó el tiempo de conexión, haga clic en la pantalla para volver a intentarlo." + ]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, [ + "La connexion a expiré, cliquez sur l'écran pour réessayer." + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["连接服务器超时,点击屏幕重试"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["連接服務器超時,點擊屏幕重試"]), + false + ); + } +}); +const initI18nShowActionSheetMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.showActionSheet."; + const keys = ["cancel"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ["Cancel"]), false); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ["Cancelar"]), false); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ["Annuler"]), false); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["取消"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["取消"]), + false + ); + } +}); +const initI18nShowToastMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.showToast."; + const keys = ["unpaired"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, [ + "Please note showToast must be paired with hideToast" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, [ + "Tenga en cuenta que showToast debe estar emparejado con hideToast" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, [ + "Veuillez noter que showToast doit être associé à hideToast" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, [ + "请注意 showToast 与 hideToast 必须配对使用" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, [ + "請注意 showToast 與 hideToast 必須配對使用" + ]), + false + ); + } +}); +const initI18nShowLoadingMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.showLoading."; + const keys = ["unpaired"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, [ + "Please note showLoading must be paired with hideLoading" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, [ + "Tenga en cuenta que showLoading debe estar emparejado con hideLoading" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, [ + "Veuillez noter que showLoading doit être associé à hideLoading" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, [ + "请注意 showLoading 与 hideLoading 必须配对使用" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, [ + "請注意 showLoading 與 hideLoading 必須配對使用" + ]), + false + ); + } +}); +const initI18nShowModalMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.showModal."; + const keys = ["cancel", "confirm"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, ["Cancel", "OK"]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, ["Cancelar", "OK"]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, ["Annuler", "OK"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["取消", "确定"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["取消", "確定"]), + false + ); + } +}); +const initI18nChooseFileMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.chooseFile."; + const keys = ["notUserActivation"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, [ + "File chooser dialog can only be shown with a user activation" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, [ + "El cuadro de diálogo del selector de archivos solo se puede mostrar con la activación del usuario" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, [ + "La boîte de dialogue du sélecteur de fichier ne peut être affichée qu'avec une activation par l'utilisateur" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["文件选择器对话框只能在由用户激活时显示"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["文件選擇器對話框只能在由用戶激活時顯示"]), + false + ); + } +}); +const initI18nSetClipboardDataMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.setClipboardData."; + const keys = ["success", "fail"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, [ + "Content copied", + "Copy failed, please copy manually" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, [ + "Contenido copiado", + "Error al copiar, copie manualmente" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, [ + "Contenu copié", + "Échec de la copie, copiez manuellement" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["内容已复制", "复制失败,请手动复制"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["內容已復制", "復制失敗,請手動復製"]), + false + ); + } +}); +const initI18nGetClipboardDataMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.getClipboardData."; + const keys = ["fail"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, ["Reading failed, please paste manually"]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, ["Error de lectura, pegue manualmente"]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, [ + "Échec de la lecture, veuillez coller manuellement" + ]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["读取失败,请手动粘贴"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["讀取失敗,請手動粘貼"]), + false + ); + } +}); +const initI18nPickerMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.picker."; + const keys = ["done", "cancel"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, ["Done", "Cancel"]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, ["OK", "Cancelar"]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, ["OK", "Annuler"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["完成", "取消"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["完成", "取消"]), + false + ); + } +}); +const initI18nVideoMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.video."; + const keys = ["danmu", "volume"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, ["Danmu", "Volume"]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, ["Danmu", "Volumen"]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, ["Danmu", "Le Volume"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["弹幕", "音量"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["彈幕", "音量"]), + false + ); + } +}); +const initI18nChooseLocationMsgsOnce = /* @__PURE__ */ once(() => { + const name = "uni.chooseLocation."; + const keys = ["search", "cancel"]; + if (__UNI_FEATURE_I18N_EN__) { + useI18n().add( + LOCALE_EN, + normalizeMessages(name, keys, ["Find Place", "Cancel"]), + false + ); + } + if (__UNI_FEATURE_I18N_ES__) { + useI18n().add( + LOCALE_ES, + normalizeMessages(name, keys, ["Encontrar", "Cancelar"]), + false + ); + } + if (__UNI_FEATURE_I18N_FR__) { + useI18n().add( + LOCALE_FR, + normalizeMessages(name, keys, ["Trouve", "Annuler"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANS__) { + useI18n().add( + LOCALE_ZH_HANS, + normalizeMessages(name, keys, ["搜索地点", "取消"]), + false + ); + } + if (__UNI_FEATURE_I18N_ZH_HANT__) { + useI18n().add( + LOCALE_ZH_HANT, + normalizeMessages(name, keys, ["搜索地點", "取消"]), + false + ); + } +}); +function initNavigationBarI18n(navigationBar) { + if (isEnableLocale()) { + return defineI18nProperties(navigationBar, [ + ["titleText"], + ["searchInput", "placeholder"], + ["buttons", "text"] + ]); + } +} +function initTabBarI18n(tabBar2) { + if (isEnableLocale() && tabBar2.list) { + tabBar2.list.forEach((item) => { + defineI18nProperty(item, ["text"]); + }); + } + return tabBar2; +} +function initBridge(subscribeNamespace) { + const emitter2 = new Emitter(); + return { + on(event, callback) { + return emitter2.on(event, callback); + }, + once(event, callback) { + return emitter2.once(event, callback); + }, + off(event, callback) { + return emitter2.off(event, callback); + }, + emit(event, ...args) { + return emitter2.emit(event, ...args); + }, + subscribe(event, callback, once2 = false) { + emitter2[once2 ? "once" : "on"](`${subscribeNamespace}.${event}`, callback); + }, + unsubscribe(event, callback) { + emitter2.off(`${subscribeNamespace}.${event}`, callback); + }, + subscribeHandler(event, args, pageId) { + emitter2.emit(`${subscribeNamespace}.${event}`, args, pageId); + } + }; +} +const INVOKE_VIEW_API = "invokeViewApi"; +const INVOKE_SERVICE_API = "invokeServiceApi"; +let invokeServiceMethodId = 1; +const invokeServiceMethod = (name, args, callback) => { + const { subscribe, publishHandler } = UniViewJSBridge; + const id2 = callback ? invokeServiceMethodId++ : 0; + callback && subscribe(INVOKE_SERVICE_API + "." + id2, callback, true); + publishHandler(INVOKE_SERVICE_API, { id: id2, name, args }); +}; +const viewMethods = /* @__PURE__ */ Object.create(null); +function normalizeViewMethodName(pageId, name) { + return pageId + "." + name; +} +function subscribeViewMethod(pageId, wrapper2) { + UniViewJSBridge.subscribe( + normalizeViewMethodName(pageId, INVOKE_VIEW_API), + wrapper2 ? wrapper2(onInvokeViewMethod) : onInvokeViewMethod + ); +} +function unsubscribeViewMethod(pageId) { + UniViewJSBridge.unsubscribe(normalizeViewMethodName(pageId, INVOKE_VIEW_API)); + Object.keys(viewMethods).forEach((name) => { + if (name.indexOf(pageId + ".") === 0) { + delete viewMethods[name]; + } + }); +} +function registerViewMethod(pageId, name, fn) { + name = normalizeViewMethodName(pageId, name); + if (!viewMethods[name]) { + viewMethods[name] = fn; + } +} +function unregisterViewMethod(pageId, name) { + name = normalizeViewMethodName(pageId, name); + delete viewMethods[name]; +} +function onInvokeViewMethod({ + id: id2, + name, + args +}, pageId) { + name = normalizeViewMethodName(pageId, name); + const publish = (res) => { + id2 && UniViewJSBridge.publishHandler(INVOKE_VIEW_API + "." + id2, res); + }; + const handler = viewMethods[name]; + if (handler) { + handler(args, publish); + } else { + publish({}); + } +} +const ViewJSBridge = /* @__PURE__ */ extend( + /* @__PURE__ */ initBridge("service"), + { + invokeServiceMethod + } +); +const LONGPRESS_TIMEOUT = 350; +const LONGPRESS_THRESHOLD = 10; +const passiveOptions$2 = /* @__PURE__ */ passive(true); +let longPressTimer; +function clearLongPressTimer() { + if (longPressTimer) { + clearTimeout(longPressTimer); + longPressTimer = null; + } +} +let startPageX = 0; +let startPageY = 0; +function touchstart(evt) { + clearLongPressTimer(); + if (evt.touches.length !== 1) { + return; + } + const { pageX, pageY } = evt.touches[0]; + startPageX = pageX; + startPageY = pageY; + longPressTimer = setTimeout(function() { + const customEvent = new CustomEvent("longpress", { + bubbles: true, + cancelable: true, + // @ts-ignore + target: evt.target, + currentTarget: evt.currentTarget + }); + customEvent.touches = evt.touches; + customEvent.changedTouches = evt.changedTouches; + evt.target.dispatchEvent(customEvent); + }, LONGPRESS_TIMEOUT); +} +function touchmove(evt) { + if (!longPressTimer) { + return; + } + if (evt.touches.length !== 1) { + return clearLongPressTimer(); + } + const { pageX, pageY } = evt.touches[0]; + if (Math.abs(pageX - startPageX) > LONGPRESS_THRESHOLD || Math.abs(pageY - startPageY) > LONGPRESS_THRESHOLD) { + return clearLongPressTimer(); + } +} +function initLongPress() { + window.addEventListener("touchstart", touchstart, passiveOptions$2); + window.addEventListener("touchmove", touchmove, passiveOptions$2); + window.addEventListener("touchend", clearLongPressTimer, passiveOptions$2); + window.addEventListener("touchcancel", clearLongPressTimer, passiveOptions$2); +} +function checkValue$1(value, defaultValue) { + const newValue = Number(value); + return isNaN(newValue) ? defaultValue : newValue; +} +function getWindowWidth$1() { + const screenFix = /^Apple/.test(navigator.vendor) && typeof window.orientation === "number"; + const landscape = screenFix && Math.abs(window.orientation) === 90; + var screenWidth = screenFix ? Math[landscape ? "max" : "min"](screen.width, screen.height) : screen.width; + var windowWidth = Math.min( + window.innerWidth, + document.documentElement.clientWidth, + screenWidth + ) || screenWidth; + return windowWidth; +} +function useRem() { + const config = __uniConfig.globalStyle || {}; + const maxWidth2 = checkValue$1(config.rpxCalcMaxDeviceWidth, 960); + const baseWidth2 = checkValue$1(config.rpxCalcBaseDeviceWidth, 375); + function updateRem() { + let width = getWindowWidth$1(); + width = width <= maxWidth2 ? width : baseWidth2; + document.documentElement.style.fontSize = width / 23.4375 + "px"; + } + updateRem(); + document.addEventListener("DOMContentLoaded", updateRem); + window.addEventListener("load", updateRem); + window.addEventListener("resize", updateRem); +} +function initView() { + useRem(); + initCustomDatasetOnce(); + if (__UNI_FEATURE_LONGPRESS__) { + initLongPress(); + } +} +function getDefaultExportFromCjs(x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; +} +var attrs = ["top", "left", "right", "bottom"]; +var inited$1; +var elementComputedStyle = {}; +var support; +function getSupport() { + if (!("CSS" in window) || typeof CSS.supports != "function") { + support = ""; + } else if (CSS.supports("top: env(safe-area-inset-top)")) { + support = "env"; + } else if (CSS.supports("top: constant(safe-area-inset-top)")) { + support = "constant"; + } else { + support = ""; + } + return support; +} +function init() { + support = typeof support === "string" ? support : getSupport(); + if (!support) { + attrs.forEach(function(attr2) { + elementComputedStyle[attr2] = 0; + }); + return; + } + function setStyle(el, style) { + var elStyle = el.style; + Object.keys(style).forEach(function(key) { + var val = style[key]; + elStyle[key] = val; + }); + } + var cbs = []; + function parentReady(callback) { + if (callback) { + cbs.push(callback); + } else { + cbs.forEach(function(cb) { + cb(); + }); + } + } + var passiveEvents = false; + try { + var opts = Object.defineProperty({}, "passive", { + get: function() { + passiveEvents = { passive: true }; + } + }); + window.addEventListener("test", null, opts); + } catch (e2) { + } + function addChild(parent, attr2) { + var a1 = document.createElement("div"); + var a2 = document.createElement("div"); + var a1Children = document.createElement("div"); + var a2Children = document.createElement("div"); + var W = 100; + var MAX = 1e4; + var aStyle = { + position: "absolute", + width: W + "px", + height: "200px", + boxSizing: "border-box", + overflow: "hidden", + paddingBottom: support + "(safe-area-inset-" + attr2 + ")" + }; + setStyle(a1, aStyle); + setStyle(a2, aStyle); + setStyle(a1Children, { + transition: "0s", + animation: "none", + width: "400px", + height: "400px" + }); + setStyle(a2Children, { + transition: "0s", + animation: "none", + width: "250%", + height: "250%" + }); + a1.appendChild(a1Children); + a2.appendChild(a2Children); + parent.appendChild(a1); + parent.appendChild(a2); + parentReady(function() { + a1.scrollTop = a2.scrollTop = MAX; + var a1LastScrollTop = a1.scrollTop; + var a2LastScrollTop = a2.scrollTop; + function onScroll() { + if (this.scrollTop === (this === a1 ? a1LastScrollTop : a2LastScrollTop)) { + return; + } + a1.scrollTop = a2.scrollTop = MAX; + a1LastScrollTop = a1.scrollTop; + a2LastScrollTop = a2.scrollTop; + attrChange(attr2); + } + a1.addEventListener("scroll", onScroll, passiveEvents); + a2.addEventListener("scroll", onScroll, passiveEvents); + }); + var computedStyle = getComputedStyle(a1); + Object.defineProperty(elementComputedStyle, attr2, { + configurable: true, + get: function() { + return parseFloat(computedStyle.paddingBottom); + } + }); + } + var parentDiv = document.createElement("div"); + setStyle(parentDiv, { + position: "absolute", + left: "0", + top: "0", + width: "0", + height: "0", + zIndex: "-1", + overflow: "hidden", + visibility: "hidden" + }); + attrs.forEach(function(key) { + addChild(parentDiv, key); + }); + document.body.appendChild(parentDiv); + parentReady(); + inited$1 = true; +} +function getAttr(attr2) { + if (!inited$1) { + init(); + } + return elementComputedStyle[attr2]; +} +var changeAttrs = []; +function attrChange(attr2) { + if (!changeAttrs.length) { + setTimeout(function() { + var style = {}; + changeAttrs.forEach(function(attr3) { + style[attr3] = elementComputedStyle[attr3]; + }); + changeAttrs.length = 0; + callbacks.forEach(function(callback) { + callback(style); + }); + }, 0); + } + changeAttrs.push(attr2); +} +var callbacks = []; +function onChange(callback) { + if (!getSupport()) { + return; + } + if (!inited$1) { + init(); + } + if (typeof callback === "function") { + callbacks.push(callback); + } +} +function offChange(callback) { + var index2 = callbacks.indexOf(callback); + if (index2 >= 0) { + callbacks.splice(index2, 1); + } +} +var safeAreaInsets = { + get support() { + return (typeof support === "string" ? support : getSupport()).length != 0; + }, + get top() { + return getAttr("top"); + }, + get left() { + return getAttr("left"); + }, + get right() { + return getAttr("right"); + }, + get bottom() { + return getAttr("bottom"); + }, + onChange, + offChange +}; +var out = safeAreaInsets; +const safeAreaInsets$1 = /* @__PURE__ */ getDefaultExportFromCjs(out); +const onEventPrevent = /* @__PURE__ */ withModifiers(() => { +}, ["prevent"]); +const onEventStop = /* @__PURE__ */ withModifiers(() => { +}, ["stop"]); +function getWindowOffsetCssVar(style, name) { + return parseInt((style.getPropertyValue(name).match(/\d+/) || ["0"])[0]); +} +function getWindowTop() { + const style = document.documentElement.style; + const top = getWindowOffsetCssVar(style, "--window-top"); + return top ? top + safeAreaInsets$1.top : 0; +} +function getWindowOffset() { + const style = document.documentElement.style; + const top = getWindowTop(); + const bottom = getWindowOffsetCssVar(style, "--window-bottom"); + const left = getWindowOffsetCssVar(style, "--window-left"); + const right = getWindowOffsetCssVar(style, "--window-right"); + const topWindowHeight = getWindowOffsetCssVar(style, "--top-window-height"); + return { + top, + bottom: bottom ? bottom + safeAreaInsets$1.bottom : 0, + left: left ? left + safeAreaInsets$1.left : 0, + right: right ? right + safeAreaInsets$1.right : 0, + topWindowHeight: topWindowHeight || 0 + }; +} +function updateCssVar(cssVars) { + const style = document.documentElement.style; + Object.keys(cssVars).forEach((name) => { + style.setProperty(name, cssVars[name]); + }); +} +function updatePageCssVar(cssVars) { + return updateCssVar(cssVars); +} +const sheetsMap = /* @__PURE__ */ new Map(); +function updateStyle(id2, content) { + let style = sheetsMap.get(id2); + if (style && !(style instanceof HTMLStyleElement)) { + removeStyle(id2); + style = void 0; + } + if (!style) { + style = document.createElement("style"); + style.setAttribute("type", "text/css"); + style.innerHTML = content; + document.head.appendChild(style); + } else { + style.innerHTML = content; + } + sheetsMap.set(id2, style); +} +function removeStyle(id2) { + let style = sheetsMap.get(id2); + if (style) { + if (style instanceof CSSStyleSheet) { + document.adoptedStyleSheets.indexOf(style); + document.adoptedStyleSheets = document.adoptedStyleSheets.filter( + (s) => s !== style + ); + } else { + document.head.removeChild(style); + } + sheetsMap.delete(id2); + } +} +function PolySymbol(name) { + return Symbol(process.env.NODE_ENV !== "production" ? "[uni-app]: " + name : name); +} +function hasRpx(str) { + str = str + ""; + return str.indexOf("rpx") !== -1 || str.indexOf("upx") !== -1; +} +function rpx2px(str, replace = false) { + if (replace) { + return rpx2pxWithReplace(str); + } + if (isString(str)) { + const res = parseInt(str) || 0; + if (hasRpx(str)) { + return uni.upx2px(res); + } + return res; + } + return str; +} +function rpx2pxWithReplace(str) { + if (!hasRpx(str)) { + return str; + } + return str.replace(/(\d+(\.\d+)?)[ru]px/g, (_a, b) => { + return uni.upx2px(parseFloat(b)) + "px"; + }); +} +const ICON_PATH_CANCEL = "M20.928 10.176l-4.928 4.928-4.928-4.928-0.896 0.896 4.928 4.928-4.928 4.928 0.896 0.896 4.928-4.928 4.928 4.928 0.896-0.896-4.928-4.928 4.928-4.928-0.896-0.896zM16 2.080q-3.776 0-7.040 1.888-3.136 1.856-4.992 4.992-1.888 3.264-1.888 7.040t1.888 7.040q1.856 3.136 4.992 4.992 3.264 1.888 7.040 1.888t7.040-1.888q3.136-1.856 4.992-4.992 1.888-3.264 1.888-7.040t-1.888-7.040q-1.856-3.136-4.992-4.992-3.264-1.888-7.040-1.888zM16 28.64q-3.424 0-6.4-1.728-2.848-1.664-4.512-4.512-1.728-2.976-1.728-6.4t1.728-6.4q1.664-2.848 4.512-4.512 2.976-1.728 6.4-1.728t6.4 1.728q2.848 1.664 4.512 4.512 1.728 2.976 1.728 6.4t-1.728 6.4q-1.664 2.848-4.512 4.512-2.976 1.728-6.4 1.728z"; +const ICON_PATH_CLEAR = "M16 0q-4.352 0-8.064 2.176-3.616 2.144-5.76 5.76-2.176 3.712-2.176 8.064t2.176 8.064q2.144 3.616 5.76 5.76 3.712 2.176 8.064 2.176t8.064-2.176q3.616-2.144 5.76-5.76 2.176-3.712 2.176-8.064t-2.176-8.064q-2.144-3.616-5.76-5.76-3.712-2.176-8.064-2.176zM22.688 21.408q0.32 0.32 0.304 0.752t-0.336 0.736-0.752 0.304-0.752-0.32l-5.184-5.376-5.376 5.184q-0.32 0.32-0.752 0.304t-0.736-0.336-0.304-0.752 0.32-0.752l5.376-5.184-5.184-5.376q-0.32-0.32-0.304-0.752t0.336-0.752 0.752-0.304 0.752 0.336l5.184 5.376 5.376-5.184q0.32-0.32 0.752-0.304t0.752 0.336 0.304 0.752-0.336 0.752l-5.376 5.184 5.184 5.376z"; +const ICON_PATH_DOWNLOAD = "M15.808 1.696q-3.776 0-7.072 1.984-3.2 1.888-5.088 5.152-1.952 3.392-1.952 7.36 0 3.776 1.952 7.072 1.888 3.2 5.088 5.088 3.296 1.952 7.072 1.952 3.968 0 7.36-1.952 3.264-1.888 5.152-5.088 1.984-3.296 1.984-7.072 0-4-1.984-7.36-1.888-3.264-5.152-5.152-3.36-1.984-7.36-1.984zM20.864 18.592l-3.776 4.928q-0.448 0.576-1.088 0.576t-1.088-0.576l-3.776-4.928q-0.448-0.576-0.24-0.992t0.944-0.416h2.976v-8.928q0-0.256 0.176-0.432t0.4-0.176h1.216q0.224 0 0.4 0.176t0.176 0.432v8.928h2.976q0.736 0 0.944 0.416t-0.24 0.992z"; +const ICON_PATH_INFO = "M15.808 0.128q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.176 3.776-2.176 8.16 0 4.224 2.176 7.872 2.080 3.552 5.632 5.632 3.648 2.176 7.872 2.176 4.384 0 8.16-2.176 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.416-2.176-8.16-2.112-3.616-5.728-5.728-3.744-2.176-8.16-2.176zM16.864 23.776q0 0.064-0.064 0.064h-1.568q-0.096 0-0.096-0.064l-0.256-11.328q0-0.064 0.064-0.064h2.112q0.096 0 0.064 0.064l-0.256 11.328zM16 10.88q-0.576 0-0.976-0.4t-0.4-0.96 0.4-0.96 0.976-0.4 0.976 0.4 0.4 0.96-0.4 0.96-0.976 0.4z"; +const ICON_PATH_SEARCH = "M20.928 22.688q-1.696 1.376-3.744 2.112-2.112 0.768-4.384 0.768-3.488 0-6.464-1.728-2.88-1.696-4.576-4.608-1.76-2.976-1.76-6.464t1.76-6.464q1.696-2.88 4.576-4.576 2.976-1.76 6.464-1.76t6.464 1.76q2.912 1.696 4.608 4.576 1.728 2.976 1.728 6.464 0 2.272-0.768 4.384-0.736 2.048-2.112 3.744l9.312 9.28-1.824 1.824-9.28-9.312zM12.8 23.008q2.784 0 5.184-1.376 2.304-1.376 3.68-3.68 1.376-2.4 1.376-5.184t-1.376-5.152q-1.376-2.336-3.68-3.68-2.4-1.408-5.184-1.408t-5.152 1.408q-2.336 1.344-3.68 3.68-1.408 2.368-1.408 5.152t1.408 5.184q1.344 2.304 3.68 3.68 2.368 1.376 5.152 1.376zM12.8 23.008v0z"; +const ICON_PATH_SUCCESS_NO_CIRCLE = "M1.952 18.080q-0.32-0.352-0.416-0.88t0.128-0.976l0.16-0.352q0.224-0.416 0.64-0.528t0.8 0.176l6.496 4.704q0.384 0.288 0.912 0.272t0.88-0.336l17.312-14.272q0.352-0.288 0.848-0.256t0.848 0.352l-0.416-0.416q0.32 0.352 0.32 0.816t-0.32 0.816l-18.656 18.912q-0.32 0.352-0.8 0.352t-0.8-0.32l-7.936-8.064z"; +const ICON_PATH_SUCCESS = "M15.808 0.16q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.144 3.744-2.144 8.128 0 4.192 2.144 7.872 2.112 3.52 5.632 5.632 3.68 2.144 7.872 2.144 4.384 0 8.128-2.144 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.384-2.176-8.128-2.112-3.616-5.728-5.728-3.744-2.176-8.128-2.176zM24.832 11.328l-11.264 11.104q-0.032 0.032-0.112 0.032t-0.112-0.032l-5.216-5.376q-0.096-0.128 0-0.288l0.704-0.96q0.032-0.064 0.112-0.064t0.112 0.032l4.256 3.264q0.064 0.032 0.144 0.032t0.112-0.032l10.336-8.608q0.064-0.064 0.144-0.064t0.112 0.064l0.672 0.672q0.128 0.128 0 0.224z"; +const ICON_PATH_WAITING = "M15.84 0.096q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.144 3.744-2.144 8.128 0 4.192 2.144 7.872 2.112 3.52 5.632 5.632 3.68 2.144 7.872 2.144 4.384 0 8.128-2.144 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.384-2.176-8.128-2.112-3.616-5.728-5.728-3.744-2.176-8.128-2.176zM23.008 21.92l-0.512 0.896q-0.096 0.128-0.224 0.064l-8-3.808q-0.096-0.064-0.16-0.128-0.128-0.096-0.128-0.288l0.512-12.096q0-0.064 0.048-0.112t0.112-0.048h1.376q0.064 0 0.112 0.048t0.048 0.112l0.448 10.848 6.304 4.256q0.064 0.064 0.080 0.128t-0.016 0.128z"; +const ICON_PATH_WARN = "M15.808 0.16q-4.224 0-7.872 2.176-3.552 2.112-5.632 5.728-2.144 3.744-2.144 8.128 0 4.192 2.144 7.872 2.112 3.52 5.632 5.632 3.68 2.144 7.872 2.144 4.384 0 8.128-2.144 3.616-2.080 5.728-5.632 2.176-3.648 2.176-7.872 0-4.384-2.176-8.128-2.112-3.616-5.728-5.728-3.744-2.176-8.128-2.176zM15.136 8.672h1.728q0.128 0 0.224 0.096t0.096 0.256l-0.384 10.24q0 0.064-0.048 0.112t-0.112 0.048h-1.248q-0.096 0-0.144-0.048t-0.048-0.112l-0.384-10.24q0-0.16 0.096-0.256t0.224-0.096zM16 23.328q-0.48 0-0.832-0.352t-0.352-0.848 0.352-0.848 0.832-0.352 0.832 0.352 0.352 0.848-0.352 0.848-0.832 0.352z"; +const ICON_PATH_BACK = "M21.781 7.844l-9.063 8.594 9.063 8.594q0.25 0.25 0.25 0.609t-0.25 0.578q-0.25 0.25-0.578 0.25t-0.578-0.25l-9.625-9.125q-0.156-0.125-0.203-0.297t-0.047-0.359q0-0.156 0.047-0.328t0.203-0.297l9.625-9.125q0.25-0.25 0.578-0.25t0.578 0.25q0.25 0.219 0.25 0.578t-0.25 0.578z"; +const ICON_PATH_CLOSE = "M17.25 16.156l7.375-7.313q0.281-0.281 0.281-0.641t-0.281-0.641q-0.25-0.25-0.625-0.25t-0.625 0.25l-7.375 7.344-7.313-7.344q-0.25-0.25-0.625-0.25t-0.625 0.25q-0.281 0.25-0.281 0.625t0.281 0.625l7.313 7.344-7.375 7.344q-0.281 0.25-0.281 0.625t0.281 0.625q0.125 0.125 0.281 0.188t0.344 0.063q0.156 0 0.328-0.063t0.297-0.188l7.375-7.344 7.375 7.406q0.125 0.156 0.297 0.219t0.328 0.063q0.188 0 0.344-0.078t0.281-0.203q0.281-0.25 0.281-0.609t-0.281-0.641l-7.375-7.406z"; +const ICON_PATH_CONFIRM = "M31.562 4.9966666659375q0.435 0.399 0.435 0.87 0.036 0.58-0.399 0.98l-18.61 19.917q-0.145 0.145-0.327 0.217-0.073 0.037-0.145 0.11-0.254 0.035-0.472 0.035-0.29 0-0.544-0.036l-0.145-0.072q-0.109-0.073-0.217-0.182l-0.11-0.072L0.363 16.2786666659375q-0.327-0.399-0.363-0.907 0-0.544 0.363-1.016 0.435-0.326 0.961-0.362 0.527-0.036 0.962 0.362l9.722 9.542L29.712 5.0326666659375q0.399-0.363 0.943-0.363 0.544-0.036 0.907 0.327z"; +function createSvgIconVNode(path, color = "#000", size = 27) { + return createVNode( + "svg", + { + width: size, + height: size, + viewBox: "0 0 32 32" + }, + [ + createVNode( + "path", + { + d: path, + fill: color + }, + null, + 8, + ["d", "fill"] + ) + ], + 8, + ["width", "height"] + ); +} +function useCurrentPageId() { + { + const { $pageInstance } = getCurrentInstance(); + return $pageInstance && $pageInstance.proxy.$page.id; + } +} +function getPageIdByVm(instance2) { + const vm = resolveComponentInstance(instance2); + if (vm.$page) { + return vm.$page.id; + } + if (!vm.$) { + return; + } + { + const { $pageInstance } = vm.$; + return $pageInstance && $pageInstance.proxy.$page.id; + } +} +function getCurrentPage() { + const pages = getCurrentPages(); + const len = pages.length; + if (len) { + return pages[len - 1]; + } +} +function getCurrentPageMeta() { + const page = getCurrentPage(); + if (page) { + return page.$page.meta; + } +} +function getCurrentPageId() { + const meta = getCurrentPageMeta(); + if (meta) { + return meta.id; + } + return -1; +} +function getCurrentPageVm() { + const page = getCurrentPage(); + if (page) { + return page.$vm; + } +} +const PAGE_META_KEYS = ["navigationBar", "pullToRefresh"]; +function initGlobalStyle() { + return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {})); +} +function initRouteMeta(pageMeta, id2) { + const globalStyle = initGlobalStyle(); + const res = extend({ id: id2 }, globalStyle, pageMeta); + PAGE_META_KEYS.forEach((name) => { + res[name] = extend({}, globalStyle[name], pageMeta[name]); + }); + const { navigationBar } = res; + navigationBar.titleText && navigationBar.titleImage && (navigationBar.titleText = ""); + return res; +} +function normalizePullToRefreshRpx(pullToRefresh) { + if (pullToRefresh.offset) { + pullToRefresh.offset = rpx2px(pullToRefresh.offset); + } + if (pullToRefresh.height) { + pullToRefresh.height = rpx2px(pullToRefresh.height); + } + if (pullToRefresh.range) { + pullToRefresh.range = rpx2px(pullToRefresh.range); + } + return pullToRefresh; +} +function initPageInternalInstance(openType, url, pageQuery, meta, eventChannel, themeMode) { + const { id: id2, route } = meta; + const titleColor = normalizeStyles( + meta.navigationBar, + __uniConfig.themeConfig, + themeMode + ).titleColor; + return { + id: id2, + path: addLeadingSlash(route), + route, + fullPath: url, + options: pageQuery, + meta, + openType, + eventChannel, + statusBarStyle: titleColor === "#ffffff" ? "light" : "dark" + }; +} +function removeHook(vm, name, hook) { + const hooks = vm.$[name]; + if (!isArray(hooks)) { + return; + } + if (hook.__weh) { + remove(hooks, hook.__weh); + } +} +function invokeHook(vm, name, args) { + if (isString(vm)) { + args = name; + name = vm; + vm = getCurrentPageVm(); + } else if (typeof vm === "number") { + const page = getCurrentPages().find((page2) => page2.$page.id === vm); + if (page) { + vm = page.$vm; + } else { + vm = getCurrentPageVm(); + } + } + if (!vm) { + return; + } + const hooks = vm.$[name]; + return hooks && invokeArrayFns(hooks, args); +} +function disableScrollListener(evt) { + evt.preventDefault(); +} +let testReachBottomTimer; +let lastScrollHeight = 0; +function createScrollListener({ + onPageScroll, + onReachBottom, + onReachBottomDistance +}) { + let ticking = false; + let hasReachBottom = false; + let reachBottomLocking = true; + const isReachBottom = () => { + const { scrollHeight } = document.documentElement; + const windowHeight = window.innerHeight; + const scrollY = window.scrollY; + const isBottom = scrollY > 0 && scrollHeight > windowHeight && scrollY + windowHeight + onReachBottomDistance >= scrollHeight; + const heightChanged = Math.abs(scrollHeight - lastScrollHeight) > onReachBottomDistance; + if (isBottom && (!hasReachBottom || heightChanged)) { + lastScrollHeight = scrollHeight; + hasReachBottom = true; + return true; + } + if (!isBottom && hasReachBottom) { + hasReachBottom = false; + } + return false; + }; + const trigger = () => { + onPageScroll && onPageScroll(window.pageYOffset); + function testReachBottom() { + if (isReachBottom()) { + onReachBottom && onReachBottom(); + reachBottomLocking = false; + setTimeout(function() { + reachBottomLocking = true; + }, 350); + return true; + } + } + if (onReachBottom && reachBottomLocking) { + if (testReachBottom()) + ; + else { + testReachBottomTimer = setTimeout(testReachBottom, 300); + } + } + ticking = false; + }; + return function onScroll() { + clearTimeout(testReachBottomTimer); + if (!ticking) { + requestAnimationFrame(trigger); + } + ticking = true; + }; +} +function normalizeRoute(toRoute) { + if (toRoute.indexOf("/") === 0) { + return toRoute; + } + let fromRoute = ""; + const pages = getCurrentPages(); + if (pages.length) { + fromRoute = pages[pages.length - 1].$page.route; + } + return getRealRoute(fromRoute, toRoute); +} +function getRealRoute(fromRoute, toRoute) { + if (toRoute.indexOf("/") === 0) { + return toRoute; + } + if (toRoute.indexOf("./") === 0) { + return getRealRoute(fromRoute, toRoute.slice(2)); + } + const toRouteArray = toRoute.split("/"); + const toRouteLength = toRouteArray.length; + let i = 0; + for (; i < toRouteLength && toRouteArray[i] === ".."; i++) { + } + toRouteArray.splice(0, i); + toRoute = toRouteArray.join("/"); + const fromRouteArray = fromRoute.length > 0 ? fromRoute.split("/") : []; + fromRouteArray.splice(fromRouteArray.length - i - 1, i + 1); + return addLeadingSlash(fromRouteArray.concat(toRouteArray).join("/")); +} +function getRouteOptions(path, alias = false) { + if (alias) { + return __uniRoutes.find( + (route) => route.path === path || route.alias === path + ); + } + return __uniRoutes.find((route) => route.path === path); +} +function normalizeTabBarRoute(index2, oldPagePath, newPagePath) { + const oldTabBarRoute = getRouteOptions(addLeadingSlash(oldPagePath)); + if (oldTabBarRoute) { + const { meta } = oldTabBarRoute; + delete meta.tabBarIndex; + meta.isQuit = meta.isTabBar = false; + } + const newTabBarRoute = getRouteOptions(addLeadingSlash(newPagePath)); + if (newTabBarRoute) { + const { meta } = newTabBarRoute; + meta.tabBarIndex = index2; + meta.isQuit = meta.isTabBar = true; + const tabBar2 = __uniConfig.tabBar; + if (tabBar2 && tabBar2.list && tabBar2.list[index2]) { + tabBar2.list[index2].pagePath = removeLeadingSlash(newPagePath); + } + } +} +class ComponentDescriptor { + constructor(vm) { + this.$bindClass = false; + this.$bindStyle = false; + this.$vm = vm; + { + this.$el = resolveOwnerEl(vm.$); + } + if (this.$el.getAttribute) { + this.$bindClass = !!this.$el.getAttribute("class"); + this.$bindStyle = !!this.$el.getAttribute("style"); + } + } + selectComponent(selector) { + if (!this.$el || !selector) { + return; + } + const wxsVm = getWxsVm(this.$el.querySelector(selector)); + if (!wxsVm) { + return; + } + return createComponentDescriptor(wxsVm, false); + } + selectAllComponents(selector) { + if (!this.$el || !selector) { + return []; + } + const descriptors = []; + const els = this.$el.querySelectorAll(selector); + for (let i = 0; i < els.length; i++) { + const wxsVm = getWxsVm(els[i]); + if (wxsVm) { + descriptors.push(createComponentDescriptor(wxsVm, false)); + } + } + return descriptors; + } + forceUpdate(type) { + if (type === "class") { + if (this.$bindClass) { + this.$el.__wxsClassChanged = true; + this.$vm.$forceUpdate(); + } else { + this.updateWxsClass(); + } + } else if (type === "style") { + if (this.$bindStyle) { + this.$el.__wxsStyleChanged = true; + this.$vm.$forceUpdate(); + } else { + this.updateWxsStyle(); + } + } + } + updateWxsClass() { + const { __wxsAddClass } = this.$el; + if (__wxsAddClass.length) { + this.$el.className = __wxsAddClass.join(" "); + } + } + updateWxsStyle() { + const { __wxsStyle } = this.$el; + if (__wxsStyle) { + this.$el.setAttribute("style", stringifyStyle(__wxsStyle)); + } + } + setStyle(style) { + if (!this.$el || !style) { + return this; + } + if (isString(style)) { + style = parseStringStyle(style); + } + if (isPlainObject(style)) { + this.$el.__wxsStyle = style; + this.forceUpdate("style"); + } + return this; + } + addClass(clazz2) { + if (!this.$el || !clazz2) { + return this; + } + const __wxsAddClass = this.$el.__wxsAddClass || (this.$el.__wxsAddClass = []); + if (__wxsAddClass.indexOf(clazz2) === -1) { + __wxsAddClass.push(clazz2); + this.forceUpdate("class"); + } + return this; + } + removeClass(clazz2) { + if (!this.$el || !clazz2) { + return this; + } + const { __wxsAddClass } = this.$el; + if (__wxsAddClass) { + const index2 = __wxsAddClass.indexOf(clazz2); + if (index2 > -1) { + __wxsAddClass.splice(index2, 1); + } + } + const __wxsRemoveClass = this.$el.__wxsRemoveClass || (this.$el.__wxsRemoveClass = []); + if (__wxsRemoveClass.indexOf(clazz2) === -1) { + __wxsRemoveClass.push(clazz2); + this.forceUpdate("class"); + } + return this; + } + hasClass(cls) { + return this.$el && this.$el.classList.contains(cls); + } + getDataset() { + return this.$el && this.$el.dataset; + } + callMethod(funcName, args = {}) { + const func = this.$vm[funcName]; + if (isFunction(func)) { + func(JSON.parse(JSON.stringify(args))); + } else if (this.$vm.ownerId) { + UniViewJSBridge.publishHandler(ON_WXS_INVOKE_CALL_METHOD, { + nodeId: this.$el.__id, + ownerId: this.$vm.ownerId, + method: funcName, + args + }); + } + } + requestAnimationFrame(callback) { + return window.requestAnimationFrame(callback); + } + getState() { + return this.$el && (this.$el.__wxsState || (this.$el.__wxsState = {})); + } + triggerEvent(eventName, detail = {}) { + return this.$vm.$emit(eventName, detail), this; + } + getComputedStyle(names) { + if (this.$el) { + const styles = window.getComputedStyle(this.$el); + if (names && names.length) { + return names.reduce((res, n) => { + res[n] = styles[n]; + return res; + }, {}); + } + return styles; + } + return {}; + } + setTimeout(handler, timeout) { + return window.setTimeout(handler, timeout); + } + clearTimeout(handle) { + return window.clearTimeout(handle); + } + getBoundingClientRect() { + return this.$el.getBoundingClientRect(); + } +} +function createComponentDescriptor(vm, isOwnerInstance = true) { + { + if (isOwnerInstance && vm) { + vm = resolveOwnerVm(vm.$); + } + } + if (vm && vm.$el) { + if (!vm.$el.__wxsComponentDescriptor) { + vm.$el.__wxsComponentDescriptor = new ComponentDescriptor(vm); + } + return vm.$el.__wxsComponentDescriptor; + } +} +function getComponentDescriptor(instance2, isOwnerInstance) { + return createComponentDescriptor(instance2, isOwnerInstance); +} +function resolveOwnerComponentPublicInstance(eventValue, instance2, checkArgsLength = true) { + if (!instance2) { + return false; + } + if (checkArgsLength && eventValue.length < 2) { + return false; + } + const ownerVm = resolveOwnerVm(instance2); + if (!ownerVm) { + return false; + } + const type = ownerVm.$.type; + if (!type.$wxs && !type.$renderjs) { + return false; + } + return ownerVm; +} +function wrapperH5WxsEvent(event, eventValue, instance2, checkArgsLength = true) { + if (eventValue) { + if (!event.__instance) { + event.__instance = true; + Object.defineProperty(event, "instance", { + get() { + return getComponentDescriptor(instance2.proxy, false); + } + }); + } + const ownerVm = resolveOwnerComponentPublicInstance( + eventValue, + instance2, + checkArgsLength + ); + if (ownerVm) { + return [event, getComponentDescriptor(ownerVm, false)]; + } + } +} +function getWxsVm(el) { + if (!el) { + return; + } + { + return el.__vueParentComponent && el.__vueParentComponent.proxy; + } +} +const isKeyboardEvent = (val) => !val.type.indexOf("key") && val instanceof KeyboardEvent; +const isClickEvent = (val) => val.type === "click"; +const isMouseEvent = (val) => val.type.indexOf("mouse") === 0 || ["contextmenu"].includes(val.type); +const isTouchEvent = (val) => typeof TouchEvent !== "undefined" && val instanceof TouchEvent || val.type.indexOf("touch") === 0 || ["longpress"].indexOf(val.type) >= 0; +function $nne(evt, eventValue, instance2) { + const { currentTarget } = evt; + if (!(evt instanceof Event) || !(currentTarget instanceof HTMLElement)) { + return [evt]; + } + const isHTMLTarget = currentTarget.tagName.indexOf("UNI-") !== 0; + { + if (isHTMLTarget) { + return wrapperH5WxsEvent( + evt, + eventValue, + instance2, + false + // 原生标签事件可能被cache,参数长度不准确,故默认不校验 + ) || [evt]; + } + } + const res = createNativeEvent(evt, isHTMLTarget); + if (isClickEvent(evt)) { + normalizeClickEvent(res, evt); + } else if (isMouseEvent(evt)) { + normalizeMouseEvent(res, evt); + } else if (isTouchEvent(evt)) { + const top = getWindowTop(); + res.touches = normalizeTouchEvent(evt.touches, top); + res.changedTouches = normalizeTouchEvent(evt.changedTouches, top); + } else if (isKeyboardEvent(evt)) { + const proxyKeys = ["key", "code"]; + proxyKeys.forEach((key) => { + Object.defineProperty(res, key, { + get() { + return evt[key]; + } + }); + }); + } + { + return wrapperH5WxsEvent( + res, + eventValue, + instance2 + ) || [res]; + } +} +function findUniTarget(target) { + while (target && target.tagName.indexOf("UNI-") !== 0) { + target = target.parentElement; + } + return target; +} +function createNativeEvent(evt, htmlElement = false) { + const { type, timeStamp, target, currentTarget } = evt; + const event = { + type, + timeStamp, + target: normalizeTarget( + htmlElement ? target : findUniTarget(target) + ), + detail: {}, + currentTarget: normalizeTarget(currentTarget) + }; + if (evt._stopped) { + event._stopped = true; + } + if (evt.type.startsWith("touch")) { + event.touches = evt.touches; + event.changedTouches = evt.changedTouches; + } + { + wrapperEvent(event, evt); + } + return event; +} +function wrapperEvent(event, evt) { + extend(event, { + preventDefault() { + return evt.preventDefault(); + }, + stopPropagation() { + return evt.stopPropagation(); + } + }); +} +function normalizeClickEvent(evt, mouseEvt) { + const { x, y } = mouseEvt; + const top = getWindowTop(); + evt.detail = { x, y: y - top }; + evt.touches = evt.changedTouches = [createTouchEvent(mouseEvt, top)]; +} +function normalizeMouseEvent(evt, mouseEvt) { + const top = getWindowTop(); + evt.pageX = mouseEvt.pageX; + evt.pageY = mouseEvt.pageY - top; + evt.clientX = mouseEvt.clientX; + evt.clientY = mouseEvt.clientY - top; + evt.touches = evt.changedTouches = [createTouchEvent(mouseEvt, top)]; +} +function createTouchEvent(evt, top) { + return { + force: 1, + identifier: 0, + clientX: evt.clientX, + clientY: evt.clientY - top, + pageX: evt.pageX, + pageY: evt.pageY - top + }; +} +function normalizeTouchEvent(touches, top) { + const res = []; + for (let i = 0; i < touches.length; i++) { + const { identifier, pageX, pageY, clientX, clientY, force } = touches[i]; + res.push({ + identifier, + pageX, + pageY: pageY - top, + clientX, + clientY: clientY - top, + force: force || 0 + }); + } + return res; +} +const instance = /* @__PURE__ */ Object.defineProperty({ + __proto__: null, + $nne, + createNativeEvent +}, Symbol.toStringTag, { value: "Module" }); +function initAppConfig$1(appConfig) { + const globalProperties = appConfig.globalProperties; + extend(globalProperties, instance); + if (__UNI_FEATURE_WXS__) { + globalProperties.$gcd = getComponentDescriptor; + } +} +function initViewPlugin(app) { + initAppConfig$1(app._context.config); +} +const invokeOnCallback = (name, res) => UniServiceJSBridge.emit("api." + name, res); +let invokeViewMethodId = 1; +function publishViewMethodName(pageId) { + return (pageId || getCurrentPageId()) + "." + INVOKE_VIEW_API; +} +const invokeViewMethod = (name, args, pageId, callback) => { + const { subscribe, publishHandler } = UniServiceJSBridge; + const id2 = callback ? invokeViewMethodId++ : 0; + callback && subscribe(INVOKE_VIEW_API + "." + id2, callback, true); + publishHandler(publishViewMethodName(pageId), { id: id2, name, args }, pageId); +}; +const invokeViewMethodKeepAlive = (name, args, callback, pageId) => { + const { subscribe, unsubscribe, publishHandler } = UniServiceJSBridge; + const id2 = invokeViewMethodId++; + const subscribeName = INVOKE_VIEW_API + "." + id2; + subscribe(subscribeName, callback); + publishHandler(publishViewMethodName(pageId), { id: id2, name, args }, pageId); + return () => { + unsubscribe(subscribeName); + }; +}; +const ServiceJSBridge = /* @__PURE__ */ extend( + /* @__PURE__ */ initBridge( + "view" + /* view 指的是 service 层订阅的是 view 层事件 */ + ), + { + invokeOnCallback, + invokeViewMethod, + invokeViewMethodKeepAlive + } +); +function initOn() { + const { on: on2 } = UniServiceJSBridge; + on2(ON_RESIZE, onResize$1); + on2(ON_APP_ENTER_FOREGROUND, onAppEnterForeground); + on2(ON_APP_ENTER_BACKGROUND, onAppEnterBackground); +} +function onResize$1(res) { + invokeHook(getCurrentPage(), ON_RESIZE, res); + UniServiceJSBridge.invokeOnCallback("onWindowResize", res); +} +function onAppEnterForeground(enterOptions2) { + const page = getCurrentPage(); + invokeHook(getApp(), ON_SHOW, enterOptions2); + invokeHook(page, ON_SHOW); +} +function onAppEnterBackground() { + invokeHook(getApp(), ON_HIDE); + invokeHook(getCurrentPage(), ON_HIDE); +} +const SUBSCRIBE_LIFECYCLE_HOOKS = [ON_PAGE_SCROLL, ON_REACH_BOTTOM]; +function initSubscribe() { + SUBSCRIBE_LIFECYCLE_HOOKS.forEach( + (name) => UniServiceJSBridge.subscribe(name, createPageEvent(name)) + ); +} +function createPageEvent(name) { + return (args, pageId) => { + invokeHook(parseInt(pageId), name, args); + }; +} +function initService() { + { + initOn(); + initSubscribe(); + } +} +function initAppVm(appVm2) { + appVm2.$vm = appVm2; + appVm2.$mpType = "app"; + const locale = ref(useI18n().getLocale()); + Object.defineProperty(appVm2, "$locale", { + get() { + return locale.value; + }, + set(v2) { + locale.value = v2; + } + }); +} +function initPageVm(pageVm, page) { + pageVm.route = page.route; + pageVm.$vm = pageVm; + pageVm.$page = page; + pageVm.$mpType = "page"; + if (page.meta.isTabBar) { + pageVm.$.__isTabBar = true; + pageVm.$.__isActive = true; + } +} +function querySelector(vm, selector) { + const el = vm.$el.querySelector(selector); + return el && el.__vue__; +} +function querySelectorAll(vm, selector) { + const nodeList = vm.$el.querySelectorAll(selector); + if (nodeList) { + return [...nodeList].map((node) => node.__vue__).filter(Boolean); + } + return []; +} +function createSelectorQuery$1() { + return uni.createSelectorQuery().in(this); +} +function createMediaQueryObserver$1() { + return uni.createMediaQueryObserver(this); +} +function createIntersectionObserver$1(options) { + return uni.createIntersectionObserver(this, options); +} +function selectComponent(selector) { + return querySelector(this, selector); +} +function selectAllComponents(selector) { + return querySelectorAll(this, selector); +} +const wxInstance = /* @__PURE__ */ Object.defineProperty({ + __proto__: null, + createIntersectionObserver: createIntersectionObserver$1, + createMediaQueryObserver: createMediaQueryObserver$1, + createSelectorQuery: createSelectorQuery$1, + selectAllComponents, + selectComponent +}, Symbol.toStringTag, { value: "Module" }); +function getOpenerEventChannel() { + { + if (this.$route) { + const meta = this.$route.meta; + if (!meta.eventChannel) { + meta.eventChannel = new EventChannel(this.$page.id); + } + return meta.eventChannel; + } + } +} +function initAppConfig(appConfig) { + const globalProperties = appConfig.globalProperties; + globalProperties.getOpenerEventChannel = getOpenerEventChannel; + if (__UNI_FEATURE_WX__) { + extend(globalProperties, wxInstance); + } +} +function initServicePlugin(app) { + initAppConfig(app._context.config); +} +function createLaunchOptions() { + return { + path: "", + query: {}, + scene: 1001, + referrerInfo: { + appId: "", + extraData: {} + } + }; +} +function defineGlobalData(app, defaultGlobalData) { + const options = app.$options || {}; + options.globalData = extend(options.globalData || {}, defaultGlobalData); + Object.defineProperty(app, "globalData", { + get() { + return options.globalData; + }, + set(newGlobalData) { + options.globalData = newGlobalData; + } + }); +} +function converPx(value) { + if (/^-?\d+[ur]px$/i.test(value)) { + return value.replace(/(^-?\d+)[ur]px$/i, (text2, num) => { + return `${uni.upx2px(parseFloat(num))}px`; + }); + } else if (/^-?[\d\.]+$/.test(value)) { + return `${value}px`; + } + return value || ""; +} +function converType(type) { + return type.replace(/[A-Z]/g, (text2) => { + return `-${text2.toLowerCase()}`; + }).replace("webkit", "-webkit"); +} +function getStyle(action) { + const animateTypes1 = [ + "matrix", + "matrix3d", + "scale", + "scale3d", + "rotate3d", + "skew", + "translate", + "translate3d" + ]; + const animateTypes2 = [ + "scaleX", + "scaleY", + "scaleZ", + "rotate", + "rotateX", + "rotateY", + "rotateZ", + "skewX", + "skewY", + "translateX", + "translateY", + "translateZ" + ]; + const animateTypes3 = ["opacity", "background-color"]; + const animateTypes4 = ["width", "height", "left", "right", "top", "bottom"]; + const animates = action.animates; + const option = action.option; + const transition = option.transition; + const style = {}; + const transform = []; + animates.forEach((animate) => { + let type = animate.type; + let args = [...animate.args]; + if (animateTypes1.concat(animateTypes2).includes(type)) { + if (type.startsWith("rotate") || type.startsWith("skew")) { + args = args.map((value) => parseFloat(value) + "deg"); + } else if (type.startsWith("translate")) { + args = args.map(converPx); + } + if (animateTypes2.indexOf(type) >= 0) { + args.length = 1; + } + transform.push(`${type}(${args.join(",")})`); + } else if (animateTypes3.concat(animateTypes4).includes(args[0])) { + type = args[0]; + const value = args[1]; + style[type] = animateTypes4.includes(type) ? converPx(value) : value; + } + }); + style.transform = style.webkitTransform = transform.join(" "); + style.transition = style.webkitTransition = Object.keys(style).map( + (type) => `${converType(type)} ${transition.duration}ms ${transition.timingFunction} ${transition.delay}ms` + ).join(","); + style.transformOrigin = style.webkitTransformOrigin = option.transformOrigin; + return style; +} +function startAnimation(context) { + const animation2 = context.animation; + if (!animation2 || !animation2.actions || !animation2.actions.length) { + return; + } + let index2 = 0; + const actions = animation2.actions; + const length = animation2.actions.length; + function animate() { + const action = actions[index2]; + const transition = action.option.transition; + const style = getStyle(action); + Object.keys(style).forEach((key) => { + context.$el.style[key] = style[key]; + }); + index2 += 1; + if (index2 < length) { + setTimeout(animate, transition.duration + transition.delay); + } + } + setTimeout(() => { + animate(); + }, 0); +} +const animation = { + props: ["animation"], + watch: { + animation: { + deep: true, + handler() { + startAnimation(this); + } + } + }, + mounted() { + startAnimation(this); + } +}; +const defineBuiltInComponent = (options) => { + options.__reserved = true; + const { props: props2, mixins } = options; + if (!props2 || !props2.animation) { + (mixins || (options.mixins = [])).push(animation); + } + return defineSystemComponent(options); +}; +const defineSystemComponent = (options) => { + options.__reserved = true; + options.compatConfig = { + MODE: 3 + // 标记为vue3 + }; + return defineComponent(options); +}; +const defineUnsupportedComponent = (name) => { + return defineBuiltInComponent({ + name: capitalize(camelize(name)), + setup() { + return () => (openBlock(), createElementBlock("uni-" + name, null, name + " is unsupported")); + } + }); +}; +const hoverProps = { + hoverClass: { + type: String, + default: "none" + }, + hoverStopPropagation: { + type: Boolean, + default: false + }, + hoverStartTime: { + type: [Number, String], + default: 50 + }, + hoverStayTime: { + type: [Number, String], + default: 400 + } +}; +function useHover(props2) { + const hovering = ref(false); + let hoverTouch = false; + let hoverStartTimer; + let hoverStayTimer; + function hoverReset() { + requestAnimationFrame(() => { + clearTimeout(hoverStayTimer); + hoverStayTimer = setTimeout(() => { + hovering.value = false; + }, parseInt(props2.hoverStayTime)); + }); + } + function onTouchstartPassive(evt) { + if (evt.touches.length > 1) { + return; + } + handleHoverStart(evt); + } + function onMousedown(evt) { + if (hoverTouch) { + return; + } + handleHoverStart(evt); + window.addEventListener("mouseup", handlePCHoverEnd); + } + function handleHoverStart(evt) { + if (evt._hoverPropagationStopped) { + return; + } + if (!props2.hoverClass || props2.hoverClass === "none" || props2.disabled) { + return; + } + if (props2.hoverStopPropagation) { + evt._hoverPropagationStopped = true; + } + hoverTouch = true; + hoverStartTimer = setTimeout(() => { + hovering.value = true; + if (!hoverTouch) { + hoverReset(); + } + }, parseInt(props2.hoverStartTime)); + } + function onTouchend() { + handleHoverEnd(); + } + function onMouseup() { + if (!hoverTouch) { + return; + } + handlePCHoverEnd(); + } + function handleHoverEnd() { + hoverTouch = false; + if (hovering.value) { + hoverReset(); + } + } + function handlePCHoverEnd() { + handleHoverEnd(); + window.removeEventListener("mouseup", handlePCHoverEnd); + } + function onTouchcancel() { + hoverTouch = false; + hovering.value = false; + clearTimeout(hoverStartTimer); + } + return { + hovering, + binding: { + onTouchstartPassive, + onMousedown, + onTouchend, + onMouseup, + onTouchcancel + } + }; +} +function useBooleanAttr(props2, keys) { + if (isString(keys)) { + keys = [keys]; + } + return keys.reduce((res, key) => { + if (props2[key]) { + res[key] = true; + } + return res; + }, /* @__PURE__ */ Object.create(null)); +} +function withWebEvent(fn) { + return fn.__wwe = true, fn; +} +function useCustomEvent(ref2, emit2) { + return (name, evt, detail) => { + if (ref2.value) { + emit2(name, normalizeCustomEvent(name, evt, ref2.value, detail || {})); + } + }; +} +function useNativeEvent(emit2) { + return (name, evt) => { + emit2(name, createNativeEvent(evt)); + }; +} +function normalizeCustomEvent(name, domEvt, el, detail) { + const target = normalizeTarget(el); + return { + type: detail.type || name, + timeStamp: domEvt.timeStamp || 0, + target, + currentTarget: target, + detail + }; +} +const uniFormKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniForm" : "uf"); +const index$z = /* @__PURE__ */ defineBuiltInComponent({ + name: "Form", + emits: ["submit", "reset"], + setup(_props, { + slots, + emit: emit2 + }) { + const rootRef = ref(null); + provideForm(useCustomEvent(rootRef, emit2)); + return () => createVNode("uni-form", { + "ref": rootRef + }, [createVNode("span", null, [slots.default && slots.default()])], 512); + } +}); +function provideForm(trigger) { + const fields2 = []; + provide(uniFormKey, { + addField(field) { + fields2.push(field); + }, + removeField(field) { + fields2.splice(fields2.indexOf(field), 1); + }, + submit(evt) { + trigger("submit", evt, { + value: fields2.reduce((res, field) => { + if (field.submit) { + const [name, value] = field.submit(); + name && (res[name] = value); + } + return res; + }, /* @__PURE__ */ Object.create(null)) + }); + }, + reset(evt) { + fields2.forEach((field) => field.reset && field.reset()); + trigger("reset", evt); + } + }); + return fields2; +} +const labelProps = { + for: { + type: String, + default: "" + } +}; +const uniLabelKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniLabel" : "ul"); +function useProvideLabel() { + const handlers = []; + provide(uniLabelKey, { + addHandler(handler) { + handlers.push(handler); + }, + removeHandler(handler) { + handlers.splice(handlers.indexOf(handler), 1); + } + }); + return handlers; +} +const index$y = /* @__PURE__ */ defineBuiltInComponent({ + name: "Label", + props: labelProps, + setup(props2, { + slots + }) { + const pageId = useCurrentPageId(); + const handlers = useProvideLabel(); + const pointer = computed(() => props2.for || slots.default && slots.default.length); + const _onClick = withWebEvent(($event) => { + const EventTarget = $event.target; + let stopPropagation = /^uni-(checkbox|radio|switch)-/.test(EventTarget.className); + if (!stopPropagation) { + stopPropagation = /^uni-(checkbox|radio|switch|button)$|^(svg|path)$/i.test(EventTarget.tagName); + } + if (stopPropagation) { + return; + } + if (props2.for) { + UniViewJSBridge.emit("uni-label-click-" + pageId + "-" + props2.for, $event, true); + } else { + handlers.length && handlers[0]($event, true); + } + }); + return () => createVNode("uni-label", { + "class": { + "uni-label-pointer": pointer + }, + "onClick": _onClick + }, [slots.default && slots.default()], 10, ["onClick"]); + } +}); +function useListeners$1(props2, listeners2) { + _addListeners(props2.id, listeners2); + watch( + () => props2.id, + (newId, oldId) => { + _removeListeners(oldId, listeners2, true); + _addListeners(newId, listeners2, true); + } + ); + onUnmounted(() => { + _removeListeners(props2.id, listeners2); + }); +} +function _addListeners(id2, listeners2, watch2) { + const pageId = useCurrentPageId(); + if (watch2 && !id2) { + return; + } + if (!isPlainObject(listeners2)) { + return; + } + Object.keys(listeners2).forEach((name) => { + if (watch2) { + if (name.indexOf("@") !== 0 && name.indexOf("uni-") !== 0) { + UniViewJSBridge.on(`uni-${name}-${pageId}-${id2}`, listeners2[name]); + } + } else { + if (name.indexOf("uni-") === 0) { + UniViewJSBridge.on(name, listeners2[name]); + } else if (id2) { + UniViewJSBridge.on(`uni-${name}-${pageId}-${id2}`, listeners2[name]); + } + } + }); +} +function _removeListeners(id2, listeners2, watch2) { + const pageId = useCurrentPageId(); + if (watch2 && !id2) { + return; + } + if (!isPlainObject(listeners2)) { + return; + } + Object.keys(listeners2).forEach((name) => { + if (watch2) { + if (name.indexOf("@") !== 0 && name.indexOf("uni-") !== 0) { + UniViewJSBridge.off(`uni-${name}-${pageId}-${id2}`, listeners2[name]); + } + } else { + if (name.indexOf("uni-") === 0) { + UniViewJSBridge.off(name, listeners2[name]); + } else if (id2) { + UniViewJSBridge.off(`uni-${name}-${pageId}-${id2}`, listeners2[name]); + } + } + }); +} +const buttonProps = { + id: { + type: String, + default: "" + }, + hoverClass: { + type: String, + default: "button-hover" + }, + hoverStartTime: { + type: [Number, String], + default: 20 + }, + hoverStayTime: { + type: [Number, String], + default: 70 + }, + hoverStopPropagation: { + type: Boolean, + default: false + }, + disabled: { + type: [Boolean, String], + default: false + }, + formType: { + type: String, + default: "" + }, + openType: { + type: String, + default: "" + }, + loading: { + type: [Boolean, String], + default: false + }, + plain: { + type: [Boolean, String], + default: false + } +}; +const index$x = /* @__PURE__ */ defineBuiltInComponent({ + name: "Button", + props: buttonProps, + setup(props2, { + slots + }) { + const rootRef = ref(null); + const uniForm = inject(uniFormKey, false); + const { + hovering, + binding + } = useHover(props2); + useI18n(); + const onClick = withWebEvent((e2, isLabelClick) => { + if (props2.disabled) { + return e2.stopImmediatePropagation(); + } + if (isLabelClick) { + rootRef.value.click(); + } + const formType = props2.formType; + if (formType) { + if (!uniForm) { + return; + } + if (formType === "submit") { + uniForm.submit(e2); + } else if (formType === "reset") { + uniForm.reset(e2); + } + return; + } + if ( + // @ts-ignore + window.weibo && // @ts-ignore + typeof window.weibo.share === "function" && props2.openType === "share" + ) { + window.weibo.share(); + } + }); + const uniLabel = inject(uniLabelKey, false); + if (uniLabel) { + uniLabel.addHandler(onClick); + onBeforeUnmount(() => { + uniLabel.removeHandler(onClick); + }); + } + useListeners$1(props2, { + "label-click": onClick + }); + return () => { + const hoverClass = props2.hoverClass; + const booleanAttrs = useBooleanAttr(props2, "disabled"); + const loadingAttrs = useBooleanAttr(props2, "loading"); + const plainAttrs = useBooleanAttr(props2, "plain"); + const hasHoverClass = hoverClass && hoverClass !== "none"; + return createVNode("uni-button", mergeProps({ + "ref": rootRef, + "onClick": onClick, + "class": hasHoverClass && hovering.value ? hoverClass : "" + }, hasHoverClass && binding, booleanAttrs, loadingAttrs, plainAttrs), [slots.default && slots.default()], 16, ["onClick"]); + }; + } +}); +function findElem(vm) { + return vm.$el; +} +function addBase(filePath) { + const { base: baseUrl } = __uniConfig.router; + if (addLeadingSlash(filePath).indexOf(baseUrl) === 0) { + return addLeadingSlash(filePath); + } + return baseUrl + filePath; +} +function getRealPath(filePath) { + const { base, assets } = __uniConfig.router; + if (base === "./") { + if (filePath.indexOf("./static/") === 0 || assets && filePath.indexOf("./" + assets + "/") === 0) { + filePath = filePath.slice(1); + } + } + if (filePath.indexOf("/") === 0) { + if (filePath.indexOf("//") === 0) { + filePath = "https:" + filePath; + } else { + return addBase(filePath.slice(1)); + } + } + if (SCHEME_RE.test(filePath) || DATA_RE.test(filePath) || filePath.indexOf("blob:") === 0) { + return filePath; + } + const pages = getCurrentPages(); + if (pages.length) { + return addBase( + getRealRoute(pages[pages.length - 1].$page.route, filePath).slice(1) + ); + } + return filePath; +} +const ua = navigator.userAgent; +const isAndroid = /* @__PURE__ */ /android/i.test(ua); +const isIOS$1 = /* @__PURE__ */ /iphone|ipad|ipod/i.test(ua); +const isWindows = /* @__PURE__ */ ua.match(/Windows NT ([\d|\d.\d]*)/i); +const isMac = /* @__PURE__ */ /Macintosh|Mac/i.test(ua); +const isLinux = /* @__PURE__ */ /Linux|X11/i.test(ua); +const isIPadOS = isMac && navigator.maxTouchPoints > 0; +function getScreenFix() { + return /^Apple/.test(navigator.vendor) && typeof window.orientation === "number"; +} +function isLandscape(screenFix) { + return screenFix && Math.abs(window.orientation) === 90; +} +function getScreenWidth(screenFix, landscape) { + return screenFix ? Math[landscape ? "max" : "min"](screen.width, screen.height) : screen.width; +} +function getScreenHeight(screenFix, landscape) { + return screenFix ? Math[landscape ? "min" : "max"](screen.height, screen.width) : screen.height; +} +function getWindowWidth(screenWidth) { + return Math.min( + window.innerWidth, + document.documentElement.clientWidth, + screenWidth + ) || screenWidth; +} +function getBaseSystemInfo() { + const screenFix = getScreenFix(); + const windowWidth = getWindowWidth( + getScreenWidth(screenFix, isLandscape(screenFix)) + ); + return { + platform: isIOS$1 ? "ios" : "other", + pixelRatio: window.devicePixelRatio, + windowWidth + }; +} +function operateVideoPlayer(videoId, pageId, type, data) { + UniServiceJSBridge.invokeViewMethod( + "video." + videoId, + { + videoId, + type, + data + }, + pageId + ); +} +function operateMap(id2, pageId, type, data, operateMapCallback2) { + UniServiceJSBridge.invokeViewMethod( + "map." + id2, + { + type, + data + }, + pageId, + operateMapCallback2 + ); +} +function getRootInfo(fields2) { + const info = {}; + if (fields2.id) { + info.id = ""; + } + if (fields2.dataset) { + info.dataset = {}; + } + if (fields2.rect) { + info.left = 0; + info.right = 0; + info.top = 0; + info.bottom = 0; + } + if (fields2.size) { + info.width = document.documentElement.clientWidth; + info.height = document.documentElement.clientHeight; + } + if (fields2.scrollOffset) { + const documentElement2 = document.documentElement; + const body = document.body; + info.scrollLeft = documentElement2.scrollLeft || body.scrollLeft || 0; + info.scrollTop = documentElement2.scrollTop || body.scrollTop || 0; + info.scrollHeight = documentElement2.scrollHeight || body.scrollHeight || 0; + info.scrollWidth = documentElement2.scrollWidth || body.scrollWidth || 0; + } + return info; +} +function getNodeInfo(el, fields2) { + const info = {}; + const { top, topWindowHeight } = getWindowOffset(); + if (fields2.id) { + info.id = el.id; + } + if (fields2.dataset) { + info.dataset = getCustomDataset(el); + } + if (fields2.rect || fields2.size) { + const rect = el.getBoundingClientRect(); + if (fields2.rect) { + info.left = rect.left; + info.right = rect.right; + info.top = rect.top - top - topWindowHeight; + info.bottom = rect.bottom - top - topWindowHeight; + } + if (fields2.size) { + info.width = rect.width; + info.height = rect.height; + } + } + if (isArray(fields2.properties)) { + fields2.properties.forEach((prop) => { + prop = prop.replace(/-([a-z])/g, function(e2, t2) { + return t2.toUpperCase(); + }); + }); + } + if (fields2.scrollOffset) { + if (el.tagName === "UNI-SCROLL-VIEW") { + const scroll = el.children[0].children[0]; + info.scrollLeft = scroll.scrollLeft; + info.scrollTop = scroll.scrollTop; + info.scrollHeight = scroll.scrollHeight; + info.scrollWidth = scroll.scrollWidth; + } else { + info.scrollLeft = 0; + info.scrollTop = 0; + info.scrollHeight = 0; + info.scrollWidth = 0; + } + } + if (isArray(fields2.computedStyle)) { + const sytle = getComputedStyle(el); + fields2.computedStyle.forEach((name) => { + info[name] = sytle[name]; + }); + } + if (fields2.context) { + info.contextInfo = getContextInfo(el); + } + return info; +} +function findElm(component, pageVm) { + if (!component) { + return pageVm.$el; + } + return component.$el; +} +function matches(element, selectors) { + const matches2 = element.matches || element.matchesSelector || element.mozMatchesSelector || element.msMatchesSelector || element.oMatchesSelector || element.webkitMatchesSelector || function(selectors2) { + const matches3 = this.parentElement.querySelectorAll( + selectors2 + ); + let i = matches3.length; + while (--i >= 0 && matches3.item(i) !== this) { + } + return i > -1; + }; + return matches2.call(element, selectors); +} +function getNodesInfo(pageVm, component, selector, single, fields2) { + const selfElement = findElm(component, pageVm); + const parentElement = selfElement.parentElement; + if (!parentElement) { + return single ? null : []; + } + const { nodeType } = selfElement; + const maybeFragment = nodeType === 3 || nodeType === 8; + if (single) { + const node = maybeFragment ? parentElement.querySelector(selector) : matches(selfElement, selector) ? selfElement : selfElement.querySelector(selector); + if (node) { + return getNodeInfo(node, fields2); + } + return null; + } else { + let infos = []; + const nodeList = (maybeFragment ? parentElement : selfElement).querySelectorAll(selector); + if (nodeList && nodeList.length) { + [].forEach.call(nodeList, (node) => { + infos.push(getNodeInfo(node, fields2)); + }); + } + if (!maybeFragment && matches(selfElement, selector)) { + infos.unshift(getNodeInfo(selfElement, fields2)); + } + return infos; + } +} +function requestComponentInfo(page, reqs, callback) { + const result = []; + reqs.forEach(({ component, selector, single, fields: fields2 }) => { + if (component === null) { + result.push(getRootInfo(fields2)); + } else { + result.push(getNodesInfo(page, component, selector, single, fields2)); + } + }); + callback(result); +} +function setCurrentPageMeta(_page, { pageStyle, rootFontSize }) { + if (pageStyle) { + const pageElm = document.querySelector("uni-page-body") || document.body; + pageElm.setAttribute("style", pageStyle); + } + if (rootFontSize && document.documentElement.style.fontSize !== rootFontSize) { + document.documentElement.style.fontSize = rootFontSize; + } +} +var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var lookup = /* @__PURE__ */ function() { + const lookup2 = new Uint8Array(256); + for (var i = 0; i < chars.length; i++) { + lookup2[chars.charCodeAt(i)] = i; + } + return lookup2; +}(); +function encode$1(arraybuffer) { + var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = ""; + for (i = 0; i < len; i += 3) { + base64 += chars[bytes[i] >> 2]; + base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; + base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; + base64 += chars[bytes[i + 2] & 63]; + } + if (len % 3 === 2) { + base64 = base64.substring(0, base64.length - 1) + "="; + } else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + "=="; + } + return base64; +} +function decode(base64) { + var bufferLength = base64.length * 0.75, len = base64.length, i, p2 = 0, encoded1, encoded2, encoded3, encoded4; + if (base64[base64.length - 1] === "=") { + bufferLength--; + if (base64[base64.length - 2] === "=") { + bufferLength--; + } + } + var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer); + for (i = 0; i < len; i += 4) { + encoded1 = lookup[base64.charCodeAt(i)]; + encoded2 = lookup[base64.charCodeAt(i + 1)]; + encoded3 = lookup[base64.charCodeAt(i + 2)]; + encoded4 = lookup[base64.charCodeAt(i + 3)]; + bytes[p2++] = encoded1 << 2 | encoded2 >> 4; + bytes[p2++] = (encoded2 & 15) << 4 | encoded3 >> 2; + bytes[p2++] = (encoded3 & 3) << 6 | encoded4 & 63; + } + return arraybuffer; +} +const CHOOSE_SIZE_TYPES = ["original", "compressed"]; +const CHOOSE_SOURCE_TYPES = ["album", "camera"]; +const HTTP_METHODS = [ + "GET", + "OPTIONS", + "HEAD", + "POST", + "PUT", + "DELETE", + "TRACE", + "CONNECT", + "PATCH" +]; +function elemInArray(str, arr) { + if (!str || arr.indexOf(str) === -1) { + return arr[0]; + } + return str; +} +function elemsInArray(strArr, optionalVal) { + if (!isArray(strArr) || strArr.length === 0 || strArr.find((val) => optionalVal.indexOf(val) === -1)) { + return optionalVal; + } + return strArr; +} +function validateProtocolFail(name, msg) { + console.warn(`${name}: ${msg}`); +} +function validateProtocol(name, data, protocol, onFail) { + if (!onFail) { + onFail = validateProtocolFail; + } + for (const key in protocol) { + const errMsg = validateProp( + key, + data[key], + protocol[key], + !hasOwn(data, key) + ); + if (isString(errMsg)) { + onFail(name, errMsg); + } + } +} +function validateProtocols(name, args, protocol, onFail) { + if (!protocol) { + return; + } + if (!isArray(protocol)) { + return validateProtocol( + name, + args[0] || /* @__PURE__ */ Object.create(null), + protocol, + onFail + ); + } + const len = protocol.length; + const argsLen = args.length; + for (let i = 0; i < len; i++) { + const opts = protocol[i]; + const data = /* @__PURE__ */ Object.create(null); + if (argsLen > i) { + data[opts.name] = args[i]; + } + validateProtocol(name, data, { [opts.name]: opts }, onFail); + } +} +function validateProp(name, value, prop, isAbsent) { + if (!isPlainObject(prop)) { + prop = { type: prop }; + } + const { type, required, validator: validator2 } = prop; + if (required && isAbsent) { + return 'Missing required args: "' + name + '"'; + } + if (value == null && !required) { + return; + } + if (type != null) { + let isValid = false; + const types = isArray(type) ? type : [type]; + const expectedTypes = []; + for (let i = 0; i < types.length && !isValid; i++) { + const { valid, expectedType } = assertType(value, types[i]); + expectedTypes.push(expectedType || ""); + isValid = valid; + } + if (!isValid) { + return getInvalidTypeMessage(name, value, expectedTypes); + } + } + if (validator2) { + return validator2(value); + } +} +const isSimpleType = /* @__PURE__ */ makeMap$1( + "String,Number,Boolean,Function,Symbol" +); +function assertType(value, type) { + let valid; + const expectedType = getType(type); + if (isSimpleType(expectedType)) { + const t2 = typeof value; + valid = t2 === expectedType.toLowerCase(); + if (!valid && t2 === "object") { + valid = value instanceof type; + } + } else if (expectedType === "Object") { + valid = isObject(value); + } else if (expectedType === "Array") { + valid = isArray(value); + } else { + { + valid = value instanceof type; + } + } + return { + valid, + expectedType + }; +} +function getInvalidTypeMessage(name, value, expectedTypes) { + let message = `Invalid args: type check failed for args "${name}". Expected ${expectedTypes.map(capitalize).join(", ")}`; + const expectedType = expectedTypes[0]; + const receivedType = toRawType(value); + const expectedValue = styleValue(value, expectedType); + const receivedValue = styleValue(value, receivedType); + if (expectedTypes.length === 1 && isExplicable(expectedType) && !isBoolean(expectedType, receivedType)) { + message += ` with value ${expectedValue}`; + } + message += `, got ${receivedType} `; + if (isExplicable(receivedType)) { + message += `with value ${receivedValue}.`; + } + return message; +} +function getType(ctor) { + const match = ctor && ctor.toString().match(/^\s*function (\w+)/); + return match ? match[1] : ""; +} +function styleValue(value, type) { + if (type === "String") { + return `"${value}"`; + } else if (type === "Number") { + return `${Number(value)}`; + } else { + return `${value}`; + } +} +function isExplicable(type) { + const explicitTypes = ["string", "number", "boolean"]; + return explicitTypes.some((elem) => type.toLowerCase() === elem); +} +function isBoolean(...args) { + return args.some((elem) => elem.toLowerCase() === "boolean"); +} +function tryCatch(fn) { + return function() { + try { + return fn.apply(fn, arguments); + } catch (e2) { + console.error(e2); + } + }; +} +let invokeCallbackId = 1; +const invokeCallbacks = {}; +function addInvokeCallback(id2, name, callback, keepAlive = false) { + invokeCallbacks[id2] = { + name, + keepAlive, + callback + }; + return id2; +} +function invokeCallback(id2, res, extras) { + if (typeof id2 === "number") { + const opts = invokeCallbacks[id2]; + if (opts) { + if (!opts.keepAlive) { + delete invokeCallbacks[id2]; + } + return opts.callback(res, extras); + } + } + return res; +} +function findInvokeCallbackByName(name) { + for (const key in invokeCallbacks) { + if (invokeCallbacks[key].name === name) { + return true; + } + } + return false; +} +function removeKeepAliveApiCallback(name, callback) { + for (const key in invokeCallbacks) { + const item = invokeCallbacks[key]; + if (item.callback === callback && item.name === name) { + delete invokeCallbacks[key]; + } + } +} +function offKeepAliveApiCallback(name) { + UniServiceJSBridge.off("api." + name); +} +function onKeepAliveApiCallback(name) { + UniServiceJSBridge.on("api." + name, (res) => { + for (const key in invokeCallbacks) { + const opts = invokeCallbacks[key]; + if (opts.name === name) { + opts.callback(res); + } + } + }); +} +function createKeepAliveApiCallback(name, callback) { + return addInvokeCallback(invokeCallbackId++, name, callback, true); +} +const API_SUCCESS = "success"; +const API_FAIL = "fail"; +const API_COMPLETE = "complete"; +function getApiCallbacks(args) { + const apiCallbacks = {}; + for (const name in args) { + const fn = args[name]; + if (isFunction(fn)) { + apiCallbacks[name] = tryCatch(fn); + delete args[name]; + } + } + return apiCallbacks; +} +function normalizeErrMsg$1(errMsg, name) { + if (!errMsg || errMsg.indexOf(":fail") === -1) { + return name + ":ok"; + } + return name + errMsg.substring(errMsg.indexOf(":fail")); +} +function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = {}) { + if (!isPlainObject(args)) { + args = {}; + } + const { success, fail, complete } = getApiCallbacks(args); + const hasSuccess = isFunction(success); + const hasFail = isFunction(fail); + const hasComplete = isFunction(complete); + const callbackId = invokeCallbackId++; + addInvokeCallback(callbackId, name, (res) => { + res = res || {}; + res.errMsg = normalizeErrMsg$1(res.errMsg, name); + isFunction(beforeAll) && beforeAll(res); + if (res.errMsg === name + ":ok") { + isFunction(beforeSuccess) && beforeSuccess(res, args); + hasSuccess && success(res); + } else { + hasFail && fail(res); + } + hasComplete && complete(res); + }); + return callbackId; +} +const HOOK_SUCCESS = "success"; +const HOOK_FAIL = "fail"; +const HOOK_COMPLETE = "complete"; +const globalInterceptors = {}; +const scopedInterceptors = {}; +function wrapperHook(hook, params) { + return function(data) { + return hook(data, params) || data; + }; +} +function queue(hooks, data, params) { + let promise = false; + for (let i = 0; i < hooks.length; i++) { + const hook = hooks[i]; + if (promise) { + promise = Promise.resolve(wrapperHook(hook, params)); + } else { + const res = hook(data, params); + if (isPromise(res)) { + promise = Promise.resolve(res); + } + if (res === false) { + return { + then() { + }, + catch() { + } + }; + } + } + } + return promise || { + then(callback) { + return callback(data); + }, + catch() { + } + }; +} +function wrapperOptions(interceptors2, options = {}) { + [HOOK_SUCCESS, HOOK_FAIL, HOOK_COMPLETE].forEach((name) => { + const hooks = interceptors2[name]; + if (!isArray(hooks)) { + return; + } + const oldCallback = options[name]; + options[name] = function callbackInterceptor(res) { + queue(hooks, res, options).then((res2) => { + return isFunction(oldCallback) && oldCallback(res2) || res2; + }); + }; + }); + return options; +} +function wrapperReturnValue(method, returnValue) { + const returnValueHooks = []; + if (isArray(globalInterceptors.returnValue)) { + returnValueHooks.push(...globalInterceptors.returnValue); + } + const interceptor = scopedInterceptors[method]; + if (interceptor && isArray(interceptor.returnValue)) { + returnValueHooks.push(...interceptor.returnValue); + } + returnValueHooks.forEach((hook) => { + returnValue = hook(returnValue) || returnValue; + }); + return returnValue; +} +function getApiInterceptorHooks(method) { + const interceptor = /* @__PURE__ */ Object.create(null); + Object.keys(globalInterceptors).forEach((hook) => { + if (hook !== "returnValue") { + interceptor[hook] = globalInterceptors[hook].slice(); + } + }); + const scopedInterceptor = scopedInterceptors[method]; + if (scopedInterceptor) { + Object.keys(scopedInterceptor).forEach((hook) => { + if (hook !== "returnValue") { + interceptor[hook] = (interceptor[hook] || []).concat( + scopedInterceptor[hook] + ); + } + }); + } + return interceptor; +} +function invokeApi(method, api2, options, params) { + const interceptor = getApiInterceptorHooks(method); + if (interceptor && Object.keys(interceptor).length) { + if (isArray(interceptor.invoke)) { + const res = queue(interceptor.invoke, options); + return res.then((options2) => { + return api2( + wrapperOptions(getApiInterceptorHooks(method), options2), + ...params + ); + }); + } else { + return api2(wrapperOptions(interceptor, options), ...params); + } + } + return api2(options, ...params); +} +function hasCallback(args) { + if (isPlainObject(args) && [API_SUCCESS, API_FAIL, API_COMPLETE].find( + (cb) => isFunction(args[cb]) + )) { + return true; + } + return false; +} +function handlePromise(promise) { + return promise; +} +function promisify(name, fn) { + return (args = {}, ...rest) => { + try { + if (window.weibo && window.weibo[name]) { + window.currentWeiboApiName = name; + const value = window.weibo[name](args); + if (name !== "switchTab") { + return value; + } + } + } catch (e2) { + } + if (hasCallback(args)) { + return wrapperReturnValue(name, invokeApi(name, fn, args, rest)); + } + return wrapperReturnValue( + name, + handlePromise( + new Promise((resolve, reject) => { + invokeApi( + name, + fn, + extend(args, { success: resolve, fail: reject }), + rest + ); + }) + ) + ); + }; +} +function formatApiArgs(args, options) { + const params = args[0]; + if (!options || !isPlainObject(options.formatArgs) && isPlainObject(params)) { + return; + } + const formatArgs = options.formatArgs; + const keys = Object.keys(formatArgs); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + const formatterOrDefaultValue = formatArgs[name]; + if (isFunction(formatterOrDefaultValue)) { + const errMsg = formatterOrDefaultValue(args[0][name], params); + if (isString(errMsg)) { + return errMsg; + } + } else { + if (!hasOwn(params, name)) { + params[name] = formatterOrDefaultValue; + } + } + } +} +function invokeSuccess(id2, name, res) { + return invokeCallback( + id2, + extend(res || {}, { errMsg: name + ":ok" }) + ); +} +function invokeFail(id2, name, errMsg, errRes) { + return invokeCallback( + id2, + extend({ errMsg: name + ":fail" + (errMsg ? " " + errMsg : "") }, errRes) + ); +} +function beforeInvokeApi(name, args, protocol, options) { + if (process.env.NODE_ENV !== "production") { + validateProtocols(name, args, protocol); + } + if (options && options.beforeInvoke) { + const errMsg2 = options.beforeInvoke(args); + if (isString(errMsg2)) { + return errMsg2; + } + } + const errMsg = formatApiArgs(args, options); + if (errMsg) { + return errMsg; + } +} +function checkCallback(callback) { + if (!isFunction(callback)) { + throw new Error( + 'Invalid args: type check failed for args "callback". Expected Function' + ); + } +} +function wrapperOnApi(name, fn, options) { + return (callback) => { + checkCallback(callback); + const errMsg = beforeInvokeApi(name, [callback], void 0, options); + if (errMsg) { + throw new Error(errMsg); + } + const isFirstInvokeOnApi = !findInvokeCallbackByName(name); + createKeepAliveApiCallback(name, callback); + if (isFirstInvokeOnApi) { + onKeepAliveApiCallback(name); + fn(); + } + }; +} +function wrapperOffApi(name, fn, options) { + return (callback) => { + checkCallback(callback); + const errMsg = beforeInvokeApi(name, [callback], void 0, options); + if (errMsg) { + throw new Error(errMsg); + } + name = name.replace("off", "on"); + removeKeepAliveApiCallback(name, callback); + const hasInvokeOnApi = findInvokeCallbackByName(name); + if (!hasInvokeOnApi) { + offKeepAliveApiCallback(name); + fn(); + } + }; +} +function normalizeErrMsg(errMsg) { + if (!errMsg || isString(errMsg)) { + return errMsg; + } + if (errMsg.stack) { + console.error(errMsg.message + LINEFEED + errMsg.stack); + return errMsg.message; + } + return errMsg; +} +function wrapperTaskApi(name, fn, protocol, options) { + return (args) => { + const id2 = createAsyncApiCallback(name, args, options); + const errMsg = beforeInvokeApi(name, [args], protocol, options); + if (errMsg) { + return invokeFail(id2, name, errMsg); + } + return fn(args, { + resolve: (res) => invokeSuccess(id2, name, res), + reject: (errMsg2, errRes) => invokeFail(id2, name, normalizeErrMsg(errMsg2), errRes) + }); + }; +} +function wrapperSyncApi(name, fn, protocol, options) { + return (...args) => { + try { + if (window.weibo && window.weibo[name]) { + window.currentWeiboApiName = name; + var value = window.weibo[name](args); + return value; + } + } catch (e2) { + } + const errMsg = beforeInvokeApi(name, args, protocol, options); + if (errMsg) { + throw new Error(errMsg); + } + return fn.apply(null, args); + }; +} +function wrapperAsyncApi(name, fn, protocol, options) { + return wrapperTaskApi(name, fn, protocol, options); +} +function defineOnApi(name, fn, options) { + return wrapperOnApi(name, fn, options); +} +function defineOffApi(name, fn, options) { + return wrapperOffApi(name, fn, options); +} +function defineTaskApi(name, fn, protocol, options) { + return promisify( + name, + wrapperTaskApi(name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options) + ); +} +function defineSyncApi(name, fn, protocol, options) { + return wrapperSyncApi( + name, + fn, + process.env.NODE_ENV !== "production" ? protocol : void 0, + options + ); +} +function defineAsyncApi(name, fn, protocol, options) { + return promisify( + name, + wrapperAsyncApi(name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options) + ); +} +function createUnsupportedMsg(name) { + return `method 'uni.${name}' not supported`; +} +function createUnsupportedSyncApi(name) { + return () => { + console.error(createUnsupportedMsg(name)); + }; +} +const createUnsupportedOnApi = createUnsupportedSyncApi; +function createUnsupportedAsyncApi(name) { + return (_args, { reject }) => { + return reject(createUnsupportedMsg(name)); + }; +} +const API_BASE64_TO_ARRAY_BUFFER = "base64ToArrayBuffer"; +const Base64ToArrayBufferProtocol = [ + { + name: "base64", + type: String, + required: true + } +]; +const API_ARRAY_BUFFER_TO_BASE64 = "arrayBufferToBase64"; +const ArrayBufferToBase64Protocol = [ + { + name: "arrayBuffer", + type: [ArrayBuffer, Uint8Array], + required: true + } +]; +const base64ToArrayBuffer = /* @__PURE__ */ defineSyncApi( + API_BASE64_TO_ARRAY_BUFFER, + (base64) => { + return decode(base64); + }, + Base64ToArrayBufferProtocol +); +const arrayBufferToBase64 = /* @__PURE__ */ defineSyncApi( + API_ARRAY_BUFFER_TO_BASE64, + (arrayBuffer) => { + return encode$1(arrayBuffer); + }, + ArrayBufferToBase64Protocol +); +const API_UPX2PX = "upx2px"; +const Upx2pxProtocol = [ + { + name: "upx", + type: [Number, String], + required: true + } +]; +const EPS = 1e-4; +const BASE_DEVICE_WIDTH = 750; +let isIOS = false; +let deviceWidth = 0; +let deviceDPR = 0; +let maxWidth = 960; +let baseWidth = 375; +let includeWidth = 750; +function checkDeviceWidth() { + const { platform, pixelRatio: pixelRatio2, windowWidth } = getBaseSystemInfo(); + deviceWidth = windowWidth; + deviceDPR = pixelRatio2; + isIOS = platform === "ios"; +} +function checkValue(value, defaultValue) { + const newValue = Number(value); + return isNaN(newValue) ? defaultValue : newValue; +} +function checkMaxWidth() { + const config = __uniConfig.globalStyle || {}; + maxWidth = checkValue(config.rpxCalcMaxDeviceWidth, 960); + baseWidth = checkValue(config.rpxCalcBaseDeviceWidth, 375); + includeWidth = checkValue(config.rpxCalcBaseDeviceWidth, 750); +} +const upx2px = /* @__PURE__ */ defineSyncApi( + API_UPX2PX, + (number, newDeviceWidth) => { + if (deviceWidth === 0) { + checkDeviceWidth(); + { + checkMaxWidth(); + } + } + number = Number(number); + if (number === 0) { + return 0; + } + let width = newDeviceWidth || deviceWidth; + { + width = number === includeWidth || width <= maxWidth ? width : baseWidth; + } + let result = number / BASE_DEVICE_WIDTH * width; + if (result < 0) { + result = -result; + } + result = Math.floor(result + EPS); + if (result === 0) { + if (deviceDPR === 1 || !isIOS) { + result = 1; + } else { + result = 0.5; + } + } + return number < 0 ? -result : result; + }, + Upx2pxProtocol +); +const API_ADD_INTERCEPTOR = "addInterceptor"; +const API_REMOVE_INTERCEPTOR = "removeInterceptor"; +const AddInterceptorProtocol = [ + { + name: "method", + type: [String, Object], + required: true + } +]; +const RemoveInterceptorProtocol = AddInterceptorProtocol; +function mergeInterceptorHook(interceptors2, interceptor) { + Object.keys(interceptor).forEach((hook) => { + if (isFunction(interceptor[hook])) { + interceptors2[hook] = mergeHook( + interceptors2[hook], + interceptor[hook] + ); + } + }); +} +function removeInterceptorHook(interceptors2, interceptor) { + if (!interceptors2 || !interceptor) { + return; + } + Object.keys(interceptor).forEach((name) => { + const hooks = interceptors2[name]; + const hook = interceptor[name]; + if (isArray(hooks) && isFunction(hook)) { + remove(hooks, hook); + } + }); +} +function mergeHook(parentVal, childVal) { + const res = childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal; + return res ? dedupeHooks(res) : res; +} +function dedupeHooks(hooks) { + const res = []; + for (let i = 0; i < hooks.length; i++) { + if (res.indexOf(hooks[i]) === -1) { + res.push(hooks[i]); + } + } + return res; +} +const addInterceptor = /* @__PURE__ */ defineSyncApi( + API_ADD_INTERCEPTOR, + (method, interceptor) => { + if (isString(method) && isPlainObject(interceptor)) { + mergeInterceptorHook( + scopedInterceptors[method] || (scopedInterceptors[method] = {}), + interceptor + ); + } else if (isPlainObject(method)) { + mergeInterceptorHook(globalInterceptors, method); + } + }, + AddInterceptorProtocol +); +const removeInterceptor = /* @__PURE__ */ defineSyncApi( + API_REMOVE_INTERCEPTOR, + (method, interceptor) => { + if (isString(method)) { + if (isPlainObject(interceptor)) { + removeInterceptorHook(scopedInterceptors[method], interceptor); + } else { + delete scopedInterceptors[method]; + } + } else if (isPlainObject(method)) { + removeInterceptorHook(globalInterceptors, method); + } + }, + RemoveInterceptorProtocol +); +const interceptors = {}; +const API_ON = "$on"; +const OnProtocol = [ + { + name: "event", + type: String, + required: true + }, + { + name: "callback", + type: Function, + required: true + } +]; +const API_ONCE = "$once"; +const OnceProtocol = OnProtocol; +const API_OFF = "$off"; +const OffProtocol = [ + { + name: "event", + type: [String, Array] + }, + { + name: "callback", + type: Function + } +]; +const API_EMIT = "$emit"; +const EmitProtocol = [ + { + name: "event", + type: String, + required: true + } +]; +const emitter = new Emitter(); +const $on = /* @__PURE__ */ defineSyncApi( + API_ON, + (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); + }, + OnProtocol +); +const $once = /* @__PURE__ */ defineSyncApi( + API_ONCE, + (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); + }, + OnceProtocol +); +const $off = /* @__PURE__ */ defineSyncApi( + API_OFF, + (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); + }, + OffProtocol +); +const $emit = /* @__PURE__ */ defineSyncApi( + API_EMIT, + (name, ...args) => { + emitter.emit(name, ...args); + }, + EmitProtocol +); +const validator = [ + { + name: "id", + type: String, + required: true + } +]; +const API_CREATE_VIDEO_CONTEXT = "createVideoContext"; +const API_CREATE_MAP_CONTEXT = "createMapContext"; +const CreateMapContextProtocol = validator; +const API_CREATE_CANVAS_CONTEXT = "createCanvasContext"; +const CreateCanvasContextProtocol = [ + { + name: "canvasId", + type: String, + required: true + }, + { + name: "componentInstance", + type: Object + } +]; +const API_CREATE_INNER_AUDIO_CONTEXT = "createInnerAudioContext"; +validator.concat({ + name: "componentInstance", + type: Object +}); +const RATES = [0.5, 0.8, 1, 1.25, 1.5, 2]; +class VideoContext { + constructor(id2, pageId) { + this.id = id2; + this.pageId = pageId; + } + play() { + operateVideoPlayer(this.id, this.pageId, "play"); + } + pause() { + operateVideoPlayer(this.id, this.pageId, "pause"); + } + stop() { + operateVideoPlayer(this.id, this.pageId, "stop"); + } + seek(position) { + operateVideoPlayer(this.id, this.pageId, "seek", { + position + }); + } + sendDanmu(args) { + operateVideoPlayer(this.id, this.pageId, "sendDanmu", args); + } + playbackRate(rate) { + if (!~RATES.indexOf(rate)) { + rate = 1; + } + operateVideoPlayer(this.id, this.pageId, "playbackRate", { + rate + }); + } + requestFullScreen(args = {}) { + operateVideoPlayer(this.id, this.pageId, "requestFullScreen", args); + } + exitFullScreen() { + operateVideoPlayer(this.id, this.pageId, "exitFullScreen"); + } + showStatusBar() { + operateVideoPlayer(this.id, this.pageId, "showStatusBar"); + } + hideStatusBar() { + operateVideoPlayer(this.id, this.pageId, "hideStatusBar"); + } +} +const createVideoContext = /* @__PURE__ */ defineSyncApi( + API_CREATE_VIDEO_CONTEXT, + (id2, context) => { + if (context) { + return new VideoContext(id2, getPageIdByVm(context)); + } + return new VideoContext(id2, getPageIdByVm(getCurrentPageVm())); + } +); +const operateMapCallback = (options, res) => { + const errMsg = res.errMsg || ""; + if (new RegExp("\\:\\s*fail").test(errMsg)) { + options.fail && options.fail(res); + } else { + options.success && options.success(res); + } + options.complete && options.complete(res); +}; +const operateMapWrap = (id2, pageId, type, options) => { + operateMap(id2, pageId, type, options, (res) => { + options && operateMapCallback(options, res); + }); +}; +class MapContext { + constructor(id2, pageId) { + this.id = id2; + this.pageId = pageId; + } + getCenterLocation(options) { + operateMapWrap(this.id, this.pageId, "getCenterLocation", options); + } + moveToLocation(options) { + operateMapWrap(this.id, this.pageId, "moveToLocation", options); + } + getScale(options) { + operateMapWrap(this.id, this.pageId, "getScale", options); + } + getRegion(options) { + operateMapWrap(this.id, this.pageId, "getRegion", options); + } + includePoints(options) { + operateMapWrap(this.id, this.pageId, "includePoints", options); + } + translateMarker(options) { + operateMapWrap(this.id, this.pageId, "translateMarker", options); + } + $getAppMap() { + } + addCustomLayer(options) { + operateMapWrap(this.id, this.pageId, "addCustomLayer", options); + } + removeCustomLayer(options) { + operateMapWrap(this.id, this.pageId, "removeCustomLayer", options); + } + addGroundOverlay(options) { + operateMapWrap(this.id, this.pageId, "addGroundOverlay", options); + } + removeGroundOverlay(options) { + operateMapWrap(this.id, this.pageId, "removeGroundOverlay", options); + } + updateGroundOverlay(options) { + operateMapWrap(this.id, this.pageId, "updateGroundOverlay", options); + } + initMarkerCluster(options) { + operateMapWrap(this.id, this.pageId, "initMarkerCluster", options); + } + addMarkers(options) { + operateMapWrap(this.id, this.pageId, "addMarkers", options); + } + removeMarkers(options) { + operateMapWrap(this.id, this.pageId, "removeMarkers", options); + } + moveAlong(options) { + operateMapWrap(this.id, this.pageId, "moveAlong", options); + } + setLocMarkerIcon(options) { + operateMapWrap(this.id, this.pageId, "setLocMarkerIcon", options); + } + openMapApp(options) { + operateMapWrap(this.id, this.pageId, "openMapApp", options); + } + on(options) { + operateMapWrap(this.id, this.pageId, "on", options); + } +} +const createMapContext = /* @__PURE__ */ defineSyncApi( + API_CREATE_MAP_CONTEXT, + (id2, context) => { + if (context) { + return new MapContext(id2, getPageIdByVm(context)); + } + return new MapContext(id2, getPageIdByVm(getCurrentPageVm())); + }, + CreateMapContextProtocol +); +function getInt(name, defaultValue) { + return function(value, params) { + if (value) { + params[name] = Math.round(value); + } else if (typeof defaultValue !== "undefined") { + params[name] = defaultValue; + } + }; +} +const formatWidth = getInt("width"); +const formatHeight = getInt("height"); +const API_CANVAS_GET_IMAGE_DATA = "canvasGetImageData"; +const CanvasGetImageDataOptions = { + formatArgs: { + x: getInt("x"), + y: getInt("y"), + width: formatWidth, + height: formatHeight + } +}; +const CanvasGetImageDataProtocol = { + canvasId: { + type: String, + required: true + }, + x: { + type: Number, + required: true + }, + y: { + type: Number, + required: true + }, + width: { + type: Number, + required: true + }, + height: { + type: Number, + required: true + } +}; +const API_CANVAS_PUT_IMAGE_DATA = "canvasPutImageData"; +const CanvasPutImageDataOptions = CanvasGetImageDataOptions; +const CanvasPutImageDataProtocol = /* @__PURE__ */ extend( + { + data: { + type: Uint8ClampedArray, + required: true + } + }, + CanvasGetImageDataProtocol, + { + height: { + type: Number + } + } +); +const fileTypes = { + PNG: "png", + JPG: "jpg", + JPEG: "jpg" +}; +const API_CANVAS_TO_TEMP_FILE_PATH = "canvasToTempFilePath"; +const CanvasToTempFilePathOptions = { + formatArgs: { + x: getInt("x", 0), + y: getInt("y", 0), + width: formatWidth, + height: formatHeight, + destWidth: getInt("destWidth"), + destHeight: getInt("destHeight"), + fileType(value, params) { + value = (value || "").toUpperCase(); + let type = fileTypes[value]; + if (!type) { + type = fileTypes.PNG; + } + params.fileType = type; + }, + quality(value, params) { + params.quality = value && value > 0 && value < 1 ? value : 1; + } + } +}; +const CanvasToTempFilePathProtocol = { + x: Number, + y: Number, + width: Number, + height: Number, + destWidth: Number, + destHeight: Number, + canvasId: { + type: String, + required: true + }, + fileType: String, + quality: Number +}; +function operateCanvas(canvasId, pageId, type, data, callback) { + UniServiceJSBridge.invokeViewMethod( + `canvas.${canvasId}`, + { + type, + data + }, + pageId, + (data2) => { + if (callback) + callback(data2); + } + ); +} +var methods1 = ["scale", "rotate", "translate", "setTransform", "transform"]; +var methods2 = [ + "drawImage", + "fillText", + "fill", + "stroke", + "fillRect", + "strokeRect", + "clearRect", + "strokeText" +]; +var methods3 = [ + "setFillStyle", + "setTextAlign", + "setStrokeStyle", + "setGlobalAlpha", + "setShadow", + "setFontSize", + "setLineCap", + "setLineJoin", + "setLineWidth", + "setMiterLimit", + "setTextBaseline", + "setLineDash" +]; +function measureText(text2, font2) { + const canvas = document.createElement("canvas"); + const c2d = canvas.getContext("2d"); + c2d.font = font2; + return c2d.measureText(text2).width || 0; +} +const predefinedColor = { + aliceblue: "#f0f8ff", + antiquewhite: "#faebd7", + aqua: "#00ffff", + aquamarine: "#7fffd4", + azure: "#f0ffff", + beige: "#f5f5dc", + bisque: "#ffe4c4", + black: "#000000", + blanchedalmond: "#ffebcd", + blue: "#0000ff", + blueviolet: "#8a2be2", + brown: "#a52a2a", + burlywood: "#deb887", + cadetblue: "#5f9ea0", + chartreuse: "#7fff00", + chocolate: "#d2691e", + coral: "#ff7f50", + cornflowerblue: "#6495ed", + cornsilk: "#fff8dc", + crimson: "#dc143c", + cyan: "#00ffff", + darkblue: "#00008b", + darkcyan: "#008b8b", + darkgoldenrod: "#b8860b", + darkgray: "#a9a9a9", + darkgrey: "#a9a9a9", + darkgreen: "#006400", + darkkhaki: "#bdb76b", + darkmagenta: "#8b008b", + darkolivegreen: "#556b2f", + darkorange: "#ff8c00", + darkorchid: "#9932cc", + darkred: "#8b0000", + darksalmon: "#e9967a", + darkseagreen: "#8fbc8f", + darkslateblue: "#483d8b", + darkslategray: "#2f4f4f", + darkslategrey: "#2f4f4f", + darkturquoise: "#00ced1", + darkviolet: "#9400d3", + deeppink: "#ff1493", + deepskyblue: "#00bfff", + dimgray: "#696969", + dimgrey: "#696969", + dodgerblue: "#1e90ff", + firebrick: "#b22222", + floralwhite: "#fffaf0", + forestgreen: "#228b22", + fuchsia: "#ff00ff", + gainsboro: "#dcdcdc", + ghostwhite: "#f8f8ff", + gold: "#ffd700", + goldenrod: "#daa520", + gray: "#808080", + grey: "#808080", + green: "#008000", + greenyellow: "#adff2f", + honeydew: "#f0fff0", + hotpink: "#ff69b4", + indianred: "#cd5c5c", + indigo: "#4b0082", + ivory: "#fffff0", + khaki: "#f0e68c", + lavender: "#e6e6fa", + lavenderblush: "#fff0f5", + lawngreen: "#7cfc00", + lemonchiffon: "#fffacd", + lightblue: "#add8e6", + lightcoral: "#f08080", + lightcyan: "#e0ffff", + lightgoldenrodyellow: "#fafad2", + lightgray: "#d3d3d3", + lightgrey: "#d3d3d3", + lightgreen: "#90ee90", + lightpink: "#ffb6c1", + lightsalmon: "#ffa07a", + lightseagreen: "#20b2aa", + lightskyblue: "#87cefa", + lightslategray: "#778899", + lightslategrey: "#778899", + lightsteelblue: "#b0c4de", + lightyellow: "#ffffe0", + lime: "#00ff00", + limegreen: "#32cd32", + linen: "#faf0e6", + magenta: "#ff00ff", + maroon: "#800000", + mediumaquamarine: "#66cdaa", + mediumblue: "#0000cd", + mediumorchid: "#ba55d3", + mediumpurple: "#9370db", + mediumseagreen: "#3cb371", + mediumslateblue: "#7b68ee", + mediumspringgreen: "#00fa9a", + mediumturquoise: "#48d1cc", + mediumvioletred: "#c71585", + midnightblue: "#191970", + mintcream: "#f5fffa", + mistyrose: "#ffe4e1", + moccasin: "#ffe4b5", + navajowhite: "#ffdead", + navy: "#000080", + oldlace: "#fdf5e6", + olive: "#808000", + olivedrab: "#6b8e23", + orange: "#ffa500", + orangered: "#ff4500", + orchid: "#da70d6", + palegoldenrod: "#eee8aa", + palegreen: "#98fb98", + paleturquoise: "#afeeee", + palevioletred: "#db7093", + papayawhip: "#ffefd5", + peachpuff: "#ffdab9", + peru: "#cd853f", + pink: "#ffc0cb", + plum: "#dda0dd", + powderblue: "#b0e0e6", + purple: "#800080", + rebeccapurple: "#663399", + red: "#ff0000", + rosybrown: "#bc8f8f", + royalblue: "#4169e1", + saddlebrown: "#8b4513", + salmon: "#fa8072", + sandybrown: "#f4a460", + seagreen: "#2e8b57", + seashell: "#fff5ee", + sienna: "#a0522d", + silver: "#c0c0c0", + skyblue: "#87ceeb", + slateblue: "#6a5acd", + slategray: "#708090", + slategrey: "#708090", + snow: "#fffafa", + springgreen: "#00ff7f", + steelblue: "#4682b4", + tan: "#d2b48c", + teal: "#008080", + thistle: "#d8bfd8", + tomato: "#ff6347", + turquoise: "#40e0d0", + violet: "#ee82ee", + wheat: "#f5deb3", + white: "#ffffff", + whitesmoke: "#f5f5f5", + yellow: "#ffff00", + yellowgreen: "#9acd32", + transparent: "#00000000" +}; +function checkColor(e2) { + e2 = e2 || "#000000"; + var t2 = null; + if ((t2 = /^#([0-9|A-F|a-f]{6})$/.exec(e2)) != null) { + const n = parseInt(t2[1].slice(0, 2), 16); + const o2 = parseInt(t2[1].slice(2, 4), 16); + const r = parseInt(t2[1].slice(4), 16); + return [n, o2, r, 255]; + } + if ((t2 = /^#([0-9|A-F|a-f]{3})$/.exec(e2)) != null) { + let n = t2[1].slice(0, 1); + let o2 = t2[1].slice(1, 2); + let r = t2[1].slice(2, 3); + n = parseInt(n + n, 16); + o2 = parseInt(o2 + o2, 16); + r = parseInt(r + r, 16); + return [n, o2, r, 255]; + } + if ((t2 = /^rgb\((.+)\)$/.exec(e2)) != null) { + return t2[1].split(",").map(function(e22) { + return Math.min(255, parseInt(e22.trim())); + }).concat(255); + } + if ((t2 = /^rgba\((.+)\)$/.exec(e2)) != null) { + return t2[1].split(",").map(function(e22, t22) { + return t22 === 3 ? Math.floor(255 * parseFloat(e22.trim())) : Math.min(255, parseInt(e22.trim())); + }); + } + var i = e2.toLowerCase(); + if (hasOwn(predefinedColor, i)) { + t2 = /^#([0-9|A-F|a-f]{6,8})$/.exec(predefinedColor[i]); + const n = parseInt(t2[1].slice(0, 2), 16); + const o2 = parseInt(t2[1].slice(2, 4), 16); + const r = parseInt(t2[1].slice(4, 6), 16); + let a2 = parseInt(t2[1].slice(6, 8), 16); + a2 = a2 >= 0 ? a2 : 255; + return [n, o2, r, a2]; + } + console.error("unsupported color:" + e2); + return [0, 0, 0, 255]; +} +class CanvasGradient { + constructor(type, data) { + this.type = type; + this.data = data; + this.colorStop = []; + } + addColorStop(position, color) { + this.colorStop.push([position, checkColor(color)]); + } +} +class Pattern { + constructor(image2, repetition) { + this.type = "pattern"; + this.data = image2; + this.colorStop = repetition; + } +} +class TextMetrics { + constructor(width) { + this.width = width; + } +} +class CanvasContext { + constructor(id2, pageId) { + this.id = id2; + this.pageId = pageId; + this.actions = []; + this.path = []; + this.subpath = []; + this.drawingState = []; + this.state = { + lineDash: [0, 0], + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowBlur: 0, + shadowColor: [0, 0, 0, 0], + font: "10px sans-serif", + fontSize: 10, + fontWeight: "normal", + fontStyle: "normal", + fontFamily: "sans-serif" + }; + } + draw(reserve = false, callback) { + var actions = [...this.actions]; + this.actions = []; + this.path = []; + operateCanvas( + this.id, + this.pageId, + "actionsChanged", + { + actions, + reserve + }, + callback + ); + } + createLinearGradient(x0, y0, x1, y1) { + return new CanvasGradient("linear", [x0, y0, x1, y1]); + } + createCircularGradient(x, y, r) { + return new CanvasGradient("radial", [x, y, r]); + } + createPattern(image2, repetition) { + if (void 0 === repetition) { + console.error( + "Failed to execute 'createPattern' on 'CanvasContext': 2 arguments required, but only 1 present." + ); + } else if (["repeat", "repeat-x", "repeat-y", "no-repeat"].indexOf(repetition) < 0) { + console.error( + "Failed to execute 'createPattern' on 'CanvasContext': The provided type ('" + repetition + "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'." + ); + } else { + return new Pattern(image2, repetition); + } + } + measureText(text2) { + const font2 = this.state.font; + let width = 0; + { + width = measureText(text2, font2); + } + return new TextMetrics(width); + } + save() { + this.actions.push({ + method: "save", + data: [] + }); + this.drawingState.push(this.state); + } + restore() { + this.actions.push({ + method: "restore", + data: [] + }); + this.state = this.drawingState.pop() || { + lineDash: [0, 0], + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowBlur: 0, + shadowColor: [0, 0, 0, 0], + font: "10px sans-serif", + fontSize: 10, + fontWeight: "normal", + fontStyle: "normal", + fontFamily: "sans-serif" + }; + } + beginPath() { + this.path = []; + this.subpath = []; + this.path.push({ + method: "beginPath", + data: [] + }); + } + moveTo(x, y) { + this.path.push({ + method: "moveTo", + data: [x, y] + }); + this.subpath = [[x, y]]; + } + lineTo(x, y) { + if (this.path.length === 0 && this.subpath.length === 0) { + this.path.push({ + method: "moveTo", + data: [x, y] + }); + } else { + this.path.push({ + method: "lineTo", + data: [x, y] + }); + } + this.subpath.push([x, y]); + } + quadraticCurveTo(cpx, cpy, x, y) { + this.path.push({ + method: "quadraticCurveTo", + data: [cpx, cpy, x, y] + }); + this.subpath.push([x, y]); + } + bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) { + this.path.push({ + method: "bezierCurveTo", + data: [cp1x, cp1y, cp2x, cp2y, x, y] + }); + this.subpath.push([x, y]); + } + arc(x, y, r, sAngle, eAngle, counterclockwise = false) { + this.path.push({ + method: "arc", + data: [x, y, r, sAngle, eAngle, counterclockwise] + }); + this.subpath.push([x, y]); + } + rect(x, y, width, height) { + this.path.push({ + method: "rect", + data: [x, y, width, height] + }); + this.subpath = [[x, y]]; + } + arcTo(x1, y1, x2, y2, radius) { + this.path.push({ + method: "arcTo", + data: [x1, y1, x2, y2, radius] + }); + this.subpath.push([x2, y2]); + } + clip() { + this.actions.push({ + method: "clip", + data: [...this.path] + }); + } + closePath() { + this.path.push({ + method: "closePath", + data: [] + }); + if (this.subpath.length) { + this.subpath = [this.subpath.shift()]; + } + } + clearActions() { + this.actions = []; + this.path = []; + this.subpath = []; + } + getActions() { + var actions = [...this.actions]; + this.clearActions(); + return actions; + } + set lineDashOffset(value) { + this.actions.push({ + method: "setLineDashOffset", + data: [value] + }); + } + set globalCompositeOperation(type) { + this.actions.push({ + method: "setGlobalCompositeOperation", + data: [type] + }); + } + set shadowBlur(level) { + this.actions.push({ + method: "setShadowBlur", + data: [level] + }); + } + set shadowColor(color) { + this.actions.push({ + method: "setShadowColor", + data: [color] + }); + } + set shadowOffsetX(x) { + this.actions.push({ + method: "setShadowOffsetX", + data: [x] + }); + } + set shadowOffsetY(y) { + this.actions.push({ + method: "setShadowOffsetY", + data: [y] + }); + } + set font(value) { + var self = this; + this.state.font = value; + var fontFormat = value.match( + /^(([\w\-]+\s)*)(\d+r?px)(\/(\d+\.?\d*(r?px)?))?\s+(.*)/ + ); + if (fontFormat) { + var style = fontFormat[1].trim().split(/\s/); + var fontSize = parseFloat(fontFormat[3]); + var fontFamily = fontFormat[7]; + var actions = []; + style.forEach(function(value2, index2) { + if (["italic", "oblique", "normal"].indexOf(value2) > -1) { + actions.push({ + method: "setFontStyle", + data: [value2] + }); + self.state.fontStyle = value2; + } else if (["bold", "normal"].indexOf(value2) > -1) { + actions.push({ + method: "setFontWeight", + data: [value2] + }); + self.state.fontWeight = value2; + } else if (index2 === 0) { + actions.push({ + method: "setFontStyle", + data: ["normal"] + }); + self.state.fontStyle = "normal"; + } else if (index2 === 1) { + pushAction(); + } + }); + if (style.length === 1) { + pushAction(); + } + style = actions.map(function(action) { + return action.data[0]; + }).join(" "); + this.state.fontSize = fontSize; + this.state.fontFamily = fontFamily; + this.actions.push({ + method: "setFont", + data: [`${style} ${fontSize}px ${fontFamily}`] + }); + } else { + console.warn("Failed to set 'font' on 'CanvasContext': invalid format."); + } + function pushAction() { + actions.push({ + method: "setFontWeight", + data: ["normal"] + }); + self.state.fontWeight = "normal"; + } + } + get font() { + return this.state.font; + } + set fillStyle(color) { + this.setFillStyle(color); + } + set strokeStyle(color) { + this.setStrokeStyle(color); + } + set globalAlpha(value) { + value = Math.floor(255 * parseFloat(value)); + this.actions.push({ + method: "setGlobalAlpha", + data: [value] + }); + } + set textAlign(align2) { + this.actions.push({ + method: "setTextAlign", + data: [align2] + }); + } + set lineCap(type) { + this.actions.push({ + method: "setLineCap", + data: [type] + }); + } + set lineJoin(type) { + this.actions.push({ + method: "setLineJoin", + data: [type] + }); + } + set lineWidth(value) { + this.actions.push({ + method: "setLineWidth", + data: [value] + }); + } + set miterLimit(value) { + this.actions.push({ + method: "setMiterLimit", + data: [value] + }); + } + set textBaseline(type) { + this.actions.push({ + method: "setTextBaseline", + data: [type] + }); + } +} +const initCanvasContextProperty = /* @__PURE__ */ once(() => { + [...methods1, ...methods2].forEach(function(method) { + function get(method2) { + switch (method2) { + case "fill": + case "stroke": + return function() { + this.actions.push({ + method: method2 + "Path", + // @ts-ignore + data: [...this.path] + }); + }; + case "fillRect": + return function(x, y, width, height) { + this.actions.push({ + method: "fillPath", + data: [ + { + method: "rect", + data: [x, y, width, height] + } + ] + }); + }; + case "strokeRect": + return function(x, y, width, height) { + this.actions.push({ + method: "strokePath", + data: [ + { + method: "rect", + data: [x, y, width, height] + } + ] + }); + }; + case "fillText": + case "strokeText": + return function(text2, x, y, maxWidth2) { + var data = [text2.toString(), x, y]; + if (typeof maxWidth2 === "number") { + data.push(maxWidth2); + } + this.actions.push({ + method: method2, + data + }); + }; + case "drawImage": + return function(imageResource, dx, dy, dWidth, dHeight, sx, sy, sWidth, sHeight) { + if (sHeight === void 0) { + sx = dx; + sy = dy; + sWidth = dWidth; + sHeight = dHeight; + dx = void 0; + dy = void 0; + dWidth = void 0; + dHeight = void 0; + } + var data; + function isNumber(e2) { + return typeof e2 === "number"; + } + data = isNumber(dx) && isNumber(dy) && isNumber(dWidth) && isNumber(dHeight) ? [ + imageResource, + sx, + sy, + sWidth, + sHeight, + dx, + dy, + dWidth, + dHeight + ] : isNumber(sWidth) && isNumber(sHeight) ? [imageResource, sx, sy, sWidth, sHeight] : [imageResource, sx, sy]; + this.actions.push({ + method: method2, + data + }); + }; + default: + return function(...data) { + this.actions.push({ + method: method2, + data + }); + }; + } + } + CanvasContext.prototype[method] = get(method); + }); + methods3.forEach(function(method) { + function get(method2) { + switch (method2) { + case "setFillStyle": + case "setStrokeStyle": + return function(color) { + if (typeof color !== "object") { + this.actions.push({ + method: method2, + data: ["normal", checkColor(color)] + }); + } else { + this.actions.push({ + method: method2, + data: [color.type, color.data, color.colorStop] + }); + } + }; + case "setGlobalAlpha": + return function(alpha) { + alpha = Math.floor(255 * parseFloat(alpha)); + this.actions.push({ + method: method2, + data: [alpha] + }); + }; + case "setShadow": + return function(offsetX, offsetY, blur, color) { + color = checkColor(color); + this.actions.push({ + method: method2, + data: [offsetX, offsetY, blur, color] + }); + this.state.shadowBlur = blur; + this.state.shadowColor = color; + this.state.shadowOffsetX = offsetX; + this.state.shadowOffsetY = offsetY; + }; + case "setLineDash": + return function(pattern, offset) { + pattern = pattern || [0, 0]; + offset = offset || 0; + this.actions.push({ + method: method2, + data: [pattern, offset] + }); + this.state.lineDash = pattern; + }; + case "setFontSize": + return function(fontSize) { + this.state.font = this.state.font.replace( + /\d+\.?\d*px/, + fontSize + "px" + ); + this.state.fontSize = fontSize; + this.actions.push({ + method: method2, + data: [fontSize] + }); + }; + default: + return function(...data) { + this.actions.push({ + method: method2, + data + }); + }; + } + } + CanvasContext.prototype[method] = get(method); + }); +}); +const createCanvasContext = /* @__PURE__ */ defineSyncApi( + API_CREATE_CANVAS_CONTEXT, + (canvasId, componentInstance) => { + initCanvasContextProperty(); + if (componentInstance) { + return new CanvasContext(canvasId, getPageIdByVm(componentInstance)); + } + const pageId = getPageIdByVm(getCurrentPageVm()); + if (pageId) { + return new CanvasContext(canvasId, pageId); + } else { + UniServiceJSBridge.emit(ON_ERROR, "createCanvasContext:fail"); + } + }, + CreateCanvasContextProtocol +); +const canvasGetImageData = /* @__PURE__ */ defineAsyncApi( + API_CANVAS_GET_IMAGE_DATA, + ({ canvasId, x, y, width, height }, { resolve, reject }) => { + const pageId = getPageIdByVm(getCurrentPageVm()); + if (!pageId) { + reject(); + return; + } + function callback(data) { + if (data.errMsg && data.errMsg.indexOf("fail") !== -1) { + reject("", data); + return; + } + let imgData = data.data; + if (imgData && imgData.length) { + data.data = new Uint8ClampedArray(imgData); + } + delete data.compressed; + resolve(data); + } + operateCanvas( + canvasId, + pageId, + "getImageData", + { + x, + y, + width, + height + }, + callback + ); + }, + CanvasGetImageDataProtocol, + CanvasGetImageDataOptions +); +const canvasPutImageData = /* @__PURE__ */ defineAsyncApi( + API_CANVAS_PUT_IMAGE_DATA, + ({ canvasId, data, x, y, width, height }, { resolve, reject }) => { + var pageId = getPageIdByVm(getCurrentPageVm()); + if (!pageId) { + reject(); + return; + } + let compressed; + const operate = () => { + operateCanvas( + canvasId, + pageId, + "putImageData", + { + data, + x, + y, + width, + height, + compressed + }, + (data2) => { + if (data2.errMsg && data2.errMsg.indexOf("fail") !== -1) { + reject(); + return; + } + resolve(data2); + } + ); + }; + { + data = Array.prototype.slice.call(data); + } + operate(); + }, + CanvasPutImageDataProtocol, + CanvasPutImageDataOptions +); +const canvasToTempFilePath = /* @__PURE__ */ defineAsyncApi( + API_CANVAS_TO_TEMP_FILE_PATH, + ({ + x = 0, + y = 0, + width, + height, + destWidth, + destHeight, + canvasId, + fileType, + quality + }, { resolve, reject }) => { + var pageId = getPageIdByVm(getCurrentPageVm()); + if (!pageId) { + reject(); + return; + } + const dirname = `${TEMP_PATH}/canvas`; + operateCanvas( + canvasId, + pageId, + "toTempFilePath", + { + x, + y, + width, + height, + destWidth, + destHeight, + fileType, + quality, + dirname + }, + (res) => { + if (res.errMsg && res.errMsg.indexOf("fail") !== -1) { + reject("", res); + return; + } + resolve(res); + } + ); + }, + CanvasToTempFilePathProtocol, + CanvasToTempFilePathOptions +); +const innerAudioContextEventNames = [ + "onCanplay", + "onPlay", + "onPause", + "onStop", + "onEnded", + "onTimeUpdate", + "onError", + "onWaiting", + "onSeeking", + "onSeeked" +]; +const innerAudioContextOffEventNames = [ + "offCanplay", + "offPlay", + "offPause", + "offStop", + "offEnded", + "offTimeUpdate", + "offError", + "offWaiting", + "offSeeking", + "offSeeked" +]; +const defaultOptions = { + thresholds: [0], + initialRatio: 0, + observeAll: false +}; +const MARGINS = ["top", "right", "bottom", "left"]; +let reqComponentObserverId$1 = 1; +function normalizeRootMargin(margins = {}) { + return MARGINS.map( + (name) => `${Number(margins[name]) || 0}px` + ).join(" "); +} +class ServiceIntersectionObserver { + constructor(component, options) { + this._pageId = getPageIdByVm(component); + this._component = component; + this._options = extend({}, defaultOptions, options); + } + relativeTo(selector, margins) { + this._options.relativeToSelector = selector; + this._options.rootMargin = normalizeRootMargin(margins); + return this; + } + relativeToViewport(margins) { + this._options.relativeToSelector = void 0; + this._options.rootMargin = normalizeRootMargin(margins); + return this; + } + observe(selector, callback) { + if (!isFunction(callback)) { + return; + } + this._options.selector = selector; + this._reqId = reqComponentObserverId$1++; + addIntersectionObserver( + { + reqId: this._reqId, + component: this._component, + options: this._options, + callback + }, + this._pageId + ); + } + disconnect() { + this._reqId && removeIntersectionObserver( + { reqId: this._reqId, component: this._component }, + this._pageId + ); + } +} +const createIntersectionObserver = /* @__PURE__ */ defineSyncApi("createIntersectionObserver", (context, options) => { + context = resolveComponentInstance(context); + if (context && !getPageIdByVm(context)) { + options = context; + context = null; + } + if (context) { + return new ServiceIntersectionObserver(context, options); + } + return new ServiceIntersectionObserver(getCurrentPageVm(), options); +}); +let reqComponentObserverId = 1; +class ServiceMediaQueryObserver { + constructor(component) { + this._pageId = component.$page && component.$page.id; + this._component = component; + } + observe(options, callback) { + if (!isFunction(callback)) { + return; + } + this._reqId = reqComponentObserverId++; + addMediaQueryObserver( + { + reqId: this._reqId, + component: this._component, + options, + callback + }, + this._pageId + ); + } + disconnect() { + this._reqId && removeMediaQueryObserver( + { + reqId: this._reqId, + component: this._component + }, + this._pageId + ); + } +} +const createMediaQueryObserver = /* @__PURE__ */ defineSyncApi("createMediaQueryObserver", (context) => { + context = resolveComponentInstance(context); + if (context && !getPageIdByVm(context)) { + context = null; + } + if (context) { + return new ServiceMediaQueryObserver(context); + } + return new ServiceMediaQueryObserver(getCurrentPageVm()); +}); +let index$w = 0; +let optionsCache = {}; +function operateEditor(componentId, pageId, type, options) { + const data = { options }; + const needCallOptions = options && ("success" in options || "fail" in options || "complete" in options); + if (needCallOptions) { + const callbackId = String(index$w++); + data.callbackId = callbackId; + optionsCache[callbackId] = options; + } + UniServiceJSBridge.invokeViewMethod( + `editor.${componentId}`, + { + type, + data + }, + pageId, + ({ callbackId, data: data2 }) => { + if (needCallOptions) { + callOptions(optionsCache[callbackId], data2); + delete optionsCache[callbackId]; + } + } + ); +} +class EditorContext { + constructor(id2, pageId) { + this.id = id2; + this.pageId = pageId; + } + format(name, value) { + this._exec("format", { + name, + value + }); + } + insertDivider() { + this._exec("insertDivider"); + } + insertImage(options) { + this._exec("insertImage", options); + } + insertText(options) { + this._exec("insertText", options); + } + setContents(options) { + this._exec("setContents", options); + } + getContents(options) { + this._exec("getContents", options); + } + clear(options) { + this._exec("clear", options); + } + removeFormat(options) { + this._exec("removeFormat", options); + } + undo(options) { + this._exec("undo", options); + } + redo(options) { + this._exec("redo", options); + } + blur(options) { + this._exec("blur", options); + } + getSelectionText(options) { + this._exec("getSelectionText", options); + } + scrollIntoView(options) { + this._exec("scrollIntoView", options); + } + _exec(method, options) { + operateEditor(this.id, this.pageId, method, options); + } +} +const ContextClasss = { + canvas: CanvasContext, + map: MapContext, + video: VideoContext, + editor: EditorContext +}; +function convertContext(result) { + if (result && result.contextInfo) { + const { id: id2, type, page } = result.contextInfo; + const ContextClass = ContextClasss[type]; + result.context = new ContextClass(id2, page); + delete result.contextInfo; + } +} +class NodesRef { + constructor(selectorQuery, component, selector, single) { + this._selectorQuery = selectorQuery; + this._component = component; + this._selector = selector; + this._single = single; + } + boundingClientRect(callback) { + this._selectorQuery._push( + this._selector, + this._component, + this._single, + { + id: true, + dataset: true, + rect: true, + size: true + }, + callback + ); + return this._selectorQuery; + } + fields(fields2, callback) { + this._selectorQuery._push( + this._selector, + this._component, + this._single, + fields2, + callback + ); + return this._selectorQuery; + } + scrollOffset(callback) { + this._selectorQuery._push( + this._selector, + this._component, + this._single, + { + id: true, + dataset: true, + scrollOffset: true + }, + callback + ); + return this._selectorQuery; + } + context(callback) { + this._selectorQuery._push( + this._selector, + this._component, + this._single, + { + context: true + }, + callback + ); + return this._selectorQuery; + } + node(_callback) { + return this._selectorQuery; + } +} +class SelectorQuery { + constructor(page) { + this._component = void 0; + this._page = page; + this._queue = []; + this._queueCb = []; + } + exec(callback) { + requestComponentInfo( + this._page, + this._queue, + (res) => { + const queueCbs = this._queueCb; + res.forEach((result, index2) => { + if (isArray(result)) { + result.forEach(convertContext); + } else { + convertContext(result); + } + const queueCb = queueCbs[index2]; + if (isFunction(queueCb)) { + queueCb.call(this, result); + } + }); + if (isFunction(callback)) { + callback.call(this, res); + } + } + ); + return this._nodesRef; + } + in(component) { + this._component = resolveComponentInstance(component); + return this; + } + select(selector) { + return this._nodesRef = new NodesRef( + this, + this._component, + selector, + true + ); + } + selectAll(selector) { + return this._nodesRef = new NodesRef( + this, + this._component, + selector, + false + ); + } + selectViewport() { + return this._nodesRef = new NodesRef(this, null, "", true); + } + _push(selector, component, single, fields2, callback) { + this._queue.push({ + component, + selector, + single, + fields: fields2 + }); + this._queueCb.push(callback); + } +} +const createSelectorQuery = /* @__PURE__ */ defineSyncApi("createSelectorQuery", (context) => { + context = resolveComponentInstance(context); + if (context && !getPageIdByVm(context)) { + context = null; + } + return new SelectorQuery(context || getCurrentPageVm()); +}); +const API_CREATE_ANIMATION = "createAnimation"; +const CreateAnimationOptions = { + // 目前参数校验不支持此api校验 + formatArgs: { + /* duration: 400, + timingFunction(timingFunction, params) { + params.timingFunction = elemInArray(timingFunction, timingFunctions) + }, + delay: 0, + transformOrigin: '50% 50% 0', */ + } +}; +const CreateAnimationProtocol = { + duration: Number, + timingFunction: String, + delay: Number, + transformOrigin: String +}; +const defaultOption = { + duration: 400, + timingFunction: "linear", + delay: 0, + transformOrigin: "50% 50% 0" +}; +class MPAnimation { + constructor(option) { + this.actions = []; + this.currentTransform = {}; + this.currentStepAnimates = []; + this.option = extend({}, defaultOption, option); + } + _getOption(option) { + const _option = { + transition: extend({}, this.option, option), + transformOrigin: "" + }; + _option.transformOrigin = _option.transition.transformOrigin; + delete _option.transition.transformOrigin; + return _option; + } + _pushAnimates(type, args) { + this.currentStepAnimates.push({ + type, + args + }); + } + _converType(type) { + return type.replace(/[A-Z]/g, (text2) => { + return `-${text2.toLowerCase()}`; + }); + } + _getValue(value) { + return typeof value === "number" ? `${value}px` : value; + } + export() { + const actions = this.actions; + this.actions = []; + return { + actions + }; + } + step(option) { + this.currentStepAnimates.forEach((animate) => { + if (animate.type !== "style") { + this.currentTransform[animate.type] = animate; + } else { + this.currentTransform[`${animate.type}.${animate.args[0]}`] = animate; + } + }); + this.actions.push({ + animates: Object.values( + this.currentTransform + ), + option: this._getOption(option) + }); + this.currentStepAnimates = []; + return this; + } +} +const initAnimationProperty = /* @__PURE__ */ once(() => { + const animateTypes1 = [ + "matrix", + "matrix3d", + "rotate", + "rotate3d", + "rotateX", + "rotateY", + "rotateZ", + "scale", + "scale3d", + "scaleX", + "scaleY", + "scaleZ", + "skew", + "skewX", + "skewY", + "translate", + "translate3d", + "translateX", + "translateY", + "translateZ" + ]; + const animateTypes2 = ["opacity", "backgroundColor"]; + const animateTypes3 = ["width", "height", "left", "right", "top", "bottom"]; + animateTypes1.concat(animateTypes2, animateTypes3).forEach((type) => { + MPAnimation.prototype[type] = function(...args) { + if (animateTypes2.concat(animateTypes3).includes(type)) { + this._pushAnimates("style", [ + this._converType(type), + animateTypes3.includes(type) ? this._getValue(args[0]) : args[0] + ]); + } else { + this._pushAnimates(type, args); + } + return this; + }; + }); +}); +const createAnimation$1 = /* @__PURE__ */ defineSyncApi( + API_CREATE_ANIMATION, + (option) => { + initAnimationProperty(); + return new MPAnimation(option); + }, + CreateAnimationProtocol, + CreateAnimationOptions +); +const API_ON_TAB_BAR_MID_BUTTON_TAP = "onTabBarMidButtonTap"; +const onTabBarMidButtonTap = /* @__PURE__ */ defineOnApi( + API_ON_TAB_BAR_MID_BUTTON_TAP, + () => { + } +); +const API_ON_WINDOW_RESIZE = "onWindowResize"; +const API_OFF_WINDOW_RESIZE = "offWindowResize"; +const onWindowResize = /* @__PURE__ */ defineOnApi( + API_ON_WINDOW_RESIZE, + () => { + } +); +const offWindowResize = /* @__PURE__ */ defineOffApi( + API_OFF_WINDOW_RESIZE, + () => { + } +); +const API_SET_LOCALE = "setLocale"; +const API_GET_LOCALE = "getLocale"; +const API_ON_LOCALE_CHANGE = "onLocaleChange"; +const getLocale = /* @__PURE__ */ defineSyncApi( + API_GET_LOCALE, + () => { + const app = getApp({ allowDefault: true }); + if (app && app.$vm) { + return app.$vm.$locale; + } + return useI18n().getLocale(); + } +); +const onLocaleChange = /* @__PURE__ */ defineOnApi( + API_ON_LOCALE_CHANGE, + () => { + } +); +const setLocale = /* @__PURE__ */ defineSyncApi( + API_SET_LOCALE, + (locale) => { + const app = getApp(); + if (!app) { + return false; + } + const oldLocale = app.$vm.$locale; + if (oldLocale !== locale) { + app.$vm.$locale = locale; + { + navigator.cookieEnabled && window.localStorage && (localStorage[UNI_STORAGE_LOCALE] = locale); + } + UniServiceJSBridge.invokeOnCallback(API_ON_LOCALE_CHANGE, { locale }); + return true; + } + return false; + } +); +const API_SET_PAGE_META = "setPageMeta"; +const setPageMeta = /* @__PURE__ */ defineAsyncApi( + API_SET_PAGE_META, + (options, { resolve }) => { + resolve(setCurrentPageMeta(getCurrentPageVm(), options)); + } +); +const API_GET_SELECTED_TEXT_RANGE = "getSelectedTextRange"; +const getSelectedTextRange$1 = /* @__PURE__ */ defineAsyncApi( + API_GET_SELECTED_TEXT_RANGE, + (_, { resolve, reject }) => { + UniServiceJSBridge.invokeViewMethod(API_GET_SELECTED_TEXT_RANGE, {}, getCurrentPageId(), (res) => { + if (typeof res.end === "undefined" && typeof res.start === "undefined") { + reject("no focused"); + } else { + resolve(res); + } + }); + } +); +const appHooks = { + [ON_UNHANDLE_REJECTION]: [], + [ON_PAGE_NOT_FOUND]: [], + [ON_ERROR]: [], + [ON_SHOW]: [], + [ON_HIDE]: [] +}; +function onAppHook(type, hook) { + const app = getApp({ allowDefault: true }); + if (app && app.$vm) { + return injectHook(type, hook, app.$vm.$); + } + appHooks[type].push(hook); +} +function injectAppHooks(appInstance) { + Object.keys(appHooks).forEach((type) => { + appHooks[type].forEach((hook) => { + injectHook(type, hook, appInstance); + }); + }); +} +function offAppHook(type, hook) { + const app = getApp({ allowDefault: true }); + if (app && app.$vm) { + return removeHook(app.$vm, type, hook); + } + remove(appHooks[type], hook); +} +function onUnhandledRejection(hook) { + onAppHook(ON_UNHANDLE_REJECTION, hook); +} +function offUnhandledRejection(hook) { + offAppHook(ON_UNHANDLE_REJECTION, hook); +} +function onPageNotFound(hook) { + onAppHook(ON_PAGE_NOT_FOUND, hook); +} +function offPageNotFound(hook) { + offAppHook(ON_PAGE_NOT_FOUND, hook); +} +function onError(hook) { + if (window.weibo) { + window.weibo.onError(hook); + return; + } + onAppHook(ON_ERROR, hook); +} +function offError(hook) { + if (window.weibo) { + window.weibo.offError(hook); + return; + } + offAppHook(ON_ERROR, hook); +} +function onAppShow(hook) { + if (window.weibo) { + window.weibo.onAppShow(hook); + return; + } + onAppHook(ON_SHOW, hook); +} +function offAppShow(hook) { + if (window.weibo) { + window.weibo.offAppShow(hook); + return; + } + offAppHook(ON_SHOW, hook); +} +function onAppHide(hook) { + if (window.weibo) { + window.weibo.onAppHide(hook); + return; + } + onAppHook(ON_HIDE, hook); +} +function offAppHide(hook) { + if (window.weibo) { + window.weibo.offAppHide(hook); + return; + } + offAppHook(ON_HIDE, hook); +} +const API_GET_ENTER_OPTIONS_SYNC = "getEnterOptionsSync"; +const getEnterOptionsSync = /* @__PURE__ */ defineSyncApi( + API_GET_ENTER_OPTIONS_SYNC, + () => { + return getEnterOptions(); + } +); +const API_GET_LAUNCH_OPTIONS_SYNC = "getLaunchOptionsSync"; +const getLaunchOptionsSync = /* @__PURE__ */ defineSyncApi( + API_GET_LAUNCH_OPTIONS_SYNC, + () => { + return getLaunchOptions(); + } +); +let cid; +let cidErrMsg; +let enabled; +function normalizePushMessage(message) { + try { + return JSON.parse(message); + } catch (e2) { + } + return message; +} +function invokePushCallback(args) { + if (args.type === "enabled") { + enabled = true; + } else if (args.type === "clientId") { + cid = args.cid; + cidErrMsg = args.errMsg; + invokeGetPushCidCallbacks(cid, args.errMsg); + } else if (args.type === "pushMsg") { + const message = { + type: "receive", + data: normalizePushMessage(args.message) + }; + for (let i = 0; i < onPushMessageCallbacks.length; i++) { + const callback = onPushMessageCallbacks[i]; + callback(message); + if (message.stopped) { + break; + } + } + } else if (args.type === "click") { + onPushMessageCallbacks.forEach((callback) => { + callback({ + type: "click", + data: normalizePushMessage(args.message) + }); + }); + } +} +const getPushCidCallbacks = []; +function invokeGetPushCidCallbacks(cid2, errMsg) { + getPushCidCallbacks.forEach((callback) => { + callback(cid2, errMsg); + }); + getPushCidCallbacks.length = 0; +} +const API_GET_PUSH_CLIENT_ID = "getPushClientId"; +const getPushClientId = /* @__PURE__ */ defineAsyncApi( + API_GET_PUSH_CLIENT_ID, + (_, { resolve, reject }) => { + Promise.resolve().then(() => { + if (typeof enabled === "undefined") { + enabled = false; + cid = ""; + cidErrMsg = "uniPush is not enabled"; + } + getPushCidCallbacks.push((cid2, errMsg) => { + if (cid2) { + resolve({ cid: cid2 }); + } else { + reject(errMsg); + } + }); + if (typeof cid !== "undefined") { + invokeGetPushCidCallbacks(cid, cidErrMsg); + } + }); + } +); +const onPushMessageCallbacks = []; +const onPushMessage = (fn) => { + if (onPushMessageCallbacks.indexOf(fn) === -1) { + onPushMessageCallbacks.push(fn); + } +}; +const offPushMessage = (fn) => { + if (!fn) { + onPushMessageCallbacks.length = 0; + } else { + const index2 = onPushMessageCallbacks.indexOf(fn); + if (index2 > -1) { + onPushMessageCallbacks.splice(index2, 1); + } + } +}; +const API_CAN_I_USE = "canIUse"; +const CanIUseProtocol = [ + { + name: "schema", + type: String, + required: true + } +]; +const API_MAKE_PHONE_CALL = "makePhoneCall"; +const MakePhoneCallProtocol = { + phoneNumber: String +}; +const API_GET_CLIPBOARD_DATA = "getClipboardData"; +const API_SET_CLIPBOARD_DATA = "setClipboardData"; +const SetClipboardDataOptions = { + formatArgs: { + showToast: true + }, + beforeInvoke() { + initI18nSetClipboardDataMsgsOnce(); + }, + beforeSuccess(res, params) { + if (!params.showToast) + return; + const { t: t2 } = useI18n(); + const title = t2("uni.setClipboardData.success"); + if (title) { + uni.showToast({ + title, + icon: "success", + mask: false + }); + } + } +}; +const SetClipboardDataProtocol = { + data: { + type: String, + required: true + }, + showToast: { + type: Boolean + } +}; +const API_ON_ACCELEROMETER = "onAccelerometer"; +const API_OFF_ACCELEROMETER = "offAccelerometer"; +const API_START_ACCELEROMETER = "startAccelerometer"; +const API_STOP_ACCELEROMETER = "stopAccelerometer"; +const API_ON_COMPASS = "onCompass"; +const API_OFF_COMPASS = "offCompass"; +const API_START_COMPASS = "startCompass"; +const API_STOP_COMPASS = "stopCompass"; +const API_VIBRATE_SHORT = "vibrateShort"; +const API_VIBRATE_LONG = "vibrateLong"; +const API_GET_STORAGE = "getStorage"; +const GetStorageProtocol = { + key: { + type: String, + required: true + } +}; +const API_GET_STORAGE_SYNC = "getStorageSync"; +const GetStorageSyncProtocol = [ + { + name: "key", + type: String, + required: true + } +]; +const API_SET_STORAGE = "setStorage"; +const SetStorageProtocol = { + key: { + type: String, + required: true + }, + data: { + required: true + } +}; +const API_SET_STORAGE_SYNC = "setStorageSync"; +const SetStorageSyncProtocol = [ + { + name: "key", + type: String, + required: true + }, + { + name: "data", + required: true + } +]; +const API_REMOVE_STORAGE = "removeStorage"; +const RemoveStorageProtocol = GetStorageProtocol; +const RemoveStorageSyncProtocol = GetStorageSyncProtocol; +const API_GET_FILE_INFO = "getFileInfo"; +const GetFileInfoOptions = { + formatArgs: { + filePath(filePath, params) { + params.filePath = getRealPath(filePath); + } + } +}; +const GetFileInfoProtocol = { + filePath: { + type: String, + required: true + } +}; +const API_OPEN_DOCUMENT = "openDocument"; +const OpenDocumentOptions = { + formatArgs: { + filePath(filePath, params) { + params.filePath = getRealPath(filePath); + } + } +}; +const OpenDocumentProtocol = { + filePath: { + type: String, + required: true + }, + fileType: String +}; +const API_HIDE_KEYBOARD = "hideKeyboard"; +const API_CHOOSE_LOCATION = "chooseLocation"; +const ChooseLocationProtocol = { + keyword: String, + latitude: Number, + longitude: Number +}; +const API_GET_LOCATION = "getLocation"; +const coordTypes$1 = ["wgs84", "gcj02"]; +const GetLocationOptions = { + formatArgs: { + type(value, params) { + value = (value || "").toLowerCase(); + if (coordTypes$1.indexOf(value) === -1) { + params.type = coordTypes$1[0]; + } else { + params.type = value; + } + }, + altitude(value, params) { + params.altitude = value ? value : false; + } + } +}; +const GetLocationProtocol = { + type: String, + altitude: Boolean +}; +const API_OPEN_LOCATION = "openLocation"; +const checkProps = (key, value) => { + if (value === void 0) { + return `${key} should not be empty.`; + } + if (typeof value !== "number") { + let receivedType = typeof value; + receivedType = receivedType[0].toUpperCase() + receivedType.substring(1); + return `Expected Number, got ${receivedType} with value ${JSON.stringify( + value + )}.`; + } +}; +const OpenLocationOptions = { + formatArgs: { + latitude(value, params) { + const checkedInfo = checkProps("latitude", value); + if (checkedInfo) { + return checkedInfo; + } + params.latitude = value; + }, + longitude(value, params) { + const checkedInfo = checkProps("longitude", value); + if (checkedInfo) { + return checkedInfo; + } + params.longitude = value; + }, + scale(value, params) { + value = Math.floor(value); + params.scale = value >= 5 && value <= 18 ? value : 18; + } + } +}; +const OpenLocationProtocol = { + latitude: Number, + longitude: Number, + scale: Number, + name: String, + address: String +}; +const API_CHOOSE_IMAGE = "chooseImage"; +const ChooseImageOptions = { + formatArgs: { + count(value, params) { + if (!value || value <= 0) { + params.count = 9; + } + }, + sizeType(sizeType, params) { + params.sizeType = elemsInArray(sizeType, CHOOSE_SIZE_TYPES); + }, + sourceType(sourceType, params) { + params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES); + }, + extension(extension, params) { + if (extension instanceof Array && extension.length === 0) { + return "param extension should not be empty."; + } + if (!extension) + params.extension = ["*"]; + } + } +}; +const ChooseImageProtocol = { + count: Number, + sizeType: [Array, String], + sourceType: Array, + extension: Array +}; +const API_CHOOSE_VIDEO = "chooseVideo"; +const ChooseVideoOptions = { + formatArgs: { + sourceType(sourceType, params) { + params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES); + }, + compressed: true, + maxDuration: 60, + camera: "back", + extension(extension, params) { + if (extension instanceof Array && extension.length === 0) { + return "param extension should not be empty."; + } + if (!extension) + params.extension = ["*"]; + } + } +}; +const ChooseVideoProtocol = { + sourceType: Array, + compressed: Boolean, + maxDuration: Number, + camera: String, + extension: Array +}; +const API_CHOOSE_FILE = "chooseFile"; +const CHOOSE_MEDIA_TYPE = [ + "all", + "image", + "video" +]; +const ChooseFileOptions = { + formatArgs: { + count(count, params) { + if (!count || count <= 0) { + params.count = 100; + } + }, + sourceType(sourceType, params) { + params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES); + }, + type(type, params) { + params.type = elemInArray(type, CHOOSE_MEDIA_TYPE); + }, + extension(extension, params) { + if (extension instanceof Array && extension.length === 0) { + return "param extension should not be empty."; + } + if (!extension) + params.extension = [""]; + } + } +}; +const ChooseFileProtocol = { + count: Number, + sourceType: Array, + type: String, + extension: Array +}; +const API_GET_IMAGE_INFO = "getImageInfo"; +const GetImageInfoOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src); + } + } +}; +const GetImageInfoProtocol = { + src: { + type: String, + required: true + } +}; +const API_PREVIEW_IMAGE = "previewImage"; +const PreviewImageOptions = { + formatArgs: { + urls(urls, params) { + params.urls = urls.map( + (url) => isString(url) && url ? getRealPath(url) : "" + ); + }, + current(current, params) { + if (typeof current === "number") { + params.current = current > 0 && current < params.urls.length ? current : 0; + } else if (isString(current) && current) { + params.current = getRealPath(current); + } + } + } +}; +const PreviewImageProtocol = { + urls: { + type: Array, + required: true + }, + current: { + type: [Number, String] + } +}; +const API_CLOSE_PREVIEW_IMAGE = "closePreviewImage"; +const API_GET_VIDEO_INFO = "getVideoInfo"; +const GetVideoInfoOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src); + } + } +}; +const GetVideoInfoProtocol = { + src: { + type: String, + required: true + } +}; +const API_SAVE_IMAGE_TO_PHOTOS_ALBUM = "saveImageToPhotosAlbum"; +const API_SAVE_VIDEO_TO_PHOTOS_ALBUM = "saveVideoToPhotosAlbum"; +const API_REQUEST = "request"; +const dataType = { + JSON: "json" +}; +const RESPONSE_TYPE = ["text", "arraybuffer"]; +const DEFAULT_RESPONSE_TYPE = "text"; +const encode = encodeURIComponent; +function stringifyQuery(url, data) { + let str = url.split("#"); + const hash = str[1] || ""; + str = str[0].split("?"); + let query = str[1] || ""; + url = str[0]; + const search = query.split("&").filter((item) => item); + const params = {}; + search.forEach((item) => { + const part = item.split("="); + params[part[0]] = part[1]; + }); + for (const key in data) { + if (hasOwn(data, key)) { + let v2 = data[key]; + if (typeof v2 === "undefined" || v2 === null) { + v2 = ""; + } else if (isPlainObject(v2)) { + v2 = JSON.stringify(v2); + } + params[encode(key)] = encode(v2); + } + } + query = Object.keys(params).map((item) => `${item}=${params[item]}`).join("&"); + return url + (query ? "?" + query : "") + (hash ? "#" + hash : ""); +} +const RequestProtocol = { + method: String, + data: [Object, String, Array, ArrayBuffer], + url: { + type: String, + required: true + }, + header: Object, + dataType: String, + responseType: String, + withCredentials: Boolean +}; +const RequestOptions = { + formatArgs: { + method(value, params) { + params.method = elemInArray( + (value || "").toUpperCase(), + HTTP_METHODS + ); + }, + data(value, params) { + params.data = value || ""; + }, + url(value, params) { + if (params.method === HTTP_METHODS[0] && isPlainObject(params.data) && Object.keys(params.data).length) { + params.url = stringifyQuery(value, params.data); + } + }, + header(value, params) { + const header = params.header = value || {}; + if (params.method !== HTTP_METHODS[0]) { + if (!Object.keys(header).find( + (key) => key.toLowerCase() === "content-type" + )) { + header["Content-Type"] = "application/json"; + } + } + }, + dataType(value, params) { + params.dataType = (value || dataType.JSON).toLowerCase(); + }, + responseType(value, params) { + params.responseType = (value || "").toLowerCase(); + if (RESPONSE_TYPE.indexOf(params.responseType) === -1) { + params.responseType = DEFAULT_RESPONSE_TYPE; + } + } + } +}; +const API_DOWNLOAD_FILE = "downloadFile"; +const DownloadFileOptions = { + formatArgs: { + header(value, params) { + params.header = value || {}; + } + } +}; +const DownloadFileProtocol = { + url: { + type: String, + required: true + }, + header: Object, + timeout: Number +}; +const API_UPLOAD_FILE = "uploadFile"; +const UploadFileOptions = { + formatArgs: { + filePath(filePath, params) { + if (filePath) { + params.filePath = getRealPath(filePath); + } + }, + header(value, params) { + params.header = value || {}; + }, + formData(value, params) { + params.formData = value || {}; + } + } +}; +const UploadFileProtocol = { + url: { + type: String, + required: true + }, + files: Array, + filePath: String, + name: String, + header: Object, + formData: Object, + timeout: Number +}; +const API_CONNECT_SOCKET = "connectSocket"; +const ConnectSocketOptions = { + formatArgs: { + header(value, params) { + params.header = value || {}; + }, + method(value, params) { + params.method = elemInArray( + (value || "").toUpperCase(), + HTTP_METHODS + ); + }, + protocols(protocols, params) { + if (isString(protocols)) { + params.protocols = [protocols]; + } + } + } +}; +const ConnectSocketProtocol = { + url: { + type: String, + required: true + }, + header: { + type: Object + }, + method: String, + protocols: [Array, String] +}; +const API_SEND_SOCKET_MESSAGE = "sendSocketMessage"; +const SendSocketMessageProtocol = { + data: [String, ArrayBuffer] +}; +const API_CLOSE_SOCKET = "closeSocket"; +const CloseSocketProtocol = { + code: Number, + reason: String +}; +const API_START_LOCATION_UPDATE = "startLocationUpdate"; +const API_ON_LOCATION_CHANGE = "onLocationChange"; +const API_STOP_LOCATION_UPDATE = "stopLocationUpdate"; +const API_OFF_LOCATION_CHANGE = "offLocationChange"; +const API_OFF_LOCATION_CHANGE_ERROR = "offLocationChangeError"; +const API_ON_LOCATION_CHANGE_ERROR = "onLocationChangeError"; +const coordTypes = ["wgs84", "gcj02"]; +const StartLocationUpdateProtocol = { + type: String +}; +const StartLocationUpdateOptions = { + formatArgs: { + type(value, params) { + value = (value || "").toLowerCase(); + if (coordTypes.indexOf(value) === -1) { + params.type = coordTypes[1]; + } else { + params.type = value; + } + } + } +}; +function encodeQueryString(url) { + if (!isString(url)) { + return url; + } + const index2 = url.indexOf("?"); + if (index2 === -1) { + return url; + } + const query = url.slice(index2 + 1).trim().replace(/^(\?|#|&)/, ""); + if (!query) { + return url; + } + url = url.slice(0, index2); + const params = []; + query.split("&").forEach((param) => { + const parts = param.replace(/\+/g, " ").split("="); + const key = parts.shift(); + const val = parts.length > 0 ? parts.join("=") : ""; + params.push(key + "=" + encodeURIComponent(val)); + }); + return params.length ? url + "?" + params.join("&") : url; +} +const ANIMATION_IN$1 = [ + "slide-in-right", + "slide-in-left", + "slide-in-top", + "slide-in-bottom", + "fade-in", + "zoom-out", + "zoom-fade-out", + "pop-in", + "none" +]; +const ANIMATION_OUT$1 = [ + "slide-out-right", + "slide-out-left", + "slide-out-top", + "slide-out-bottom", + "fade-out", + "zoom-in", + "zoom-fade-in", + "pop-out", + "none" +]; +const BaseRouteProtocol = { + url: { + type: String, + required: true + } +}; +const API_NAVIGATE_TO = "navigateTo"; +const API_REDIRECT_TO = "redirectTo"; +const API_RE_LAUNCH = "reLaunch"; +const API_SWITCH_TAB = "switchTab"; +const API_NAVIGATE_BACK = "navigateBack"; +const API_PRELOAD_PAGE = "preloadPage"; +const API_UN_PRELOAD_PAGE = "unPreloadPage"; +const NavigateToProtocol = /* @__PURE__ */ extend( + {}, + BaseRouteProtocol, + createAnimationProtocol(ANIMATION_IN$1) +); +const NavigateBackProtocol = /* @__PURE__ */ extend( + { + delta: { + type: Number + } + }, + createAnimationProtocol(ANIMATION_OUT$1) +); +const RedirectToProtocol = BaseRouteProtocol; +const ReLaunchProtocol = BaseRouteProtocol; +const SwitchTabProtocol = BaseRouteProtocol; +const PreloadPageProtocol = BaseRouteProtocol; +const NavigateToOptions = /* @__PURE__ */ createRouteOptions(API_NAVIGATE_TO); +const RedirectToOptions = /* @__PURE__ */ createRouteOptions(API_REDIRECT_TO); +const ReLaunchOptions = /* @__PURE__ */ createRouteOptions(API_RE_LAUNCH); +const SwitchTabOptions = /* @__PURE__ */ createRouteOptions(API_SWITCH_TAB); +const NavigateBackOptions = { + formatArgs: { + delta(value, params) { + value = parseInt(value + "") || 1; + params.delta = Math.min(getCurrentPages().length - 1, value); + } + } +}; +function createAnimationProtocol(animationTypes) { + return { + animationType: { + type: String, + validator(type) { + if (type && animationTypes.indexOf(type) === -1) { + return "`" + type + "` is not supported for `animationType` (supported values are: `" + animationTypes.join("`|`") + "`)"; + } + } + }, + animationDuration: { + type: Number + } + }; +} +let navigatorLock; +function beforeRoute() { + navigatorLock = ""; +} +function createRouteOptions(type) { + return { + formatArgs: { + url: createNormalizeUrl(type) + }, + beforeAll: beforeRoute + }; +} +function createNormalizeUrl(type) { + return function normalizeUrl(url, params) { + if (!url) { + return `Missing required args: "url"`; + } + url = normalizeRoute(url); + const pagePath = url.split("?")[0]; + const routeOptions = getRouteOptions(pagePath, true); + if (!routeOptions) { + return "page `" + url + "` is not found"; + } + if (type === API_NAVIGATE_TO || type === API_REDIRECT_TO) { + if (routeOptions.meta.isTabBar) { + return `can not ${type} a tabbar page`; + } + } else if (type === API_SWITCH_TAB) { + if (!routeOptions.meta.isTabBar) { + return "can not switch to no-tabBar page"; + } + } + if ((type === API_SWITCH_TAB || type === API_PRELOAD_PAGE) && routeOptions.meta.isTabBar && params.openType !== "appLaunch") { + url = pagePath; + } + if (routeOptions.meta.isEntry) { + url = url.replace(routeOptions.alias, "/"); + } + params.url = encodeQueryString(url); + if (type === API_UN_PRELOAD_PAGE) { + return; + } else if (type === API_PRELOAD_PAGE) { + if (routeOptions.meta.isTabBar) { + const pages = getCurrentPages(); + const tabBarPagePath = routeOptions.path.slice(1); + if (pages.find((page) => page.route === tabBarPagePath)) { + return "tabBar page `" + tabBarPagePath + "` already exists"; + } + } + return; + } + if (navigatorLock === url && params.openType !== "appLaunch") { + return `${navigatorLock} locked`; + } + if (__uniConfig.ready) { + navigatorLock = url; + } + }; +} +const API_HIDE_LOADING = "hideLoading"; +const API_HIDE_TOAST = "hideToast"; +const API_LOAD_FONT_FACE = "loadFontFace"; +const LoadFontFaceProtocol = { + family: { + type: String, + required: true + }, + source: { + type: String, + required: true + }, + desc: Object +}; +const FRONT_COLORS = ["#ffffff", "#000000"]; +const API_SET_NAVIGATION_BAR_COLOR = "setNavigationBarColor"; +const SetNavigationBarColorOptions = { + formatArgs: { + animation(animation2, params) { + if (!animation2) { + animation2 = { duration: 0, timingFunc: "linear" }; + } + params.animation = { + duration: animation2.duration || 0, + timingFunc: animation2.timingFunc || "linear" + }; + } + } +}; +const SetNavigationBarColorProtocol = { + frontColor: { + type: String, + required: true, + validator(frontColor) { + if (FRONT_COLORS.indexOf(frontColor) === -1) { + return `invalid frontColor "${frontColor}"`; + } + } + }, + backgroundColor: { + type: String, + required: true + }, + animation: Object +}; +const API_SET_NAVIGATION_BAR_TITLE = "setNavigationBarTitle"; +const SetNavigationBarTitleProtocol = { + title: { + type: String, + required: true + } +}; +const API_SHOW_NAVIGATION_BAR_LOADING = "showNavigationBarLoading"; +const API_HIDE_NAVIGATION_BAR_LOADING = "hideNavigationBarLoading"; +const API_PAGE_SCROLL_TO = "pageScrollTo"; +const PageScrollToProtocol = { + scrollTop: Number, + selector: String, + duration: Number +}; +const PageScrollToOptions = { + formatArgs: { + duration: 300 + } +}; +const API_SHOW_ACTION_SHEET = "showActionSheet"; +const ShowActionSheetProtocol = { + itemList: { + type: Array, + required: true + }, + title: String, + itemColor: String, + popover: Object +}; +const ShowActionSheetOptions = { + formatArgs: { + itemColor: "#000" + } +}; +const API_SHOW_LOADING = "showLoading"; +const ShowLoadingProtocol = { + title: String, + mask: Boolean +}; +const ShowLoadingOptions = { + formatArgs: { + title: "", + mask: false + } +}; +const API_SHOW_MODAL = "showModal"; +const ShowModalProtocol = { + title: String, + content: String, + showCancel: Boolean, + cancelText: String, + cancelColor: String, + confirmText: String, + confirmColor: String +}; +const ShowModalOptions = { + beforeInvoke() { + initI18nShowModalMsgsOnce(); + }, + formatArgs: { + title: "", + content: "", + placeholderText: "", + showCancel: true, + editable: false, + cancelText(_value, params) { + if (!hasOwn(params, "cancelText")) { + const { t: t2 } = useI18n(); + params.cancelText = t2("uni.showModal.cancel"); + } + }, + cancelColor: "#000", + confirmText(_value, params) { + if (!hasOwn(params, "confirmText")) { + const { t: t2 } = useI18n(); + params.confirmText = t2("uni.showModal.confirm"); + } + }, + confirmColor: PRIMARY_COLOR + } +}; +const API_SHOW_TOAST = "showToast"; +const SHOW_TOAST_ICON = [ + "success", + "loading", + "none", + "error" +]; +const ShowToastProtocol = { + title: String, + icon: String, + image: String, + duration: Number, + mask: Boolean +}; +const ShowToastOptions = { + formatArgs: { + title: "", + icon(type, params) { + params.icon = elemInArray(type, SHOW_TOAST_ICON); + }, + image(value, params) { + if (value) { + params.image = getRealPath(value); + } else { + params.image = ""; + } + }, + duration: 1500, + mask: false + } +}; +const API_START_PULL_DOWN_REFRESH = "startPullDownRefresh"; +const API_STOP_PULL_DOWN_REFRESH = "stopPullDownRefresh"; +const IndexProtocol = { + index: { + type: Number, + required: true + } +}; +const IndexOptions = { + beforeInvoke() { + const pageMeta = getCurrentPageMeta(); + if (pageMeta && !pageMeta.isTabBar) { + return "not TabBar page"; + } + }, + formatArgs: { + index(value) { + if (!__uniConfig.tabBar.list[value]) { + return "tabbar item not found"; + } + } + } +}; +const API_SET_TAB_BAR_ITEM = "setTabBarItem"; +const SetTabBarItemProtocol = /* @__PURE__ */ extend( + { + text: String, + iconPath: String, + selectedIconPath: String, + pagePath: String + }, + IndexProtocol +); +const SetTabBarItemOptions = { + beforeInvoke: IndexOptions.beforeInvoke, + formatArgs: /* @__PURE__ */ extend( + { + pagePath(value, params) { + if (value) { + params.pagePath = removeLeadingSlash(value); + } + } + }, + IndexOptions.formatArgs + ) +}; +const API_SET_TAB_BAR_STYLE = "setTabBarStyle"; +const SetTabBarStyleProtocol = { + color: String, + selectedColor: String, + backgroundColor: String, + backgroundImage: String, + backgroundRepeat: String, + borderStyle: String +}; +const GRADIENT_RE = /^(linear|radial)-gradient\(.+?\);?$/; +const SetTabBarStyleOptions = { + beforeInvoke: IndexOptions.beforeInvoke, + formatArgs: { + backgroundImage(value, params) { + if (value && !GRADIENT_RE.test(value)) { + params.backgroundImage = getRealPath(value); + } + }, + borderStyle(value, params) { + if (value) { + params.borderStyle = value === "white" ? "white" : "black"; + } + } + } +}; +const API_HIDE_TAB_BAR = "hideTabBar"; +const HideTabBarProtocol = { + animation: Boolean +}; +const API_SHOW_TAB_BAR = "showTabBar"; +const ShowTabBarProtocol = HideTabBarProtocol; +const API_HIDE_TAB_BAR_RED_DOT = "hideTabBarRedDot"; +const HideTabBarRedDotProtocol = IndexProtocol; +const HideTabBarRedDotOptions = IndexOptions; +const API_SHOW_TAB_BAR_RED_DOT = "showTabBarRedDot"; +const ShowTabBarRedDotProtocol = IndexProtocol; +const ShowTabBarRedDotOptions = IndexOptions; +const API_REMOVE_TAB_BAR_BADGE = "removeTabBarBadge"; +const RemoveTabBarBadgeProtocol = IndexProtocol; +const RemoveTabBarBadgeOptions = IndexOptions; +const API_SET_TAB_BAR_BADGE = "setTabBarBadge"; +const SetTabBarBadgeProtocol = /* @__PURE__ */ extend( + { + text: { + type: String, + required: true + } + }, + IndexProtocol +); +const SetTabBarBadgeOptions = { + beforeInvoke: IndexOptions.beforeInvoke, + formatArgs: /* @__PURE__ */ extend( + { + text(value, params) { + if (getLen(value) >= 4) { + params.text = "..."; + } + } + }, + IndexOptions.formatArgs + ) +}; +const initIntersectionObserverPolyfill = function() { + if (typeof window !== "object") { + return; + } + if ("IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype) { + if (!("isIntersecting" in window.IntersectionObserverEntry.prototype)) { + Object.defineProperty( + window.IntersectionObserverEntry.prototype, + "isIntersecting", + { + get: function() { + return this.intersectionRatio > 0; + } + } + ); + } + return; + } + function getFrameElement(doc) { + try { + return doc.defaultView && doc.defaultView.frameElement || null; + } catch (e2) { + return null; + } + } + var document2 = function(startDoc) { + var doc = startDoc; + var frame = getFrameElement(doc); + while (frame) { + doc = frame.ownerDocument; + frame = getFrameElement(doc); + } + return doc; + }(window.document); + var registry = []; + var crossOriginUpdater = null; + var crossOriginRect = null; + function IntersectionObserverEntry(entry) { + this.time = entry.time; + this.target = entry.target; + this.rootBounds = ensureDOMRect(entry.rootBounds); + this.boundingClientRect = ensureDOMRect(entry.boundingClientRect); + this.intersectionRect = ensureDOMRect( + entry.intersectionRect || getEmptyRect() + ); + this.isIntersecting = !!entry.intersectionRect; + var targetRect = this.boundingClientRect; + var targetArea = targetRect.width * targetRect.height; + var intersectionRect = this.intersectionRect; + var intersectionArea = intersectionRect.width * intersectionRect.height; + if (targetArea) { + this.intersectionRatio = Number( + (intersectionArea / targetArea).toFixed(4) + ); + } else { + this.intersectionRatio = this.isIntersecting ? 1 : 0; + } + } + function IntersectionObserver2(callback, opt_options) { + var options = opt_options || {}; + if (typeof callback != "function") { + throw new Error("callback must be a function"); + } + if (options.root && options.root.nodeType != 1 && options.root.nodeType != 9) { + throw new Error("root must be a Document or Element"); + } + this._checkForIntersections = throttle2( + this._checkForIntersections.bind(this), + this.THROTTLE_TIMEOUT + ); + this._callback = callback; + this._observationTargets = []; + this._queuedEntries = []; + this._rootMarginValues = this._parseRootMargin(options.rootMargin); + this.thresholds = this._initThresholds(options.threshold); + this.root = options.root || null; + this.rootMargin = this._rootMarginValues.map(function(margin) { + return margin.value + margin.unit; + }).join(" "); + this._monitoringDocuments = []; + this._monitoringUnsubscribes = []; + } + IntersectionObserver2.prototype.THROTTLE_TIMEOUT = 100; + IntersectionObserver2.prototype.POLL_INTERVAL = null; + IntersectionObserver2.prototype.USE_MUTATION_OBSERVER = true; + IntersectionObserver2._setupCrossOriginUpdater = function() { + if (!crossOriginUpdater) { + crossOriginUpdater = function(boundingClientRect, intersectionRect) { + if (!boundingClientRect || !intersectionRect) { + crossOriginRect = getEmptyRect(); + } else { + crossOriginRect = convertFromParentRect( + boundingClientRect, + intersectionRect + ); + } + registry.forEach(function(observer) { + observer._checkForIntersections(); + }); + }; + } + return crossOriginUpdater; + }; + IntersectionObserver2._resetCrossOriginUpdater = function() { + crossOriginUpdater = null; + crossOriginRect = null; + }; + IntersectionObserver2.prototype.observe = function(target) { + var isTargetAlreadyObserved = this._observationTargets.some(function(item) { + return item.element == target; + }); + if (isTargetAlreadyObserved) { + return; + } + if (!(target && target.nodeType == 1)) { + throw new Error("target must be an Element"); + } + this._registerInstance(); + this._observationTargets.push({ element: target, entry: null }); + this._monitorIntersections(target.ownerDocument); + this._checkForIntersections(); + }; + IntersectionObserver2.prototype.unobserve = function(target) { + this._observationTargets = this._observationTargets.filter(function(item) { + return item.element != target; + }); + this._unmonitorIntersections(target.ownerDocument); + if (this._observationTargets.length == 0) { + this._unregisterInstance(); + } + }; + IntersectionObserver2.prototype.disconnect = function() { + this._observationTargets = []; + this._unmonitorAllIntersections(); + this._unregisterInstance(); + }; + IntersectionObserver2.prototype.takeRecords = function() { + var records = this._queuedEntries.slice(); + this._queuedEntries = []; + return records; + }; + IntersectionObserver2.prototype._initThresholds = function(opt_threshold) { + var threshold = opt_threshold || [0]; + if (!Array.isArray(threshold)) + threshold = [threshold]; + return threshold.sort().filter(function(t2, i, a2) { + if (typeof t2 != "number" || isNaN(t2) || t2 < 0 || t2 > 1) { + throw new Error( + "threshold must be a number between 0 and 1 inclusively" + ); + } + return t2 !== a2[i - 1]; + }); + }; + IntersectionObserver2.prototype._parseRootMargin = function(opt_rootMargin) { + var marginString = opt_rootMargin || "0px"; + var margins = marginString.split(/\s+/).map(function(margin) { + var parts = /^(-?\d*\.?\d+)(px|%)$/.exec(margin); + if (!parts) { + throw new Error("rootMargin must be specified in pixels or percent"); + } + return { value: parseFloat(parts[1]), unit: parts[2] }; + }); + margins[1] = margins[1] || margins[0]; + margins[2] = margins[2] || margins[0]; + margins[3] = margins[3] || margins[1]; + return margins; + }; + IntersectionObserver2.prototype._monitorIntersections = function(doc) { + var win = doc.defaultView; + if (!win) { + return; + } + if (this._monitoringDocuments.indexOf(doc) != -1) { + return; + } + var callback = this._checkForIntersections; + var monitoringInterval = null; + var domObserver = null; + if (this.POLL_INTERVAL) { + monitoringInterval = win.setInterval(callback, this.POLL_INTERVAL); + } else { + addEvent(win, "resize", callback, true); + addEvent(doc, "scroll", callback, true); + if (this.USE_MUTATION_OBSERVER && "MutationObserver" in win) { + domObserver = new win.MutationObserver(callback); + domObserver.observe(doc, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + } + } + this._monitoringDocuments.push(doc); + this._monitoringUnsubscribes.push(function() { + var win2 = doc.defaultView; + if (win2) { + if (monitoringInterval) { + win2.clearInterval(monitoringInterval); + } + removeEvent(win2, "resize", callback, true); + } + removeEvent(doc, "scroll", callback, true); + if (domObserver) { + domObserver.disconnect(); + } + }); + var rootDoc = this.root && (this.root.ownerDocument || this.root) || document2; + if (doc != rootDoc) { + var frame = getFrameElement(doc); + if (frame) { + this._monitorIntersections(frame.ownerDocument); + } + } + }; + IntersectionObserver2.prototype._unmonitorIntersections = function(doc) { + var index2 = this._monitoringDocuments.indexOf(doc); + if (index2 == -1) { + return; + } + var rootDoc = this.root && (this.root.ownerDocument || this.root) || document2; + var hasDependentTargets = this._observationTargets.some(function(item) { + var itemDoc = item.element.ownerDocument; + if (itemDoc == doc) { + return true; + } + while (itemDoc && itemDoc != rootDoc) { + var frame2 = getFrameElement(itemDoc); + itemDoc = frame2 && frame2.ownerDocument; + if (itemDoc == doc) { + return true; + } + } + return false; + }); + if (hasDependentTargets) { + return; + } + var unsubscribe = this._monitoringUnsubscribes[index2]; + this._monitoringDocuments.splice(index2, 1); + this._monitoringUnsubscribes.splice(index2, 1); + unsubscribe(); + if (doc != rootDoc) { + var frame = getFrameElement(doc); + if (frame) { + this._unmonitorIntersections(frame.ownerDocument); + } + } + }; + IntersectionObserver2.prototype._unmonitorAllIntersections = function() { + var unsubscribes = this._monitoringUnsubscribes.slice(0); + this._monitoringDocuments.length = 0; + this._monitoringUnsubscribes.length = 0; + for (var i = 0; i < unsubscribes.length; i++) { + unsubscribes[i](); + } + }; + IntersectionObserver2.prototype._checkForIntersections = function() { + if (!this.root && crossOriginUpdater && !crossOriginRect) { + return; + } + var rootIsInDom = this._rootIsInDom(); + var rootRect = rootIsInDom ? this._getRootRect() : getEmptyRect(); + this._observationTargets.forEach(function(item) { + var target = item.element; + var targetRect = getBoundingClientRect(target); + var rootContainsTarget = this._rootContainsTarget(target); + var oldEntry = item.entry; + var intersectionRect = rootIsInDom && rootContainsTarget && this._computeTargetAndRootIntersection(target, targetRect, rootRect); + var rootBounds = null; + if (!this._rootContainsTarget(target)) { + rootBounds = getEmptyRect(); + } else if (!crossOriginUpdater || this.root) { + rootBounds = rootRect; + } + var newEntry = item.entry = new IntersectionObserverEntry({ + time: now(), + target, + boundingClientRect: targetRect, + rootBounds, + intersectionRect + }); + if (!oldEntry) { + this._queuedEntries.push(newEntry); + } else if (rootIsInDom && rootContainsTarget) { + if (this._hasCrossedThreshold(oldEntry, newEntry)) { + this._queuedEntries.push(newEntry); + } + } else { + if (oldEntry && oldEntry.isIntersecting) { + this._queuedEntries.push(newEntry); + } + } + }, this); + if (this._queuedEntries.length) { + this._callback(this.takeRecords(), this); + } + }; + IntersectionObserver2.prototype._computeTargetAndRootIntersection = function(target, targetRect, rootRect) { + if (window.getComputedStyle(target).display == "none") + return; + var intersectionRect = targetRect; + var parent = getParentNode(target); + var atRoot = false; + while (!atRoot && parent) { + var parentRect = null; + var parentComputedStyle = parent.nodeType == 1 ? window.getComputedStyle(parent) : {}; + if (parentComputedStyle.display == "none") + return null; + if (parent == this.root || parent.nodeType == /* DOCUMENT */ + 9) { + atRoot = true; + if (parent == this.root || parent == document2) { + if (crossOriginUpdater && !this.root) { + if (!crossOriginRect || crossOriginRect.width == 0 && crossOriginRect.height == 0) { + parent = null; + parentRect = null; + intersectionRect = null; + } else { + parentRect = crossOriginRect; + } + } else { + parentRect = rootRect; + } + } else { + var frame = getParentNode(parent); + var frameRect = frame && getBoundingClientRect(frame); + var frameIntersect = frame && this._computeTargetAndRootIntersection(frame, frameRect, rootRect); + if (frameRect && frameIntersect) { + parent = frame; + parentRect = convertFromParentRect(frameRect, frameIntersect); + } else { + parent = null; + intersectionRect = null; + } + } + } else { + var doc = parent.ownerDocument; + if (parent != doc.body && parent != doc.documentElement && parentComputedStyle.overflow != "visible") { + parentRect = getBoundingClientRect(parent); + } + } + if (parentRect) { + intersectionRect = computeRectIntersection(parentRect, intersectionRect); + } + if (!intersectionRect) + break; + parent = parent && getParentNode(parent); + } + return intersectionRect; + }; + IntersectionObserver2.prototype._getRootRect = function() { + var rootRect; + if (this.root && !isDoc(this.root)) { + rootRect = getBoundingClientRect(this.root); + } else { + var doc = isDoc(this.root) ? this.root : document2; + var html = doc.documentElement; + var body = doc.body; + rootRect = { + top: 0, + left: 0, + right: html.clientWidth || body.clientWidth, + width: html.clientWidth || body.clientWidth, + bottom: html.clientHeight || body.clientHeight, + height: html.clientHeight || body.clientHeight + }; + } + return this._expandRectByRootMargin(rootRect); + }; + IntersectionObserver2.prototype._expandRectByRootMargin = function(rect) { + var margins = this._rootMarginValues.map(function(margin, i) { + return margin.unit == "px" ? margin.value : margin.value * (i % 2 ? rect.width : rect.height) / 100; + }); + var newRect = { + top: rect.top - margins[0], + right: rect.right + margins[1], + bottom: rect.bottom + margins[2], + left: rect.left - margins[3] + }; + newRect.width = newRect.right - newRect.left; + newRect.height = newRect.bottom - newRect.top; + return newRect; + }; + IntersectionObserver2.prototype._hasCrossedThreshold = function(oldEntry, newEntry) { + var oldRatio = oldEntry && oldEntry.isIntersecting ? oldEntry.intersectionRatio || 0 : -1; + var newRatio = newEntry.isIntersecting ? newEntry.intersectionRatio || 0 : -1; + if (oldRatio === newRatio) + return; + for (var i = 0; i < this.thresholds.length; i++) { + var threshold = this.thresholds[i]; + if (threshold == oldRatio || threshold == newRatio || threshold < oldRatio !== threshold < newRatio) { + return true; + } + } + }; + IntersectionObserver2.prototype._rootIsInDom = function() { + return !this.root || containsDeep(document2, this.root); + }; + IntersectionObserver2.prototype._rootContainsTarget = function(target) { + var rootDoc = this.root && (this.root.ownerDocument || this.root) || document2; + return containsDeep(rootDoc, target) && (!this.root || rootDoc == target.ownerDocument); + }; + IntersectionObserver2.prototype._registerInstance = function() { + if (registry.indexOf(this) < 0) { + registry.push(this); + } + }; + IntersectionObserver2.prototype._unregisterInstance = function() { + var index2 = registry.indexOf(this); + if (index2 != -1) + registry.splice(index2, 1); + }; + function now() { + return window.performance && performance.now && performance.now(); + } + function throttle2(fn, timeout) { + var timer = null; + return function() { + if (!timer) { + timer = setTimeout(function() { + fn(); + timer = null; + }, timeout); + } + }; + } + function addEvent(node, event, fn, opt_useCapture) { + if (typeof node.addEventListener == "function") { + node.addEventListener(event, fn, opt_useCapture || false); + } else if (typeof node.attachEvent == "function") { + node.attachEvent("on" + event, fn); + } + } + function removeEvent(node, event, fn, opt_useCapture) { + if (typeof node.removeEventListener == "function") { + node.removeEventListener(event, fn, opt_useCapture || false); + } else if (typeof node.detatchEvent == "function") { + node.detatchEvent("on" + event, fn); + } + } + function computeRectIntersection(rect1, rect2) { + var top = Math.max(rect1.top, rect2.top); + var bottom = Math.min(rect1.bottom, rect2.bottom); + var left = Math.max(rect1.left, rect2.left); + var right = Math.min(rect1.right, rect2.right); + var width = right - left; + var height = bottom - top; + return width >= 0 && height >= 0 && { + top, + bottom, + left, + right, + width, + height + } || null; + } + function getBoundingClientRect(el) { + var rect; + try { + rect = el.getBoundingClientRect(); + } catch (err) { + } + if (!rect) + return getEmptyRect(); + if (!(rect.width && rect.height)) { + rect = { + top: rect.top, + right: rect.right, + bottom: rect.bottom, + left: rect.left, + width: rect.right - rect.left, + height: rect.bottom - rect.top + }; + } + return rect; + } + function getEmptyRect() { + return { + top: 0, + bottom: 0, + left: 0, + right: 0, + width: 0, + height: 0 + }; + } + function ensureDOMRect(rect) { + if (!rect || "x" in rect) { + return rect; + } + return { + top: rect.top, + y: rect.top, + bottom: rect.bottom, + left: rect.left, + x: rect.left, + right: rect.right, + width: rect.width, + height: rect.height + }; + } + function convertFromParentRect(parentBoundingRect, parentIntersectionRect) { + var top = parentIntersectionRect.top - parentBoundingRect.top; + var left = parentIntersectionRect.left - parentBoundingRect.left; + return { + top, + left, + height: parentIntersectionRect.height, + width: parentIntersectionRect.width, + bottom: top + parentIntersectionRect.height, + right: left + parentIntersectionRect.width + }; + } + function containsDeep(parent, child) { + var node = child; + while (node) { + if (node == parent) + return true; + node = getParentNode(node); + } + return false; + } + function getParentNode(node) { + var parent = node.parentNode; + if (node.nodeType == /* DOCUMENT */ + 9 && node != document2) { + return getFrameElement(node); + } + if (parent && parent.assignedSlot) { + parent = parent.assignedSlot.parentNode; + } + if (parent && parent.nodeType == 11 && parent.host) { + return parent.host; + } + return parent; + } + function isDoc(node) { + return node && node.nodeType === 9; + } + window.IntersectionObserver = IntersectionObserver2; + window.IntersectionObserverEntry = IntersectionObserverEntry; +}; +function normalizeRect(rect) { + const { bottom, height, left, right, top, width } = rect || {}; + return { + bottom, + height, + left, + right, + top, + width + }; +} +function rectifyIntersectionRatio(entrie) { + const { + intersectionRatio, + boundingClientRect: { height: overAllHeight, width: overAllWidth }, + intersectionRect: { height: intersectionHeight, width: intersectionWidth } + } = entrie; + if (intersectionRatio !== 0) + return intersectionRatio; + return intersectionHeight === overAllHeight ? intersectionWidth / overAllWidth : intersectionHeight / overAllHeight; +} +function requestComponentObserver($el, options, callback) { + initIntersectionObserverPolyfill(); + const root = options.relativeToSelector ? $el.querySelector(options.relativeToSelector) : null; + const intersectionObserver = new IntersectionObserver( + (entries2) => { + entries2.forEach((entrie) => { + callback({ + intersectionRatio: rectifyIntersectionRatio(entrie), + intersectionRect: normalizeRect(entrie.intersectionRect), + boundingClientRect: normalizeRect(entrie.boundingClientRect), + relativeRect: normalizeRect(entrie.rootBounds), + time: Date.now(), + dataset: getCustomDataset(entrie.target), + id: entrie.target.id + }); + }); + }, + { + root, + rootMargin: options.rootMargin, + threshold: options.thresholds + } + ); + if (options.observeAll) { + intersectionObserver.USE_MUTATION_OBSERVER = true; + const nodeList = $el.querySelectorAll(options.selector); + for (let i = 0; i < nodeList.length; i++) { + intersectionObserver.observe(nodeList[i]); + } + } else { + intersectionObserver.USE_MUTATION_OBSERVER = false; + const el = $el.querySelector(options.selector); + if (!el) { + console.warn( + `Node ${options.selector} is not found. Intersection observer will not trigger.` + ); + } else { + intersectionObserver.observe(el); + } + } + return intersectionObserver; +} +function addIntersectionObserver({ reqId, component, options, callback }, _pageId) { + const $el = findElem(component); + ($el.__io || ($el.__io = {}))[reqId] = requestComponentObserver( + $el, + options, + callback + ); +} +function removeIntersectionObserver({ reqId, component }, _pageId) { + const $el = findElem(component); + const intersectionObserver = $el.__io && $el.__io[reqId]; + if (intersectionObserver) { + intersectionObserver.disconnect(); + delete $el.__io[reqId]; + } +} +let mediaQueryObservers = {}; +let listeners = {}; +function handleMediaQueryStr($props) { + const mediaQueryArr = []; + const propsMenu = [ + "width", + "minWidth", + "maxWidth", + "height", + "minHeight", + "maxHeight", + "orientation" + ]; + for (const item of propsMenu) { + if (item !== "orientation" && $props[item] && Number($props[item] >= 0)) { + mediaQueryArr.push( + `(${humpToLine(item)}: ${Number( + $props[item] + )}px)` + ); + } + if (item === "orientation" && $props[item]) { + mediaQueryArr.push(`(${humpToLine(item)}: ${$props[item]})`); + } + } + const mediaQueryStr = mediaQueryArr.join(" and "); + return mediaQueryStr; +} +function humpToLine(name) { + return name.replace(/([A-Z])/g, "-$1").toLowerCase(); +} +function addMediaQueryObserver({ reqId, component, options, callback }, _pageId) { + const mediaQueryObserver = mediaQueryObservers[reqId] = window.matchMedia( + handleMediaQueryStr(options) + ); + const listener2 = listeners[reqId] = (observer) => callback(observer.matches); + listener2(mediaQueryObserver); + mediaQueryObserver.addListener(listener2); +} +function removeMediaQueryObserver({ reqId, component }, _pageId) { + const listener2 = listeners[reqId]; + const mediaQueryObserver = mediaQueryObservers[reqId]; + if (mediaQueryObserver) { + mediaQueryObserver.removeListener(listener2); + delete listeners[reqId]; + delete mediaQueryObservers[reqId]; + } +} +function saveImage(base64, dirname, callback) { + callback(null, base64); +} +const TEMP_PATH = ""; +const files = {}; +function urlToFile(url, local) { + const file = files[url]; + if (file) { + return Promise.resolve(file); + } + if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) { + return Promise.resolve(base64ToFile(url)); + } + if (local) { + return Promise.reject(new Error("not find")); + } + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.responseType = "blob"; + xhr.onload = function() { + resolve(this.response); + }; + xhr.onerror = reject; + xhr.send(); + }); +} +function base64ToFile(base64) { + const base64Array = base64.split(","); + const res = base64Array[0].match(/:(.*?);/); + const type = res ? res[1] : ""; + const str = atob(base64Array[1]); + let n = str.length; + const array = new Uint8Array(n); + while (n--) { + array[n] = str.charCodeAt(n); + } + return blobToFile(array, type); +} +function getExtname(type) { + const extname = type.split("/")[1]; + return extname ? `.${extname}` : ""; +} +function getFileName(url) { + url = url.split("#")[0].split("?")[0]; + const array = url.split("/"); + return array[array.length - 1]; +} +function blobToFile(blob, type) { + let file; + if (blob instanceof File) { + file = blob; + } else { + type = type || blob.type || ""; + const filename = `${Date.now()}${getExtname(type)}`; + try { + file = new File([blob], filename, { type }); + } catch (error) { + blob = blob instanceof Blob ? blob : new Blob([blob], { type }); + file = blob; + file.name = file.name || filename; + } + } + return file; +} +function fileToUrl(file) { + for (const key in files) { + if (hasOwn(files, key)) { + const oldFile = files[key]; + if (oldFile === file) { + return key; + } + } + } + var url = (window.URL || window.webkitURL).createObjectURL(file); + files[url] = file; + return url; +} +function getSameOriginUrl(url) { + const a2 = document.createElement("a"); + a2.href = url; + if (a2.origin === location.origin) { + return Promise.resolve(url); + } + return urlToFile(url).then(fileToUrl); +} +function revokeObjectURL(url) { + const URL = window.URL || window.webkitURL; + URL.revokeObjectURL(url); + delete files[url]; +} +const launchOptions = /* @__PURE__ */ createLaunchOptions(); +const enterOptions = /* @__PURE__ */ createLaunchOptions(); +function getEnterOptions() { + return extend({}, enterOptions); +} +function getLaunchOptions() { + return extend({}, launchOptions); +} +function initLaunchOptions({ + path, + query +}) { + extend(launchOptions, { + path, + query + }); + extend(enterOptions, launchOptions); + return extend({}, launchOptions); +} +const inflateRaw = (...args) => { +}; +const deflateRaw = (...args) => { +}; +const ResizeSensor = /* @__PURE__ */ defineBuiltInComponent({ + name: "ResizeSensor", + props: { + initial: { + type: Boolean, + default: false + } + }, + emits: ["resize"], + setup(props2, { + emit: emit2 + }) { + const rootRef = ref(null); + const reset = useResizeSensorReset(rootRef); + const update = useResizeSensorUpdate(rootRef, emit2, reset); + useResizeSensorLifecycle(rootRef, props2, update, reset); + return () => createVNode("uni-resize-sensor", { + "ref": rootRef, + "onAnimationstartOnce": update + }, [createVNode("div", { + "onScroll": update + }, [createVNode("div", null, null)], 40, ["onScroll"]), createVNode("div", { + "onScroll": update + }, [createVNode("div", null, null)], 40, ["onScroll"])], 40, ["onAnimationstartOnce"]); + } +}); +function useResizeSensorUpdate(rootRef, emit2, reset) { + const size = reactive({ + width: -1, + height: -1 + }); + watch(() => extend({}, size), (value) => emit2("resize", value)); + return () => { + const rootEl = rootRef.value; + size.width = rootEl.offsetWidth; + size.height = rootEl.offsetHeight; + reset(); + }; +} +function useResizeSensorReset(rootRef) { + return () => { + const { + firstElementChild, + lastElementChild + } = rootRef.value; + firstElementChild.scrollLeft = 1e5; + firstElementChild.scrollTop = 1e5; + lastElementChild.scrollLeft = 1e5; + lastElementChild.scrollTop = 1e5; + }; +} +function useResizeSensorLifecycle(rootRef, props2, update, reset) { + onActivated(reset); + onMounted(() => { + if (props2.initial) { + nextTick(update); + } + const rootEl = rootRef.value; + if (rootEl.offsetParent !== rootEl.parentElement) { + rootEl.parentElement.style.position = "relative"; + } + if (!("AnimationEvent" in window)) { + reset(); + } + }); +} +const pixelRatio = /* @__PURE__ */ function() { + const canvas = document.createElement("canvas"); + canvas.height = canvas.width = 0; + const context = canvas.getContext("2d"); + const backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; + return (window.devicePixelRatio || 1) / backingStore; +}(); +function wrapper(canvas, hidpi = true) { + canvas.width = canvas.offsetWidth * (hidpi ? pixelRatio : 1); + canvas.height = canvas.offsetHeight * (hidpi ? pixelRatio : 1); + canvas.getContext("2d").__hidpi__ = hidpi; +} +let isHidpi = false; +function initHidpi() { + if (isHidpi) { + return; + } + isHidpi = true; + const forEach = function(obj, func) { + for (const key in obj) { + if (hasOwn(obj, key)) { + func(obj[key], key); + } + } + }; + const ratioArgs = { + fillRect: "all", + clearRect: "all", + strokeRect: "all", + moveTo: "all", + lineTo: "all", + arc: [0, 1, 2], + arcTo: "all", + bezierCurveTo: "all", + isPointinPath: "all", + isPointinStroke: "all", + quadraticCurveTo: "all", + rect: "all", + translate: "all", + createRadialGradient: "all", + createLinearGradient: "all", + transform: [4, 5], + setTransform: [4, 5] + }; + const proto = CanvasRenderingContext2D.prototype; + proto.drawImageByCanvas = function(_super) { + return function(canvas, srcx, srcy, srcw, srch, desx, desy, desw, desh, isScale) { + if (!this.__hidpi__) { + return _super.apply(this, arguments); + } + srcx *= pixelRatio; + srcy *= pixelRatio; + srcw *= pixelRatio; + srch *= pixelRatio; + desx *= pixelRatio; + desy *= pixelRatio; + desw = isScale ? desw * pixelRatio : desw; + desh = isScale ? desh * pixelRatio : desh; + _super.call(this, canvas, srcx, srcy, srcw, srch, desx, desy, desw, desh); + }; + }(proto.drawImage); + if (pixelRatio !== 1) { + forEach(ratioArgs, function(value, key) { + proto[key] = function(_super) { + return function() { + if (!this.__hidpi__) { + return _super.apply(this, arguments); + } + let args = Array.prototype.slice.call(arguments); + if (value === "all") { + args = args.map(function(a2) { + return a2 * pixelRatio; + }); + } else if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + args[value[i]] *= pixelRatio; + } + } + return _super.apply(this, args); + }; + }(proto[key]); + }); + proto.stroke = function(_super) { + return function() { + if (!this.__hidpi__) { + return _super.apply(this, arguments); + } + this.lineWidth *= pixelRatio; + _super.apply(this, arguments); + this.lineWidth /= pixelRatio; + }; + }(proto.stroke); + proto.fillText = function(_super) { + return function() { + if (!this.__hidpi__) { + return _super.apply(this, arguments); + } + const args = Array.prototype.slice.call(arguments); + args[1] *= pixelRatio; + args[2] *= pixelRatio; + if (args[3] && typeof args[3] === "number") { + args[3] *= pixelRatio; + } + var font2 = this.font; + this.font = font2.replace( + /(\d+\.?\d*)(px|em|rem|pt)/g, + function(w, m, u) { + return m * pixelRatio + u; + } + ); + _super.apply(this, args); + this.font = font2; + }; + }(proto.fillText); + proto.strokeText = function(_super) { + return function() { + if (!this.__hidpi__) { + return _super.apply(this, arguments); + } + var args = Array.prototype.slice.call(arguments); + args[1] *= pixelRatio; + args[2] *= pixelRatio; + if (args[3] && typeof args[3] === "number") { + args[3] *= pixelRatio; + } + var font2 = this.font; + this.font = font2.replace( + /(\d+\.?\d*)(px|em|rem|pt)/g, + function(w, m, u) { + return m * pixelRatio + u; + } + ); + _super.apply(this, args); + this.font = font2; + }; + }(proto.strokeText); + proto.drawImage = function(_super) { + return function() { + if (!this.__hidpi__) { + return _super.apply(this, arguments); + } + this.scale(pixelRatio, pixelRatio); + _super.apply(this, arguments); + this.scale(1 / pixelRatio, 1 / pixelRatio); + }; + }(proto.drawImage); + } +} +const initHidpiOnce = /* @__PURE__ */ once(() => { + return initHidpi(); +}); +function $getRealPath(src) { + return src ? getRealPath(src) : src; +} +function resolveColor(color) { + color = color.slice(0); + color[3] = color[3] / 255; + return "rgba(" + color.join(",") + ")"; +} +function processTouches(rect, touches) { + Array.from(touches).forEach((touch) => { + touch.x = touch.clientX - rect.left; + touch.y = touch.clientY - rect.top; + }); +} +let tempCanvas; +function getTempCanvas(width = 0, height = 0) { + if (!tempCanvas) { + tempCanvas = document.createElement("canvas"); + } + tempCanvas.width = width; + tempCanvas.height = height; + return tempCanvas; +} +const props$x = { + canvasId: { + type: String, + default: "" + }, + disableScroll: { + type: [Boolean, String], + default: false + }, + hidpi: { + type: Boolean, + default: true + } +}; +const index$v = /* @__PURE__ */ defineBuiltInComponent({ + inheritAttrs: false, + name: "Canvas", + compatConfig: { + MODE: 3 + }, + props: props$x, + computed: { + id() { + return this.canvasId; + } + }, + setup(props2, { + emit: emit2, + slots + }) { + initHidpiOnce(); + const canvas = ref(null); + const sensor = ref(null); + const actionsWaiting = ref(false); + const trigger = useNativeEvent(emit2); + const { + $attrs, + $excludeAttrs, + $listeners + } = useAttrs({ + excludeListeners: true + }); + const { + _listeners + } = useListeners(props2, $listeners, trigger); + const { + _handleSubscribe, + _resize + } = useMethods(props2, canvas, actionsWaiting); + useSubscribe(_handleSubscribe, useContextInfo(props2.canvasId), true); + onMounted(() => { + _resize(); + }); + return () => { + const { + canvasId, + disableScroll + } = props2; + return createVNode("uni-canvas", mergeProps({ + "canvas-id": canvasId, + "disable-scroll": disableScroll + }, $attrs.value, $excludeAttrs.value, _listeners.value), [createVNode("canvas", { + "ref": canvas, + "class": "uni-canvas-canvas", + "width": "300", + "height": "150" + }, null, 512), createVNode("div", { + "style": "position: absolute;top: 0;left: 0;width: 100%;height: 100%;overflow: hidden;" + }, [slots.default && slots.default()]), createVNode(ResizeSensor, { + "ref": sensor, + "onResize": _resize + }, null, 8, ["onResize"])], 16, ["canvas-id", "disable-scroll"]); + }; + } +}); +function useListeners(props2, Listeners, trigger) { + const _listeners = computed(() => { + let events = ["onTouchstart", "onTouchmove", "onTouchend"]; + let _$listeners = Listeners.value; + let $listeners = extend({}, (() => { + let obj = {}; + for (const key in _$listeners) { + if (hasOwn(_$listeners, key)) { + const event = _$listeners[key]; + obj[key] = event; + } + } + return obj; + })()); + events.forEach((event) => { + let existing = $listeners[event]; + let eventHandler = []; + if (existing) { + eventHandler.push(withWebEvent(($event) => { + const rect = $event.currentTarget.getBoundingClientRect(); + processTouches(rect, $event.touches); + processTouches(rect, $event.changedTouches); + trigger(event.replace("on", "").toLocaleLowerCase(), $event); + })); + } + if (props2.disableScroll && event === "onTouchmove") { + eventHandler.push(onEventPrevent); + } + $listeners[event] = eventHandler; + }); + return $listeners; + }); + return { + _listeners + }; +} +function useMethods(props2, canvasRef, actionsWaiting) { + let _actionsDefer = []; + let _images = {}; + const _pixelRatio = computed(() => props2.hidpi ? pixelRatio : 1); + function _resize(size) { + let canvas = canvasRef.value; + var hasChanged = !size || canvas.width !== Math.floor(size.width * _pixelRatio.value) || canvas.height !== Math.floor(size.height * _pixelRatio.value); + if (!hasChanged) + return; + if (canvas.width > 0 && canvas.height > 0) { + let context = canvas.getContext("2d"); + let imageData = context.getImageData(0, 0, canvas.width, canvas.height); + wrapper(canvas, props2.hidpi); + context.putImageData(imageData, 0, 0); + } else { + wrapper(canvas, props2.hidpi); + } + } + function actionsChanged({ + actions, + reserve + }, resolve) { + if (!actions) { + return; + } + if (actionsWaiting.value) { + _actionsDefer.push([actions, reserve]); + return; + } + let canvas = canvasRef.value; + let c2d = canvas.getContext("2d"); + if (!reserve) { + c2d.fillStyle = "#000000"; + c2d.strokeStyle = "#000000"; + c2d.shadowColor = "#000000"; + c2d.shadowBlur = 0; + c2d.shadowOffsetX = 0; + c2d.shadowOffsetY = 0; + c2d.setTransform(1, 0, 0, 1, 0, 0); + c2d.clearRect(0, 0, canvas.width, canvas.height); + } + preloadImage(actions); + for (let index2 = 0; index2 < actions.length; index2++) { + const action = actions[index2]; + let method = action.method; + const data = action.data; + const actionType = data[0]; + if (/^set/.test(method) && method !== "setTransform") { + const method1 = method[3].toLowerCase() + method.slice(4); + let color; + if (method1 === "fillStyle" || method1 === "strokeStyle") { + if (actionType === "normal") { + color = resolveColor(data[1]); + } else if (actionType === "linear") { + const LinearGradient = c2d.createLinearGradient(...data[1]); + data[2].forEach(function(data2) { + const offset = data2[0]; + const color2 = resolveColor(data2[1]); + LinearGradient.addColorStop(offset, color2); + }); + color = LinearGradient; + } else if (actionType === "radial") { + let _data = data[1]; + const x = _data[0]; + const y = _data[1]; + const r = _data[2]; + const LinearGradient = c2d.createRadialGradient(x, y, 0, x, y, r); + data[2].forEach(function(data2) { + const offset = data2[0]; + const color2 = resolveColor(data2[1]); + LinearGradient.addColorStop(offset, color2); + }); + color = LinearGradient; + } else if (actionType === "pattern") { + const loaded = checkImageLoaded(data[1], actions.slice(index2 + 1), resolve, function(image2) { + if (image2) { + c2d[method1] = c2d.createPattern(image2, data[2]); + } + }); + if (!loaded) { + break; + } + continue; + } + c2d[method1] = color; + } else if (method1 === "globalAlpha") { + c2d[method1] = Number(actionType) / 255; + } else if (method1 === "shadow") { + let shadowArray = ["shadowOffsetX", "shadowOffsetY", "shadowBlur", "shadowColor"]; + data.forEach(function(color_, method_) { + c2d[shadowArray[method_]] = shadowArray[method_] === "shadowColor" ? resolveColor(color_) : color_; + }); + } else if (method1 === "fontSize") { + const font2 = c2d.__font__ || c2d.font; + c2d.__font__ = c2d.font = font2.replace(/\d+\.?\d*px/, actionType + "px"); + } else if (method1 === "lineDash") { + c2d.setLineDash(actionType); + c2d.lineDashOffset = data[1] || 0; + } else if (method1 === "textBaseline") { + if (actionType === "normal") { + data[0] = "alphabetic"; + } + c2d[method1] = actionType; + } else if (method1 === "font") { + c2d.__font__ = c2d.font = actionType; + } else { + c2d[method1] = actionType; + } + } else if (method === "fillPath" || method === "strokePath") { + method = method.replace(/Path/, ""); + c2d.beginPath(); + data.forEach(function(data_) { + c2d[data_.method].apply(c2d, data_.data); + }); + c2d[method](); + } else if (method === "fillText") { + c2d.fillText.apply(c2d, data); + } else if (method === "drawImage") { + let drawImage = function() { + let dataArray = [...data]; + let url = dataArray[0]; + let otherData = dataArray.slice(1); + _images = _images || {}; + if (!checkImageLoaded(url, actions.slice(index2 + 1), resolve, function(image2) { + if (image2) { + c2d.drawImage.apply( + c2d, + // @ts-ignore + [image2].concat( + // @ts-ignore + [...otherData.slice(4, 8)], + [...otherData.slice(0, 4)] + ) + ); + } + })) + return "break"; + }(); + if (drawImage === "break") { + break; + } + } else { + if (method === "clip") { + data.forEach(function(data_) { + c2d[data_.method].apply(c2d, data_.data); + }); + c2d.clip(); + } else { + c2d[method].apply(c2d, data); + } + } + } + if (!actionsWaiting.value) { + resolve({ + errMsg: "drawCanvas:ok" + }); + } + } + function preloadImage(actions) { + actions.forEach(function(action) { + let method = action.method; + let data = action.data; + let src = ""; + if (method === "drawImage") { + src = data[0]; + src = $getRealPath(src); + data[0] = src; + } else if (method === "setFillStyle" && data[0] === "pattern") { + src = data[1]; + src = $getRealPath(src); + data[1] = src; + } + if (src && !_images[src]) { + loadImage(); + } + function loadImage() { + const image2 = _images[src] = new Image(); + image2.onload = function() { + image2.ready = true; + }; + getSameOriginUrl(src).then((src2) => { + image2.src = src2; + }).catch(() => { + image2.src = src; + }); + } + }); + } + function checkImageLoaded(src, actions, resolve, fn) { + let image2 = _images[src]; + if (image2.ready) { + fn(image2); + return true; + } else { + _actionsDefer.unshift([actions, true]); + actionsWaiting.value = true; + image2.onload = function() { + image2.ready = true; + fn(image2); + actionsWaiting.value = false; + let actions2 = _actionsDefer.slice(0); + _actionsDefer = []; + for (let action = actions2.shift(); action; ) { + actionsChanged({ + actions: action[0], + reserve: action[1] + }, resolve); + action = actions2.shift(); + } + }; + return false; + } + } + function getImageData({ + x = 0, + y = 0, + width, + height, + destWidth, + destHeight, + hidpi = true, + dataType: dataType2, + quality = 1, + type = "png" + }, resolve) { + const canvas = canvasRef.value; + let data; + const maxWidth2 = canvas.offsetWidth - x; + width = width ? Math.min(width, maxWidth2) : maxWidth2; + const maxHeight = canvas.offsetHeight - y; + height = height ? Math.min(height, maxHeight) : maxHeight; + if (!hidpi) { + if (!destWidth && !destHeight) { + destWidth = Math.round(width * _pixelRatio.value); + destHeight = Math.round(height * _pixelRatio.value); + } else if (!destWidth) { + destWidth = Math.round(width / height * destHeight); + } else if (!destHeight) { + destHeight = Math.round(height / width * destWidth); + } + } else { + destWidth = width; + destHeight = height; + } + const newCanvas = getTempCanvas(destWidth, destHeight); + const context = newCanvas.getContext("2d"); + if (type === "jpeg" || type === "jpg") { + type = "jpeg"; + context.fillStyle = "#fff"; + context.fillRect(0, 0, destWidth, destHeight); + } + context.__hidpi__ = true; + context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false); + let result; + try { + let compressed; + if (dataType2 === "base64") { + data = newCanvas.toDataURL(`image/${type}`, quality); + } else { + const imgData = context.getImageData(0, 0, destWidth, destHeight); + if (false) + ; + else { + data = Array.prototype.slice.call(imgData.data); + } + } + result = { + data, + compressed, + width: destWidth, + height: destHeight + }; + } catch (error) { + result = { + errMsg: `canvasGetImageData:fail ${error}` + }; + } + newCanvas.height = newCanvas.width = 0; + context.__hidpi__ = false; + if (!resolve) { + return result; + } else { + resolve(result); + } + } + function putImageData({ + data, + x, + y, + width, + height, + compressed + }, resolve) { + try { + if (false) + ; + if (!height) { + height = Math.round(data.length / 4 / width); + } + const canvas = getTempCanvas(width, height); + const context = canvas.getContext("2d"); + context.putImageData(new ImageData(new Uint8ClampedArray(data), width, height), 0, 0); + canvasRef.value.getContext("2d").drawImage(canvas, x, y, width, height); + canvas.height = canvas.width = 0; + } catch (error) { + resolve({ + errMsg: "canvasPutImageData:fail" + }); + return; + } + resolve({ + errMsg: "canvasPutImageData:ok" + }); + } + function toTempFilePath({ + x = 0, + y = 0, + width, + height, + destWidth, + destHeight, + fileType, + quality, + dirname + }, resolve) { + const res = getImageData({ + x, + y, + width, + height, + destWidth, + destHeight, + hidpi: false, + dataType: "base64", + type: fileType, + quality + }); + if (!res.data || !res.data.length) { + resolve({ + errMsg: res.errMsg.replace("canvasPutImageData", "toTempFilePath") + }); + return; + } + saveImage(res.data, dirname, (error, tempFilePath) => { + let errMsg = `toTempFilePath:${error ? "fail" : "ok"}`; + if (error) { + errMsg += ` ${error.message}`; + } + resolve({ + errMsg, + tempFilePath + }); + }); + } + const methods = { + actionsChanged, + getImageData, + putImageData, + toTempFilePath + }; + function _handleSubscribe(type, data, resolve) { + let method = methods[type]; + if (type.indexOf("_") !== 0 && isFunction(method)) { + method(data, resolve); + } + } + return extend(methods, { + _resize, + _handleSubscribe + }); +} +const uniCheckGroupKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniCheckGroup" : "ucg"); +const props$w = { + name: { + type: String, + default: "" + } +}; +const index$u = /* @__PURE__ */ defineBuiltInComponent({ + name: "CheckboxGroup", + props: props$w, + emits: ["change"], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + useProvideCheckGroup(props2, trigger); + return () => { + return createVNode("uni-checkbox-group", { + "ref": rootRef + }, [slots.default && slots.default()], 512); + }; + } +}); +function useProvideCheckGroup(props2, trigger) { + const fields2 = []; + const getFieldsValue = () => fields2.reduce((res, field) => { + if (field.value.checkboxChecked) { + res.push(field.value.value); + } + return res; + }, new Array()); + provide(uniCheckGroupKey, { + addField(field) { + fields2.push(field); + }, + removeField(field) { + fields2.splice(fields2.indexOf(field), 1); + }, + checkboxChange($event) { + trigger("change", $event, { + value: getFieldsValue() + }); + } + }); + const uniForm = inject(uniFormKey, false); + if (uniForm) { + uniForm.addField({ + submit: () => { + let data = ["", null]; + if (props2.name !== "") { + data[0] = props2.name; + data[1] = getFieldsValue(); + } + return data; + } + }); + } + return getFieldsValue; +} +const props$v = { + checked: { + type: [Boolean, String], + default: false + }, + id: { + type: String, + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "#007aff" + }, + value: { + type: String, + default: "" + } +}; +const index$t = /* @__PURE__ */ defineBuiltInComponent({ + name: "Checkbox", + props: props$v, + setup(props2, { + slots + }) { + const checkboxChecked = ref(props2.checked); + const checkboxValue = ref(props2.value); + watch([() => props2.checked, () => props2.value], ([newChecked, newModelValue]) => { + checkboxChecked.value = newChecked; + checkboxValue.value = newModelValue; + }); + const reset = () => { + checkboxChecked.value = false; + }; + const { + uniCheckGroup, + uniLabel + } = useCheckboxInject(checkboxChecked, checkboxValue, reset); + const _onClick = ($event) => { + if (props2.disabled) { + return; + } + checkboxChecked.value = !checkboxChecked.value; + uniCheckGroup && uniCheckGroup.checkboxChange($event); + $event.stopPropagation(); + }; + if (!!uniLabel) { + uniLabel.addHandler(_onClick); + onBeforeUnmount(() => { + uniLabel.removeHandler(_onClick); + }); + } + useListeners$1(props2, { + "label-click": _onClick + }); + return () => { + const booleanAttrs = useBooleanAttr(props2, "disabled"); + return createVNode("uni-checkbox", mergeProps(booleanAttrs, { + "onClick": _onClick + }), [createVNode("div", { + "class": "uni-checkbox-wrapper" + }, [createVNode("div", { + "class": ["uni-checkbox-input", { + "uni-checkbox-input-disabled": props2.disabled + }] + }, [checkboxChecked.value ? createSvgIconVNode(ICON_PATH_SUCCESS_NO_CIRCLE, props2.color, 22) : ""], 2), slots.default && slots.default()])], 16, ["onClick"]); + }; + } +}); +function useCheckboxInject(checkboxChecked, checkboxValue, reset) { + const field = computed(() => ({ + checkboxChecked: Boolean(checkboxChecked.value), + value: checkboxValue.value + })); + const formField = { + reset + }; + const uniCheckGroup = inject(uniCheckGroupKey, false); + if (!!uniCheckGroup) { + uniCheckGroup.addField(field); + } + const uniForm = inject(uniFormKey, false); + if (!!uniForm) { + uniForm.addField(formField); + } + const uniLabel = inject(uniLabelKey, false); + onBeforeUnmount(() => { + uniCheckGroup && uniCheckGroup.removeField(field); + uniForm && uniForm.removeField(formField); + }); + return { + uniCheckGroup, + uniForm, + uniLabel + }; +} +let resetTimer; +function iosHideKeyboard() { +} +const props$u = { + cursorSpacing: { + type: [Number, String], + default: 0 + }, + showConfirmBar: { + type: [Boolean, String], + default: "auto" + }, + adjustPosition: { + type: [Boolean, String], + default: true + }, + autoBlur: { + type: [Boolean, String], + default: false + } +}; +const emit$1 = ["keyboardheightchange"]; +function useKeyboard$1(props2, elRef, trigger) { + function initKeyboard(el) { + const isApple = computed( + () => String(navigator.vendor).indexOf("Apple") === 0 + ); + el.addEventListener("focus", () => { + clearTimeout(resetTimer); + document.addEventListener("click", iosHideKeyboard, false); + }); + const onKeyboardHide = () => { + document.removeEventListener("click", iosHideKeyboard, false); + if (isApple.value) { + document.documentElement.scrollTo( + document.documentElement.scrollLeft, + document.documentElement.scrollTop + ); + } + }; + el.addEventListener("blur", () => { + if (isApple.value) { + el.blur(); + } + onKeyboardHide(); + }); + } + watch( + () => elRef.value, + (el) => el && initKeyboard(el) + ); +} +var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; +var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; +var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; +var empty = /* @__PURE__ */ makeMap( + "area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr" +); +var block = /* @__PURE__ */ makeMap( + "a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video" +); +var inline = /* @__PURE__ */ makeMap( + "abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var" +); +var closeSelf = /* @__PURE__ */ makeMap( + "colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr" +); +var fillAttrs = /* @__PURE__ */ makeMap( + "checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected" +); +var special = /* @__PURE__ */ makeMap("script,style"); +function HTMLParser(html, handler) { + var index2; + var chars2; + var match; + var stack = []; + var last = html; + stack.last = function() { + return this[this.length - 1]; + }; + while (html) { + chars2 = true; + if (!stack.last() || !special[stack.last()]) { + if (html.indexOf(""); + if (index2 >= 0) { + if (handler.comment) { + handler.comment(html.substring(4, index2)); + } + html = html.substring(index2 + 3); + chars2 = false; + } + } else if (html.indexOf("]*>"), + function(all, text3) { + text3 = text3.replace( + /|/g, + "$1$2" + ); + if (handler.chars) { + handler.chars(text3); + } + return ""; + } + ); + parseEndTag("", stack.last()); + } + if (html == last) { + throw "Parse Error: " + html; + } + last = html; + } + parseEndTag(); + function parseStartTag(tag, tagName, rest, unary) { + tagName = tagName.toLowerCase(); + if (block[tagName]) { + while (stack.last() && inline[stack.last()]) { + parseEndTag("", stack.last()); + } + } + if (closeSelf[tagName] && stack.last() == tagName) { + parseEndTag("", tagName); + } + unary = empty[tagName] || !!unary; + if (!unary) { + stack.push(tagName); + } + if (handler.start) { + var attrs2 = []; + rest.replace(attr, function(match2, name) { + var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : ""; + attrs2.push({ + name, + value, + escaped: value.replace(/(^|[^\\])"/g, '$1\\"') + // " + }); + }); + if (handler.start) { + handler.start(tagName, attrs2, unary); + } + } + } + function parseEndTag(tag, tagName) { + if (!tagName) { + var pos = 0; + } else { + for (var pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos] == tagName) { + break; + } + } + } + if (pos >= 0) { + for (var i = stack.length - 1; i >= pos; i--) { + if (handler.end) { + handler.end(stack[i]); + } + } + stack.length = pos; + } + } +} +function makeMap(str) { + var obj = {}; + var items = str.split(","); + for (var i = 0; i < items.length; i++) { + obj[items[i]] = true; + } + return obj; +} +const scripts = {}; +function loadScript(globalName, src, callback) { + const globalObject = isString(globalName) ? window[globalName] : globalName; + if (globalObject) { + callback(); + return; + } + let callbacks2 = scripts[src]; + if (!callbacks2) { + callbacks2 = scripts[src] = []; + const script = document.createElement("script"); + script.src = src; + document.body.appendChild(script); + script.onload = function() { + callbacks2.forEach((callback2) => callback2()); + delete scripts[src]; + }; + } + callbacks2.push(callback); +} +function divider(Quill) { + const BlockEmbed = Quill.import("blots/block/embed"); + class Divider extends BlockEmbed { + } + Divider.blotName = "divider"; + Divider.tagName = "HR"; + return { + "formats/divider": Divider + }; +} +function ins(Quill) { + const Inline = Quill.import("blots/inline"); + class Ins extends Inline { + } + Ins.blotName = "ins"; + Ins.tagName = "INS"; + return { + "formats/ins": Ins + }; +} +function align(Quill) { + const { Scope, Attributor } = Quill.import("parchment"); + const config = { + scope: Scope.BLOCK, + whitelist: ["left", "right", "center", "justify"] + }; + const AlignStyle = new Attributor.Style("align", "text-align", config); + return { + "formats/align": AlignStyle + }; +} +function direction(Quill) { + const { Scope, Attributor } = Quill.import("parchment"); + const config = { + scope: Scope.BLOCK, + whitelist: ["rtl"] + }; + const DirectionStyle = new Attributor.Style("direction", "direction", config); + return { + "formats/direction": DirectionStyle + }; +} +function list(Quill) { + const Parchment = Quill.import("parchment"); + const Container = Quill.import("blots/container"); + const ListItem = Quill.import("formats/list/item"); + class List extends Container { + static create(value) { + const tagName = value === "ordered" ? "OL" : "UL"; + const node = super.create(tagName); + if (value === "checked" || value === "unchecked") { + node.setAttribute("data-checked", value === "checked"); + } + return node; + } + static formats(domNode) { + if (domNode.tagName === "OL") + return "ordered"; + if (domNode.tagName === "UL") { + if (domNode.hasAttribute("data-checked")) { + return domNode.getAttribute("data-checked") === "true" ? "checked" : "unchecked"; + } else { + return "bullet"; + } + } + return void 0; + } + constructor(domNode) { + super(domNode); + const listEventHandler = (e2) => { + if (e2.target.parentNode !== domNode) + return; + const format = this.statics.formats(domNode); + const blot = Parchment.find(e2.target); + if (format === "checked") { + blot.format("list", "unchecked"); + } else if (format === "unchecked") { + blot.format("list", "checked"); + } + }; + domNode.addEventListener("click", listEventHandler); + } + format(name, value) { + if (this.children.length > 0) { + this.children.tail.format(name, value); + } + } + formats() { + return { [this.statics.blotName]: this.statics.formats(this.domNode) }; + } + insertBefore(blot, ref2) { + if (blot instanceof ListItem) { + super.insertBefore(blot, ref2); + } else { + const index2 = ref2 == null ? this.length() : ref2.offset(this); + const after = this.split(index2); + after.parent.insertBefore(blot, after); + } + } + optimize(context) { + super.optimize(context); + const next = this.next; + if (next != null && next.prev === this && next.statics.blotName === this.statics.blotName && next.domNode.tagName === this.domNode.tagName && next.domNode.getAttribute("data-checked") === this.domNode.getAttribute("data-checked")) { + next.moveChildren(this); + next.remove(); + } + } + replace(target) { + if (target.statics.blotName !== this.statics.blotName) { + const item = Parchment.create(this.statics.defaultChild); + target.moveChildren(item); + this.appendChild(item); + } + super.replace(target); + } + } + List.blotName = "list"; + List.scope = Parchment.Scope.BLOCK_BLOT; + List.tagName = ["OL", "UL"]; + List.defaultChild = "list-item"; + List.allowedChildren = [ListItem]; + return { + "formats/list": List + }; +} +function background(Quill) { + const { Scope } = Quill.import("parchment"); + const BackgroundStyle = Quill.import("formats/background"); + const BackgroundColorStyle = new BackgroundStyle.constructor( + "backgroundColor", + "background-color", + { + scope: Scope.INLINE + } + ); + return { + "formats/backgroundColor": BackgroundColorStyle + }; +} +function box(Quill) { + const { Scope, Attributor } = Quill.import("parchment"); + const config = { + scope: Scope.BLOCK + }; + const margin = [ + "margin", + "marginTop", + "marginBottom", + "marginLeft", + "marginRight" + ]; + const padding = [ + "padding", + "paddingTop", + "paddingBottom", + "paddingLeft", + "paddingRight" + ]; + const result = {}; + margin.concat(padding).forEach((name) => { + result[`formats/${name}`] = new Attributor.Style( + name, + hyphenate(name), + config + ); + }); + return result; +} +function font(Quill) { + const { Scope, Attributor } = Quill.import("parchment"); + const config = { + scope: Scope.INLINE + }; + const font2 = [ + "font", + "fontSize", + "fontStyle", + "fontVariant", + "fontWeight", + "fontFamily" + ]; + const result = {}; + font2.forEach((name) => { + result[`formats/${name}`] = new Attributor.Style( + name, + hyphenate(name), + config + ); + }); + return result; +} +function text(Quill) { + const { Scope, Attributor } = Quill.import("parchment"); + const text2 = [ + { + name: "lineHeight", + scope: Scope.BLOCK + }, + { + name: "letterSpacing", + scope: Scope.INLINE + }, + { + name: "textDecoration", + scope: Scope.INLINE + }, + { + name: "textIndent", + scope: Scope.BLOCK + } + ]; + const result = {}; + text2.forEach(({ name, scope: scope2 }) => { + result[`formats/${name}`] = new Attributor.Style(name, hyphenate(name), { + scope: scope2 + }); + }); + return result; +} +function image(Quill) { + const Image2 = Quill.import("formats/image"); + const ATTRIBUTES = [ + "alt", + "height", + "width", + "data-custom", + "class", + "data-local" + ]; + Image2.sanitize = (url) => url ? getRealPath(url) : url; + Image2.formats = function formats(domNode) { + return ATTRIBUTES.reduce( + function(formats2, attribute) { + if (domNode.hasAttribute(attribute)) { + formats2[attribute] = domNode.getAttribute(attribute); + } + return formats2; + }, + {} + ); + }; + const format = Image2.prototype.format; + Image2.prototype.format = function(name, value) { + if (ATTRIBUTES.indexOf(name) > -1) { + if (value) { + this.domNode.setAttribute(name, value); + } else { + this.domNode.removeAttribute(name); + } + } else { + format.call(this, name, value); + } + }; +} +function link(Quill) { + const Link = Quill.import("formats/link"); + Link.sanitize = (url) => { + const anchor = document.createElement("a"); + anchor.href = url; + const protocol = anchor.href.slice(0, anchor.href.indexOf(":")); + return Link.PROTOCOL_WHITELIST.concat("file").indexOf(protocol) > -1 ? url : Link.SANITIZED_URL; + }; +} +function register(Quill) { + const formats = { + divider, + ins, + align, + direction, + list, + background, + box, + font, + text, + image, + link + }; + const options = {}; + Object.values(formats).forEach((value) => extend(options, value(Quill))); + Quill.register(options, true); +} +function useQuill(props2, rootRef, trigger) { + let quillReady; + let skipMatcher; + let quill; + watch( + () => props2.readOnly, + (value) => { + if (quillReady) { + quill.enable(!value); + if (!value) { + quill.blur(); + } + } + } + ); + watch( + () => props2.placeholder, + (value) => { + if (quillReady) { + setPlaceHolder(value); + } + } + ); + function html2delta(html) { + const tags = [ + "span", + "strong", + "b", + "ins", + "em", + "i", + "u", + "a", + "del", + "s", + "sub", + "sup", + "img", + "div", + "p", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "hr", + "ol", + "ul", + "li", + "br" + ]; + let content = ""; + let disable; + HTMLParser(html, { + start: function(tag, attrs2, unary) { + if (!tags.includes(tag)) { + disable = !unary; + return; + } + disable = false; + const arrts = attrs2.map(({ name, value }) => `${name}="${value}"`).join(" "); + const start = `<${tag} ${arrts} ${unary ? "/" : ""}>`; + content += start; + }, + end: function(tag) { + if (!disable) { + content += ``; + } + }, + chars: function(text2) { + if (!disable) { + content += text2; + } + } + }); + skipMatcher = true; + const delta = quill.clipboard.convert(content); + skipMatcher = false; + return delta; + } + function getContents() { + const html = quill.root.innerHTML; + const text2 = quill.getText(); + const delta = quill.getContents(); + return { + html, + text: text2, + delta + }; + } + function setPlaceHolder(placeholder) { + const placeHolderAttrName = "data-placeholder"; + const QuillRoot = quill.root; + QuillRoot.getAttribute(placeHolderAttrName) !== placeholder && QuillRoot.setAttribute(placeHolderAttrName, placeholder); + } + let oldStatus = {}; + function updateStatus(range) { + const status = range ? quill.getFormat(range) : {}; + const keys = Object.keys(status); + if (keys.length !== Object.keys(oldStatus).length || keys.find((key) => status[key] !== oldStatus[key])) { + oldStatus = status; + trigger("statuschange", {}, status); + } + } + function textChangeHandler() { + trigger("input", {}, getContents()); + } + function initQuill(imageResizeModules) { + const Quill = window.Quill; + register(Quill); + const options = { + toolbar: false, + readOnly: props2.readOnly, + placeholder: props2.placeholder + }; + if (imageResizeModules.length) { + Quill.register( + "modules/ImageResize", + window.ImageResize.default + ); + options.modules = { + ImageResize: { + modules: imageResizeModules + } + }; + } + const rootEl = rootRef.value; + quill = new Quill(rootEl, options); + const $el = quill.root; + const events = ["focus", "blur", "input"]; + events.forEach((name) => { + $el.addEventListener(name, ($event) => { + const contents = getContents(); + if (name === "input") { + if (getBaseSystemInfo().platform === "ios") { + const regExpContent = (contents.html.match( + /([\s\S]*)<\/span>/ + ) || [])[1]; + const placeholder = regExpContent && regExpContent.replace(/\s/g, "") ? "" : props2.placeholder; + setPlaceHolder(placeholder); + } + $event.stopPropagation(); + } else { + trigger(name, $event, contents); + } + }); + }); + quill.on("text-change", textChangeHandler); + quill.on("selection-change", updateStatus); + quill.on("scroll-optimize", () => { + const range = quill.selection.getRange()[0]; + updateStatus(range); + }); + quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => { + if (skipMatcher) { + return delta; + } + if (delta.ops) { + delta.ops = delta.ops.filter(({ insert }) => isString(insert)).map(({ insert }) => ({ insert })); + } + return delta; + }); + quillReady = true; + trigger("ready", {}, {}); + } + const id2 = useContextInfo(); + useSubscribe( + (type, data, resolve) => { + const { options, callbackId } = data; + let res; + let range; + let errMsg; + if (quillReady) { + const Quill = window.Quill; + switch (type) { + case "format": + { + let { name = "", value = false } = options; + range = quill.getSelection(true); + let format = quill.getFormat(range)[name] || false; + if (["bold", "italic", "underline", "strike", "ins"].includes(name)) { + value = !format; + } else if (name === "direction") { + value = value === "rtl" && format ? false : value; + const align2 = quill.getFormat(range).align; + if (value === "rtl" && !align2) { + quill.format("align", "right", "user"); + } else if (!value && align2 === "right") { + quill.format("align", false, "user"); + } + } else if (name === "indent") { + const rtl = quill.getFormat(range).direction === "rtl"; + value = value === "+1"; + if (rtl) { + value = !value; + } + value = value ? "+1" : "-1"; + } else { + if (name === "list") { + value = value === "check" ? "unchecked" : value; + format = format === "checked" ? "unchecked" : format; + } + value = format && format !== (value || false) || !format && value ? value : !format; + } + quill.format(name, value, "user"); + } + break; + case "insertDivider": + range = quill.getSelection(true); + quill.insertText(range.index, LINEFEED, "user"); + quill.insertEmbed(range.index + 1, "divider", true, "user"); + quill.setSelection(range.index + 2, 0, "silent"); + break; + case "insertImage": + { + range = quill.getSelection(true); + const { + src = "", + alt = "", + width = "", + height = "", + extClass = "", + data: data2 = {} + } = options; + const path = getRealPath(src); + quill.insertEmbed(range.index, "image", path, "silent"); + const local = /^(file|blob):/.test(path) ? path : false; + quill.formatText(range.index, 1, "data-local", local, "silent"); + quill.formatText(range.index, 1, "alt", alt, "silent"); + quill.formatText(range.index, 1, "width", width, "silent"); + quill.formatText(range.index, 1, "height", height, "silent"); + quill.formatText(range.index, 1, "class", extClass, "silent"); + quill.formatText( + range.index, + 1, + "data-custom", + Object.keys(data2).map((key) => `${key}=${data2[key]}`).join("&"), + "silent" + ); + quill.setSelection(range.index + 1, 0, "silent"); + quill.scrollIntoView(); + setTimeout(() => { + textChangeHandler(); + }, 1e3); + } + break; + case "insertText": + { + range = quill.getSelection(true); + const { text: text2 = "" } = options; + quill.insertText(range.index, text2, "user"); + quill.setSelection(range.index + text2.length, 0, "silent"); + } + break; + case "setContents": + { + const { delta, html } = options; + if (typeof delta === "object") { + quill.setContents(delta, "silent"); + } else if (isString(html)) { + quill.setContents(html2delta(html), "silent"); + } else { + errMsg = "contents is missing"; + } + } + break; + case "getContents": + res = getContents(); + break; + case "clear": + quill.setText(""); + break; + case "removeFormat": + { + range = quill.getSelection(true); + const parchment = Quill.import("parchment"); + if (range.length) { + quill.removeFormat(range.index, range.length, "user"); + } else { + Object.keys(quill.getFormat(range)).forEach((key) => { + if (parchment.query(key, parchment.Scope.INLINE)) { + quill.format(key, false); + } + }); + } + } + break; + case "undo": + quill.history.undo(); + break; + case "redo": + quill.history.redo(); + break; + case "blur": + quill.blur(); + break; + case "getSelectionText": + range = quill.selection.savedRange; + res = { text: "" }; + if (range && range.length !== 0) { + res.text = quill.getText(range.index, range.length); + } + break; + case "scrollIntoView": + quill.scrollIntoView(); + break; + } + updateStatus(range); + } else { + errMsg = "not ready"; + } + if (callbackId) { + resolve({ + callbackId, + data: extend({}, res, { + errMsg: `${type}:${errMsg ? "fail " + errMsg : "ok"}` + }) + }); + } + }, + id2, + true + ); + onMounted(() => { + const imageResizeModules = []; + if (props2.showImgSize) { + imageResizeModules.push("DisplaySize"); + } + if (props2.showImgToolbar) { + imageResizeModules.push("Toolbar"); + } + if (props2.showImgResize) { + imageResizeModules.push("Resize"); + } + const quillSrc = "https://unpkg.com/quill@1.3.7/dist/quill.min.js"; + loadScript(window.Quill, quillSrc, () => { + if (imageResizeModules.length) { + const imageResizeSrc = "https://unpkg.com/quill-image-resize-mp@3.0.1/image-resize.min.js"; + loadScript(window.ImageResize, imageResizeSrc, () => { + initQuill(imageResizeModules); + }); + } else { + initQuill(imageResizeModules); + } + }); + }); +} +const props$t = /* @__PURE__ */ extend({}, props$u, { + id: { + type: String, + default: "" + }, + readOnly: { + type: [Boolean, String], + default: false + }, + placeholder: { + type: String, + default: "" + }, + showImgSize: { + type: [Boolean, String], + default: false + }, + showImgToolbar: { + type: [Boolean, String], + default: false + }, + showImgResize: { + type: [Boolean, String], + default: false + } +}); +const index$s = /* @__PURE__ */ defineBuiltInComponent({ + name: "Editor", + props: props$t, + emit: ["ready", "focus", "blur", "input", "statuschange", ...emit$1], + setup(props2, { + emit: emit2 + }) { + const rootRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + useQuill(props2, rootRef, trigger); + useKeyboard$1(props2, rootRef); + return () => { + return createVNode("uni-editor", { + "ref": rootRef, + "id": props2.id, + "class": "ql-container" + }, null, 8, ["id"]); + }; + } +}); +const INFO_COLOR = "#10aeff"; +const WARN_COLOR = "#f76260"; +const GREY_COLOR = "#b2b2b2"; +const CANCEL_COLOR = "#f43530"; +const ICONS = { + success: { + d: ICON_PATH_SUCCESS, + c: PRIMARY_COLOR + }, + success_no_circle: { + d: ICON_PATH_SUCCESS_NO_CIRCLE, + c: PRIMARY_COLOR + }, + info: { + d: ICON_PATH_INFO, + c: INFO_COLOR + }, + warn: { + d: ICON_PATH_WARN, + c: WARN_COLOR + }, + waiting: { + d: ICON_PATH_WAITING, + c: INFO_COLOR + }, + cancel: { + d: ICON_PATH_CANCEL, + c: CANCEL_COLOR + }, + download: { + d: ICON_PATH_DOWNLOAD, + c: PRIMARY_COLOR + }, + search: { + d: ICON_PATH_SEARCH, + c: GREY_COLOR + }, + clear: { + d: ICON_PATH_CLEAR, + c: GREY_COLOR + } +}; +const index$r = /* @__PURE__ */ defineBuiltInComponent({ + name: "Icon", + props: { + type: { + type: String, + required: true, + default: "" + }, + size: { + type: [String, Number], + default: 23 + }, + color: { + type: String, + default: "" + } + }, + setup(props2) { + const path = computed(() => ICONS[props2.type]); + return () => { + const { + value + } = path; + return createVNode("uni-icon", null, [value && value.d && createSvgIconVNode(value.d, props2.color || value.c, rpx2px(props2.size))]); + }; + } +}); +const props$s = { + src: { + type: String, + default: "" + }, + mode: { + type: String, + default: "scaleToFill" + }, + lazyLoad: { + type: [Boolean, String], + default: false + }, + draggable: { + type: Boolean, + default: false + } +}; +const FIX_MODES = { + widthFix: ["offsetWidth", "height", (value, ratio) => value / ratio], + heightFix: ["offsetHeight", "width", (value, ratio) => value * ratio] +}; +const IMAGE_MODES = { + aspectFit: ["center center", "contain"], + aspectFill: ["center center", "cover"], + widthFix: [, "100% 100%"], + heightFix: [, "100% 100%"], + top: ["center top"], + bottom: ["center bottom"], + center: ["center center"], + left: ["left center"], + right: ["right center"], + "top left": ["left top"], + "top right": ["right top"], + "bottom left": ["left bottom"], + "bottom right": ["right bottom"] +}; +const index$q = /* @__PURE__ */ defineBuiltInComponent({ + name: "Image", + props: props$s, + setup(props2, { + emit: emit2 + }) { + const rootRef = ref(null); + const state2 = useImageState(rootRef, props2); + const trigger = useCustomEvent(rootRef, emit2); + const { + fixSize + } = useImageSize(rootRef, props2, state2); + useImageLoader(state2, props2, rootRef, fixSize, trigger); + return () => { + return createVNode("uni-image", { + "ref": rootRef + }, [createVNode("div", { + "style": state2.modeStyle + }, null, 4), FIX_MODES[props2.mode] ? ( + // @ts-ignore + createVNode(ResizeSensor, { + "onResize": fixSize + }, null, 8, ["onResize"]) + ) : createVNode("span", null, null)], 512); + }; + } +}); +function useImageState(rootRef, props2) { + const imgSrc = ref(""); + const modeStyleRef = computed(() => { + let size = "auto"; + let position = ""; + const opts = IMAGE_MODES[props2.mode]; + if (!opts) { + position = "0% 0%"; + size = "100% 100%"; + } else { + opts[0] && (position = opts[0]); + opts[1] && (size = opts[1]); + } + if (window.weibo && props2.src.startsWith("Temp")) { + imgSrc.value = `../../${props2.src}`; + } + return `background-image:${imgSrc.value ? 'url("' + imgSrc.value + '")' : "none"};background-position:${position};background-size:${size};`; + }); + const state2 = reactive({ + rootEl: rootRef, + src: computed(function() { + if (window.weibo && props2.src.startsWith("Temp")) { + return `../../${props2.src}`; + } + return props2.src ? getRealPath(props2.src) : ""; + }), + origWidth: 0, + origHeight: 0, + origStyle: { + width: "", + height: "" + }, + modeStyle: modeStyleRef, + imgSrc + }); + onMounted(() => { + const rootEl = rootRef.value; + const style = rootEl.style; + state2.origWidth = Number(style.width) || 0; + state2.origHeight = Number(style.height) || 0; + }); + return state2; +} +function useImageLoader(state2, props2, rootRef, fixSize, trigger) { + let img; + let draggableImg; + const setState = (width = 0, height = 0, imgSrc = "") => { + state2.origWidth = width; + state2.origHeight = height; + state2.imgSrc = imgSrc; + }; + const loadImage = (src) => { + if (!src) { + resetImage(); + setState(); + return; + } + img = img || new Image(); + img.onload = (evt) => { + const { + width, + height + } = img; + setState(width, height, src); + fixSize(); + img.draggable = props2.draggable; + if (draggableImg) { + draggableImg.remove(); + } + draggableImg = img; + rootRef.value.appendChild(img); + resetImage(); + trigger("load", evt, { + width, + height + }); + }; + img.onerror = (evt) => { + setState(); + resetImage(); + trigger("error", evt, { + errMsg: `GET ${state2.src} 404 (Not Found)` + }); + }; + img.src = src; + }; + const resetImage = () => { + if (img) { + img.onload = null; + img.onerror = null; + img = null; + } + }; + watch(() => state2.src, (value) => loadImage(value)); + watch(() => state2.imgSrc, (value) => { + if (!value && draggableImg) { + draggableImg.remove(); + draggableImg = null; + } + }); + onMounted(() => loadImage(state2.src)); + onBeforeUnmount(() => resetImage()); +} +const isChrome = navigator.vendor === "Google Inc."; +function fixNumber(num) { + if (isChrome && num > 10) { + num = Math.round(num / 2) * 2; + } + return num; +} +function useImageSize(rootRef, props2, state2) { + const fixSize = () => { + const { + mode: mode2 + } = props2; + const names = FIX_MODES[mode2]; + if (!names) { + return; + } + const { + origWidth, + origHeight + } = state2; + const ratio = origWidth && origHeight ? origWidth / origHeight : 0; + if (!ratio) { + return; + } + const rootEl = rootRef.value; + const value = rootEl[names[0]]; + if (value) { + rootEl.style[names[1]] = fixNumber(names[2](value, ratio)) + "px"; + } + }; + const resetSize = () => { + const { + style + } = rootRef.value; + const { + origStyle: { + width, + height + } + } = state2; + style.width = width; + style.height = height; + }; + watch(() => props2.mode, (value, oldValue) => { + if (FIX_MODES[oldValue]) { + resetSize(); + } + if (FIX_MODES[value]) { + fixSize(); + } + }); + return { + fixSize, + resetSize + }; +} +function throttle(fn, wait) { + let last = 0; + let timeout; + let waitCallback; + const newFn = function(...arg) { + const now = Date.now(); + clearTimeout(timeout); + waitCallback = () => { + waitCallback = null; + last = now; + fn.apply(this, arg); + }; + if (now - last < wait) { + timeout = setTimeout(waitCallback, wait - (now - last)); + return; + } + waitCallback(); + }; + newFn.cancel = function() { + clearTimeout(timeout); + waitCallback = null; + }; + newFn.flush = function() { + clearTimeout(timeout); + waitCallback && waitCallback(); + }; + return newFn; +} +const passiveOptions$1 = /* @__PURE__ */ passive(true); +const states = []; +let userInteract = 0; +let inited; +const setUserAction = (userAction) => states.forEach((vm) => vm.userAction = userAction); +function addInteractListener(vm = { userAction: false }) { + if (!inited) { + const eventNames = [ + "touchstart", + "touchmove", + "touchend", + "mousedown", + "mouseup" + ]; + eventNames.forEach((eventName) => { + document.addEventListener( + eventName, + function() { + !userInteract && setUserAction(true); + userInteract++; + setTimeout(() => { + !--userInteract && setUserAction(false); + }, 0); + }, + passiveOptions$1 + ); + }); + inited = true; + } + states.push(vm); +} +function removeInteractListener(vm) { + const index2 = states.indexOf(vm); + if (index2 >= 0) { + states.splice(index2, 1); + } +} +const getInteractStatus = () => !!userInteract; +function useUserAction() { + const state2 = reactive({ + /** + * 是否用户激活 + */ + userAction: false + }); + onMounted(() => { + addInteractListener(state2); + }); + onBeforeUnmount(() => { + removeInteractListener(state2); + }); + return { + state: state2 + }; +} +function useScopedAttrs() { + const state2 = reactive({ + attrs: {} + }); + onMounted(() => { + let instance2 = getCurrentInstance(); + while (instance2) { + const scopeId = instance2.type.__scopeId; + if (scopeId) { + state2.attrs[scopeId] = ""; + } + instance2 = instance2.proxy && instance2.proxy.$mpType === "page" ? null : instance2.parent; + } + }); + return { + state: state2 + }; +} +function useFormField(nameKey, value) { + const uniForm = inject( + uniFormKey, + false + // remove warning + ); + if (!uniForm) { + return; + } + const instance2 = getCurrentInstance(); + const ctx = { + submit() { + const proxy = instance2.proxy; + return [ + proxy[nameKey], + isString(value) ? proxy[value] : value.value + ]; + }, + reset() { + if (isString(value)) { + instance2.proxy[value] = ""; + } else { + value.value = ""; + } + } + }; + uniForm.addField(ctx); + onBeforeUnmount(() => { + uniForm.removeField(ctx); + }); +} +function getSelectedTextRange(_, resolve) { + const activeElement = document.activeElement; + if (!activeElement) { + return resolve({}); + } + const data = {}; + if (["input", "textarea"].includes(activeElement.tagName.toLowerCase())) { + data.start = activeElement.selectionStart; + data.end = activeElement.selectionEnd; + } + resolve(data); +} +const UniViewJSBridgeSubscribe = function() { + registerViewMethod( + getCurrentPageId(), + "getSelectedTextRange", + getSelectedTextRange + ); +}; +function getValueString(value, type) { + if (type === "number" && isNaN(Number(value))) { + value = ""; + } + return value === null ? "" : String(value); +} +const INPUT_MODES = [ + "none", + "text", + "decimal", + "numeric", + "tel", + "search", + "email", + "url" +]; +const props$r = /* @__PURE__ */ extend( + {}, + { + name: { + type: String, + default: "" + }, + modelValue: { + type: [String, Number], + default: "" + }, + value: { + type: [String, Number], + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + /** + * 已废弃属性,用于历史兼容 + */ + autoFocus: { + type: [Boolean, String], + default: false + }, + focus: { + type: [Boolean, String], + default: false + }, + cursor: { + type: [Number, String], + default: -1 + }, + selectionStart: { + type: [Number, String], + default: -1 + }, + selectionEnd: { + type: [Number, String], + default: -1 + }, + type: { + type: String, + default: "text" + }, + password: { + type: [Boolean, String], + default: false + }, + placeholder: { + type: String, + default: "" + }, + placeholderStyle: { + type: String, + default: "" + }, + placeholderClass: { + type: String, + default: "" + }, + maxlength: { + type: [Number, String], + default: 140 + }, + confirmType: { + type: String, + default: "done" + }, + confirmHold: { + type: Boolean, + default: false + }, + ignoreCompositionEvent: { + type: Boolean, + default: true + }, + step: { + type: String, + default: "0.000000000000000001" + }, + inputmode: { + type: String, + default: void 0, + validator: (value) => !!~INPUT_MODES.indexOf(value) + } + }, + props$u +); +const emit = [ + "input", + "focus", + "blur", + "update:value", + "update:modelValue", + "update:focus", + "compositionstart", + "compositionupdate", + "compositionend", + ...emit$1 +]; +function useBase(props2, rootRef, emit2) { + const fieldRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const selectionStart = computed(() => { + const selectionStart2 = Number(props2.selectionStart); + return isNaN(selectionStart2) ? -1 : selectionStart2; + }); + const selectionEnd = computed(() => { + const selectionEnd2 = Number(props2.selectionEnd); + return isNaN(selectionEnd2) ? -1 : selectionEnd2; + }); + const cursor = computed(() => { + const cursor2 = Number(props2.cursor); + return isNaN(cursor2) ? -1 : cursor2; + }); + const maxlength = computed(() => { + var maxlength2 = Number(props2.maxlength); + return isNaN(maxlength2) ? 140 : maxlength2; + }); + const value = getValueString(props2.modelValue, props2.type) || getValueString(props2.value, props2.type); + const state2 = reactive({ + value, + valueOrigin: value, + maxlength, + focus: props2.focus, + composing: false, + selectionStart, + selectionEnd, + cursor + }); + watch( + () => state2.focus, + (val) => emit2("update:focus", val) + ); + watch( + () => state2.maxlength, + (val) => state2.value = state2.value.slice(0, val) + ); + return { + fieldRef, + state: state2, + trigger + }; +} +function useValueSync(props2, state2, emit2, trigger) { + const valueChangeFn = debounce( + (val) => { + state2.value = getValueString(val, props2.type); + }, + 100, + { setTimeout, clearTimeout } + ); + watch(() => props2.modelValue, valueChangeFn); + watch(() => props2.value, valueChangeFn); + const triggerInputFn = throttle((event, detail) => { + valueChangeFn.cancel(); + emit2("update:modelValue", detail.value); + emit2("update:value", detail.value); + trigger("input", event, detail); + }, 100); + const triggerInput = (event, detail, force) => { + valueChangeFn.cancel(); + triggerInputFn(event, detail); + if (force) { + triggerInputFn.flush(); + } + }; + onBeforeMount(() => { + valueChangeFn.cancel(); + triggerInputFn.cancel(); + }); + return { + trigger, + triggerInput + }; +} +function useAutoFocus(props2, fieldRef) { + useUserAction(); + const needFocus = computed(() => props2.autoFocus || props2.focus); + function focus() { + if (!needFocus.value) { + return; + } + const field = fieldRef.value; + if (!field || false) { + setTimeout(focus, 100); + return; + } + { + field.focus(); + } + } + function blur() { + const field = fieldRef.value; + if (field) { + field.blur(); + } + } + watch( + () => props2.focus, + (value) => { + if (value) { + focus(); + } else { + blur(); + } + } + ); + onMounted(() => { + if (needFocus.value) { + nextTick(focus); + } + }); +} +function useEvent(fieldRef, state2, props2, trigger, triggerInput, beforeInput) { + function checkSelection() { + const field = fieldRef.value; + if (field && state2.focus && state2.selectionStart > -1 && state2.selectionEnd > -1 && field.type !== "number") { + field.selectionStart = state2.selectionStart; + field.selectionEnd = state2.selectionEnd; + } + } + function checkCursor() { + const field = fieldRef.value; + if (field && state2.focus && state2.selectionStart < 0 && state2.selectionEnd < 0 && state2.cursor > -1 && field.type !== "number") { + field.selectionEnd = field.selectionStart = state2.cursor; + } + } + function getFieldSelectionEnd(field) { + if (field.type === "number") { + return null; + } else { + return field.selectionEnd; + } + } + function initField() { + const field = fieldRef.value; + if (!field) + return; + const onFocus = function(event) { + state2.focus = true; + trigger("focus", event, { + value: state2.value + }); + checkSelection(); + checkCursor(); + }; + const onInput = function(event, force) { + event.stopPropagation(); + if (isFunction(beforeInput) && beforeInput(event, state2) === false) { + return; + } + state2.value = field.value; + if (!state2.composing || !props2.ignoreCompositionEvent) { + triggerInput( + event, + { + value: field.value, + cursor: getFieldSelectionEnd(field) + }, + force + ); + } + }; + const onBlur = function(event) { + if (state2.composing) { + state2.composing = false; + onInput(event, true); + } + state2.focus = false; + trigger("blur", event, { + value: state2.value, + cursor: getFieldSelectionEnd(event.target) + }); + }; + field.addEventListener("change", (event) => event.stopPropagation()); + field.addEventListener("focus", onFocus); + field.addEventListener("blur", onBlur); + field.addEventListener("input", onInput); + field.addEventListener("compositionstart", (event) => { + event.stopPropagation(); + state2.composing = true; + _onComposition(event); + }); + field.addEventListener("compositionend", (event) => { + event.stopPropagation(); + if (state2.composing) { + state2.composing = false; + onInput(event); + } + _onComposition(event); + }); + field.addEventListener("compositionupdate", _onComposition); + function _onComposition(event) { + if (!props2.ignoreCompositionEvent) { + trigger(event.type, event, { + value: event.data + }); + } + } + } + watch([() => state2.selectionStart, () => state2.selectionEnd], checkSelection); + watch(() => state2.cursor, checkCursor); + watch(() => fieldRef.value, initField); +} +function useField(props2, rootRef, emit2, beforeInput) { + UniViewJSBridgeSubscribe(); + const { fieldRef, state: state2, trigger } = useBase(props2, rootRef, emit2); + const { triggerInput } = useValueSync(props2, state2, emit2, trigger); + useAutoFocus(props2, fieldRef); + useKeyboard$1(props2, fieldRef); + const { state: scopedAttrsState } = useScopedAttrs(); + useFormField("name", state2); + useEvent(fieldRef, state2, props2, trigger, triggerInput, beforeInput); + const fixDisabledColor = String(navigator.vendor).indexOf("Apple") === 0 && CSS.supports("image-orientation:from-image"); + return { + fieldRef, + state: state2, + scopedAttrsState, + fixDisabledColor, + trigger + }; +} +const props$q = /* @__PURE__ */ extend({}, props$r, { + placeholderClass: { + type: String, + default: "input-placeholder" + }, + textContentType: { + type: String, + default: "" + } +}); +const Input = /* @__PURE__ */ defineBuiltInComponent({ + name: "Input", + props: props$q, + emits: ["confirm", ...emit], + setup(props2, { + emit: emit2 + }) { + const INPUT_TYPES = ["text", "number", "idcard", "digit", "password", "tel"]; + const AUTOCOMPLETES = ["off", "one-time-code"]; + const type = computed(() => { + let type2 = ""; + switch (props2.type) { + case "text": + if (props2.confirmType === "search") { + type2 = "search"; + } + break; + case "idcard": + type2 = "text"; + break; + case "digit": + type2 = "number"; + break; + default: + type2 = ~INPUT_TYPES.includes(props2.type) ? props2.type : "text"; + break; + } + return props2.password ? "password" : type2; + }); + const autocomplete = computed(() => { + const camelizeIndex = AUTOCOMPLETES.indexOf(props2.textContentType); + const kebabCaseIndex = AUTOCOMPLETES.indexOf(hyphenate(props2.textContentType)); + const index2 = camelizeIndex !== -1 ? camelizeIndex : kebabCaseIndex !== -1 ? kebabCaseIndex : 0; + return AUTOCOMPLETES[index2]; + }); + let cache = ref(""); + let resetCache; + const rootRef = ref(null); + const { + fieldRef, + state: state2, + scopedAttrsState, + fixDisabledColor, + trigger + } = useField(props2, rootRef, emit2, (event, state3) => { + const input = event.target; + if (type.value === "number") { + if (resetCache) { + input.removeEventListener("blur", resetCache); + resetCache = null; + } + if (input.validity && !input.validity.valid) { + if ((!cache.value || !input.value) && event.data === "-" || cache.value[0] === "-" && event.inputType === "deleteContentBackward") { + cache.value = "-"; + state3.value = ""; + resetCache = () => { + cache.value = input.value = ""; + }; + input.addEventListener("blur", resetCache); + return false; + } + if (cache.value) { + if (cache.value.indexOf(".") !== -1) { + if (event.data !== "." && event.inputType === "deleteContentBackward") { + const dotIndex = cache.value.indexOf("."); + cache.value = input.value = state3.value = cache.value.slice(0, dotIndex); + return true; + } + } else if (event.data === ".") { + cache.value += "."; + resetCache = () => { + cache.value = input.value = cache.value.slice(0, -1); + }; + input.addEventListener("blur", resetCache); + return false; + } + } + cache.value = state3.value = input.value = cache.value === "-" ? "" : cache.value; + return false; + } else { + cache.value = input.value; + } + const maxlength = state3.maxlength; + if (maxlength > 0 && input.value.length > maxlength) { + input.value = input.value.slice(0, maxlength); + state3.value = input.value; + return false; + } + } + }); + watch(() => state2.value, (value) => { + if (props2.type === "number" && !(cache.value === "-" && value === "")) { + cache.value = value; + } + }); + const NUMBER_TYPES = ["number", "digit"]; + const step = computed(() => NUMBER_TYPES.includes(props2.type) ? props2.step : ""); + function onKeyUpEnter(event) { + if (event.key !== "Enter") { + return; + } + const input = event.target; + event.stopPropagation(); + trigger("confirm", event, { + value: input.value + }); + !props2.confirmHold && input.blur(); + } + return () => { + let inputNode = props2.disabled && fixDisabledColor ? createVNode("input", { + "key": "disabled-input", + "ref": fieldRef, + "value": state2.value, + "tabindex": "-1", + "readonly": !!props2.disabled, + "type": type.value, + "maxlength": state2.maxlength, + "step": step.value, + "class": "uni-input-input", + "onFocus": (event) => event.target.blur() + }, null, 40, ["value", "readonly", "type", "maxlength", "step", "onFocus"]) : withDirectives(createVNode("input", { + "key": "input", + "ref": fieldRef, + "onUpdate:modelValue": ($event) => state2.value = $event, + "disabled": !!props2.disabled, + "type": type.value, + "maxlength": state2.maxlength, + "step": step.value, + "enterkeyhint": props2.confirmType, + "pattern": props2.type === "number" ? "[0-9]*" : void 0, + "class": "uni-input-input", + "autocomplete": autocomplete.value, + "onKeyup": onKeyUpEnter, + "inputmode": props2.inputmode + }, null, 40, ["onUpdate:modelValue", "disabled", "type", "maxlength", "step", "enterkeyhint", "pattern", "autocomplete", "onKeyup", "inputmode"]), [[vModelDynamic, state2.value]]); + return createVNode("uni-input", { + "ref": rootRef + }, [createVNode("div", { + "class": "uni-input-wrapper" + }, [withDirectives(createVNode("div", mergeProps(scopedAttrsState.attrs, { + "style": props2.placeholderStyle, + "class": ["uni-input-placeholder", props2.placeholderClass] + }), [props2.placeholder], 16), [[vShow, !(state2.value.length || cache.value === "-")]]), props2.confirmType === "search" ? createVNode("form", { + "action": "", + "onSubmit": (event) => event.preventDefault(), + "class": "uni-input-form" + }, [inputNode], 40, ["onSubmit"]) : inputNode])], 512); + }; + } +}); +function entries(obj) { + return Object.keys(obj).map((key) => [key, obj[key]]); +} +const DEFAULT_EXCLUDE_KEYS = ["class", "style"]; +const LISTENER_PREFIX = /^on[A-Z]+/; +const useAttrs = (params = {}) => { + const { excludeListeners = false, excludeKeys = [] } = params; + const instance2 = getCurrentInstance(); + const attrs2 = shallowRef({}); + const listeners2 = shallowRef({}); + const excludeAttrs = shallowRef({}); + const allExcludeKeys = excludeKeys.concat(DEFAULT_EXCLUDE_KEYS); + instance2.attrs = reactive(instance2.attrs); + watchEffect(() => { + const res = entries(instance2.attrs).reduce( + (acc, [key, val]) => { + if (allExcludeKeys.includes(key)) { + acc.exclude[key] = val; + } else if (LISTENER_PREFIX.test(key)) { + if (!excludeListeners) { + acc.attrs[key] = val; + } + acc.listeners[key] = val; + } else { + acc.attrs[key] = val; + } + return acc; + }, + { + exclude: {}, + attrs: {}, + listeners: {} + } + ); + attrs2.value = res.attrs; + listeners2.value = res.listeners; + excludeAttrs.value = res.exclude; + }); + return { $attrs: attrs2, $listeners: listeners2, $excludeAttrs: excludeAttrs }; +}; +function flatVNode(nodes) { + const array = []; + if (isArray(nodes)) { + nodes.forEach((vnode) => { + if (isVNode(vnode)) { + if (vnode.type === Fragment) { + array.push(...flatVNode(vnode.children)); + } else { + array.push(vnode); + } + } else if (isArray(vnode)) { + array.push(...flatVNode(vnode)); + } + }); + } + return array; +} +const movableAreaProps = { + scaleArea: { + type: Boolean, + default: false + } +}; +const MovableArea = /* @__PURE__ */ defineBuiltInComponent({ + inheritAttrs: false, + name: "MovableArea", + props: movableAreaProps, + setup(props2, { + slots + }) { + const rootRef = ref(null); + const _isMounted = ref(false); + let { + setContexts, + events: movableAreaEvents + } = useMovableAreaState(props2, rootRef); + const { + $listeners, + $attrs, + $excludeAttrs + } = useAttrs(); + const _listeners = $listeners.value; + let events = ["onTouchstart", "onTouchmove", "onTouchend"]; + events.forEach((event) => { + let existing = _listeners[event]; + let ours = movableAreaEvents[`_${event}`]; + _listeners[event] = existing ? [].concat(existing, ours) : ours; + }); + onMounted(() => { + movableAreaEvents._resize(); + _isMounted.value = true; + }); + let movableViewItems = []; + const originMovableViewContexts = []; + function updateMovableViewContexts() { + const contexts = []; + for (let index2 = 0; index2 < movableViewItems.length; index2++) { + let movableViewItem = movableViewItems[index2]; + { + movableViewItem = movableViewItem.el; + } + const movableViewContext = originMovableViewContexts.find((context) => movableViewItem === context.rootRef.value); + if (movableViewContext) { + contexts.push(markRaw(movableViewContext)); + } + } + setContexts(contexts); + } + const addMovableViewContext = (movableViewContext) => { + originMovableViewContexts.push(movableViewContext); + updateMovableViewContexts(); + }; + const removeMovableViewContext = (movableViewContext) => { + const index2 = originMovableViewContexts.indexOf(movableViewContext); + if (index2 >= 0) { + originMovableViewContexts.splice(index2, 1); + updateMovableViewContexts(); + } + }; + provide("_isMounted", _isMounted); + provide("movableAreaRootRef", rootRef); + provide("addMovableViewContext", addMovableViewContext); + provide("removeMovableViewContext", removeMovableViewContext); + return () => { + const defaultSlots = slots.default && slots.default(); + { + movableViewItems = flatVNode(defaultSlots); + } + return createVNode("uni-movable-area", mergeProps({ + "ref": rootRef + }, $attrs.value, $excludeAttrs.value, _listeners), [createVNode(ResizeSensor, { + "onResize": movableAreaEvents._resize + }, null, 8, ["onResize"]), movableViewItems], 16); + }; + } +}); +function calc(e2) { + return Math.sqrt(e2.x * e2.x + e2.y * e2.y); +} +function useMovableAreaState(props2, rootRef) { + const width = ref(0); + const height = ref(0); + const gapV = reactive({ + x: null, + y: null + }); + const pinchStartLen = ref(null); + let _scaleMovableView = null; + let movableViewContexts = []; + function _updateScale(e2) { + if (e2 && e2 !== 1) { + if (props2.scaleArea) { + movableViewContexts.forEach(function(item) { + item._setScale(e2); + }); + } else { + if (_scaleMovableView) { + _scaleMovableView._setScale(e2); + } + } + } + } + function _find(target, items = movableViewContexts) { + let root = rootRef.value; + function get(node) { + for (let i = 0; i < items.length; i++) { + const item = items[i]; + if (node === item.rootRef.value) { + return item; + } + } + if (node === root || node === document.body || node === document) { + return null; + } + return get(node.parentNode); + } + return get(target); + } + const _onTouchstart = withWebEvent((t2) => { + let i = t2.touches; + if (i) { + if (i.length > 1) { + let r = { + x: i[1].pageX - i[0].pageX, + y: i[1].pageY - i[0].pageY + }; + pinchStartLen.value = calc(r); + gapV.x = r.x; + gapV.y = r.y; + if (!props2.scaleArea) { + let touch0 = _find(i[0].target); + let touch1 = _find(i[1].target); + _scaleMovableView = touch0 && touch0 === touch1 ? touch0 : null; + } + } + } + }); + const _onTouchmove = withWebEvent((t2) => { + let n = t2.touches; + if (n) { + if (n.length > 1) { + t2.preventDefault(); + let i = { + x: n[1].pageX - n[0].pageX, + y: n[1].pageY - n[0].pageY + }; + if (gapV.x !== null && pinchStartLen.value && pinchStartLen.value > 0) { + let r = calc(i) / pinchStartLen.value; + _updateScale(r); + } + gapV.x = i.x; + gapV.y = i.y; + } + } + }); + const _onTouchend = withWebEvent((e2) => { + let t2 = e2.touches; + if (!(t2 && t2.length)) { + if (e2.changedTouches) { + gapV.x = 0; + gapV.y = 0; + pinchStartLen.value = null; + if (props2.scaleArea) { + movableViewContexts.forEach(function(item) { + item._endScale(); + }); + } else { + if (_scaleMovableView) { + _scaleMovableView._endScale(); + } + } + } + } + }); + function _resize() { + _getWH(); + movableViewContexts.forEach(function(item, index2) { + item.setParent(); + }); + } + function _getWH() { + let style = window.getComputedStyle(rootRef.value); + let rect = rootRef.value.getBoundingClientRect(); + width.value = rect.width - ["Left", "Right"].reduce(function(all, item) { + const LEFT = "border" + item + "Width"; + const RIGHT = "padding" + item; + return all + parseFloat(style[LEFT]) + parseFloat(style[RIGHT]); + }, 0); + height.value = rect.height - ["Top", "Bottom"].reduce(function(all, item) { + const TOP = "border" + item + "Width"; + const BOTTOM = "padding" + item; + return all + parseFloat(style[TOP]) + parseFloat(style[BOTTOM]); + }, 0); + } + provide("movableAreaWidth", width); + provide("movableAreaHeight", height); + return { + setContexts(contexts) { + movableViewContexts = contexts; + }, + events: { + _onTouchstart, + _onTouchmove, + _onTouchend, + _resize + } + }; +} +const addListenerToElement = function(element, type, callback, capture) { + element.addEventListener( + type, + ($event) => { + if (isFunction(callback)) { + if (callback($event) === false) { + if (typeof $event.cancelable !== "undefined" ? $event.cancelable : true) { + $event.preventDefault(); + } + $event.stopPropagation(); + } + } + }, + { + passive: false + } + ); +}; +let __mouseMoveEventListener; +let __mouseUpEventListener; +function useTouchtrack(element, method, useCancel) { + onBeforeUnmount(() => { + document.removeEventListener("mousemove", __mouseMoveEventListener); + document.removeEventListener("mouseup", __mouseUpEventListener); + }); + let x0 = 0; + let y0 = 0; + let x1 = 0; + let y1 = 0; + const fn = function($event, state2, x, y) { + if (method({ + // @ts-expect-error + cancelable: $event.cancelable, + target: $event.target, + currentTarget: $event.currentTarget, + preventDefault: $event.preventDefault.bind($event), + stopPropagation: $event.stopPropagation.bind($event), + touches: $event.touches, + changedTouches: $event.changedTouches, + detail: { + state: state2, + x, + y, + dx: x - x0, + dy: y - y0, + ddx: x - x1, + ddy: y - y1, + timeStamp: $event.timeStamp + } + }) === false) { + return false; + } + }; + let $eventOld = null; + let hasTouchStart; + let hasMouseDown; + addListenerToElement(element, "touchstart", function($event) { + hasTouchStart = true; + if ($event.touches.length === 1 && !$eventOld) { + $eventOld = $event; + x0 = x1 = $event.touches[0].pageX; + y0 = y1 = $event.touches[0].pageY; + return fn($event, "start", x0, y0); + } + }); + addListenerToElement(element, "mousedown", function($event) { + hasMouseDown = true; + if (!hasTouchStart && !$eventOld) { + $eventOld = $event; + x0 = x1 = $event.pageX; + y0 = y1 = $event.pageY; + return fn($event, "start", x0, y0); + } + }); + addListenerToElement(element, "touchmove", function($event) { + if ($event.touches.length === 1 && $eventOld) { + const res = fn( + $event, + "move", + $event.touches[0].pageX, + $event.touches[0].pageY + ); + x1 = $event.touches[0].pageX; + y1 = $event.touches[0].pageY; + return res; + } + }); + const mouseMoveEventListener = __mouseMoveEventListener = function($event) { + if (!hasTouchStart && hasMouseDown && $eventOld) { + const res = fn($event, "move", $event.pageX, $event.pageY); + x1 = $event.pageX; + y1 = $event.pageY; + return res; + } + }; + document.addEventListener("mousemove", mouseMoveEventListener); + addListenerToElement(element, "touchend", function($event) { + if ($event.touches.length === 0 && $eventOld) { + hasTouchStart = false; + $eventOld = null; + return fn( + $event, + "end", + $event.changedTouches[0].pageX, + $event.changedTouches[0].pageY + ); + } + }); + const mouseUpEventListener = __mouseUpEventListener = function($event) { + hasMouseDown = false; + if (!hasTouchStart && $eventOld) { + $eventOld = null; + return fn($event, "end", $event.pageX, $event.pageY); + } + }; + document.addEventListener("mouseup", mouseUpEventListener); + addListenerToElement(element, "touchcancel", function($event) { + if ($eventOld) { + hasTouchStart = false; + const $eventTemp = $eventOld; + $eventOld = null; + return fn( + $event, + useCancel ? "cancel" : "end", + $eventTemp.touches[0].pageX, + $eventTemp.touches[0].pageY + ); + } + }); +} +function e(e2, t2, n) { + return e2 > t2 - n && e2 < t2 + n; +} +function t(t2, n) { + return e(t2, 0, n); +} +function Decline() { +} +Decline.prototype.x = function(e2) { + return Math.sqrt(e2); +}; +function Friction$1(e2, t2) { + this._m = e2; + this._f = 1e3 * t2; + this._startTime = 0; + this._v = 0; +} +Friction$1.prototype.setV = function(x, y) { + const n = Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5); + this._x_v = x; + this._y_v = y; + this._x_a = -this._f * this._x_v / n; + this._y_a = -this._f * this._y_v / n; + this._t = Math.abs(x / this._x_a) || Math.abs(y / this._y_a); + this._lastDt = null; + this._startTime = (/* @__PURE__ */ new Date()).getTime(); +}; +Friction$1.prototype.setS = function(x, y) { + this._x_s = x; + this._y_s = y; +}; +Friction$1.prototype.s = function(t2) { + if (void 0 === t2) { + t2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + if (t2 > this._t) { + t2 = this._t; + this._lastDt = t2; + } + let x = this._x_v * t2 + 0.5 * this._x_a * Math.pow(t2, 2) + this._x_s; + let y = this._y_v * t2 + 0.5 * this._y_a * Math.pow(t2, 2) + this._y_s; + if (this._x_a > 0 && x < this._endPositionX || this._x_a < 0 && x > this._endPositionX) { + x = this._endPositionX; + } + if (this._y_a > 0 && y < this._endPositionY || this._y_a < 0 && y > this._endPositionY) { + y = this._endPositionY; + } + return { + x, + y + }; +}; +Friction$1.prototype.ds = function(t2) { + if (void 0 === t2) { + t2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + if (t2 > this._t) { + t2 = this._t; + } + return { + dx: this._x_v + this._x_a * t2, + dy: this._y_v + this._y_a * t2 + }; +}; +Friction$1.prototype.delta = function() { + return { + x: -1.5 * Math.pow(this._x_v, 2) / this._x_a || 0, + y: -1.5 * Math.pow(this._y_v, 2) / this._y_a || 0 + }; +}; +Friction$1.prototype.dt = function() { + return -this._x_v / this._x_a; +}; +Friction$1.prototype.done = function() { + const t2 = e(this.s().x, this._endPositionX) || e(this.s().y, this._endPositionY) || this._lastDt === this._t; + this._lastDt = null; + return t2; +}; +Friction$1.prototype.setEnd = function(x, y) { + this._endPositionX = x; + this._endPositionY = y; +}; +Friction$1.prototype.reconfigure = function(m, f2) { + this._m = m; + this._f = 1e3 * f2; +}; +function Spring$1(m, k, c) { + this._m = m; + this._k = k; + this._c = c; + this._solution = null; + this._endPosition = 0; + this._startTime = 0; +} +Spring$1.prototype._solve = function(e2, t2) { + const n = this._c; + const i = this._m; + const r = this._k; + const o2 = n * n - 4 * i * r; + if (o2 === 0) { + const a2 = -n / (2 * i); + const s = e2; + const l = t2 / (a2 * e2); + return { + x: function(e3) { + return (s + l * e3) * Math.pow(Math.E, a2 * e3); + }, + dx: function(e3) { + const t3 = Math.pow(Math.E, a2 * e3); + return a2 * (s + l * e3) * t3 + l * t3; + } + }; + } + if (o2 > 0) { + const c = (-n - Math.sqrt(o2)) / (2 * i); + const u = (-n + Math.sqrt(o2)) / (2 * i); + const d = (t2 - c * e2) / (u - c); + const h2 = e2 - d; + return { + x: function(e3) { + let t3; + let n2; + if (e3 === this._t) { + t3 = this._powER1T; + n2 = this._powER2T; + } + this._t = e3; + if (!t3) { + t3 = this._powER1T = Math.pow(Math.E, c * e3); + } + if (!n2) { + n2 = this._powER2T = Math.pow(Math.E, u * e3); + } + return h2 * t3 + d * n2; + }, + dx: function(e3) { + let t3; + let n2; + if (e3 === this._t) { + t3 = this._powER1T; + n2 = this._powER2T; + } + this._t = e3; + if (!t3) { + t3 = this._powER1T = Math.pow(Math.E, c * e3); + } + if (!n2) { + n2 = this._powER2T = Math.pow(Math.E, u * e3); + } + return h2 * c * t3 + d * u * n2; + } + }; + } + const p2 = Math.sqrt(4 * i * r - n * n) / (2 * i); + const f2 = -n / 2 * i; + const v2 = e2; + const g2 = (t2 - f2 * e2) / p2; + return { + x: function(e3) { + return Math.pow(Math.E, f2 * e3) * (v2 * Math.cos(p2 * e3) + g2 * Math.sin(p2 * e3)); + }, + dx: function(e3) { + const t3 = Math.pow(Math.E, f2 * e3); + const n2 = Math.cos(p2 * e3); + const i2 = Math.sin(p2 * e3); + return t3 * (g2 * p2 * n2 - v2 * p2 * i2) + f2 * t3 * (g2 * i2 + v2 * n2); + } + }; +}; +Spring$1.prototype.x = function(e2) { + if (void 0 === e2) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + return this._solution ? this._endPosition + this._solution.x(e2) : 0; +}; +Spring$1.prototype.dx = function(e2) { + if (void 0 === e2) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + return this._solution ? this._solution.dx(e2) : 0; +}; +Spring$1.prototype.setEnd = function(e2, n, i) { + if (!i) { + i = (/* @__PURE__ */ new Date()).getTime(); + } + if (e2 !== this._endPosition || !t(n, 0.1)) { + n = n || 0; + let r = this._endPosition; + if (this._solution) { + if (t(n, 0.1)) { + n = this._solution.dx((i - this._startTime) / 1e3); + } + r = this._solution.x((i - this._startTime) / 1e3); + if (t(n, 0.1)) { + n = 0; + } + if (t(r, 0.1)) { + r = 0; + } + r += this._endPosition; + } + if (!(this._solution && t(r - e2, 0.1) && t(n, 0.1))) { + this._endPosition = e2; + this._solution = this._solve(r - this._endPosition, n); + this._startTime = i; + } + } +}; +Spring$1.prototype.snap = function(e2) { + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + this._endPosition = e2; + this._solution = { + x: function() { + return 0; + }, + dx: function() { + return 0; + } + }; +}; +Spring$1.prototype.done = function(n) { + if (!n) { + n = (/* @__PURE__ */ new Date()).getTime(); + } + return e(this.x(), this._endPosition, 0.1) && t(this.dx(), 0.1); +}; +Spring$1.prototype.reconfigure = function(m, t2, c) { + this._m = m; + this._k = t2; + this._c = c; + if (!this.done()) { + this._solution = this._solve(this.x() - this._endPosition, this.dx()); + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + } +}; +Spring$1.prototype.springConstant = function() { + return this._k; +}; +Spring$1.prototype.damping = function() { + return this._c; +}; +Spring$1.prototype.configuration = function() { + function e2(e3, t3) { + e3.reconfigure(1, t3, e3.damping()); + } + function t2(e3, t3) { + e3.reconfigure(1, e3.springConstant(), t3); + } + return [ + { + label: "Spring Constant", + read: this.springConstant.bind(this), + write: e2.bind(this, this), + min: 100, + max: 1e3 + }, + { + label: "Damping", + read: this.damping.bind(this), + write: t2.bind(this, this), + min: 1, + max: 500 + } + ]; +}; +function STD(e2, t2, n) { + this._springX = new Spring$1(e2, t2, n); + this._springY = new Spring$1(e2, t2, n); + this._springScale = new Spring$1(e2, t2, n); + this._startTime = 0; +} +STD.prototype.setEnd = function(e2, t2, n, i) { + const r = (/* @__PURE__ */ new Date()).getTime(); + this._springX.setEnd(e2, i, r); + this._springY.setEnd(t2, i, r); + this._springScale.setEnd(n, i, r); + this._startTime = r; +}; +STD.prototype.x = function() { + const e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + return { + x: this._springX.x(e2), + y: this._springY.x(e2), + scale: this._springScale.x(e2) + }; +}; +STD.prototype.done = function() { + const e2 = (/* @__PURE__ */ new Date()).getTime(); + return this._springX.done(e2) && this._springY.done(e2) && this._springScale.done(e2); +}; +STD.prototype.reconfigure = function(e2, t2, n) { + this._springX.reconfigure(e2, t2, n); + this._springY.reconfigure(e2, t2, n); + this._springScale.reconfigure(e2, t2, n); +}; +const movableViewProps = { + direction: { + type: String, + default: "none" + }, + inertia: { + type: [Boolean, String], + default: false + }, + outOfBounds: { + type: [Boolean, String], + default: false + }, + x: { + type: [Number, String], + default: 0 + }, + y: { + type: [Number, String], + default: 0 + }, + damping: { + type: [Number, String], + default: 20 + }, + friction: { + type: [Number, String], + default: 2 + }, + disabled: { + type: [Boolean, String], + default: false + }, + scale: { + type: [Boolean, String], + default: false + }, + scaleMin: { + type: [Number, String], + default: 0.5 + }, + scaleMax: { + type: [Number, String], + default: 10 + }, + scaleValue: { + type: [Number, String], + default: 1 + }, + animation: { + type: [Boolean, String], + default: true + } +}; +function v(a2, b) { + return +((1e3 * a2 - 1e3 * b) / 1e3).toFixed(1); +} +const MovableView = /* @__PURE__ */ defineBuiltInComponent({ + name: "MovableView", + props: movableViewProps, + emits: ["change", "scale"], + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const { + setParent + } = useMovableViewState(props2, trigger, rootRef); + return () => { + return createVNode("uni-movable-view", { + "ref": rootRef + }, [createVNode(ResizeSensor, { + "onResize": setParent + }, null, 8, ["onResize"]), slots.default && slots.default()], 512); + }; + } +}); +let requesting = false; +function _requestAnimationFrame(e2) { + if (!requesting) { + requesting = true; + requestAnimationFrame(function() { + e2(); + requesting = false; + }); + } +} +function p(t2, n) { + if (t2 === n) { + return 0; + } + let i = t2.offsetLeft; + return t2.offsetParent ? i += p(t2.offsetParent, n) : 0; +} +function f(t2, n) { + if (t2 === n) { + return 0; + } + let i = t2.offsetTop; + return t2.offsetParent ? i += f(t2.offsetParent, n) : 0; +} +function g(friction, execute, endCallback) { + let record = { + id: 0, + cancelled: false + }; + let cancel = function(record2) { + if (record2 && record2.id) { + cancelAnimationFrame(record2.id); + } + if (record2) { + record2.cancelled = true; + } + }; + function fn(record2, friction2, execute2, endCallback2) { + if (!record2 || !record2.cancelled) { + execute2(friction2); + let isDone = friction2.done(); + if (!isDone) { + if (!record2.cancelled) { + record2.id = requestAnimationFrame(fn.bind(null, record2, friction2, execute2, endCallback2)); + } + } + if (isDone && endCallback2) { + endCallback2(friction2); + } + } + } + fn(record, friction, execute, endCallback); + return { + cancel: cancel.bind(null, record), + model: friction + }; +} +function _getPx(val) { + if (/\d+[ur]px$/i.test(val)) { + return uni.upx2px(parseFloat(val)); + } + return Number(val) || 0; +} +function useMovableViewLayout(rootRef, _scale, _adjustScale) { + const movableAreaWidth = inject("movableAreaWidth", ref(0)); + const movableAreaHeight = inject("movableAreaHeight", ref(0)); + const movableAreaRootRef = inject("movableAreaRootRef"); + const _offset = { + x: 0, + y: 0 + }; + const _scaleOffset = { + x: 0, + y: 0 + }; + const width = ref(0); + const height = ref(0); + const minX = ref(0); + const minY = ref(0); + const maxX = ref(0); + const maxY = ref(0); + function _updateBoundary() { + let x = 0 - _offset.x + _scaleOffset.x; + let _width = movableAreaWidth.value - width.value - _offset.x - _scaleOffset.x; + minX.value = Math.min(x, _width); + maxX.value = Math.max(x, _width); + let y = 0 - _offset.y + _scaleOffset.y; + let _height = movableAreaHeight.value - height.value - _offset.y - _scaleOffset.y; + minY.value = Math.min(y, _height); + maxY.value = Math.max(y, _height); + } + function _updateOffset() { + _offset.x = p(rootRef.value, movableAreaRootRef.value); + _offset.y = f(rootRef.value, movableAreaRootRef.value); + } + function _updateWH(scale) { + scale = scale || _scale.value; + scale = _adjustScale(scale); + let rect = rootRef.value.getBoundingClientRect(); + height.value = rect.height / _scale.value; + width.value = rect.width / _scale.value; + let _height = height.value * scale; + let _width = width.value * scale; + _scaleOffset.x = (_width - width.value) / 2; + _scaleOffset.y = (_height - height.value) / 2; + } + return { + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY + }; +} +function useMovableViewTransform(rootRef, props2, _scaleOffset, _scale, maxX, maxY, minX, minY, _translateX, _translateY, _SFA, _FA, _adjustScale, trigger) { + const dampingNumber = computed(() => { + let val = Number(props2.damping); + return isNaN(val) ? 20 : val; + }); + const xMove = computed(() => props2.direction === "all" || props2.direction === "horizontal"); + const yMove = computed(() => props2.direction === "all" || props2.direction === "vertical"); + const xSync = ref(_getPx(props2.x)); + const ySync = ref(_getPx(props2.y)); + watch(() => props2.x, (val) => { + xSync.value = _getPx(val); + }); + watch(() => props2.y, (val) => { + ySync.value = _getPx(val); + }); + watch(xSync, (val) => { + _setX(val); + }); + watch(ySync, (val) => { + _setY(val); + }); + const _STD = new STD(1, 9 * Math.pow(dampingNumber.value, 2) / 40, dampingNumber.value); + function _getLimitXY(x, y) { + let outOfBounds = false; + if (x > maxX.value) { + x = maxX.value; + outOfBounds = true; + } else { + if (x < minX.value) { + x = minX.value; + outOfBounds = true; + } + } + if (y > maxY.value) { + y = maxY.value; + outOfBounds = true; + } else { + if (y < minY.value) { + y = minY.value; + outOfBounds = true; + } + } + return { + x, + y, + outOfBounds + }; + } + function FAandSFACancel() { + if (_FA) { + _FA.cancel(); + } + if (_SFA) { + _SFA.cancel(); + } + } + function _animationTo(x, y, scale, source, r, o2) { + FAandSFACancel(); + if (!xMove.value) { + x = _translateX.value; + } + if (!yMove.value) { + y = _translateY.value; + } + if (!props2.scale) { + scale = _scale.value; + } + let limitXY = _getLimitXY(x, y); + x = limitXY.x; + y = limitXY.y; + if (!props2.animation) { + _setTransform(x, y, scale, source, r, o2); + return; + } + _STD._springX._solution = null; + _STD._springY._solution = null; + _STD._springScale._solution = null; + _STD._springX._endPosition = _translateX.value; + _STD._springY._endPosition = _translateY.value; + _STD._springScale._endPosition = _scale.value; + _STD.setEnd(x, y, scale, 1); + _SFA = g(_STD, function() { + let data = _STD.x(); + let x2 = data.x; + let y2 = data.y; + let scale2 = data.scale; + _setTransform(x2, y2, scale2, source, r, o2); + }, function() { + _SFA.cancel(); + }); + } + function _setTransform(x, y, scale, source = "", r, o2) { + if (!(x !== null && x.toString() !== "NaN" && typeof x === "number")) { + x = _translateX.value || 0; + } + if (!(y !== null && y.toString() !== "NaN" && typeof y === "number")) { + y = _translateY.value || 0; + } + x = Number(x.toFixed(1)); + y = Number(y.toFixed(1)); + scale = Number(scale.toFixed(1)); + if (!(_translateX.value === x && _translateY.value === y)) { + if (!r) { + trigger("change", {}, { + x: v(x, _scaleOffset.x), + y: v(y, _scaleOffset.y), + source + }); + } + } + if (!props2.scale) { + scale = _scale.value; + } + scale = _adjustScale(scale); + scale = +scale.toFixed(3); + if (o2 && scale !== _scale.value) { + trigger("scale", {}, { + x, + y, + scale + }); + } + let transform = "translateX(" + x + "px) translateY(" + y + "px) translateZ(0px) scale(" + scale + ")"; + if (rootRef.value) { + rootRef.value.style.transform = transform; + rootRef.value.style.webkitTransform = transform; + _translateX.value = x; + _translateY.value = y; + _scale.value = scale; + } + } + function _revise(source) { + let limitXY = _getLimitXY(_translateX.value, _translateY.value); + let x = limitXY.x; + let y = limitXY.y; + let outOfBounds = limitXY.outOfBounds; + if (outOfBounds) { + _animationTo(x, y, _scale.value, source); + } + return outOfBounds; + } + function _setX(val) { + if (xMove.value) { + if (val + _scaleOffset.x === _translateX.value) { + return _translateX; + } else { + if (_SFA) { + _SFA.cancel(); + } + _animationTo(val + _scaleOffset.x, ySync.value + _scaleOffset.y, _scale.value); + } + } + return val; + } + function _setY(val) { + if (yMove.value) { + if (val + _scaleOffset.y === _translateY.value) { + return _translateY; + } else { + if (_SFA) { + _SFA.cancel(); + } + _animationTo(xSync.value + _scaleOffset.x, val + _scaleOffset.y, _scale.value); + } + } + return val; + } + return { + FAandSFACancel, + _getLimitXY, + _animationTo, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + }; +} +function useMovableViewInit(props2, rootRef, trigger, _scale, _oldScale, _isScaling, _translateX, _translateY, _SFA, _FA) { + const scaleMinNumber = computed(() => { + let val = Number(props2.scaleMin); + return isNaN(val) ? 0.5 : val; + }); + const scaleMaxNumber = computed(() => { + let val = Number(props2.scaleMax); + return isNaN(val) ? 10 : val; + }); + const scaleValueSync = ref(Number(props2.scaleValue) || 1); + watch(scaleValueSync, (val) => { + _setScaleValue(val); + }); + watch(scaleMinNumber, () => { + _setScaleMinOrMax(); + }); + watch(scaleMaxNumber, () => { + _setScaleMinOrMax(); + }); + watch(() => props2.scaleValue, (val) => { + scaleValueSync.value = Number(val) || 0; + }); + const { + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY + } = useMovableViewLayout(rootRef, _scale, _adjustScale); + const { + FAandSFACancel, + _getLimitXY, + _animationTo, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + } = useMovableViewTransform(rootRef, props2, _scaleOffset, _scale, maxX, maxY, minX, minY, _translateX, _translateY, _SFA, _FA, _adjustScale, trigger); + function _updateScale(scale, animat) { + if (props2.scale) { + scale = _adjustScale(scale); + _updateWH(scale); + _updateBoundary(); + const limitXY = _getLimitXY(_translateX.value, _translateY.value); + const x = limitXY.x; + const y = limitXY.y; + if (animat) { + _animationTo(x, y, scale, "", true, true); + } else { + _requestAnimationFrame(function() { + _setTransform(x, y, scale, "", true, true); + }); + } + } + } + function _beginScale() { + _isScaling.value = true; + } + function _updateOldScale(scale) { + _oldScale.value = scale; + } + function _adjustScale(scale) { + scale = Math.max(0.5, scaleMinNumber.value, scale); + scale = Math.min(10, scaleMaxNumber.value, scale); + return scale; + } + function _setScaleMinOrMax() { + if (!props2.scale) { + return false; + } + _updateScale(_scale.value, true); + _updateOldScale(_scale.value); + } + function _setScaleValue(scale) { + if (!props2.scale) { + return false; + } + scale = _adjustScale(scale); + _updateScale(scale, true); + _updateOldScale(scale); + return scale; + } + function _endScale() { + _isScaling.value = false; + _updateOldScale(_scale.value); + } + function _setScale(scale) { + if (scale) { + scale = _oldScale.value * scale; + _beginScale(); + _updateScale(scale); + } + } + return { + // scale + _updateOldScale, + _endScale, + _setScale, + scaleValueSync, + // layout + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY, + // transform + FAandSFACancel, + _getLimitXY, + _animationTo, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + }; +} +function useMovableViewState(props2, trigger, rootRef) { + const _isMounted = inject("_isMounted", ref(false)); + const addMovableViewContext = inject("addMovableViewContext", () => { + }); + const removeMovableViewContext = inject("removeMovableViewContext", () => { + }); + let _scale = ref(1); + let _oldScale = ref(1); + let _isScaling = ref(false); + let _translateX = ref(0); + let _translateY = ref(0); + let _SFA = null; + let _FA = null; + let _isTouching = false; + let __baseX; + let __baseY; + let _checkCanMove = null; + let _firstMoveDirection = null; + const _declineX = new Decline(); + const _declineY = new Decline(); + const __touchInfo = { + historyX: [0, 0], + historyY: [0, 0], + historyT: [0, 0] + }; + const frictionNumber = computed(() => { + let val = Number(props2.friction); + return isNaN(val) || val <= 0 ? 2 : val; + }); + const _friction = new Friction$1(1, frictionNumber.value); + watch(() => props2.disabled, () => { + __handleTouchStart(); + }); + const { + // scale + _updateOldScale, + _endScale, + _setScale, + scaleValueSync, + // layout + _updateBoundary, + _updateOffset, + _updateWH, + _scaleOffset, + minX, + minY, + maxX, + maxY, + // transform + FAandSFACancel, + _getLimitXY, + _setTransform, + _revise, + dampingNumber, + xMove, + yMove, + xSync, + ySync, + _STD + } = useMovableViewInit(props2, rootRef, trigger, _scale, _oldScale, _isScaling, _translateX, _translateY, _SFA, _FA); + function __handleTouchStart() { + if (!_isScaling.value) { + if (!props2.disabled) { + FAandSFACancel(); + __touchInfo.historyX = [0, 0]; + __touchInfo.historyY = [0, 0]; + __touchInfo.historyT = [0, 0]; + if (xMove.value) { + __baseX = _translateX.value; + } + if (yMove.value) { + __baseY = _translateY.value; + } + rootRef.value.style.willChange = "transform"; + _checkCanMove = null; + _firstMoveDirection = null; + _isTouching = true; + } + } + } + function __handleTouchMove(event) { + if (!_isScaling.value && !props2.disabled && _isTouching) { + let x = _translateX.value; + let y = _translateY.value; + if (_firstMoveDirection === null) { + _firstMoveDirection = Math.abs(event.detail.dx / event.detail.dy) > 1 ? "htouchmove" : "vtouchmove"; + } + if (xMove.value) { + x = event.detail.dx + __baseX; + __touchInfo.historyX.shift(); + __touchInfo.historyX.push(x); + if (!yMove.value && _checkCanMove === null) { + _checkCanMove = Math.abs(event.detail.dx / event.detail.dy) < 1; + } + } + if (yMove.value) { + y = event.detail.dy + __baseY; + __touchInfo.historyY.shift(); + __touchInfo.historyY.push(y); + if (!xMove.value && _checkCanMove === null) { + _checkCanMove = Math.abs(event.detail.dy / event.detail.dx) < 1; + } + } + __touchInfo.historyT.shift(); + __touchInfo.historyT.push(event.detail.timeStamp); + if (!_checkCanMove) { + event.preventDefault(); + let source = "touch"; + if (x < minX.value) { + if (props2.outOfBounds) { + source = "touch-out-of-bounds"; + x = minX.value - _declineX.x(minX.value - x); + } else { + x = minX.value; + } + } else if (x > maxX.value) { + if (props2.outOfBounds) { + source = "touch-out-of-bounds"; + x = maxX.value + _declineX.x(x - maxX.value); + } else { + x = maxX.value; + } + } + if (y < minY.value) { + if (props2.outOfBounds) { + source = "touch-out-of-bounds"; + y = minY.value - _declineY.x(minY.value - y); + } else { + y = minY.value; + } + } else { + if (y > maxY.value) { + if (props2.outOfBounds) { + source = "touch-out-of-bounds"; + y = maxY.value + _declineY.x(y - maxY.value); + } else { + y = maxY.value; + } + } + } + _requestAnimationFrame(function() { + _setTransform(x, y, _scale.value, source); + }); + } + } + } + function __handleTouchEnd() { + if (!_isScaling.value && !props2.disabled && _isTouching) { + rootRef.value.style.willChange = "auto"; + _isTouching = false; + if (!_checkCanMove && !_revise("out-of-bounds") && props2.inertia) { + const xv = 1e3 * (__touchInfo.historyX[1] - __touchInfo.historyX[0]) / (__touchInfo.historyT[1] - __touchInfo.historyT[0]); + const yv = 1e3 * (__touchInfo.historyY[1] - __touchInfo.historyY[0]) / (__touchInfo.historyT[1] - __touchInfo.historyT[0]); + const __translateX = _translateX.value; + const __translateY = _translateY.value; + _friction.setV(xv, yv); + _friction.setS(__translateX, __translateY); + const x0 = _friction.delta().x; + const y0 = _friction.delta().y; + let x = x0 + __translateX; + let y = y0 + __translateY; + if (x < minX.value) { + x = minX.value; + y = __translateY + (minX.value - __translateX) * y0 / x0; + } else { + if (x > maxX.value) { + x = maxX.value; + y = __translateY + (maxX.value - __translateX) * y0 / x0; + } + } + if (y < minY.value) { + y = minY.value; + x = __translateX + (minY.value - __translateY) * x0 / y0; + } else { + if (y > maxY.value) { + y = maxY.value; + x = __translateX + (maxY.value - __translateY) * x0 / y0; + } + } + _friction.setEnd(x, y); + _FA = g(_friction, function() { + let t2 = _friction.s(); + let x2 = t2.x; + let y2 = t2.y; + _setTransform(x2, y2, _scale.value, "friction"); + }, function() { + _FA.cancel(); + }); + } + } + if (!props2.outOfBounds && !props2.inertia) { + FAandSFACancel(); + } + } + function setParent() { + if (!_isMounted.value) { + return; + } + FAandSFACancel(); + let scale = props2.scale ? scaleValueSync.value : 1; + _updateOffset(); + _updateWH(scale); + _updateBoundary(); + let limitXY = _getLimitXY(xSync.value + _scaleOffset.x, ySync.value + _scaleOffset.y); + let x = limitXY.x; + let y = limitXY.y; + _setTransform(x, y, scale, "", true); + _updateOldScale(scale); + } + onMounted(() => { + useTouchtrack(rootRef.value, (event) => { + switch (event.detail.state) { + case "start": + __handleTouchStart(); + break; + case "move": + __handleTouchMove(event); + break; + case "end": + __handleTouchEnd(); + } + }); + setParent(); + _friction.reconfigure(1, frictionNumber.value); + _STD.reconfigure(1, 9 * Math.pow(dampingNumber.value, 2) / 40, dampingNumber.value); + rootRef.value.style.transformOrigin = "center"; + const context = { + rootRef, + setParent, + _endScale, + _setScale + }; + addMovableViewContext(context); + onUnmounted(() => { + removeMovableViewContext(context); + }); + }); + onUnmounted(() => { + FAandSFACancel(); + }); + return { + setParent + }; +} +const OPEN_TYPES = [ + "navigate", + "redirect", + "switchTab", + "reLaunch", + "navigateBack" +]; +const ANIMATION_IN = [ + "slide-in-right", + "slide-in-left", + "slide-in-top", + "slide-in-bottom", + "fade-in", + "zoom-out", + "zoom-fade-out", + "pop-in", + "none" +]; +const ANIMATION_OUT = [ + "slide-out-right", + "slide-out-left", + "slide-out-top", + "slide-out-bottom", + "fade-out", + "zoom-in", + "zoom-fade-in", + "pop-out", + "none" +]; +const navigatorProps = { + hoverClass: { + type: String, + default: "navigator-hover" + }, + url: { + type: String, + default: "" + }, + openType: { + type: String, + default: "navigate", + validator(value) { + return Boolean(~OPEN_TYPES.indexOf(value)); + } + }, + delta: { + type: Number, + default: 1 + }, + hoverStartTime: { + type: [Number, String], + default: 50 + }, + hoverStayTime: { + type: [Number, String], + default: 600 + }, + exists: { + type: String, + default: "" + }, + hoverStopPropagation: { + type: Boolean, + default: false + }, + animationType: { + type: String, + default: "", + validator(value) { + return !value || ANIMATION_IN.concat(ANIMATION_OUT).includes(value); + } + }, + animationDuration: { + type: [String, Number], + default: 300 + } +}; +function createNavigatorOnClick(props2) { + return () => { + if (props2.openType !== "navigateBack" && !props2.url) { + console.error( + " should have url attribute when using navigateTo, redirectTo, reLaunch or switchTab" + ); + return; + } + const animationDuration = parseInt(props2.animationDuration); + switch (props2.openType) { + case "navigate": + uni.navigateTo({ + url: props2.url, + animationType: props2.animationType || "pop-in", + animationDuration + }); + break; + case "redirect": + uni.redirectTo({ + url: props2.url, + // @ts-ignore + exists: props2.exists + }); + break; + case "switchTab": + uni.switchTab({ + url: props2.url + }); + break; + case "reLaunch": + uni.reLaunch({ + url: props2.url + }); + break; + case "navigateBack": + uni.navigateBack({ + delta: props2.delta, + animationType: props2.animationType || "pop-out", + animationDuration + }); + break; + } + }; +} +const index$p = /* @__PURE__ */ defineBuiltInComponent({ + name: "Navigator", + inheritAttrs: false, + compatConfig: { + MODE: 3 + }, + props: extend({}, navigatorProps, { + renderLink: { + type: Boolean, + default: true + } + }), + setup(props2, { + slots + }) { + const vm = getCurrentInstance(); + const __scopeId = vm && vm.vnode.scopeId || ""; + const { + hovering, + binding + } = useHover(props2); + const onClick = createNavigatorOnClick(props2); + return () => { + const { + hoverClass, + url + } = props2; + const hasHoverClass = props2.hoverClass && props2.hoverClass !== "none"; + const navigatorTsx = createVNode("uni-navigator", mergeProps({ + "class": hasHoverClass && hovering.value ? hoverClass : "" + }, hasHoverClass && binding, vm ? vm.attrs : {}, { + [__scopeId]: "" + }, { + "onClick": onClick + }), [slots.default && slots.default()], 16, ["onClick"]); + return props2.renderLink ? createVNode("a", { + "class": "navigator-wrap", + "href": url, + "onClick": onEventPrevent, + "onMousedown": onEventPrevent + }, [navigatorTsx], 40, ["href", "onClick", "onMousedown"]) : navigatorTsx; + }; + } +}); +const pickerViewProps = { + value: { + type: Array, + default() { + return []; + }, + validator: function(val) { + return isArray(val) && val.filter((val2) => typeof val2 === "number").length === val.length; + } + }, + indicatorStyle: { + type: String, + default: "" + }, + indicatorClass: { + type: String, + default: "" + }, + maskStyle: { + type: String, + default: "" + }, + maskClass: { + type: String, + default: "" + } +}; +function useState$4(props2) { + const value = reactive([...props2.value]); + const state2 = reactive({ + value, + height: 34 + }); + watch(() => props2.value, (val, oldVal) => { + { + state2.value.length = val.length; + val.forEach((val2, index2) => { + if (val2 !== state2.value[index2]) { + state2.value.splice(index2, 1, val2); + } + }); + } + }); + return state2; +} +const PickerView = /* @__PURE__ */ defineBuiltInComponent({ + name: "PickerView", + props: pickerViewProps, + emits: ["change", "pickstart", "pickend", "update:value"], + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = ref(null); + const wrapperRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const state2 = useState$4(props2); + const resizeSensorRef = ref(null); + const onMountedCallback = () => { + const resizeSensor = resizeSensorRef.value; + resizeSensor && (state2.height = resizeSensor.$el.offsetHeight); + }; + { + onMounted(onMountedCallback); + } + let ColumnsPreRef = ref([]); + let columnsRef = ref([]); + function getItemIndex(vnode) { + let columnVNodes = columnsRef.value; + { + columnVNodes = columnVNodes.filter((vnode2) => vnode2.type !== Comment); + } + let index2 = columnVNodes.indexOf(vnode); + return index2 !== -1 ? index2 : ColumnsPreRef.value.indexOf(vnode); + } + const getPickerViewColumn = function(columnInstance) { + const ref2 = computed({ + get() { + const index2 = getItemIndex(columnInstance.vnode); + return state2.value[index2] || 0; + }, + set(current) { + const index2 = getItemIndex(columnInstance.vnode); + if (index2 < 0) { + return; + } + const oldCurrent = state2.value[index2]; + if (oldCurrent !== current) { + state2.value[index2] = current; + const value = state2.value.map((val) => val); + emit2("update:value", value); + trigger("change", {}, { + value + }); + } + } + }); + return ref2; + }; + provide("getPickerViewColumn", getPickerViewColumn); + provide("pickerViewProps", props2); + provide("pickerViewState", state2); + return () => { + const defaultSlots = slots.default && slots.default(); + { + const vnode = flatVNode(defaultSlots); + ColumnsPreRef.value = vnode; + nextTick(() => { + columnsRef.value = vnode; + }); + } + return createVNode("uni-picker-view", { + "ref": rootRef + }, [createVNode(ResizeSensor, { + "ref": resizeSensorRef, + "onResize": ({ + height + }) => state2.height = height + }, null, 8, ["onResize"]), createVNode("div", { + "ref": wrapperRef, + "class": "uni-picker-view-wrapper" + }, [defaultSlots], 512)], 512); + }; + } +}); +class Friction { + constructor(drag) { + this._drag = drag; + this._dragLog = Math.log(drag); + this._x = 0; + this._v = 0; + this._startTime = 0; + } + set(x, v2) { + this._x = x; + this._v = v2; + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + } + setVelocityByEnd(e2) { + this._v = (e2 - this._x) * this._dragLog / (Math.pow(this._drag, 100) - 1); + } + x(e2) { + if (e2 === void 0) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + const t2 = e2 === this._dt && this._powDragDt ? this._powDragDt : this._powDragDt = Math.pow(this._drag, e2); + this._dt = e2; + return this._x + this._v * t2 / this._dragLog - this._v / this._dragLog; + } + dx(e2) { + if (e2 === void 0) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + const t2 = e2 === this._dt && this._powDragDt ? this._powDragDt : this._powDragDt = Math.pow(this._drag, e2); + this._dt = e2; + return this._v * t2; + } + done() { + return Math.abs(this.dx()) < 3; + } + reconfigure(e2) { + const t2 = this.x(); + const n = this.dx(); + this._drag = e2; + this._dragLog = Math.log(e2); + this.set(t2, n); + } + configuration() { + const e2 = this; + return [ + { + label: "Friction", + read: function() { + return e2._drag; + }, + write: function(t2) { + e2.reconfigure(t2); + }, + min: 1e-3, + max: 0.1, + step: 1e-3 + } + ]; + } +} +function o(e2, t2, n) { + return e2 > t2 - n && e2 < t2 + n; +} +function a(e2, t2) { + return o(e2, 0, t2); +} +class Spring { + constructor(m, k, c) { + this._m = m; + this._k = k; + this._c = c; + this._solution = null; + this._endPosition = 0; + this._startTime = 0; + } + _solve(e2, t2) { + const n = this._c; + const i = this._m; + const r = this._k; + const o2 = n * n - 4 * i * r; + if (o2 === 0) { + const a3 = -n / (2 * i); + const s2 = e2; + const l2 = t2 / (a3 * e2); + return { + x: function(e22) { + return (s2 + l2 * e22) * Math.pow(Math.E, a3 * e22); + }, + dx: function(e22) { + const t22 = Math.pow(Math.E, a3 * e22); + return a3 * (s2 + l2 * e22) * t22 + l2 * t22; + } + }; + } + if (o2 > 0) { + const c = (-n - Math.sqrt(o2)) / (2 * i); + const u = (-n + Math.sqrt(o2)) / (2 * i); + const l2 = (t2 - c * e2) / (u - c); + const s2 = e2 - l2; + return { + x: function(e22) { + let t22; + let n2; + if (e22 === this._t) { + t22 = this._powER1T; + n2 = this._powER2T; + } + this._t = e22; + if (!t22) { + t22 = this._powER1T = Math.pow(Math.E, c * e22); + } + if (!n2) { + n2 = this._powER2T = Math.pow(Math.E, u * e22); + } + return s2 * t22 + l2 * n2; + }, + dx: function(e22) { + let t22; + let n2; + if (e22 === this._t) { + t22 = this._powER1T; + n2 = this._powER2T; + } + this._t = e22; + if (!t22) { + t22 = this._powER1T = Math.pow(Math.E, c * e22); + } + if (!n2) { + n2 = this._powER2T = Math.pow(Math.E, u * e22); + } + return s2 * c * t22 + l2 * u * n2; + } + }; + } + const d = Math.sqrt(4 * i * r - n * n) / (2 * i); + const a2 = -n / 2 * i; + const s = e2; + const l = (t2 - a2 * e2) / d; + return { + x: function(e22) { + return Math.pow(Math.E, a2 * e22) * (s * Math.cos(d * e22) + l * Math.sin(d * e22)); + }, + dx: function(e22) { + const t22 = Math.pow(Math.E, a2 * e22); + const n2 = Math.cos(d * e22); + const i2 = Math.sin(d * e22); + return t22 * (l * d * n2 - s * d * i2) + a2 * t22 * (l * i2 + s * n2); + } + }; + } + x(e2) { + if (e2 === void 0) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + return this._solution ? this._endPosition + this._solution.x(e2) : 0; + } + dx(e2) { + if (e2 === void 0) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + return this._solution ? this._solution.dx(e2) : 0; + } + setEnd(e2, t2, n) { + if (!n) { + n = (/* @__PURE__ */ new Date()).getTime(); + } + if (e2 !== this._endPosition || !a(t2, 0.4)) { + t2 = t2 || 0; + let i = this._endPosition; + if (this._solution) { + if (a(t2, 0.4)) { + t2 = this._solution.dx((n - this._startTime) / 1e3); + } + i = this._solution.x((n - this._startTime) / 1e3); + if (a(t2, 0.4)) { + t2 = 0; + } + if (a(i, 0.4)) { + i = 0; + } + i += this._endPosition; + } + if (!(this._solution && a(i - e2, 0.4) && a(t2, 0.4))) { + this._endPosition = e2; + this._solution = this._solve(i - this._endPosition, t2); + this._startTime = n; + } + } + } + snap(e2) { + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + this._endPosition = e2; + this._solution = { + x: function() { + return 0; + }, + dx: function() { + return 0; + } + }; + } + done(e2) { + if (!e2) { + e2 = (/* @__PURE__ */ new Date()).getTime(); + } + return o(this.x(), this._endPosition, 0.4) && a(this.dx(), 0.4); + } + reconfigure(e2, t2, n) { + this._m = e2; + this._k = t2; + this._c = n; + if (!this.done()) { + this._solution = this._solve(this.x() - this._endPosition, this.dx()); + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + } + } + springConstant() { + return this._k; + } + damping() { + return this._c; + } + configuration() { + function e2(e22, t22) { + e22.reconfigure(1, t22, e22.damping()); + } + function t2(e22, t22) { + e22.reconfigure(1, e22.springConstant(), t22); + } + return [ + { + label: "Spring Constant", + read: this.springConstant.bind(this), + write: e2.bind(this, this), + min: 100, + max: 1e3 + }, + { + label: "Damping", + read: this.damping.bind(this), + write: t2.bind(this, this), + min: 1, + max: 500 + } + ]; + } +} +class Scroll { + constructor(extent, friction, spring) { + this._extent = extent; + this._friction = friction || new Friction(0.01); + this._spring = spring || new Spring(1, 90, 20); + this._startTime = 0; + this._springing = false; + this._springOffset = 0; + } + snap(e2, t2) { + this._springOffset = 0; + this._springing = true; + this._spring.snap(e2); + this._spring.setEnd(t2); + } + set(e2, t2) { + this._friction.set(e2, t2); + if (e2 > 0 && t2 >= 0) { + this._springOffset = 0; + this._springing = true; + this._spring.snap(e2); + this._spring.setEnd(0); + } else { + if (e2 < -this._extent && t2 <= 0) { + this._springOffset = 0; + this._springing = true; + this._spring.snap(e2); + this._spring.setEnd(-this._extent); + } else { + this._springing = false; + } + } + this._startTime = (/* @__PURE__ */ new Date()).getTime(); + } + x(e2) { + if (!this._startTime) { + return 0; + } + if (!e2) { + e2 = ((/* @__PURE__ */ new Date()).getTime() - this._startTime) / 1e3; + } + if (this._springing) { + return this._spring.x() + this._springOffset; + } + let t2 = this._friction.x(e2); + let n = this.dx(e2); + if (t2 > 0 && n >= 0 || t2 < -this._extent && n <= 0) { + this._springing = true; + this._spring.setEnd(0, n); + if (t2 < -this._extent) { + this._springOffset = -this._extent; + } else { + this._springOffset = 0; + } + t2 = this._spring.x() + this._springOffset; + } + return t2; + } + dx(e2) { + let t2; + if (this._lastTime === e2) { + t2 = this._lastDx; + } else { + t2 = this._springing ? this._spring.dx(e2) : this._friction.dx(e2); + } + this._lastTime = e2; + this._lastDx = t2; + return t2; + } + done() { + return this._springing ? this._spring.done() : this._friction.done(); + } + setVelocityByEnd(e2) { + this._friction.setVelocityByEnd(e2); + } + configuration() { + const e2 = this._friction.configuration(); + e2.push.apply(e2, this._spring.configuration()); + return e2; + } +} +function createAnimation(scroll, onScroll, onEnd) { + const state2 = { + id: 0, + cancelled: false + }; + function startAnimation2(state22, scroll2, onScroll2, onEnd2) { + if (!state22 || !state22.cancelled) { + onScroll2(scroll2); + const isDone = scroll2.done(); + if (!isDone) { + if (!state22.cancelled) { + state22.id = requestAnimationFrame( + startAnimation2.bind(null, state22, scroll2, onScroll2, onEnd2) + ); + } + } + if (isDone && onEnd2) { + onEnd2(scroll2); + } + } + } + function cancel(state22) { + if (state22 && state22.id) { + cancelAnimationFrame(state22.id); + } + if (state22) { + state22.cancelled = true; + } + } + startAnimation2(state2, scroll, onScroll, onEnd); + return { + cancel: cancel.bind(null, state2), + model: scroll + }; +} +class Scroller { + constructor(element, options) { + options = options || {}; + this._element = element; + this._options = options; + this._enableSnap = options.enableSnap || false; + this._itemSize = options.itemSize || 0; + this._enableX = options.enableX || false; + this._enableY = options.enableY || false; + this._shouldDispatchScrollEvent = !!options.onScroll; + if (this._enableX) { + this._extent = (options.scrollWidth || this._element.offsetWidth) - this._element.parentElement.offsetWidth; + this._scrollWidth = options.scrollWidth; + } else { + this._extent = (options.scrollHeight || this._element.offsetHeight) - this._element.parentElement.offsetHeight; + this._scrollHeight = options.scrollHeight; + } + this._position = 0; + this._scroll = new Scroll(this._extent, options.friction, options.spring); + this._onTransitionEnd = this.onTransitionEnd.bind(this); + this.updatePosition(); + } + onTouchStart() { + this._startPosition = this._position; + this._lastChangePos = this._startPosition; + if (this._startPosition > 0) { + this._startPosition /= 0.5; + } else { + if (this._startPosition < -this._extent) { + this._startPosition = (this._startPosition + this._extent) / 0.5 - this._extent; + } + } + if (this._animation) { + this._animation.cancel(); + this._scrolling = false; + } + this.updatePosition(); + } + onTouchMove(x, y) { + let startPosition = this._startPosition; + if (this._enableX) { + startPosition += x; + } else if (this._enableY) { + startPosition += y; + } + if (startPosition > 0) { + startPosition *= 0.5; + } else if (startPosition < -this._extent) { + startPosition = 0.5 * (startPosition + this._extent) - this._extent; + } + this._position = startPosition; + this.updatePosition(); + this.dispatchScroll(); + } + onTouchEnd(x, y, o2) { + if (this._enableSnap && this._position > -this._extent && this._position < 0) { + if (this._enableY && (Math.abs(y) < this._itemSize && Math.abs(o2.y) < 300 || Math.abs(o2.y) < 150)) { + this.snap(); + return; + } + if (this._enableX && (Math.abs(x) < this._itemSize && Math.abs(o2.x) < 300 || Math.abs(o2.x) < 150)) { + this.snap(); + return; + } + } + if (this._enableX) { + this._scroll.set(this._position, o2.x); + } else if (this._enableY) { + this._scroll.set(this._position, o2.y); + } + let c; + if (this._enableSnap) { + const s = this._scroll._friction.x(100); + const l = s % this._itemSize; + c = Math.abs(l) > this._itemSize / 2 ? s - (this._itemSize - Math.abs(l)) : s - l; + if (c <= 0 && c >= -this._extent) { + this._scroll.setVelocityByEnd(c); + } + } + this._lastTime = Date.now(); + this._lastDelay = 0; + this._scrolling = true; + this._lastChangePos = this._position; + this._lastIdx = Math.floor(Math.abs(this._position / this._itemSize)); + this._animation = createAnimation( + this._scroll, + () => { + const e2 = Date.now(); + const i = (e2 - this._scroll._startTime) / 1e3; + const r = this._scroll.x(i); + this._position = r; + this.updatePosition(); + const o22 = this._scroll.dx(i); + if (this._shouldDispatchScrollEvent && e2 - this._lastTime > this._lastDelay) { + this.dispatchScroll(); + this._lastDelay = Math.abs(2e3 / o22); + this._lastTime = e2; + } + }, + () => { + if (this._enableSnap) { + if (c <= 0 && c >= -this._extent) { + this._position = c; + this.updatePosition(); + } + if (isFunction(this._options.onSnap)) { + this._options.onSnap( + Math.floor(Math.abs(this._position) / this._itemSize) + ); + } + } + if (this._shouldDispatchScrollEvent) { + this.dispatchScroll(); + } + this._scrolling = false; + } + ); + } + onTransitionEnd() { + this._element.style.webkitTransition = ""; + this._element.style.transition = ""; + this._element.removeEventListener("transitionend", this._onTransitionEnd); + if (this._snapping) { + this._snapping = false; + } + this.dispatchScroll(); + } + snap() { + const itemSize = this._itemSize; + const position = this._position % itemSize; + const i = Math.abs(position) > this._itemSize / 2 ? this._position - (itemSize - Math.abs(position)) : this._position - position; + if (this._position !== i) { + this._snapping = true; + this.scrollTo(-i); + if (isFunction(this._options.onSnap)) { + this._options.onSnap( + Math.floor(Math.abs(this._position) / this._itemSize) + ); + } + } + } + scrollTo(position, time) { + if (this._animation) { + this._animation.cancel(); + this._scrolling = false; + } + if (typeof position === "number") { + this._position = -position; + } + if (this._position < -this._extent) { + this._position = -this._extent; + } else { + if (this._position > 0) { + this._position = 0; + } + } + const transition = "transform " + (time || 0.2) + "s ease-out"; + this._element.style.webkitTransition = "-webkit-" + transition; + this._element.style.transition = transition; + this.updatePosition(); + this._element.addEventListener("transitionend", this._onTransitionEnd); + } + dispatchScroll() { + if (isFunction(this._options.onScroll) && Math.round(Number(this._lastPos)) !== Math.round(this._position)) { + this._lastPos = this._position; + const event = { + target: { + scrollLeft: this._enableX ? -this._position : 0, + scrollTop: this._enableY ? -this._position : 0, + scrollHeight: this._scrollHeight || this._element.offsetHeight, + scrollWidth: this._scrollWidth || this._element.offsetWidth, + offsetHeight: this._element.parentElement.offsetHeight, + offsetWidth: this._element.parentElement.offsetWidth + } + }; + this._options.onScroll(event); + } + } + update(height, scrollHeight, itemSize) { + let extent = 0; + const position = this._position; + if (this._enableX) { + extent = this._element.childNodes.length ? (scrollHeight || this._element.offsetWidth) - this._element.parentElement.offsetWidth : 0; + this._scrollWidth = scrollHeight; + } else { + extent = this._element.childNodes.length ? (scrollHeight || this._element.offsetHeight) - this._element.parentElement.offsetHeight : 0; + this._scrollHeight = scrollHeight; + } + if (typeof height === "number") { + this._position = -height; + } + if (this._position < -extent) { + this._position = -extent; + } else { + if (this._position > 0) { + this._position = 0; + } + } + this._itemSize = itemSize || this._itemSize; + this.updatePosition(); + if (position !== this._position) { + this.dispatchScroll(); + if (isFunction(this._options.onSnap)) { + this._options.onSnap( + Math.floor(Math.abs(this._position) / this._itemSize) + ); + } + } + this._extent = extent; + this._scroll._extent = extent; + } + updatePosition() { + let transform = ""; + if (this._enableX) { + transform = "translateX(" + this._position + "px) translateZ(0)"; + } else { + if (this._enableY) { + transform = "translateY(" + this._position + "px) translateZ(0)"; + } + } + this._element.style.webkitTransform = transform; + this._element.style.transform = transform; + } + isScrolling() { + return this._scrolling || this._snapping; + } +} +function useScroller(element, options) { + const touchInfo = { + trackingID: -1, + maxDy: 0, + maxDx: 0 + }; + const scroller = new Scroller(element, options); + function findDelta(event) { + const touchtrackEvent = event; + const mouseEvent = event; + return touchtrackEvent.detail.state === "move" || touchtrackEvent.detail.state === "end" ? { + x: touchtrackEvent.detail.dx, + y: touchtrackEvent.detail.dy + } : { + x: mouseEvent.screenX - touchInfo.x, + y: mouseEvent.screenY - touchInfo.y + }; + } + function handleTouchStart(event) { + const touchtrackEvent = event; + const mouseEvent = event; + if (touchtrackEvent.detail.state === "start") { + touchInfo.trackingID = "touch"; + touchInfo.x = touchtrackEvent.detail.x; + touchInfo.y = touchtrackEvent.detail.y; + } else { + touchInfo.trackingID = "mouse"; + touchInfo.x = mouseEvent.screenX; + touchInfo.y = mouseEvent.screenY; + } + touchInfo.maxDx = 0; + touchInfo.maxDy = 0; + touchInfo.historyX = [0]; + touchInfo.historyY = [0]; + touchInfo.historyTime = [ + touchtrackEvent.detail.timeStamp || mouseEvent.timeStamp + ]; + touchInfo.listener = scroller; + if (scroller.onTouchStart) { + scroller.onTouchStart(); + } + if (typeof event.cancelable !== "boolean" || event.cancelable) + event.preventDefault(); + } + function handleTouchMove(event) { + const touchtrackEvent = event; + const mouseEvent = event; + if (touchInfo.trackingID !== -1) { + if (typeof event.cancelable !== "boolean" || event.cancelable) + event.preventDefault(); + const delta = findDelta(event); + if (delta) { + for (touchInfo.maxDy = Math.max(touchInfo.maxDy, Math.abs(delta.y)), touchInfo.maxDx = Math.max(touchInfo.maxDx, Math.abs(delta.x)), touchInfo.historyX.push(delta.x), touchInfo.historyY.push(delta.y), touchInfo.historyTime.push( + touchtrackEvent.detail.timeStamp || mouseEvent.timeStamp + ); touchInfo.historyTime.length > 10; ) { + touchInfo.historyTime.shift(); + touchInfo.historyX.shift(); + touchInfo.historyY.shift(); + } + if (touchInfo.listener && touchInfo.listener.onTouchMove) { + touchInfo.listener.onTouchMove(delta.x, delta.y); + } + } + } + } + function handleTouchEnd(event) { + if (touchInfo.trackingID !== -1) { + event.preventDefault(); + const delta = findDelta(event); + if (delta) { + const listener2 = touchInfo.listener; + touchInfo.trackingID = -1; + touchInfo.listener = null; + const length = touchInfo.historyTime.length; + const o2 = { + x: 0, + y: 0 + }; + if (length > 2) { + for (let i = touchInfo.historyTime.length - 1, time1 = touchInfo.historyTime[i], x = touchInfo.historyX[i], y = touchInfo.historyY[i]; i > 0; ) { + i--; + const time0 = touchInfo.historyTime[i]; + const time = time1 - time0; + if (time > 30 && time < 50) { + o2.x = (x - touchInfo.historyX[i]) / (time / 1e3); + o2.y = (y - touchInfo.historyY[i]) / (time / 1e3); + break; + } + } + } + touchInfo.historyTime = []; + touchInfo.historyX = []; + touchInfo.historyY = []; + if (listener2 && listener2.onTouchEnd) { + listener2.onTouchEnd(delta.x, delta.y, o2); + } + } + } + } + return { + scroller, + handleTouchStart, + handleTouchMove, + handleTouchEnd + }; +} +let scopedIndex = 0; +function useScopedClass(indicatorHeightRef) { + const className = `uni-picker-view-content-${scopedIndex++}`; + function updateStyle2() { + const style = document.createElement("style"); + style.innerText = `.uni-picker-view-content.${className}>*{height: ${indicatorHeightRef.value}px;overflow: hidden;}`; + document.head.appendChild(style); + } + watch(() => indicatorHeightRef.value, updateStyle2); + return className; +} +function useCustomClick(dom) { + const MAX_MOVE = 20; + let x = 0; + let y = 0; + dom.addEventListener("touchstart", (event) => { + const info = event.changedTouches[0]; + x = info.clientX; + y = info.clientY; + }); + dom.addEventListener("touchend", (event) => { + const info = event.changedTouches[0]; + if (Math.abs(info.clientX - x) < MAX_MOVE && Math.abs(info.clientY - y) < MAX_MOVE) { + const options = { + bubbles: true, + cancelable: true, + target: event.target, + currentTarget: event.currentTarget + }; + const customClick = new CustomEvent("click", options); + const props2 = ["screenX", "screenY", "clientX", "clientY", "pageX", "pageY"]; + props2.forEach((key) => { + customClick[key] = info[key]; + }); + event.target.dispatchEvent(customClick); + } + }); +} +const PickerViewColumn = /* @__PURE__ */ defineBuiltInComponent({ + name: "PickerViewColumn", + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = ref(null); + const contentRef = ref(null); + const getPickerViewColumn = inject("getPickerViewColumn"); + const instance2 = getCurrentInstance(); + const currentRef = getPickerViewColumn ? getPickerViewColumn(instance2) : ref(0); + const pickerViewProps2 = inject("pickerViewProps"); + const pickerViewState = inject("pickerViewState"); + const indicatorHeight = ref(34); + const resizeSensorRef = ref(null); + const initIndicatorHeight = () => { + const resizeSensor = resizeSensorRef.value; + indicatorHeight.value = resizeSensor.$el.offsetHeight; + }; + { + onMounted(initIndicatorHeight); + } + const maskSize = computed(() => (pickerViewState.height - indicatorHeight.value) / 2); + const { + state: scopedAttrsState + } = useScopedAttrs(); + const className = useScopedClass(indicatorHeight); + let scroller; + const state2 = reactive({ + current: currentRef.value, + length: 0 + }); + let updatesScrollerRequest; + function updatesScroller() { + if (scroller && !updatesScrollerRequest) { + updatesScrollerRequest = true; + nextTick(() => { + updatesScrollerRequest = false; + let current = Math.min(state2.current, state2.length - 1); + current = Math.max(current, 0); + scroller.update(current * indicatorHeight.value, void 0, indicatorHeight.value); + }); + } + } + watch(() => currentRef.value, (current) => { + if (current !== state2.current) { + state2.current = current; + updatesScroller(); + } + }); + watch(() => state2.current, (current) => currentRef.value = current); + watch([() => indicatorHeight.value, () => state2.length, () => pickerViewState.height], updatesScroller); + let oldDeltaY = 0; + function handleWheel(event) { + const deltaY = oldDeltaY + event.deltaY; + if (Math.abs(deltaY) > 10) { + oldDeltaY = 0; + let current = Math.min(state2.current + (deltaY < 0 ? -1 : 1), state2.length - 1); + state2.current = current = Math.max(current, 0); + scroller.scrollTo(current * indicatorHeight.value); + } else { + oldDeltaY = deltaY; + } + event.preventDefault(); + } + function handleTap({ + clientY + }) { + const el = rootRef.value; + if (!scroller.isScrolling()) { + const rect = el.getBoundingClientRect(); + const r = clientY - rect.top - pickerViewState.height / 2; + const o2 = indicatorHeight.value / 2; + if (!(Math.abs(r) <= o2)) { + const a2 = Math.ceil((Math.abs(r) - o2) / indicatorHeight.value); + const s = r < 0 ? -a2 : a2; + let current = Math.min(state2.current + s, state2.length - 1); + state2.current = current = Math.max(current, 0); + scroller.scrollTo(current * indicatorHeight.value); + } + } + } + const initScroller = () => { + const el = rootRef.value; + const content = contentRef.value; + const { + scroller: scrollerOrigin, + handleTouchStart, + handleTouchMove, + handleTouchEnd + } = useScroller(content, { + enableY: true, + enableX: false, + enableSnap: true, + itemSize: indicatorHeight.value, + friction: new Friction(1e-4), + spring: new Spring(2, 90, 20), + onSnap: (index2) => { + if (!isNaN(index2) && index2 !== state2.current) { + state2.current = index2; + } + } + }); + scroller = scrollerOrigin; + useTouchtrack(el, (e2) => { + switch (e2.detail.state) { + case "start": + handleTouchStart(e2); + break; + case "move": + handleTouchMove(e2); + e2.stopPropagation(); + break; + case "end": + case "cancel": + handleTouchEnd(e2); + } + }, true); + useCustomClick(el); + updatesScroller(); + }; + { + onMounted(initScroller); + } + return () => { + const defaultSlots = slots.default && slots.default(); + { + state2.length = flatVNode(defaultSlots).length; + } + const padding = `${maskSize.value}px 0`; + return createVNode("uni-picker-view-column", { + "ref": rootRef + }, [createVNode("div", { + "onWheel": handleWheel, + "onClick": handleTap, + "class": "uni-picker-view-group" + }, [createVNode("div", mergeProps(scopedAttrsState.attrs, { + "class": ["uni-picker-view-mask", pickerViewProps2.maskClass], + "style": `background-size: 100% ${maskSize.value}px;${pickerViewProps2.maskStyle}` + }), null, 16), createVNode("div", mergeProps(scopedAttrsState.attrs, { + "class": ["uni-picker-view-indicator", pickerViewProps2.indicatorClass], + "style": pickerViewProps2.indicatorStyle + }), [createVNode(ResizeSensor, { + "ref": resizeSensorRef, + "onResize": ({ + height + }) => indicatorHeight.value = height + }, null, 8, ["onResize"])], 16), createVNode("div", { + "ref": contentRef, + "class": ["uni-picker-view-content", className], + "style": { + padding + } + }, [defaultSlots], 6)], 40, ["onWheel", "onClick"])], 512); + }; + } +}); +const FONT_SIZE = 16; +const PROGRESS_VALUES = { + activeColor: PRIMARY_COLOR, + backgroundColor: "#EBEBEB", + activeMode: "backwards" +}; +const progressProps = { + percent: { + type: [Number, String], + default: 0, + validator(value) { + return !isNaN(parseFloat(value)); + } + }, + fontSize: { + type: [String, Number], + default: FONT_SIZE + }, + showInfo: { + type: [Boolean, String], + default: false + }, + strokeWidth: { + type: [Number, String], + default: 6, + validator(value) { + return !isNaN(parseFloat(value)); + } + }, + color: { + type: String, + default: PROGRESS_VALUES.activeColor + }, + activeColor: { + type: String, + default: PROGRESS_VALUES.activeColor + }, + backgroundColor: { + type: String, + default: PROGRESS_VALUES.backgroundColor + }, + active: { + type: [Boolean, String], + default: false + }, + activeMode: { + type: String, + default: PROGRESS_VALUES.activeMode + }, + duration: { + type: [Number, String], + default: 30, + validator(value) { + return !isNaN(parseFloat(value)); + } + }, + borderRadius: { + type: [Number, String], + default: 0 + } +}; +const index$o = /* @__PURE__ */ defineBuiltInComponent({ + name: "Progress", + props: progressProps, + setup(props2) { + const state2 = useProgressState(props2); + _activeAnimation(state2, props2); + watch(() => state2.realPercent, (newValue, oldValue) => { + state2.strokeTimer && clearInterval(state2.strokeTimer); + state2.lastPercent = oldValue || 0; + _activeAnimation(state2, props2); + }); + return () => { + const { + showInfo + } = props2; + const { + outerBarStyle, + innerBarStyle, + currentPercent + } = state2; + return createVNode("uni-progress", { + "class": "uni-progress" + }, [createVNode("div", { + "style": outerBarStyle, + "class": "uni-progress-bar" + }, [createVNode("div", { + "style": innerBarStyle, + "class": "uni-progress-inner-bar" + }, null, 4)], 4), showInfo ? ( + // {currentPercent}% 的写法会影响 SSR Hydration (tsx插件的问题) + createVNode("p", { + "class": "uni-progress-info" + }, [currentPercent + "%"]) + ) : ""]); + }; + } +}); +function useProgressState(props2) { + const currentPercent = ref(0); + const outerBarStyle = computed(() => `background-color: ${props2.backgroundColor}; height: ${props2.strokeWidth}px;`); + const innerBarStyle = computed(() => { + const backgroundColor = props2.color !== PROGRESS_VALUES.activeColor && props2.activeColor === PROGRESS_VALUES.activeColor ? props2.color : props2.activeColor; + return `width: ${currentPercent.value}%;background-color: ${backgroundColor}`; + }); + const realPercent = computed(() => { + let realValue = parseFloat(props2.percent); + realValue < 0 && (realValue = 0); + realValue > 100 && (realValue = 100); + return realValue; + }); + const state2 = reactive({ + outerBarStyle, + innerBarStyle, + realPercent, + currentPercent, + strokeTimer: 0, + lastPercent: 0 + }); + return state2; +} +function _activeAnimation(state2, props2) { + if (props2.active) { + state2.currentPercent = props2.activeMode === PROGRESS_VALUES.activeMode ? 0 : state2.lastPercent; + state2.strokeTimer = setInterval(() => { + if (state2.currentPercent + 1 > state2.realPercent) { + state2.currentPercent = state2.realPercent; + state2.strokeTimer && clearInterval(state2.strokeTimer); + } else { + state2.currentPercent += 1; + } + }, parseFloat(props2.duration)); + } else { + state2.currentPercent = state2.realPercent; + } +} +const uniRadioGroupKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniCheckGroup" : "ucg"); +const props$p = { + name: { + type: String, + default: "" + } +}; +const index$n = /* @__PURE__ */ defineBuiltInComponent({ + name: "RadioGroup", + props: props$p, + // emits: ['change'], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + useProvideRadioGroup(props2, trigger); + return () => { + return createVNode("uni-radio-group", { + "ref": rootRef + }, [slots.default && slots.default()], 512); + }; + } +}); +function useProvideRadioGroup(props2, trigger) { + const fields2 = []; + onMounted(() => { + _resetRadioGroupValue(fields2.length - 1); + }); + const getFieldsValue = () => { + var _a; + return (_a = fields2.find((field) => field.value.radioChecked)) == null ? void 0 : _a.value.value; + }; + provide(uniRadioGroupKey, { + addField(field) { + fields2.push(field); + }, + removeField(field) { + fields2.splice(fields2.indexOf(field), 1); + }, + radioChange($event, field) { + const index2 = fields2.indexOf(field); + _resetRadioGroupValue(index2, true); + trigger("change", $event, { + value: getFieldsValue() + }); + } + }); + const uniForm = inject(uniFormKey, false); + const formField = { + submit: () => { + let data = ["", null]; + if (props2.name !== "") { + data[0] = props2.name; + data[1] = getFieldsValue(); + } + return data; + } + }; + if (uniForm) { + uniForm.addField(formField); + onBeforeUnmount(() => { + uniForm.removeField(formField); + }); + } + function setFieldChecked(field, radioChecked) { + field.value = { + radioChecked, + value: field.value.value + }; + } + function _resetRadioGroupValue(key, change) { + fields2.forEach((value, index2) => { + if (index2 === key) { + return; + } + if (change) { + setFieldChecked(fields2[index2], false); + } else { + fields2.forEach((v2, i) => { + if (index2 >= i) { + return; + } + if (fields2[i].value.radioChecked) { + setFieldChecked(fields2[index2], false); + } + }); + } + }); + } + return fields2; +} +const props$o = { + checked: { + type: [Boolean, String], + default: false + }, + id: { + type: String, + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "#007aff" + }, + value: { + type: String, + default: "" + } +}; +const index$m = /* @__PURE__ */ defineBuiltInComponent({ + name: "Radio", + props: props$o, + setup(props2, { + slots + }) { + const radioChecked = ref(props2.checked); + const radioValue = ref(props2.value); + const checkedStyle = computed(() => { + if (props2.disabled) + return "background-color: #E1E1E1;border-color: ##D1D1D1;"; + return `background-color: ${props2.color};border-color: ${props2.color};`; + }); + watch([() => props2.checked, () => props2.value], ([newChecked, newModelValue]) => { + radioChecked.value = newChecked; + radioValue.value = newModelValue; + }); + const reset = () => { + radioChecked.value = false; + }; + const { + uniCheckGroup, + uniLabel, + field + } = useRadioInject(radioChecked, radioValue, reset); + const _onClick = ($event) => { + if (props2.disabled || radioChecked.value) { + return; + } + radioChecked.value = true; + uniCheckGroup && uniCheckGroup.radioChange($event, field); + $event.stopPropagation(); + }; + if (!!uniLabel) { + uniLabel.addHandler(_onClick); + onBeforeUnmount(() => { + uniLabel.removeHandler(_onClick); + }); + } + useListeners$1(props2, { + "label-click": _onClick + }); + return () => { + const booleanAttrs = useBooleanAttr(props2, "disabled"); + return createVNode("uni-radio", mergeProps(booleanAttrs, { + "onClick": _onClick + }), [createVNode("div", { + "class": "uni-radio-wrapper" + }, [createVNode("div", { + "class": ["uni-radio-input", { + "uni-radio-input-disabled": props2.disabled + }], + "style": radioChecked.value ? checkedStyle.value : "" + }, [radioChecked.value ? createSvgIconVNode(ICON_PATH_SUCCESS_NO_CIRCLE, props2.disabled ? "#ADADAD" : "#fff", 18) : ""], 6), slots.default && slots.default()])], 16, ["onClick"]); + }; + } +}); +function useRadioInject(radioChecked, radioValue, reset) { + const field = computed({ + get: () => ({ + radioChecked: Boolean(radioChecked.value), + value: radioValue.value + }), + set: ({ + radioChecked: checked + }) => { + radioChecked.value = checked; + } + }); + const formField = { + reset + }; + const uniCheckGroup = inject(uniRadioGroupKey, false); + if (!!uniCheckGroup) { + uniCheckGroup.addField(field); + } + const uniForm = inject(uniFormKey, false); + if (!!uniForm) { + uniForm.addField(formField); + } + const uniLabel = inject(uniLabelKey, false); + onBeforeUnmount(() => { + uniCheckGroup && uniCheckGroup.removeField(field); + uniForm && uniForm.removeField(formField); + }); + return { + uniCheckGroup, + uniForm, + uniLabel, + field + }; +} +const TAGS = { + a: "", + abbr: "", + address: "", + article: "", + aside: "", + b: "", + bdi: "", + bdo: ["dir"], + big: "", + blockquote: "", + br: "", + caption: "", + center: "", + cite: "", + code: "", + col: ["span", "width"], + colgroup: ["span", "width"], + dd: "", + del: "", + div: "", + dl: "", + dt: "", + em: "", + fieldset: "", + font: "", + footer: "", + h1: "", + h2: "", + h3: "", + h4: "", + h5: "", + h6: "", + header: "", + hr: "", + i: "", + img: ["alt", "src", "height", "width"], + ins: "", + label: "", + legend: "", + li: "", + mark: "", + nav: "", + ol: ["start", "type"], + p: "", + pre: "", + q: "", + rt: "", + ruby: "", + s: "", + section: "", + small: "", + span: "", + strong: "", + sub: "", + sup: "", + table: ["width"], + tbody: "", + td: ["colspan", "height", "rowspan", "width"], + tfoot: "", + th: ["colspan", "height", "rowspan", "width"], + thead: "", + tr: ["colspan", "height", "rowspan", "width"], + tt: "", + u: "", + ul: "" +}; +const CHARS = { + amp: "&", + gt: ">", + lt: "<", + nbsp: " ", + quot: '"', + apos: "'", + ldquo: "“", + rdquo: "”", + yen: "¥", + radic: "√", + lceil: "⌈", + rceil: "⌉", + lfloor: "⌊", + rfloor: "⌋", + hellip: "…" +}; +function decodeEntities(htmlString) { + return htmlString.replace( + /&(([a-zA-Z]+)|(#x{0,1}[\da-zA-Z]+));/gi, + function(match, stage) { + if (hasOwn(CHARS, stage) && CHARS[stage]) { + return CHARS[stage]; + } + if (/^#[0-9]{1,4}$/.test(stage)) { + return String.fromCharCode(stage.slice(1)); + } + if (/^#x[0-9a-f]{1,4}$/i.test(stage)) { + return String.fromCharCode(0 + stage.slice(1)); + } + return match; + } + ); +} +function processClickEvent(node, triggerItemClick) { + if (["a", "img"].includes(node.name) && triggerItemClick) { + return { + onClick: (e2) => { + triggerItemClick(e2, { node }); + e2.stopPropagation(); + e2.preventDefault(); + e2.returnValue = false; + } + }; + } +} +function normalizeAttrs(tagName, attrs2) { + if (!isPlainObject(attrs2)) + return; + for (const key in attrs2) { + if (hasOwn(attrs2, key)) { + const value = attrs2[key]; + if (tagName === "img" && key === "src") + attrs2[key] = getRealPath(value); + } + } +} +const nodeList2VNode = (scopeId, triggerItemClick, nodeList) => { + if (!nodeList || isArray(nodeList) && !nodeList.length) + return []; + return nodeList.map((node) => { + if (!isPlainObject(node)) { + return; + } + if (!hasOwn(node, "type") || node.type === "node") { + let nodeProps = { [scopeId]: "" }; + const tagName = node.name.toLowerCase(); + if (!hasOwn(TAGS, tagName)) { + return; + } + normalizeAttrs(tagName, node.attrs); + nodeProps = extend( + nodeProps, + processClickEvent(node, triggerItemClick), + node.attrs + ); + return h( + node.name, + nodeProps, + nodeList2VNode(scopeId, triggerItemClick, node.children) + ); + } + if (node.type === "text" && isString(node.text) && node.text !== "") + return createTextVNode(decodeEntities(node.text || "")); + }); +}; +function removeDOCTYPE(html) { + return html.replace(/<\?xml.*\?>\n/, "").replace(/\n/, "").replace(/\n/, ""); +} +function parseAttrs(attrs2) { + return attrs2.reduce(function(pre, attr2) { + let value = attr2.value; + const name = attr2.name; + if (value.match(/ /) && ["style", "src"].indexOf(name) === -1) { + value = value.split(" "); + } + if (pre[name]) { + if (Array.isArray(pre[name])) { + pre[name].push(value); + } else { + pre[name] = [pre[name], value]; + } + } else { + pre[name] = value; + } + return pre; + }, {}); +} +function parseHtml(html) { + html = removeDOCTYPE(html); + const stacks = []; + const results = { + node: "root", + children: [] + }; + HTMLParser(html, { + start: function(tag, attrs2, unary) { + const node = { + name: tag + }; + if (attrs2.length !== 0) { + node.attrs = parseAttrs(attrs2); + } + if (unary) { + const parent = stacks[0] || results; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } else { + stacks.unshift(node); + } + }, + end: function(tag) { + const node = stacks.shift(); + if (node.name !== tag) + console.error("invalid state: mismatch end tag"); + if (stacks.length === 0) { + results.children.push(node); + } else { + const parent = stacks[0]; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } + }, + chars: function(text2) { + const node = { + type: "text", + text: text2 + }; + if (stacks.length === 0) { + results.children.push(node); + } else { + const parent = stacks[0]; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } + }, + comment: function(text2) { + const node = { + node: "comment", + text: text2 + }; + const parent = stacks[0]; + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } + }); + return results.children; +} +const props$n = { + nodes: { + type: [Array, String], + default: function() { + return []; + } + } +}; +const index$l = /* @__PURE__ */ defineBuiltInComponent({ + name: "RichText", + compatConfig: { + MODE: 3 + }, + props: props$n, + emits: ["click", "touchstart", "touchmove", "touchcancel", "touchend", "longpress", "itemclick"], + setup(props2, { + emit: emit2 + }) { + const vm = getCurrentInstance(); + const scopeId = vm && vm.vnode.scopeId || ""; + const rootRef = ref(null); + const _vnode = ref([]); + const trigger = useCustomEvent(rootRef, emit2); + function triggerItemClick(e2, detail = {}) { + trigger("itemclick", e2, detail); + } + function renderVNode() { + let nodeList = props2.nodes; + if (isString(nodeList)) { + nodeList = parseHtml(props2.nodes); + } + _vnode.value = nodeList2VNode(scopeId, triggerItemClick, nodeList); + } + watch(() => props2.nodes, renderVNode, { + immediate: true + }); + return () => h("uni-rich-text", { + ref: rootRef + }, h("div", {}, _vnode.value)); + } +}); +const passiveOptions = /* @__PURE__ */ passive(true); +const props$m = { + scrollX: { + type: [Boolean, String], + default: false + }, + scrollY: { + type: [Boolean, String], + default: false + }, + upperThreshold: { + type: [Number, String], + default: 50 + }, + lowerThreshold: { + type: [Number, String], + default: 50 + }, + scrollTop: { + type: [Number, String], + default: 0 + }, + scrollLeft: { + type: [Number, String], + default: 0 + }, + scrollIntoView: { + type: String, + default: "" + }, + scrollWithAnimation: { + type: [Boolean, String], + default: false + }, + enableBackToTop: { + type: [Boolean, String], + default: false + }, + refresherEnabled: { + type: [Boolean, String], + default: false + }, + refresherThreshold: { + type: Number, + default: 45 + }, + refresherDefaultStyle: { + type: String, + default: "back" + }, + refresherBackground: { + type: String, + default: "#fff" + }, + refresherTriggered: { + type: [Boolean, String], + default: false + } +}; +const ScrollView = /* @__PURE__ */ defineBuiltInComponent({ + name: "ScrollView", + compatConfig: { + MODE: 3 + }, + props: props$m, + emits: ["scroll", "scrolltoupper", "scrolltolower", "refresherrefresh", "refresherrestore", "refresherpulling", "refresherabort", "update:refresherTriggered"], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = ref(null); + const main = ref(null); + const wrap = ref(null); + const content = ref(null); + const refresherinner = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const { + state: state2, + scrollTopNumber, + scrollLeftNumber + } = useScrollViewState(props2); + useScrollViewLoader(props2, state2, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2); + const mainStyle = computed(() => { + let style = ""; + props2.scrollX ? style += "overflow-x:auto;" : style += "overflow-x:hidden;"; + props2.scrollY ? style += "overflow-y:auto;" : style += "overflow-y:hidden;"; + return style; + }); + return () => { + const { + refresherEnabled, + refresherBackground, + refresherDefaultStyle + } = props2; + const { + refresherHeight, + refreshState, + refreshRotate + } = state2; + return createVNode("uni-scroll-view", { + "ref": rootRef + }, [createVNode("div", { + "ref": wrap, + "class": "uni-scroll-view" + }, [createVNode("div", { + "ref": main, + "style": mainStyle.value, + "class": "uni-scroll-view" + }, [createVNode("div", { + "ref": content, + "class": "uni-scroll-view-content" + }, [refresherEnabled ? createVNode("div", { + "ref": refresherinner, + "style": { + backgroundColor: refresherBackground, + height: refresherHeight + "px" + }, + "class": "uni-scroll-view-refresher" + }, [refresherDefaultStyle !== "none" ? createVNode("div", { + "class": "uni-scroll-view-refresh" + }, [createVNode("div", { + "class": "uni-scroll-view-refresh-inner" + }, [refreshState == "pulling" ? createVNode("svg", { + "key": "refresh__icon", + "style": { + transform: "rotate(" + refreshRotate + "deg)" + }, + "fill": "#2BD009", + "class": "uni-scroll-view-refresh__icon", + "width": "24", + "height": "24", + "viewBox": "0 0 24 24" + }, [createVNode("path", { + "d": "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" + }, null), createVNode("path", { + "d": "M0 0h24v24H0z", + "fill": "none" + }, null)], 4) : null, refreshState == "refreshing" ? createVNode("svg", { + "key": "refresh__spinner", + "class": "uni-scroll-view-refresh__spinner", + "width": "24", + "height": "24", + "viewBox": "25 25 50 50" + }, [createVNode("circle", { + "cx": "50", + "cy": "50", + "r": "20", + "fill": "none", + "style": "color: #2bd009", + "stroke-width": "3" + }, null)]) : null])]) : null, refresherDefaultStyle == "none" ? slots.refresher && slots.refresher() : null], 4) : null, slots.default && slots.default()], 512)], 4)], 512)], 512); + }; + } +}); +function useScrollViewState(props2) { + const scrollTopNumber = computed(() => { + return Number(props2.scrollTop) || 0; + }); + const scrollLeftNumber = computed(() => { + return Number(props2.scrollLeft) || 0; + }); + const state2 = reactive({ + lastScrollTop: scrollTopNumber.value, + lastScrollLeft: scrollLeftNumber.value, + lastScrollToUpperTime: 0, + lastScrollToLowerTime: 0, + refresherHeight: 0, + refreshRotate: 0, + refreshState: "" + }); + return { + state: state2, + scrollTopNumber, + scrollLeftNumber + }; +} +function useScrollViewLoader(props2, state2, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2) { + let beforeRefreshing = false; + let toUpperNumber = 0; + let triggerAbort = false; + let __transitionEnd = () => { + }; + const upperThresholdNumber = computed(() => { + let val = Number(props2.upperThreshold); + return isNaN(val) ? 50 : val; + }); + const lowerThresholdNumber = computed(() => { + let val = Number(props2.lowerThreshold); + return isNaN(val) ? 50 : val; + }); + function scrollTo2(scrollToValue, direction2) { + const container = main.value; + let transformValue = 0; + let transform = ""; + scrollToValue < 0 ? scrollToValue = 0 : direction2 === "x" && scrollToValue > container.scrollWidth - container.offsetWidth ? scrollToValue = container.scrollWidth - container.offsetWidth : direction2 === "y" && scrollToValue > container.scrollHeight - container.offsetHeight && (scrollToValue = container.scrollHeight - container.offsetHeight); + direction2 === "x" ? transformValue = container.scrollLeft - scrollToValue : direction2 === "y" && (transformValue = container.scrollTop - scrollToValue); + if (transformValue === 0) + return; + let _content = content.value; + _content.style.transition = "transform .3s ease-out"; + _content.style.webkitTransition = "-webkit-transform .3s ease-out"; + if (direction2 === "x") { + transform = "translateX(" + transformValue + "px) translateZ(0)"; + } else { + direction2 === "y" && (transform = "translateY(" + transformValue + "px) translateZ(0)"); + } + _content.removeEventListener("transitionend", __transitionEnd); + _content.removeEventListener("webkitTransitionEnd", __transitionEnd); + __transitionEnd = () => _transitionEnd(scrollToValue, direction2); + _content.addEventListener("transitionend", __transitionEnd); + _content.addEventListener("webkitTransitionEnd", __transitionEnd); + if (direction2 === "x") { + container.style.overflowX = "hidden"; + } else if (direction2 === "y") { + container.style.overflowY = "hidden"; + } + _content.style.transform = transform; + _content.style.webkitTransform = transform; + } + function _handleScroll($event) { + const target = $event.target; + trigger("scroll", $event, { + scrollLeft: target.scrollLeft, + scrollTop: target.scrollTop, + scrollHeight: target.scrollHeight, + scrollWidth: target.scrollWidth, + deltaX: state2.lastScrollLeft - target.scrollLeft, + deltaY: state2.lastScrollTop - target.scrollTop + }); + if (props2.scrollY) { + if (target.scrollTop <= upperThresholdNumber.value && state2.lastScrollTop - target.scrollTop > 0 && $event.timeStamp - state2.lastScrollToUpperTime > 200) { + trigger("scrolltoupper", $event, { + direction: "top" + }); + state2.lastScrollToUpperTime = $event.timeStamp; + } + if (target.scrollTop + target.offsetHeight + lowerThresholdNumber.value >= target.scrollHeight && state2.lastScrollTop - target.scrollTop < 0 && $event.timeStamp - state2.lastScrollToLowerTime > 200) { + trigger("scrolltolower", $event, { + direction: "bottom" + }); + state2.lastScrollToLowerTime = $event.timeStamp; + } + } + if (props2.scrollX) { + if (target.scrollLeft <= upperThresholdNumber.value && state2.lastScrollLeft - target.scrollLeft > 0 && $event.timeStamp - state2.lastScrollToUpperTime > 200) { + trigger("scrolltoupper", $event, { + direction: "left" + }); + state2.lastScrollToUpperTime = $event.timeStamp; + } + if (target.scrollLeft + target.offsetWidth + lowerThresholdNumber.value >= target.scrollWidth && state2.lastScrollLeft - target.scrollLeft < 0 && $event.timeStamp - state2.lastScrollToLowerTime > 200) { + trigger("scrolltolower", $event, { + direction: "right" + }); + state2.lastScrollToLowerTime = $event.timeStamp; + } + } + state2.lastScrollTop = target.scrollTop; + state2.lastScrollLeft = target.scrollLeft; + } + function _scrollTopChanged(val) { + if (props2.scrollY) { + { + if (props2.scrollWithAnimation) { + scrollTo2(val, "y"); + } else { + main.value.scrollTop = val; + } + } + } + } + function _scrollLeftChanged(val) { + if (props2.scrollX) { + { + if (props2.scrollWithAnimation) { + scrollTo2(val, "x"); + } else { + main.value.scrollLeft = val; + } + } + } + } + function _scrollIntoViewChanged(val) { + if (val) { + if (!/^[_a-zA-Z][-_a-zA-Z0-9:]*$/.test(val)) { + console.error(`id error: scroll-into-view=${val}`); + return; + } + let element = rootRef.value.querySelector("#" + val); + if (element) { + let mainRect = main.value.getBoundingClientRect(); + let elRect = element.getBoundingClientRect(); + if (props2.scrollX) { + let left = elRect.left - mainRect.left; + let scrollLeft = main.value.scrollLeft; + let x = scrollLeft + left; + if (props2.scrollWithAnimation) { + scrollTo2(x, "x"); + } else { + main.value.scrollLeft = x; + } + } + if (props2.scrollY) { + let top = elRect.top - mainRect.top; + let scrollTop = main.value.scrollTop; + let y = scrollTop + top; + if (props2.scrollWithAnimation) { + scrollTo2(y, "y"); + } else { + main.value.scrollTop = y; + } + } + } + } + } + function _transitionEnd(val, direction2) { + content.value.style.transition = ""; + content.value.style.webkitTransition = ""; + content.value.style.transform = ""; + content.value.style.webkitTransform = ""; + let _main = main.value; + if (direction2 === "x") { + _main.style.overflowX = props2.scrollX ? "auto" : "hidden"; + _main.scrollLeft = val; + } else if (direction2 === "y") { + _main.style.overflowY = props2.scrollY ? "auto" : "hidden"; + _main.scrollTop = val; + } + content.value.removeEventListener("transitionend", __transitionEnd); + content.value.removeEventListener("webkitTransitionEnd", __transitionEnd); + } + function _setRefreshState(_state) { + if (!props2.refresherEnabled) + return; + switch (_state) { + case "refreshing": + state2.refresherHeight = props2.refresherThreshold; + if (!beforeRefreshing) { + beforeRefreshing = true; + trigger("refresherrefresh", {}, {}); + emit2("update:refresherTriggered", true); + } + break; + case "restore": + case "refresherabort": + beforeRefreshing = false; + state2.refresherHeight = toUpperNumber = 0; + if (_state === "restore") { + triggerAbort = false; + trigger("refresherrestore", {}, {}); + } + if (_state === "refresherabort" && triggerAbort) { + triggerAbort = false; + trigger("refresherabort", {}, {}); + } + break; + } + state2.refreshState = _state; + } + onMounted(() => { + nextTick(() => { + _scrollTopChanged(scrollTopNumber.value); + _scrollLeftChanged(scrollLeftNumber.value); + }); + _scrollIntoViewChanged(props2.scrollIntoView); + let __handleScroll = function(event) { + event.preventDefault(); + event.stopPropagation(); + _handleScroll(event); + }; + let touchStart = { + x: 0, + y: 0 + }; + let needStop = null; + let __handleTouchMove = function(event) { + if (touchStart === null) + return; + let x = event.touches[0].pageX; + let y = event.touches[0].pageY; + let _main = main.value; + if (Math.abs(x - touchStart.x) > Math.abs(y - touchStart.y)) { + if (props2.scrollX) { + if (_main.scrollLeft === 0 && x > touchStart.x) { + needStop = false; + return; + } else if (_main.scrollWidth === _main.offsetWidth + _main.scrollLeft && x < touchStart.x) { + needStop = false; + return; + } + needStop = true; + } else { + needStop = false; + } + } else { + if (props2.scrollY) { + if (_main.scrollTop === 0 && y > touchStart.y) { + needStop = false; + if (props2.refresherEnabled && event.cancelable !== false) + event.preventDefault(); + } else if (_main.scrollHeight === _main.offsetHeight + _main.scrollTop && y < touchStart.y) { + needStop = false; + return; + } else { + needStop = true; + } + } else { + needStop = false; + } + } + if (needStop) { + event.stopPropagation(); + } + if (_main.scrollTop === 0 && event.touches.length === 1) { + _setRefreshState("pulling"); + } + if (props2.refresherEnabled && state2.refreshState === "pulling") { + const dy = y - touchStart.y; + if (toUpperNumber === 0) { + toUpperNumber = y; + } + if (!beforeRefreshing) { + state2.refresherHeight = y - toUpperNumber; + if (state2.refresherHeight > 0) { + triggerAbort = true; + trigger("refresherpulling", event, { + deltaY: dy + }); + } + } else { + state2.refresherHeight = dy + props2.refresherThreshold; + triggerAbort = false; + } + const route = state2.refresherHeight / props2.refresherThreshold; + state2.refreshRotate = (route > 1 ? 1 : route) * 360; + } + }; + let __handleTouchStart = function(event) { + if (event.touches.length === 1) { + touchStart = { + x: event.touches[0].pageX, + y: event.touches[0].pageY + }; + } + }; + let __handleTouchEnd = function(event) { + touchStart = null; + if (state2.refresherHeight >= props2.refresherThreshold) { + _setRefreshState("refreshing"); + } else { + _setRefreshState("refresherabort"); + } + }; + main.value.addEventListener("touchstart", __handleTouchStart, passiveOptions); + main.value.addEventListener("touchmove", __handleTouchMove, passive(false)); + main.value.addEventListener("scroll", __handleScroll, passive(false)); + main.value.addEventListener("touchend", __handleTouchEnd, passiveOptions); + onBeforeUnmount(() => { + main.value.removeEventListener("touchstart", __handleTouchStart); + main.value.removeEventListener("touchmove", __handleTouchMove); + main.value.removeEventListener("scroll", __handleScroll); + main.value.removeEventListener("touchend", __handleTouchEnd); + }); + }); + onActivated(() => { + props2.scrollY && (main.value.scrollTop = state2.lastScrollTop); + props2.scrollX && (main.value.scrollLeft = state2.lastScrollLeft); + }); + watch(scrollTopNumber, (val) => { + _scrollTopChanged(val); + }); + watch(scrollLeftNumber, (val) => { + _scrollLeftChanged(val); + }); + watch(() => props2.scrollIntoView, (val) => { + _scrollIntoViewChanged(val); + }); + watch(() => props2.refresherTriggered, (val) => { + if (val === true) { + _setRefreshState("refreshing"); + } else if (val === false) { + _setRefreshState("restore"); + } + }); +} +const props$l = { + name: { + type: String, + default: "" + }, + min: { + type: [Number, String], + default: 0 + }, + max: { + type: [Number, String], + default: 100 + }, + value: { + type: [Number, String], + default: 0 + }, + step: { + type: [Number, String], + default: 1 + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "#e9e9e9" + }, + backgroundColor: { + type: String, + default: "#e9e9e9" + }, + activeColor: { + type: String, + default: "#007aff" + }, + selectedColor: { + type: String, + default: "#007aff" + }, + blockColor: { + type: String, + default: "#ffffff" + }, + blockSize: { + type: [Number, String], + default: 28 + }, + showValue: { + type: [Boolean, String], + default: false + } +}; +const index$k = /* @__PURE__ */ defineBuiltInComponent({ + name: "Slider", + props: props$l, + emits: ["changing", "change"], + setup(props2, { + emit: emit2 + }) { + const sliderRef = ref(null); + const sliderValueRef = ref(null); + const sliderHandleRef = ref(null); + const sliderValue = ref(Number(props2.value)); + watch(() => props2.value, (val) => { + sliderValue.value = Number(val); + }); + const trigger = useCustomEvent(sliderRef, emit2); + const state2 = useSliderState(props2, sliderValue); + const { + _onClick, + _onTrack + } = useSliderLoader(props2, sliderValue, sliderRef, sliderValueRef, trigger); + onMounted(() => { + useTouchtrack(sliderHandleRef.value, _onTrack); + }); + return () => { + const { + setBgColor, + setBlockBg, + setActiveColor, + setBlockStyle + } = state2; + return createVNode("uni-slider", { + "ref": sliderRef, + "onClick": withWebEvent(_onClick) + }, [createVNode("div", { + "class": "uni-slider-wrapper" + }, [createVNode("div", { + "class": "uni-slider-tap-area" + }, [createVNode("div", { + "style": setBgColor.value, + "class": "uni-slider-handle-wrapper" + }, [createVNode("div", { + "ref": sliderHandleRef, + "style": setBlockBg.value, + "class": "uni-slider-handle" + }, null, 4), createVNode("div", { + "style": setBlockStyle.value, + "class": "uni-slider-thumb" + }, null, 4), createVNode("div", { + "style": setActiveColor.value, + "class": "uni-slider-track" + }, null, 4)], 4)]), withDirectives(createVNode("span", { + "ref": sliderValueRef, + "class": "uni-slider-value" + }, [sliderValue.value], 512), [[vShow, props2.showValue]])]), createVNode("slot", null, null)], 8, ["onClick"]); + }; + } +}); +function useSliderState(props2, sliderValue) { + const _getValueWidth = () => { + const max = Number(props2.max); + const min = Number(props2.min); + return 100 * (sliderValue.value - min) / (max - min) + "%"; + }; + const _getBgColor = () => { + return props2.backgroundColor !== "#e9e9e9" ? props2.backgroundColor : props2.color !== "#007aff" ? props2.color : "#007aff"; + }; + const _getActiveColor = () => { + return props2.activeColor !== "#007aff" ? props2.activeColor : props2.selectedColor !== "#e9e9e9" ? props2.selectedColor : "#e9e9e9"; + }; + const state2 = { + setBgColor: computed(() => ({ + backgroundColor: _getBgColor() + })), + setBlockBg: computed(() => ({ + left: _getValueWidth() + })), + setActiveColor: computed(() => ({ + backgroundColor: _getActiveColor(), + width: _getValueWidth() + })), + setBlockStyle: computed(() => ({ + width: props2.blockSize + "px", + height: props2.blockSize + "px", + marginLeft: -props2.blockSize / 2 + "px", + marginTop: -props2.blockSize / 2 + "px", + left: _getValueWidth(), + backgroundColor: props2.blockColor + })) + }; + return state2; +} +function useSliderLoader(props2, sliderValue, sliderRef, sliderValueRef, trigger) { + const _onClick = ($event) => { + if (props2.disabled) { + return; + } + _onUserChangedValue($event); + trigger("change", $event, { + value: sliderValue.value + }); + }; + const _filterValue = (e2) => { + const max = Number(props2.max); + const min = Number(props2.min); + const step = Number(props2.step); + return e2 < min ? min : e2 > max ? max : computeController.mul.call(Math.round((e2 - min) / step), step) + min; + }; + const _onUserChangedValue = (e2) => { + const max = Number(props2.max); + const min = Number(props2.min); + const sliderRightBox = sliderValueRef.value; + const sliderRightBoxLeft = getComputedStyle(sliderRightBox, null).marginLeft; + let sliderRightBoxWidth = sliderRightBox.offsetWidth; + sliderRightBoxWidth = sliderRightBoxWidth + parseInt(sliderRightBoxLeft); + const slider = sliderRef.value; + const offsetWidth = slider.offsetWidth - (props2.showValue ? sliderRightBoxWidth : 0); + const boxLeft = slider.getBoundingClientRect().left; + const value = (e2.x - boxLeft) * (max - min) / offsetWidth + min; + sliderValue.value = _filterValue(value); + }; + const _onTrack = (e2) => { + if (!props2.disabled) { + return e2.detail.state === "move" ? (_onUserChangedValue({ + x: e2.detail.x + }), trigger("changing", e2, { + value: sliderValue.value + }), false) : e2.detail.state === "end" && trigger("change", e2, { + value: sliderValue.value + }); + } + }; + const uniForm = inject(uniFormKey, false); + if (!!uniForm) { + const field = { + reset: () => sliderValue.value = Number(props2.min), + submit: () => { + const data = ["", null]; + if (props2.name !== "") { + data[0] = props2.name; + data[1] = sliderValue.value; + } + return data; + } + }; + uniForm.addField(field); + onBeforeUnmount(() => { + uniForm.removeField(field); + }); + } + return { + _onClick, + _onTrack + }; +} +var computeController = { + mul: function(arg) { + let m = 0; + let s1 = this.toString(); + let s2 = arg.toString(); + try { + m += s1.split(".")[1].length; + } catch (e2) { + } + try { + m += s2.split(".")[1].length; + } catch (e2) { + } + return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); + } +}; +const props$k = { + indicatorDots: { + type: [Boolean, String], + default: false + }, + vertical: { + type: [Boolean, String], + default: false + }, + autoplay: { + type: [Boolean, String], + default: false + }, + circular: { + type: [Boolean, String], + default: false + }, + interval: { + type: [Number, String], + default: 5e3 + }, + duration: { + type: [Number, String], + default: 500 + }, + current: { + type: [Number, String], + default: 0 + }, + indicatorColor: { + type: String, + default: "" + }, + indicatorActiveColor: { + type: String, + default: "" + }, + previousMargin: { + type: String, + default: "" + }, + nextMargin: { + type: String, + default: "" + }, + currentItemId: { + type: String, + default: "" + }, + skipHiddenItemLayout: { + type: [Boolean, String], + default: false + }, + displayMultipleItems: { + type: [Number, String], + default: 1 + }, + disableTouch: { + type: [Boolean, String], + default: false + }, + navigation: { + type: [Boolean, String], + default: false + }, + navigationColor: { + type: String, + default: "#fff" + }, + navigationActiveColor: { + type: String, + default: "rgba(53, 53, 53, 0.6)" + } +}; +function useState$3(props2) { + const interval = computed(() => { + const interval2 = Number(props2.interval); + return isNaN(interval2) ? 5e3 : interval2; + }); + const duration = computed(() => { + const duration2 = Number(props2.duration); + return isNaN(duration2) ? 500 : duration2; + }); + const displayMultipleItems = computed(() => { + const displayMultipleItems2 = Math.round(props2.displayMultipleItems); + return isNaN(displayMultipleItems2) ? 1 : displayMultipleItems2; + }); + const state2 = reactive({ + interval, + duration, + displayMultipleItems, + current: Math.round(props2.current) || 0, + currentItemId: props2.currentItemId, + userTracking: false + }); + return state2; +} +function useLayout(props2, state2, swiperContexts, slideFrameRef, emit2, trigger) { + function cancelSchedule() { + if (timer) { + clearTimeout(timer); + timer = null; + } + } + let timer = null; + let invalid = true; + let viewportPosition = 0; + let viewportMoveRatio = 1; + let animating = null; + let requestedAnimation = false; + let contentTrackViewport = 0; + let transitionStart; + let currentChangeSource = ""; + let animationFrame; + const swiperEnabled = computed(() => swiperContexts.value.length > state2.displayMultipleItems); + const circularEnabled = computed(() => props2.circular && swiperEnabled.value); + function checkCircularLayout(index2) { + if (!invalid) { + for (let items = swiperContexts.value, n = items.length, i = index2 + state2.displayMultipleItems, r = 0; r < n; r++) { + const item = items[r]; + const s = Math.floor(index2 / n) * n + r; + const l = s + n; + const c = s - n; + const u = Math.max(index2 - (s + 1), s - i, 0); + const d = Math.max(index2 - (l + 1), l - i, 0); + const h2 = Math.max(index2 - (c + 1), c - i, 0); + const p2 = Math.min(u, d, h2); + const position = [s, l, c][[u, d, h2].indexOf(p2)]; + item.updatePosition(position, props2.vertical); + } + } + } + function updateViewport(index2) { + if (!(Math.floor(2 * viewportPosition) === Math.floor(2 * index2) && Math.ceil(2 * viewportPosition) === Math.ceil(2 * index2))) { + if (circularEnabled.value) { + checkCircularLayout(index2); + } + } + const x = props2.vertical ? "0" : 100 * -index2 * viewportMoveRatio + "%"; + const y = props2.vertical ? 100 * -index2 * viewportMoveRatio + "%" : "0"; + const transform = "translate(" + x + ", " + y + ") translateZ(0)"; + const slideFrame = slideFrameRef.value; + if (slideFrame) { + slideFrame.style.webkitTransform = transform; + slideFrame.style.transform = transform; + } + viewportPosition = index2; + if (!transitionStart) { + if (index2 % 1 === 0) { + return; + } + transitionStart = index2; + } + index2 -= Math.floor(transitionStart); + const items = swiperContexts.value; + if (index2 <= -(items.length - 1)) { + index2 += items.length; + } else if (index2 >= items.length) { + index2 -= items.length; + } + index2 = transitionStart % 1 > 0.5 || transitionStart < 0 ? index2 - 1 : index2; + trigger("transition", {}, { + dx: props2.vertical ? 0 : index2 * slideFrame.offsetWidth, + dy: props2.vertical ? index2 * slideFrame.offsetHeight : 0 + }); + } + function endViewportAnimation() { + if (animating) { + updateViewport(animating.toPos); + animating = null; + } + } + function normalizeCurrentValue(current) { + const length = swiperContexts.value.length; + if (!length) { + return -1; + } + const index2 = (Math.round(current) % length + length) % length; + if (circularEnabled.value) { + if (length <= state2.displayMultipleItems) { + return 0; + } + } else if (index2 > length - state2.displayMultipleItems) { + return length - state2.displayMultipleItems; + } + return index2; + } + function cancelViewportAnimation() { + animating = null; + } + function animateFrameFuncProto() { + if (!animating) { + requestedAnimation = false; + return; + } + const _animating = animating; + const toPos = _animating.toPos; + const acc = _animating.acc; + const endTime = _animating.endTime; + const source = _animating.source; + const time = endTime - Date.now(); + if (time <= 0) { + updateViewport(toPos); + animating = null; + requestedAnimation = false; + transitionStart = null; + const item = swiperContexts.value[state2.current]; + if (item) { + const currentItemId = item.getItemId(); + trigger("animationfinish", {}, { + current: state2.current, + currentItemId, + source + }); + } + return; + } + const s = acc * time * time / 2; + const l = toPos + s; + updateViewport(l); + animationFrame = requestAnimationFrame(animateFrameFuncProto); + } + function animateViewport(current, source, n) { + cancelViewportAnimation(); + const duration = state2.duration; + const length = swiperContexts.value.length; + let position = viewportPosition; + if (circularEnabled.value) { + if (n < 0) { + for (; position < current; ) { + position += length; + } + for (; position - length > current; ) { + position -= length; + } + } else if (n > 0) { + for (; position > current; ) { + position -= length; + } + for (; position + length < current; ) { + position += length; + } + if (position + length - current < current - position) { + position += length; + } + } else { + for (; position + length < current; ) { + position += length; + } + for (; position - length > current; ) { + position -= length; + } + if (position + length - current < current - position) { + position += length; + } + } + } else if (source === "click") { + current = current + state2.displayMultipleItems - 1 < length ? current : 0; + } + animating = { + toPos: current, + acc: 2 * (position - current) / (duration * duration), + endTime: Date.now() + duration, + source + }; + if (!requestedAnimation) { + requestedAnimation = true; + animationFrame = requestAnimationFrame(animateFrameFuncProto); + } + } + function scheduleAutoplay() { + cancelSchedule(); + const items = swiperContexts.value; + const callback = function() { + timer = null; + currentChangeSource = "autoplay"; + if (circularEnabled.value) { + state2.current = normalizeCurrentValue(state2.current + 1); + } else { + state2.current = state2.current + state2.displayMultipleItems < items.length ? state2.current + 1 : 0; + } + animateViewport(state2.current, "autoplay", circularEnabled.value ? 1 : 0); + timer = setTimeout(callback, state2.interval); + }; + if (!(invalid || items.length <= state2.displayMultipleItems)) { + timer = setTimeout(callback, state2.interval); + } + } + function resetLayout() { + cancelSchedule(); + endViewportAnimation(); + const items = swiperContexts.value; + for (let i = 0; i < items.length; i++) { + items[i].updatePosition(i, props2.vertical); + } + viewportMoveRatio = 1; + const slideFrameEl = slideFrameRef.value; + if (state2.displayMultipleItems === 1 && items.length) { + const itemRect = items[0].getBoundingClientRect(); + const slideFrameRect = slideFrameEl.getBoundingClientRect(); + viewportMoveRatio = itemRect.width / slideFrameRect.width; + if (!(viewportMoveRatio > 0 && viewportMoveRatio < 1)) { + viewportMoveRatio = 1; + } + } + const position = viewportPosition; + viewportPosition = -2; + const current = state2.current; + if (current >= 0) { + invalid = false; + if (state2.userTracking) { + updateViewport(position + current - contentTrackViewport); + contentTrackViewport = current; + } else { + updateViewport(current); + if (props2.autoplay) { + scheduleAutoplay(); + } + } + } else { + invalid = true; + updateViewport(-state2.displayMultipleItems - 1); + } + } + watch([() => props2.current, () => props2.currentItemId, () => [...swiperContexts.value]], () => { + let current = -1; + if (props2.currentItemId) { + for (let i = 0, items = swiperContexts.value; i < items.length; i++) { + const itemId = items[i].getItemId(); + if (itemId === props2.currentItemId) { + current = i; + break; + } + } + } + if (current < 0) { + current = Math.round(props2.current) || 0; + } + current = current < 0 ? 0 : current; + if (state2.current !== current) { + currentChangeSource = ""; + state2.current = current; + } + }); + watch([() => props2.vertical, () => circularEnabled.value, () => state2.displayMultipleItems, () => [...swiperContexts.value]], resetLayout); + watch(() => state2.interval, () => { + if (timer) { + cancelSchedule(); + scheduleAutoplay(); + } + }); + function currentChanged(current, history2) { + const source = currentChangeSource; + currentChangeSource = ""; + const items = swiperContexts.value; + if (!source) { + const length = items.length; + animateViewport(current, "", circularEnabled.value && history2 + (length - current) % length > length / 2 ? 1 : 0); + } + const item = items[current]; + if (item) { + const currentItemId = state2.currentItemId = item.getItemId(); + trigger("change", {}, { + current: state2.current, + currentItemId, + source + }); + } + } + watch(() => state2.current, (val, oldVal) => { + currentChanged(val, oldVal); + emit2("update:current", val); + }); + watch(() => state2.currentItemId, (val) => { + emit2("update:currentItemId", val); + }); + function inintAutoplay(enable) { + if (enable) { + scheduleAutoplay(); + } else { + cancelSchedule(); + } + } + watch(() => props2.autoplay && !state2.userTracking, inintAutoplay); + inintAutoplay(props2.autoplay && !state2.userTracking); + onMounted(() => { + let userDirectionChecked = false; + let contentTrackSpeed = 0; + let contentTrackT = 0; + function handleTrackStart() { + cancelSchedule(); + contentTrackViewport = viewportPosition; + contentTrackSpeed = 0; + contentTrackT = Date.now(); + cancelViewportAnimation(); + } + function handleTrackMove(data) { + const oldContentTrackT = contentTrackT; + contentTrackT = Date.now(); + const length = swiperContexts.value.length; + const other = length - state2.displayMultipleItems; + function calc2(val) { + return 0.5 - 0.25 / (val + 0.5); + } + function move(oldVal, newVal) { + let val = contentTrackViewport + oldVal; + contentTrackSpeed = 0.6 * contentTrackSpeed + 0.4 * newVal; + if (!circularEnabled.value) { + if (val < 0 || val > other) { + if (val < 0) { + val = -calc2(-val); + } else { + if (val > other) { + val = other + calc2(val - other); + } + } + contentTrackSpeed = 0; + } + } + updateViewport(val); + } + const time = contentTrackT - oldContentTrackT || 1; + const slideFrameEl = slideFrameRef.value; + if (props2.vertical) { + move(-data.dy / slideFrameEl.offsetHeight, -data.ddy / time); + } else { + move(-data.dx / slideFrameEl.offsetWidth, -data.ddx / time); + } + } + function handleTrackEnd(isCancel) { + state2.userTracking = false; + const t2 = contentTrackSpeed / Math.abs(contentTrackSpeed); + let n = 0; + if (!isCancel && Math.abs(contentTrackSpeed) > 0.2) { + n = 0.5 * t2; + } + const current = normalizeCurrentValue(viewportPosition + n); + if (isCancel) { + updateViewport(contentTrackViewport); + } else { + currentChangeSource = "touch"; + state2.current = current; + animateViewport(current, "touch", n !== 0 ? n : current === 0 && circularEnabled.value && viewportPosition >= 1 ? 1 : 0); + } + } + useTouchtrack(slideFrameRef.value, (event) => { + if (props2.disableTouch) { + return; + } + if (!invalid) { + if (event.detail.state === "start") { + state2.userTracking = true; + userDirectionChecked = false; + return handleTrackStart(); + } + if (event.detail.state === "end") { + return handleTrackEnd(false); + } + if (event.detail.state === "cancel") { + return handleTrackEnd(true); + } + if (state2.userTracking) { + if (!userDirectionChecked) { + userDirectionChecked = true; + const t2 = Math.abs(event.detail.dx); + const n = Math.abs(event.detail.dy); + if (t2 >= n && props2.vertical) { + state2.userTracking = false; + } else { + if (t2 <= n && !props2.vertical) { + state2.userTracking = false; + } + } + if (!state2.userTracking) { + if (props2.autoplay) { + scheduleAutoplay(); + } + return; + } + } + handleTrackMove(event.detail); + return false; + } + } + }); + }); + onUnmounted(() => { + cancelSchedule(); + cancelAnimationFrame(animationFrame); + }); + function onSwiperDotClick(index2) { + animateViewport(state2.current = index2, currentChangeSource = "click", circularEnabled.value ? 1 : 0); + } + return { + onSwiperDotClick, + circularEnabled, + swiperEnabled + }; +} +const Swiper = /* @__PURE__ */ defineBuiltInComponent({ + name: "Swiper", + props: props$k, + emits: ["change", "transition", "animationfinish", "update:current", "update:currentItemId"], + setup(props2, { + slots, + emit: emit2 + }) { + const rootRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const slidesWrapperRef = ref(null); + const slideFrameRef = ref(null); + const state2 = useState$3(props2); + const slidesStyle = computed(() => { + let style = {}; + if (props2.nextMargin || props2.previousMargin) { + style = props2.vertical ? { + left: 0, + right: 0, + top: rpx2px(props2.previousMargin, true), + bottom: rpx2px(props2.nextMargin, true) + } : { + top: 0, + bottom: 0, + left: rpx2px(props2.previousMargin, true), + right: rpx2px(props2.nextMargin, true) + }; + } + return style; + }); + const slideFrameStyle = computed(() => { + const value = Math.abs(100 / state2.displayMultipleItems) + "%"; + return { + width: props2.vertical ? "100%" : value, + height: !props2.vertical ? "100%" : value + }; + }); + let swiperItems = []; + const originSwiperContexts = []; + const swiperContexts = ref([]); + function updateSwiperContexts() { + const contexts = []; + for (let index2 = 0; index2 < swiperItems.length; index2++) { + let swiperItem = swiperItems[index2]; + if (!(swiperItem instanceof Element)) { + swiperItem = swiperItem.el; + } + const swiperContext = originSwiperContexts.find((context) => swiperItem === context.rootRef.value); + if (swiperContext) { + contexts.push(markRaw(swiperContext)); + } + } + swiperContexts.value = contexts; + } + const addSwiperContext = function(swiperContext) { + originSwiperContexts.push(swiperContext); + updateSwiperContexts(); + }; + provide("addSwiperContext", addSwiperContext); + const removeSwiperContext = function(swiperContext) { + const index2 = originSwiperContexts.indexOf(swiperContext); + if (index2 >= 0) { + originSwiperContexts.splice(index2, 1); + updateSwiperContexts(); + } + }; + provide("removeSwiperContext", removeSwiperContext); + const { + onSwiperDotClick, + circularEnabled, + swiperEnabled + } = useLayout(props2, state2, swiperContexts, slideFrameRef, emit2, trigger); + let createNavigationTsx = () => null; + { + createNavigationTsx = useSwiperNavigation(rootRef, props2, state2, onSwiperDotClick, swiperContexts, circularEnabled, swiperEnabled); + } + return () => { + const defaultSlots = slots.default && slots.default(); + swiperItems = flatVNode(defaultSlots); + return createVNode("uni-swiper", { + "ref": rootRef + }, [createVNode("div", { + "ref": slidesWrapperRef, + "class": "uni-swiper-wrapper" + }, [createVNode("div", { + "class": "uni-swiper-slides", + "style": slidesStyle.value + }, [createVNode("div", { + "ref": slideFrameRef, + "class": "uni-swiper-slide-frame", + "style": slideFrameStyle.value + }, [defaultSlots], 4)], 4), props2.indicatorDots && createVNode("div", { + "class": ["uni-swiper-dots", props2.vertical ? "uni-swiper-dots-vertical" : "uni-swiper-dots-horizontal"] + }, [swiperContexts.value.map((_, index2, array) => createVNode("div", { + "onClick": () => onSwiperDotClick(index2), + "class": { + "uni-swiper-dot": true, + "uni-swiper-dot-active": index2 < state2.current + state2.displayMultipleItems && index2 >= state2.current || index2 < state2.current + state2.displayMultipleItems - array.length + }, + "style": { + background: index2 === state2.current ? props2.indicatorActiveColor : props2.indicatorColor + } + }, null, 14, ["onClick"]))], 2), createNavigationTsx()], 512)], 512); + }; + } +}); +const useSwiperNavigation = (rootRef, props2, state2, onSwiperDotClick, swiperContext, circularEnabled, swiperEnabled) => { + let isNavigationAuto = false; + let prevDisabled = false; + let nextDisabled = false; + let hideNavigation = ref(false); + watchEffect(() => { + isNavigationAuto = props2.navigation === "auto"; + hideNavigation.value = props2.navigation !== true || isNavigationAuto; + swiperAddMouseEvent(); + }); + watchEffect(() => { + const swiperItemLength = swiperContext.value.length; + const notCircular = !circularEnabled.value; + prevDisabled = state2.current === 0 && notCircular; + nextDisabled = state2.current === swiperItemLength - 1 && notCircular || notCircular && state2.current + state2.displayMultipleItems >= swiperItemLength; + if (!swiperEnabled.value) { + prevDisabled = true; + nextDisabled = true; + isNavigationAuto && (hideNavigation.value = true); + } + }); + function navigationHover(event, type) { + const target = event.currentTarget; + if (!target) + return; + target.style.backgroundColor = type === "over" ? props2.navigationActiveColor : ""; + } + const navigationAttr = { + onMouseover: (event) => navigationHover(event, "over"), + onMouseout: (event) => navigationHover(event, "out") + }; + function navigationClick($event, type, disabled) { + $event.stopPropagation(); + if (disabled) + return; + const swiperItemLength = swiperContext.value.length; + let _current = state2.current; + switch (type) { + case "prev": + _current--; + if (_current < 0 && circularEnabled.value) { + _current = swiperItemLength - 1; + } + break; + case "next": + _current++; + if (_current >= swiperItemLength && circularEnabled.value) { + _current = 0; + } + break; + } + onSwiperDotClick(_current); + } + const createNavigationSVG = () => createSvgIconVNode(ICON_PATH_BACK, props2.navigationColor, 26); + let setHideNavigationTimer; + const _mousemove = (e2) => { + clearTimeout(setHideNavigationTimer); + const { + clientX, + clientY + } = e2; + const { + left, + right, + top, + bottom, + width, + height + } = rootRef.value.getBoundingClientRect(); + let hide = false; + if (props2.vertical) { + hide = !(clientY - top < height / 3 || bottom - clientY < height / 3); + } else { + hide = !(clientX - left < width / 3 || right - clientX < width / 3); + } + if (hide) { + return setHideNavigationTimer = setTimeout(() => { + hideNavigation.value = hide; + }, 300); + } + hideNavigation.value = hide; + }; + const _mouseleave = () => { + hideNavigation.value = true; + }; + function swiperAddMouseEvent() { + if (rootRef.value) { + rootRef.value.removeEventListener("mousemove", _mousemove); + rootRef.value.removeEventListener("mouseleave", _mouseleave); + if (isNavigationAuto) { + rootRef.value.addEventListener("mousemove", _mousemove); + rootRef.value.addEventListener("mouseleave", _mouseleave); + } + } + } + onMounted(swiperAddMouseEvent); + function createNavigationTsx() { + const navigationClass = { + "uni-swiper-navigation-hide": hideNavigation.value, + "uni-swiper-navigation-vertical": props2.vertical + }; + if (props2.navigation) { + return createVNode(Fragment, null, [createVNode("div", mergeProps({ + "class": ["uni-swiper-navigation uni-swiper-navigation-prev", extend({ + "uni-swiper-navigation-disabled": prevDisabled + }, navigationClass)], + "onClick": (e2) => navigationClick(e2, "prev", prevDisabled) + }, navigationAttr), [createNavigationSVG()], 16, ["onClick"]), createVNode("div", mergeProps({ + "class": ["uni-swiper-navigation uni-swiper-navigation-next", extend({ + "uni-swiper-navigation-disabled": nextDisabled + }, navigationClass)], + "onClick": (e2) => navigationClick(e2, "next", nextDisabled) + }, navigationAttr), [createNavigationSVG()], 16, ["onClick"])]); + } + return null; + } + return createNavigationTsx; +}; +const props$j = { + itemId: { + type: String, + default: "" + } +}; +const SwiperItem = /* @__PURE__ */ defineBuiltInComponent({ + name: "SwiperItem", + props: props$j, + setup(props2, { + slots + }) { + const rootRef = ref(null); + const context = { + rootRef, + getItemId() { + return props2.itemId; + }, + getBoundingClientRect() { + const el = rootRef.value; + return el.getBoundingClientRect(); + }, + updatePosition(position, vertical) { + const x = vertical ? "0" : 100 * position + "%"; + const y = vertical ? 100 * position + "%" : "0"; + const rootEl = rootRef.value; + const value = `translate(${x},${y}) translateZ(0)`; + if (rootEl) { + rootEl.style.webkitTransform = value; + rootEl.style.transform = value; + } + } + }; + onMounted(() => { + const addSwiperContext = inject("addSwiperContext"); + if (addSwiperContext) { + addSwiperContext(context); + } + }); + onUnmounted(() => { + const removeSwiperContext = inject("removeSwiperContext"); + if (removeSwiperContext) { + removeSwiperContext(context); + } + }); + return () => { + return createVNode("uni-swiper-item", { + "ref": rootRef, + "style": { + position: "absolute", + width: "100%", + height: "100%" + } + }, [slots.default && slots.default()], 512); + }; + } +}); +const props$i = { + name: { + type: String, + default: "" + }, + checked: { + type: [Boolean, String], + default: false + }, + type: { + type: String, + default: "switch" + }, + id: { + type: String, + default: "" + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: "" + } +}; +const index$j = /* @__PURE__ */ defineBuiltInComponent({ + name: "Switch", + props: props$i, + emits: ["change"], + setup(props2, { + emit: emit2 + }) { + const rootRef = ref(null); + const switchChecked = ref(props2.checked); + const uniLabel = useSwitchInject(props2, switchChecked); + const trigger = useCustomEvent(rootRef, emit2); + watch(() => props2.checked, (val) => { + switchChecked.value = val; + }); + const _onClick = ($event) => { + if (props2.disabled) { + return; + } + switchChecked.value = !switchChecked.value; + trigger("change", $event, { + value: switchChecked.value + }); + }; + if (!!uniLabel) { + uniLabel.addHandler(_onClick); + onBeforeUnmount(() => { + uniLabel.removeHandler(_onClick); + }); + } + useListeners$1(props2, { + "label-click": _onClick + }); + return () => { + const { + color, + type + } = props2; + const booleanAttrs = useBooleanAttr(props2, "disabled"); + const switchInputStyle = {}; + if (color && switchChecked.value) { + switchInputStyle["backgroundColor"] = color; + switchInputStyle["borderColor"] = color; + } + return createVNode("uni-switch", mergeProps({ + "ref": rootRef + }, booleanAttrs, { + "onClick": _onClick + }), [createVNode("div", { + "class": "uni-switch-wrapper" + }, [withDirectives(createVNode("div", { + "class": ["uni-switch-input", [switchChecked.value ? "uni-switch-input-checked" : ""]], + "style": switchInputStyle + }, null, 6), [[vShow, type === "switch"]]), withDirectives(createVNode("div", { + "class": "uni-checkbox-input" + }, [switchChecked.value ? createSvgIconVNode(ICON_PATH_SUCCESS_NO_CIRCLE, props2.color, 22) : ""], 512), [[vShow, type === "checkbox"]])])], 16, ["onClick"]); + }; + } +}); +function useSwitchInject(props2, switchChecked) { + const uniForm = inject(uniFormKey, false); + const uniLabel = inject(uniLabelKey, false); + const formField = { + submit: () => { + const data = ["", null]; + if (props2.name) { + data[0] = props2.name; + data[1] = switchChecked.value; + } + return data; + }, + reset: () => { + switchChecked.value = false; + } + }; + if (!!uniForm) { + uniForm.addField(formField); + onUnmounted(() => { + uniForm.removeField(formField); + }); + } + return uniLabel; +} +const SPACE_UNICODE = { + ensp: " ", + emsp: " ", + nbsp: " " +}; +function parseText(text2, options) { + return text2.replace(/\\n/g, LINEFEED).split(LINEFEED).map((text22) => { + return normalizeText(text22, options); + }); +} +function normalizeText(text2, { space, decode: decode2 }) { + if (!text2) { + return text2; + } + if (space && SPACE_UNICODE[space]) { + text2 = text2.replace(/ /g, SPACE_UNICODE[space]); + } + if (!decode2) { + return text2; + } + return text2.replace(/ /g, SPACE_UNICODE.nbsp).replace(/ /g, SPACE_UNICODE.ensp).replace(/ /g, SPACE_UNICODE.emsp).replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'"); +} +const index$i = /* @__PURE__ */ defineBuiltInComponent({ + name: "Text", + props: { + selectable: { + type: [Boolean, String], + default: false + }, + space: { + type: String, + default: "" + }, + decode: { + type: [Boolean, String], + default: false + } + }, + setup(props2, { + slots + }) { + return () => { + const children = []; + if (slots.default) { + slots.default().forEach((vnode) => { + if (vnode.shapeFlag & 8 && vnode.type !== Comment) { + const lines = parseText(vnode.children, { + space: props2.space, + decode: props2.decode + }); + const len = lines.length - 1; + lines.forEach((line, index2) => { + if (index2 === 0 && !line) + ; + else { + children.push(createTextVNode(line)); + } + if (index2 !== len) { + children.push(createVNode("br")); + } + }); + } else { + if (process.env.NODE_ENV !== "production" && vnode.shapeFlag & 6 && vnode.type.name !== "Text") { + console.warn("Do not nest other components in the text component, as there may be display differences on different platforms."); + } + children.push(vnode); + } + }); + } + return createVNode("uni-text", { + "selectable": props2.selectable ? true : null + }, [createVNode("span", null, children)], 8, ["selectable"]); + }; + } +}); +const props$h = /* @__PURE__ */ extend({}, props$r, { + placeholderClass: { + type: String, + default: "input-placeholder" + }, + autoHeight: { + type: [Boolean, String], + default: false + }, + confirmType: { + type: String, + default: "return", + validator(val) { + return ConfirmTypes.concat("return").includes(val); + } + } +}); +let fixMargin = false; +const ConfirmTypes = ["done", "go", "next", "search", "send"]; +function setFixMargin() { + const DARK_TEST_STRING = "(prefers-color-scheme: dark)"; + fixMargin = String(navigator.platform).indexOf("iP") === 0 && String(navigator.vendor).indexOf("Apple") === 0 && window.matchMedia(DARK_TEST_STRING).media !== DARK_TEST_STRING; +} +const index$h = /* @__PURE__ */ defineBuiltInComponent({ + name: "Textarea", + props: props$h, + emits: ["confirm", "linechange", ...emit], + setup(props2, { + emit: emit2 + }) { + const rootRef = ref(null); + const wrapperRef = ref(null); + const { + fieldRef, + state: state2, + scopedAttrsState, + fixDisabledColor, + trigger + } = useField(props2, rootRef, emit2); + const valueCompute = computed(() => state2.value.split(LINEFEED)); + const isDone = computed(() => ConfirmTypes.includes(props2.confirmType)); + const heightRef = ref(0); + const lineRef = ref(null); + watch(() => heightRef.value, (height) => { + const el = rootRef.value; + const lineEl = lineRef.value; + const wrapper2 = wrapperRef.value; + let lineHeight = parseFloat(getComputedStyle(el).lineHeight); + if (isNaN(lineHeight)) { + lineHeight = lineEl.offsetHeight; + } + var lineCount = Math.round(height / lineHeight); + trigger("linechange", {}, { + height, + heightRpx: 750 / window.innerWidth * height, + lineCount + }); + if (props2.autoHeight) { + el.style.height = "auto"; + wrapper2.style.height = height + "px"; + } + }); + function onResize2({ + height + }) { + heightRef.value = height; + } + function confirm(event) { + trigger("confirm", event, { + value: state2.value + }); + } + function onKeyDownEnter(event) { + if (event.key !== "Enter") { + return; + } + if (isDone.value) { + event.preventDefault(); + } + } + function onKeyUpEnter(event) { + if (event.key !== "Enter") { + return; + } + if (isDone.value) { + confirm(event); + const textarea = event.target; + !props2.confirmHold && textarea.blur(); + } + } + { + setFixMargin(); + } + return () => { + let textareaNode = props2.disabled && fixDisabledColor ? createVNode("textarea", { + "key": "disabled-textarea", + "ref": fieldRef, + "value": state2.value, + "tabindex": "-1", + "readonly": !!props2.disabled, + "maxlength": state2.maxlength, + "class": { + "uni-textarea-textarea": true, + "uni-textarea-textarea-fix-margin": fixMargin + }, + "style": { + overflowY: props2.autoHeight ? "hidden" : "auto" + }, + "onFocus": (event) => event.target.blur() + }, null, 46, ["value", "readonly", "maxlength", "onFocus"]) : createVNode("textarea", { + "key": "textarea", + "ref": fieldRef, + "value": state2.value, + "disabled": !!props2.disabled, + "maxlength": state2.maxlength, + "enterkeyhint": props2.confirmType, + "inputmode": props2.inputmode, + "class": { + "uni-textarea-textarea": true, + "uni-textarea-textarea-fix-margin": fixMargin + }, + "style": { + overflowY: props2.autoHeight ? "hidden" : "auto" + }, + "onKeydown": onKeyDownEnter, + "onKeyup": onKeyUpEnter + }, null, 46, ["value", "disabled", "maxlength", "enterkeyhint", "inputmode", "onKeydown", "onKeyup"]); + return createVNode("uni-textarea", { + "ref": rootRef + }, [createVNode("div", { + "ref": wrapperRef, + "class": "uni-textarea-wrapper" + }, [withDirectives(createVNode("div", mergeProps(scopedAttrsState.attrs, { + "style": props2.placeholderStyle, + "class": ["uni-textarea-placeholder", props2.placeholderClass] + }), [props2.placeholder], 16), [[vShow, !state2.value.length]]), createVNode("div", { + "ref": lineRef, + "class": "uni-textarea-line" + }, [" "], 512), createVNode("div", { + "class": "uni-textarea-compute" + }, [valueCompute.value.map((item) => createVNode("div", null, [item.trim() ? item : "."])), createVNode(ResizeSensor, { + "initial": true, + "onResize": onResize2 + }, null, 8, ["initial", "onResize"])]), props2.confirmType === "search" ? createVNode("form", { + "action": "", + "onSubmit": () => false, + "class": "uni-input-form" + }, [textareaNode], 40, ["onSubmit"]) : textareaNode], 512)], 512); + }; + } +}); +const index$g = /* @__PURE__ */ defineBuiltInComponent({ + name: "View", + props: extend({}, hoverProps), + setup(props2, { + slots + }) { + const { + hovering, + binding + } = useHover(props2); + return () => { + const hoverClass = props2.hoverClass; + if (hoverClass && hoverClass !== "none") { + return createVNode("uni-view", mergeProps({ + "class": hovering.value ? hoverClass : "" + }, binding), [slots.default && slots.default()], 16); + } + return createVNode("uni-view", null, [slots.default && slots.default()]); + }; + } +}); +function normalizeEvent(vm, id2) { + if (!id2) { + id2 = vm.id; + } + if (!id2) { + return; + } + return vm.$options.name.toLowerCase() + "." + id2; +} +function addSubscribe(name, callback, pageId) { + if (!name) { + return; + } + registerViewMethod( + pageId || getCurrentPageId(), + name, + ({ type, data }, resolve) => { + callback(type, data, resolve); + } + ); +} +function removeSubscribe(name, pageId) { + if (!name) { + return; + } + unregisterViewMethod(pageId || getCurrentPageId(), name); +} +function useSubscribe(callback, name, multiple, pageId) { + const instance2 = getCurrentInstance(); + const vm = instance2.proxy; + onMounted(() => { + addSubscribe(name || normalizeEvent(vm), callback, pageId); + if (multiple || !name) { + watch( + () => vm.id, + (value, oldValue) => { + addSubscribe(normalizeEvent(vm, value), callback, pageId); + removeSubscribe(oldValue && normalizeEvent(vm, oldValue)); + } + ); + } + }); + onBeforeUnmount(() => { + removeSubscribe(name || normalizeEvent(vm), pageId); + }); +} +function useOn(name, callback) { + onMounted(() => UniViewJSBridge.on(name, callback)); + onBeforeUnmount(() => UniViewJSBridge.off(name)); +} +let index$f = 0; +function useContextInfo(_id) { + const page = useCurrentPageId(); + const instance2 = getCurrentInstance(); + const vm = instance2.proxy; + const type = vm.$options.name.toLowerCase(); + const id2 = _id || vm.id || `context${index$f++}`; + onMounted(() => { + const el = vm.$el; + el.__uniContextInfo = { + id: id2, + type, + page + }; + }); + return `${type}.${id2}`; +} +function getContextInfo(el) { + return el.__uniContextInfo; +} +function injectLifecycleHook(name, hook, publicThis, instance2) { + if (isFunction(hook)) { + injectHook(name, hook.bind(publicThis), instance2); + } +} +function initHooks(options, instance2, publicThis) { + var _a; + const mpType = options.mpType || publicThis.$mpType; + if (!mpType || mpType === "component") { + return; + } + Object.keys(options).forEach((name) => { + if (isUniLifecycleHook(name, options[name], false)) { + const hooks = options[name]; + if (isArray(hooks)) { + hooks.forEach( + (hook) => injectLifecycleHook(name, hook, publicThis, instance2) + ); + } else { + injectLifecycleHook(name, hooks, publicThis, instance2); + } + } + }); + if (mpType === "page") { + instance2.__isVisible = true; + try { + invokeHook(publicThis, ON_LOAD, instance2.attrs.__pageQuery); + delete instance2.attrs.__pageQuery; + if (((_a = publicThis.$page) == null ? void 0 : _a.openType) !== "preloadPage") { + invokeHook(publicThis, ON_SHOW); + } + } catch (e2) { + console.error(e2.message + LINEFEED + e2.stack); + } + } +} +function applyOptions(options, instance2, publicThis) { + initHooks(options, instance2, publicThis); +} +function set(target, key, val) { + return target[key] = val; +} +function createErrorHandler(app) { + return function errorHandler(err, instance2, _info) { + if (!instance2) { + throw err; + } + const appInstance = app._instance; + if (!appInstance || !appInstance.proxy) { + throw err; + } + { + appInstance.proxy.$callHook(ON_ERROR, err); + } + }; +} +function mergeAsArray(to, from) { + return to ? [...new Set([].concat(to, from))] : from; +} +function initOptionMergeStrategies(optionMergeStrategies) { + UniLifecycleHooks.forEach((name) => { + optionMergeStrategies[name] = mergeAsArray; + }); +} +let realAtob; +const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; +const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; +if (typeof atob !== "function") { + realAtob = function(str) { + str = String(str).replace(/[\t\n\f\r ]+/g, ""); + if (!b64re.test(str)) { + throw new Error( + "Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded." + ); + } + str += "==".slice(2 - (str.length & 3)); + var bitmap; + var result = ""; + var r1; + var r2; + var i = 0; + for (; i < str.length; ) { + bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 | (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++))); + result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) : String.fromCharCode( + bitmap >> 16 & 255, + bitmap >> 8 & 255, + bitmap & 255 + ); + } + return result; + }; +} else { + realAtob = atob; +} +function b64DecodeUnicode(str) { + return decodeURIComponent( + realAtob(str).split("").map(function(c) { + return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); + }).join("") + ); +} +function getCurrentUserInfo() { + const token = uni.getStorageSync("uni_id_token") || ""; + const tokenArr = token.split("."); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0 + }; + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } catch (error) { + throw new Error("获取当前用户信息出错,详细错误信息为:" + error.message); + } + userInfo.tokenExpired = userInfo.exp * 1e3; + delete userInfo.exp; + delete userInfo.iat; + return userInfo; +} +function uniIdMixin(globalProperties) { + globalProperties.uniIDHasRole = function(roleId) { + const { role } = getCurrentUserInfo(); + return role.indexOf(roleId) > -1; + }; + globalProperties.uniIDHasPermission = function(permissionId) { + const { permission } = getCurrentUserInfo(); + return this.uniIDHasRole("admin") || permission.indexOf(permissionId) > -1; + }; + globalProperties.uniIDTokenValid = function() { + const { tokenExpired } = getCurrentUserInfo(); + return tokenExpired > Date.now(); + }; +} +function initApp$1(app) { + const appConfig = app._context.config; + appConfig.errorHandler = invokeCreateErrorHandler(app, createErrorHandler); + initOptionMergeStrategies(appConfig.optionMergeStrategies); + const globalProperties = appConfig.globalProperties; + { + if (__UNI_FEATURE_UNI_CLOUD__) { + uniIdMixin(globalProperties); + } + } + { + globalProperties.$set = set; + globalProperties.$applyOptions = applyOptions; + } + { + invokeCreateVueAppHook(app); + } +} +const pageMetaKey = PolySymbol(process.env.NODE_ENV !== "production" ? "UniPageMeta" : "upm"); +function usePageMeta() { + return inject(pageMetaKey); +} +function providePageMeta(id2) { + const pageMeta = initPageMeta(id2); + provide(pageMetaKey, pageMeta); + return pageMeta; +} +function usePageRoute() { + if (__UNI_FEATURE_PAGES__) { + return useRoute(); + } + const url = location.href; + const searchPos = url.indexOf("?"); + const hashPos = url.indexOf("#", searchPos > -1 ? searchPos : 0); + let query = {}; + if (searchPos > -1) { + query = parseQuery( + url.slice(searchPos + 1, hashPos > -1 ? hashPos : url.length) + ); + } + const { meta } = __uniRoutes[0]; + const path = addLeadingSlash(meta.route); + return { + meta, + query, + path, + matched: [{ path }] + }; +} +function initPageMeta(id2) { + if (__UNI_FEATURE_PAGES__) { + return reactive( + normalizePageMeta( + JSON.parse( + JSON.stringify( + initRouteMeta( + useRoute().meta, + id2 + ) + ) + ) + ) + ); + } + return reactive( + normalizePageMeta( + JSON.parse(JSON.stringify(initRouteMeta(__uniRoutes[0].meta, id2))) + ) + ); +} +function normalizePageMeta(pageMeta) { + if (__UNI_FEATURE_PULL_DOWN_REFRESH__) { + const { enablePullDownRefresh, navigationBar } = pageMeta; + if (enablePullDownRefresh) { + const pullToRefresh = normalizePullToRefreshRpx( + extend( + { + support: true, + color: "#2BD009", + style: "circle", + height: 70, + range: 150, + offset: 0 + }, + pageMeta.pullToRefresh + ) + ); + const { type, style } = navigationBar; + if (style !== "custom" && type !== "transparent") { + pullToRefresh.offset += NAVBAR_HEIGHT + safeAreaInsets$1.top; + } + pageMeta.pullToRefresh = pullToRefresh; + } + } + if (__UNI_FEATURE_NAVIGATIONBAR__) { + const { navigationBar } = pageMeta; + const { titleSize, titleColor, backgroundColor } = navigationBar; + navigationBar.titleText = navigationBar.titleText || ""; + navigationBar.type = navigationBar.type || "default"; + navigationBar.titleSize = titleSize || "16px"; + navigationBar.titleColor = titleColor || "#ffffff"; + navigationBar.backgroundColor = backgroundColor || "#F7F7F7"; + __UNI_FEATURE_I18N_LOCALE__ && initNavigationBarI18n(navigationBar); + } + if (__UNI_FEATURE_PAGES__ && history.state) { + const type = history.state.__type__; + if ((type === "redirectTo" || type === "reLaunch") && getCurrentPages().length === 0) { + pageMeta.isEntry = true; + pageMeta.isQuit = true; + } + } + return pageMeta; +} +const screen$1 = window.screen; +const documentElement = document.documentElement; +function checkMinWidth(minWidth) { + const sizes = [ + window.outerWidth, + window.outerHeight, + screen$1.width, + screen$1.height, + documentElement.clientWidth, + documentElement.clientHeight + ]; + return Math.max.apply(null, sizes) > minWidth; +} +function getStateId() { + return history.state && history.state.__id__ || 1; +} +let tabBar; +function useTabBar() { + if (!tabBar) { + tabBar = __uniConfig.tabBar && reactive(initTabBarI18n(__uniConfig.tabBar)); + } + return tabBar; +} +const supports = window.CSS && window.CSS.supports; +function cssSupports(css) { + return supports && (supports(css) || supports.apply(window.CSS, css.split(":"))); +} +const cssVar = /* @__PURE__ */ cssSupports("--a:0"); +const cssEnv = /* @__PURE__ */ cssSupports("top:env(a)"); +const cssConstant = /* @__PURE__ */ cssSupports("top:constant(a)"); +const cssBackdropFilter = /* @__PURE__ */ cssSupports("backdrop-filter:blur(10px)"); +const SCHEMA_CSS = { + "css.var": cssVar, + "css.env": cssEnv, + "css.constant": cssConstant, + "css.backdrop-filter": cssBackdropFilter +}; +const canIUse = /* @__PURE__ */ defineSyncApi( + API_CAN_I_USE, + (schema) => { + if (hasOwn(SCHEMA_CSS, schema)) { + return SCHEMA_CSS[schema]; + } + return true; + }, + CanIUseProtocol +); +const envMethod = /* @__PURE__ */ (() => cssEnv ? "env" : cssConstant ? "constant" : "")(); +function updateCurPageCssVar(pageMeta) { + let windowTopValue = 0; + let windowBottomValue = 0; + if (__UNI_FEATURE_NAVIGATIONBAR__ && pageMeta.navigationBar.style !== "custom" && ["default", "float"].indexOf(pageMeta.navigationBar.type) > -1) { + windowTopValue = NAVBAR_HEIGHT; + } + if (__UNI_FEATURE_TABBAR__ && pageMeta.isTabBar) { + const tabBar2 = useTabBar(); + tabBar2.shown && (windowBottomValue = parseInt(tabBar2.height)); + } + updatePageCssVar({ + "--window-top": normalizeWindowTop(windowTopValue), + "--window-bottom": normalizeWindowBottom(windowBottomValue) + }); +} +function normalizeWindowTop(windowTop) { + return envMethod ? `calc(${windowTop}px + ${envMethod}(safe-area-inset-top))` : `${windowTop}px`; +} +function normalizeWindowBottom(windowBottom) { + return envMethod ? `calc(${windowBottom}px + ${envMethod}(safe-area-inset-bottom))` : `${windowBottom}px`; +} +const SEP = "$$"; +const currentPagesMap = /* @__PURE__ */ new Map(); +function pruneCurrentPages() { + currentPagesMap.forEach((page, id2) => { + if (page.$.isUnmounted) { + currentPagesMap.delete(id2); + } + }); +} +function getCurrentPagesMap() { + return currentPagesMap; +} +function getCurrentPages$1() { + const curPages = []; + const pages = currentPagesMap.values(); + for (const page of pages) { + if (page.$.__isTabBar) { + if (page.$.__isActive) { + curPages.push(page); + } + } else { + curPages.push(page); + } + } + return curPages; +} +function removeRouteCache(routeKey) { + const vnode = pageCacheMap.get(routeKey); + if (vnode) { + pageCacheMap.delete(routeKey); + routeCache.pruneCacheEntry(vnode); + } +} +function removePage(routeKey, removeRouteCaches = true) { + const pageVm = currentPagesMap.get(routeKey); + pageVm.$.__isUnload = true; + invokeHook(pageVm, ON_UNLOAD); + currentPagesMap.delete(routeKey); + removeRouteCaches && removeRouteCache(routeKey); +} +let id = /* @__PURE__ */ getStateId(); +function createPageState(type, __id__) { + return { + __id__: __id__ || ++id, + __type__: type + }; +} +function initPublicPage(route) { + const meta = usePageMeta(); + if (!__UNI_FEATURE_PAGES__) { + return initPageInternalInstance("navigateTo", __uniRoutes[0].path, {}, meta); + } + let fullPath = route.fullPath; + if (route.meta.isEntry && fullPath.indexOf(route.meta.route) === -1) { + fullPath = "/" + route.meta.route + fullPath.replace("/", ""); + } + return initPageInternalInstance("navigateTo", fullPath, {}, meta); +} +function initPage(vm) { + const route = vm.$route; + const page = initPublicPage(route); + initPageVm(vm, page); + currentPagesMap.set(normalizeRouteKey(page.path, page.id), vm); +} +function normalizeRouteKey(path, id2) { + return path + SEP + id2; +} +function useKeepAliveRoute() { + const route = useRoute(); + const routeKey = computed( + () => normalizeRouteKey("/" + route.meta.route, getStateId()) + ); + const isTabBar = computed(() => route.meta.isTabBar); + return { + routeKey, + isTabBar, + routeCache + }; +} +const pageCacheMap = /* @__PURE__ */ new Map(); +const routeCache = { + get(key) { + return pageCacheMap.get(key); + }, + set(key, value) { + pruneRouteCache(key); + pageCacheMap.set(key, value); + }, + delete(key) { + const vnode = pageCacheMap.get(key); + if (!vnode) { + return; + } + pageCacheMap.delete(key); + }, + forEach(fn) { + pageCacheMap.forEach(fn); + } +}; +function isTabBarVNode(vnode) { + return vnode.props.type === "tabBar"; +} +function pruneRouteCache(key) { + const pageId = parseInt(key.split(SEP)[1]); + if (!pageId) { + return; + } + routeCache.forEach((vnode, key2) => { + const cPageId = parseInt(key2.split(SEP)[1]); + if (cPageId && cPageId > pageId) { + if (__UNI_FEATURE_TABBAR__ && isTabBarVNode(vnode)) { + return; + } + routeCache.delete(key2); + routeCache.pruneCacheEntry(vnode); + nextTick(() => pruneCurrentPages()); + } + }); +} +function updateCurPageAttrs(pageMeta) { + const nvueDirKey = "nvue-dir-" + __uniConfig.nvue["flex-direction"]; + if (pageMeta.isNVue) { + document.body.setAttribute("nvue", ""); + document.body.setAttribute(nvueDirKey, ""); + } else { + document.body.removeAttribute("nvue"); + document.body.removeAttribute(nvueDirKey); + } +} +function onPageShow(instance2, pageMeta) { + updateBodyScopeId(instance2); + updateCurPageCssVar(pageMeta); + updateCurPageAttrs(pageMeta); + initPageScrollListener(instance2, pageMeta); +} +function onPageReady(instance2) { + const scopeId = getScopeId(instance2); + scopeId && updateCurPageBodyScopeId(scopeId); +} +function updateCurPageBodyScopeId(scopeId) { + const pageBodyEl = document.querySelector("uni-page-body"); + if (pageBodyEl) { + pageBodyEl.setAttribute(scopeId, ""); + } else if (process.env.NODE_ENV !== "production") { + console.warn("uni-page-body not found"); + } +} +function getScopeId(instance2) { + return instance2.type.__scopeId; +} +let curScopeId; +function updateBodyScopeId(instance2) { + const scopeId = getScopeId(instance2); + const { body } = document; + curScopeId && body.removeAttribute(curScopeId); + scopeId && body.setAttribute(scopeId, ""); + curScopeId = scopeId; +} +let curScrollListener; +function initPageScrollListener(instance2, pageMeta) { + document.removeEventListener("touchmove", disableScrollListener); + if (curScrollListener) { + document.removeEventListener("scroll", curScrollListener); + } + if (pageMeta.disableScroll) { + return document.addEventListener("touchmove", disableScrollListener); + } + const { onPageScroll, onReachBottom } = instance2; + const navigationBarTransparent = pageMeta.navigationBar.type === "transparent"; + if (!onPageScroll && !onReachBottom && !navigationBarTransparent) { + return; + } + const opts = {}; + const pageId = instance2.proxy.$page.id; + if (onPageScroll || navigationBarTransparent) { + opts.onPageScroll = createOnPageScroll( + pageId, + onPageScroll, + navigationBarTransparent + ); + } + if (onReachBottom) { + opts.onReachBottomDistance = pageMeta.onReachBottomDistance || ON_REACH_BOTTOM_DISTANCE; + opts.onReachBottom = () => UniViewJSBridge.publishHandler(ON_REACH_BOTTOM, {}, pageId); + } + curScrollListener = createScrollListener(opts); + requestAnimationFrame( + () => document.addEventListener("scroll", curScrollListener) + ); +} +function createOnPageScroll(pageId, onPageScroll, navigationBarTransparent) { + return (scrollTop) => { + if (onPageScroll) { + UniViewJSBridge.publishHandler(ON_PAGE_SCROLL, { scrollTop }, pageId); + } + if (navigationBarTransparent) { + UniViewJSBridge.emit(pageId + "." + ON_PAGE_SCROLL, { + scrollTop + }); + } + }; +} +function initRouter(app) { + const router = createRouter(createRouterOptions()); + app.router = router; + app.use(router); +} +const scrollBehavior = (_to, _from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } +}; +function createRouterOptions() { + return { + history: initHistory(), + strict: !!__uniConfig.router.strict, + routes: __uniRoutes, + scrollBehavior + }; +} +function removeCurrentPages(delta = 1) { + const keys = getCurrentPages$1(); + const start = keys.length - 1; + const end = start - delta; + for (let i = start; i > end; i--) { + const page = keys[i].$page; + removePage(normalizeRouteKey(page.path, page.id), false); + } +} +function initHistory() { + let { routerBase } = __uniConfig.router; + if (routerBase === "/") { + routerBase = ""; + } + const history2 = __UNI_FEATURE_ROUTER_MODE__ === "history" ? createWebHistory(routerBase) : createWebHashHistory(routerBase); + history2.listen((_to, _from, info) => { + if (info.direction === "back") { + removeCurrentPages(Math.abs(info.delta)); + } + }); + return history2; +} +const index$e = { + install(app) { + initApp$1(app); + initViewPlugin(app); + initServicePlugin(app); + if (!app.config.warnHandler) { + app.config.warnHandler = warnHandler; + } + if (__UNI_FEATURE_PAGES__) { + initRouter(app); + } + } +}; +function warnHandler(msg, instance2, trace) { + if (instance2) { + const name = instance2.$.type.name; + if ("PageMetaHead" === name) { + return; + } + const parent = instance2.$.parent; + if (parent && parent.type.name === "PageMeta") { + return; + } + } + const warnArgs = [`[Vue warn]: ${msg}`]; + if (trace.length) { + warnArgs.push(` +`, trace); + } + console.warn(...warnArgs); +} +const clazz = { class: "uni-async-loading" }; +const loadingVNode = /* @__PURE__ */ createVNode( + "i", + { class: "uni-loading" }, + null, + -1 + /* HOISTED */ +); +const AsyncLoadingComponent = /* @__PURE__ */ defineSystemComponent({ + name: "AsyncLoading", + render() { + return openBlock(), createBlock("div", clazz, [loadingVNode]); + } +}); +function reload() { + window.location.reload(); +} +const AsyncErrorComponent = /* @__PURE__ */ defineSystemComponent({ + name: "AsyncError", + setup() { + initI18nAsyncMsgsOnce(); + const { + t: t2 + } = useI18n(); + return () => createVNode("div", { + "class": "uni-async-error", + "onClick": reload + }, [t2("uni.async.error")], 8, ["onClick"]); + } +}); +let appVm; +function getApp$1() { + return appVm; +} +function initApp(vm) { + appVm = vm; + Object.defineProperty(appVm.$.ctx, "$children", { + get() { + return getCurrentPages().map((page) => page.$vm); + } + }); + const app = appVm.$.appContext.app; + if (!app.component(AsyncLoadingComponent.name)) { + app.component(AsyncLoadingComponent.name, AsyncLoadingComponent); + } + if (!app.component(AsyncErrorComponent.name)) { + app.component(AsyncErrorComponent.name, AsyncErrorComponent); + } + initAppVm(appVm); + defineGlobalData(appVm); + initService(); + initView(); +} +function wrapperComponentSetup(comp, { clone, init: init2, setup, before }) { + if (clone) { + comp = extend({}, comp); + } + before && before(comp); + const oldSetup = comp.setup; + comp.setup = (props2, ctx) => { + const instance2 = getCurrentInstance(); + init2(instance2.proxy); + const query = setup(instance2); + if (oldSetup) { + return oldSetup(query || props2, ctx); + } + }; + return comp; +} +function setupComponent(comp, options) { + if (comp && (comp.__esModule || comp[Symbol.toStringTag] === "Module")) { + return wrapperComponentSetup(comp.default, options); + } + return wrapperComponentSetup(comp, options); +} +function setupWindow(comp, id2) { + return setupComponent(comp, { + init: (vm) => { + vm.$page = { + id: id2 + }; + }, + setup(instance2) { + instance2.$pageInstance = instance2; + } + }); +} +function setupPage(comp) { + const weiboMixin = { + onShow() { + let onShareAppMessage = this.$options.onShareAppMessage; + if (onShareAppMessage && typeof onShareAppMessage === "function") { + window.weibo.sendShareMessage({ + data: onShareAppMessage.call(this) + }); + } else { + window.weibo.sendShareMessage({ + data: null + }); + } + } + }; + if (window.weibo && typeof window.weibo.sendShareMessage === "function") { + comp.mixins = [weiboMixin]; + } + if (process.env.NODE_ENV !== "production") { + comp.__mpType = "page"; + } + return setupComponent(comp, { + clone: true, + // 页面组件可能会被其他地方手动引用,比如 windows 等,需要 clone 一份新的作为页面组件 + init: initPage, + setup(instance2) { + instance2.$pageInstance = instance2; + const route = usePageRoute(); + const query = decodedQuery(route.query); + instance2.attrs.__pageQuery = query; + instance2.proxy.$page.options = query; + const pageMeta = usePageMeta(); + onBeforeMount(() => { + onPageShow(instance2, pageMeta); + }); + onMounted(() => { + onPageReady(instance2); + const { onReady } = instance2; + onReady && invokeArrayFns$1(onReady); + invokeOnTabItemTap(route); + }); + onBeforeActivate(() => { + if (!instance2.__isVisible) { + onPageShow(instance2, pageMeta); + instance2.__isVisible = true; + const { onShow } = instance2; + onShow && invokeArrayFns$1(onShow); + nextTick(() => { + invokeOnTabItemTap(route); + }); + } + }); + onBeforeDeactivate(() => { + if (instance2.__isVisible && !instance2.__isUnload) { + instance2.__isVisible = false; + const { onHide } = instance2; + onHide && invokeArrayFns$1(onHide); + } + }); + subscribeViewMethod(pageMeta.id); + onBeforeUnmount(() => { + unsubscribeViewMethod(pageMeta.id); + }); + return query; + } + }); +} +function setupApp(comp) { + if (process.env.NODE_ENV !== "production") { + comp.__mpType = "app"; + } + return setupComponent(comp, { + init: initApp, + setup(instance2) { + const route = usePageRoute(); + const onLaunch = () => { + injectAppHooks(instance2); + const { onLaunch: onLaunch2, onShow, onPageNotFound: onPageNotFound2, onError: onError2 } = instance2; + const path = route.path.slice(1); + const launchOptions2 = initLaunchOptions({ + path: path || __uniRoutes[0].meta.route, + query: decodedQuery(route.query) + }); + onLaunch2 && invokeArrayFns$1(onLaunch2, launchOptions2); + onShow && invokeArrayFns$1(onShow, launchOptions2); + if (__UNI_FEATURE_PAGES__) { + if (!route.matched.length) { + const pageNotFoundOptions = { + notFound: true, + openType: "appLaunch", + path: route.path, + query: {}, + scene: 1001 + }; + onPageNotFound2 && invokeArrayFns$1(onPageNotFound2, pageNotFoundOptions); + } + } + if (onError2) { + instance2.appContext.config.errorHandler = (err) => { + invokeArrayFns$1(onError2, err); + }; + } + }; + if (__UNI_FEATURE_PAGES__) { + useRouter().isReady().then(onLaunch); + } else { + onBeforeMount(onLaunch); + } + onMounted(() => { + window.addEventListener( + "resize", + debounce(onResize, 50, { setTimeout, clearTimeout }) + ); + window.addEventListener("message", onMessage); + document.addEventListener("visibilitychange", onVisibilityChange); + onThemeChange$2(); + }); + return route.query; + }, + before(comp2) { + comp2.mpType = "app"; + const { setup } = comp2; + const render = () => { + return openBlock(), createBlock(LayoutComponent); + }; + comp2.setup = (props2, ctx) => { + const res = setup && setup(props2, ctx); + return isFunction(res) ? render : res; + }; + comp2.render = render; + } + }); +} +function onResize() { + const { windowWidth, windowHeight, screenWidth, screenHeight } = uni.getSystemInfoSync(); + const landscape = Math.abs(Number(window.orientation)) === 90; + const deviceOrientation = landscape ? "landscape" : "portrait"; + UniServiceJSBridge.emit(ON_RESIZE, { + deviceOrientation, + size: { + windowWidth, + windowHeight, + screenWidth, + screenHeight + } + }); +} +function onMessage(evt) { + if (isPlainObject(evt.data) && evt.data.type === WEB_INVOKE_APPSERVICE) { + UniServiceJSBridge.emit( + ON_WEB_INVOKE_APP_SERVICE, + evt.data.data, + evt.data.pageId + ); + } +} +function onVisibilityChange() { + const { emit: emit2 } = UniServiceJSBridge; + if (document.visibilityState === "visible") { + emit2(ON_APP_ENTER_FOREGROUND, getEnterOptions()); + } else { + emit2(ON_APP_ENTER_BACKGROUND); + } +} +function onThemeChange$2() { + let mediaQueryList = null; + try { + mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); + } catch (error) { + } + if (mediaQueryList) { + let callback = (e2) => { + UniServiceJSBridge.emit(ON_THEME_CHANGE, { + theme: e2.matches ? "dark" : "light" + }); + }; + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener("change", callback); + } else { + mediaQueryList.addListener(callback); + } + } +} +function invokeOnTabItemTap(route) { + const { tabBarText, tabBarIndex, route: pagePath } = route.meta; + if (tabBarText) { + invokeHook("onTabItemTap", { + index: tabBarIndex, + text: tabBarText, + pagePath + }); + } +} +function formatTime(val) { + val = val > 0 && val < Infinity ? val : 0; + const h2 = Math.floor(val / 3600); + const m = Math.floor(val % 3600 / 60); + const s = Math.floor(val % 3600 % 60); + const hStr = (h2 < 10 ? "0" : "") + h2; + const mStr = (m < 10 ? "0" : "") + m; + const sStr = (s < 10 ? "0" : "") + s; + let str = mStr + ":" + sStr; + if (hStr !== "00") { + str = hStr + ":" + str; + } + return str; +} +function useGesture(props2, videoRef, fullscreenState) { + const state2 = reactive({ + gestureType: "none", + volumeOld: 0, + volumeNew: 0, + currentTimeOld: 0, + currentTimeNew: 0 + }); + const touchStartOrigin = { + x: 0, + y: 0 + }; + function onTouchstart(event) { + const toucher = event.targetTouches[0]; + touchStartOrigin.x = toucher.pageX; + touchStartOrigin.y = toucher.pageY; + state2.gestureType = "none"; + state2.volumeOld = 0; + state2.currentTimeOld = state2.currentTimeNew = 0; + } + function onTouchmove(event) { + function stop() { + event.stopPropagation(); + event.preventDefault(); + } + if (fullscreenState.fullscreen) { + stop(); + } + const gestureType = state2.gestureType; + if (gestureType === "stop") { + return; + } + const toucher = event.targetTouches[0]; + const pageX = toucher.pageX; + const pageY = toucher.pageY; + const origin = touchStartOrigin; + const video = videoRef.value; + if (gestureType === "progress") { + changeProgress(pageX - origin.x); + } else if (gestureType === "volume") { + changeVolume(pageY - origin.y); + } + if (gestureType !== "none") { + return; + } + if (Math.abs(pageX - origin.x) > Math.abs(pageY - origin.y)) { + if (!props2.enableProgressGesture) { + state2.gestureType = "stop"; + return; + } + state2.gestureType = "progress"; + state2.currentTimeOld = state2.currentTimeNew = video.currentTime; + if (!fullscreenState.fullscreen) { + stop(); + } + } else { + if (!props2.pageGesture) { + state2.gestureType = "stop"; + return; + } + state2.gestureType = "volume"; + state2.volumeOld = video.volume; + if (!fullscreenState.fullscreen) { + stop(); + } + } + } + function onTouchend(event) { + const video = videoRef.value; + if (state2.gestureType !== "none" && state2.gestureType !== "stop") { + event.stopPropagation(); + event.preventDefault(); + } + if (state2.gestureType === "progress" && state2.currentTimeOld !== state2.currentTimeNew) { + video.currentTime = state2.currentTimeNew; + } + state2.gestureType = "none"; + } + function changeProgress(x) { + const video = videoRef.value; + const duration = video.duration; + let currentTimeNew = x / 600 * duration + state2.currentTimeOld; + if (currentTimeNew < 0) { + currentTimeNew = 0; + } else if (currentTimeNew > duration) { + currentTimeNew = duration; + } + state2.currentTimeNew = currentTimeNew; + } + function changeVolume(y) { + const video = videoRef.value; + const valueOld = state2.volumeOld; + let value; + if (typeof valueOld === "number") { + value = valueOld - y / 200; + if (value < 0) { + value = 0; + } else if (value > 1) { + value = 1; + } + video.volume = value; + state2.volumeNew = value; + } + } + return { + state: state2, + onTouchstart, + onTouchmove, + onTouchend + }; +} +function useFullscreen(trigger, containerRef, videoRef, userActionState, rootRef) { + const state2 = reactive({ + fullscreen: false + }); + const isSafari = /^Apple/.test(navigator.vendor); + function onFullscreenChange($event, webkit) { + if (webkit && document.fullscreenEnabled) { + return; + } + emitFullscreenChange(!!(document.fullscreenElement || document.webkitFullscreenElement)); + } + function emitFullscreenChange(val) { + state2.fullscreen = val; + trigger("fullscreenchange", {}, { + fullScreen: val, + direction: "vertical" + }); + } + function toggleFullscreen(val) { + const root = rootRef.value; + const container = containerRef.value; + const video = videoRef.value; + let mockFullScreen; + if (val) { + if ((document.fullscreenEnabled || document.webkitFullscreenEnabled) && (!isSafari || userActionState.userAction)) { + container[document.fullscreenEnabled ? "requestFullscreen" : "webkitRequestFullscreen"](); + } else if (video.webkitEnterFullScreen) { + video.webkitEnterFullScreen(); + } else { + mockFullScreen = true; + container.remove(); + container.classList.add("uni-video-type-fullscreen"); + document.body.appendChild(container); + } + } else { + if (document.fullscreenEnabled || document.webkitFullscreenEnabled) { + if (document.fullscreenElement) { + document.exitFullscreen(); + } else if (document.webkitFullscreenElement) { + document.webkitExitFullscreen(); + } + } else if (video.webkitExitFullScreen) { + video.webkitExitFullScreen(); + } else { + mockFullScreen = true; + container.remove(); + container.classList.remove("uni-video-type-fullscreen"); + root.appendChild(container); + } + } + if (mockFullScreen) { + emitFullscreenChange(val); + } + } + function requestFullScreen() { + toggleFullscreen(true); + } + function exitFullScreen() { + toggleFullscreen(false); + } + onBeforeUnmount(exitFullScreen); + return { + state: state2, + onFullscreenChange, + emitFullscreenChange, + toggleFullscreen, + requestFullScreen, + exitFullScreen + }; +} +function useVideo(props2, attrs2, trigger) { + const videoRef = ref(null); + const src = computed(() => getRealPath(props2.src)); + const state2 = reactive({ + start: false, + src, + playing: false, + currentTime: 0, + duration: 0, + progress: 0, + buffered: 0 + }); + watch(() => src.value, () => { + state2.playing = false; + state2.currentTime = 0; + }); + watch(() => state2.buffered, (buffered) => { + trigger("progress", {}, { + buffered + }); + }); + function onDurationChange({ + target + }) { + state2.duration = target.duration; + } + function onLoadedMetadata($event) { + const initialTime = Number(props2.initialTime) || 0; + const video = $event.target; + if (initialTime > 0) { + video.currentTime = initialTime; + } + trigger("loadedmetadata", $event, { + width: video.videoWidth, + height: video.videoHeight, + duration: video.duration + }); + onProgress($event); + } + function onProgress($event) { + const video = $event.target; + const buffered = video.buffered; + if (buffered.length) { + state2.buffered = buffered.end(buffered.length - 1) / video.duration * 100; + } + } + function onWaiting($event) { + trigger("waiting", $event, {}); + } + function onVideoError($event) { + state2.playing = false; + trigger("error", $event, {}); + } + function onPlay($event) { + state2.start = true; + state2.playing = true; + trigger("play", $event, {}); + } + function onPause($event) { + state2.playing = false; + trigger("pause", $event, {}); + } + function onEnded($event) { + state2.playing = false; + trigger("ended", $event, {}); + } + function onTimeUpdate($event) { + const video = $event.target; + const currentTime = state2.currentTime = video.currentTime; + trigger("timeupdate", $event, { + currentTime, + duration: video.duration + }); + } + function toggle() { + const video = videoRef.value; + if (state2.playing) { + video.pause(); + } else { + video.play(); + } + } + function play() { + const video = videoRef.value; + state2.start = true; + video.play(); + } + function pause() { + const video = videoRef.value; + video.pause(); + } + function seek(position) { + const video = videoRef.value; + position = Number(position); + if (typeof position === "number" && !isNaN(position)) { + video.currentTime = position; + } + } + function playbackRate(rate) { + const video = videoRef.value; + video.playbackRate = rate; + } + return { + videoRef, + state: state2, + play, + pause, + seek, + playbackRate, + toggle, + onDurationChange, + onLoadedMetadata, + onProgress, + onWaiting, + onVideoError, + onPlay, + onPause, + onEnded, + onTimeUpdate + }; +} +function useControls(props2, videoState, seek) { + const progressRef = ref(null); + const ballRef = ref(null); + const centerPlayBtnShow = computed(() => props2.showCenterPlayBtn && !videoState.start); + const controlsVisible = ref(true); + const controlsShow = computed(() => !centerPlayBtnShow.value && props2.controls && controlsVisible.value); + const state2 = reactive({ + touching: false, + controlsTouching: false, + centerPlayBtnShow, + controlsShow, + controlsVisible + }); + function clickProgress(event) { + const $progress = progressRef.value; + let element = event.target; + let x = event.offsetX; + while (element && element !== $progress) { + x += element.offsetLeft; + element = element.parentNode; + } + const w = $progress.offsetWidth; + let progress = 0; + if (x >= 0 && x <= w) { + progress = x / w; + seek(videoState.duration * progress); + } + } + function toggleControls() { + state2.controlsVisible = !state2.controlsVisible; + } + let hideTiming; + function autoHideStart() { + hideTiming = setTimeout(() => { + state2.controlsVisible = false; + }, 3e3); + } + function autoHideEnd() { + if (hideTiming) { + clearTimeout(hideTiming); + hideTiming = null; + } + } + onBeforeUnmount(() => { + if (hideTiming) { + clearTimeout(hideTiming); + } + }); + watch(() => state2.controlsShow && videoState.playing && !state2.controlsTouching, (val) => { + if (val) { + autoHideStart(); + } else { + autoHideEnd(); + } + }); + watch([() => videoState.currentTime, () => { + props2.duration; + }], function updateProgress() { + if (!state2.touching) { + videoState.progress = videoState.currentTime / videoState.duration * 100; + } + }); + onMounted(() => { + const passiveOptions2 = passive(false); + let originX; + let originY; + let moveOnce = true; + let originProgress; + const ball = ballRef.value; + function touchmove2(event) { + const toucher = event.targetTouches[0]; + const pageX = toucher.pageX; + const pageY = toucher.pageY; + if (moveOnce && Math.abs(pageX - originX) < Math.abs(pageY - originY)) { + touchend(event); + return; + } + moveOnce = false; + const progressEl = progressRef.value; + const w = progressEl.offsetWidth; + let progress = originProgress + (pageX - originX) / w * 100; + if (progress < 0) { + progress = 0; + } else if (progress > 100) { + progress = 100; + } + videoState.progress = progress; + event.preventDefault(); + event.stopPropagation(); + } + function touchend(event) { + state2.controlsTouching = false; + if (state2.touching) { + ball.removeEventListener("touchmove", touchmove2, passiveOptions2); + if (!moveOnce) { + event.preventDefault(); + event.stopPropagation(); + seek(videoState.duration * videoState.progress / 100); + } + state2.touching = false; + } + } + ball.addEventListener("touchstart", (event) => { + state2.controlsTouching = true; + const toucher = event.targetTouches[0]; + originX = toucher.pageX; + originY = toucher.pageY; + originProgress = videoState.progress; + moveOnce = true; + state2.touching = true; + ball.addEventListener("touchmove", touchmove2, passiveOptions2); + }); + ball.addEventListener("touchend", touchend); + ball.addEventListener("touchcancel", touchend); + }); + return { + state: state2, + progressRef, + ballRef, + clickProgress, + toggleControls, + autoHideStart, + autoHideEnd + }; +} +function useDanmu(props2, videoState) { + const danmuRef = ref(null); + const state2 = reactive({ + enable: Boolean(props2.enableDanmu) + }); + let danmuIndex = { + time: 0, + index: -1 + }; + const danmuList = isArray(props2.danmuList) ? JSON.parse(JSON.stringify(props2.danmuList)) : []; + danmuList.sort(function(a2, b) { + return (a2.time || 0) - (b.time || 0); + }); + function toggleDanmu() { + state2.enable = !state2.enable; + } + function updateDanmu(event) { + const video = event.target; + const currentTime = video.currentTime; + const oldDanmuIndex = danmuIndex; + const newDanmuIndex = { + time: currentTime, + index: oldDanmuIndex.index + }; + if (currentTime > oldDanmuIndex.time) { + for (let index2 = oldDanmuIndex.index + 1; index2 < danmuList.length; index2++) { + const element = danmuList[index2]; + if (currentTime >= (element.time || 0)) { + newDanmuIndex.index = index2; + if (videoState.playing && state2.enable) { + playDanmu(element); + } + } else { + break; + } + } + } else if (currentTime < oldDanmuIndex.time) { + for (let index2 = oldDanmuIndex.index - 1; index2 > -1; index2--) { + const element = danmuList[index2]; + if (currentTime <= (element.time || 0)) { + newDanmuIndex.index = index2 - 1; + } else { + break; + } + } + } + danmuIndex = newDanmuIndex; + } + function playDanmu(danmu) { + const p2 = document.createElement("p"); + p2.className = "uni-video-danmu-item"; + p2.innerText = danmu.text; + let style = `bottom: ${Math.random() * 100}%;color: ${danmu.color};`; + p2.setAttribute("style", style); + const danmuEl = danmuRef.value; + danmuEl.appendChild(p2); + setTimeout(function() { + style += "left: 0;-webkit-transform: translateX(-100%);transform: translateX(-100%);"; + p2.setAttribute("style", style); + setTimeout(function() { + p2.remove(); + }, 4e3); + }, 17); + } + function sendDanmu(danmu) { + danmuList.splice(danmuIndex.index + 1, 0, { + text: String(danmu.text), + color: danmu.color, + time: videoState.currentTime || 0 + }); + } + return { + state: state2, + danmuRef, + updateDanmu, + toggleDanmu, + sendDanmu + }; +} +function useContext(play, pause, seek, sendDanmu, playbackRate, requestFullScreen, exitFullScreen) { + const methods = { + play, + pause, + seek, + sendDanmu, + playbackRate, + requestFullScreen, + exitFullScreen + }; + const id2 = useContextInfo(); + useSubscribe((type, data) => { + let options; + switch (type) { + case "seek": + options = data.position; + break; + case "sendDanmu": + options = data; + break; + case "playbackRate": + options = data.rate; + break; + } + if (type in methods) { + methods[type](options); + } + }, id2, true); +} +const props$g = { + id: { + type: String, + default: "" + }, + src: { + type: String, + default: "" + }, + duration: { + type: [Number, String], + default: "" + }, + controls: { + type: [Boolean, String], + default: true + }, + danmuList: { + type: Array, + default() { + return []; + } + }, + danmuBtn: { + type: [Boolean, String], + default: false + }, + enableDanmu: { + type: [Boolean, String], + default: false + }, + autoplay: { + type: [Boolean, String], + default: false + }, + loop: { + type: [Boolean, String], + default: false + }, + muted: { + type: [Boolean, String], + default: false + }, + objectFit: { + type: String, + default: "contain" + }, + poster: { + type: String, + default: "" + }, + direction: { + type: [String, Number], + default: "" + }, + showProgress: { + type: Boolean, + default: true + }, + initialTime: { + type: [String, Number], + default: 0 + }, + showFullscreenBtn: { + type: [Boolean, String], + default: true + }, + pageGesture: { + type: [Boolean, String], + default: false + }, + enableProgressGesture: { + type: [Boolean, String], + default: true + }, + showPlayBtn: { + type: [Boolean, String], + default: true + }, + showCenterPlayBtn: { + type: [Boolean, String], + default: true + } +}; +const index$d = /* @__PURE__ */ defineBuiltInComponent({ + name: "Video", + props: props$g, + emits: ["fullscreenchange", "progress", "loadedmetadata", "waiting", "error", "play", "pause", "ended", "timeupdate"], + setup(props2, { + emit: emit2, + attrs: attrs2, + slots + }) { + const rootRef = ref(null); + const containerRef = ref(null); + const trigger = useCustomEvent(rootRef, emit2); + const { + state: userActionState + } = useUserAction(); + const { + $attrs: videoAttrs + } = useAttrs({ + excludeListeners: true + }); + const { + t: t2 + } = useI18n(); + initI18nVideoMsgsOnce(); + const { + videoRef, + state: videoState, + play, + pause, + seek, + playbackRate, + toggle, + onDurationChange, + onLoadedMetadata, + onProgress, + onWaiting, + onVideoError, + onPlay, + onPause, + onEnded, + onTimeUpdate + } = useVideo(props2, attrs2, trigger); + const { + state: danmuState, + danmuRef, + updateDanmu, + toggleDanmu, + sendDanmu + } = useDanmu(props2, videoState); + const { + state: fullscreenState, + onFullscreenChange, + emitFullscreenChange, + toggleFullscreen, + requestFullScreen, + exitFullScreen + } = useFullscreen(trigger, containerRef, videoRef, userActionState, rootRef); + const { + state: gestureState, + onTouchstart, + onTouchend, + onTouchmove + } = useGesture(props2, videoRef, fullscreenState); + const { + state: controlsState, + progressRef, + ballRef, + clickProgress, + toggleControls + } = useControls(props2, videoState, seek); + useContext(play, pause, seek, sendDanmu, playbackRate, requestFullScreen, exitFullScreen); + return () => { + return createVNode("uni-video", { + "ref": rootRef, + "id": props2.id + }, [createVNode("div", { + "ref": containerRef, + "class": "uni-video-container", + "onTouchstart": onTouchstart, + "onTouchend": onTouchend, + "onTouchmove": onTouchmove, + "onFullscreenchange": withModifiers(onFullscreenChange, ["stop"]), + "onWebkitfullscreenchange": withModifiers(($event) => onFullscreenChange($event, true), ["stop"]) + }, [createVNode("video", mergeProps({ + "ref": videoRef, + "style": { + "object-fit": props2.objectFit + }, + "muted": !!props2.muted, + "loop": !!props2.loop, + "src": videoState.src, + "poster": props2.poster, + "autoplay": !!props2.autoplay + }, videoAttrs.value, { + "class": "uni-video-video", + "webkit-playsinline": true, + "playsinline": true, + "onClick": toggleControls, + "onDurationchange": onDurationChange, + "onLoadedmetadata": onLoadedMetadata, + "onProgress": onProgress, + "onWaiting": onWaiting, + "onError": onVideoError, + "onPlay": onPlay, + "onPause": onPause, + "onEnded": onEnded, + "onTimeupdate": (event) => { + onTimeUpdate(event); + updateDanmu(event); + }, + "onWebkitbeginfullscreen": () => emitFullscreenChange(true), + "onX5videoenterfullscreen": () => emitFullscreenChange(true), + "onWebkitendfullscreen": () => emitFullscreenChange(false), + "onX5videoexitfullscreen": () => emitFullscreenChange(false) + }), null, 16, ["muted", "loop", "src", "poster", "autoplay", "webkit-playsinline", "playsinline", "onClick", "onDurationchange", "onLoadedmetadata", "onProgress", "onWaiting", "onError", "onPlay", "onPause", "onEnded", "onTimeupdate", "onWebkitbeginfullscreen", "onX5videoenterfullscreen", "onWebkitendfullscreen", "onX5videoexitfullscreen"]), withDirectives(createVNode("div", { + "class": "uni-video-bar uni-video-bar-full", + "onClick": withModifiers(() => { + }, ["stop"]) + }, [createVNode("div", { + "class": "uni-video-controls" + }, [withDirectives(createVNode("div", { + "class": { + "uni-video-control-button": true, + "uni-video-control-button-play": !videoState.playing, + "uni-video-control-button-pause": videoState.playing + }, + "onClick": withModifiers(toggle, ["stop"]) + }, null, 10, ["onClick"]), [[vShow, props2.showPlayBtn]]), withDirectives(createVNode("div", { + "class": "uni-video-current-time" + }, [formatTime(videoState.currentTime)], 512), [[vShow, props2.showProgress]]), withDirectives(createVNode("div", { + "ref": progressRef, + "class": "uni-video-progress-container", + "onClick": withModifiers(clickProgress, ["stop"]) + }, [createVNode("div", { + "class": "uni-video-progress" + }, [createVNode("div", { + "style": { + width: videoState.buffered + "%" + }, + "class": "uni-video-progress-buffered" + }, null, 4), createVNode("div", { + "ref": ballRef, + "style": { + left: videoState.progress + "%" + }, + "class": "uni-video-ball" + }, [createVNode("div", { + "class": "uni-video-inner" + }, null)], 4)])], 8, ["onClick"]), [[vShow, props2.showProgress]]), withDirectives(createVNode("div", { + "class": "uni-video-duration" + }, [formatTime(Number(props2.duration) || videoState.duration)], 512), [[vShow, props2.showProgress]])]), withDirectives(createVNode("div", { + "class": { + "uni-video-danmu-button": true, + "uni-video-danmu-button-active": danmuState.enable + }, + "onClick": withModifiers(toggleDanmu, ["stop"]) + }, [t2("uni.video.danmu")], 10, ["onClick"]), [[vShow, props2.danmuBtn]]), withDirectives(createVNode("div", { + "class": { + "uni-video-fullscreen": true, + "uni-video-type-fullscreen": fullscreenState.fullscreen + }, + "onClick": withModifiers(() => toggleFullscreen(!fullscreenState.fullscreen), ["stop"]) + }, null, 10, ["onClick"]), [[vShow, props2.showFullscreenBtn]])], 8, ["onClick"]), [[vShow, controlsState.controlsShow]]), withDirectives(createVNode("div", { + "ref": danmuRef, + "style": "z-index: 0;", + "class": "uni-video-danmu" + }, null, 512), [[vShow, videoState.start && danmuState.enable]]), controlsState.centerPlayBtnShow && createVNode("div", { + "class": "uni-video-cover", + "onClick": withModifiers(() => { + }, ["stop"]) + }, [createVNode("div", { + "class": "uni-video-cover-play-button", + "onClick": withModifiers(play, ["stop"]) + }, null, 8, ["onClick"]), createVNode("p", { + "class": "uni-video-cover-duration" + }, [formatTime(Number(props2.duration) || videoState.duration)])], 8, ["onClick"]), createVNode("div", { + "class": { + "uni-video-toast": true, + "uni-video-toast-volume": gestureState.gestureType === "volume" + } + }, [createVNode("div", { + "class": "uni-video-toast-title" + }, [t2("uni.video.volume")]), createVNode("svg", { + "class": "uni-video-toast-icon", + "width": "200px", + "height": "200px", + "viewBox": "0 0 1024 1024", + "version": "1.1", + "xmlns": "http://www.w3.org/2000/svg" + }, [createVNode("path", { + "d": "M475.400704 201.19552l0 621.674496q0 14.856192-10.856448 25.71264t-25.71264 10.856448-25.71264-10.856448l-190.273536-190.273536-149.704704 0q-14.856192 0-25.71264-10.856448t-10.856448-25.71264l0-219.414528q0-14.856192 10.856448-25.71264t25.71264-10.856448l149.704704 0 190.273536-190.273536q10.856448-10.856448 25.71264-10.856448t25.71264 10.856448 10.856448 25.71264zm219.414528 310.837248q0 43.425792-24.28416 80.851968t-64.2816 53.425152q-5.71392 2.85696-14.2848 2.85696-14.856192 0-25.71264-10.570752t-10.856448-25.998336q0-11.999232 6.856704-20.284416t16.570368-14.2848 19.427328-13.142016 16.570368-20.284416 6.856704-32.569344-6.856704-32.569344-16.570368-20.284416-19.427328-13.142016-16.570368-14.2848-6.856704-20.284416q0-15.427584 10.856448-25.998336t25.71264-10.570752q8.57088 0 14.2848 2.85696 39.99744 15.427584 64.2816 53.139456t24.28416 81.137664zm146.276352 0q0 87.422976-48.56832 161.41824t-128.5632 107.707392q-7.428096 2.85696-14.2848 2.85696-15.427584 0-26.284032-10.856448t-10.856448-25.71264q0-22.284288 22.284288-33.712128 31.997952-16.570368 43.425792-25.141248 42.283008-30.855168 65.995776-77.423616t23.712768-99.136512-23.712768-99.136512-65.995776-77.423616q-11.42784-8.57088-43.425792-25.141248-22.284288-11.42784-22.284288-33.712128 0-14.856192 10.856448-25.71264t25.71264-10.856448q7.428096 0 14.856192 2.85696 79.99488 33.712128 128.5632 107.707392t48.56832 161.41824zm146.276352 0q0 131.42016-72.566784 241.41312t-193.130496 161.989632q-7.428096 2.85696-14.856192 2.85696-14.856192 0-25.71264-10.856448t-10.856448-25.71264q0-20.570112 22.284288-33.712128 3.999744-2.285568 12.85632-5.999616t12.85632-5.999616q26.284032-14.2848 46.854144-29.140992 70.281216-51.996672 109.707264-129.705984t39.426048-165.132288-39.426048-165.132288-109.707264-129.705984q-20.570112-14.856192-46.854144-29.140992-3.999744-2.285568-12.85632-5.999616t-12.85632-5.999616q-22.284288-13.142016-22.284288-33.712128 0-14.856192 10.856448-25.71264t25.71264-10.856448q7.428096 0 14.856192 2.85696 120.563712 51.996672 193.130496 161.989632t72.566784 241.41312z" + }, null)]), createVNode("div", { + "class": "uni-video-toast-value" + }, [createVNode("div", { + "style": { + width: gestureState.volumeNew * 100 + "%" + }, + "class": "uni-video-toast-value-content" + }, [createVNode("div", { + "class": "uni-video-toast-volume-grids" + }, [renderList(10, () => createVNode("div", { + "class": "uni-video-toast-volume-grids-item" + }, null))])], 4)])], 2), createVNode("div", { + "class": { + "uni-video-toast": true, + "uni-video-toast-progress": gestureState.gestureType === "progress" + } + }, [createVNode("div", { + "class": "uni-video-toast-title" + }, [formatTime(gestureState.currentTimeNew), " / ", formatTime(videoState.duration)])], 2), createVNode("div", { + "class": "uni-video-slots" + }, [slots.default && slots.default()])], 40, ["onTouchstart", "onTouchend", "onTouchmove", "onFullscreenchange", "onWebkitfullscreenchange"])], 8, ["id"]); + }; + } +}); +const onWebInvokeAppService = ({ name, arg }) => { + if (name === "postMessage") + ; + else { + uni[name](arg); + } +}; +const Invoke = /* @__PURE__ */ once(() => UniServiceJSBridge.on(ON_WEB_INVOKE_APP_SERVICE, onWebInvokeAppService)); +const props$f = { + src: { + type: String, + default: "" + }, + fullscreen: { + type: Boolean, + default: true + } +}; +const index$c = /* @__PURE__ */ defineBuiltInComponent({ + inheritAttrs: false, + name: "WebView", + props: props$f, + setup(props2) { + Invoke(); + const rootRef = ref(null); + const iframeRef = ref(null); + const { + $attrs, + $excludeAttrs, + $listeners + } = useAttrs({ + excludeListeners: true + }); + let _resize; + const renderIframe = () => { + const iframe = document.createElement("iframe"); + watchEffect(() => { + for (const key in $attrs.value) { + if (hasOwn($attrs.value, key)) { + const attr2 = $attrs.value[key]; + iframe[key] = attr2; + } + } + }); + watchEffect(() => { + iframe.src = getRealPath(props2.src); + }); + iframeRef.value = iframe; + _resize = useWebViewSize(rootRef, iframeRef, props2.fullscreen); + if (props2.fullscreen) { + document.body.appendChild(iframe); + } + }; + renderIframe(); + onMounted(() => { + var _a; + _resize(); + !props2.fullscreen && ((_a = rootRef.value) == null ? void 0 : _a.appendChild(iframeRef.value)); + }); + onActivated(() => { + props2.fullscreen && (iframeRef.value.style.display = "block"); + }); + onDeactivated(() => { + props2.fullscreen && (iframeRef.value.style.display = "none"); + }); + onBeforeUnmount(() => { + props2.fullscreen && document.body.removeChild(iframeRef.value); + }); + return () => { + return createVNode(Fragment, null, [createVNode("uni-web-view", mergeProps({ + "class": props2.fullscreen ? "uni-webview--fullscreen" : "" + }, $listeners.value, $excludeAttrs.value, { + "ref": rootRef + }), [createVNode(ResizeSensor, { + "onResize": _resize + }, null, 8, ["onResize"])], 16)]); + }; + } +}); +function useWebViewSize(rootRef, iframeRef, fullscreen) { + const _resize = () => { + var _a, _b; + if (fullscreen) { + const { + top, + left, + width, + height + } = rootRef.value.getBoundingClientRect(); + updateElementStyle(iframeRef.value, { + position: "absolute", + display: "block", + border: "0", + top: top + "px", + left: left + "px", + width: width + "px", + height: height + "px" + }); + } else { + updateElementStyle(iframeRef.value, { + width: ((_a = rootRef.value) == null ? void 0 : _a.style.width) || "300px", + height: ((_b = rootRef.value) == null ? void 0 : _b.style.height) || "150px" + }); + } + }; + return _resize; +} +let index$b = 0; +function getJSONP(url, options, success, error) { + var js = document.createElement("script"); + var callbackKey = options.callback || "callback"; + var callbackName = "__uni_jsonp_callback_" + index$b++; + var timeout = options.timeout || 3e4; + var timing; + function end() { + clearTimeout(timing); + delete window[callbackName]; + js.remove(); + } + window[callbackName] = (res) => { + if (isFunction(success)) { + success(res); + } + end(); + }; + js.onerror = () => { + if (isFunction(error)) { + error(); + } + end(); + }; + timing = setTimeout(function() { + if (isFunction(error)) { + error(); + } + end(); + }, timeout); + js.src = url + (url.indexOf("?") >= 0 ? "&" : "?") + callbackKey + "=" + callbackName; + document.body.appendChild(js); +} +const ICON_PATH_LOCTAION = "M13.3334375 16 q0.033125 1.1334375 0.783125 1.8834375 q0.75 0.75 1.8834375 0.75 q1.1334375 0 1.8834375 -0.75 q0.75 -0.75 0.75 -1.8834375 q0 -1.1334375 -0.75 -1.8834375 q-0.75 -0.75 -1.8834375 -0.75 q-1.1334375 0 -1.8834375 0.75 q-0.75 0.75 -0.783125 1.8834375 ZM30.9334375 14.9334375 l-1.1334375 0 q-0.5 -5.2 -4.0165625 -8.716875 q-3.516875 -3.5165625 -8.716875 -4.0165625 l0 -1.1334375 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 l0 1.1334375 q-5.2 0.5 -8.716875 4.0165625 q-3.5165625 3.516875 -4.0165625 8.716875 l-1.1334375 0 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 l1.1334375 0 q0.5 5.2 4.0165625 8.716875 q3.516875 3.5165625 8.716875 4.0165625 l0 1.1334375 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 l0 -1.1334375 q5.2 -0.5 8.716875 -4.0165625 q3.5165625 -3.516875 4.0165625 -8.716875 l1.1334375 0 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 ZM17.0665625 27.6665625 l0 -2.0665625 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 l0 2.0665625 q-4.3 -0.4665625 -7.216875 -3.383125 q-2.916875 -2.916875 -3.3834375 -7.216875 l2.0665625 0 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 l-2.0665625 0 q0.4665625 -4.3 3.3834375 -7.216875 q2.9165625 -2.916875 7.216875 -3.3834375 l0 2.0665625 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 l0 -2.0665625 q4.3 0.4665625 7.216875 3.3834375 q2.9165625 2.9165625 3.383125 7.216875 l-2.0665625 0 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 l2.0665625 0 q-0.4665625 4.3 -3.383125 7.216875 q-2.916875 2.9165625 -7.216875 3.383125 Z"; +const ICON_PATH_ORIGIN = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAACECAMAAABmmnOVAAAC01BMVEUAAAAAef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef96quGStdqStdpbnujMzMzCyM7Gyc7Ky83MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMwAef8GfP0yjfNWnOp0qOKKsdyYt9mju9aZt9mMstx1qeJYnekyjvIIfP0qivVmouaWttnMzMyat9lppOUujPQKffxhoOfNzc3Y2Njh4eHp6enu7u7y8vL19fXv7+/i4uLZ2dnOzs6auNgOf/sKff15quHR0dHx8fH9/f3////j4+N6quFdn+iywdPb29vw8PD+/v7c3NyywtLa2tr29vbS0tLd3d38/Pzf39/o6Ojc7f+q0v+HwP9rsf9dqv9Hnv9Vpv/q6urj8P+Vx/9Am/8Pgf8Iff/z8/OAvP95uf/n5+c5l//V6f+52v+y1//7+/vt7e0rkP/09PTQ0NDq9P8Whf+cy//W1tbe3t7A3v/m5ubs7OxOov/r6+vk5OQiaPjKAAAAknRSTlMACBZ9oB71/jiqywJBZATT6hBukRXv+zDCAVrkDIf4JbQsTb7eVeJLbwfa8Rh4G/OlPS/6/kxQ9/xdmZudoJxNVhng7B6wtWdzAtQOipcF1329wS44doK/BAkyP1pvgZOsrbnGXArAg34G2IsD1eMRe7bi7k5YnqFT9V0csyPedQyYD3p/Fje+hDpskq/MwpRBC6yKp2MAAAQdSURBVHja7Zn1exMxGIAPHbrhDsPdneHuNtzd3d3dIbjLh93o2o4i7TpgG1Jk0g0mMNwd/gTa5rq129reHnK5e/bk/TFNk/dJ7r5894XjGAwGg8GgTZasCpDIll1+hxw5vXLJLpEboTx5ZXbIhyzkl9fB28cqUaCgrBKFkI3CcjoUKYolihWXUSI7EihRUjaHXF52CVRKLoe8eZIdUOkyMknkRw6UlcehYAFHiXK+skgURk6Ul8OhQjFnCVRRBolKqRxQ5SzUHaqgNGSj7VCmalqJnDkoS5RF6ZCbroNvufQkUD6qEuXTdUA+3hQdqiEXVKfnUKOmK4latalJ1EEuoZZ6162HJ9x/4OChw0eOHj12/MTJU6dxG7XUu751tjNnz4ET5y9ctLZTSr0beKFLl89bpuUDrqgC1RqNWqsKuqqzNFw7e51S6u3tc+OmZUJ9kCHY6ECwOkRvab51iUrqXej2HYDQsHBjWgx3Ae7dppB6N2wEcF9jdMGDUIDGTaR2aNoM9FqjG7QmaN5CWgc/gIePjG559BigpZQOrYB/4jBfRGRUtDkmJjY6KjLCofkpD62lc2gDfMpWPIuLdwyV8XEpHgaddBZ+wBuSFcwJqSN2ovmZ/dfnOvCTxqGtwzq8SEjv4EhISn48eWgnhUP7DvDSvgzxrs6vV6+FLiro2EkCic4QKkzwJsH1KYreCp0eQhfyDl1B/w4P/xa5JVJ4U03QjbRD9x7wXlgH5IE3wmMBHXoSlugFAcI6f/AkkSi8q6HQm6xDn77wEQ8djTwSj3tqAMguRTe4ikeOQyJ4YV+KfkQl+oNW5GbY4gWOWgbwJ+kwAD6Fi90MK2ZsrIeBBCUGwRXbqJ+/iJMQliIEBhOU6AJhtlG/IpHE2bqrYQg5h6HA4yQiRqwEfkGCdTCMmMRw+IbPDCQaHCsCYAQxiZHw3TbmD/ESOHgHwShiEqPhp/gggYkSztIxxCRawy/bmEniJaJtfwiEscQkxkFgRqJESqQwwHhiEuMBp3Vm8RK/cZoHEzKXhCK2QxEPpiJe0YlKCFaKCNv/cYBNUsBRPlkJSc0U+dM7E9H0ThGJbgZT/iR7yj+VqMS06Qr4+OFm2JdCxIa8lugzkJs5K6MfxAaYPUcBpYG5khZJEkUUSb7DPCnKRfPBXj6M8FwuegoLpCgXcQszVjhbJFUJUee2hBhLoYTIcYtB57KY+opSMdVqwatSlZVj05aV//CwJLMX2DluaUcwhXm4ali2XOoLjxUrPV26zFtF4f5p0Gp310+z13BUWNvbehEXona6iAtX/zVZmtfN4WixfsNky4S6gCCVVq3RPLdfSfpv3MRRZfPoLc6Xs/5bt3EyMGzE9h07/Xft2t15z6i9+zgGg8FgMBgMBoPBYDAYDAYj8/APG67Rie8pUDsAAAAASUVORK5CYII="; +const ICON_PATH_TARGET = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAACcCAMAAAC3Fl5oAAAB3VBMVEVMaXH/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/EhL/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/Dw//AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/GRn/NTX/Dw//Fhb/AAD/AAD/AAD/GRn/GRn/Y2P/AAD/AAD/ExP/Ghr/AAD/AAD/MzP/GRn/AAD/Hh7/AAD/RUX/AAD/AAD/AAD/AAD/AAD/AAD/Dg7/AAD/HR3/Dw//FRX/SUn/AAD/////kJD/DQ3/Zmb/+/v/wMD/mJj/6en/vb3/1NT//Pz/ODj/+fn/3Nz/nJz/j4//9/f/7e3/9vb/7Oz/2Nj/x8f/Ozv/+Pj/3d3/nZ3/2dn//f3/6Oj/2tr/v7//09P/vr7/mZn/l5cdSvP3AAAAe3RSTlMAAhLiZgTb/vztB/JMRhlp6lQW86g8mQ4KFPs3UCH5U8huwlesWtTYGI7RsdVeJGfTW5rxnutLsvXWF8vQNdo6qQbuz7D4hgVIx2xtw8GC1TtZaIw0i84P98tU0/fsj7PKaAgiZZxeVfo8Z52eg1P0nESrENnjXVPUgw/uuSmDAAADsUlEQVR42u3aZ3cTRxgF4GtbYleSLdnGcsENG2ODjbExEHrvhAQCIb1Bem+QdkeuuFMNBBJIfmuOckzZI8/srHYmH3Lm+QNXK632LTvQ03Tu/IWeU/tTGTKT2n+q58L5c00wpXJd47DHEt5w47pKxLbhdLdPKb/7dBYxVLxw1GcI/2h1BcpzKNFHLX2JQ4gumaiitqpEEhEdOMJI9h5AFC3feYzI+7IF2tpSLEOqDXpObPRYFm/jCWho/4Ble7MdoT7fzhhq9yHEz28wltU1UPrJZ0wd66HwicfYvEFIfePTAP8tSLTupBHvtGJFH9bSkNrNWEHzERrT34xSH9Ogr1CijkbVAUH1KRqVqkdQAw07iIAaGlcTqI+/0LjeJJ5J0IIEnkpXMdzs4sTtW9dnZq7fuj2xOMtwVWk88RHDjBYejYvnjD8qjOpfQsUqhvj7oSjxcJIhVj3pyKqpNjYvVjQ/RrXq5YABKi3MCYm5BSrtWO5v11DlmlC4RpU1WRS9SJU7QukOVbpQ9JLu549+Dd0AUOlTbkGEuk85vxLAK5QbuytC3R2j3HoAjZSbFxrmKTcCoJdSk0LLJKV6gSaPMqNTQsvUKGW8JrxKqUWhaZFSeWyh1LTQNE2pHF6mzOy40DQ+S5mLimJcENoKlOnBWsr8KbRNUGYt5LXgd6HtD3lNQIoyN4S2G5RJIUOZm0LbTcqsBqVmhLYZSlkPsP4VWf+Rrd+m1v9o9h8Vv5p42C1R5qL1x7WRglOgVN52yfwNOBu76P+lLPoYidu23KPciIHGa07ZeIW1jvcNtI7q5vexCPGYCmf+m/Y9a3sAwQ5bI9T7ukPgPcn9GToEao+xk1OixJT+GIsvNAbx6eAgPq0xiF+KtkpYKhRXCQ8eFFcJhSWGu3rZ8jJkCM8kz9K4TUnrC6mAgzTsB9tLwQ2W15qfosQ2GrQNpZr7aczbzVjBZsvLcaC1g0bsbIVEnU8DOr6H1KDH2LwtUBi0/JII6Dxm9zUXkH+XMWzfh1Dte1i2Pe3QkC77Zel7aehpO8wyHG6Dtt0NjKxhN6I4uSli/TqJiJJDUQ4NDCURXTrXRy1XcumyD24M+AzhD1RXIIZsl/LoyZmurJHDM7s8lvB2FQ/PmPJ6PseAXP5HGMYAAC7ABbgAF+ACXIALcAEuwAW4ABfgAlyAC3ABLsAFuID/d8Cx4NEt8/byOf0wLnis8zjMq9/Kp7bWw4JOj8u8TlhRl+G/Mp2wpOX48GffvvZ1CyL4B53LAS6zb08EAAAAAElFTkSuQmCC"; +var MapType = /* @__PURE__ */ ((MapType2) => { + MapType2["QQ"] = "qq"; + MapType2["GOOGLE"] = "google"; + MapType2["AMAP"] = "AMap"; + MapType2["UNKNOWN"] = ""; + return MapType2; +})(MapType || {}); +function getMapInfo() { + if (__uniConfig.qqMapKey) { + return { + type: "qq", + key: __uniConfig.qqMapKey + }; + } + if (__uniConfig.googleMapKey) { + return { + type: "google", + key: __uniConfig.googleMapKey + }; + } + if (__uniConfig.aMapKey) { + return { + type: "AMap", + key: __uniConfig.aMapKey, + securityJsCode: __uniConfig.aMapSecurityJsCode, + serviceHost: __uniConfig.aMapServiceHost + }; + } + return { + type: "", + key: "" + }; +} +let IS_AMAP = false; +let hasGetIsAMap = false; +const getIsAMap = () => { + if (hasGetIsAMap) { + return IS_AMAP; + } else { + hasGetIsAMap = true; + return IS_AMAP = getMapInfo().type === "AMap"; + } +}; +function translateCoordinateSystem(type, coords, skip) { + const mapInfo = getMapInfo(); + const wgs84Map = [ + "google" + /* GOOGLE */ + ]; + if (type && type.toUpperCase() === "WGS84" || wgs84Map.includes(mapInfo.type) || skip) { + return Promise.resolve(coords); + } + if (mapInfo.type === "qq") { + return new Promise((resolve) => { + getJSONP( + `https://apis.map.qq.com/jsapi?qt=translate&type=1&points=${coords.longitude},${coords.latitude}&key=${mapInfo.key}&output=jsonp&pf=jsapi&ref=jsapi`, + { + callback: "cb" + }, + (res) => { + if ("detail" in res && "points" in res.detail && res.detail.points.length) { + const { lng, lat } = res.detail.points[0]; + resolve({ + longitude: lng, + latitude: lat, + altitude: coords.altitude, + accuracy: coords.accuracy, + altitudeAccuracy: coords.altitudeAccuracy, + heading: coords.heading, + speed: coords.speed + }); + } else { + resolve(coords); + } + }, + () => resolve(coords) + ); + }); + } + if (mapInfo.type === "AMap") { + return new Promise((resolve) => { + loadMaps([], () => { + window.AMap.convertFrom( + [coords.longitude, coords.latitude], + "gps", + (_, res) => { + if (res.info === "ok" && res.locations.length) { + const { lat, lng } = res.locations[0]; + resolve({ + longitude: lng, + latitude: lat, + altitude: coords.altitude, + accuracy: coords.accuracy, + altitudeAccuracy: coords.altitudeAccuracy, + heading: coords.heading, + speed: coords.speed + }); + } else { + resolve(coords); + } + } + ); + }); + }); + } + return Promise.reject(new Error("translate coordinate system faild")); +} +function createCallout(maps2) { + function onAdd() { + const div = this.div; + const panes = this.getPanes(); + panes.floatPane.appendChild(div); + } + function onRemove() { + const parentNode = this.div.parentNode; + if (parentNode) { + parentNode.removeChild(this.div); + } + } + function createAMapText() { + const option = this.option; + this.Text = new maps2.Text({ + text: option.content, + anchor: "bottom-center", + // 设置文本标记锚点 + offset: new maps2.Pixel(0, option.offsetY - 16), + style: { + padding: (option.padding || 8) + "px", + "line-height": (option.fontSize || 14) + "px", + "border-radius": (option.borderRadius || 0) + "px", + "border-color": `${option.bgColor || "#fff"} transparent transparent`, + "background-color": option.bgColor || "#fff", + "box-shadow": "0 2px 6px 0 rgba(114, 124, 245, .5)", + "text-align": "center", + "font-size": (option.fontSize || 14) + "px", + color: option.color || "#000" + }, + position: option.position + }); + const event = maps2.event || maps2.Event; + event.addListener(this.Text, "click", () => { + this.callback(); + }); + this.Text.setMap(option.map); + } + function removeAMapText() { + if (this.Text) { + this.option.map.remove(this.Text); + } + } + class Callout { + constructor(option = {}, callback) { + this.createAMapText = createAMapText; + this.removeAMapText = removeAMapText; + this.onAdd = onAdd; + this.construct = onAdd; + this.onRemove = onRemove; + this.destroy = onRemove; + this.option = option || {}; + const visible = this.visible = this.alwaysVisible = option.display === "ALWAYS"; + if (getIsAMap()) { + this.callback = callback; + if (this.visible) { + this.createAMapText(); + } + } else { + const map = option.map; + this.position = option.position; + this.index = 1; + const div = this.div = document.createElement("div"); + const divStyle = div.style; + divStyle.position = "absolute"; + divStyle.whiteSpace = "nowrap"; + divStyle.transform = "translateX(-50%) translateY(-100%)"; + divStyle.zIndex = "1"; + divStyle.boxShadow = option.boxShadow || "none"; + divStyle.display = visible ? "block" : "none"; + const triangle = this.triangle = document.createElement("div"); + triangle.setAttribute( + "style", + "position: absolute;white-space: nowrap;border-width: 4px;border-style: solid;border-color: #fff transparent transparent;border-image: initial;font-size: 12px;padding: 0px;background-color: transparent;width: 0px;height: 0px;transform: translate(-50%, 100%);left: 50%;bottom: 0;" + ); + this.setStyle(option); + div.appendChild(triangle); + if (map) { + this.setMap(map); + } + } + } + set onclick(callback) { + this.div.onclick = callback; + } + get onclick() { + return this.div.onclick; + } + setOption(option) { + this.option = option; + if (option.display === "ALWAYS") { + this.alwaysVisible = this.visible = true; + } else { + this.alwaysVisible = false; + } + if (getIsAMap()) { + if (this.visible) { + this.createAMapText(); + } + } else { + this.setPosition(option.position); + this.setStyle(option); + } + } + setStyle(option) { + const div = this.div; + const divStyle = div.style; + div.innerText = option.content || ""; + divStyle.lineHeight = (option.fontSize || 14) + "px"; + divStyle.fontSize = (option.fontSize || 14) + "px"; + divStyle.padding = (option.padding || 8) + "px"; + divStyle.color = option.color || "#000"; + divStyle.borderRadius = (option.borderRadius || 0) + "px"; + divStyle.backgroundColor = option.bgColor || "#fff"; + divStyle.marginTop = "-" + ((option.top || 0) + 5) + "px"; + this.triangle.style.borderColor = `${option.bgColor || "#fff"} transparent transparent`; + } + setPosition(position) { + this.position = position; + this.draw(); + } + draw() { + const overlayProjection = this.getProjection(); + if (!this.position || !this.div || !overlayProjection) { + return; + } + const pixel = overlayProjection.fromLatLngToDivPixel( + this.position + ); + const divStyle = this.div.style; + divStyle.left = pixel.x + "px"; + divStyle.top = pixel.y + "px"; + } + changed() { + const divStyle = this.div.style; + divStyle.display = this.visible ? "block" : "none"; + } + } + if (!getIsAMap()) { + const overlay = new (maps2.OverlayView || maps2.Overlay)(); + Callout.prototype.setMap = overlay.setMap; + Callout.prototype.getMap = overlay.getMap; + Callout.prototype.getPanes = overlay.getPanes; + Callout.prototype.getProjection = overlay.getProjection; + Callout.prototype.map_changed = overlay.map_changed; + Callout.prototype.set = overlay.set; + Callout.prototype.get = overlay.get; + Callout.prototype.setOptions = overlay.setValues; + Callout.prototype.bindTo = overlay.bindTo; + Callout.prototype.bindsTo = overlay.bindsTo; + Callout.prototype.notify = overlay.notify; + Callout.prototype.setValues = overlay.setValues; + Callout.prototype.unbind = overlay.unbind; + Callout.prototype.unbindAll = overlay.unbindAll; + Callout.prototype.addListener = overlay.addListener; + } + return Callout; +} +let maps; +const callbacksMap = {}; +const GOOGLE_MAP_CALLBACKNAME = "__map_callback__"; +function loadMaps(libraries, callback) { + const mapInfo = getMapInfo(); + if (!mapInfo.key) { + console.error("Map key not configured."); + return; + } + const callbacks2 = callbacksMap[mapInfo.type] = callbacksMap[mapInfo.type] || []; + if (maps) { + callback(maps); + } else if (window[mapInfo.type] && window[mapInfo.type].maps) { + maps = getIsAMap() ? window[mapInfo.type] : window[mapInfo.type].maps; + maps.Callout = maps.Callout || createCallout(maps); + callback(maps); + } else if (callbacks2.length) { + callbacks2.push(callback); + } else { + callbacks2.push(callback); + const globalExt = window; + const callbackName = GOOGLE_MAP_CALLBACKNAME + mapInfo.type; + globalExt[callbackName] = function() { + delete globalExt[callbackName]; + maps = getIsAMap() ? window[mapInfo.type] : window[mapInfo.type].maps; + maps.Callout = createCallout(maps); + callbacks2.forEach((callback2) => callback2(maps)); + callbacks2.length = 0; + }; + if (getIsAMap()) { + handleAMapSecurityPolicy(mapInfo); + } + const script = document.createElement("script"); + let src = getScriptBaseUrl(mapInfo.type); + if (mapInfo.type === MapType.QQ) { + libraries.push("geometry"); + } + if (libraries.length) { + src += `libraries=${libraries.join("%2C")}&`; + } + script.src = `${src}key=${mapInfo.key}&callback=${callbackName}`; + script.onerror = function() { + console.error("Map load failed."); + }; + document.body.appendChild(script); + } +} +const getScriptBaseUrl = (mapType) => { + const urlMap = { + qq: "https://map.qq.com/api/js?v=2.exp&", + google: "https://maps.googleapis.com/maps/api/js?", + AMap: "https://webapi.amap.com/maps?v=2.0&" + }; + return urlMap[mapType]; +}; +function handleAMapSecurityPolicy(mapInfo) { + window._AMapSecurityConfig = { + securityJsCode: mapInfo.securityJsCode || "", + serviceHost: mapInfo.serviceHost || "" + }; +} +const props$e = { + id: { + type: [Number, String], + default: "" + }, + latitude: { + type: [Number, String], + require: true + }, + longitude: { + type: [Number, String], + require: true + }, + title: { + type: String, + default: "" + }, + iconPath: { + type: String, + require: true + }, + rotate: { + type: [Number, String], + default: 0 + }, + alpha: { + type: [Number, String], + default: 1 + }, + width: { + type: [Number, String], + default: "" + }, + height: { + type: [Number, String], + default: "" + }, + callout: { + type: Object, + default: null + }, + label: { + type: Object, + default: null + }, + anchor: { + type: Object, + default: null + }, + clusterId: { + type: [Number, String], + default: "" + }, + customCallout: { + type: Object, + default: null + }, + ariaLabel: { + type: String, + default: "" + } +}; +function useMarkerLabelStyle(id2) { + const className = "uni-map-marker-label-" + id2; + const styleEl = document.createElement("style"); + styleEl.id = className; + document.head.appendChild(styleEl); + onUnmounted(() => { + styleEl.remove(); + }); + return function updateMarkerLabelStyle(style) { + const newStyle = Object.assign({}, style, { + position: "absolute", + top: "70px", + borderStyle: "solid" + }); + const div = document.createElement("div"); + Object.keys(newStyle).forEach((key) => { + div.style[key] = newStyle[key] || ""; + }); + styleEl.innerText = `.${className}{${div.getAttribute("style")}}`; + return className; + }; +} +const MapMarker = /* @__PURE__ */ defineSystemComponent({ + name: "MapMarker", + props: props$e, + setup(props2) { + const id2 = String(!isNaN(Number(props2.id)) ? props2.id : ""); + const onMapReady = inject("onMapReady"); + const updateMarkerLabelStyle = useMarkerLabelStyle(id2); + let marker; + function removeMarker() { + if (marker) { + if (marker.label && "setMap" in marker.label) { + marker.label.setMap(null); + } + if (marker.callout) { + removeMarkerCallout(marker.callout); + } + marker.setMap(null); + } + } + function removeMarkerCallout(callout) { + if (getIsAMap()) { + callout.removeAMapText(); + } else { + callout.setMap(null); + } + } + onMapReady((map, maps2, trigger) => { + function updateMarker(option) { + const title = option.title; + const position = getIsAMap() ? new maps2.LngLat(option.longitude, option.latitude) : new maps2.LatLng(option.latitude, option.longitude); + const img = new Image(); + let imgHeight = 0; + img.onload = () => { + const anchor = option.anchor || {}; + let icon; + let w; + let h2; + let top; + let x = typeof anchor.x === "number" ? anchor.x : 0.5; + let y = typeof anchor.y === "number" ? anchor.y : 1; + if (option.iconPath && (option.width || option.height)) { + w = option.width || img.width / img.height * option.height; + h2 = option.height || img.height / img.width * option.width; + } else { + w = img.width / 2; + h2 = img.height / 2; + } + imgHeight = h2; + top = h2 - (h2 - y * h2); + if ("MarkerImage" in maps2) { + icon = new maps2.MarkerImage(img.src, null, null, new maps2.Point(x * w, y * h2), new maps2.Size(w, h2)); + } else if ("Icon" in maps2) { + icon = new maps2.Icon({ + image: img.src, + size: new maps2.Size(w, h2), + imageSize: new maps2.Size(w, h2), + imageOffset: new maps2.Pixel(x * w, y * h2) + }); + } else { + icon = { + url: img.src, + anchor: new maps2.Point(x, y), + size: new maps2.Size(w, h2) + }; + } + marker.setPosition(position); + marker.setIcon(icon); + if ("setRotation" in marker) { + marker.setRotation(option.rotate || 0); + } + const labelOpt = option.label || {}; + if ("label" in marker) { + marker.label.setMap(null); + delete marker.label; + } + let label; + if (labelOpt.content) { + const labelStyle = { + borderColor: labelOpt.borderColor, + borderWidth: (Number(labelOpt.borderWidth) || 0) + "px", + padding: (Number(labelOpt.padding) || 0) + "px", + borderRadius: (Number(labelOpt.borderRadius) || 0) + "px", + backgroundColor: labelOpt.bgColor, + color: labelOpt.color, + fontSize: (labelOpt.fontSize || 14) + "px", + lineHeight: (labelOpt.fontSize || 14) + "px", + marginLeft: (Number(labelOpt.anchorX || labelOpt.x) || 0) + "px", + marginTop: (Number(labelOpt.anchorY || labelOpt.y) || 0) + "px" + }; + if ("Label" in maps2) { + label = new maps2.Label({ + position, + map, + clickable: false, + content: labelOpt.content, + style: labelStyle + }); + marker.label = label; + } else if ("setLabel" in marker) { + if (getIsAMap()) { + const content = `
+ ${labelOpt.content} +
`; + marker.setLabel({ + content, + direction: "bottom-right" + }); + } else { + const className = updateMarkerLabelStyle(labelStyle); + marker.setLabel({ + text: labelOpt.content, + color: labelStyle.color, + fontSize: labelStyle.fontSize, + className + }); + } + } + } + const calloutOpt = option.callout || {}; + let callout = marker.callout; + let calloutStyle; + if (calloutOpt.content || title) { + if (getIsAMap() && calloutOpt.content) { + calloutOpt.content = calloutOpt.content.replaceAll("\n", "
"); + } + const boxShadow = "0px 0px 3px 1px rgba(0,0,0,0.5)"; + let offsetY = -imgHeight / 2; + if (option.width || option.height) { + offsetY += 14 - imgHeight / 2; + } + calloutStyle = calloutOpt.content ? { + position, + map, + top, + // handle AMap callout offset + offsetY, + content: calloutOpt.content, + color: calloutOpt.color, + fontSize: calloutOpt.fontSize, + borderRadius: calloutOpt.borderRadius, + bgColor: calloutOpt.bgColor, + padding: calloutOpt.padding, + boxShadow: calloutOpt.boxShadow || boxShadow, + display: calloutOpt.display + } : { + position, + map, + top, + // handle AMap callout offset + offsetY, + content: title, + boxShadow + }; + if (callout) { + callout.setOption(calloutStyle); + } else { + if (getIsAMap()) { + const callback = (id3) => { + if (id3 !== "") { + trigger("callouttap", {}, { + markerId: Number(id3) + }); + } + }; + callout = marker.callout = new maps2.Callout(calloutStyle, callback); + } else { + callout = marker.callout = new maps2.Callout(calloutStyle); + callout.div.onclick = function($event) { + if (id2 !== "") { + trigger("callouttap", $event, { + markerId: Number(id2) + }); + } + $event.stopPropagation(); + $event.preventDefault(); + }; + if (getMapInfo().type === MapType.GOOGLE) { + callout.div.ontouchstart = function($event) { + $event.stopPropagation(); + }; + callout.div.onpointerdown = function($event) { + $event.stopPropagation(); + }; + } + } + } + } else { + if (callout) { + removeMarkerCallout(callout); + delete marker.callout; + } + } + }; + if (option.iconPath) { + img.src = getRealPath(option.iconPath); + } else { + console.error("Marker.iconPath is required."); + } + } + function addMarker(props3) { + marker = new maps2.Marker({ + map, + flat: true, + autoRotation: false + }); + updateMarker(props3); + const MapsEvent = maps2.event || maps2.Event; + MapsEvent.addListener(marker, "click", () => { + const callout = marker.callout; + if (callout && !callout.alwaysVisible) { + if (getIsAMap()) { + callout.visible = !callout.visible; + if (callout.visible) { + marker.callout.createAMapText(); + } else { + marker.callout.removeAMapText(); + } + } else { + callout.set("visible", !callout.visible); + if (callout.visible) { + const div = callout.div; + const parent = div.parentNode; + parent.removeChild(div); + parent.appendChild(div); + } + } + } + if (id2) { + trigger("markertap", {}, { + markerId: Number(id2), + latitude: props3.latitude, + longitude: props3.longitude + }); + } + }); + } + addMarker(props2); + watch(props2, updateMarker); + }); + if (id2) { + const addMapChidlContext = inject("addMapChidlContext"); + const removeMapChidlContext = inject("removeMapChidlContext"); + const context = { + id: id2, + translate(data) { + onMapReady((map, maps2, trigger) => { + const destination = data.destination; + const duration = data.duration; + const autoRotate = !!data.autoRotate; + let rotate = Number(data.rotate) || 0; + let rotation = 0; + if ("getRotation" in marker) { + rotation = marker.getRotation(); + } + const a2 = marker.getPosition(); + const b = new maps2.LatLng(destination.latitude, destination.longitude); + const distance2 = maps2.geometry.spherical.computeDistanceBetween(a2, b) / 1e3; + const time = (typeof duration === "number" ? duration : 1e3) / (1e3 * 60 * 60); + const speed = distance2 / time; + const MapsEvent = maps2.event || maps2.Event; + const movingEvent = MapsEvent.addListener(marker, "moving", (e2) => { + const latLng = e2.latLng; + const label = marker.label; + if (label) { + label.setPosition(latLng); + } + const callout = marker.callout; + if (callout) { + callout.setPosition(latLng); + } + }); + const event = MapsEvent.addListener(marker, "moveend", () => { + event.remove(); + movingEvent.remove(); + marker.lastPosition = a2; + marker.setPosition(b); + const label = marker.label; + if (label) { + label.setPosition(b); + } + const callout = marker.callout; + if (callout) { + callout.setPosition(b); + } + const cb = data.animationEnd; + if (isFunction(cb)) { + cb(); + } + }); + let lastRtate = 0; + if (autoRotate) { + if (marker.lastPosition) { + lastRtate = maps2.geometry.spherical.computeHeading(marker.lastPosition, a2); + } + rotate = maps2.geometry.spherical.computeHeading(a2, b) - lastRtate; + } + if ("setRotation" in marker) { + marker.setRotation(rotation + rotate); + } + if ("moveTo" in marker) { + marker.moveTo(b, speed); + } else { + marker.setPosition(b); + MapsEvent.trigger(marker, "moveend", {}); + } + }); + } + }; + addMapChidlContext(context); + onUnmounted(() => removeMapChidlContext(context)); + } + onUnmounted(removeMarker); + return () => { + return null; + }; + } +}); +function hexToRgba(hex) { + if (!hex) { + return { + r: 0, + g: 0, + b: 0, + a: 0 + }; + } + let tmpHex = hex.slice(1); + const tmpHexLen = tmpHex.length; + if (![3, 4, 6, 8].includes(tmpHexLen)) { + return { + r: 0, + g: 0, + b: 0, + a: 0 + }; + } + if (tmpHexLen === 3 || tmpHexLen === 4) { + tmpHex = tmpHex.replace(/(\w{1})/g, "$1$1"); + } + let [sr, sg, sb, sa] = tmpHex.match(/(\w{2})/g); + const r = parseInt(sr, 16), g2 = parseInt(sg, 16), b = parseInt(sb, 16); + if (!sa) { + return { r, g: g2, b, a: 1 }; + } + return { + r, + g: g2, + b, + a: (`0x100${sa}` - 65536) / 255 + }; +} +const props$d = { + points: { + type: Array, + require: true + }, + color: { + type: String, + default: "#000000" + }, + width: { + type: [Number, String], + default: "" + }, + dottedLine: { + type: [Boolean, String], + default: false + }, + arrowLine: { + type: [Boolean, String], + default: false + }, + arrowIconPath: { + type: String, + default: "" + }, + borderColor: { + type: String, + default: "#000000" + }, + borderWidth: { + type: [Number, String], + default: "" + }, + colorList: { + type: Array, + default() { + return []; + } + }, + level: { + type: String, + default: "" + } +}; +const MapPolyline = /* @__PURE__ */ defineSystemComponent({ + name: "MapPolyline", + props: props$d, + setup(props2) { + const onMapReady = inject("onMapReady"); + let polyline; + let polylineBorder; + function removePolyline() { + if (polyline) { + polyline.setMap(null); + } + if (polylineBorder) { + polylineBorder.setMap(null); + } + } + onMapReady((map, maps2) => { + function updatePolyline(option) { + removePolyline(); + addPolyline(option); + } + function addPolyline(option) { + const path = []; + option.points.forEach((point) => { + const pointPosition = getIsAMap() ? [point.longitude, point.latitude] : new maps2.LatLng(point.latitude, point.longitude); + path.push(pointPosition); + }); + const strokeWeight = Number(option.width) || 1; + const { + r: sr, + g: sg, + b: sb, + a: sa + } = hexToRgba(option.color); + const { + r: br, + g: bg, + b: bb, + a: ba + } = hexToRgba(option.borderColor); + const polylineOptions = { + map, + clickable: false, + path, + strokeWeight, + strokeColor: option.color || void 0, + strokeDashStyle: option.dottedLine ? "dash" : "solid" + }; + const borderWidth = Number(option.borderWidth) || 0; + const polylineBorderOptions = { + map, + clickable: false, + path, + strokeWeight: strokeWeight + borderWidth * 2, + strokeColor: option.borderColor || void 0, + strokeDashStyle: option.dottedLine ? "dash" : "solid" + }; + if ("Color" in maps2) { + polylineOptions.strokeColor = new maps2.Color(sr, sg, sb, sa); + polylineBorderOptions.strokeColor = new maps2.Color(br, bg, bb, ba); + } else { + polylineOptions.strokeColor = `rgb(${sr}, ${sg}, ${sb})`; + polylineOptions.strokeOpacity = sa; + polylineBorderOptions.strokeColor = `rgb(${br}, ${bg}, ${bb})`; + polylineBorderOptions.strokeOpacity = ba; + } + if (borderWidth) { + polylineBorder = new maps2.Polyline(polylineBorderOptions); + } + polyline = new maps2.Polyline(polylineOptions); + } + addPolyline(props2); + watch(props2, updatePolyline); + }); + onUnmounted(removePolyline); + return () => { + return null; + }; + } +}); +const props$c = { + latitude: { + type: [Number, String], + require: true + }, + longitude: { + type: [Number, String], + require: true + }, + color: { + type: String, + default: "#000000" + }, + fillColor: { + type: String, + default: "#00000000" + }, + radius: { + type: [Number, String], + require: true + }, + strokeWidth: { + type: [Number, String], + default: "" + }, + level: { + type: String, + default: "" + } +}; +const MapCircle = /* @__PURE__ */ defineSystemComponent({ + name: "MapCircle", + props: props$c, + setup(props2) { + const onMapReady = inject("onMapReady"); + let circle; + function removeCircle() { + if (circle) { + circle.setMap(null); + } + } + onMapReady((map, maps2) => { + function updateCircle(option) { + removeCircle(); + addCircle(option); + } + function addCircle(option) { + const center = getIsAMap() ? [option.longitude, option.latitude] : new maps2.LatLng(option.latitude, option.longitude); + const circleOptions = { + map, + center, + clickable: false, + radius: option.radius, + strokeWeight: Number(option.strokeWidth) || 1, + strokeDashStyle: "solid" + }; + if (getIsAMap()) { + circleOptions.strokeColor = option.color; + circleOptions.fillColor = option.fillColor || "#000"; + circleOptions.fillOpacity = 1; + } else { + const { + r: fr, + g: fg, + b: fb, + a: fa + } = hexToRgba(option.fillColor); + const { + r: sr, + g: sg, + b: sb, + a: sa + } = hexToRgba(option.color); + if ("Color" in maps2) { + circleOptions.fillColor = new maps2.Color(fr, fg, fb, fa); + circleOptions.strokeColor = new maps2.Color(sr, sg, sb, sa); + } else { + circleOptions.fillColor = `rgb(${fr}, ${fg}, ${fb})`; + circleOptions.fillOpacity = fa; + circleOptions.strokeColor = `rgb(${sr}, ${sg}, ${sb})`; + circleOptions.strokeOpacity = sa; + } + } + circle = new maps2.Circle(circleOptions); + if (getIsAMap()) { + map.add(circle); + } + } + addCircle(props2); + watch(props2, updateCircle); + }); + onUnmounted(removeCircle); + return () => { + return null; + }; + } +}); +const props$b = { + id: { + type: [Number, String], + default: "" + }, + position: { + type: Object, + required: true + }, + iconPath: { + type: String, + required: true + }, + clickable: { + type: [Boolean, String], + default: "" + }, + trigger: { + type: Function, + required: true + } +}; +const MapControl = /* @__PURE__ */ defineSystemComponent({ + name: "MapControl", + props: props$b, + setup(props2) { + const imgPath = computed(() => getRealPath(props2.iconPath)); + const positionStyle = computed(() => { + let positionStyle2 = `top:${props2.position.top || 0}px;left:${props2.position.left || 0}px;`; + if (props2.position.width) { + positionStyle2 += `width:${props2.position.width}px;`; + } + if (props2.position.height) { + positionStyle2 += `height:${props2.position.height}px;`; + } + return positionStyle2; + }); + const handleClick = ($event) => { + if (props2.clickable) { + props2.trigger("controltap", $event, { + controlId: props2.id + }); + } + }; + return () => { + return createVNode("div", { + "class": "uni-map-control" + }, [createVNode("img", { + "src": imgPath.value, + "style": positionStyle.value, + "class": "uni-map-control-icon", + "onClick": handleClick + }, null, 12, ["src", "onClick"])]); + }; + } +}); +const initInnerAudioContextEventOnce = /* @__PURE__ */ once(() => { + innerAudioContextEventNames.forEach((eventName) => { + InnerAudioContext.prototype[eventName] = function(callback) { + if (isFunction(callback)) { + this._events[eventName].push(callback); + } + }; + }); + innerAudioContextOffEventNames.forEach((eventName) => { + InnerAudioContext.prototype[eventName] = function(callback) { + var handle = this._events[eventName.replace("off", "on")]; + var index2 = handle.indexOf(callback); + if (index2 >= 0) { + handle.splice(index2, 1); + } + }; + }); +}); +class InnerAudioContext { + /** + * 音频上下文初始化 + */ + constructor() { + this._src = ""; + var audio = this._audio = new Audio(); + this._stoping = false; + const propertys = [ + "src", + "autoplay", + "loop", + "duration", + "currentTime", + "paused", + "volume" + ]; + propertys.forEach((property) => { + Object.defineProperty(this, property, { + set: property === "src" ? (src) => { + audio.src = getRealPath(src); + this._src = src; + return src; + } : (val) => { + audio[property] = val; + return val; + }, + get: property === "src" ? () => { + return this._src; + } : () => { + return audio[property]; + } + }); + }); + this.startTime = 0; + Object.defineProperty(this, "obeyMuteSwitch", { + set: () => false, + get: () => false + }); + Object.defineProperty(this, "buffered", { + get() { + var buffered = audio.buffered; + if (buffered.length) { + return buffered.end(buffered.length - 1); + } else { + return 0; + } + } + }); + this._events = {}; + innerAudioContextEventNames.forEach((eventName) => { + this._events[eventName] = []; + }); + audio.addEventListener("loadedmetadata", () => { + var startTime = Number(this.startTime) || 0; + if (startTime > 0) { + audio.currentTime = startTime; + } + }); + var stopEventNames = ["canplay", "pause", "seeking", "seeked", "timeUpdate"]; + var eventNames = stopEventNames.concat([ + "play", + "ended", + "error", + "waiting" + ]); + eventNames.forEach((eventName) => { + audio.addEventListener( + eventName.toLowerCase(), + () => { + if (this._stoping && stopEventNames.indexOf(eventName) >= 0) { + return; + } + const EventName = `on${eventName.slice(0, 1).toUpperCase()}${eventName.slice(1)}`; + this._events[EventName].forEach((callback) => { + callback(); + }); + }, + false + ); + }); + initInnerAudioContextEventOnce(); + } + /** + * 播放 + */ + play() { + this._stoping = false; + this._audio.play(); + } + /** + * 暂停 + */ + pause() { + this._audio.pause(); + } + /** + * 停止 + */ + stop() { + this._stoping = true; + this._audio.pause(); + this._audio.currentTime = 0; + this._events.onStop.forEach((callback) => { + callback(); + }); + } + /** + * 跳转到 + * @param {number} position + */ + seek(position) { + this._stoping = false; + position = Number(position); + if (typeof position === "number" && !isNaN(position)) { + this._audio.currentTime = position; + } + } + /** + * 销毁 + */ + destroy() { + this.stop(); + } +} +const createInnerAudioContext = /* @__PURE__ */ defineSyncApi( + API_CREATE_INNER_AUDIO_CONTEXT, + () => { + return new InnerAudioContext(); + } +); +const makePhoneCall = /* @__PURE__ */ defineAsyncApi( + API_MAKE_PHONE_CALL, + ({ phoneNumber }, { resolve }) => { + window.location.href = `tel:${phoneNumber}`; + return resolve(); + }, + MakePhoneCallProtocol +); +const UUID_KEY = "__DC_STAT_UUID"; +const storage = navigator.cookieEnabled && (window.localStorage || window.sessionStorage) || {}; +let deviceId; +function deviceId$1() { + deviceId = deviceId || storage[UUID_KEY]; + if (!deviceId) { + deviceId = Date.now() + "" + Math.floor(Math.random() * 1e7); + try { + storage[UUID_KEY] = deviceId; + } catch (error) { + } + } + return deviceId; +} +function IEVersion() { + const userAgent = navigator.userAgent; + const isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; + const isEdge = userAgent.indexOf("Edge") > -1 && !isIE; + const isIE11 = userAgent.indexOf("Trident") > -1 && userAgent.indexOf("rv:11.0") > -1; + if (isIE) { + const reIE = new RegExp("MSIE (\\d+\\.\\d+);"); + reIE.test(userAgent); + const fIEVersion = parseFloat(RegExp.$1); + if (fIEVersion > 6) { + return fIEVersion; + } else { + return 6; + } + } else if (isEdge) { + return -1; + } else if (isIE11) { + return 11; + } else { + return -1; + } +} +function getTheme() { + if (__uniConfig.darkmode !== true) + return isString(__uniConfig.darkmode) ? __uniConfig.darkmode : "light"; + try { + return window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark"; + } catch (error) { + return "light"; + } +} +function getBrowserInfo() { + let osname; + let osversion = "0"; + let model = ""; + let deviceType = "phone"; + const language = navigator.language; + if (isIOS$1) { + osname = "iOS"; + const osversionFind = ua.match(/OS\s([\w_]+)\slike/); + if (osversionFind) { + osversion = osversionFind[1].replace(/_/g, "."); + } + const modelFind = ua.match(/\(([a-zA-Z]+);/); + if (modelFind) { + model = modelFind[1]; + } + } else if (isAndroid) { + osname = "Android"; + const osversionFind = ua.match(/Android[\s/]([\w\.]+)[;\s]/); + if (osversionFind) { + osversion = osversionFind[1]; + } + const infoFind = ua.match(/\((.+?)\)/); + const infos = infoFind ? infoFind[1].split(";") : ua.split(" "); + const otherInfo = [ + /\bAndroid\b/i, + /\bLinux\b/i, + /\bU\b/i, + /^\s?[a-z][a-z]$/i, + /^\s?[a-z][a-z]-[a-z][a-z]$/i, + /\bwv\b/i, + /\/[\d\.,]+$/, + /^\s?[\d\.,]+$/, + /\bBrowser\b/i, + /\bMobile\b/i + ]; + for (let i = 0; i < infos.length; i++) { + const info = infos[i]; + if (info.indexOf("Build") > 0) { + model = info.split("Build")[0].trim(); + break; + } + let other; + for (let o2 = 0; o2 < otherInfo.length; o2++) { + if (otherInfo[o2].test(info)) { + other = true; + break; + } + } + if (!other) { + model = info.trim(); + break; + } + } + } else if (isIPadOS) { + model = "iPad"; + osname = "iOS"; + deviceType = "pad"; + osversion = isFunction(window.BigInt) ? "14.0" : "13.0"; + } else if (isWindows || isMac || isLinux) { + model = "PC"; + osname = "PC"; + deviceType = "pc"; + osversion = "0"; + let osversionFind = ua.match(/\((.+?)\)/)[1]; + if (isWindows) { + osname = "Windows"; + switch (isWindows[1]) { + case "5.1": + osversion = "XP"; + break; + case "6.0": + osversion = "Vista"; + break; + case "6.1": + osversion = "7"; + break; + case "6.2": + osversion = "8"; + break; + case "6.3": + osversion = "8.1"; + break; + case "10.0": + osversion = "10"; + break; + } + const framework = osversionFind && osversionFind.match(/[Win|WOW]([\d]+)/); + if (framework) { + osversion += ` x${framework[1]}`; + } + } else if (isMac) { + osname = "macOS"; + const _osversion = osversionFind && osversionFind.match(/Mac OS X (.+)/) || ""; + if (osversion) { + osversion = _osversion[1].replace(/_/g, "."); + if (osversion.indexOf(";") !== -1) { + osversion = osversion.split(";")[0]; + } + } + } else if (isLinux) { + osname = "Linux"; + const _osversion = osversionFind && osversionFind.match(/Linux (.*)/) || ""; + if (_osversion) { + osversion = _osversion[1]; + if (osversion.indexOf(";") !== -1) { + osversion = osversion.split(";")[0]; + } + } + } + } else { + osname = "Other"; + osversion = "0"; + deviceType = "unknown"; + } + const system = `${osname} ${osversion}`; + const platform = osname.toLocaleLowerCase(); + let browserName = ""; + let browserVersion = String(IEVersion()); + if (browserVersion !== "-1") { + browserName = "IE"; + } else { + const browseVendors = ["Version", "Firefox", "Chrome", "Edge{0,1}"]; + const vendors = ["Safari", "Firefox", "Chrome", "Edge"]; + for (let index2 = 0; index2 < browseVendors.length; index2++) { + const vendor = browseVendors[index2]; + const reg = new RegExp(`(${vendor})/(\\S*)\\b`); + if (reg.test(ua)) { + browserName = vendors[index2]; + browserVersion = ua.match(reg)[2]; + } + } + } + let deviceOrientation = "portrait"; + const orientation = typeof window.screen.orientation === "undefined" ? window.orientation : window.screen.orientation.angle; + deviceOrientation = Math.abs(orientation) === 90 ? "landscape" : "portrait"; + return { + deviceBrand: void 0, + brand: void 0, + deviceModel: model, + deviceOrientation, + model, + system, + platform, + browserName: browserName.toLocaleLowerCase(), + browserVersion, + language, + deviceType, + ua, + osname, + osversion, + theme: getTheme() + }; +} +const getWindowInfo = /* @__PURE__ */ defineSyncApi( + "getWindowInfo", + () => { + const pixelRatio2 = window.devicePixelRatio; + const screenFix = getScreenFix(); + const landscape = isLandscape(screenFix); + const screenWidth = getScreenWidth(screenFix, landscape); + const screenHeight = getScreenHeight(screenFix, landscape); + const windowWidth = getWindowWidth(screenWidth); + let windowHeight = window.innerHeight; + const statusBarHeight = safeAreaInsets$1.top; + const safeArea = { + left: safeAreaInsets$1.left, + right: windowWidth - safeAreaInsets$1.right, + top: safeAreaInsets$1.top, + bottom: windowHeight - safeAreaInsets$1.bottom, + width: windowWidth - safeAreaInsets$1.left - safeAreaInsets$1.right, + height: windowHeight - safeAreaInsets$1.top - safeAreaInsets$1.bottom + }; + const { top: windowTop, bottom: windowBottom } = getWindowOffset(); + windowHeight -= windowTop; + windowHeight -= windowBottom; + return { + windowTop, + windowBottom, + windowWidth, + windowHeight, + pixelRatio: pixelRatio2, + screenWidth, + screenHeight, + statusBarHeight, + safeArea, + safeAreaInsets: { + top: safeAreaInsets$1.top, + right: safeAreaInsets$1.right, + bottom: safeAreaInsets$1.bottom, + left: safeAreaInsets$1.left + }, + screenTop: screenHeight - windowHeight + }; + } +); +let browserInfo; +let _initBrowserInfo = true; +function initBrowserInfo() { + if (!_initBrowserInfo) + return; + browserInfo = getBrowserInfo(); +} +const getDeviceInfo = /* @__PURE__ */ defineSyncApi( + "getDeviceInfo", + () => { + initBrowserInfo(); + const { + deviceBrand, + deviceModel, + brand, + model, + platform, + system, + deviceOrientation, + deviceType + } = browserInfo; + return { + brand, + deviceBrand, + deviceModel, + devicePixelRatio: window.devicePixelRatio, + deviceId: deviceId$1(), + deviceOrientation, + deviceType, + model, + platform, + system + }; + } +); +const getAppBaseInfo = /* @__PURE__ */ defineSyncApi( + "getAppBaseInfo", + () => { + initBrowserInfo(); + const { theme, language, browserName, browserVersion } = browserInfo; + return { + appId: __uniConfig.appId, + appName: __uniConfig.appName, + appVersion: __uniConfig.appVersion, + appVersionCode: __uniConfig.appVersionCode, + appLanguage: getLocale ? getLocale() : language, + enableDebug: false, + hostSDKVersion: void 0, + hostPackageName: void 0, + hostFontSizeSetting: void 0, + hostName: browserName, + hostVersion: browserVersion, + hostTheme: theme, + hostLanguage: language, + language, + SDKVersion: "", + theme, + version: "" + }; + } +); +const getSystemInfoSync = /* @__PURE__ */ defineSyncApi( + "getSystemInfoSync", + () => { + _initBrowserInfo = true; + initBrowserInfo(); + _initBrowserInfo = false; + const windowInfo = getWindowInfo(); + const deviceInfo = getDeviceInfo(); + const appBaseInfo = getAppBaseInfo(); + _initBrowserInfo = true; + const { ua: ua2, browserName, browserVersion, osname, osversion } = browserInfo; + const systemInfo = extend( + windowInfo, + deviceInfo, + appBaseInfo, + { + ua: ua2, + browserName, + browserVersion, + uniPlatform: "web", + uniCompileVersion: __uniConfig.compilerVersion, + uniRuntimeVersion: __uniConfig.compilerVersion, + fontSizeSetting: void 0, + osName: osname.toLocaleLowerCase(), + osVersion: osversion, + osLanguage: void 0, + osTheme: void 0 + } + ); + delete systemInfo.screenTop; + delete systemInfo.enableDebug; + if (!__uniConfig.darkmode) + delete systemInfo.theme; + return sortObject(systemInfo); + } +); +const getSystemInfo = /* @__PURE__ */ defineAsyncApi( + "getSystemInfo", + (_args, { resolve }) => { + return resolve(getSystemInfoSync()); + } +); +const API_ON_NETWORK_STATUS_CHANGE = "onNetworkStatusChange"; +function networkListener() { + getNetworkType().then(({ networkType }) => { + UniServiceJSBridge.invokeOnCallback( + API_ON_NETWORK_STATUS_CHANGE, + { + isConnected: networkType !== "none", + networkType + } + ); + }); +} +function getConnection() { + return navigator.connection || navigator.webkitConnection || navigator.mozConnection; +} +const onNetworkStatusChange = /* @__PURE__ */ defineOnApi( + API_ON_NETWORK_STATUS_CHANGE, + () => { + const connection = getConnection(); + if (connection) { + connection.addEventListener("change", networkListener); + } else { + window.addEventListener("offline", networkListener); + window.addEventListener("online", networkListener); + } + } +); +const offNetworkStatusChange = /* @__PURE__ */ defineOffApi("offNetworkStatusChange", () => { + const connection = getConnection(); + if (connection) { + connection.removeEventListener("change", networkListener); + } else { + window.removeEventListener("offline", networkListener); + window.removeEventListener("online", networkListener); + } +}); +const getNetworkType = /* @__PURE__ */ defineAsyncApi( + "getNetworkType", + (_args, { resolve }) => { + const connection = getConnection(); + let networkType = "unknown"; + if (connection) { + networkType = connection.type; + if (networkType === "cellular" && connection.effectiveType) { + networkType = connection.effectiveType.replace("slow-", ""); + } else if (!["none", "wifi"].includes(networkType)) { + networkType = "unknown"; + } + } else if (navigator.onLine === false) { + networkType = "none"; + } + return resolve({ networkType }); + } +); +let listener$1 = null; +const onAccelerometerChange = /* @__PURE__ */ defineOnApi(API_ON_ACCELEROMETER, () => { + startAccelerometer(); +}); +const offAccelerometerChange = /* @__PURE__ */ defineOnApi(API_OFF_ACCELEROMETER, () => { + stopAccelerometer(); +}); +const startAccelerometer = /* @__PURE__ */ defineAsyncApi( + API_START_ACCELEROMETER, + (_, { resolve, reject }) => { + if (!window.DeviceMotionEvent) { + reject(); + return; + } + function addEventListener() { + listener$1 = function(event) { + const acceleration = event.acceleration || event.accelerationIncludingGravity; + UniServiceJSBridge.invokeOnCallback(API_ON_ACCELEROMETER, { + x: acceleration && acceleration.x || 0, + y: acceleration && acceleration.y || 0, + z: acceleration && acceleration.z || 0 + }); + }; + window.addEventListener("devicemotion", listener$1, false); + } + if (!listener$1) { + if (DeviceMotionEvent.requestPermission) { + DeviceMotionEvent.requestPermission().then((res) => { + if (res === "granted") { + addEventListener(); + resolve(); + } else { + reject(`${res}`); + } + }).catch((error) => { + reject(`${error}`); + }); + return; + } + addEventListener(); + } + resolve(); + } +); +const stopAccelerometer = /* @__PURE__ */ defineAsyncApi( + API_STOP_ACCELEROMETER, + (_, { resolve }) => { + if (listener$1) { + window.removeEventListener("devicemotion", listener$1, false); + listener$1 = null; + } + resolve(); + } +); +let listener = null; +const onCompassChange = /* @__PURE__ */ defineOnApi( + API_ON_COMPASS, + () => { + startCompass(); + } +); +const offCompassChange = /* @__PURE__ */ defineOffApi( + API_OFF_COMPASS, + () => { + stopCompass(); + } +); +const startCompass = /* @__PURE__ */ defineAsyncApi( + API_START_COMPASS, + (_, { resolve, reject }) => { + if (!window.DeviceOrientationEvent) { + reject(); + return; + } + function addEventListener() { + listener = function(event) { + const direction2 = 360 - (event.alpha !== null ? event.alpha : 360); + UniServiceJSBridge.invokeOnCallback(API_ON_COMPASS, { + direction: direction2 + }); + }; + window.addEventListener("deviceorientation", listener, false); + } + if (!listener) { + if (DeviceOrientationEvent.requestPermission) { + DeviceOrientationEvent.requestPermission().then((res) => { + if (res === "granted") { + addEventListener(); + resolve(); + } else { + reject(`${res}`); + } + }).catch((error) => { + reject(`${error}`); + }); + return; + } + addEventListener(); + } + resolve(); + } +); +const stopCompass = /* @__PURE__ */ defineAsyncApi( + API_STOP_COMPASS, + (_, { resolve }) => { + if (listener) { + window.removeEventListener("deviceorientation", listener, false); + listener = null; + } + resolve(); + } +); +const _isSupport = !!window.navigator.vibrate; +const vibrateShort = /* @__PURE__ */ defineAsyncApi( + API_VIBRATE_SHORT, + (args, { resolve, reject }) => { + if (_isSupport && window.navigator.vibrate(15)) { + resolve(); + } else { + reject("vibrateLong:fail"); + } + } +); +const vibrateLong = /* @__PURE__ */ defineAsyncApi( + API_VIBRATE_LONG, + (args, { resolve, reject }) => { + if (_isSupport && window.navigator.vibrate(400)) { + resolve(); + } else { + reject("vibrateLong:fail"); + } + } +); +var __async = (__this, __arguments, generator) => { + return new Promise((resolve, reject) => { + var fulfilled = (value) => { + try { + step(generator.next(value)); + } catch (e2) { + reject(e2); + } + }; + var rejected = (value) => { + try { + step(generator.throw(value)); + } catch (e2) { + reject(e2); + } + }; + var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); + step((generator = generator.apply(__this, __arguments)).next()); + }); +}; +const getClipboardData = /* @__PURE__ */ defineAsyncApi( + API_GET_CLIPBOARD_DATA, + (_0, _1) => __async(void 0, [_0, _1], function* (_, { resolve, reject }) { + initI18nGetClipboardDataMsgsOnce(); + const { t: t2 } = useI18n(); + try { + const data = yield navigator.clipboard.readText(); + resolve({ data }); + } catch (error) { + _getClipboardData(resolve, () => { + reject(`${error} ${t2("uni.getClipboardData.fail")}`); + }); + } + }) +); +const setClipboardData = /* @__PURE__ */ defineAsyncApi( + API_SET_CLIPBOARD_DATA, + (_0, _1) => __async(void 0, [_0, _1], function* ({ data }, { resolve, reject }) { + try { + yield navigator.clipboard.writeText(data); + resolve(); + } catch (error) { + _setClipboardData(data, resolve, reject); + } + }), + SetClipboardDataProtocol, + SetClipboardDataOptions +); +function _getClipboardData(resolve, reject) { + const pasteText = document.getElementById("#clipboard"); + const data = pasteText ? pasteText.value : void 0; + if (data) { + resolve({ data }); + } else { + reject(); + } +} +function _setClipboardData(data, resolve, reject) { + const pasteText = document.getElementById("#clipboard"); + pasteText && pasteText.remove(); + const textarea = document.createElement("textarea"); + textarea.id = "#clipboard"; + textarea.style.position = "fixed"; + textarea.style.top = "-9999px"; + textarea.style.zIndex = "-9999"; + document.body.appendChild(textarea); + textarea.value = data; + textarea.select(); + textarea.setSelectionRange(0, textarea.value.length); + const result = document.execCommand("Copy", false); + textarea.blur(); + if (result) { + resolve(); + } else { + reject(); + } +} +const themeChangeCallBack = (res) => { + UniServiceJSBridge.invokeOnCallback(ON_THEME_CHANGE, res); +}; +const onThemeChange$1 = /* @__PURE__ */ defineOnApi( + ON_THEME_CHANGE, + () => { + UniServiceJSBridge.on(ON_THEME_CHANGE, themeChangeCallBack); + } +); +const offThemeChange$1 = /* @__PURE__ */ defineOffApi( + OFF_THEME_CHANGE, + () => { + UniServiceJSBridge.off(ON_THEME_CHANGE, themeChangeCallBack); + } +); +const STORAGE_KEYS = "uni-storage-keys"; +function parseValue(value) { + const types = ["object", "string", "number", "boolean", "undefined"]; + try { + const object = isString(value) ? JSON.parse(value) : value; + const type = object.type; + if (types.indexOf(type) >= 0) { + const keys = Object.keys(object); + if (keys.length === 2 && "data" in object) { + if (typeof object.data === type) { + return object.data; + } + if (type === "object" && /^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z$/.test(object.data)) { + return new Date(object.data); + } + } else if (keys.length === 1) { + return ""; + } + } + } catch (error) { + } +} +const setStorageSync = /* @__PURE__ */ defineSyncApi( + API_SET_STORAGE_SYNC, + (key, data) => { + const type = typeof data; + const value = type === "string" ? data : JSON.stringify({ + type, + data + }); + localStorage.setItem(key, value); + }, + SetStorageSyncProtocol +); +const setStorage = /* @__PURE__ */ defineAsyncApi( + API_SET_STORAGE, + ({ key, data }, { resolve, reject }) => { + try { + setStorageSync(key, data); + resolve(); + } catch (error) { + reject(error.message); + } + }, + SetStorageProtocol +); +function getStorageOrigin(key) { + const value = localStorage && localStorage.getItem(key); + if (!isString(value)) { + throw new Error("data not found"); + } + let data = value; + try { + const object = JSON.parse(value); + const result = parseValue(object); + if (result !== void 0) { + data = result; + } + } catch (error) { + } + return data; +} +const getStorageSync = /* @__PURE__ */ defineSyncApi( + API_GET_STORAGE_SYNC, + (key) => { + try { + return getStorageOrigin(key); + } catch (error) { + return ""; + } + }, + GetStorageSyncProtocol +); +const getStorage = /* @__PURE__ */ defineAsyncApi( + API_GET_STORAGE, + ({ key }, { resolve, reject }) => { + try { + const data = getStorageOrigin(key); + resolve({ + data + }); + } catch (error) { + reject(error.message); + } + }, + GetStorageProtocol +); +const removeStorageSync = /* @__PURE__ */ defineSyncApi( + API_REMOVE_STORAGE, + (key) => { + if (localStorage) { + localStorage.removeItem(key); + } + }, + RemoveStorageSyncProtocol +); +const removeStorage = /* @__PURE__ */ defineAsyncApi( + API_REMOVE_STORAGE, + ({ key }, { resolve }) => { + removeStorageSync(key); + resolve(); + }, + RemoveStorageProtocol +); +const clearStorageSync = /* @__PURE__ */ defineSyncApi( + "clearStorageSync", + () => { + if (localStorage) { + localStorage.clear(); + } + } +); +const clearStorage = /* @__PURE__ */ defineAsyncApi( + "clearStorage", + (_, { resolve }) => { + clearStorageSync(); + resolve(); + } +); +const getStorageInfoSync = /* @__PURE__ */ defineSyncApi( + "getStorageInfoSync", + () => { + const length = localStorage && localStorage.length || 0; + const keys = []; + let currentSize = 0; + for (let index2 = 0; index2 < length; index2++) { + const key = localStorage.key(index2); + const value = localStorage.getItem(key) || ""; + currentSize += key.length + value.length; + if (key !== STORAGE_KEYS) { + keys.push(key); + } + } + return { + keys, + currentSize: Math.ceil(currentSize * 2 / 1024), + limitSize: Number.MAX_VALUE + }; + } +); +const getStorageInfo = /* @__PURE__ */ defineAsyncApi( + "getStorageInfo", + (_, { resolve }) => { + resolve(getStorageInfoSync()); + } +); +const getFileInfo = /* @__PURE__ */ defineAsyncApi( + API_GET_FILE_INFO, + ({ filePath }, { resolve, reject }) => { + urlToFile(filePath).then((res) => { + resolve({ + size: res.size + }); + }).catch((err) => { + reject(String(err)); + }); + }, + GetFileInfoProtocol, + GetFileInfoOptions +); +const openDocument = /* @__PURE__ */ defineAsyncApi( + API_OPEN_DOCUMENT, + ({ filePath }, { resolve }) => { + window.open(filePath); + return resolve(); + }, + OpenDocumentProtocol, + OpenDocumentOptions +); +const hideKeyboard = /* @__PURE__ */ defineAsyncApi( + API_HIDE_KEYBOARD, + (args, { resolve, reject }) => { + const activeElement = document.activeElement; + if (activeElement && (activeElement.tagName === "TEXTAREA" || activeElement.tagName === "INPUT")) { + activeElement.blur(); + resolve(); + } + } +); +const API_ON_KEYBOARD_HEIGHT_CHANGE = "onKeyboardHeightChange"; +const onKeyboardHeightChange = /* @__PURE__ */ defineAsyncApi( + API_ON_KEYBOARD_HEIGHT_CHANGE, + (args, { resolve, reject }) => { + resolve(); + } +); +const API_OFF_KEYBOARD_HEIGHT_CHANGE = "offKeyboardHeightChange"; +const offKeyboardHeightChange = /* @__PURE__ */ defineAsyncApi( + API_OFF_KEYBOARD_HEIGHT_CHANGE, + (args, { resolve, reject }) => { + resolve(); + } +); +function getServiceAddress() { + return window.location.protocol + "//" + window.location.host; +} +const getImageInfo = /* @__PURE__ */ defineAsyncApi( + API_GET_IMAGE_INFO, + ({ src }, { resolve, reject }) => { + const img = new Image(); + img.onload = function() { + resolve({ + width: img.naturalWidth, + height: img.naturalHeight, + path: src.indexOf("/") === 0 ? getServiceAddress() + src : src + }); + }; + img.onerror = function() { + reject(); + }; + img.src = src; + }, + GetImageInfoProtocol, + GetImageInfoOptions +); +const getVideoInfo = /* @__PURE__ */ defineAsyncApi( + API_GET_VIDEO_INFO, + ({ src }, { resolve, reject }) => { + urlToFile(src, true).then((file) => { + return file; + }).catch(() => { + return null; + }).then((file) => { + const video = document.createElement("video"); + if (video.onloadedmetadata !== void 0) { + const handle = setTimeout( + () => { + video.onloadedmetadata = null; + video.onerror = null; + reject(); + }, + src.startsWith("data:") || src.startsWith("blob:") ? 300 : 3e3 + ); + video.onloadedmetadata = function() { + clearTimeout(handle); + video.onerror = null; + resolve({ + size: file ? file.size : 0, + duration: video.duration || 0, + width: video.videoWidth || 0, + height: video.videoHeight || 0 + }); + }; + video.onerror = function() { + clearTimeout(handle); + video.onloadedmetadata = null; + reject(); + }; + video.src = src; + } else { + reject(); + } + }); + }, + GetVideoInfoProtocol, + GetVideoInfoOptions +); +const MIMEType = { + /** + * 关于图片常见的MIME类型 + */ + image: { + jpg: "jpeg", + jpe: "jpeg", + pbm: "x-portable-bitmap", + pgm: "x-portable-graymap", + pnm: "x-portable-anymap", + ppm: "x-portable-pixmap", + psd: "vnd.adobe.photoshop", + pic: "x-pict", + rgb: "x-rgb", + svg: "svg+xml", + svgz: "svg+xml", + tif: "tiff", + xif: "vnd.xiff", + wbmp: "vnd.wap.wbmp", + wdp: "vnd.ms-photo", + xbm: "x-xbitmap", + ico: "x-icon" + }, + /** + * 关于视频常见的MIME类型 + */ + video: { + "3g2": "3gpp2", + "3gp": "3gpp", + avi: "x-msvideo", + f4v: "x-f4v", + flv: "x-flv", + jpgm: "jpm", + jpgv: "jpeg", + m1v: "mpeg", + m2v: "mpeg", + mpe: "mpeg", + mpg: "mpeg", + mpg4: "mpeg", + m4v: "x-m4v", + mkv: "x-matroska", + mov: "quicktime", + qt: "quicktime", + movie: "x-sgi-movie", + mp4v: "mp4", + ogv: "ogg", + smv: "x-smv", + wm: "x-ms-wm", + wmv: "x-ms-wmv", + wmx: "x-ms-wmx", + wvx: "x-ms-wvx" + } +}; +const MIMEType$1 = MIMEType; +const ALL = "all"; +addInteractListener(); +function isWXEnv() { + const ua2 = window.navigator.userAgent.toLowerCase(); + const matchUA = ua2.match(/MicroMessenger/i); + return !!(matchUA && matchUA[0] === "micromessenger"); +} +function _createInput({ + count, + sourceType, + type, + extension +}) { + const inputEl = document.createElement("input"); + inputEl.type = "file"; + updateElementStyle(inputEl, { + position: "absolute", + visibility: "hidden", + zIndex: "-999", + width: "0", + height: "0", + top: "0", + left: "0" + }); + inputEl.accept = extension.map((item) => { + if (type !== ALL) { + const MIMEKey = item.replace(".", ""); + return `${type}/${MIMEType$1[type][MIMEKey] || MIMEKey}`; + } else { + if (isWXEnv()) { + return "."; + } + return item.indexOf(".") === 0 ? item : `.${item}`; + } + }).join(","); + if (count && count > 1) { + inputEl.multiple = true; + } + if (type !== ALL && sourceType instanceof Array && sourceType.length === 1 && sourceType[0] === "camera") { + inputEl.setAttribute("capture", "camera"); + } + return inputEl; +} +let fileInput = null; +const chooseFile = /* @__PURE__ */ defineAsyncApi( + API_CHOOSE_FILE, + ({ + // sizeType, + count, + sourceType, + type, + extension + }, { resolve, reject }) => { + initI18nChooseFileMsgsOnce(); + const { t: t2 } = useI18n(); + if (fileInput) { + document.body.removeChild(fileInput); + fileInput = null; + } + fileInput = _createInput({ + count, + sourceType, + type, + extension + }); + document.body.appendChild(fileInput); + fileInput.addEventListener("change", function(event) { + const eventTarget = event.target; + const tempFiles = []; + if (eventTarget && eventTarget.files) { + const fileCount = eventTarget.files.length; + for (let i = 0; i < fileCount; i++) { + const file = eventTarget.files[i]; + let filePath; + Object.defineProperty(file, "path", { + get() { + filePath = filePath || fileToUrl(file); + return filePath; + } + }); + if (i < count) + tempFiles.push(file); + } + } + const res = { + get tempFilePaths() { + return tempFiles.map(({ path }) => path); + }, + tempFiles + }; + resolve(res); + }); + fileInput.click(); + if (!getInteractStatus()) { + console.warn(t2("uni.chooseFile.notUserActivation")); + } + }, + ChooseFileProtocol, + ChooseFileOptions +); +let imageInput = null; +const chooseImage = /* @__PURE__ */ defineAsyncApi( + API_CHOOSE_IMAGE, + ({ + count, + // sizeType, + sourceType, + extension + }, { resolve, reject }) => { + initI18nChooseFileMsgsOnce(); + const { t: t2 } = useI18n(); + if (imageInput) { + document.body.removeChild(imageInput); + imageInput = null; + } + imageInput = _createInput({ + count, + sourceType, + extension, + type: "image" + }); + document.body.appendChild(imageInput); + imageInput.addEventListener("change", function(event) { + const eventTarget = event.target; + const tempFiles = []; + if (eventTarget && eventTarget.files) { + const fileCount = eventTarget.files.length; + for (let i = 0; i < fileCount; i++) { + const file = eventTarget.files[i]; + let filePath; + Object.defineProperty(file, "path", { + get() { + filePath = filePath || fileToUrl(file); + return filePath; + } + }); + if (i < count) + tempFiles.push(file); + } + } + const res = { + get tempFilePaths() { + return tempFiles.map(({ path }) => path); + }, + tempFiles + }; + resolve(res); + }); + imageInput.click(); + if (!getInteractStatus()) { + console.warn(t2("uni.chooseFile.notUserActivation")); + } + }, + ChooseImageProtocol, + ChooseImageOptions +); +const KEY_MAPS = { + esc: ["Esc", "Escape"], + // tab: ['Tab'], + enter: ["Enter"] + // space: [' ', 'Spacebar'], + // up: ['Up', 'ArrowUp'], + // left: ['Left', 'ArrowLeft'], + // right: ['Right', 'ArrowRight'], + // down: ['Down', 'ArrowDown'], + // delete: ['Backspace', 'Delete', 'Del'], +}; +const KEYS = Object.keys(KEY_MAPS); +function useKeyboard() { + const key = ref(""); + const disable = ref(false); + const onKeyup = (evt) => { + if (disable.value) { + return; + } + const res = KEYS.find( + (key2) => KEY_MAPS[key2].indexOf(evt.key) !== -1 + ); + if (res) { + key.value = res; + } + nextTick(() => key.value = ""); + }; + onMounted(() => { + document.addEventListener("keyup", onKeyup); + }); + onBeforeUnmount(() => { + document.removeEventListener("keyup", onKeyup); + }); + return { + key, + disable + }; +} +const VNODE_MASK = /* @__PURE__ */ createVNode( + "div", + { class: "uni-mask" }, + null, + -1 + /* HOISTED */ +); +function createRootApp(component, rootState, callback) { + rootState.onClose = (...args) => (rootState.visible = false, callback.apply(null, args)); + return createApp( + defineComponent({ + setup() { + return () => (openBlock(), createBlock( + component, + rootState, + null, + 16 + /* FULL_PROPS */ + )); + } + }) + ); +} +function ensureRoot(id2) { + let rootEl = document.getElementById(id2); + if (!rootEl) { + rootEl = document.createElement("div"); + rootEl.id = id2; + document.body.append(rootEl); + } + return rootEl; +} +function usePopup(props2, { + onEsc, + onEnter +}) { + const visible = ref(props2.visible); + const { key, disable } = useKeyboard(); + watch( + () => props2.visible, + (value) => visible.value = value + ); + watch( + () => visible.value, + (value) => disable.value = !value + ); + watchEffect(() => { + const { value } = key; + if (value === "esc") { + onEsc && onEsc(); + } else if (value === "enter") { + onEnter && onEnter(); + } + }); + return visible; +} +let index$a = 0; +let overflow = ""; +function preventScroll(prevent) { + let before = index$a; + index$a += prevent ? 1 : -1; + index$a = Math.max(0, index$a); + if (index$a > 0) { + if (before === 0) { + overflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; + } + } else { + document.body.style.overflow = overflow; + overflow = ""; + } +} +function usePreventScroll() { + onMounted(() => preventScroll(true)); + onUnmounted(() => preventScroll(false)); +} +const props$a = { + src: { + type: String, + default: "" + } +}; +const ImageView = /* @__PURE__ */ defineSystemComponent({ + name: "ImageView", + props: props$a, + setup(props2) { + const state2 = reactive({ + direction: "none" + }); + let scale = 1; + let imgWidth = 0; + let imgHeight = 0; + let width = 0; + let height = 0; + function onScale({ + detail + }) { + scale = detail.scale; + } + function onImgLoad(event) { + const target = event.target; + const rect = target.getBoundingClientRect(); + imgWidth = rect.width; + imgHeight = rect.height; + } + function onTouchStart(event) { + const target = event.target; + const rect = target.getBoundingClientRect(); + width = rect.width; + height = rect.height; + checkDirection(event); + } + function onTouchEnd(event) { + const horizontal = scale * imgWidth > width; + const vertical = scale * imgHeight > height; + if (horizontal && vertical) { + state2.direction = "all"; + } else if (horizontal) { + state2.direction = "horizontal"; + } else if (vertical) { + state2.direction = "vertical"; + } else { + state2.direction = "none"; + } + checkDirection(event); + } + function checkDirection(event) { + if (state2.direction === "all" || state2.direction === "horizontal") { + event.stopPropagation(); + } + } + return () => { + const viewStyle = { + position: "absolute", + left: "0", + top: "0", + width: "100%", + height: "100%" + }; + return createVNode(MovableArea, { + "style": viewStyle, + "onTouchstart": withWebEvent(onTouchStart), + "onTouchmove": withWebEvent(checkDirection), + "onTouchend": withWebEvent(onTouchEnd) + }, { + default: () => [createVNode(MovableView, { + "style": viewStyle, + "direction": state2.direction, + "inertia": true, + "scale": true, + "scale-min": "1", + "scale-max": "4", + "onScale": onScale + }, { + default: () => [createVNode("img", { + "src": props2.src, + "style": { + position: "absolute", + left: "50%", + top: "50%", + transform: "translate(-50%, -50%)", + maxHeight: "100%", + maxWidth: "100%" + }, + "onLoad": onImgLoad + }, null, 40, ["src", "onLoad"])] + }, 8, ["style", "direction", "inertia", "scale", "onScale"])] + }, 8, ["style", "onTouchstart", "onTouchmove", "onTouchend"]); + }; + } +}); +function _isSlot$2(s) { + return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s); +} +const props$9 = { + urls: { + type: Array, + default() { + return []; + } + }, + current: { + type: [Number, String], + default: 0 + } +}; +function getIndex(props2) { + let index2 = typeof props2.current === "number" ? props2.current : props2.urls.indexOf(props2.current); + index2 = index2 < 0 ? 0 : index2; + return index2; +} +const ImagePreview = /* @__PURE__ */ defineSystemComponent({ + name: "ImagePreview", + props: props$9, + emits: ["close"], + setup(props2, { + emit: emit2 + }) { + usePreventScroll(); + const rootRef = ref(null); + const indexRef = ref(getIndex(props2)); + watch(() => props2.current, () => indexRef.value = getIndex(props2)); + let preventDefault; + onMounted(() => { + const el = rootRef.value; + const MAX_MOVE = 20; + let x = 0; + let y = 0; + el.addEventListener("mousedown", (event) => { + preventDefault = false; + x = event.clientX; + y = event.clientY; + }); + el.addEventListener("mouseup", (event) => { + if (Math.abs(event.clientX - x) > MAX_MOVE || Math.abs(event.clientY - y) > MAX_MOVE) { + preventDefault = true; + } + }); + }); + function onClick() { + if (!preventDefault) { + nextTick(() => { + emit2("close"); + }); + } + } + function onChange2(event) { + indexRef.value = event.detail.current; + } + const closeBtnStyle = { + position: "absolute", + "box-sizing": "border-box", + top: "0", + right: "0", + width: "60px", + height: "44px", + padding: "6px", + "line-height": "32px", + "font-size": "26px", + color: "white", + "text-align": "center", + cursor: "pointer" + }; + return () => { + let _slot; + return createVNode("div", { + "ref": rootRef, + "style": { + display: "block", + position: "fixed", + left: "0", + top: "0", + width: "100%", + height: "100%", + zIndex: 999, + background: "rgba(0,0,0,0.8)" + }, + "onClick": onClick + }, [createVNode(Swiper, { + "navigation": "auto", + "current": indexRef.value, + "onChange": onChange2, + "indicator-dots": false, + "autoplay": false, + "style": { + position: "absolute", + left: "0", + top: "0", + width: "100%", + height: "100%" + } + }, _isSlot$2(_slot = props2.urls.map((src) => createVNode(SwiperItem, null, { + default: () => [createVNode(ImageView, { + "src": src + }, null, 8, ["src"])] + }))) ? _slot : { + default: () => [_slot], + _: 1 + }, 8, ["current", "onChange"]), createVNode("div", { + "style": closeBtnStyle + }, [createSvgIconVNode(ICON_PATH_CLOSE, "#ffffff", 26)], 4)], 8, ["onClick"]); + }; + } +}); +let state$2 = null; +let imagePreviewInstance; +const closePreviewImageView = () => { + state$2 = null; + nextTick(() => { + imagePreviewInstance == null ? void 0 : imagePreviewInstance.unmount(); + imagePreviewInstance = null; + }); +}; +const previewImage = /* @__PURE__ */ defineAsyncApi( + API_PREVIEW_IMAGE, + (args, { resolve }) => { + if (!state$2) { + state$2 = reactive(args); + nextTick(() => { + imagePreviewInstance = createRootApp( + ImagePreview, + state$2, + closePreviewImageView + ); + imagePreviewInstance.mount(ensureRoot("u-a-p")); + }); + } else { + extend(state$2, args); + } + resolve(); + }, + PreviewImageProtocol, + PreviewImageOptions +); +const closePreviewImage = /* @__PURE__ */ defineAsyncApi( + API_CLOSE_PREVIEW_IMAGE, + (_, { resolve, reject }) => { + if (imagePreviewInstance) { + closePreviewImageView(); + resolve(); + } else { + reject(); + } + } +); +let videoInput = null; +const chooseVideo = /* @__PURE__ */ defineAsyncApi( + API_CHOOSE_VIDEO, + ({ sourceType, extension }, { resolve, reject }) => { + initI18nChooseFileMsgsOnce(); + const { t: t2 } = useI18n(); + if (videoInput) { + document.body.removeChild(videoInput); + videoInput = null; + } + videoInput = _createInput({ + sourceType, + extension, + type: "video" + }); + document.body.appendChild(videoInput); + videoInput.addEventListener("change", function(event) { + const eventTarget = event.target; + const file = eventTarget.files[0]; + let filePath = ""; + const callbackResult = { + tempFilePath: filePath, + tempFile: file, + size: file.size, + duration: 0, + width: 0, + height: 0, + name: file.name + }; + Object.defineProperty(callbackResult, "tempFilePath", { + get() { + filePath = filePath || fileToUrl(this.tempFile); + return filePath; + } + }); + const video = document.createElement("video"); + if (video.onloadedmetadata !== void 0) { + const filePath2 = fileToUrl(file); + video.onloadedmetadata = function() { + revokeObjectURL(filePath2); + resolve( + extend(callbackResult, { + duration: video.duration || 0, + width: video.videoWidth || 0, + height: video.videoHeight || 0 + }) + ); + }; + setTimeout(() => { + video.onloadedmetadata = null; + revokeObjectURL(filePath2); + resolve(callbackResult); + }, 300); + video.src = filePath2; + } else { + resolve(callbackResult); + } + }); + videoInput.click(); + if (!getInteractStatus()) { + console.warn(t2("uni.chooseFile.notUserActivation")); + } + }, + ChooseVideoProtocol, + ChooseVideoOptions +); +const request = /* @__PURE__ */ defineTaskApi( + API_REQUEST, + ({ + url, + data, + header, + method, + dataType: dataType2, + responseType, + withCredentials, + timeout = __uniConfig.networkTimeout.request + }, { resolve, reject }) => { + let body = null; + const contentType = normalizeContentType(header); + if (method !== "GET") { + if (isString(data) || data instanceof ArrayBuffer) { + body = data; + } else { + if (contentType === "json") { + try { + body = JSON.stringify(data); + } catch (error) { + body = data.toString(); + } + } else if (contentType === "urlencoded") { + const bodyArray = []; + for (const key in data) { + if (hasOwn(data, key)) { + bodyArray.push( + encodeURIComponent(key) + "=" + encodeURIComponent(data[key]) + ); + } + } + body = bodyArray.join("&"); + } else { + body = data.toString(); + } + } + } + const xhr = new XMLHttpRequest(); + const requestTask = new RequestTask(xhr); + xhr.open(method, url); + for (const key in header) { + if (hasOwn(header, key)) { + xhr.setRequestHeader(key, header[key]); + } + } + const timer = setTimeout(function() { + xhr.onload = xhr.onabort = xhr.onerror = null; + requestTask.abort(); + reject("timeout"); + }, timeout); + xhr.responseType = responseType; + xhr.onload = function() { + clearTimeout(timer); + const statusCode = xhr.status; + let res = responseType === "text" ? xhr.responseText : xhr.response; + if (responseType === "text" && dataType2 === "json") { + try { + res = JSON.parse(res); + } catch (error) { + } + } + resolve({ + data: res, + statusCode, + header: parseHeaders(xhr.getAllResponseHeaders()), + cookies: [] + }); + }; + xhr.onabort = function() { + clearTimeout(timer); + reject("abort"); + }; + xhr.onerror = function() { + clearTimeout(timer); + reject(); + }; + xhr.withCredentials = withCredentials; + xhr.send(body); + return requestTask; + }, + RequestProtocol, + RequestOptions +); +function normalizeContentType(header) { + const name = Object.keys(header).find( + (name2) => name2.toLowerCase() === "content-type" + ); + if (!name) { + return; + } + const contentType = header[name]; + if (contentType.indexOf("application/json") === 0) { + return "json"; + } else if (contentType.indexOf("application/x-www-form-urlencoded") === 0) { + return "urlencoded"; + } + return "string"; +} +class RequestTask { + constructor(xhr) { + this._xhr = xhr; + } + abort() { + if (this._xhr) { + this._xhr.abort(); + delete this._xhr; + } + } + onHeadersReceived(callback) { + throw new Error("Method not implemented."); + } + offHeadersReceived(callback) { + throw new Error("Method not implemented."); + } +} +function parseHeaders(headers) { + const headersObject = {}; + headers.split(LINEFEED).forEach((header) => { + const find = header.match(/(\S+\s*):\s*(.*)/); + if (!find || find.length !== 3) { + return; + } + headersObject[find[1]] = find[2]; + }); + return headersObject; +} +class DownloadTask { + constructor(xhr) { + this._callbacks = []; + this._xhr = xhr; + } + /** + * 监听下载进度 + * @param {Function} callback 回调 + */ + onProgressUpdate(callback) { + if (!isFunction(callback)) { + return; + } + this._callbacks.push(callback); + } + offProgressUpdate(callback) { + const index2 = this._callbacks.indexOf(callback); + if (index2 >= 0) { + this._callbacks.splice(index2, 1); + } + } + /** + * 停止任务 + */ + abort() { + if (this._xhr) { + this._xhr.abort(); + delete this._xhr; + } + } + onHeadersReceived(callback) { + throw new Error("Method not implemented."); + } + offHeadersReceived(callback) { + throw new Error("Method not implemented."); + } +} +const downloadFile = /* @__PURE__ */ defineTaskApi( + API_DOWNLOAD_FILE, + ({ url, header, timeout = __uniConfig.networkTimeout.downloadFile }, { resolve, reject }) => { + var timer; + var xhr = new XMLHttpRequest(); + var downloadTask = new DownloadTask(xhr); + xhr.open("GET", url, true); + Object.keys(header).forEach((key) => { + xhr.setRequestHeader(key, header[key]); + }); + xhr.responseType = "blob"; + xhr.onload = function() { + clearTimeout(timer); + const statusCode = xhr.status; + const blob = this.response; + let filename; + const contentDisposition = xhr.getResponseHeader("content-disposition"); + if (contentDisposition) { + const res = contentDisposition.match(/filename="?(\S+)"?\b/); + if (res) { + filename = res[1]; + } + } + blob.name = filename || getFileName(url); + resolve({ + statusCode, + tempFilePath: fileToUrl(blob) + }); + }; + xhr.onabort = function() { + clearTimeout(timer); + reject("abort"); + }; + xhr.onerror = function() { + clearTimeout(timer); + reject(); + }; + xhr.onprogress = function(event) { + downloadTask._callbacks.forEach((callback) => { + var totalBytesWritten = event.loaded; + var totalBytesExpectedToWrite = event.total; + var progress = Math.round( + totalBytesWritten / totalBytesExpectedToWrite * 100 + ); + callback({ + progress, + totalBytesWritten, + totalBytesExpectedToWrite + }); + }); + }; + xhr.send(); + timer = setTimeout(function() { + xhr.onprogress = xhr.onload = xhr.onabort = xhr.onerror = null; + downloadTask.abort(); + reject("timeout"); + }, timeout); + return downloadTask; + }, + DownloadFileProtocol, + DownloadFileOptions +); +class UploadTask { + constructor(xhr) { + this._callbacks = []; + this._xhr = xhr; + } + /** + * 监听上传进度 + * @param callback 回调 + */ + onProgressUpdate(callback) { + if (!isFunction(callback)) { + return; + } + this._callbacks.push(callback); + } + offProgressUpdate(callback) { + const index2 = this._callbacks.indexOf(callback); + if (index2 >= 0) { + this._callbacks.splice(index2, 1); + } + } + /** + * 中断上传任务 + */ + abort() { + this._isAbort = true; + if (this._xhr) { + this._xhr.abort(); + delete this._xhr; + } + } + onHeadersReceived(callback) { + throw new Error("Method not implemented."); + } + offHeadersReceived(callback) { + throw new Error("Method not implemented."); + } +} +const uploadFile = /* @__PURE__ */ defineTaskApi( + API_UPLOAD_FILE, + ({ + url, + file, + filePath, + name, + files: files2, + header, + formData, + timeout = __uniConfig.networkTimeout.uploadFile + }, { resolve, reject }) => { + var uploadTask = new UploadTask(); + if (!isArray(files2) || !files2.length) { + files2 = [ + { + name, + file, + uri: filePath + } + ]; + } + function upload(realFiles) { + var xhr = new XMLHttpRequest(); + var form = new FormData(); + var timer; + Object.keys(formData).forEach((key) => { + form.append(key, formData[key]); + }); + Object.values(files2).forEach(({ name: name2 }, index2) => { + const file2 = realFiles[index2]; + form.append(name2 || "file", file2, file2.name || `file-${Date.now()}`); + }); + xhr.open("POST", url); + Object.keys(header).forEach((key) => { + xhr.setRequestHeader(key, header[key]); + }); + xhr.upload.onprogress = function(event) { + uploadTask._callbacks.forEach((callback) => { + var totalBytesSent = event.loaded; + var totalBytesExpectedToSend = event.total; + var progress = Math.round( + totalBytesSent / totalBytesExpectedToSend * 100 + ); + callback({ + progress, + totalBytesSent, + totalBytesExpectedToSend + }); + }); + }; + xhr.onerror = function() { + clearTimeout(timer); + reject(); + }; + xhr.onabort = function() { + clearTimeout(timer); + reject("abort"); + }; + xhr.onload = function() { + clearTimeout(timer); + const statusCode = xhr.status; + resolve({ + statusCode, + data: xhr.responseText || xhr.response + }); + }; + if (!uploadTask._isAbort) { + timer = setTimeout(function() { + xhr.upload.onprogress = xhr.onload = xhr.onabort = xhr.onerror = null; + uploadTask.abort(); + reject("timeout"); + }, timeout); + xhr.send(form); + uploadTask._xhr = xhr; + } else { + reject("abort"); + } + } + Promise.all( + files2.map( + ({ file: file2, uri }) => file2 instanceof Blob ? Promise.resolve(blobToFile(file2)) : urlToFile(uri) + ) + ).then(upload).catch(() => { + setTimeout(() => { + reject("file error"); + }, 0); + }); + return uploadTask; + }, + UploadFileProtocol, + UploadFileOptions +); +const socketTasks = []; +const globalEvent = { + open: "", + close: "", + error: "", + message: "" +}; +class SocketTask { + /** + * 构造函数 + * @param {string} url + * @param {Array} protocols + */ + constructor(url, protocols, callback) { + this._callbacks = { + open: [], + close: [], + error: [], + message: [] + }; + let error; + try { + const webSocket = this._webSocket = new WebSocket(url, protocols); + webSocket.binaryType = "arraybuffer"; + const eventNames = ["open", "close", "error", "message"]; + eventNames.forEach((name) => { + this._callbacks[name] = []; + webSocket.addEventListener(name, (event) => { + const { data, code, reason } = event; + const res = name === "message" ? { data } : name === "close" ? { code, reason } : {}; + this._callbacks[name].forEach((callback2) => { + try { + callback2(res); + } catch (e2) { + console.error( + `thirdScriptError +${e2};at socketTask.on${capitalize( + name + )} callback function +`, + e2 + ); + } + }); + if (this === socketTasks[0] && globalEvent[name]) { + UniServiceJSBridge.invokeOnCallback(globalEvent[name], res); + } + if (name === "error" || name === "close") { + const index2 = socketTasks.indexOf(this); + if (index2 >= 0) { + socketTasks.splice(index2, 1); + } + } + }); + }); + const propertys = [ + "CLOSED", + "CLOSING", + "CONNECTING", + "OPEN", + "readyState" + ]; + propertys.forEach((property) => { + Object.defineProperty(this, property, { + get() { + return webSocket[property]; + } + }); + }); + } catch (e2) { + error = e2; + } + callback && callback(error, this); + } + /** + * 发送 + * @param {any} data + */ + send(options) { + const data = (options || {}).data; + const ws = this._webSocket; + try { + if (ws.readyState !== ws.OPEN) { + throw new Error("SocketTask.readyState is not OPEN"); + } + ws.send(data); + callOptions(options, "sendSocketMessage:ok"); + } catch (error) { + callOptions(options, `sendSocketMessage:fail ${error}`); + } + } + /** + * 关闭 + * @param {number} code + * @param {string} reason + */ + close(options = {}) { + const ws = this._webSocket; + try { + const code = options.code || 1e3; + const reason = options.reason; + if (isString(reason)) { + ws.close(code, reason); + } else { + ws.close(code); + } + callOptions(options, "closeSocket:ok"); + } catch (error) { + callOptions(options, `closeSocket:fail ${error}`); + } + } + onOpen(callback) { + this._callbacks.open.push(callback); + } + onMessage(callback) { + this._callbacks.message.push(callback); + } + onError(callback) { + this._callbacks.error.push(callback); + } + onClose(callback) { + this._callbacks.close.push(callback); + } +} +const connectSocket = /* @__PURE__ */ defineTaskApi( + API_CONNECT_SOCKET, + ({ url, protocols }, { resolve, reject }) => { + return new SocketTask( + url, + protocols, + (error, socketTask) => { + if (error) { + reject(error.toString()); + return; + } + socketTasks.push(socketTask); + resolve(); + } + ); + }, + ConnectSocketProtocol, + ConnectSocketOptions +); +function callSocketTask(socketTask, method, option, resolve, reject) { + const fn = socketTask[method]; + if (isFunction(fn)) { + fn.call( + socketTask, + extend({}, option, { + success() { + resolve(); + }, + fail({ errMsg }) { + reject(errMsg.replace("sendSocketMessage:fail ", "")); + }, + complete: void 0 + }) + ); + } +} +const sendSocketMessage = /* @__PURE__ */ defineAsyncApi( + API_SEND_SOCKET_MESSAGE, + (options, { resolve, reject }) => { + const socketTask = socketTasks[0]; + if (socketTask && socketTask.readyState === socketTask.OPEN) { + callSocketTask(socketTask, "send", options, resolve, reject); + } else { + reject("WebSocket is not connected"); + } + }, + SendSocketMessageProtocol +); +const closeSocket = /* @__PURE__ */ defineAsyncApi( + API_CLOSE_SOCKET, + (options, { resolve, reject }) => { + const socketTask = socketTasks[0]; + if (socketTask) { + callSocketTask(socketTask, "close", options, resolve, reject); + } else { + reject("WebSocket is not connected"); + } + }, + CloseSocketProtocol +); +function on(event) { + const api2 = `onSocket${capitalize(event)}`; + return /* @__PURE__ */ defineOnApi(api2, () => { + globalEvent[event] = api2; + }); +} +const onSocketOpen = /* @__PURE__ */ on("open"); +const onSocketError = /* @__PURE__ */ on("error"); +const onSocketMessage = /* @__PURE__ */ on("message"); +const onSocketClose = /* @__PURE__ */ on("close"); +const getLocation = /* @__PURE__ */ defineAsyncApi( + API_GET_LOCATION, + ({ type, altitude, highAccuracyExpireTime, isHighAccuracy }, { resolve, reject }) => { + const mapInfo = getMapInfo(); + new Promise((resolve2, reject2) => { + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition( + (res) => resolve2({ coords: res.coords }), + reject2, + { + enableHighAccuracy: isHighAccuracy || altitude, + timeout: highAccuracyExpireTime || 1e3 * 100 + } + ); + } else { + reject2(new Error("device nonsupport geolocation")); + } + }).catch((error) => { + return new Promise( + (resolve2, reject2) => { + if (mapInfo.type === MapType.QQ) { + getJSONP( + `https://apis.map.qq.com/ws/location/v1/ip?output=jsonp&key=${mapInfo.key}`, + { + callback: "callback" + }, + (res) => { + if ("result" in res && res.result.location) { + const location2 = res.result.location; + resolve2({ + coords: { + latitude: location2.lat, + longitude: location2.lng + }, + skip: true + }); + } else { + reject2(new Error(res.message || JSON.stringify(res))); + } + }, + () => reject2(new Error("network error")) + ); + } else if (mapInfo.type === MapType.GOOGLE) { + request({ + method: "POST", + url: `https://www.googleapis.com/geolocation/v1/geolocate?key=${mapInfo.key}`, + success(res) { + const data = res.data; + if ("location" in data) { + resolve2({ + coords: { + latitude: data.location.lat, + longitude: data.location.lng, + accuracy: data.accuracy + }, + skip: true + }); + } else { + reject2( + new Error( + data.error && data.error.message || JSON.stringify(res) + ) + ); + } + }, + fail() { + reject2(new Error("network error")); + } + }); + } else if (mapInfo.type === MapType.AMAP) { + loadMaps([], () => { + window.AMap.plugin("AMap.Geolocation", () => { + const geolocation = new window.AMap.Geolocation({ + enableHighAccuracy: true, + timeout: 1e4 + }); + geolocation.getCurrentPosition( + (status, data) => { + if (status === "complete") { + resolve2({ + coords: { + latitude: data.position.lat, + longitude: data.position.lng, + accuracy: data.accuracy + }, + skip: true + }); + } else { + reject2(new Error(data.message)); + } + } + ); + }); + }); + } else { + reject2(error); + } + } + ); + }).then(({ coords, skip }) => { + translateCoordinateSystem(type, coords, skip).then((coords2) => { + resolve({ + latitude: coords2.latitude, + longitude: coords2.longitude, + accuracy: coords2.accuracy, + speed: coords2.altitude || 0, + altitude: coords2.altitude || 0, + verticalAccuracy: coords2.altitudeAccuracy || 0, + // 无专门水平精度,使用位置精度替代 + horizontalAccuracy: coords2.accuracy || 0 + }); + }).catch((error) => { + reject(error.message); + }); + }).catch((error) => { + reject(error.message || JSON.stringify(error)); + }); + }, + GetLocationProtocol, + GetLocationOptions +); +const ICON_PATH_NAV = "M28 17c-6.49396875 0-12.13721875 2.57040625-15 6.34840625V5.4105l6.29859375 6.29859375c0.387875 0.387875 1.02259375 0.387875 1.4105 0 0.387875-0.387875 0.387875-1.02259375 0-1.4105L12.77853125 2.36803125a0.9978125 0.9978125 0 0 0-0.0694375-0.077125c-0.1944375-0.1944375-0.45090625-0.291375-0.70721875-0.290875l-0.00184375-0.0000625-0.00184375 0.0000625c-0.2563125-0.0005-0.51278125 0.09640625-0.70721875 0.290875a0.9978125 0.9978125 0 0 0-0.0694375 0.077125l-7.930625 7.9305625c-0.387875 0.387875-0.387875 1.02259375 0 1.4105 0.387875 0.387875 1.02259375 0.387875 1.4105 0L11 5.4105V29c0 0.55 0.45 1 1 1s1-0.45 1-1c0-5.52284375 6.71571875-10 15-10 0.55228125 0 1-0.44771875 1-1 0-0.55228125-0.44771875-1-1-1z"; +const props$8 = { + latitude: { + type: Number + }, + longitude: { + type: Number + }, + scale: { + type: Number, + default: 18 + }, + name: { + type: String, + default: "" + }, + address: { + type: String, + default: "" + } +}; +function useState$2(props2) { + const state2 = reactive({ + center: { + latitude: 0, + longitude: 0 + }, + marker: { + id: 1, + latitude: 0, + longitude: 0, + iconPath: ICON_PATH_TARGET, + width: 32, + height: 52 + }, + location: { + id: 2, + latitude: 0, + longitude: 0, + iconPath: ICON_PATH_ORIGIN, + width: 44, + height: 44 + } + }); + function updatePosition() { + if (props2.latitude && props2.longitude) { + state2.center.latitude = props2.latitude; + state2.center.longitude = props2.longitude; + state2.marker.latitude = props2.latitude; + state2.marker.longitude = props2.longitude; + } + } + watch([() => props2.latitude, () => props2.longitude], updatePosition); + updatePosition(); + return state2; +} +const LocationView = /* @__PURE__ */ defineSystemComponent({ + name: "LocationView", + props: props$8, + emits: ["close"], + setup(props2, { + emit: emit2 + }) { + const state2 = useState$2(props2); + usePreventScroll(); + getLocation({ + type: "gcj02", + success: ({ + latitude, + longitude + }) => { + state2.location.latitude = latitude; + state2.location.longitude = longitude; + } + }); + function onRegionChange(event) { + const centerLocation = event.detail.centerLocation; + if (centerLocation) { + state2.center.latitude = centerLocation.latitude; + state2.center.longitude = centerLocation.longitude; + } + } + function nav() { + const mapInfo = getMapInfo(); + let url = ""; + if (mapInfo.type === MapType.GOOGLE) { + const origin = state2.location.latitude ? `&origin=${state2.location.latitude}%2C${state2.location.longitude}` : ""; + url = `https://www.google.com/maps/dir/?api=1${origin}&destination=${props2.latitude}%2C${props2.longitude}`; + } else if (mapInfo.type === MapType.QQ) { + const fromcoord = state2.location.latitude ? `&fromcoord=${state2.location.latitude}%2C${state2.location.longitude}&from=${encodeURIComponent("我的位置")}` : ""; + url = `https://apis.map.qq.com/uri/v1/routeplan?type=drive${fromcoord}&tocoord=${props2.latitude}%2C${props2.longitude}&to=${encodeURIComponent(props2.name || "目的地")}&ref=${mapInfo.key}`; + } else if (mapInfo.type === MapType.AMAP) { + const from = state2.location.latitude ? `from=${state2.location.longitude},${state2.location.latitude},${encodeURIComponent("我的位置")}&` : ""; + url = `https://uri.amap.com/navigation?${from}to=${props2.longitude},${props2.latitude},${encodeURIComponent(props2.name || "目的地")}`; + } + window.open(url); + } + function back() { + emit2("close"); + } + function setCenter({ + latitude, + longitude + }) { + state2.center.latitude = latitude; + state2.center.longitude = longitude; + } + return () => { + return createVNode("div", { + "class": "uni-system-open-location" + }, [createVNode(Map$1, { + "latitude": state2.center.latitude, + "longitude": state2.center.longitude, + "class": "map", + "markers": [state2.marker, state2.location], + "onRegionchange": onRegionChange + }, { + default: () => [createVNode("div", { + "class": "map-move", + "onClick": () => setCenter(state2.location) + }, [createSvgIconVNode(ICON_PATH_LOCTAION, "#000000", 24)], 8, ["onClick"])] + }, 8, ["latitude", "longitude", "markers", "onRegionchange"]), createVNode("div", { + "class": "info" + }, [createVNode("div", { + "class": "name", + "onClick": () => setCenter(state2.marker) + }, [props2.name], 8, ["onClick"]), createVNode("div", { + "class": "address", + "onClick": () => setCenter(state2.marker) + }, [props2.address], 8, ["onClick"]), createVNode("div", { + "class": "nav", + "onClick": nav + }, [createSvgIconVNode(ICON_PATH_NAV, "#ffffff", 26)], 8, ["onClick"])]), createVNode("div", { + "class": "nav-btn-back", + "onClick": back + }, [createSvgIconVNode(ICON_PATH_BACK, "#ffffff", 26)], 8, ["onClick"])]); + }; + } +}); +let state$1 = null; +const openLocation = /* @__PURE__ */ defineAsyncApi( + API_OPEN_LOCATION, + (args, { resolve }) => { + if (!state$1) { + state$1 = reactive(args); + nextTick(() => { + const app = createRootApp(LocationView, state$1, () => { + state$1 = null; + nextTick(() => { + app.unmount(); + }); + }); + app.mount(ensureRoot("u-a-o")); + }); + } else { + extend(state$1, args); + } + resolve(); + }, + OpenLocationProtocol, + OpenLocationOptions +); +function _isSlot$1(s) { + return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s); +} +const props$7 = { + latitude: { + type: Number + }, + longitude: { + type: Number + } +}; +function distance(distance2) { + if (distance2 > 100) { + return `${distance2 > 1e3 ? (distance2 / 1e3).toFixed(1) + "k" : distance2.toFixed(0)}m | `; + } else if (distance2 > 0) { + return "<100m | "; + } else { + return ""; + } +} +function useState$1(props2) { + const state2 = reactive({ + latitude: 0, + longitude: 0, + keyword: "", + searching: false + }); + function updatePosition() { + if (props2.latitude && props2.longitude) { + state2.latitude = props2.latitude; + state2.longitude = props2.longitude; + } + } + watch([() => props2.latitude, () => props2.longitude], updatePosition); + updatePosition(); + return state2; +} +function useList(state2) { + const key = __uniConfig.qqMapKey; + const list2 = reactive([]); + const selectedIndexRef = ref(-1); + const selectedRef = computed(() => list2[selectedIndexRef.value]); + const listState = reactive({ + loading: true, + // google map default + pageSize: 20, + pageIndex: 1, + hasNextPage: true, + nextPage: null, + selectedIndex: selectedIndexRef, + selected: selectedRef + }); + const adcodeRef = ref(""); + const boundaryRef = computed(() => adcodeRef.value ? `region(${adcodeRef.value},1,${state2.latitude},${state2.longitude})` : `nearby(${state2.latitude},${state2.longitude},5000)`); + function pushData(array) { + array.forEach((item) => { + list2.push({ + name: item.title, + address: item.address, + distance: item._distance || item.distance, + latitude: item.location.lat, + longitude: item.location.lng + }); + }); + } + function getList() { + listState.loading = true; + const mapInfo = getMapInfo(); + if (mapInfo.type === MapType.GOOGLE) { + if (listState.pageIndex > 1 && listState.nextPage) { + listState.nextPage(); + return; + } + const service = new google.maps.places.PlacesService(document.createElement("div")); + service[state2.searching ? "textSearch" : "nearbySearch"]({ + location: { + lat: state2.latitude, + lng: state2.longitude + }, + query: state2.keyword, + radius: 5e3 + }, (results, state3, page) => { + listState.loading = false; + if (results && results.length) { + results.forEach((item) => { + list2.push({ + name: item.name || "", + address: item.vicinity || item.formatted_address || "", + distance: 0, + latitude: item.geometry.location.lat(), + longitude: item.geometry.location.lng() + }); + }); + } + if (page) { + if (!page.hasNextPage) { + listState.hasNextPage = false; + } else { + listState.nextPage = () => { + page.nextPage(); + }; + } + } + }); + } else if (mapInfo.type === MapType.QQ) { + const url = state2.searching ? `https://apis.map.qq.com/ws/place/v1/search?output=jsonp&key=${key}&boundary=${boundaryRef.value}&keyword=${state2.keyword}&page_size=${listState.pageSize}&page_index=${listState.pageIndex}` : `https://apis.map.qq.com/ws/geocoder/v1/?output=jsonp&key=${key}&location=${state2.latitude},${state2.longitude}&get_poi=1&poi_options=page_size=${listState.pageSize};page_index=${listState.pageIndex}`; + getJSONP(url, { + callback: "callback" + }, (res) => { + listState.loading = false; + if (state2.searching && "data" in res && res.data.length) { + pushData(res.data); + } else if ("result" in res) { + const result = res.result; + adcodeRef.value = result.ad_info ? result.ad_info.adcode : ""; + if (result.pois) { + pushData(result.pois); + } + } + if (list2.length === listState.pageSize * listState.pageIndex) { + listState.hasNextPage = false; + } + }, () => { + listState.loading = false; + }); + } else if (mapInfo.type === MapType.AMAP) { + window.AMap.plugin("AMap.PlaceSearch", function() { + const placeSearch = new window.AMap.PlaceSearch({ + city: "全国", + pageSize: 10, + pageIndex: listState.pageIndex + }); + const keyword = state2.searching ? state2.keyword : ""; + const radius = state2.searching ? 5e4 : 5e3; + placeSearch.searchNearBy(keyword, [state2.longitude, state2.latitude], radius, function(status, result) { + if (status === "error") { + console.error(result); + } else if (status === "no_data") { + listState.hasNextPage = false; + } else { + pushData(result.poiList.pois); + } + }); + listState.loading = false; + }); + } + } + function loadMore() { + if (!listState.loading && listState.hasNextPage) { + listState.pageIndex++; + getList(); + } + } + function reset() { + listState.selectedIndex = -1; + listState.pageIndex = 1; + listState.hasNextPage = true; + listState.nextPage = null; + list2.splice(0, list2.length); + } + return { + listState, + list: list2, + loadMore, + reset, + getList + }; +} +const LoctaionPicker = /* @__PURE__ */ defineSystemComponent({ + name: "LoctaionPicker", + props: props$7, + emits: ["close"], + setup(props2, { + emit: emit2 + }) { + usePreventScroll(); + initI18nChooseLocationMsgsOnce(); + const { + t: t2 + } = useI18n(); + const state2 = useState$1(props2); + const { + list: list2, + listState, + loadMore, + reset, + getList + } = useList(state2); + const search = debounce(() => { + reset(); + if (state2.keyword) { + getList(); + } + }, 1e3, { + setTimeout, + clearTimeout + }); + watch(() => state2.searching, (val) => { + reset(); + if (!val) { + getList(); + } + }); + function onInput(event) { + state2.keyword = event.detail.value; + search(); + } + function onChoose() { + emit2("close", extend({}, listState.selected)); + } + function onBack() { + emit2("close"); + } + function onRegionChange(event) { + const centerLocation = event.detail.centerLocation; + if (centerLocation) { + move(centerLocation); + } + } + function moveToLocation() { + getLocation({ + type: "gcj02", + success: move, + fail: () => { + } + }); + } + function move({ + latitude, + longitude + }) { + state2.latitude = latitude; + state2.longitude = longitude; + if (!state2.searching) { + reset(); + getList(); + } + } + if (!state2.latitude || !state2.longitude) { + moveToLocation(); + } + return () => { + const content = list2.map((item, index2) => { + return createVNode("div", { + "key": index2, + "class": { + "list-item": true, + selected: listState.selectedIndex === index2 + }, + "onClick": () => { + listState.selectedIndex = index2; + state2.latitude = item.latitude; + state2.longitude = item.longitude; + } + }, [createSvgIconVNode(ICON_PATH_CONFIRM, "#007aff", 24), createVNode("div", { + "class": "list-item-title" + }, [item.name]), createVNode("div", { + "class": "list-item-detail" + }, [distance(item.distance), item.address])], 10, ["onClick"]); + }); + if (listState.loading) { + content.unshift(createVNode("div", { + "class": "list-loading" + }, [createVNode("i", { + "class": "uni-loading" + }, null)])); + } + return createVNode("div", { + "class": "uni-system-choose-location" + }, [createVNode(Map$1, { + "latitude": state2.latitude, + "longitude": state2.longitude, + "class": "map", + "show-location": true, + "libraries": ["places"], + "onUpdated": getList, + "onRegionchange": onRegionChange + }, { + default: () => [createVNode("div", { + "class": "map-location", + "style": `background-image: url("${ICON_PATH_TARGET}")` + }, null), createVNode("div", { + "class": "map-move", + "onClick": moveToLocation + }, [createSvgIconVNode(ICON_PATH_LOCTAION, "#000000", 24)], 8, ["onClick"])], + _: 1 + }, 8, ["latitude", "longitude", "show-location", "onUpdated", "onRegionchange"]), createVNode("div", { + "class": "nav" + }, [createVNode("div", { + "class": "nav-btn back", + "onClick": onBack + }, [createSvgIconVNode(ICON_PATH_CLOSE, "#ffffff", 26)], 8, ["onClick"]), createVNode("div", { + "class": { + "nav-btn": true, + confirm: true, + disable: !listState.selected + }, + "onClick": onChoose + }, [createSvgIconVNode(ICON_PATH_CONFIRM, "#ffffff", 26)], 10, ["onClick"])]), createVNode("div", { + "class": "menu" + }, [createVNode("div", { + "class": "search" + }, [createVNode(Input, { + "value": state2.keyword, + "class": "search-input", + "placeholder": t2("uni.chooseLocation.search"), + "onFocus": () => state2.searching = true, + "onInput": onInput + }, null, 8, ["value", "placeholder", "onFocus", "onInput"]), state2.searching && createVNode("div", { + "class": "search-btn", + "onClick": () => { + state2.searching = false; + state2.keyword = ""; + } + }, [t2("uni.chooseLocation.cancel")], 8, ["onClick"])]), createVNode(ScrollView, { + "scroll-y": true, + "class": "list", + "onScrolltolower": loadMore + }, _isSlot$1(content) ? content : { + default: () => [content], + _: 2 + }, 8, ["scroll-y", "onScrolltolower"])])]); + }; + } +}); +let state = null; +const chooseLocation = /* @__PURE__ */ defineAsyncApi( + API_CHOOSE_LOCATION, + (args, { resolve, reject }) => { + if (!state) { + state = reactive(args); + nextTick(() => { + const app = createRootApp( + LoctaionPicker, + state, + (poi) => { + state = null; + nextTick(() => { + app.unmount(); + }); + poi ? resolve(poi) : reject("cancel"); + } + ); + app.mount(ensureRoot("u-a-c")); + }); + } else { + reject("cancel"); + } + }, + ChooseLocationProtocol +); +let started = false; +let watchId = 0; +const startLocationUpdate = /* @__PURE__ */ defineAsyncApi( + API_START_LOCATION_UPDATE, + (options, { resolve, reject }) => { + if (!navigator.geolocation) { + reject(); + return; + } + watchId = watchId || navigator.geolocation.watchPosition( + (res) => { + started = true; + translateCoordinateSystem(options == null ? void 0 : options.type, res.coords).then((coords) => { + UniServiceJSBridge.invokeOnCallback( + API_ON_LOCATION_CHANGE, + coords + ); + resolve(); + }).catch((error) => { + UniServiceJSBridge.invokeOnCallback( + API_ON_LOCATION_CHANGE_ERROR, + { errMsg: `onLocationChange:fail ${error.message}` } + ); + }); + }, + (error) => { + if (!started) { + reject(error.message); + started = true; + } + UniServiceJSBridge.invokeOnCallback(API_ON_LOCATION_CHANGE_ERROR, { + errMsg: `onLocationChange:fail ${error.message}` + }); + } + ); + setTimeout(resolve, 100); + }, + StartLocationUpdateProtocol, + StartLocationUpdateOptions +); +const stopLocationUpdate = /* @__PURE__ */ defineAsyncApi( + API_STOP_LOCATION_UPDATE, + (_, { resolve }) => { + if (watchId) { + navigator.geolocation.clearWatch(watchId); + started = false; + watchId = 0; + } + resolve(); + } +); +const onLocationChange = /* @__PURE__ */ defineOnApi( + API_ON_LOCATION_CHANGE, + () => { + } +); +const offLocationChange = /* @__PURE__ */ defineOffApi( + API_OFF_LOCATION_CHANGE, + () => { + } +); +const onLocationChangeError = /* @__PURE__ */ defineOnApi( + API_ON_LOCATION_CHANGE_ERROR, + () => { + } +); +const offLocationChangeError = /* @__PURE__ */ defineOffApi( + API_OFF_LOCATION_CHANGE_ERROR, + () => { + } +); +const navigateBack = /* @__PURE__ */ defineAsyncApi( + API_NAVIGATE_BACK, + (args, { resolve, reject }) => { + let canBack = true; + if (invokeHook(ON_BACK_PRESS, { + from: args.from || "navigateBack" + }) === true) { + canBack = false; + } + if (!canBack) { + return reject(ON_BACK_PRESS); + } + getApp().$router.go(-args.delta); + return resolve(); + }, + NavigateBackProtocol, + NavigateBackOptions +); +function navigate({ type, url, tabBarText, events }, __id__) { + const router = getApp().$router; + const { path, query } = parseUrl(url); + return new Promise((resolve, reject) => { + const state2 = createPageState(type, __id__); + router[type === "navigateTo" ? "push" : "replace"]({ + path, + query, + state: state2, + force: true + }).then((failure) => { + if (isNavigationFailure(failure)) { + return reject(failure.message); + } + if (type === "switchTab") { + router.currentRoute.value.meta.tabBarText = tabBarText; + } + if (type === "navigateTo") { + const meta = router.currentRoute.value.meta; + if (!meta.eventChannel) { + meta.eventChannel = new EventChannel(state2.__id__, events); + } else if (events) { + Object.keys(events).forEach((eventName) => { + meta.eventChannel._addListener( + eventName, + "on", + events[eventName] + ); + }); + meta.eventChannel._clearCache(); + } + return resolve({ + eventChannel: meta.eventChannel + }); + } + return resolve(); + }); + }); +} +const navigateTo = /* @__PURE__ */ defineAsyncApi( + API_NAVIGATE_TO, + ({ url, events }, { resolve, reject }) => navigate({ type: API_NAVIGATE_TO, url, events }).then(resolve).catch(reject), + NavigateToProtocol, + NavigateToOptions +); +function removeLastPage() { + const page = getCurrentPage(); + if (!page) { + return; + } + const $page = page.$page; + removePage(normalizeRouteKey($page.path, $page.id)); +} +const redirectTo = /* @__PURE__ */ defineAsyncApi( + API_REDIRECT_TO, + ({ url }, { resolve, reject }) => { + return ( + // TODO exists 属性未实现 + removeLastPage(), navigate({ type: API_REDIRECT_TO, url }).then(resolve).catch(reject) + ); + }, + RedirectToProtocol, + RedirectToOptions +); +function removeAllPages() { + const keys = getCurrentPagesMap().keys(); + for (const routeKey of keys) { + removePage(routeKey); + } +} +const reLaunch = /* @__PURE__ */ defineAsyncApi( + API_RE_LAUNCH, + ({ url }, { resolve, reject }) => { + return removeAllPages(), navigate({ type: API_RE_LAUNCH, url }).then(resolve).catch(reject); + }, + ReLaunchProtocol, + ReLaunchOptions +); +function removeNonTabBarPages() { + const curTabBarPageVm = getCurrentPageVm(); + if (!curTabBarPageVm) { + return; + } + const pagesMap = getCurrentPagesMap(); + const keys = pagesMap.keys(); + for (const routeKey of keys) { + const page = pagesMap.get(routeKey); + if (!page.$.__isTabBar) { + removePage(routeKey); + } else { + page.$.__isActive = false; + } + } + if (curTabBarPageVm.$.__isTabBar) { + curTabBarPageVm.$.__isVisible = false; + invokeHook(curTabBarPageVm, ON_HIDE); + } +} +function isSamePage(url, $page) { + return url === $page.fullPath || url === "/" && $page.meta.isEntry; +} +function getTabBarPageId(url) { + const pages = getCurrentPagesMap().values(); + for (const page of pages) { + const $page = page.$page; + if (isSamePage(url, $page)) { + page.$.__isActive = true; + return $page.id; + } + } +} +const switchTab = /* @__PURE__ */ defineAsyncApi( + API_SWITCH_TAB, + // @ts-ignore + ({ url, tabBarText }, { resolve, reject }) => { + return removeNonTabBarPages(), navigate({ type: API_SWITCH_TAB, url, tabBarText }, getTabBarPageId(url)).then(resolve).catch(reject); + }, + SwitchTabProtocol, + SwitchTabOptions +); +const preloadPage = /* @__PURE__ */ defineAsyncApi( + API_PRELOAD_PAGE, + ({ url }, { resolve, reject }) => { + const path = url.split("?")[0]; + const route = getRouteOptions(path); + if (!route) { + reject(`${url}}`); + return; + } + route.loader && route.loader().then(() => { + resolve({ + url, + errMsg: "preloadPage:ok" + }); + }).catch((err) => { + reject(`${url} ${String(err)}`); + }); + }, + PreloadPageProtocol +); +function onThemeChange(callback) { + if (__uniConfig.darkmode) { + UniServiceJSBridge.on(ON_THEME_CHANGE, callback); + } +} +function offThemeChange(callback) { + UniServiceJSBridge.off(ON_THEME_CHANGE, callback); +} +function parseTheme(pageStyle) { + let parsedStyle = {}; + if (__uniConfig.darkmode) { + parsedStyle = normalizeStyles( + pageStyle, + __uniConfig.themeConfig, + getTheme() + ); + } + return __uniConfig.darkmode ? parsedStyle : pageStyle; +} +const ModalTheme = { + light: { + cancelColor: "#000000" + }, + dark: { + cancelColor: "rgb(170, 170, 170)" + } +}; +const setCancelColor = (theme, cancelColor) => cancelColor.value = ModalTheme[theme].cancelColor; +const props$6 = { + title: { + type: String, + default: "" + }, + content: { + type: String, + default: "" + }, + showCancel: { + type: Boolean, + default: true + }, + cancelText: { + type: String, + default: "Cancel" + }, + cancelColor: { + type: String, + default: "#000000" + }, + confirmText: { + type: String, + default: "OK" + }, + confirmColor: { + type: String, + default: "#007aff" + }, + visible: { + type: Boolean + }, + editable: { + type: Boolean, + default: false + }, + placeholderText: { + type: String, + default: "" + } +}; +const modal = /* @__PURE__ */ defineComponent({ + props: props$6, + setup(props2, { + emit: emit2 + }) { + const editContent = ref(""); + const close = () => visible.value = false; + const cancel = () => (close(), emit2("close", "cancel")); + const confirm = () => (close(), emit2("close", "confirm", editContent.value)); + const visible = usePopup(props2, { + onEsc: cancel, + onEnter: () => { + !props2.editable && confirm(); + } + }); + const cancelColor = useOnThemeChange$1(props2); + return () => { + const { + title, + content, + showCancel, + confirmText, + confirmColor, + editable, + placeholderText + } = props2; + editContent.value = content; + return createVNode(Transition, { + "name": "uni-fade" + }, { + default: () => [withDirectives(createVNode("uni-modal", { + "onTouchmove": onEventPrevent + }, [VNODE_MASK, createVNode("div", { + "class": "uni-modal" + }, [title && createVNode("div", { + "class": "uni-modal__hd" + }, [createVNode("strong", { + "class": "uni-modal__title", + "textContent": title + }, null, 8, ["textContent"])]), editable ? createVNode("textarea", { + "class": "uni-modal__textarea", + "rows": "1", + "placeholder": placeholderText, + "value": content, + "onInput": (e2) => editContent.value = e2.target.value + }, null, 40, ["placeholder", "value", "onInput"]) : createVNode("div", { + "class": "uni-modal__bd", + "onTouchmovePassive": onEventStop, + "textContent": content + }, null, 40, ["onTouchmovePassive", "textContent"]), createVNode("div", { + "class": "uni-modal__ft" + }, [showCancel && createVNode("div", { + "style": { + color: cancelColor.value + }, + "class": "uni-modal__btn uni-modal__btn_default", + "onClick": cancel + }, [props2.cancelText], 12, ["onClick"]), createVNode("div", { + "style": { + color: confirmColor + }, + "class": "uni-modal__btn uni-modal__btn_primary", + "onClick": confirm + }, [confirmText], 12, ["onClick"])])])], 40, ["onTouchmove"]), [[vShow, visible.value]])] + }); + }; + } +}); +function useOnThemeChange$1(props2) { + const cancelColor = ref(props2.cancelColor); + const _onThemeChange = ({ + theme + }) => { + setCancelColor(theme, cancelColor); + }; + watchEffect(() => { + if (props2.visible) { + cancelColor.value = props2.cancelColor; + if (props2.cancelColor === "#000") { + if (getTheme() === "dark") + _onThemeChange({ + theme: "dark" + }); + onThemeChange(_onThemeChange); + } + } else { + offThemeChange(_onThemeChange); + } + }); + return cancelColor; +} +let showModalState; +const onHidePopupOnce$1 = /* @__PURE__ */ once(() => { + UniServiceJSBridge.on("onHidePopup", () => showModalState.visible = false); +}); +let currentShowModalResolve; +function onModalClose(type, content) { + const isConfirm = type === "confirm"; + const res = { + confirm: isConfirm, + cancel: type === "cancel" + }; + isConfirm && showModalState.editable && (res.content = content); + currentShowModalResolve && currentShowModalResolve(res); +} +const showModal = /* @__PURE__ */ defineAsyncApi( + API_SHOW_MODAL, + (args, { resolve }) => { + onHidePopupOnce$1(); + currentShowModalResolve = resolve; + if (!showModalState) { + showModalState = reactive(args); + nextTick( + () => (createRootApp(modal, showModalState, onModalClose).mount( + ensureRoot("u-a-m") + ), //下一帧执行,确保首次显示时有动画效果 + nextTick(() => showModalState.visible = true)) + ); + } else { + extend(showModalState, args); + showModalState.visible = true; + } + }, + ShowModalProtocol, + ShowModalOptions +); +const props$5 = { + title: { + type: String, + default: "" + }, + icon: { + default: "success", + validator(value) { + return SHOW_TOAST_ICON.indexOf(value) !== -1; + } + }, + image: { + type: String, + default: "" + }, + duration: { + type: Number, + default: 1500 + }, + mask: { + type: Boolean, + default: false + }, + visible: { + type: Boolean + } +}; +const ToastIconClassName = "uni-toast__icon"; +const ICONCOLOR = { + light: "#fff", + dark: "rgba(255,255,255,0.9)" +}; +const getIconColor = (theme) => ICONCOLOR[theme]; +const Toast = /* @__PURE__ */ defineComponent({ + name: "Toast", + props: props$5, + setup(props2) { + initI18nShowToastMsgsOnce(); + initI18nShowLoadingMsgsOnce(); + const { + Icon + } = useToastIcon(props2); + const visible = usePopup(props2, {}); + return () => { + const { + mask, + duration, + title, + image: image2 + } = props2; + return createVNode(Transition, { + "name": "uni-fade" + }, { + default: () => [withDirectives(createVNode("uni-toast", { + "data-duration": duration + }, [mask ? createVNode("div", { + "class": "uni-mask", + "style": "background: transparent;", + "onTouchmove": onEventPrevent + }, null, 40, ["onTouchmove"]) : "", !image2 && !Icon.value ? createVNode("div", { + "class": "uni-sample-toast" + }, [createVNode("p", { + "class": "uni-simple-toast__text" + }, [title])]) : createVNode("div", { + "class": "uni-toast" + }, [image2 ? createVNode("img", { + "src": image2, + "class": ToastIconClassName + }, null, 10, ["src"]) : Icon.value, createVNode("p", { + "class": "uni-toast__content" + }, [title])])], 8, ["data-duration"]), [[vShow, visible.value]])] + }); + }; + } +}); +function useToastIcon(props2) { + const iconColor = ref(getIconColor(getTheme())); + const _onThemeChange = ({ + theme + }) => iconColor.value = getIconColor(theme); + watchEffect(() => { + if (props2.visible) { + onThemeChange(_onThemeChange); + } else { + offThemeChange(_onThemeChange); + } + }); + const Icon = computed(() => { + switch (props2.icon) { + case "success": + return createVNode(createSvgIconVNode(ICON_PATH_SUCCESS_NO_CIRCLE, iconColor.value, 38), { + class: ToastIconClassName + }); + case "error": + return createVNode(createSvgIconVNode(ICON_PATH_WARN, iconColor.value, 38), { + class: ToastIconClassName + }); + case "loading": + return createVNode("i", { + "class": [ToastIconClassName, "uni-loading"] + }, null, 2); + default: + return null; + } + }); + return { + Icon + }; +} +let showToastState; +let showType = ""; +let timeoutId; +const scope = /* @__PURE__ */ effectScope(); +function watchVisible() { + scope.run(() => { + watch( + [() => showToastState.visible, () => showToastState.duration], + ([visible, duration]) => { + if (visible) { + timeoutId && clearTimeout(timeoutId); + if (showType === "onShowLoading") + return; + timeoutId = setTimeout(() => { + hidePopup("onHideToast"); + }, duration); + } else { + timeoutId && clearTimeout(timeoutId); + } + } + ); + }); +} +function createToast(args) { + if (!showToastState) { + showToastState = reactive(extend(args, { visible: false })); + nextTick(() => { + watchVisible(); + UniServiceJSBridge.on("onHidePopup", () => hidePopup("onHidePopup")); + createRootApp(Toast, showToastState, () => { + }).mount(ensureRoot("u-a-t")); + }); + } else { + extend(showToastState, args); + } + setTimeout(() => { + showToastState.visible = true; + }, 10); +} +const showToast = /* @__PURE__ */ defineAsyncApi( + API_SHOW_TOAST, + (args, { resolve, reject }) => { + createToast(args); + showType = "onShowToast"; + resolve(); + }, + ShowToastProtocol, + ShowToastOptions +); +const showLoadingDefaultState = { + icon: "loading", + duration: 1e8, + image: "" +}; +const showLoading = /* @__PURE__ */ defineAsyncApi( + API_SHOW_LOADING, + (args, { resolve, reject }) => { + extend(args, showLoadingDefaultState); + createToast(args); + showType = "onShowLoading"; + resolve(); + }, + ShowLoadingProtocol, + ShowLoadingOptions +); +const hideToast = /* @__PURE__ */ defineAsyncApi( + API_HIDE_TOAST, + (args, { resolve, reject }) => { + hidePopup("onHideToast"); + resolve(); + } +); +const hideLoading = /* @__PURE__ */ defineAsyncApi( + API_HIDE_LOADING, + (args, { resolve, reject }) => { + hidePopup("onHideLoading"); + resolve(); + } +); +function hidePopup(type) { + const { t: t2 } = useI18n(); + if (!showType) { + return; + } + let warnMsg = ""; + if (type === "onHideToast" && showType !== "onShowToast") { + warnMsg = t2("uni.showToast.unpaired"); + } else if (type === "onHideLoading" && showType !== "onShowLoading") { + warnMsg = t2("uni.showLoading.unpaired"); + } + if (warnMsg) { + return console.warn(warnMsg); + } + showType = ""; + setTimeout(() => { + showToastState.visible = false; + }, 10); +} +function usePopupStyle(props2) { + const popupWidth = ref(0); + const popupHeight = ref(0); + const isDesktop = computed( + () => popupWidth.value >= 500 && popupHeight.value >= 500 + ); + const popupStyle = computed(() => { + const style = { + content: { + transform: "", + left: "", + top: "", + bottom: "" + }, + triangle: { + left: "", + top: "", + bottom: "", + "border-width": "", + "border-color": "" + } + }; + const contentStyle = style.content; + const triangleStyle = style.triangle; + const popover = props2.popover; + function getNumber(value) { + return Number(value) || 0; + } + if (isDesktop.value && popover) { + extend(triangleStyle, { + position: "absolute", + width: "0", + height: "0", + "margin-left": "-6px", + "border-style": "solid" + }); + const popoverLeft = getNumber(popover.left); + const popoverWidth = getNumber(popover.width); + const popoverTop = getNumber(popover.top); + const popoverHeight = getNumber(popover.height); + const center = popoverLeft + popoverWidth / 2; + contentStyle.transform = "none !important"; + const contentLeft = Math.max(0, center - 300 / 2); + contentStyle.left = `${contentLeft}px`; + let triangleLeft = Math.max(12, center - contentLeft); + triangleLeft = Math.min(300 - 12, triangleLeft); + triangleStyle.left = `${triangleLeft}px`; + const vcl = popupHeight.value / 2; + if (popoverTop + popoverHeight - vcl > vcl - popoverTop) { + contentStyle.top = "auto"; + contentStyle.bottom = `${popupHeight.value - popoverTop + 6}px`; + triangleStyle.bottom = "-6px"; + triangleStyle["border-width"] = "6px 6px 0 6px"; + triangleStyle["border-color"] = "#fcfcfd transparent transparent transparent"; + } else { + contentStyle.top = `${popoverTop + popoverHeight + 6}px`; + triangleStyle.top = "-6px"; + triangleStyle["border-width"] = "0 6px 6px 6px"; + triangleStyle["border-color"] = "transparent transparent #fcfcfd transparent"; + } + } + return style; + }); + onMounted(() => { + const fixSize = () => { + const { windowWidth, windowHeight, windowTop } = uni.getSystemInfoSync(); + popupWidth.value = windowWidth; + popupHeight.value = windowHeight + (windowTop || 0); + }; + window.addEventListener("resize", fixSize); + fixSize(); + onUnmounted(() => { + window.removeEventListener("resize", fixSize); + }); + }); + return { + isDesktop, + popupStyle + }; +} +const ACTION_SHEET_THEME = { + light: { + listItemColor: "#000000", + cancelItemColor: "#000000" + }, + dark: { + listItemColor: "rgba(255, 255, 255, 0.8)", + cancelItemColor: "rgba(255, 255, 255)" + } +}; +function setActionSheetTheme(theme, actionSheetTheme) { + const ActionSheetThemeKey = ["listItemColor", "cancelItemColor"]; + ActionSheetThemeKey.forEach((key) => { + actionSheetTheme[key] = ACTION_SHEET_THEME[theme][key]; + }); +} +const props$4 = { + title: { + type: String, + default: "" + }, + itemList: { + type: Array, + default() { + return []; + } + }, + itemColor: { + type: String, + default: "#000000" + }, + popover: { + type: Object, + default: null + }, + visible: { + type: Boolean, + default: false + } +}; +const actionSheet = /* @__PURE__ */ defineComponent({ + name: "ActionSheet", + props: props$4, + emits: ["close"], + setup(props2, { + emit: emit2 + }) { + initI18nShowActionSheetMsgsOnce(); + const HEIGHT = ref(260); + const contentHeight = ref(0); + const titleHeight = ref(0); + const deltaY = ref(0); + const scrollTop = ref(0); + const content = ref(null); + const main = ref(null); + const { + t: t2 + } = useI18n(); + const { + _close + } = useActionSheetLoader(props2, emit2); + const { + popupStyle + } = usePopupStyle(props2); + let scroller; + onMounted(() => { + const { + scroller: _scroller, + handleTouchStart, + handleTouchMove, + handleTouchEnd + } = useScroller(content.value, { + enableY: true, + friction: new Friction(1e-4), + spring: new Spring(2, 90, 20), + onScroll: (e2) => { + scrollTop.value = e2.target.scrollTop; + } + }); + scroller = _scroller; + useTouchtrack(content.value, (e2) => { + if (_scroller) { + switch (e2.detail.state) { + case "start": + handleTouchStart(e2); + break; + case "move": + handleTouchMove(e2); + break; + case "end": + case "cancel": + handleTouchEnd(e2); + } + } + }, true); + }); + function _handleWheel($event) { + const _deltaY = deltaY.value + $event.deltaY; + if (Math.abs(_deltaY) > 10) { + scrollTop.value += _deltaY / 3; + scrollTop.value = scrollTop.value >= contentHeight.value ? contentHeight.value : scrollTop.value <= 0 ? 0 : scrollTop.value; + scroller.scrollTo(scrollTop.value); + } else { + deltaY.value = _deltaY; + } + $event.preventDefault(); + } + watch(() => props2.visible, () => { + nextTick(() => { + if (props2.title) { + titleHeight.value = document.querySelector(".uni-actionsheet__title").offsetHeight; + } + scroller.update(); + if (content.value) + contentHeight.value = content.value.clientHeight - HEIGHT.value; + document.querySelectorAll(".uni-actionsheet__cell").forEach((item) => { + initClick(item); + }); + }); + }); + const actionSheetTheme = useOnThemeChange(props2); + return () => { + return createVNode("uni-actionsheet", { + "onTouchmove": onEventPrevent + }, [createVNode(Transition, { + "name": "uni-fade" + }, { + default: () => [withDirectives(createVNode("div", { + "class": "uni-mask uni-actionsheet__mask", + "onClick": () => _close(-1) + }, null, 8, ["onClick"]), [[vShow, props2.visible]])] + }), createVNode("div", { + "class": ["uni-actionsheet", { + "uni-actionsheet_toggle": props2.visible + }], + "style": popupStyle.value.content + }, [createVNode("div", { + "ref": main, + "class": "uni-actionsheet__menu", + "onWheel": _handleWheel + }, [props2.title ? createVNode(Fragment, null, [createVNode("div", { + "class": "uni-actionsheet__cell", + "style": { + height: `${titleHeight.value}px` + } + }, null), createVNode("div", { + "class": "uni-actionsheet__title" + }, [props2.title])]) : "", createVNode("div", { + "style": { + maxHeight: `${HEIGHT.value}px`, + overflow: "hidden" + } + }, [createVNode("div", { + "ref": content + }, [props2.itemList.map((itemTitle, index2) => createVNode("div", { + "key": index2, + "style": { + color: actionSheetTheme.listItemColor + }, + "class": "uni-actionsheet__cell", + "onClick": () => _close(index2) + }, [itemTitle], 12, ["onClick"]))], 512)])], 40, ["onWheel"]), createVNode("div", { + "class": "uni-actionsheet__action" + }, [createVNode("div", { + "style": { + color: actionSheetTheme.cancelItemColor + }, + "class": "uni-actionsheet__cell", + "onClick": () => _close(-1) + }, [t2("uni.showActionSheet.cancel")], 12, ["onClick"])]), createVNode("div", { + "style": popupStyle.value.triangle + }, null, 4)], 6)], 40, ["onTouchmove"]); + }; + } +}); +function useActionSheetLoader(props2, emit2) { + function _close(tapIndex) { + emit2("close", tapIndex); + } + const { + key, + disable + } = useKeyboard(); + watch(() => props2.visible, (value) => disable.value = !value); + watchEffect(() => { + const { + value + } = key; + if (value === "esc") { + _close && _close(-1); + } + }); + return { + _close + }; +} +function initClick(dom) { + const MAX_MOVE = 20; + let x = 0; + let y = 0; + dom.addEventListener("touchstart", (event) => { + const info = event.changedTouches[0]; + x = info.clientX; + y = info.clientY; + }); + dom.addEventListener("touchend", (event) => { + const info = event.changedTouches[0]; + if (Math.abs(info.clientX - x) < MAX_MOVE && Math.abs(info.clientY - y) < MAX_MOVE) { + const target = event.target; + const currentTarget = event.currentTarget; + const customEvent = new CustomEvent("click", { + bubbles: true, + cancelable: true, + target, + currentTarget + }); + ["screenX", "screenY", "clientX", "clientY", "pageX", "pageY"].forEach((key) => { + customEvent[key] = info[key]; + }); + event.target.dispatchEvent(customEvent); + } + }); +} +function useOnThemeChange(props2) { + const actionSheetTheme = reactive({ + listItemColor: "#000", + cancelItemColor: "#000" + }); + const _onThemeChange = ({ + theme + }) => { + setActionSheetTheme(theme, actionSheetTheme); + }; + watchEffect(() => { + if (props2.visible) { + actionSheetTheme.listItemColor = actionSheetTheme.cancelItemColor = props2.itemColor; + if (props2.itemColor === "#000") { + _onThemeChange({ + theme: getTheme() + }); + onThemeChange(_onThemeChange); + } + } else { + offThemeChange(_onThemeChange); + } + }); + return actionSheetTheme; +} +let resolveAction; +let rejectAction; +let showActionSheetState; +const onHidePopupOnce = /* @__PURE__ */ once(() => { + UniServiceJSBridge.on( + "onHidePopup", + () => showActionSheetState.visible = false + ); +}); +function onActionSheetClose(tapIndex) { + if (tapIndex === -1) { + rejectAction && rejectAction("cancel"); + } else { + resolveAction && resolveAction({ tapIndex }); + } +} +const showActionSheet = /* @__PURE__ */ defineAsyncApi( + API_SHOW_ACTION_SHEET, + (args, { resolve, reject }) => { + onHidePopupOnce(); + resolveAction = resolve; + rejectAction = reject; + if (!showActionSheetState) { + showActionSheetState = reactive(args); + nextTick( + () => (createRootApp( + actionSheet, + showActionSheetState, + onActionSheetClose + ).mount(ensureRoot("u-s-a-s")), //下一帧执行,确保首次显示时有动画效果 + nextTick(() => showActionSheetState.visible = true)) + ); + } else { + extend(showActionSheetState, args); + showActionSheetState.visible = true; + } + }, + ShowActionSheetProtocol, + ShowActionSheetOptions +); +const loadFontFace = /* @__PURE__ */ defineAsyncApi( + API_LOAD_FONT_FACE, + ({ family, source, desc }, { resolve, reject }) => { + addFont(family, source, desc).then(() => { + resolve(); + }).catch((err) => { + reject(`loadFontFace:fail ${err}`); + }); + }, + LoadFontFaceProtocol +); +function updateDocumentTitle(title) { + { + document.title = title; + } + UniServiceJSBridge.emit(ON_NAVIGATION_BAR_CHANGE, { titleText: title }); +} +function useDocumentTitle(pageMeta) { + function update() { + updateDocumentTitle(pageMeta.navigationBar.titleText); + } + watchEffect(update); + onActivated(update); +} +function setNavigationBar(pageMeta, type, args, resolve, reject) { + if (!pageMeta) { + return reject("page not found"); + } + const { navigationBar } = pageMeta; + switch (type) { + case API_SET_NAVIGATION_BAR_COLOR: + const { frontColor, backgroundColor, animation: animation2 } = args; + const { duration, timingFunc } = animation2; + if (frontColor) { + navigationBar.titleColor = frontColor === "#000000" ? "#000000" : "#ffffff"; + } + if (backgroundColor) { + navigationBar.backgroundColor = backgroundColor; + } + navigationBar.duration = duration + "ms"; + navigationBar.timingFunc = timingFunc; + break; + case API_SHOW_NAVIGATION_BAR_LOADING: + navigationBar.loading = true; + break; + case API_HIDE_NAVIGATION_BAR_LOADING: + navigationBar.loading = false; + break; + case API_SET_NAVIGATION_BAR_TITLE: + const { title } = args; + navigationBar.titleText = title; + break; + } + resolve(); +} +const setNavigationBarColor = /* @__PURE__ */ defineAsyncApi( + API_SET_NAVIGATION_BAR_COLOR, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_SET_NAVIGATION_BAR_COLOR, + args, + resolve, + reject + ); + }, + SetNavigationBarColorProtocol, + SetNavigationBarColorOptions +); +const showNavigationBarLoading = /* @__PURE__ */ defineAsyncApi( + API_SHOW_NAVIGATION_BAR_LOADING, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_SHOW_NAVIGATION_BAR_LOADING, + args || {}, + resolve, + reject + ); + } +); +const hideNavigationBarLoading = /* @__PURE__ */ defineAsyncApi( + API_HIDE_NAVIGATION_BAR_LOADING, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_HIDE_NAVIGATION_BAR_LOADING, + args || {}, + resolve, + reject + ); + } +); +const setNavigationBarTitle = /* @__PURE__ */ defineAsyncApi( + API_SET_NAVIGATION_BAR_TITLE, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_SET_NAVIGATION_BAR_TITLE, + args, + resolve, + reject + ); + }, + SetNavigationBarTitleProtocol +); +const pageScrollTo = /* @__PURE__ */ defineAsyncApi( + API_PAGE_SCROLL_TO, + ({ scrollTop, selector, duration }, { resolve }) => { + scrollTo(selector || scrollTop || 0, duration, true); + resolve(); + }, + PageScrollToProtocol, + PageScrollToOptions +); +const startPullDownRefresh = /* @__PURE__ */ defineAsyncApi( + API_START_PULL_DOWN_REFRESH, + (_args, { resolve }) => { + UniServiceJSBridge.invokeViewMethod( + API_START_PULL_DOWN_REFRESH, + {}, + getCurrentPageId() + ); + resolve(); + } +); +const stopPullDownRefresh = /* @__PURE__ */ defineAsyncApi( + API_STOP_PULL_DOWN_REFRESH, + (_args, { resolve }) => { + UniServiceJSBridge.invokeViewMethod( + API_STOP_PULL_DOWN_REFRESH, + {}, + getCurrentPageId() + ); + resolve(); + } +); +const setTabBarItemProps = [ + "text", + "iconPath", + "iconfont", + "selectedIconPath", + "visible" +]; +const setTabBarStyleProps = [ + "color", + "selectedColor", + "backgroundColor", + "borderStyle", + "midButton" +]; +const setTabBarBadgeProps = ["badge", "redDot"]; +function setProperties(item, props2, propsData) { + props2.forEach(function(name) { + if (hasOwn(propsData, name)) { + item[name] = propsData[name]; + } + }); +} +function setTabBar(type, args, resolve) { + const tabBar2 = useTabBar(); + switch (type) { + case API_SHOW_TAB_BAR: + tabBar2.shown = true; + break; + case API_HIDE_TAB_BAR: + tabBar2.shown = false; + break; + case API_SET_TAB_BAR_ITEM: + const { index: index2 } = args; + const tabBarItem = tabBar2.list[index2]; + const oldPagePath = tabBarItem.pagePath; + setProperties(tabBarItem, setTabBarItemProps, args); + const { pagePath } = args; + if (pagePath) { + const newPagePath = addLeadingSlash(pagePath); + if (newPagePath !== oldPagePath) { + normalizeTabBarRoute(index2, oldPagePath, newPagePath); + } + } + break; + case API_SET_TAB_BAR_STYLE: + setProperties(tabBar2, setTabBarStyleProps, args); + break; + case API_SHOW_TAB_BAR_RED_DOT: + setProperties(tabBar2.list[args.index], setTabBarBadgeProps, { + badge: "", + redDot: true + }); + break; + case API_SET_TAB_BAR_BADGE: + setProperties(tabBar2.list[args.index], setTabBarBadgeProps, { + badge: args.text, + redDot: true + }); + break; + case API_HIDE_TAB_BAR_RED_DOT: + case API_REMOVE_TAB_BAR_BADGE: + setProperties(tabBar2.list[args.index], setTabBarBadgeProps, { + badge: "", + redDot: false + }); + break; + } + resolve(); +} +const setTabBarItem = /* @__PURE__ */ defineAsyncApi( + API_SET_TAB_BAR_ITEM, + (args, { resolve }) => { + setTabBar(API_SET_TAB_BAR_ITEM, args, resolve); + }, + SetTabBarItemProtocol, + SetTabBarItemOptions +); +const setTabBarStyle = /* @__PURE__ */ defineAsyncApi( + API_SET_TAB_BAR_STYLE, + (args, { resolve }) => { + setTabBar(API_SET_TAB_BAR_STYLE, args, resolve); + }, + SetTabBarStyleProtocol, + SetTabBarStyleOptions +); +const hideTabBar = /* @__PURE__ */ defineAsyncApi( + API_HIDE_TAB_BAR, + (args, { resolve }) => { + setTabBar(API_HIDE_TAB_BAR, args ? args : {}, resolve); + }, + HideTabBarProtocol +); +const showTabBar = /* @__PURE__ */ defineAsyncApi( + API_SHOW_TAB_BAR, + (args, { resolve }) => { + setTabBar(API_SHOW_TAB_BAR, args ? args : {}, resolve); + }, + ShowTabBarProtocol +); +const hideTabBarRedDot = /* @__PURE__ */ defineAsyncApi( + API_HIDE_TAB_BAR_RED_DOT, + (args, { resolve }) => { + setTabBar(API_HIDE_TAB_BAR_RED_DOT, args, resolve); + }, + HideTabBarRedDotProtocol, + HideTabBarRedDotOptions +); +const showTabBarRedDot = /* @__PURE__ */ defineAsyncApi( + API_SHOW_TAB_BAR_RED_DOT, + (args, { resolve }) => { + setTabBar(API_SHOW_TAB_BAR_RED_DOT, args, resolve); + }, + ShowTabBarRedDotProtocol, + ShowTabBarRedDotOptions +); +const removeTabBarBadge = /* @__PURE__ */ defineAsyncApi( + API_REMOVE_TAB_BAR_BADGE, + (args, { resolve }) => { + setTabBar(API_REMOVE_TAB_BAR_BADGE, args, resolve); + }, + RemoveTabBarBadgeProtocol, + RemoveTabBarBadgeOptions +); +const setTabBarBadge = /* @__PURE__ */ defineAsyncApi( + API_SET_TAB_BAR_BADGE, + (args, { resolve }) => { + setTabBar(API_SET_TAB_BAR_BADGE, args, resolve); + }, + SetTabBarBadgeProtocol, + SetTabBarBadgeOptions +); +const UNI_TABBAR_ICON_FONT = "UniTabbarIconFont"; +const _middleButton = { + width: "50px", + height: "50px", + iconWidth: "24px" +}; +const TabBar = /* @__PURE__ */ defineSystemComponent({ + name: "TabBar", + setup() { + const visibleList = ref([]); + const _tabBar = useTabBar(); + const tabBar2 = reactive(parseTheme(_tabBar)); + useVisibleList(tabBar2, visibleList); + useTabBarCssVar(tabBar2); + const onSwitchTab = useSwitchTab(useRoute(), tabBar2, visibleList); + const { + style, + borderStyle, + placeholderStyle + } = useTabBarStyle(tabBar2); + onThemeChange(() => { + const tabBarStyle = parseTheme(_tabBar); + tabBar2.backgroundColor = tabBarStyle.backgroundColor; + tabBar2.borderStyle = tabBarStyle.borderStyle; + tabBar2.color = tabBarStyle.color; + tabBar2.selectedColor = tabBarStyle.selectedColor; + tabBar2.blurEffect = tabBarStyle.blurEffect; + if (tabBarStyle.list && tabBarStyle.list.length) { + tabBarStyle.list.forEach((item, index2) => { + tabBar2.list[index2].iconPath = item.iconPath; + tabBar2.list[index2].selectedIconPath = item.selectedIconPath; + }); + } + }); + onMounted(() => { + if (tabBar2.iconfontSrc) { + loadFontFace({ + family: UNI_TABBAR_ICON_FONT, + source: `url("${tabBar2.iconfontSrc}")` + }); + } + }); + return () => { + const tabBarItemsTsx = createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList); + return createVNode("uni-tabbar", { + "class": "uni-tabbar-" + tabBar2.position + }, [createVNode("div", { + "class": "uni-tabbar", + "style": style.value + }, [createVNode("div", { + "class": "uni-tabbar-border", + "style": borderStyle.value + }, null, 4), tabBarItemsTsx], 4), createVNode("div", { + "class": "uni-placeholder", + "style": placeholderStyle.value + }, null, 4)], 2); + }; + } +}); +function useTabBarCssVar(tabBar2) { + watch(() => tabBar2.shown, (value) => { + updatePageCssVar({ + "--window-bottom": normalizeWindowBottom(value ? parseInt(tabBar2.height) : 0) + }); + }); +} +function useVisibleList(tabBar2, visibleList) { + const internalMidButton = ref(extend({ + type: "midButton" + }, tabBar2.midButton)); + function setVisibleList() { + let tempList = []; + tempList = tabBar2.list.filter((item) => item.visible !== false); + if (__UNI_FEATURE_TABBAR_MIDBUTTON__ && tabBar2.midButton) { + internalMidButton.value = extend({}, _middleButton, internalMidButton.value, tabBar2.midButton); + tempList = tempList.filter((item) => !isMidButton(item)); + if (tempList.length % 2 === 0) { + tempList.splice(Math.floor(tempList.length / 2), 0, internalMidButton.value); + } + } + visibleList.value = tempList; + } + watchEffect(setVisibleList); +} +function useSwitchTab(route, tabBar2, visibleList) { + watchEffect(() => { + const meta = route.meta; + if (meta.isTabBar) { + const pagePath = meta.route; + const index2 = visibleList.value.findIndex((item) => item.pagePath === pagePath); + tabBar2.selectedIndex = index2; + } + }); + return (tabBarItem, index2) => { + const { + type + } = tabBarItem; + return () => { + if (__UNI_FEATURE_TABBAR_MIDBUTTON__ && type === "midButton") { + return UniServiceJSBridge.invokeOnCallback(API_ON_TAB_BAR_MID_BUTTON_TAP); + } + const { + pagePath, + text: text2 + } = tabBarItem; + let url = addLeadingSlash(pagePath); + if (url === __uniRoutes[0].alias) { + url = "/"; + } + if (route.path !== url) { + uni.switchTab({ + from: "tabBar", + url, + tabBarText: text2 + }); + } else { + invokeHook("onTabItemTap", { + index: index2, + text: text2, + pagePath + }); + } + }; + }; +} +const DEFAULT_BG_COLOR = "#f7f7fa"; +const BLUR_EFFECT_COLOR_DARK = "rgb(0, 0, 0, 0.8)"; +const BLUR_EFFECT_COLOR_LIGHT = "rgb(250, 250, 250, 0.8)"; +const BLUR_EFFECT_COLORS = { + dark: BLUR_EFFECT_COLOR_DARK, + light: BLUR_EFFECT_COLOR_LIGHT, + extralight: BLUR_EFFECT_COLOR_LIGHT +}; +const BORDER_COLORS = { + white: "rgba(255, 255, 255, 0.33)", + black: "rgba(0, 0, 0, 0.33)" +}; +function useTabBarStyle(tabBar2) { + const style = computed(() => { + let backgroundColor = tabBar2.backgroundColor; + const blurEffect = tabBar2.blurEffect; + if (!backgroundColor) { + if (cssBackdropFilter && blurEffect && blurEffect !== "none") { + backgroundColor = BLUR_EFFECT_COLORS[blurEffect]; + } + } + return { + backgroundColor: backgroundColor || DEFAULT_BG_COLOR, + backdropFilter: blurEffect !== "none" ? "blur(10px)" : blurEffect + }; + }); + const borderStyle = computed(() => { + const { + borderStyle: borderStyle2 + } = tabBar2; + return { + backgroundColor: BORDER_COLORS[borderStyle2] || borderStyle2 + }; + }); + const placeholderStyle = computed(() => { + return { + height: tabBar2.height + }; + }); + return { + style, + borderStyle, + placeholderStyle + }; +} +function isMidButton(item) { + return item.type === "midButton"; +} +function createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList) { + const { + selectedIndex, + selectedColor, + color + } = tabBar2; + return visibleList.value.map((item, index2) => { + const selected = selectedIndex === index2; + const textColor = selected ? selectedColor : color; + const iconPath = (selected ? item.selectedIconPath || item.iconPath : item.iconPath) || ""; + const iconfontText = item.iconfont ? selected ? item.iconfont.selectedText || item.iconfont.text : item.iconfont.text : void 0; + const iconfontColor = item.iconfont ? selected ? item.iconfont.selectedColor || item.iconfont.color : item.iconfont.color : void 0; + if (!__UNI_FEATURE_TABBAR_MIDBUTTON__) { + return createTabBarItemTsx(textColor, iconPath, iconfontText, iconfontColor, item, tabBar2, index2, onSwitchTab); + } + return isMidButton(item) ? createTabBarMidButtonTsx(textColor, iconPath, iconfontText, iconfontColor, item, tabBar2, index2, onSwitchTab) : createTabBarItemTsx(textColor, iconPath, iconfontText, iconfontColor, item, tabBar2, index2, onSwitchTab); + }); +} +function createTabBarItemTsx(color, iconPath, iconfontText, iconfontColor, tabBarItem, tabBar2, index2, onSwitchTab) { + return createVNode("div", { + "key": index2, + "class": "uni-tabbar__item", + "onClick": onSwitchTab(tabBarItem, index2) + }, [createTabBarItemBdTsx(color, iconPath || "", iconfontText, iconfontColor, tabBarItem, tabBar2)], 8, ["onClick"]); +} +function createTabBarItemBdTsx(color, iconPath, iconfontText, iconfontColor, tabBarItem, tabBar2) { + const { + height + } = tabBar2; + return createVNode("div", { + "class": "uni-tabbar__bd", + "style": { + height + } + }, [iconfontText ? createTabBarItemIconfontTsx(iconfontText, iconfontColor || BLUR_EFFECT_COLOR_DARK, tabBarItem, tabBar2) : iconPath && createTabBarItemIconTsx(iconPath, tabBarItem, tabBar2), tabBarItem.text && createTabBarItemTextTsx(color, tabBarItem, tabBar2), tabBarItem.redDot && createTabBarItemRedDotTsx(tabBarItem.badge)], 4); +} +function createTabBarItemIconTsx(iconPath, tabBarItem, tabBar2) { + const { + type, + text: text2 + } = tabBarItem; + const { + iconWidth + } = tabBar2; + const clazz2 = "uni-tabbar__icon" + (text2 ? " uni-tabbar__icon__diff" : ""); + const style = { + width: iconWidth, + height: iconWidth + }; + return createVNode("div", { + "class": clazz2, + "style": style + }, [type !== "midButton" && createVNode("img", { + "src": getRealPath(iconPath) + }, null, 8, ["src"])], 6); +} +function createTabBarItemIconfontTsx(iconfontText, iconfontColor, tabBarItem, tabBar2) { + var _a; + const { + type, + text: text2 + } = tabBarItem; + const { + iconWidth + } = tabBar2; + const clazz2 = "uni-tabbar__icon" + (text2 ? " uni-tabbar__icon__diff" : ""); + const style = { + width: iconWidth, + height: iconWidth + }; + const iconfontStyle = { + fontSize: ((_a = tabBarItem.iconfont) == null ? void 0 : _a.fontSize) || iconWidth, + color: iconfontColor + }; + return createVNode("div", { + "class": clazz2, + "style": style + }, [type !== "midButton" && createVNode("div", { + "class": "uni-tabbar__iconfont", + "style": iconfontStyle + }, [iconfontText], 4)], 6); +} +function createTabBarItemTextTsx(color, tabBarItem, tabBar2) { + const { + iconPath, + text: text2 + } = tabBarItem; + const { + fontSize, + spacing + } = tabBar2; + const style = { + color, + fontSize, + lineHeight: !iconPath ? 1.8 : "normal", + marginTop: !iconPath ? "inherit" : spacing + }; + return createVNode("div", { + "class": "uni-tabbar__label", + "style": style + }, [text2], 4); +} +function createTabBarItemRedDotTsx(badge) { + const clazz2 = "uni-tabbar__reddot" + (badge ? " uni-tabbar__badge" : ""); + return createVNode("div", { + "class": clazz2 + }, [badge], 2); +} +function createTabBarMidButtonTsx(color, iconPath, iconfontText, iconfontColor, midButton, tabBar2, index2, onSwitchTab) { + const { + width, + height, + backgroundImage, + iconWidth + } = midButton; + return createVNode("div", { + "key": "midButton", + "class": "uni-tabbar__item", + "style": { + flex: "0 0 " + width, + position: "relative" + }, + "onClick": onSwitchTab(midButton, index2) + }, [createVNode("div", { + "class": "uni-tabbar__mid", + "style": { + width, + height, + backgroundImage: backgroundImage ? "url('" + getRealPath(backgroundImage) + "')" : "none" + } + }, [iconPath && createVNode("img", { + "style": { + width: iconWidth, + height: iconWidth + }, + "src": getRealPath(iconPath) + }, null, 12, ["src"])], 4), createTabBarItemBdTsx(color, iconPath, iconfontText, iconfontColor, midButton, tabBar2)], 12, ["onClick"]); +} +const DEFAULT_CSS_VAR_VALUE = "0px"; +let globalLayoutState = void 0; +function getLayoutState() { + return globalLayoutState; +} +const LayoutComponent = /* @__PURE__ */ defineSystemComponent({ + name: "Layout", + setup(_props, { + emit: emit2 + }) { + const rootRef = ref(null); + initCssVar(); + const keepAliveRoute = __UNI_FEATURE_PAGES__ && useKeepAliveRoute(); + const { + layoutState, + windowState + } = useState(); + useMaxWidth(layoutState, rootRef); + const topWindow = __UNI_FEATURE_TOPWINDOW__ && useTopWindow(layoutState); + const leftWindow = __UNI_FEATURE_LEFTWINDOW__ && useLeftWindow(layoutState); + const rightWindow = __UNI_FEATURE_RIGHTWINDOW__ && useRightWindow(layoutState); + const showTabBar2 = __UNI_FEATURE_TABBAR__ && useShowTabBar(); + const clazz2 = useAppClass(showTabBar2); + globalLayoutState = layoutState; + return () => { + const layoutTsx = createLayoutTsx(keepAliveRoute, layoutState, windowState, topWindow, leftWindow, rightWindow); + const tabBarTsx = __UNI_FEATURE_TABBAR__ && createTabBarTsx(showTabBar2); + return createVNode("uni-app", { + "ref": rootRef, + "class": clazz2.value + }, [layoutTsx, tabBarTsx], 2); + }; + } +}); +function useAppClass(showTabBar2) { + const showMaxWidth = ref(false); + return computed(() => { + return { + "uni-app--showtabbar": showTabBar2 && showTabBar2.value, + "uni-app--maxwidth": showMaxWidth.value + }; + }); +} +function initCssVar() { + updateCssVar({ + "--status-bar-height": DEFAULT_CSS_VAR_VALUE, + "--top-window-height": DEFAULT_CSS_VAR_VALUE, + "--window-left": DEFAULT_CSS_VAR_VALUE, + "--window-right": DEFAULT_CSS_VAR_VALUE, + "--window-margin": DEFAULT_CSS_VAR_VALUE, + "--tab-bar-height": DEFAULT_CSS_VAR_VALUE + }); +} +function initMediaQuery(minWidth, callback) { + const mediaQueryList = window.matchMedia("(min-width: " + minWidth + "px)"); + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener("change", callback); + } else { + mediaQueryList.addListener(callback); + } + return mediaQueryList.matches; +} +function useMaxWidth(layoutState, rootRef) { + const route = usePageRoute(); + function checkMaxWidth2() { + const windowWidth = document.body.clientWidth; + const pages = getCurrentPages(); + let meta = {}; + if (pages.length > 0) { + const curPage = pages[pages.length - 1]; + meta = curPage.$page.meta; + } else { + const routeOptions = getRouteOptions(route.path, true); + if (routeOptions) { + meta = routeOptions.meta; + } + } + const maxWidth2 = parseInt(String((hasOwn(meta, "maxWidth") ? meta.maxWidth : __uniConfig.globalStyle.maxWidth) || Number.MAX_SAFE_INTEGER)); + let showMaxWidth = false; + if (windowWidth > maxWidth2) { + showMaxWidth = true; + } else { + showMaxWidth = false; + } + if (showMaxWidth && maxWidth2) { + layoutState.marginWidth = (windowWidth - maxWidth2) / 2; + nextTick(() => { + const rootEl = rootRef.value; + if (rootEl) { + rootEl.setAttribute("style", "max-width:" + maxWidth2 + "px;margin:0 auto;"); + } + }); + } else { + layoutState.marginWidth = 0; + nextTick(() => { + const rootEl = rootRef.value; + if (rootEl) { + rootEl.removeAttribute("style"); + } + }); + } + } + watch([() => route.path], checkMaxWidth2); + onMounted(() => { + checkMaxWidth2(); + window.addEventListener("resize", checkMaxWidth2); + }); +} +function useState() { + const route = usePageRoute(); + if (!__UNI_FEATURE_RESPONSIVE__) { + const layoutState2 = reactive({ + marginWidth: 0, + leftWindowWidth: 0, + rightWindowWidth: 0 + }); + watch(() => layoutState2.marginWidth, (value) => updateCssVar({ + "--window-margin": value + "px" + })); + watch(() => layoutState2.leftWindowWidth + layoutState2.marginWidth, (value) => { + updateCssVar({ + "--window-left": value + "px" + }); + }); + watch(() => layoutState2.rightWindowWidth + layoutState2.marginWidth, (value) => { + updateCssVar({ + "--window-right": value + "px" + }); + }); + return { + layoutState: layoutState2, + windowState: computed(() => ({})) + }; + } + const topWindowMediaQuery = ref(false); + const leftWindowMediaQuery = ref(false); + const rightWindowMediaQuery = ref(false); + const showTopWindow2 = computed(() => __UNI_FEATURE_TOPWINDOW__ && route.meta.topWindow !== false && topWindowMediaQuery.value); + const showLeftWindow2 = computed(() => __UNI_FEATURE_LEFTWINDOW__ && route.meta.leftWindow !== false && leftWindowMediaQuery.value); + const showRightWindow2 = computed(() => __UNI_FEATURE_RIGHTWINDOW__ && route.meta.rightWindow !== false && rightWindowMediaQuery.value); + const layoutState = reactive({ + topWindowMediaQuery, + showTopWindow: showTopWindow2, + apiShowTopWindow: false, + leftWindowMediaQuery, + showLeftWindow: showLeftWindow2, + apiShowLeftWindow: false, + rightWindowMediaQuery, + showRightWindow: showRightWindow2, + apiShowRightWindow: false, + topWindowHeight: 0, + marginWidth: 0, + leftWindowWidth: 0, + rightWindowWidth: 0, + navigationBarTitleText: "", + topWindowStyle: {}, + leftWindowStyle: {}, + rightWindowStyle: {} + }); + const props2 = ["topWindow", "leftWindow", "rightWindow"]; + props2.forEach((prop) => { + var _a; + const matchMedia = (_a = __uniConfig[prop]) == null ? void 0 : _a.matchMedia; + let topWindowMinWidth = RESPONSIVE_MIN_WIDTH; + if (matchMedia && hasOwn(matchMedia, "minWidth")) { + const minWidth = matchMedia.minWidth; + topWindowMinWidth = checkMinWidth(minWidth) ? minWidth : topWindowMinWidth; + } + const matches2 = initMediaQuery(topWindowMinWidth, (ev) => { + layoutState[`${prop}MediaQuery`] = ev.matches; + }); + layoutState[`${prop}MediaQuery`] = matches2; + }); + watch(() => layoutState.topWindowHeight, (value) => updateCssVar({ + "--top-window-height": value + "px" + })); + watch(() => layoutState.marginWidth, (value) => updateCssVar({ + "--window-margin": value + "px" + })); + watch(() => layoutState.leftWindowWidth + layoutState.marginWidth, (value) => { + updateCssVar({ + "--window-left": value + "px" + }); + }); + watch(() => layoutState.rightWindowWidth + layoutState.marginWidth, (value) => { + updateCssVar({ + "--window-right": value + "px" + }); + }); + UniServiceJSBridge.on(ON_NAVIGATION_BAR_CHANGE, (navigationBar) => { + layoutState.navigationBarTitleText = navigationBar.titleText; + }); + const windowState = computed(() => ({ + matchTopWindow: layoutState.topWindowMediaQuery, + showTopWindow: layoutState.showTopWindow || layoutState.apiShowTopWindow, + matchLeftWindow: layoutState.leftWindowMediaQuery, + showLeftWindow: layoutState.showLeftWindow || layoutState.apiShowLeftWindow, + matchRightWindow: layoutState.rightWindowMediaQuery, + showRightWindow: layoutState.showRightWindow || layoutState.apiShowRightWindow + })); + return { + layoutState, + windowState + }; +} +function createLayoutTsx(keepAliveRoute, layoutState, windowState, topWindow, leftWindow, rightWindow) { + const routerVNode = __UNI_FEATURE_PAGES__ ? createRouterViewVNode(keepAliveRoute) : createPageVNode(); + if (!__UNI_FEATURE_RESPONSIVE__) { + return routerVNode; + } + const topWindowTsx = __UNI_FEATURE_TOPWINDOW__ ? createTopWindowTsx(topWindow, layoutState, windowState.value) : null; + const leftWindowTsx = __UNI_FEATURE_LEFTWINDOW__ ? createLeftWindowTsx(leftWindow, layoutState, windowState.value) : null; + const rightWindowTsx = __UNI_FEATURE_RIGHTWINDOW__ ? createRightWindowTsx(rightWindow, layoutState, windowState.value) : null; + return createVNode("uni-layout", { + "class": { + "uni-app--showtopwindow": __UNI_FEATURE_TOPWINDOW__ && layoutState.showTopWindow, + "uni-app--showleftwindow": __UNI_FEATURE_LEFTWINDOW__ && layoutState.showLeftWindow, + "uni-app--showrightwindow": __UNI_FEATURE_RIGHTWINDOW__ && layoutState.showRightWindow + } + }, [topWindowTsx, createVNode("uni-content", null, [createVNode("uni-main", null, [routerVNode]), leftWindowTsx, rightWindowTsx])], 2); +} +function useShowTabBar(emit2) { + const route = usePageRoute(); + const tabBar2 = useTabBar(); + const showTabBar2 = computed(() => route.meta.isTabBar && tabBar2.shown); + updateCssVar({ + "--tab-bar-height": tabBar2.height + }); + return showTabBar2; +} +function createTabBarTsx(showTabBar2) { + return withDirectives(createVNode(TabBar, null, null, 512), [[vShow, showTabBar2.value]]); +} +function createPageVNode() { + return createVNode(__uniRoutes[0].component); +} +function createRouterViewVNode({ + routeKey, + isTabBar, + routeCache: routeCache2 +}) { + return createVNode(RouterView, null, { + default: withCtx(({ + Component + }) => [(openBlock(), createBlock(KeepAlive, { + matchBy: "key", + cache: routeCache2 + }, [(openBlock(), createBlock(resolveDynamicComponent(Component), { + type: isTabBar.value ? "tabBar" : "", + key: routeKey.value + }))], 1032, ["cache"]))]), + _: 1 + /* STABLE */ + }); +} +function useTopWindow(layoutState) { + const { + component, + style + } = __uniConfig.topWindow; + const windowRef = ref(null); + function updateWindow() { + const instance2 = windowRef.value; + const el = resolveOwnerEl(instance2.$); + const height = el.getBoundingClientRect().height; + layoutState.topWindowHeight = height; + } + onMounted(updateWindow); + watch(() => layoutState.showTopWindow || layoutState.apiShowTopWindow, () => nextTick(updateWindow)); + layoutState.topWindowStyle = style; + return { + component, + windowRef + }; +} +function useLeftWindow(layoutState) { + const { + component, + style + } = __uniConfig.leftWindow; + const windowRef = ref(null); + function updateWindow() { + const instance2 = windowRef.value; + const el = resolveOwnerEl(instance2.$); + const width = el.getBoundingClientRect().width; + layoutState.leftWindowWidth = width; + } + onMounted(updateWindow); + watch(() => layoutState.showLeftWindow || layoutState.apiShowLeftWindow, () => nextTick(updateWindow)); + layoutState.leftWindowStyle = style; + return { + component, + windowRef + }; +} +function useRightWindow(layoutState) { + const { + component, + style + } = __uniConfig.rightWindow; + const windowRef = ref(null); + function updateWindow() { + const instance2 = windowRef.value; + const el = resolveOwnerEl(instance2.$); + const width = el.getBoundingClientRect().width; + layoutState.rightWindowWidth = width; + } + onMounted(updateWindow); + watch(() => layoutState.showRightWindow || layoutState.apiShowRightWindow, () => nextTick(updateWindow)); + layoutState.rightWindowStyle = style; + return { + component, + windowRef + }; +} +function createTopWindowTsx(topWindow, layoutState, windowState) { + if (topWindow) { + const { + component: TopWindow, + windowRef + } = topWindow; + return withDirectives(createVNode("uni-top-window", null, [createVNode("div", { + "class": "uni-top-window", + "style": layoutState.topWindowStyle + }, [createVNode(TopWindow, mergeProps({ + "ref": windowRef, + "navigation-bar-title-text": layoutState.navigationBarTitleText + }, windowState), null, 16, ["navigation-bar-title-text"])], 4), createVNode("div", { + "class": "uni-top-window--placeholder", + "style": { + height: layoutState.topWindowHeight + "px" + } + }, null, 4)], 512), [[vShow, layoutState.showTopWindow || layoutState.apiShowTopWindow]]); + } +} +function createLeftWindowTsx(leftWindow, layoutState, windowState) { + if (leftWindow) { + const { + component: LeftWindow, + windowRef + } = leftWindow; + return withDirectives(createVNode("uni-left-window", { + "data-show": layoutState.apiShowLeftWindow || void 0, + "style": layoutState.leftWindowStyle + }, [layoutState.apiShowLeftWindow ? createVNode("div", { + "class": "uni-mask", + "onClick": () => layoutState.apiShowLeftWindow = false + }, null, 8, ["onClick"]) : null, createVNode("div", { + "class": "uni-left-window" + }, [createVNode(LeftWindow, mergeProps({ + "ref": windowRef + }, windowState), null, 16)])], 12, ["data-show"]), [[vShow, layoutState.showLeftWindow || layoutState.apiShowLeftWindow]]); + } +} +function createRightWindowTsx(rightWindow, layoutState, windowState) { + if (rightWindow) { + const { + component: RightWindow, + windowRef + } = rightWindow; + return withDirectives(createVNode("uni-right-window", { + "data-show": layoutState.apiShowRightWindow || void 0, + "style": layoutState.rightWindowStyle + }, [layoutState.apiShowRightWindow ? createVNode("div", { + "class": "uni-mask", + "onClick": () => layoutState.apiShowRightWindow = false + }, null, 8, ["onClick"]) : null, createVNode("div", { + "class": "uni-right-window" + }, [createVNode(RightWindow, mergeProps({ + "ref": windowRef + }, windowState), null, 16)])], 12, ["data-show"]), [[vShow, layoutState.showRightWindow || layoutState.apiShowRightWindow]]); + } +} +const showTopWindow = /* @__PURE__ */ defineAsyncApi( + "showTopWindow", + (_, { resolve, reject }) => { + const state2 = getLayoutState(); + if (!state2) { + reject(); + return; + } + state2.apiShowTopWindow = true; + nextTick(resolve); + } +); +const hideTopWindow = /* @__PURE__ */ defineAsyncApi( + "hideTopWindow", + (_, { resolve, reject }) => { + const state2 = getLayoutState(); + if (!state2) { + reject(); + return; + } + state2.apiShowTopWindow = false; + nextTick(resolve); + } +); +const showLeftWindow = /* @__PURE__ */ defineAsyncApi( + "showLeftWindow", + (_, { resolve, reject }) => { + const state2 = getLayoutState(); + if (!state2) { + reject(); + return; + } + state2.apiShowLeftWindow = true; + nextTick(resolve); + } +); +const hideLeftWindow = /* @__PURE__ */ defineAsyncApi( + "hideLeftWindow", + (_, { resolve, reject }) => { + const state2 = getLayoutState(); + if (!state2) { + reject(); + return; + } + state2.apiShowLeftWindow = false; + nextTick(resolve); + } +); +const showRightWindow = /* @__PURE__ */ defineAsyncApi( + "showRightWindow", + (_, { resolve, reject }) => { + const state2 = getLayoutState(); + if (!state2) { + reject(); + return; + } + state2.apiShowRightWindow = true; + nextTick(resolve); + } +); +const hideRightWindow = /* @__PURE__ */ defineAsyncApi( + "hideRightWindow", + (_, { resolve, reject }) => { + const state2 = getLayoutState(); + if (!state2) { + reject(); + return; + } + state2.apiShowRightWindow = false; + nextTick(resolve); + } +); +const getTopWindowStyle = /* @__PURE__ */ defineSyncApi( + "getTopWindowStyle", + () => { + const state2 = getLayoutState(); + return extend({}, state2 && state2.topWindowStyle); + } +); +const setTopWindowStyle = /* @__PURE__ */ defineSyncApi( + "setTopWindowStyle", + (style) => { + const state2 = getLayoutState(); + if (state2) { + state2.topWindowStyle = style; + } + } +); +const getLeftWindowStyle = /* @__PURE__ */ defineSyncApi( + "getLeftWindowStyle", + () => { + const state2 = getLayoutState(); + return extend({}, state2 && state2.leftWindowStyle); + } +); +const setLeftWindowStyle = /* @__PURE__ */ defineSyncApi( + "setLeftWindowStyle", + (style) => { + const state2 = getLayoutState(); + if (state2) { + state2.leftWindowStyle = style; + } + } +); +const getRightWindowStyle = /* @__PURE__ */ defineSyncApi("getRightWindowStyle", () => { + const state2 = getLayoutState(); + return extend({}, state2 && state2.rightWindowStyle); +}); +const setRightWindowStyle = /* @__PURE__ */ defineSyncApi("setRightWindowStyle", (style) => { + const state2 = getLayoutState(); + if (state2) { + state2.rightWindowStyle = style; + } +}); +const saveImageToPhotosAlbum = /* @__PURE__ */ defineAsyncApi( + API_SAVE_IMAGE_TO_PHOTOS_ALBUM, + createUnsupportedAsyncApi(API_SAVE_IMAGE_TO_PHOTOS_ALBUM) +); +const API_GET_RECORDER_MANAGER = "getRecorderManager"; +const getRecorderManager = /* @__PURE__ */ defineSyncApi( + API_GET_RECORDER_MANAGER, + createUnsupportedSyncApi(API_GET_RECORDER_MANAGER) +); +const saveVideoToPhotosAlbum = /* @__PURE__ */ defineAsyncApi( + API_SAVE_VIDEO_TO_PHOTOS_ALBUM, + createUnsupportedAsyncApi(API_SAVE_VIDEO_TO_PHOTOS_ALBUM) +); +const API_CREATE_CAMERA_CONTEXT = "createCameraContext"; +const createCameraContext = /* @__PURE__ */ defineSyncApi( + API_CREATE_CAMERA_CONTEXT, + createUnsupportedSyncApi(API_CREATE_CAMERA_CONTEXT) +); +const API_CREATE_LIVE_PLAYER_CONTEXT = "createLivePlayerContext"; +const createLivePlayerContext = /* @__PURE__ */ defineSyncApi( + API_CREATE_LIVE_PLAYER_CONTEXT, + createUnsupportedSyncApi(API_CREATE_LIVE_PLAYER_CONTEXT) +); +const API_SAVE_FILE = "saveFile"; +const saveFile = /* @__PURE__ */ defineAsyncApi( + API_SAVE_FILE, + createUnsupportedAsyncApi(API_SAVE_FILE) +); +const API_GET_SAVED_FILE_LIST = "getSavedFileList"; +const getSavedFileList = /* @__PURE__ */ defineAsyncApi( + API_GET_SAVED_FILE_LIST, + createUnsupportedAsyncApi(API_GET_SAVED_FILE_LIST) +); +const API_GET_SAVED_FILE_INFO = "getSavedFileInfo"; +const getSavedFileInfo = /* @__PURE__ */ defineAsyncApi( + API_GET_SAVED_FILE_INFO, + createUnsupportedAsyncApi(API_GET_SAVED_FILE_INFO) +); +const API_REMOVE_SAVED_FILE = "removeSavedFile"; +const removeSavedFile = /* @__PURE__ */ defineAsyncApi( + API_REMOVE_SAVED_FILE, + createUnsupportedAsyncApi(API_REMOVE_SAVED_FILE) +); +const API_ON_MEMORY_WARNING = "onMemoryWarning"; +const onMemoryWarning = /* @__PURE__ */ defineOnApi( + API_ON_MEMORY_WARNING, + createUnsupportedOnApi(API_ON_MEMORY_WARNING) +); +const API_ON_GYROSCOPE_CHANGE = "onGyroscopeChange"; +const onGyroscopeChange = /* @__PURE__ */ defineOnApi( + API_ON_GYROSCOPE_CHANGE, + createUnsupportedOnApi(API_ON_GYROSCOPE_CHANGE) +); +const API_START_GYROSCOPE = "startGyroscope"; +const startGyroscope = /* @__PURE__ */ defineAsyncApi( + API_START_GYROSCOPE, + createUnsupportedAsyncApi(API_START_GYROSCOPE) +); +const API_STOP_GYROSCOPE = "stopGyroscope"; +const stopGyroscope = /* @__PURE__ */ defineAsyncApi( + API_STOP_GYROSCOPE, + createUnsupportedAsyncApi(API_STOP_GYROSCOPE) +); +const API_SCAN_CODE = "scanCode"; +const scanCode = /* @__PURE__ */ defineAsyncApi( + API_SCAN_CODE, + createUnsupportedAsyncApi(API_SCAN_CODE) +); +const API_SET_SCREEN_BRIGHTNESS = "setScreenBrightness"; +const setScreenBrightness = /* @__PURE__ */ defineAsyncApi( + API_SET_SCREEN_BRIGHTNESS, + createUnsupportedAsyncApi(API_SET_SCREEN_BRIGHTNESS) +); +const API_GET_SCREEN_BRIGHTNESS = "getScreenBrightness"; +const getScreenBrightness = /* @__PURE__ */ defineAsyncApi( + API_GET_SCREEN_BRIGHTNESS, + createUnsupportedAsyncApi(API_GET_SCREEN_BRIGHTNESS) +); +const API_SET_KEEP_SCREEN_ON = "setKeepScreenOn"; +const setKeepScreenOn = /* @__PURE__ */ defineAsyncApi( + API_SET_KEEP_SCREEN_ON, + createUnsupportedAsyncApi(API_SET_KEEP_SCREEN_ON) +); +const API_ON_USER_CAPTURE_SCREEN = "onUserCaptureScreen"; +const onUserCaptureScreen = /* @__PURE__ */ defineOnApi( + API_ON_USER_CAPTURE_SCREEN, + createUnsupportedOnApi(API_ON_USER_CAPTURE_SCREEN) +); +const API_ADD_PHONE_CONTACT = "addPhoneContact"; +const addPhoneContact = /* @__PURE__ */ defineAsyncApi( + API_ADD_PHONE_CONTACT, + createUnsupportedAsyncApi(API_ADD_PHONE_CONTACT) +); +const API_LOGIN = "login"; +const login = /* @__PURE__ */ defineAsyncApi( + API_LOGIN, + createUnsupportedAsyncApi(API_LOGIN) +); +const API_GET_USER_INFO = "getUserInfo"; +const getUserInfo = /* @__PURE__ */ defineAsyncApi( + API_GET_USER_INFO, + (args, { resolve, reject }) => { + resolve(); + } +); +const API_CHECK_SESSION = "checkSession"; +const checkSession = /* @__PURE__ */ defineAsyncApi( + API_CHECK_SESSION, + (args, { resolve, reject }) => { + resolve(); + } +); +const API_GET_PROVIDER = "getProvider"; +const getProvider = /* @__PURE__ */ defineAsyncApi( + API_GET_PROVIDER, + createUnsupportedAsyncApi(API_GET_PROVIDER) +); +const api = /* @__PURE__ */ Object.defineProperty({ + __proto__: null, + $emit, + $off, + $on, + $once, + API_OFF_KEYBOARD_HEIGHT_CHANGE, + API_ON_KEYBOARD_HEIGHT_CHANGE, + addInterceptor, + addPhoneContact, + arrayBufferToBase64, + base64ToArrayBuffer, + canIUse, + canvasGetImageData, + canvasPutImageData, + canvasToTempFilePath, + checkSession, + chooseFile, + chooseImage, + chooseLocation, + chooseVideo, + clearStorage, + clearStorageSync, + closePreviewImage, + closeSocket, + connectSocket, + createAnimation: createAnimation$1, + createCameraContext, + createCanvasContext, + createInnerAudioContext, + createIntersectionObserver, + createLivePlayerContext, + createMapContext, + createMediaQueryObserver, + createSelectorQuery, + createVideoContext, + cssBackdropFilter, + cssConstant, + cssEnv, + cssVar, + downloadFile, + getAppBaseInfo, + getClipboardData, + getDeviceInfo, + getEnterOptionsSync, + getFileInfo, + getImageInfo, + getLaunchOptionsSync, + getLeftWindowStyle, + getLocale, + getLocation, + getNetworkType, + getProvider, + getPushClientId, + getRecorderManager, + getRightWindowStyle, + getSavedFileInfo, + getSavedFileList, + getScreenBrightness, + getSelectedTextRange: getSelectedTextRange$1, + getStorage, + getStorageInfo, + getStorageInfoSync, + getStorageSync, + getSystemInfo, + getSystemInfoSync, + getTopWindowStyle, + getUserInfo, + getVideoInfo, + getWindowInfo, + hideKeyboard, + hideLeftWindow, + hideLoading, + hideNavigationBarLoading, + hideRightWindow, + hideTabBar, + hideTabBarRedDot, + hideToast, + hideTopWindow, + interceptors, + invokePushCallback, + loadFontFace, + login, + makePhoneCall, + navigateBack, + navigateTo, + offAccelerometerChange, + offAppHide, + offAppShow, + offCompassChange, + offError, + offKeyboardHeightChange, + offLocationChange, + offLocationChangeError, + offNetworkStatusChange, + offPageNotFound, + offPushMessage, + offThemeChange: offThemeChange$1, + offUnhandledRejection, + offWindowResize, + onAccelerometerChange, + onAppHide, + onAppShow, + onCompassChange, + onCreateVueApp, + onError, + onGyroscopeChange, + onKeyboardHeightChange, + onLocaleChange, + onLocationChange, + onLocationChangeError, + onMemoryWarning, + onNetworkStatusChange, + onPageNotFound, + onPushMessage, + onSocketClose, + onSocketError, + onSocketMessage, + onSocketOpen, + onTabBarMidButtonTap, + onThemeChange: onThemeChange$1, + onUnhandledRejection, + onUserCaptureScreen, + onWindowResize, + openDocument, + openLocation, + pageScrollTo, + preloadPage, + previewImage, + reLaunch, + redirectTo, + removeInterceptor, + removeSavedFile, + removeStorage, + removeStorageSync, + removeTabBarBadge, + request, + saveFile, + saveImageToPhotosAlbum, + saveVideoToPhotosAlbum, + scanCode, + sendSocketMessage, + setClipboardData, + setKeepScreenOn, + setLeftWindowStyle, + setLocale, + setNavigationBarColor, + setNavigationBarTitle, + setPageMeta, + setRightWindowStyle, + setScreenBrightness, + setStorage, + setStorageSync, + setTabBarBadge, + setTabBarItem, + setTabBarStyle, + setTopWindowStyle, + showActionSheet, + showLeftWindow, + showLoading, + showModal, + showNavigationBarLoading, + showRightWindow, + showTabBar, + showTabBarRedDot, + showToast, + showTopWindow, + startAccelerometer, + startCompass, + startGyroscope, + startLocationUpdate, + startPullDownRefresh, + stopAccelerometer, + stopCompass, + stopGyroscope, + stopLocationUpdate, + stopPullDownRefresh, + switchTab, + uploadFile, + upx2px, + vibrateLong, + vibrateShort +}, Symbol.toStringTag, { value: "Module" }); +const CONTEXT_ID = "MAP_LOCATION"; +const MapLocation = /* @__PURE__ */ defineSystemComponent({ + name: "MapLocation", + setup() { + const state2 = reactive({ + latitude: 0, + longitude: 0, + rotate: 0 + }); + { + let compassChangeHandler = function(res) { + state2.rotate = res.direction; + }, updateLocation = function() { + getLocation({ + type: "gcj02", + success: (res) => { + state2.latitude = res.latitude; + state2.longitude = res.longitude; + }, + complete: () => { + timer = setTimeout(updateLocation, 3e4); + } + }); + }, removeLocation = function() { + if (timer) { + clearTimeout(timer); + } + offCompassChange(compassChangeHandler); + }; + const onMapReady = inject("onMapReady"); + let timer; + onCompassChange(compassChangeHandler); + onMapReady(updateLocation); + onUnmounted(removeLocation); + const addMapChidlContext = inject("addMapChidlContext"); + const removeMapChidlContext = inject("removeMapChidlContext"); + const context = { + id: CONTEXT_ID, + state: state2 + }; + addMapChidlContext(context); + onUnmounted(() => removeMapChidlContext(context)); + } + return () => { + return state2.latitude ? createVNode(MapMarker, mergeProps({ + "anchor": { + x: 0.5, + y: 0.5 + }, + "width": "44", + "height": "44", + "iconPath": ICON_PATH_ORIGIN + }, state2), null, 16, ["iconPath"]) : null; + }; + } +}); +const props$3 = { + // 边框虚线,腾讯地图支持,google 高德 地图不支持,默认值为[0, 0] 为实线,非 [0, 0] 为虚线,H5 端无法像微信小程序一样控制虚线的间隔像素大小 + dashArray: { + type: Array, + default: () => [0, 0] + }, + // 经纬度数组,[{latitude: 0, longitude: 0}] + points: { + type: Array, + required: true + }, + // 描边的宽度 + strokeWidth: { + type: Number, + default: 1 + }, + // 描边的颜色,十六进制 + strokeColor: { + type: String, + default: "#000000" + }, + // 填充颜色,十六进制 + fillColor: { + type: String, + default: "#00000000" + }, + // 设置多边形 Z 轴数值 + zIndex: { + type: Number, + default: 0 + } +}; +const MapPolygon = /* @__PURE__ */ defineSystemComponent({ + name: "MapPolygon", + props: props$3, + setup(props2) { + let polygonIns; + const onMapReady = inject("onMapReady"); + onMapReady((map, maps2, trigger) => { + function drawPolygon() { + const { + points, + strokeWidth, + strokeColor, + dashArray, + fillColor, + zIndex + } = props2; + const path = points.map((item) => { + const { + latitude, + longitude + } = item; + return getIsAMap() ? [longitude, latitude] : new maps2.LatLng(latitude, longitude); + }); + const { + r: fcR, + g: fcG, + b: fcB, + a: fcA + } = hexToRgba(fillColor); + const { + r: scR, + g: scG, + b: scB, + a: scA + } = hexToRgba(strokeColor); + const polygonOptions = { + //多边形是否可点击。 + clickable: true, + //鼠标在多边形内的光标样式。 + cursor: "crosshair", + //多边形是否可编辑。 + editable: false, + // 地图实例,即要显示多边形的地图 + // @ts-ignore + map, + // 区域填充色 + fillColor: "", + //多边形的路径,以经纬度坐标数组构成。 + path, + // 区域边框 + strokeColor: "", + //多边形的边框样式。实线是solid,虚线是dash。 + strokeDashStyle: dashArray.some((item) => item > 0) ? "dash" : "solid", + //多边形的边框线宽。 + strokeWeight: strokeWidth, + //多边形是否可见。 + visible: true, + //多边形的zIndex值。 + zIndex + }; + if (maps2.Color) { + polygonOptions.fillColor = new maps2.Color(fcR, fcG, fcB, fcA); + polygonOptions.strokeColor = new maps2.Color(scR, scG, scB, scA); + } else { + polygonOptions.fillColor = `rgb(${fcR}, ${fcG}, ${fcB})`; + polygonOptions.fillOpacity = fcA; + polygonOptions.strokeColor = `rgb(${scR}, ${scG}, ${scB})`; + polygonOptions.strokeOpacity = scA; + } + if (polygonIns) { + polygonIns.setOptions(polygonOptions); + return; + } + polygonIns = new maps2.Polygon(polygonOptions); + } + drawPolygon(); + watch(props2, drawPolygon); + }); + onUnmounted(() => { + polygonIns.setMap(null); + }); + return () => null; + } +}); +const props$2 = { + id: { + type: String, + default: "" + }, + latitude: { + type: [String, Number], + default: 0 + }, + longitude: { + type: [String, Number], + default: 0 + }, + scale: { + type: [String, Number], + default: 16 + }, + markers: { + type: Array, + default() { + return []; + } + }, + includePoints: { + type: Array, + default() { + return []; + } + }, + polyline: { + type: Array, + default() { + return []; + } + }, + circles: { + type: Array, + default() { + return []; + } + }, + controls: { + type: Array, + default() { + return []; + } + }, + showLocation: { + type: [Boolean, String], + default: false + }, + libraries: { + type: Array, + default() { + return []; + } + }, + polygons: { + type: Array, + default: () => [] + } +}; +function getPoints(points) { + const newPoints = []; + if (isArray(points)) { + points.forEach((point) => { + if (point && point.latitude && point.longitude) { + newPoints.push({ + latitude: point.latitude, + longitude: point.longitude + }); + } + }); + } + return newPoints; +} +function getAMapPosition(maps2, latitude, longitude) { + return new maps2.LngLat(longitude, latitude); +} +function getGoogleOrQQMapPosition(maps2, latitude, longitude) { + return new maps2.LatLng(latitude, longitude); +} +function getMapPosition(maps2, latitude, longitude) { + return getIsAMap() ? getAMapPosition(maps2, latitude, longitude) : getGoogleOrQQMapPosition(maps2, latitude, longitude); +} +function getLat(latLng) { + if ("getLat" in latLng) { + return latLng.getLat(); + } else { + return latLng.lat(); + } +} +function getLng(latLng) { + if ("getLng" in latLng) { + return latLng.getLng(); + } else { + return latLng.lng(); + } +} +function useMap(props2, rootRef, emit2) { + const trigger = useCustomEvent(rootRef, emit2); + const mapRef = ref(null); + let maps2; + let map; + const state2 = reactive({ + latitude: Number(props2.latitude), + longitude: Number(props2.longitude), + includePoints: getPoints(props2.includePoints) + }); + const onMapReadyCallbacks = []; + let isMapReady; + function onMapReady(callback) { + if (isMapReady) { + callback(map, maps2, trigger); + } else { + onMapReadyCallbacks.push(callback); + } + } + function emitMapReady() { + isMapReady = true; + onMapReadyCallbacks.forEach((callback) => callback(map, maps2, trigger)); + onMapReadyCallbacks.length = 0; + } + let isBoundsReady; + const onBoundsReadyCallbacks = []; + function onBoundsReady(callback) { + if (isBoundsReady) { + callback(); + } else { + onMapReadyCallbacks.push(callback); + } + } + const contexts = {}; + function addMapChidlContext(context) { + contexts[context.id] = context; + } + function removeMapChidlContext(context) { + delete contexts[context.id]; + } + watch([() => props2.latitude, () => props2.longitude], ([latitudeVlaue, longitudeVlaue]) => { + const latitude = Number(latitudeVlaue); + const longitude = Number(longitudeVlaue); + if (latitude !== state2.latitude || longitude !== state2.longitude) { + state2.latitude = latitude; + state2.longitude = longitude; + if (map) { + const centerPosition = getMapPosition(maps2, state2.latitude, state2.longitude); + map.setCenter(centerPosition); + } + } + }); + watch(() => props2.includePoints, (points) => { + state2.includePoints = getPoints(points); + if (isBoundsReady) { + updateBounds(); + } + }, { + deep: true + }); + function emitBoundsReady() { + isBoundsReady = true; + onBoundsReadyCallbacks.forEach((callback) => callback()); + onBoundsReadyCallbacks.length = 0; + } + function getMapInfo2() { + const center = map.getCenter(); + return { + scale: map.getZoom(), + centerLocation: { + latitude: getLat(center), + longitude: getLng(center) + } + }; + } + function updateCenter() { + const centerPosition = getMapPosition(maps2, state2.latitude, state2.longitude); + map.setCenter(centerPosition); + } + function updateBounds() { + if (getIsAMap()) { + const points = []; + state2.includePoints.forEach((point) => { + points.push([point.longitude, point.latitude]); + }); + const bounds = new maps2.Bounds(...points); + map.setBounds(bounds); + } else { + const bounds = new maps2.LatLngBounds(); + state2.includePoints.forEach(({ + latitude, + longitude + }) => { + const latLng = new maps2.LatLng(latitude, longitude); + bounds.extend(latLng); + }); + map.fitBounds(bounds); + } + } + function initMap() { + const mapEl = mapRef.value; + const center = getMapPosition(maps2, state2.latitude, state2.longitude); + const event = maps2.event || maps2.Event; + const map2 = new maps2.Map(mapEl, { + center, + zoom: Number(props2.scale), + // scrollwheel: false, + disableDoubleClickZoom: true, + mapTypeControl: false, + zoomControl: false, + scaleControl: false, + panControl: false, + fullscreenControl: false, + streetViewControl: false, + keyboardShortcuts: false, + minZoom: 5, + maxZoom: 18, + draggable: true + }); + watch(() => props2.scale, (scale) => { + map2.setZoom(Number(scale) || 16); + }); + onBoundsReady(() => { + if (state2.includePoints.length) { + updateBounds(); + updateCenter(); + } + }); + const boundsChangedEvent = event.addListener(map2, "bounds_changed", () => { + boundsChangedEvent.remove(); + emitBoundsReady(); + }); + event.addListener(map2, "click", () => { + trigger("tap", {}, {}); + trigger("click", {}, {}); + }); + event.addListener(map2, "dragstart", () => { + trigger("regionchange", {}, { + type: "begin", + causedBy: "gesture" + }); + }); + event.addListener(map2, "dragend", () => { + trigger("regionchange", {}, extend({ + type: "end", + causedBy: "drag" + }, getMapInfo2())); + }); + const zoomChangedCallback = () => { + emit2("update:scale", map2.getZoom()); + trigger("regionchange", {}, extend({ + type: "end", + causedBy: "scale" + }, getMapInfo2())); + }; + event.addListener(map2, "zoom_changed", zoomChangedCallback); + event.addListener(map2, "zoomend", zoomChangedCallback); + event.addListener(map2, "center_changed", () => { + const center2 = map2.getCenter(); + const latitude = getLat(center2); + const longitude = getLng(center2); + emit2("update:latitude", latitude); + emit2("update:longitude", longitude); + }); + return map2; + } + try { + const id2 = useContextInfo(); + useSubscribe((type, data = {}) => { + switch (type) { + case "getCenterLocation": + onMapReady(() => { + const center = map.getCenter(); + callOptions(data, { + latitude: getLat(center), + longitude: getLng(center), + errMsg: `${type}:ok` + }); + }); + break; + case "moveToLocation": + { + let latitude = Number(data.latitude); + let longitude = Number(data.longitude); + if (!latitude || !longitude) { + const context = contexts[CONTEXT_ID]; + if (context) { + latitude = context.state.latitude; + longitude = context.state.longitude; + } + } + if (latitude && longitude) { + state2.latitude = latitude; + state2.longitude = longitude; + if (map) { + const centerPosition = getMapPosition(maps2, latitude, longitude); + map.setCenter(centerPosition); + } + onMapReady(() => { + callOptions(data, `${type}:ok`); + }); + } else { + callOptions(data, `${type}:fail`); + } + } + break; + case "translateMarker": + onMapReady(() => { + const context = contexts[data.markerId]; + if (context) { + try { + context.translate(data); + } catch (error) { + callOptions(data, `${type}:fail ${error.message}`); + } + callOptions(data, `${type}:ok`); + } else { + callOptions(data, `${type}:fail not found`); + } + }); + break; + case "includePoints": + state2.includePoints = getPoints(data.includePoints); + if (isBoundsReady || getIsAMap()) { + updateBounds(); + } + onBoundsReady(() => { + callOptions(data, `${type}:ok`); + }); + break; + case "getRegion": + onBoundsReady(() => { + const latLngBounds = map.getBounds(); + const southwest = latLngBounds.getSouthWest(); + const northeast = latLngBounds.getNorthEast(); + callOptions(data, { + southwest: { + latitude: getLat(southwest), + longitude: getLng(southwest) + }, + northeast: { + latitude: getLat(northeast), + longitude: getLng(northeast) + }, + errMsg: `${type}:ok` + }); + }); + break; + case "getScale": + onMapReady(() => { + callOptions(data, { + scale: map.getZoom(), + errMsg: `${type}:ok` + }); + }); + break; + } + }, id2, true); + } catch (error) { + } + onMounted(() => { + loadMaps(props2.libraries, (result) => { + maps2 = result; + map = initMap(); + emitMapReady(); + trigger("updated", {}, {}); + }); + }); + provide("onMapReady", onMapReady); + provide("addMapChidlContext", addMapChidlContext); + provide("removeMapChidlContext", removeMapChidlContext); + return { + state: state2, + mapRef, + trigger + }; +} +const Map$1 = /* @__PURE__ */ defineBuiltInComponent({ + name: "Map", + props: props$2, + emits: ["markertap", "labeltap", "callouttap", "controltap", "regionchange", "tap", "click", "updated", "update:scale", "update:latitude", "update:longitude"], + setup(props2, { + emit: emit2, + slots + }) { + const rootRef = ref(null); + const { + mapRef, + trigger + } = useMap(props2, rootRef, emit2); + return () => { + return createVNode("uni-map", { + "ref": rootRef, + "id": props2.id + }, [createVNode("div", { + "ref": mapRef, + "style": "width: 100%; height: 100%; position: relative; overflow: hidden" + }, null, 512), props2.markers.map((item) => createVNode(MapMarker, mergeProps({ + "key": item.id + }, item), null, 16)), props2.polyline.map((item) => createVNode(MapPolyline, item, null, 16)), props2.circles.map((item) => createVNode(MapCircle, item, null, 16)), props2.controls.map((item) => createVNode(MapControl, mergeProps(item, { + "trigger": trigger + }), null, 16, ["trigger"])), props2.showLocation && createVNode(MapLocation, null, null), props2.polygons.map((item) => createVNode(MapPolygon, item, null, 16)), createVNode("div", { + "style": "position: absolute;top: 0;width: 100%;height: 100%;overflow: hidden;pointer-events: none;" + }, [slots.default && slots.default()])], 8, ["id"]); + }; + } +}); +const props$1 = { + scrollTop: { + type: [String, Number], + default: 0 + } +}; +const index$9 = /* @__PURE__ */ defineBuiltInComponent({ + name: "CoverView", + compatConfig: { + MODE: 3 + }, + props: props$1, + setup(props2, { + slots + }) { + const content = ref(null); + watch(() => props2.scrollTop, (val) => { + setScrollTop(val); + }); + function setScrollTop(val) { + let _content = content.value; + if (getComputedStyle(_content).overflowY === "scroll") { + _content.scrollTop = _upx2pxNum(val); + } + } + function _upx2pxNum(val) { + let _val = String(val); + if (/\d+[ur]px$/i.test(_val)) { + _val.replace(/\d+[ur]px$/i, (text2) => { + return String(uni.upx2px(parseFloat(text2))); + }); + } + return parseFloat(_val) || 0; + } + onMounted(() => { + setScrollTop(props2.scrollTop); + }); + return () => { + return createVNode("uni-cover-view", { + "scroll-top": props2.scrollTop + }, [createVNode("div", { + "ref": content, + "class": "uni-cover-view" + }, [slots.default && slots.default()], 512)], 8, ["scroll-top"]); + }; + } +}); +const index$8 = /* @__PURE__ */ defineBuiltInComponent({ + name: "CoverImage", + compatConfig: { + MODE: 3 + }, + props: { + src: { + type: String, + default: "" + } + }, + emits: ["load", "error"], + setup(props2, { + emit: emit2 + }) { + const root = ref(null); + const trigger = useCustomEvent(root, emit2); + function load($event) { + trigger("load", $event); + } + function error($event) { + trigger("error", $event); + } + return () => { + const { + src + } = props2; + return createVNode("uni-cover-image", { + "ref": root, + "src": src + }, [createVNode("div", { + "class": "uni-cover-image" + }, [src ? createVNode("img", { + "src": getRealPath(src), + "onLoad": load, + "onError": error + }, null, 40, ["src", "onLoad", "onError"]) : null])], 8, ["src"]); + }; + } +}); +function _isSlot(s) { + return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s); +} +function getDefaultStartValue(props2) { + if (props2.mode === mode.TIME) { + return "00:00"; + } + if (props2.mode === mode.DATE) { + const year = (/* @__PURE__ */ new Date()).getFullYear() - 150; + switch (props2.fields) { + case fields.YEAR: + return year.toString(); + case fields.MONTH: + return year + "-01"; + default: + return year + "-01-01"; + } + } + return ""; +} +function getDefaultEndValue(props2) { + if (props2.mode === mode.TIME) { + return "23:59"; + } + if (props2.mode === mode.DATE) { + const year = (/* @__PURE__ */ new Date()).getFullYear() + 150; + switch (props2.fields) { + case fields.YEAR: + return year.toString(); + case fields.MONTH: + return year + "-12"; + default: + return year + "-12-31"; + } + } + return ""; +} +function getDateValueArray(props2, state2, valueStr, defaultValue) { + const splitStr = props2.mode === mode.DATE ? "-" : ":"; + const array = props2.mode === mode.DATE ? state2.dateArray : state2.timeArray; + let max; + if (props2.mode === mode.TIME) { + max = 2; + } else { + switch (props2.fields) { + case fields.YEAR: + max = 1; + break; + case fields.MONTH: + max = 2; + break; + default: + max = 3; + break; + } + } + const inputArray = String(valueStr).split(splitStr); + let value = []; + for (let i = 0; i < max; i++) { + const val = inputArray[i]; + value.push(array[i].indexOf(val)); + } + if (value.indexOf(-1) >= 0) { + value = defaultValue ? getDateValueArray(props2, state2, defaultValue) : value.map(() => 0); + } + return value; +} +const mode = { + SELECTOR: "selector", + MULTISELECTOR: "multiSelector", + TIME: "time", + DATE: "date" + // 暂不支持城市选择 + // REGION: 'region' +}; +const fields = { + YEAR: "year", + MONTH: "month", + DAY: "day" +}; +const selectorType = { + PICKER: "picker", + SELECT: "select" +}; +const props = { + name: { + type: String, + default: "" + }, + range: { + type: Array, + default() { + return []; + } + }, + rangeKey: { + type: String, + default: "" + }, + value: { + type: [Number, String, Array], + default: 0 + }, + mode: { + type: String, + default: mode.SELECTOR, + validator(val) { + return Object.values(mode).includes(val); + } + }, + fields: { + type: String, + default: "" + }, + start: { + type: String, + default: (props2) => { + return getDefaultStartValue(props2); + } + }, + end: { + type: String, + default: (props2) => { + return getDefaultEndValue(props2); + } + }, + disabled: { + type: [Boolean, String], + default: false + }, + selectorType: { + type: String, + default: "" + } +}; +const index$7 = /* @__PURE__ */ defineBuiltInComponent({ + name: "Picker", + compatConfig: { + MODE: 3 + }, + props, + emits: ["change", "cancel", "columnchange"], + setup(props2, { + emit: emit2, + slots + }) { + initI18nPickerMsgsOnce(); + const { + t: t2 + } = useI18n(); + const rootRef = ref(null); + const pickerRef = ref(null); + const selectRef = ref(null); + const inputRef = ref(null); + const pickerRender = ref(false); + const { + state: state2, + rangeArray + } = usePickerState(props2); + const trigger = useCustomEvent(rootRef, emit2); + const { + system, + selectorTypeComputed, + _show, + _l10nColumn, + _l10nItem, + _input, + _fixInputPosition, + _pickerViewChange, + _cancel, + _change, + _resetFormData, + _getFormData, + _createTime, + _createDate, + _setValueSync + } = usePickerMethods(props2, state2, trigger, rootRef, pickerRef, selectRef, inputRef); + usePickerWatch(state2, _cancel, _change); + usePickerForm(_resetFormData, _getFormData); + _createTime(); + _createDate(); + _setValueSync(); + const popup = usePopupStyle(state2); + watchEffect(() => { + state2.isDesktop = popup.isDesktop.value; + state2.popupStyle = popup.popupStyle.value; + }); + onBeforeUnmount(() => { + pickerRef.value && pickerRef.value.remove(); + }); + onMounted(() => { + pickerRender.value = true; + }); + return () => { + let _slot2; + const { + visible, + contentVisible, + valueArray, + popupStyle, + valueSync + } = state2; + const { + rangeKey, + mode: mode2, + start, + end + } = props2; + const booleanAttrs = useBooleanAttr(props2, "disabled"); + return createVNode("uni-picker", mergeProps({ + "ref": rootRef + }, booleanAttrs, { + "onClick": withWebEvent(_show) + }), [pickerRender.value ? createVNode("div", { + "ref": pickerRef, + "class": ["uni-picker-container", `uni-${mode2}-${selectorTypeComputed.value}`], + "onWheel": onEventPrevent, + "onTouchmove": onEventPrevent + }, [createVNode(Transition, { + "name": "uni-fade" + }, { + default: () => [withDirectives(createVNode("div", { + "class": "uni-mask uni-picker-mask", + "onClick": withWebEvent(_cancel), + "onMousemove": _fixInputPosition + }, null, 40, ["onClick", "onMousemove"]), [[vShow, visible]])] + }), !system.value ? createVNode("div", { + "class": [{ + "uni-picker-toggle": visible + }, "uni-picker-custom"], + "style": popupStyle.content + }, [createVNode("div", { + "class": "uni-picker-header", + "onClick": onEventStop + }, [createVNode("div", { + "class": "uni-picker-action uni-picker-action-cancel", + "onClick": withWebEvent(_cancel) + }, [t2("uni.picker.cancel")], 8, ["onClick"]), createVNode("div", { + "class": "uni-picker-action uni-picker-action-confirm", + "onClick": _change + }, [t2("uni.picker.done")], 8, ["onClick"])], 8, ["onClick"]), contentVisible ? createVNode(PickerView, { + "value": _l10nColumn(valueArray), + "class": "uni-picker-content", + "onChange": _pickerViewChange + }, _isSlot(_slot2 = renderList(_l10nColumn(rangeArray.value), (rangeItem, index0) => { + let _slot; + return createVNode(PickerViewColumn, { + "key": index0 + }, _isSlot(_slot = renderList(rangeItem, (item, index2) => createVNode("div", { + "key": index2, + "class": "uni-picker-item" + }, [typeof item === "object" ? item[rangeKey] || "" : _l10nItem(item, index0)]))) ? _slot : { + default: () => [_slot], + _: 1 + }); + })) ? _slot2 : { + default: () => [_slot2], + _: 1 + }, 8, ["value", "onChange"]) : null, createVNode("div", { + "ref": selectRef, + "class": "uni-picker-select", + "onWheel": onEventStop, + "onTouchmove": onEventStop + }, [renderList(rangeArray.value[0], (item, index2) => createVNode("div", { + "key": index2, + "class": ["uni-picker-item", { + selected: valueArray[0] === index2 + }], + "onClick": () => { + valueArray[0] = index2; + _change(); + } + }, [typeof item === "object" ? item[rangeKey] || "" : item], 10, ["onClick"]))], 40, ["onWheel", "onTouchmove"]), createVNode("div", { + "style": popupStyle.triangle + }, null, 4)], 6) : null], 40, ["onWheel", "onTouchmove"]) : null, createVNode("div", null, [slots.default && slots.default()]), system.value ? createVNode("div", { + "class": "uni-picker-system", + "onMousemove": withWebEvent(_fixInputPosition) + }, [createVNode("input", { + "class": ["uni-picker-system_input", system.value], + "ref": inputRef, + "value": valueSync, + "type": mode2, + "tabindex": "-1", + "min": start, + "max": end, + "onChange": ($event) => { + _input($event); + onEventStop($event); + } + }, null, 42, ["value", "type", "min", "max", "onChange"])], 40, ["onMousemove"]) : null], 16, ["onClick"]); + }; + } +}); +function usePickerState(props2) { + const state2 = reactive({ + valueSync: void 0, + visible: false, + contentVisible: false, + popover: null, + valueChangeSource: "", + timeArray: [], + dateArray: [], + valueArray: [], + oldValueArray: [], + isDesktop: false, + popupStyle: { + content: {}, + triangle: {} + } + }); + const rangeArray = computed(() => { + let val = props2.range; + switch (props2.mode) { + case mode.SELECTOR: + return [val]; + case mode.MULTISELECTOR: + return val; + case mode.TIME: + return state2.timeArray; + case mode.DATE: { + const dateArray = state2.dateArray; + switch (props2.fields) { + case fields.YEAR: + return [dateArray[0]]; + case fields.MONTH: + return [dateArray[0], dateArray[1]]; + default: + return [dateArray[0], dateArray[1], dateArray[2]]; + } + } + } + return []; + }); + return { + state: state2, + rangeArray + }; +} +const getiPadFlag = () => String(navigator.vendor).indexOf("Apple") === 0 && navigator.maxTouchPoints > 0; +function useIsiPad() { + const isiPad = ref(false); + { + isiPad.value = getiPadFlag(); + } + return isiPad; +} +const getSystem = () => { + if (/win|mac/i.test(navigator.platform)) { + if (navigator.vendor === "Google Inc.") { + return "chrome"; + } else if (/Firefox/.test(navigator.userAgent)) { + return "firefox"; + } + } + return ""; +}; +function useSystem() { + const _system = ref(""); + { + _system.value = getSystem(); + } + return _system; +} +let __contentVisibleDelay; +function usePickerMethods(props2, state2, trigger, rootRef, pickerRef, selectRef, inputRef) { + const isiPad = useIsiPad(); + const _system = useSystem(); + const selectorTypeComputed = computed(() => { + const type = props2.selectorType; + if (Object.values(selectorType).includes(type)) { + return type; + } + return isiPad.value ? selectorType.PICKER : selectorType.SELECT; + }); + const system = computed(() => { + if (props2.mode === mode.DATE && !Object.values(fields).includes(props2.fields) && state2.isDesktop) { + return _system.value; + } + return ""; + }); + const startArray = computed(() => { + return getDateValueArray(props2, state2, props2.start, getDefaultStartValue(props2)); + }); + const endArray = computed(() => { + return getDateValueArray(props2, state2, props2.end, getDefaultEndValue(props2)); + }); + function _show(event) { + if (props2.disabled) { + return; + } + state2.valueChangeSource = ""; + let $picker = pickerRef.value; + let _currentTarget = event.currentTarget; + $picker.remove(); + (document.querySelector("uni-app") || document.body).appendChild($picker); + $picker.style.display = "block"; + const rect = _currentTarget.getBoundingClientRect(); + state2.popover = { + top: rect.top, + left: rect.left, + width: rect.width, + height: rect.height + }; + setTimeout(() => { + state2.visible = true; + }, 20); + } + function _getFormData() { + return { + value: state2.valueSync, + key: props2.name + }; + } + function _resetFormData() { + switch (props2.mode) { + case mode.SELECTOR: + state2.valueSync = 0; + break; + case mode.MULTISELECTOR: + state2.valueSync = props2.value.map((val) => 0); + break; + case mode.DATE: + case mode.TIME: + state2.valueSync = ""; + break; + } + } + function _createTime() { + let hours = []; + let minutes = []; + for (let i = 0; i < 24; i++) { + hours.push((i < 10 ? "0" : "") + i); + } + for (let i = 0; i < 60; i++) { + minutes.push((i < 10 ? "0" : "") + i); + } + state2.timeArray.push(hours, minutes); + } + function getYearStartEnd() { + let year = (/* @__PURE__ */ new Date()).getFullYear(); + let start = year - 150; + let end = year + 150; + if (props2.start) { + const _year = new Date(props2.start).getFullYear(); + if (!isNaN(_year) && _year < start) { + start = _year; + } + } + if (props2.end) { + const _year = new Date(props2.end).getFullYear(); + if (!isNaN(_year) && _year > end) { + end = _year; + } + } + return { + start, + end + }; + } + function _createDate() { + let years = []; + const year = getYearStartEnd(); + for (let i = year.start, end = year.end; i <= end; i++) { + years.push(String(i)); + } + let months = []; + for (let i = 1; i <= 12; i++) { + months.push((i < 10 ? "0" : "") + i); + } + let days = []; + for (let i = 1; i <= 31; i++) { + days.push((i < 10 ? "0" : "") + i); + } + state2.dateArray.push(years, months, days); + } + function _getTimeValue(val) { + return val[0] * 60 + val[1]; + } + function _getDateValue(val) { + const DAY = 31; + return val[0] * DAY * 12 + (val[1] || 0) * DAY + (val[2] || 0); + } + function _cloneArray(val1, val2) { + for (let i = 0; i < val1.length && i < val2.length; i++) { + val1[i] = val2[i]; + } + } + function _setValueSync() { + let val = props2.value; + switch (props2.mode) { + case mode.MULTISELECTOR: + { + if (!isArray(val)) { + val = state2.valueArray; + } + if (!isArray(state2.valueSync)) { + state2.valueSync = []; + } + const length = state2.valueSync.length = Math.max(val.length, props2.range.length); + for (let index2 = 0; index2 < length; index2++) { + const val0 = Number(val[index2]); + const val1 = Number(state2.valueSync[index2]); + const val2 = isNaN(val0) ? isNaN(val1) ? 0 : val1 : val0; + const maxVal = props2.range[index2] ? props2.range[index2].length - 1 : 0; + state2.valueSync.splice(index2, 1, val2 < 0 || val2 > maxVal ? 0 : val2); + } + } + break; + case mode.TIME: + case mode.DATE: + state2.valueSync = String(val); + break; + default: { + const valueSync = Number(val); + state2.valueSync = valueSync < 0 ? 0 : valueSync; + break; + } + } + } + function _setValueArray() { + let val = state2.valueSync; + let valueArray; + switch (props2.mode) { + case mode.MULTISELECTOR: + valueArray = [...val]; + break; + case mode.TIME: + valueArray = getDateValueArray(props2, state2, val, formatDateTime({ + mode: mode.TIME + })); + break; + case mode.DATE: + valueArray = getDateValueArray(props2, state2, val, formatDateTime({ + mode: mode.DATE + })); + break; + default: + valueArray = [val]; + break; + } + state2.oldValueArray = [...valueArray]; + state2.valueArray = [...valueArray]; + } + function _getValue() { + let val = state2.valueArray; + switch (props2.mode) { + case mode.SELECTOR: + return val[0]; + case mode.MULTISELECTOR: + return val.map((val2) => val2); + case mode.TIME: + return state2.valueArray.map((val2, i) => state2.timeArray[i][val2]).join(":"); + case mode.DATE: + return state2.valueArray.map((val2, i) => state2.dateArray[i][val2]).join("-"); + } + } + function _change() { + _close(); + state2.valueChangeSource = "click"; + const value = _getValue(); + state2.valueSync = isArray(value) ? value.map((val) => val) : value; + trigger("change", {}, { + value + }); + } + function _cancel($event) { + if (system.value === "firefox" && $event) { + const { + top, + left, + width, + height + } = state2.popover; + const { + pageX, + pageY + } = $event; + if (pageX > left && pageX < left + width && pageY > top && pageY < top + height) { + return; + } + } + _close(); + trigger("cancel", {}, {}); + } + function _close() { + state2.visible = false; + setTimeout(() => { + let $picker = pickerRef.value; + $picker.remove(); + rootRef.value.prepend($picker); + $picker.style.display = "none"; + }, 260); + } + function _select() { + if (props2.mode === mode.SELECTOR && selectorTypeComputed.value === selectorType.SELECT) { + selectRef.value.scrollTop = state2.valueArray[0] * 34; + } + } + function _input($event) { + const EventTarget = $event.target; + state2.valueSync = EventTarget.value; + nextTick(() => { + _change(); + }); + } + function _fixInputPosition($event) { + if (system.value === "chrome") { + const rect = rootRef.value.getBoundingClientRect(); + const fontSize = 32; + inputRef.value.style.left = `${$event.clientX - rect.left - fontSize * 1.5}px`; + inputRef.value.style.top = `${$event.clientY - rect.top - fontSize * 0.5}px`; + } + } + function _pickerViewChange(event) { + state2.valueArray = _l10nColumn(event.detail.value, true); + } + function _l10nColumn(array, normalize) { + const { + getLocale: getLocale2 + } = useI18n(); + if (props2.mode === mode.DATE) { + const locale = getLocale2(); + if (!locale.startsWith("zh")) { + switch (props2.fields) { + case fields.YEAR: + return array; + case fields.MONTH: + return [array[1], array[0]]; + default: + switch (locale) { + case "es": + case "fr": + return [array[2], array[1], array[0]]; + default: + return normalize ? [array[2], array[0], array[1]] : [array[1], array[2], array[0]]; + } + } + } + } + return array; + } + function _l10nItem(item, index2) { + const { + getLocale: getLocale2 + } = useI18n(); + if (props2.mode === mode.DATE) { + const locale = getLocale2(); + if (locale.startsWith("zh")) { + const array = ["年", "月", "日"]; + return item + array[index2]; + } else if (props2.fields !== fields.YEAR && index2 === (props2.fields !== fields.MONTH && (locale === "es" || locale === "fr") ? 1 : 0)) { + let array; + switch (locale) { + case "es": + array = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "​​julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]; + break; + case "fr": + array = ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; + break; + default: + array = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + break; + } + return array[Number(item) - 1]; + } + } + return item; + } + watch(() => state2.visible, (val) => { + if (val) { + clearTimeout(__contentVisibleDelay); + state2.contentVisible = val; + _select(); + } else { + __contentVisibleDelay = setTimeout(() => { + state2.contentVisible = val; + }, 300); + } + }); + watch([() => props2.mode, () => props2.value, () => props2.range], _setValueSync, { + deep: true + }); + watch(() => state2.valueSync, _setValueArray, { + deep: true + }); + watch(() => state2.valueArray, (val) => { + if (props2.mode === mode.TIME || props2.mode === mode.DATE) { + const getValue = props2.mode === mode.TIME ? _getTimeValue : _getDateValue; + const valueArray = state2.valueArray; + const _startArray = startArray.value; + const _endArray = endArray.value; + if (props2.mode === mode.DATE) { + const dateArray = state2.dateArray; + const max = dateArray[2].length; + const day = Number(dateArray[2][valueArray[2]]) || 1; + const realDay = (/* @__PURE__ */ new Date(`${dateArray[0][valueArray[0]]}/${dateArray[1][valueArray[1]]}/${day}`)).getDate(); + if (realDay < day) { + valueArray[2] -= realDay + max - day; + } + } + if (getValue(valueArray) < getValue(_startArray)) { + _cloneArray(valueArray, _startArray); + } else if (getValue(valueArray) > getValue(_endArray)) { + _cloneArray(valueArray, _endArray); + } + } + val.forEach((value, column) => { + if (value !== state2.oldValueArray[column]) { + state2.oldValueArray[column] = value; + if (props2.mode === mode.MULTISELECTOR) { + trigger("columnchange", {}, { + column, + value + }); + } + } + }); + }); + return { + selectorTypeComputed, + system, + _show, + _cancel, + _change, + _l10nColumn, + _l10nItem, + _input, + _resetFormData, + _getFormData, + _createTime, + _createDate, + _setValueSync, + _fixInputPosition, + _pickerViewChange + }; +} +function usePickerWatch(state2, _cancel, _change) { + const { + key, + disable + } = useKeyboard(); + watchEffect(() => { + disable.value = !state2.visible; + }); + watch(key, (value) => { + if (value === "esc") { + _cancel(); + } else if (value === "enter") { + _change(); + } + }); +} +function usePickerForm(_resetFormData, _getFormData) { + const uniForm = inject(uniFormKey, false); + if (uniForm) { + const field = { + reset: _resetFormData, + submit: () => { + const data = ["", null]; + const { + key, + value + } = _getFormData(); + if (key !== "") { + data[0] = key; + data[1] = value; + } + return data; + } + }; + uniForm.addField(field); + onBeforeUnmount(() => { + uniForm.removeField(field); + }); + } +} +const index$6 = /* @__PURE__ */ defineUnsupportedComponent("ad"); +const index$5 = /* @__PURE__ */ defineUnsupportedComponent("ad-content-page"); +const index$4 = /* @__PURE__ */ defineUnsupportedComponent("ad-draw"); +const index$3 = /* @__PURE__ */ defineUnsupportedComponent("camera"); +const index$2 = /* @__PURE__ */ defineUnsupportedComponent("live-player"); +const index$1 = /* @__PURE__ */ defineUnsupportedComponent("live-pusher"); +const UniViewJSBridge$1 = /* @__PURE__ */ extend(ViewJSBridge, { + publishHandler(event, args, pageId) { + UniServiceJSBridge.subscribeHandler(event, args, pageId); + } +}); +const uni$1 = api; +const UniServiceJSBridge$1 = /* @__PURE__ */ extend(ServiceJSBridge, { + publishHandler(event, args, pageId) { + UniViewJSBridge.subscribeHandler(event, args, pageId); + } +}); +function usePageHeadTransparentBackgroundColor(backgroundColor) { + const { r, g: g2, b } = hexToRgba(backgroundColor); + return `rgba(${r},${g2},${b},0)`; +} +function usePageHeadTransparent(headRef, { + id: id2, + navigationBar: { titleColor, coverage, backgroundColor } +}) { + let A = 0; + const rgb = computed(() => hexToRgba(backgroundColor)); + const offset = parseInt(coverage); + let titleElem; + let transparentElemStyle; + const iconElemsPaths = []; + const borderRadiusElemsStyles = []; + const oldColors = []; + onMounted(() => { + const $el = headRef.value; + transparentElemStyle = $el.style; + titleElem = $el.querySelector(".uni-page-head__title"); + const borderRadiusElems = $el.querySelectorAll( + ".uni-page-head-btn" + ); + const iconSvgElems = $el.querySelectorAll( + "svg path" + ); + for (let i = 0; i < iconSvgElems.length; i++) { + iconElemsPaths.push(iconSvgElems[i]); + } + for (let i = 0; i < borderRadiusElems.length; i++) { + const borderRadiusElem = borderRadiusElems[i]; + oldColors.push(getComputedStyle(borderRadiusElem).backgroundColor); + borderRadiusElemsStyles.push(borderRadiusElem.style); + } + }); + useOn(id2 + ".onPageScroll", ({ scrollTop }) => { + const alpha = Math.min(scrollTop / offset, 1); + if (alpha === 1 && A === 1) { + return; + } + if (alpha > 0.5 && A <= 0.5) { + iconElemsPaths.forEach(function(iconElemPath) { + iconElemPath.setAttribute("fill", titleColor); + }); + } else if (alpha <= 0.5 && A > 0.5) { + iconElemsPaths.forEach(function(iconElemPath) { + iconElemPath.setAttribute("fill", "#fff"); + }); + } + A = alpha; + if (titleElem) { + titleElem.style.opacity = alpha; + } + const bg = rgb.value; + transparentElemStyle.backgroundColor = `rgba(${bg.r},${bg.g},${bg.b},${alpha})`; + borderRadiusElemsStyles.forEach(function(borderRadiusElemStyle, index2) { + const oldColor = oldColors[index2]; + const rgba = oldColor.match(/[\d+\.]+/g); + rgba[3] = (1 - alpha) * (rgba.length === 4 ? rgba[3] : 1); + borderRadiusElemStyle.backgroundColor = `rgba(${rgba})`; + }); + }); +} +const ICON_PATHS = { + none: "", + forward: "M11 7.844q-0.25-0.219-0.25-0.578t0.25-0.578q0.219-0.25 0.563-0.25t0.563 0.25l9.656 9.125q0.125 0.125 0.188 0.297t0.063 0.328q0 0.188-0.063 0.359t-0.188 0.297l-9.656 9.125q-0.219 0.25-0.563 0.25t-0.563-0.25q-0.25-0.219-0.25-0.578t0.25-0.609l9.063-8.594-9.063-8.594z", + back: ICON_PATH_BACK, + select: ICON_PATH_BACK, + share: "M26.563 24.844q0 0.125-0.109 0.234t-0.234 0.109h-17.938q-0.125 0-0.219-0.109t-0.094-0.234v-13.25q0-0.156 0.094-0.25t0.219-0.094h5.5v-1.531h-6q-0.531 0-0.906 0.391t-0.375 0.922v14.375q0 0.531 0.375 0.922t0.906 0.391h18.969q0.531 0 0.891-0.391t0.359-0.953v-5.156h-1.438v4.625zM29.813 10.969l-5.125-5.375-1.031 1.094 3.438 3.594-3.719 0.031q-2.313 0.188-4.344 1.125t-3.578 2.422-2.5 3.453-1.109 4.188l-0.031 0.25h1.469v-0.219q0.156-1.875 1-3.594t2.25-3.063 3.234-2.125 3.828-0.906l0.188-0.031 3.313-0.031-3.438 3.625 1.031 1.063 5.125-5.375-0.031-0.063 0.031-0.063z", + favorite: "M27.594 13.375q-0.063-0.188-0.219-0.313t-0.344-0.156l-7.094-0.969-3.219-6.406q-0.094-0.188-0.25-0.281t-0.375-0.094q-0.188 0-0.344 0.094t-0.25 0.281l-3.125 6.438-7.094 1.094q-0.188 0.031-0.344 0.156t-0.219 0.313q-0.031 0.188 0.016 0.375t0.172 0.313l5.156 4.969-1.156 7.063q-0.031 0.188 0.047 0.375t0.234 0.313q0.094 0.063 0.188 0.094t0.219 0.031q0.063 0 0.141-0.031t0.172-0.063l6.313-3.375 6.375 3.313q0.063 0.031 0.141 0.047t0.172 0.016q0.188 0 0.344-0.094t0.25-0.281q0.063-0.094 0.078-0.234t-0.016-0.234q0-0.031 0-0.063l-1.25-6.938 5.094-5.031q0.156-0.156 0.203-0.344t-0.016-0.375zM11.469 19.063q0.031-0.188-0.016-0.344t-0.172-0.281l-4.406-4.25 6.063-0.906q0.156-0.031 0.297-0.125t0.203-0.25l2.688-5.531 2.75 5.5q0.063 0.156 0.203 0.25t0.297 0.125l6.094 0.844-4.375 4.281q-0.125 0.125-0.172 0.297t-0.016 0.328l1.063 6.031-5.438-2.813q-0.156-0.094-0.328-0.078t-0.297 0.078l-5.438 2.875 1-6.031z", + home: "M23.719 16.5q-0.313 0-0.531 0.219t-0.219 0.5v7.063q0 0.219-0.172 0.391t-0.391 0.172h-12.344q-0.25 0-0.422-0.172t-0.172-0.391v-7.063q0-0.281-0.219-0.5t-0.531-0.219q-0.281 0-0.516 0.219t-0.234 0.5v7.063q0.031 0.844 0.625 1.453t1.438 0.609h12.375q0.844 0 1.453-0.609t0.609-1.453v-7.063q0-0.125-0.063-0.266t-0.156-0.234q-0.094-0.125-0.234-0.172t-0.297-0.047zM26.5 14.875l-8.813-8.813q-0.313-0.313-0.688-0.453t-0.781-0.141-0.781 0.141-0.656 0.422l-8.813 8.844q-0.188 0.219-0.188 0.516t0.219 0.484q0.094 0.125 0.234 0.172t0.297 0.047q0.125 0 0.25-0.047t0.25-0.141l8.781-8.781q0.156-0.156 0.406-0.156t0.406 0.156l8.813 8.781q0.219 0.188 0.516 0.188t0.516-0.219q0.188-0.188 0.203-0.484t-0.172-0.516z", + menu: "M8.938 18.313q0.875 0 1.484-0.609t0.609-1.453-0.609-1.453-1.484-0.609q-0.844 0-1.453 0.609t-0.609 1.453 0.609 1.453 1.453 0.609zM16.188 18.313q0.875 0 1.484-0.609t0.609-1.453-0.609-1.453-1.484-0.609q-0.844 0-1.453 0.609t-0.609 1.453 0.609 1.453 1.453 0.609zM23.469 18.313q0.844 0 1.453-0.609t0.609-1.453-0.609-1.453-1.453-0.609q-0.875 0-1.484 0.609t-0.609 1.453 0.609 1.453 1.484 0.609z", + close: ICON_PATH_CLOSE +}; +const PageHead = /* @__PURE__ */ defineSystemComponent({ + name: "PageHead", + setup() { + if (window.weibo) { + return; + } + const headRef = ref(null); + const pageMeta = usePageMeta(); + const navigationBar = reactive(parseTheme(pageMeta.navigationBar)); + const { + clazz: clazz2, + style + } = usePageHead(navigationBar); + onThemeChange(() => { + const _navigationBar = parseTheme(pageMeta.navigationBar); + navigationBar.backgroundColor = _navigationBar.backgroundColor; + navigationBar.titleColor = _navigationBar.titleColor; + }); + const buttons = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ && usePageHeadButtons(pageMeta); + const searchInput = __UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__ && navigationBar.searchInput && usePageHeadSearchInput(pageMeta); + __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ && navigationBar.type === "transparent" && usePageHeadTransparent(headRef, pageMeta); + return () => { + const backButtonTsx = __UNI_FEATURE_PAGES__ ? createBackButtonTsx(navigationBar, pageMeta.isQuit) : null; + const leftButtonsTsx = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ ? createButtonsTsx(buttons.left) : []; + const rightButtonsTsx = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ ? createButtonsTsx(buttons.right) : []; + const type = navigationBar.type || "default"; + const placeholderTsx = type !== "transparent" && type !== "float" && createVNode("div", { + "class": { + "uni-placeholder": true, + "uni-placeholder-titlePenetrate": navigationBar.titlePenetrate + } + }, null, 2); + return createVNode("uni-page-head", { + "uni-page-head-type": type + }, [createVNode("div", { + "ref": headRef, + "class": clazz2.value, + "style": style.value + }, [createVNode("div", { + "class": "uni-page-head-hd" + }, [backButtonTsx, ...leftButtonsTsx]), createPageHeadBdTsx(navigationBar, searchInput), createVNode("div", { + "class": "uni-page-head-ft" + }, [...rightButtonsTsx])], 6), placeholderTsx], 8, ["uni-page-head-type"]); + }; + } +}); +function createBackButtonTsx(navigationBar, isQuit) { + if (!isQuit) { + return createVNode("div", { + "class": "uni-page-head-btn", + "onClick": onPageHeadBackButton + }, [createSvgIconVNode(ICON_PATH_BACK, navigationBar.type === "transparent" ? "#fff" : navigationBar.titleColor, 27)], 8, ["onClick"]); + } +} +function createButtonsTsx(btns) { + return btns.map(({ + onClick, + btnClass, + btnStyle, + btnText, + btnIconPath, + badgeText, + iconStyle, + btnSelect + }, index2) => { + return createVNode("div", { + "key": index2, + "class": btnClass, + "style": btnStyle, + "onClick": onClick, + "badge-text": badgeText + }, [btnIconPath ? createSvgIconVNode(btnIconPath, iconStyle.color, iconStyle.fontSize) : btnSelect ? createVNode("span", { + "style": iconStyle + }, [createVNode("i", { + "class": "uni-btn-icon", + "innerHTML": btnText + }, null, 8, ["innerHTML"]), createSvgIconVNode(ICON_PATHS["select"], "#000", 14)], 4) : createVNode("i", { + "class": "uni-btn-icon", + "style": iconStyle, + "innerHTML": btnText + }, null, 12, ["innerHTML"])], 14, ["onClick", "badge-text"]); + }); +} +function createPageHeadBdTsx(navigationBar, searchInput) { + if (!__UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__ || !navigationBar.searchInput) { + return createPageHeadTitleTextTsx(navigationBar); + } + return createPageHeadSearchInputTsx(navigationBar, searchInput); +} +function createPageHeadTitleTextTsx({ + type, + loading, + titleSize, + titleText, + titleImage +}) { + return createVNode("div", { + "class": "uni-page-head-bd" + }, [createVNode("div", { + "style": { + fontSize: titleSize, + opacity: type === "transparent" ? 0 : 1 + }, + "class": "uni-page-head__title" + }, [loading ? createVNode("i", { + "class": "uni-loading" + }, null) : titleImage ? createVNode("img", { + "src": titleImage, + "class": "uni-page-head__title_image" + }, null, 8, ["src"]) : titleText], 4)]); +} +function createPageHeadSearchInputTsx(navigationBar, { + text: text2, + focus, + composing, + onBlur, + onFocus, + onInput, + onConfirm, + onClick +}) { + const { + color, + align: align2, + autoFocus, + disabled, + borderRadius, + backgroundColor, + placeholder, + placeholderColor + } = navigationBar.searchInput; + const searchStyle = { + borderRadius, + backgroundColor + }; + const placeholderClass = ["uni-page-head-search-placeholder", `uni-page-head-search-placeholder-${focus.value || text2.value ? "left" : align2}`]; + return createVNode("div", { + "class": "uni-page-head-search", + "style": searchStyle + }, [createVNode("div", { + "style": { + color: placeholderColor + }, + "class": placeholderClass + }, [createVNode("div", { + "class": "uni-page-head-search-icon" + }, [createSvgIconVNode(ICON_PATH_SEARCH, placeholderColor, 20)]), text2.value || composing.value ? "" : placeholder], 6), disabled ? createVNode(Input, { + "disabled": true, + "style": { + color + }, + "placeholder-style": "color: " + placeholderColor, + "class": "uni-page-head-search-input", + "confirm-type": "search", + "onClick": onClick + }, null, 8, ["style", "placeholder-style", "onClick"]) : createVNode(Input, { + "focus": autoFocus, + "style": { + color + }, + "placeholder-style": "color: " + placeholderColor, + "class": "uni-page-head-search-input", + "confirm-type": "search", + "onFocus": onFocus, + "onBlur": onBlur, + "onInput": onInput, + "onConfirm": onConfirm + }, null, 8, ["focus", "style", "placeholder-style", "onFocus", "onBlur", "onInput", "onConfirm"])], 4); +} +function onPageHeadBackButton() { + if (getCurrentPages().length === 1) { + uni.reLaunch({ + url: "/" + }); + } else { + uni.navigateBack({ + from: "backbutton", + success() { + } + // 传入空方法,避免返回Promise,因为onBackPress可能导致fail + }); + } +} +function usePageHead(navigationBar) { + const clazz2 = computed(() => { + const { + type, + titlePenetrate, + shadowColorType + } = navigationBar; + const clazz3 = { + "uni-page-head": true, + "uni-page-head-transparent": type === "transparent", + "uni-page-head-titlePenetrate": titlePenetrate === "YES", + "uni-page-head-shadow": !!shadowColorType + }; + if (shadowColorType) { + clazz3[`uni-page-head-shadow-${shadowColorType}`] = true; + } + return clazz3; + }); + const style = computed(() => { + const backgroundColor = __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ && navigationBar.type === "transparent" ? usePageHeadTransparentBackgroundColor(navigationBar.backgroundColor) : navigationBar.backgroundColor; + return { + backgroundColor, + color: navigationBar.titleColor, + transitionDuration: navigationBar.duration, + transitionTimingFunction: navigationBar.timingFunc + }; + }); + return { + clazz: clazz2, + style + }; +} +function usePageHeadButtons({ + id: id2, + navigationBar +}) { + const left = []; + const right = []; + const { + buttons + } = navigationBar; + if (isArray(buttons)) { + const { + type + } = navigationBar; + const isTransparent = type === "transparent"; + const fonts = /* @__PURE__ */ Object.create(null); + buttons.forEach((btn, index2) => { + if (btn.fontSrc && !btn.fontFamily) { + const fontSrc = getRealPath(btn.fontSrc); + let fontFamily = fonts[fontSrc]; + if (!fontFamily) { + fontFamily = `font${Date.now()}`; + fonts[fontSrc] = fontFamily; + onBeforeMount(() => updateStyle("uni-btn-" + fontFamily, `@font-face{font-family: "${fontFamily}";src: url("${fontSrc}") format("truetype")}`)); + } + btn.fontFamily = fontFamily; + } + const pageHeadBtn = usePageHeadButton(id2, index2, btn, isTransparent); + if (btn.float === "left") { + left.push(pageHeadBtn); + } else { + right.push(pageHeadBtn); + } + }); + } + return { + left, + right + }; +} +function usePageHeadButton(pageId, index2, btn, isTransparent) { + const iconStyle = { + color: btn.color, + fontSize: btn.fontSize, + fontWeight: btn.fontWeight + }; + if (btn.fontFamily) { + iconStyle.fontFamily = btn.fontFamily; + } + return new Proxy({ + btnClass: { + // 类似这样的大量重复的字符串,会在gzip时压缩大小,无需在代码层考虑优化相同字符串 + "uni-page-head-btn": true, + "uni-page-head-btn-red-dot": !!(btn.redDot || btn.badgeText), + "uni-page-head-btn-select": !!btn.select + }, + btnStyle: { + backgroundColor: isTransparent ? btn.background : "transparent", + width: btn.width + }, + btnText: "", + btnIconPath: ICON_PATHS[btn.type], + badgeText: btn.badgeText, + iconStyle, + onClick() { + invokeHook(pageId, ON_NAVIGATION_BAR_BUTTON_TAP, extend({ + index: index2 + }, btn)); + }, + btnSelect: btn.select + }, { + get(target, key, receiver) { + if (["btnText"].includes(key)) { + return btn.fontSrc && btn.fontFamily ? btn.text.replace("\\u", "&#x") : btn.text; + } else { + return Reflect.get(target, key, receiver); + } + } + }); +} +function usePageHeadSearchInput({ + id: id2, + navigationBar: { + searchInput + } +}) { + const focus = ref(false); + const text2 = ref(""); + const composing = ref(false); + const { + disabled + } = searchInput; + if (disabled) { + const onClick = () => { + invokeHook(id2, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED); + }; + return { + focus, + text: text2, + composing, + onClick + }; + } + const onFocus = () => { + focus.value = true; + invokeHook(id2, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, { + focus: true + }); + }; + const onBlur = () => { + focus.value = false; + invokeHook(id2, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, { + focus: false + }); + }; + const onInput = (evt) => { + text2.value = evt.detail.value; + invokeHook(id2, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, { + text: text2.value + }); + }; + const onConfirm = (evt) => { + invokeHook(id2, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, { + text: text2.value + }); + }; + return { + focus, + text: text2, + composing, + onFocus, + onBlur, + onInput, + onConfirm + }; +} +const _sfc_main = { + name: "PageRefresh", + setup() { + const { pullToRefresh } = usePageMeta(); + return { + offset: pullToRefresh.offset, + color: pullToRefresh.color + }; + } +}; +const _export_sfc = (sfc, props2) => { + const target = sfc.__vccOpts || sfc; + for (const [key, val] of props2) { + target[key] = val; + } + return target; +}; +const _hoisted_1 = { class: "uni-page-refresh-inner" }; +const _hoisted_2 = ["fill"]; +const _hoisted_3 = /* @__PURE__ */ createElementVNode("path", { d: "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" }, null, -1); +const _hoisted_4 = /* @__PURE__ */ createElementVNode("path", { + d: "M0 0h24v24H0z", + fill: "none" +}, null, -1); +const _hoisted_5 = [ + _hoisted_3, + _hoisted_4 +]; +const _hoisted_6 = { + class: "uni-page-refresh__spinner", + width: "24", + height: "24", + viewBox: "25 25 50 50" +}; +const _hoisted_7 = ["stroke"]; +function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { + return openBlock(), createElementBlock("uni-page-refresh", null, [ + createElementVNode("div", { + style: normalizeStyle({ "margin-top": $setup.offset + "px" }), + class: "uni-page-refresh" + }, [ + createElementVNode("div", _hoisted_1, [ + (openBlock(), createElementBlock("svg", { + fill: $setup.color, + class: "uni-page-refresh__icon", + width: "24", + height: "24", + viewBox: "0 0 24 24" + }, _hoisted_5, 8, _hoisted_2)), + (openBlock(), createElementBlock("svg", _hoisted_6, [ + createElementVNode("circle", { + stroke: $setup.color, + class: "uni-page-refresh__path", + cx: "50", + cy: "50", + r: "20", + fill: "none", + "stroke-width": "4", + "stroke-miterlimit": "10" + }, null, 8, _hoisted_7) + ])) + ]) + ], 4) + ]); +} +const PageRefresh = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); +function processDeltaY(ev, identifier, startY) { + const touch = Array.prototype.slice.call(ev.changedTouches).filter((touch2) => touch2.identifier === identifier)[0]; + if (!touch) { + return false; + } + ev.deltaY = touch.pageY - startY; + return true; +} +const PULLING = "pulling"; +const REACHED = "reached"; +const ABORTING = "aborting"; +const REFRESHING = "refreshing"; +const RESTORING = "restoring"; +function usePageRefresh(refreshRef) { + const { id: id2, pullToRefresh } = usePageMeta(); + const { range, height } = pullToRefresh; + let refreshContainerElem; + let refreshControllerElem; + let refreshControllerElemStyle; + let refreshInnerElemStyle; + useSubscribe( + () => { + if (!state2) { + state2 = REFRESHING; + addClass(); + setTimeout(() => { + refreshing(); + }, 50); + } + }, + API_START_PULL_DOWN_REFRESH, + false, + id2 + ); + useSubscribe( + () => { + if (state2 === REFRESHING) { + removeClass(); + state2 = RESTORING; + addClass(); + restoring(() => { + removeClass(); + state2 = distance2 = offset = null; + }); + } + }, + API_STOP_PULL_DOWN_REFRESH, + false, + id2 + ); + onMounted(() => { + refreshContainerElem = refreshRef.value.$el; + refreshControllerElem = refreshContainerElem.querySelector(".uni-page-refresh"); + refreshControllerElemStyle = refreshControllerElem.style; + refreshInnerElemStyle = refreshControllerElem.querySelector( + ".uni-page-refresh-inner" + ).style; + }); + let touchId; + let startY; + let canRefresh; + let state2; + let distance2 = null; + let offset = null; + function toggleClass(type) { + if (!state2) { + return; + } + if (refreshContainerElem) { + refreshContainerElem.classList[type]("uni-page-refresh--" + state2); + } + } + function addClass() { + toggleClass("add"); + } + function removeClass() { + toggleClass("remove"); + } + function pulling(deltaY) { + if (!refreshControllerElem) { + return; + } + let rotate = deltaY / range; + if (rotate > 1) { + rotate = 1; + } else { + rotate = rotate * rotate * rotate; + } + const y = Math.round(deltaY / (range / height)) || 0; + refreshInnerElemStyle.transform = "rotate(" + 360 * rotate + "deg)"; + refreshControllerElemStyle.clip = "rect(" + (45 - y) + "px,45px,45px,-5px)"; + refreshControllerElemStyle.transform = "translate3d(-50%, " + y + "px, 0)"; + } + const onTouchstartPassive = withWebEvent((ev) => { + const touch = ev.changedTouches[0]; + touchId = touch.identifier; + startY = touch.pageY; + if ([ABORTING, REFRESHING, RESTORING].indexOf(state2) >= 0) { + canRefresh = false; + } else { + canRefresh = true; + } + }); + const onTouchmove = withWebEvent((ev) => { + if (!canRefresh) { + return; + } + if (!processDeltaY(ev, touchId, startY)) { + return; + } + let { deltaY } = ev; + if ((document.documentElement.scrollTop || document.body.scrollTop) !== 0) { + touchId = null; + return; + } + if (deltaY < 0 && !state2) { + return; + } + ev.preventDefault(); + if (distance2 === null) { + offset = deltaY; + state2 = PULLING; + addClass(); + } + deltaY = deltaY - offset; + if (deltaY < 0) { + deltaY = 0; + } + distance2 = deltaY; + const isReached = deltaY >= range && state2 !== REACHED; + const isPulling = deltaY < range && state2 !== PULLING; + if (isReached || isPulling) { + removeClass(); + state2 = state2 === REACHED ? PULLING : REACHED; + addClass(); + } + pulling(deltaY); + }); + const onTouchend = withWebEvent((ev) => { + if (!processDeltaY(ev, touchId, startY)) { + return; + } + if (state2 === null) { + return; + } + if (state2 === PULLING) { + removeClass(); + state2 = ABORTING; + addClass(); + aborting(() => { + removeClass(); + state2 = distance2 = offset = null; + }); + } else if (state2 === REACHED) { + removeClass(); + state2 = REFRESHING; + addClass(); + refreshing(); + } + }); + function aborting(callback) { + if (!refreshControllerElem) { + return; + } + if (refreshControllerElemStyle.transform) { + refreshControllerElemStyle.transition = "-webkit-transform 0.3s"; + refreshControllerElemStyle.transform = "translate3d(-50%, 0, 0)"; + const abortTransitionEnd = function() { + timeout && clearTimeout(timeout); + refreshControllerElem.removeEventListener( + "webkitTransitionEnd", + abortTransitionEnd + ); + refreshControllerElemStyle.transition = ""; + callback(); + }; + refreshControllerElem.addEventListener( + "webkitTransitionEnd", + abortTransitionEnd + ); + const timeout = setTimeout(abortTransitionEnd, 350); + } else { + callback(); + } + } + function refreshing() { + if (!refreshControllerElem) { + return; + } + refreshControllerElemStyle.transition = "-webkit-transform 0.2s"; + refreshControllerElemStyle.transform = "translate3d(-50%, " + height + "px, 0)"; + invokeHook(id2, ON_PULL_DOWN_REFRESH); + } + function restoring(callback) { + if (!refreshControllerElem) { + return; + } + refreshControllerElemStyle.transition = "-webkit-transform 0.3s"; + refreshControllerElemStyle.transform += " scale(0.01)"; + const restoreTransitionEnd = function() { + timeout && clearTimeout(timeout); + refreshControllerElem.removeEventListener( + "webkitTransitionEnd", + restoreTransitionEnd + ); + refreshControllerElemStyle.transition = ""; + refreshControllerElemStyle.transform = "translate3d(-50%, 0, 0)"; + callback(); + }; + refreshControllerElem.addEventListener( + "webkitTransitionEnd", + restoreTransitionEnd + ); + const timeout = setTimeout(restoreTransitionEnd, 350); + } + return { + onTouchstartPassive, + onTouchmove, + onTouchend, + onTouchcancel: onTouchend + }; +} +const PageBody = defineSystemComponent({ + name: "PageBody", + setup(props2, ctx) { + const pageMeta = __UNI_FEATURE_PULL_DOWN_REFRESH__ && usePageMeta(); + const refreshRef = __UNI_FEATURE_PULL_DOWN_REFRESH__ && ref(null); + const pageRefresh = __UNI_FEATURE_PULL_DOWN_REFRESH__ && pageMeta.enablePullDownRefresh ? usePageRefresh(refreshRef) : null; + return () => { + const pageRefreshTsx = __UNI_FEATURE_PULL_DOWN_REFRESH__ && createPageRefreshTsx(refreshRef, pageMeta); + return createVNode(Fragment, null, [pageRefreshTsx, createVNode("uni-page-wrapper", pageRefresh, [createVNode("uni-page-body", null, [renderSlot(ctx.slots, "default")])], 16)]); + }; + } +}); +function createPageRefreshTsx(refreshRef, pageMeta) { + if (!__UNI_FEATURE_PULL_DOWN_REFRESH__ || !pageMeta.enablePullDownRefresh) { + return null; + } + return createVNode(PageRefresh, { + "ref": refreshRef + }, null, 512); +} +const index = defineSystemComponent({ + name: "Page", + setup(_props, ctx) { + const pageMeta = providePageMeta(getStateId()); + const navigationBar = pageMeta.navigationBar; + useDocumentTitle(pageMeta); + return () => createVNode( + "uni-page", + { "data-page": pageMeta.route }, + __UNI_FEATURE_NAVIGATIONBAR__ && navigationBar.style !== "custom" ? [createVNode(PageHead), createPageBodyVNode(ctx)] : [createPageBodyVNode(ctx)] + ); + } +}); +function createPageBodyVNode(ctx) { + return openBlock(), createBlock( + PageBody, + { key: 0 }, + { + default: withCtx(() => [renderSlot(ctx.slots, "page")]), + _: 3 + } + ); +} +export { + $emit, + $off, + $on, + $once, + API_OFF_KEYBOARD_HEIGHT_CHANGE, + API_ON_KEYBOARD_HEIGHT_CHANGE, + index$6 as Ad, + index$5 as AdContentPage, + index$4 as AdDraw, + AsyncErrorComponent, + AsyncLoadingComponent, + index$x as Button, + index$3 as Camera, + index$v as Canvas, + index$t as Checkbox, + index$u as CheckboxGroup, + index$8 as CoverImage, + index$9 as CoverView, + index$s as Editor, + index$z as Form, + index$r as Icon, + index$q as Image, + Input, + index$y as Label, + LayoutComponent, + index$2 as LivePlayer, + index$1 as LivePusher, + Map$1 as Map, + MovableArea, + MovableView, + index$p as Navigator, + index as PageComponent, + index$7 as Picker, + PickerView, + PickerViewColumn, + index$o as Progress, + index$m as Radio, + index$n as RadioGroup, + ResizeSensor, + index$l as RichText, + ScrollView, + index$k as Slider, + Swiper, + SwiperItem, + index$j as Switch, + index$i as Text, + index$h as Textarea, + UniServiceJSBridge$1 as UniServiceJSBridge, + UniViewJSBridge$1 as UniViewJSBridge, + index$d as Video, + index$g as View, + index$c as WebView, + addInterceptor, + addPhoneContact, + arrayBufferToBase64, + base64ToArrayBuffer, + canIUse, + canvasGetImageData, + canvasPutImageData, + canvasToTempFilePath, + checkSession, + chooseFile, + chooseImage, + chooseLocation, + chooseVideo, + clearStorage, + clearStorageSync, + closePreviewImage, + closeSocket, + connectSocket, + createAnimation$1 as createAnimation, + createCameraContext, + createCanvasContext, + createInnerAudioContext, + createIntersectionObserver, + createLivePlayerContext, + createMapContext, + createMediaQueryObserver, + createSelectorQuery, + createVideoContext, + cssBackdropFilter, + cssConstant, + cssEnv, + cssVar, + downloadFile, + getApp$1 as getApp, + getAppBaseInfo, + getClipboardData, + getCurrentPages$1 as getCurrentPages, + getDeviceInfo, + getEnterOptionsSync, + getFileInfo, + getImageInfo, + getLaunchOptionsSync, + getLeftWindowStyle, + getLocale, + getLocation, + getNetworkType, + getProvider, + getPushClientId, + getRealPath, + getRecorderManager, + getRightWindowStyle, + getSavedFileInfo, + getSavedFileList, + getScreenBrightness, + getSelectedTextRange$1 as getSelectedTextRange, + getStorage, + getStorageInfo, + getStorageInfoSync, + getStorageSync, + getSystemInfo, + getSystemInfoSync, + getTopWindowStyle, + getUserInfo, + getVideoInfo, + getWindowInfo, + hideKeyboard, + hideLeftWindow, + hideLoading, + hideNavigationBarLoading, + hideRightWindow, + hideTabBar, + hideTabBarRedDot, + hideToast, + hideTopWindow, + interceptors, + invokePushCallback, + loadFontFace, + login, + makePhoneCall, + navigateBack, + navigateTo, + offAccelerometerChange, + offAppHide, + offAppShow, + offCompassChange, + offError, + offKeyboardHeightChange, + offLocationChange, + offLocationChangeError, + offNetworkStatusChange, + offPageNotFound, + offPushMessage, + offThemeChange$1 as offThemeChange, + offUnhandledRejection, + offWindowResize, + onAccelerometerChange, + onAppHide, + onAppShow, + onCompassChange, + onCreateVueApp2 as onCreateVueApp, + onError, + onGyroscopeChange, + onKeyboardHeightChange, + onLocaleChange, + onLocationChange, + onLocationChangeError, + onMemoryWarning, + onNetworkStatusChange, + onPageNotFound, + onPushMessage, + onSocketClose, + onSocketError, + onSocketMessage, + onSocketOpen, + onTabBarMidButtonTap, + onThemeChange$1 as onThemeChange, + onUnhandledRejection, + onUserCaptureScreen, + onWindowResize, + openDocument, + openLocation, + pageScrollTo, + index$e as plugin, + preloadPage, + previewImage, + reLaunch, + redirectTo, + removeInterceptor, + removeSavedFile, + removeStorage, + removeStorageSync, + removeTabBarBadge, + request, + saveFile, + saveImageToPhotosAlbum, + saveVideoToPhotosAlbum, + scanCode, + sendSocketMessage, + setClipboardData, + setKeepScreenOn, + setLeftWindowStyle, + setLocale, + setNavigationBarColor, + setNavigationBarTitle, + setPageMeta, + setRightWindowStyle, + setScreenBrightness, + setStorage, + setStorageSync, + setTabBarBadge, + setTabBarItem, + setTabBarStyle, + setTopWindowStyle, + setupApp, + setupPage, + setupWindow, + showActionSheet, + showLeftWindow, + showLoading, + showModal, + showNavigationBarLoading, + showRightWindow, + showTabBar, + showTabBarRedDot, + showToast, + showTopWindow, + startAccelerometer, + startCompass, + startGyroscope, + startLocationUpdate, + startPullDownRefresh, + stopAccelerometer, + stopCompass, + stopGyroscope, + stopLocationUpdate, + stopPullDownRefresh, + switchTab, + uni$1 as uni, + uploadFile, + upx2px, + useI18n, + useTabBar, + vibrateLong, + vibrateShort +}; diff --git a/packages/uni-mp-weibo/dist/uni.compiler.js b/packages/uni-mp-weibo/dist/uni.compiler.js new file mode 100644 index 00000000000..a99da81be30 --- /dev/null +++ b/packages/uni-mp-weibo/dist/uni.compiler.js @@ -0,0 +1,17149 @@ +'use strict'; + +var uniMpWeiboVite = require('@dcloudio/uni-mp-weibo-vite'); +var require$$1$1 = require('path'); +var require$$1 = require('fs'); +var require$$0 = require('constants'); +var require$$0$1 = require('stream'); +var require$$4 = require('util'); +var require$$5 = require('assert'); +var require$$0$2 = require('buffer'); +var require$$2 = require('os'); + +function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } + +function _interopNamespace(e) { + if (e && e.__esModule) return e; + var n = Object.create(null); + if (e) { + Object.keys(e).forEach(function (k) { + if (k !== 'default') { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + } + n.default = e; + return Object.freeze(n); +} + +var uniMpWeiboVite__namespace = /*#__PURE__*/_interopNamespace(uniMpWeiboVite); +var require$$1__default$1 = /*#__PURE__*/_interopDefault(require$$1$1); +var require$$1__default = /*#__PURE__*/_interopDefault(require$$1); +var require$$0__default = /*#__PURE__*/_interopDefault(require$$0); +var require$$0__default$1 = /*#__PURE__*/_interopDefault(require$$0$1); +var require$$4__default = /*#__PURE__*/_interopDefault(require$$4); +var require$$5__default = /*#__PURE__*/_interopDefault(require$$5); +var require$$0__default$2 = /*#__PURE__*/_interopDefault(require$$0$2); +var require$$2__default = /*#__PURE__*/_interopDefault(require$$2); + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +var fs$j = {}; + +var universalify$1 = {}; + +universalify$1.fromCallback = function (fn) { + return Object.defineProperty(function (...args) { + if (typeof args[args.length - 1] === 'function') fn.apply(this, args); + else { + return new Promise((resolve, reject) => { + fn.call( + this, + ...args, + (err, res) => (err != null) ? reject(err) : resolve(res) + ); + }) + } + }, 'name', { value: fn.name }) +}; + +universalify$1.fromPromise = function (fn) { + return Object.defineProperty(function (...args) { + const cb = args[args.length - 1]; + if (typeof cb !== 'function') return fn.apply(this, args) + else fn.apply(this, args.slice(0, -1)).then(r => cb(null, r), cb); + }, 'name', { value: fn.name }) +}; + +var constants = require$$0__default.default; + +var origCwd = process.cwd; +var cwd = null; + +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform; + +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process); + return cwd +}; +try { + process.cwd(); +} catch (er) {} + +// This check is needed until node.js 12 is required +if (typeof process.chdir === 'function') { + var chdir = process.chdir; + process.chdir = function (d) { + cwd = null; + chdir.call(process, d); + }; + if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir); +} + +var polyfills$1 = patch$1; + +function patch$1 (fs) { + // (re-)implement some things that are known busted or missing. + + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs); + } + + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs); + } + + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. + + fs.chown = chownFix(fs.chown); + fs.fchown = chownFix(fs.fchown); + fs.lchown = chownFix(fs.lchown); + + fs.chmod = chmodFix(fs.chmod); + fs.fchmod = chmodFix(fs.fchmod); + fs.lchmod = chmodFix(fs.lchmod); + + fs.chownSync = chownFixSync(fs.chownSync); + fs.fchownSync = chownFixSync(fs.fchownSync); + fs.lchownSync = chownFixSync(fs.lchownSync); + + fs.chmodSync = chmodFixSync(fs.chmodSync); + fs.fchmodSync = chmodFixSync(fs.fchmodSync); + fs.lchmodSync = chmodFixSync(fs.lchmodSync); + + fs.stat = statFix(fs.stat); + fs.fstat = statFix(fs.fstat); + fs.lstat = statFix(fs.lstat); + + fs.statSync = statFixSync(fs.statSync); + fs.fstatSync = statFixSync(fs.fstatSync); + fs.lstatSync = statFixSync(fs.lstatSync); + + // if lchmod/lchown do not exist, then make them no-ops + if (fs.chmod && !fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb); + }; + fs.lchmodSync = function () {}; + } + if (fs.chown && !fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb); + }; + fs.lchownSync = function () {}; + } + + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. + + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = typeof fs.rename !== 'function' ? fs.rename + : (function (fs$rename) { + function rename (from, to, cb) { + var start = Date.now(); + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er); + }); + }, backoff); + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er); + }); + } + if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename); + return rename + })(fs.rename); + } + + // if read() returns EAGAIN, then just try it again. + fs.read = typeof fs.read !== 'function' ? fs.read + : (function (fs$read) { + function read (fd, buffer, offset, length, position, callback_) { + var callback; + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0; + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++; + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments); + }; + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + + // This ensures `util.promisify` works as it does for native `fs.read`. + if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read); + return read + })(fs.read); + + fs.readSync = typeof fs.readSync !== 'function' ? fs.readSync + : (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0; + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++; + continue + } + throw er + } + } + }})(fs.readSync); + + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err); + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2); + }); + }); + }); + }; + + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode); + + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true; + var ret; + try { + ret = fs.fchmodSync(fd, mode); + threw = false; + } finally { + if (threw) { + try { + fs.closeSync(fd); + } catch (er) {} + } else { + fs.closeSync(fd); + } + } + return ret + }; + } + + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK") && fs.futimes) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er); + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2); + }); + }); + }); + }; + + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK); + var ret; + var threw = true; + try { + ret = fs.futimesSync(fd, at, mt); + threw = false; + } finally { + if (threw) { + try { + fs.closeSync(fd); + } catch (er) {} + } else { + fs.closeSync(fd); + } + } + return ret + }; + + } else if (fs.futimes) { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb); }; + fs.lutimesSync = function () {}; + } + } + + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null; + if (cb) cb.apply(this, arguments); + }) + } + } + + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } + + + function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null; + if (cb) cb.apply(this, arguments); + }) + } + } + + function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } + + function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, options, cb) { + if (typeof options === 'function') { + cb = options; + options = null; + } + function callback (er, stats) { + if (stats) { + if (stats.uid < 0) stats.uid += 0x100000000; + if (stats.gid < 0) stats.gid += 0x100000000; + } + if (cb) cb.apply(this, arguments); + } + return options ? orig.call(fs, target, options, callback) + : orig.call(fs, target, callback) + } + } + + function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, options) { + var stats = options ? orig.call(fs, target, options) + : orig.call(fs, target); + if (stats) { + if (stats.uid < 0) stats.uid += 0x100000000; + if (stats.gid < 0) stats.gid += 0x100000000; + } + return stats; + } + } + + // ENOSYS means that the fs doesn't support the op. Just ignore + // that, because it doesn't matter. + // + // if there's no getuid, or if getuid() is something other + // than 0, and the error is EINVAL or EPERM, then just ignore + // it. + // + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // + // When running as root, or if other types of errors are + // encountered, then it's strict. + function chownErOk (er) { + if (!er) + return true + + if (er.code === "ENOSYS") + return true + + var nonroot = !process.getuid || process.getuid() !== 0; + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + return false + } +} + +var Stream = require$$0__default$1.default.Stream; + +var legacyStreams = legacy$1; + +function legacy$1 (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream + } + + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); + + Stream.call(this); + + var self = this; + + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; + + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.encoding) this.setEncoding(this.encoding); + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); + } + + if (this.start > this.end) { + throw new Error('start must be <= end'); + } + + this.pos = this.start; + } + + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } + + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } + + self.fd = fd; + self.emit('open', fd); + self._read(); + }); + } + + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); + + Stream.call(this); + + this.path = path; + this.fd = null; + this.writable = true; + + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } + + this.pos = this.start; + } + + this.busy = false; + this._queue = []; + + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } + } +} + +var clone_1 = clone$1; + +var getPrototypeOf = Object.getPrototypeOf || function (obj) { + return obj.__proto__ +}; + +function clone$1 (obj) { + if (obj === null || typeof obj !== 'object') + return obj + + if (obj instanceof Object) + var copy = { __proto__: getPrototypeOf(obj) }; + else + var copy = Object.create(null); + + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)); + }); + + return copy +} + +var fs$i = require$$1__default.default; +var polyfills = polyfills$1; +var legacy = legacyStreams; +var clone = clone_1; + +var util$2 = require$$4__default.default; + +/* istanbul ignore next - node 0.x polyfill */ +var gracefulQueue; +var previousSymbol; + +/* istanbul ignore else - node 0.x polyfill */ +if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { + gracefulQueue = Symbol.for('graceful-fs.queue'); + // This is used in testing by future versions + previousSymbol = Symbol.for('graceful-fs.previous'); +} else { + gracefulQueue = '___graceful-fs.queue'; + previousSymbol = '___graceful-fs.previous'; +} + +function noop () {} + +function publishQueue(context, queue) { + Object.defineProperty(context, gracefulQueue, { + get: function() { + return queue + } + }); +} + +var debug = noop; +if (util$2.debuglog) + debug = util$2.debuglog('gfs4'); +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util$2.format.apply(util$2, arguments); + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: '); + console.error(m); + }; + +// Once time initialization +if (!fs$i[gracefulQueue]) { + // This queue can be shared by multiple loaded instances + var queue = commonjsGlobal[gracefulQueue] || []; + publishQueue(fs$i, queue); + + // Patch fs.close/closeSync to shared queue version, because we need + // to retry() whenever a close happens *anywhere* in the program. + // This is essential when multiple graceful-fs instances are + // in play at the same time. + fs$i.close = (function (fs$close) { + function close (fd, cb) { + return fs$close.call(fs$i, fd, function (err) { + // This function uses the graceful-fs shared queue + if (!err) { + resetQueue(); + } + + if (typeof cb === 'function') + cb.apply(this, arguments); + }) + } + + Object.defineProperty(close, previousSymbol, { + value: fs$close + }); + return close + })(fs$i.close); + + fs$i.closeSync = (function (fs$closeSync) { + function closeSync (fd) { + // This function uses the graceful-fs shared queue + fs$closeSync.apply(fs$i, arguments); + resetQueue(); + } + + Object.defineProperty(closeSync, previousSymbol, { + value: fs$closeSync + }); + return closeSync + })(fs$i.closeSync); + + if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(fs$i[gracefulQueue]); + require$$5__default.default.equal(fs$i[gracefulQueue].length, 0); + }); + } +} + +if (!commonjsGlobal[gracefulQueue]) { + publishQueue(commonjsGlobal, fs$i[gracefulQueue]); +} + +var gracefulFs = patch(clone(fs$i)); +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$i.__patched) { + gracefulFs = patch(fs$i); + fs$i.__patched = true; +} + +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs); + fs.gracefulify = patch; + + fs.createReadStream = createReadStream; + fs.createWriteStream = createWriteStream; + var fs$readFile = fs.readFile; + fs.readFile = readFile; + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null; + + return go$readFile(path, options, cb) + + function go$readFile (path, options, cb, startTime) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb === 'function') + cb.apply(this, arguments); + } + }) + } + } + + var fs$writeFile = fs.writeFile; + fs.writeFile = writeFile; + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null; + + return go$writeFile(path, data, options, cb) + + function go$writeFile (path, data, options, cb, startTime) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb === 'function') + cb.apply(this, arguments); + } + }) + } + } + + var fs$appendFile = fs.appendFile; + if (fs$appendFile) + fs.appendFile = appendFile; + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null; + + return go$appendFile(path, data, options, cb) + + function go$appendFile (path, data, options, cb, startTime) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb === 'function') + cb.apply(this, arguments); + } + }) + } + } + + var fs$copyFile = fs.copyFile; + if (fs$copyFile) + fs.copyFile = copyFile; + function copyFile (src, dest, flags, cb) { + if (typeof flags === 'function') { + cb = flags; + flags = 0; + } + return go$copyFile(src, dest, flags, cb) + + function go$copyFile (src, dest, flags, cb, startTime) { + return fs$copyFile(src, dest, flags, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$copyFile, [src, dest, flags, cb], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb === 'function') + cb.apply(this, arguments); + } + }) + } + } + + var fs$readdir = fs.readdir; + fs.readdir = readdir; + var noReaddirOptionVersions = /^v[0-5]\./; + function readdir (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null; + + var go$readdir = noReaddirOptionVersions.test(process.version) + ? function go$readdir (path, options, cb, startTime) { + return fs$readdir(path, fs$readdirCallback( + path, options, cb, startTime + )) + } + : function go$readdir (path, options, cb, startTime) { + return fs$readdir(path, options, fs$readdirCallback( + path, options, cb, startTime + )) + }; + + return go$readdir(path, options, cb) + + function fs$readdirCallback (path, options, cb, startTime) { + return function (err, files) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([ + go$readdir, + [path, options, cb], + err, + startTime || Date.now(), + Date.now() + ]); + else { + if (files && files.sort) + files.sort(); + + if (typeof cb === 'function') + cb.call(this, err, files); + } + } + } + } + + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs); + ReadStream = legStreams.ReadStream; + WriteStream = legStreams.WriteStream; + } + + var fs$ReadStream = fs.ReadStream; + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype); + ReadStream.prototype.open = ReadStream$open; + } + + var fs$WriteStream = fs.WriteStream; + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype); + WriteStream.prototype.open = WriteStream$open; + } + + Object.defineProperty(fs, 'ReadStream', { + get: function () { + return ReadStream + }, + set: function (val) { + ReadStream = val; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(fs, 'WriteStream', { + get: function () { + return WriteStream + }, + set: function (val) { + WriteStream = val; + }, + enumerable: true, + configurable: true + }); + + // legacy names + var FileReadStream = ReadStream; + Object.defineProperty(fs, 'FileReadStream', { + get: function () { + return FileReadStream + }, + set: function (val) { + FileReadStream = val; + }, + enumerable: true, + configurable: true + }); + var FileWriteStream = WriteStream; + Object.defineProperty(fs, 'FileWriteStream', { + get: function () { + return FileWriteStream + }, + set: function (val) { + FileWriteStream = val; + }, + enumerable: true, + configurable: true + }); + + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } + + function ReadStream$open () { + var that = this; + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy(); + + that.emit('error', err); + } else { + that.fd = fd; + that.emit('open', fd); + that.read(); + } + }); + } + + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) + } + + function WriteStream$open () { + var that = this; + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy(); + that.emit('error', err); + } else { + that.fd = fd; + that.emit('open', fd); + } + }); + } + + function createReadStream (path, options) { + return new fs.ReadStream(path, options) + } + + function createWriteStream (path, options) { + return new fs.WriteStream(path, options) + } + + var fs$open = fs.open; + fs.open = open; + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null; + + return go$open(path, flags, mode, cb) + + function go$open (path, flags, mode, cb, startTime) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb], err, startTime || Date.now(), Date.now()]); + else { + if (typeof cb === 'function') + cb.apply(this, arguments); + } + }) + } + } + + return fs +} + +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]); + fs$i[gracefulQueue].push(elem); + retry(); +} + +// keep track of the timeout between retry() calls +var retryTimer; + +// reset the startTime and lastTime to now +// this resets the start of the 60 second overall timeout as well as the +// delay between attempts so that we'll retry these jobs sooner +function resetQueue () { + var now = Date.now(); + for (var i = 0; i < fs$i[gracefulQueue].length; ++i) { + // entries that are only a length of 2 are from an older version, don't + // bother modifying those since they'll be retried anyway. + if (fs$i[gracefulQueue][i].length > 2) { + fs$i[gracefulQueue][i][3] = now; // startTime + fs$i[gracefulQueue][i][4] = now; // lastTime + } + } + // call retry to make sure we're actively processing the queue + retry(); +} + +function retry () { + // clear the timer and remove it to help prevent unintended concurrency + clearTimeout(retryTimer); + retryTimer = undefined; + + if (fs$i[gracefulQueue].length === 0) + return + + var elem = fs$i[gracefulQueue].shift(); + var fn = elem[0]; + var args = elem[1]; + // these items may be unset if they were added by an older graceful-fs + var err = elem[2]; + var startTime = elem[3]; + var lastTime = elem[4]; + + // if we don't have a startTime we have no way of knowing if we've waited + // long enough, so go ahead and retry this item now + if (startTime === undefined) { + debug('RETRY', fn.name, args); + fn.apply(null, args); + } else if (Date.now() - startTime >= 60000) { + // it's been more than 60 seconds total, bail now + debug('TIMEOUT', fn.name, args); + var cb = args.pop(); + if (typeof cb === 'function') + cb.call(null, err); + } else { + // the amount of time between the last attempt and right now + var sinceAttempt = Date.now() - lastTime; + // the amount of time between when we first tried, and when we last tried + // rounded up to at least 1 + var sinceStart = Math.max(lastTime - startTime, 1); + // backoff. wait longer than the total time we've been retrying, but only + // up to a maximum of 100ms + var desiredDelay = Math.min(sinceStart * 1.2, 100); + // it's been long enough since the last retry, do it again + if (sinceAttempt >= desiredDelay) { + debug('RETRY', fn.name, args); + fn.apply(null, args.concat([startTime])); + } else { + // if we can't do this job yet, push it to the end of the queue + // and let the next iteration check again + fs$i[gracefulQueue].push(elem); + } + } + + // schedule our next run if one isn't already scheduled + if (retryTimer === undefined) { + retryTimer = setTimeout(retry, 0); + } +} + +(function (exports) { + // This is adapted from https://github.com/normalize/mz + // Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors + const u = universalify$1.fromCallback; + const fs = gracefulFs; + + const api = [ + 'access', + 'appendFile', + 'chmod', + 'chown', + 'close', + 'copyFile', + 'fchmod', + 'fchown', + 'fdatasync', + 'fstat', + 'fsync', + 'ftruncate', + 'futimes', + 'lchmod', + 'lchown', + 'link', + 'lstat', + 'mkdir', + 'mkdtemp', + 'open', + 'opendir', + 'readdir', + 'readFile', + 'readlink', + 'realpath', + 'rename', + 'rm', + 'rmdir', + 'stat', + 'symlink', + 'truncate', + 'unlink', + 'utimes', + 'writeFile' + ].filter(key => { + // Some commands are not available on some systems. Ex: + // fs.opendir was added in Node.js v12.12.0 + // fs.rm was added in Node.js v14.14.0 + // fs.lchown is not available on at least some Linux + return typeof fs[key] === 'function' + }); + + // Export cloned fs: + Object.assign(exports, fs); + + // Universalify async methods: + api.forEach(method => { + exports[method] = u(fs[method]); + }); + exports.realpath.native = u(fs.realpath.native); + + // We differ from mz/fs in that we still ship the old, broken, fs.exists() + // since we are a drop-in replacement for the native module + exports.exists = function (filename, callback) { + if (typeof callback === 'function') { + return fs.exists(filename, callback) + } + return new Promise(resolve => { + return fs.exists(filename, resolve) + }) + }; + + // fs.read(), fs.write(), & fs.writev() need special treatment due to multiple callback args + + exports.read = function (fd, buffer, offset, length, position, callback) { + if (typeof callback === 'function') { + return fs.read(fd, buffer, offset, length, position, callback) + } + return new Promise((resolve, reject) => { + fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => { + if (err) return reject(err) + resolve({ bytesRead, buffer }); + }); + }) + }; + + // Function signature can be + // fs.write(fd, buffer[, offset[, length[, position]]], callback) + // OR + // fs.write(fd, string[, position[, encoding]], callback) + // We need to handle both cases, so we use ...args + exports.write = function (fd, buffer, ...args) { + if (typeof args[args.length - 1] === 'function') { + return fs.write(fd, buffer, ...args) + } + + return new Promise((resolve, reject) => { + fs.write(fd, buffer, ...args, (err, bytesWritten, buffer) => { + if (err) return reject(err) + resolve({ bytesWritten, buffer }); + }); + }) + }; + + // fs.writev only available in Node v12.9.0+ + if (typeof fs.writev === 'function') { + // Function signature is + // s.writev(fd, buffers[, position], callback) + // We need to handle the optional arg, so we use ...args + exports.writev = function (fd, buffers, ...args) { + if (typeof args[args.length - 1] === 'function') { + return fs.writev(fd, buffers, ...args) + } + + return new Promise((resolve, reject) => { + fs.writev(fd, buffers, ...args, (err, bytesWritten, buffers) => { + if (err) return reject(err) + resolve({ bytesWritten, buffers }); + }); + }) + }; + } +} (fs$j)); + +var makeDir$1 = {}; + +var utils$1 = {}; + +const path$d = require$$1__default$1.default; + +// https://github.com/nodejs/node/issues/8987 +// https://github.com/libuv/libuv/pull/1088 +utils$1.checkPath = function checkPath (pth) { + if (process.platform === 'win32') { + const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path$d.parse(pth).root, '')); + + if (pathHasInvalidWinCharacters) { + const error = new Error(`Path contains invalid characters: ${pth}`); + error.code = 'EINVAL'; + throw error + } + } +}; + +const fs$h = fs$j; +const { checkPath } = utils$1; + +const getMode = options => { + const defaults = { mode: 0o777 }; + if (typeof options === 'number') return options + return ({ ...defaults, ...options }).mode +}; + +makeDir$1.makeDir = async (dir, options) => { + checkPath(dir); + + return fs$h.mkdir(dir, { + mode: getMode(options), + recursive: true + }) +}; + +makeDir$1.makeDirSync = (dir, options) => { + checkPath(dir); + + return fs$h.mkdirSync(dir, { + mode: getMode(options), + recursive: true + }) +}; + +const u$a = universalify$1.fromPromise; +const { makeDir: _makeDir, makeDirSync } = makeDir$1; +const makeDir = u$a(_makeDir); + +var mkdirs$2 = { + mkdirs: makeDir, + mkdirsSync: makeDirSync, + // alias + mkdirp: makeDir, + mkdirpSync: makeDirSync, + ensureDir: makeDir, + ensureDirSync: makeDirSync +}; + +const fs$g = gracefulFs; + +function utimesMillis$1 (path, atime, mtime, callback) { + // if (!HAS_MILLIS_RES) return fs.utimes(path, atime, mtime, callback) + fs$g.open(path, 'r+', (err, fd) => { + if (err) return callback(err) + fs$g.futimes(fd, atime, mtime, futimesErr => { + fs$g.close(fd, closeErr => { + if (callback) callback(futimesErr || closeErr); + }); + }); + }); +} + +function utimesMillisSync$1 (path, atime, mtime) { + const fd = fs$g.openSync(path, 'r+'); + fs$g.futimesSync(fd, atime, mtime); + return fs$g.closeSync(fd) +} + +var utimes = { + utimesMillis: utimesMillis$1, + utimesMillisSync: utimesMillisSync$1 +}; + +const fs$f = fs$j; +const path$c = require$$1__default$1.default; +const util$1 = require$$4__default.default; + +function getStats$2 (src, dest, opts) { + const statFunc = opts.dereference + ? (file) => fs$f.stat(file, { bigint: true }) + : (file) => fs$f.lstat(file, { bigint: true }); + return Promise.all([ + statFunc(src), + statFunc(dest).catch(err => { + if (err.code === 'ENOENT') return null + throw err + }) + ]).then(([srcStat, destStat]) => ({ srcStat, destStat })) +} + +function getStatsSync (src, dest, opts) { + let destStat; + const statFunc = opts.dereference + ? (file) => fs$f.statSync(file, { bigint: true }) + : (file) => fs$f.lstatSync(file, { bigint: true }); + const srcStat = statFunc(src); + try { + destStat = statFunc(dest); + } catch (err) { + if (err.code === 'ENOENT') return { srcStat, destStat: null } + throw err + } + return { srcStat, destStat } +} + +function checkPaths (src, dest, funcName, opts, cb) { + util$1.callbackify(getStats$2)(src, dest, opts, (err, stats) => { + if (err) return cb(err) + const { srcStat, destStat } = stats; + + if (destStat) { + if (areIdentical$2(srcStat, destStat)) { + const srcBaseName = path$c.basename(src); + const destBaseName = path$c.basename(dest); + if (funcName === 'move' && + srcBaseName !== destBaseName && + srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { + return cb(null, { srcStat, destStat, isChangingCase: true }) + } + return cb(new Error('Source and destination must not be the same.')) + } + if (srcStat.isDirectory() && !destStat.isDirectory()) { + return cb(new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`)) + } + if (!srcStat.isDirectory() && destStat.isDirectory()) { + return cb(new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`)) + } + } + + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + return cb(new Error(errMsg(src, dest, funcName))) + } + return cb(null, { srcStat, destStat }) + }); +} + +function checkPathsSync (src, dest, funcName, opts) { + const { srcStat, destStat } = getStatsSync(src, dest, opts); + + if (destStat) { + if (areIdentical$2(srcStat, destStat)) { + const srcBaseName = path$c.basename(src); + const destBaseName = path$c.basename(dest); + if (funcName === 'move' && + srcBaseName !== destBaseName && + srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { + return { srcStat, destStat, isChangingCase: true } + } + throw new Error('Source and destination must not be the same.') + } + if (srcStat.isDirectory() && !destStat.isDirectory()) { + throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`) + } + if (!srcStat.isDirectory() && destStat.isDirectory()) { + throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`) + } + } + + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + throw new Error(errMsg(src, dest, funcName)) + } + return { srcStat, destStat } +} + +// recursively check if dest parent is a subdirectory of src. +// It works for all file types including symlinks since it +// checks the src and dest inodes. It starts from the deepest +// parent and stops once it reaches the src parent or the root path. +function checkParentPaths (src, srcStat, dest, funcName, cb) { + const srcParent = path$c.resolve(path$c.dirname(src)); + const destParent = path$c.resolve(path$c.dirname(dest)); + if (destParent === srcParent || destParent === path$c.parse(destParent).root) return cb() + fs$f.stat(destParent, { bigint: true }, (err, destStat) => { + if (err) { + if (err.code === 'ENOENT') return cb() + return cb(err) + } + if (areIdentical$2(srcStat, destStat)) { + return cb(new Error(errMsg(src, dest, funcName))) + } + return checkParentPaths(src, srcStat, destParent, funcName, cb) + }); +} + +function checkParentPathsSync (src, srcStat, dest, funcName) { + const srcParent = path$c.resolve(path$c.dirname(src)); + const destParent = path$c.resolve(path$c.dirname(dest)); + if (destParent === srcParent || destParent === path$c.parse(destParent).root) return + let destStat; + try { + destStat = fs$f.statSync(destParent, { bigint: true }); + } catch (err) { + if (err.code === 'ENOENT') return + throw err + } + if (areIdentical$2(srcStat, destStat)) { + throw new Error(errMsg(src, dest, funcName)) + } + return checkParentPathsSync(src, srcStat, destParent, funcName) +} + +function areIdentical$2 (srcStat, destStat) { + return destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev +} + +// return true if dest is a subdir of src, otherwise false. +// It only checks the path strings. +function isSrcSubdir (src, dest) { + const srcArr = path$c.resolve(src).split(path$c.sep).filter(i => i); + const destArr = path$c.resolve(dest).split(path$c.sep).filter(i => i); + return srcArr.reduce((acc, cur, i) => acc && destArr[i] === cur, true) +} + +function errMsg (src, dest, funcName) { + return `Cannot ${funcName} '${src}' to a subdirectory of itself, '${dest}'.` +} + +var stat$4 = { + checkPaths, + checkPathsSync, + checkParentPaths, + checkParentPathsSync, + isSrcSubdir, + areIdentical: areIdentical$2 +}; + +const fs$e = gracefulFs; +const path$b = require$$1__default$1.default; +const mkdirsSync$1 = mkdirs$2.mkdirsSync; +const utimesMillisSync = utimes.utimesMillisSync; +const stat$3 = stat$4; + +function copySync$2 (src, dest, opts) { + if (typeof opts === 'function') { + opts = { filter: opts }; + } + + opts = opts || {}; + opts.clobber = 'clobber' in opts ? !!opts.clobber : true; // default to true for now + opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber; // overwrite falls back to clobber + + // Warn about using preserveTimestamps on 32-bit node + if (opts.preserveTimestamps && process.arch === 'ia32') { + console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n + see https://github.com/jprichardson/node-fs-extra/issues/269`); + } + + const { srcStat, destStat } = stat$3.checkPathsSync(src, dest, 'copy', opts); + stat$3.checkParentPathsSync(src, srcStat, dest, 'copy'); + return handleFilterAndCopy(destStat, src, dest, opts) +} + +function handleFilterAndCopy (destStat, src, dest, opts) { + if (opts.filter && !opts.filter(src, dest)) return + const destParent = path$b.dirname(dest); + if (!fs$e.existsSync(destParent)) mkdirsSync$1(destParent); + return getStats$1(destStat, src, dest, opts) +} + +function startCopy$1 (destStat, src, dest, opts) { + if (opts.filter && !opts.filter(src, dest)) return + return getStats$1(destStat, src, dest, opts) +} + +function getStats$1 (destStat, src, dest, opts) { + const statSync = opts.dereference ? fs$e.statSync : fs$e.lstatSync; + const srcStat = statSync(src); + + if (srcStat.isDirectory()) return onDir$1(srcStat, destStat, src, dest, opts) + else if (srcStat.isFile() || + srcStat.isCharacterDevice() || + srcStat.isBlockDevice()) return onFile$1(srcStat, destStat, src, dest, opts) + else if (srcStat.isSymbolicLink()) return onLink$1(destStat, src, dest, opts) + else if (srcStat.isSocket()) throw new Error(`Cannot copy a socket file: ${src}`) + else if (srcStat.isFIFO()) throw new Error(`Cannot copy a FIFO pipe: ${src}`) + throw new Error(`Unknown file: ${src}`) +} + +function onFile$1 (srcStat, destStat, src, dest, opts) { + if (!destStat) return copyFile$1(srcStat, src, dest, opts) + return mayCopyFile$1(srcStat, src, dest, opts) +} + +function mayCopyFile$1 (srcStat, src, dest, opts) { + if (opts.overwrite) { + fs$e.unlinkSync(dest); + return copyFile$1(srcStat, src, dest, opts) + } else if (opts.errorOnExist) { + throw new Error(`'${dest}' already exists`) + } +} + +function copyFile$1 (srcStat, src, dest, opts) { + fs$e.copyFileSync(src, dest); + if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest); + return setDestMode$1(dest, srcStat.mode) +} + +function handleTimestamps (srcMode, src, dest) { + // Make sure the file is writable before setting the timestamp + // otherwise open fails with EPERM when invoked with 'r+' + // (through utimes call) + if (fileIsNotWritable$1(srcMode)) makeFileWritable$1(dest, srcMode); + return setDestTimestamps$1(src, dest) +} + +function fileIsNotWritable$1 (srcMode) { + return (srcMode & 0o200) === 0 +} + +function makeFileWritable$1 (dest, srcMode) { + return setDestMode$1(dest, srcMode | 0o200) +} + +function setDestMode$1 (dest, srcMode) { + return fs$e.chmodSync(dest, srcMode) +} + +function setDestTimestamps$1 (src, dest) { + // The initial srcStat.atime cannot be trusted + // because it is modified by the read(2) system call + // (See https://nodejs.org/api/fs.html#fs_stat_time_values) + const updatedSrcStat = fs$e.statSync(src); + return utimesMillisSync(dest, updatedSrcStat.atime, updatedSrcStat.mtime) +} + +function onDir$1 (srcStat, destStat, src, dest, opts) { + if (!destStat) return mkDirAndCopy$1(srcStat.mode, src, dest, opts) + return copyDir$1(src, dest, opts) +} + +function mkDirAndCopy$1 (srcMode, src, dest, opts) { + fs$e.mkdirSync(dest); + copyDir$1(src, dest, opts); + return setDestMode$1(dest, srcMode) +} + +function copyDir$1 (src, dest, opts) { + fs$e.readdirSync(src).forEach(item => copyDirItem$1(item, src, dest, opts)); +} + +function copyDirItem$1 (item, src, dest, opts) { + const srcItem = path$b.join(src, item); + const destItem = path$b.join(dest, item); + const { destStat } = stat$3.checkPathsSync(srcItem, destItem, 'copy', opts); + return startCopy$1(destStat, srcItem, destItem, opts) +} + +function onLink$1 (destStat, src, dest, opts) { + let resolvedSrc = fs$e.readlinkSync(src); + if (opts.dereference) { + resolvedSrc = path$b.resolve(process.cwd(), resolvedSrc); + } + + if (!destStat) { + return fs$e.symlinkSync(resolvedSrc, dest) + } else { + let resolvedDest; + try { + resolvedDest = fs$e.readlinkSync(dest); + } catch (err) { + // dest exists and is a regular file or directory, + // Windows may throw UNKNOWN error. If dest already exists, + // fs throws error anyway, so no need to guard against it here. + if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs$e.symlinkSync(resolvedSrc, dest) + throw err + } + if (opts.dereference) { + resolvedDest = path$b.resolve(process.cwd(), resolvedDest); + } + if (stat$3.isSrcSubdir(resolvedSrc, resolvedDest)) { + throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`) + } + + // prevent copy if src is a subdir of dest since unlinking + // dest in this case would result in removing src contents + // and therefore a broken symlink would be created. + if (fs$e.statSync(dest).isDirectory() && stat$3.isSrcSubdir(resolvedDest, resolvedSrc)) { + throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`) + } + return copyLink$1(resolvedSrc, dest) + } +} + +function copyLink$1 (resolvedSrc, dest) { + fs$e.unlinkSync(dest); + return fs$e.symlinkSync(resolvedSrc, dest) +} + +var copySync_1 = copySync$2; + +var copySync$1 = { + copySync: copySync_1 +}; + +const u$9 = universalify$1.fromPromise; +const fs$d = fs$j; + +function pathExists$6 (path) { + return fs$d.access(path).then(() => true).catch(() => false) +} + +var pathExists_1 = { + pathExists: u$9(pathExists$6), + pathExistsSync: fs$d.existsSync +}; + +const fs$c = gracefulFs; +const path$a = require$$1__default$1.default; +const mkdirs$1 = mkdirs$2.mkdirs; +const pathExists$5 = pathExists_1.pathExists; +const utimesMillis = utimes.utimesMillis; +const stat$2 = stat$4; + +function copy$3 (src, dest, opts, cb) { + if (typeof opts === 'function' && !cb) { + cb = opts; + opts = {}; + } else if (typeof opts === 'function') { + opts = { filter: opts }; + } + + cb = cb || function () {}; + opts = opts || {}; + + opts.clobber = 'clobber' in opts ? !!opts.clobber : true; // default to true for now + opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber; // overwrite falls back to clobber + + // Warn about using preserveTimestamps on 32-bit node + if (opts.preserveTimestamps && process.arch === 'ia32') { + console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n + see https://github.com/jprichardson/node-fs-extra/issues/269`); + } + + stat$2.checkPaths(src, dest, 'copy', opts, (err, stats) => { + if (err) return cb(err) + const { srcStat, destStat } = stats; + stat$2.checkParentPaths(src, srcStat, dest, 'copy', err => { + if (err) return cb(err) + if (opts.filter) return handleFilter(checkParentDir, destStat, src, dest, opts, cb) + return checkParentDir(destStat, src, dest, opts, cb) + }); + }); +} + +function checkParentDir (destStat, src, dest, opts, cb) { + const destParent = path$a.dirname(dest); + pathExists$5(destParent, (err, dirExists) => { + if (err) return cb(err) + if (dirExists) return getStats(destStat, src, dest, opts, cb) + mkdirs$1(destParent, err => { + if (err) return cb(err) + return getStats(destStat, src, dest, opts, cb) + }); + }); +} + +function handleFilter (onInclude, destStat, src, dest, opts, cb) { + Promise.resolve(opts.filter(src, dest)).then(include => { + if (include) return onInclude(destStat, src, dest, opts, cb) + return cb() + }, error => cb(error)); +} + +function startCopy (destStat, src, dest, opts, cb) { + if (opts.filter) return handleFilter(getStats, destStat, src, dest, opts, cb) + return getStats(destStat, src, dest, opts, cb) +} + +function getStats (destStat, src, dest, opts, cb) { + const stat = opts.dereference ? fs$c.stat : fs$c.lstat; + stat(src, (err, srcStat) => { + if (err) return cb(err) + + if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts, cb) + else if (srcStat.isFile() || + srcStat.isCharacterDevice() || + srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts, cb) + else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts, cb) + else if (srcStat.isSocket()) return cb(new Error(`Cannot copy a socket file: ${src}`)) + else if (srcStat.isFIFO()) return cb(new Error(`Cannot copy a FIFO pipe: ${src}`)) + return cb(new Error(`Unknown file: ${src}`)) + }); +} + +function onFile (srcStat, destStat, src, dest, opts, cb) { + if (!destStat) return copyFile(srcStat, src, dest, opts, cb) + return mayCopyFile(srcStat, src, dest, opts, cb) +} + +function mayCopyFile (srcStat, src, dest, opts, cb) { + if (opts.overwrite) { + fs$c.unlink(dest, err => { + if (err) return cb(err) + return copyFile(srcStat, src, dest, opts, cb) + }); + } else if (opts.errorOnExist) { + return cb(new Error(`'${dest}' already exists`)) + } else return cb() +} + +function copyFile (srcStat, src, dest, opts, cb) { + fs$c.copyFile(src, dest, err => { + if (err) return cb(err) + if (opts.preserveTimestamps) return handleTimestampsAndMode(srcStat.mode, src, dest, cb) + return setDestMode(dest, srcStat.mode, cb) + }); +} + +function handleTimestampsAndMode (srcMode, src, dest, cb) { + // Make sure the file is writable before setting the timestamp + // otherwise open fails with EPERM when invoked with 'r+' + // (through utimes call) + if (fileIsNotWritable(srcMode)) { + return makeFileWritable(dest, srcMode, err => { + if (err) return cb(err) + return setDestTimestampsAndMode(srcMode, src, dest, cb) + }) + } + return setDestTimestampsAndMode(srcMode, src, dest, cb) +} + +function fileIsNotWritable (srcMode) { + return (srcMode & 0o200) === 0 +} + +function makeFileWritable (dest, srcMode, cb) { + return setDestMode(dest, srcMode | 0o200, cb) +} + +function setDestTimestampsAndMode (srcMode, src, dest, cb) { + setDestTimestamps(src, dest, err => { + if (err) return cb(err) + return setDestMode(dest, srcMode, cb) + }); +} + +function setDestMode (dest, srcMode, cb) { + return fs$c.chmod(dest, srcMode, cb) +} + +function setDestTimestamps (src, dest, cb) { + // The initial srcStat.atime cannot be trusted + // because it is modified by the read(2) system call + // (See https://nodejs.org/api/fs.html#fs_stat_time_values) + fs$c.stat(src, (err, updatedSrcStat) => { + if (err) return cb(err) + return utimesMillis(dest, updatedSrcStat.atime, updatedSrcStat.mtime, cb) + }); +} + +function onDir (srcStat, destStat, src, dest, opts, cb) { + if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts, cb) + return copyDir(src, dest, opts, cb) +} + +function mkDirAndCopy (srcMode, src, dest, opts, cb) { + fs$c.mkdir(dest, err => { + if (err) return cb(err) + copyDir(src, dest, opts, err => { + if (err) return cb(err) + return setDestMode(dest, srcMode, cb) + }); + }); +} + +function copyDir (src, dest, opts, cb) { + fs$c.readdir(src, (err, items) => { + if (err) return cb(err) + return copyDirItems(items, src, dest, opts, cb) + }); +} + +function copyDirItems (items, src, dest, opts, cb) { + const item = items.pop(); + if (!item) return cb() + return copyDirItem(items, item, src, dest, opts, cb) +} + +function copyDirItem (items, item, src, dest, opts, cb) { + const srcItem = path$a.join(src, item); + const destItem = path$a.join(dest, item); + stat$2.checkPaths(srcItem, destItem, 'copy', opts, (err, stats) => { + if (err) return cb(err) + const { destStat } = stats; + startCopy(destStat, srcItem, destItem, opts, err => { + if (err) return cb(err) + return copyDirItems(items, src, dest, opts, cb) + }); + }); +} + +function onLink (destStat, src, dest, opts, cb) { + fs$c.readlink(src, (err, resolvedSrc) => { + if (err) return cb(err) + if (opts.dereference) { + resolvedSrc = path$a.resolve(process.cwd(), resolvedSrc); + } + + if (!destStat) { + return fs$c.symlink(resolvedSrc, dest, cb) + } else { + fs$c.readlink(dest, (err, resolvedDest) => { + if (err) { + // dest exists and is a regular file or directory, + // Windows may throw UNKNOWN error. If dest already exists, + // fs throws error anyway, so no need to guard against it here. + if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs$c.symlink(resolvedSrc, dest, cb) + return cb(err) + } + if (opts.dereference) { + resolvedDest = path$a.resolve(process.cwd(), resolvedDest); + } + if (stat$2.isSrcSubdir(resolvedSrc, resolvedDest)) { + return cb(new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)) + } + + // do not copy if src is a subdir of dest since unlinking + // dest in this case would result in removing src contents + // and therefore a broken symlink would be created. + if (destStat.isDirectory() && stat$2.isSrcSubdir(resolvedDest, resolvedSrc)) { + return cb(new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)) + } + return copyLink(resolvedSrc, dest, cb) + }); + } + }); +} + +function copyLink (resolvedSrc, dest, cb) { + fs$c.unlink(dest, err => { + if (err) return cb(err) + return fs$c.symlink(resolvedSrc, dest, cb) + }); +} + +var copy_1 = copy$3; + +const u$8 = universalify$1.fromCallback; +var copy$2 = { + copy: u$8(copy_1) +}; + +const fs$b = gracefulFs; +const path$9 = require$$1__default$1.default; +const assert = require$$5__default.default; + +const isWindows = (process.platform === 'win32'); + +function defaults (options) { + const methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ]; + methods.forEach(m => { + options[m] = options[m] || fs$b[m]; + m = m + 'Sync'; + options[m] = options[m] || fs$b[m]; + }); + + options.maxBusyTries = options.maxBusyTries || 3; +} + +function rimraf$1 (p, options, cb) { + let busyTries = 0; + + if (typeof options === 'function') { + cb = options; + options = {}; + } + + assert(p, 'rimraf: missing path'); + assert.strictEqual(typeof p, 'string', 'rimraf: path should be a string'); + assert.strictEqual(typeof cb, 'function', 'rimraf: callback function required'); + assert(options, 'rimraf: invalid options argument provided'); + assert.strictEqual(typeof options, 'object', 'rimraf: options should be object'); + + defaults(options); + + rimraf_(p, options, function CB (er) { + if (er) { + if ((er.code === 'EBUSY' || er.code === 'ENOTEMPTY' || er.code === 'EPERM') && + busyTries < options.maxBusyTries) { + busyTries++; + const time = busyTries * 100; + // try again, with the same exact callback as this one. + return setTimeout(() => rimraf_(p, options, CB), time) + } + + // already gone + if (er.code === 'ENOENT') er = null; + } + + cb(er); + }); +} + +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +function rimraf_ (p, options, cb) { + assert(p); + assert(options); + assert(typeof cb === 'function'); + + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, (er, st) => { + if (er && er.code === 'ENOENT') { + return cb(null) + } + + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === 'EPERM' && isWindows) { + return fixWinEPERM(p, options, er, cb) + } + + if (st && st.isDirectory()) { + return rmdir(p, options, er, cb) + } + + options.unlink(p, er => { + if (er) { + if (er.code === 'ENOENT') { + return cb(null) + } + if (er.code === 'EPERM') { + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + } + if (er.code === 'EISDIR') { + return rmdir(p, options, er, cb) + } + } + return cb(er) + }); + }); +} + +function fixWinEPERM (p, options, er, cb) { + assert(p); + assert(options); + assert(typeof cb === 'function'); + + options.chmod(p, 0o666, er2 => { + if (er2) { + cb(er2.code === 'ENOENT' ? null : er); + } else { + options.stat(p, (er3, stats) => { + if (er3) { + cb(er3.code === 'ENOENT' ? null : er); + } else if (stats.isDirectory()) { + rmdir(p, options, er, cb); + } else { + options.unlink(p, cb); + } + }); + } + }); +} + +function fixWinEPERMSync (p, options, er) { + let stats; + + assert(p); + assert(options); + + try { + options.chmodSync(p, 0o666); + } catch (er2) { + if (er2.code === 'ENOENT') { + return + } else { + throw er + } + } + + try { + stats = options.statSync(p); + } catch (er3) { + if (er3.code === 'ENOENT') { + return + } else { + throw er + } + } + + if (stats.isDirectory()) { + rmdirSync(p, options, er); + } else { + options.unlinkSync(p); + } +} + +function rmdir (p, options, originalEr, cb) { + assert(p); + assert(options); + assert(typeof cb === 'function'); + + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, er => { + if (er && (er.code === 'ENOTEMPTY' || er.code === 'EEXIST' || er.code === 'EPERM')) { + rmkids(p, options, cb); + } else if (er && er.code === 'ENOTDIR') { + cb(originalEr); + } else { + cb(er); + } + }); +} + +function rmkids (p, options, cb) { + assert(p); + assert(options); + assert(typeof cb === 'function'); + + options.readdir(p, (er, files) => { + if (er) return cb(er) + + let n = files.length; + let errState; + + if (n === 0) return options.rmdir(p, cb) + + files.forEach(f => { + rimraf$1(path$9.join(p, f), options, er => { + if (errState) { + return + } + if (er) return cb(errState = er) + if (--n === 0) { + options.rmdir(p, cb); + } + }); + }); + }); +} + +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +function rimrafSync (p, options) { + let st; + + options = options || {}; + defaults(options); + + assert(p, 'rimraf: missing path'); + assert.strictEqual(typeof p, 'string', 'rimraf: path should be a string'); + assert(options, 'rimraf: missing options'); + assert.strictEqual(typeof options, 'object', 'rimraf: options should be object'); + + try { + st = options.lstatSync(p); + } catch (er) { + if (er.code === 'ENOENT') { + return + } + + // Windows can EPERM on stat. Life is suffering. + if (er.code === 'EPERM' && isWindows) { + fixWinEPERMSync(p, options, er); + } + } + + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) { + rmdirSync(p, options, null); + } else { + options.unlinkSync(p); + } + } catch (er) { + if (er.code === 'ENOENT') { + return + } else if (er.code === 'EPERM') { + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + } else if (er.code !== 'EISDIR') { + throw er + } + rmdirSync(p, options, er); + } +} + +function rmdirSync (p, options, originalEr) { + assert(p); + assert(options); + + try { + options.rmdirSync(p); + } catch (er) { + if (er.code === 'ENOTDIR') { + throw originalEr + } else if (er.code === 'ENOTEMPTY' || er.code === 'EEXIST' || er.code === 'EPERM') { + rmkidsSync(p, options); + } else if (er.code !== 'ENOENT') { + throw er + } + } +} + +function rmkidsSync (p, options) { + assert(p); + assert(options); + options.readdirSync(p).forEach(f => rimrafSync(path$9.join(p, f), options)); + + if (isWindows) { + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + const startTime = Date.now(); + do { + try { + const ret = options.rmdirSync(p, options); + return ret + } catch {} + } while (Date.now() - startTime < 500) // give up after 500ms + } else { + const ret = options.rmdirSync(p, options); + return ret + } +} + +var rimraf_1 = rimraf$1; +rimraf$1.sync = rimrafSync; + +const fs$a = gracefulFs; +const u$7 = universalify$1.fromCallback; +const rimraf = rimraf_1; + +function remove$2 (path, callback) { + // Node 14.14.0+ + if (fs$a.rm) return fs$a.rm(path, { recursive: true, force: true }, callback) + rimraf(path, callback); +} + +function removeSync$1 (path) { + // Node 14.14.0+ + if (fs$a.rmSync) return fs$a.rmSync(path, { recursive: true, force: true }) + rimraf.sync(path); +} + +var remove_1 = { + remove: u$7(remove$2), + removeSync: removeSync$1 +}; + +const u$6 = universalify$1.fromPromise; +const fs$9 = fs$j; +const path$8 = require$$1__default$1.default; +const mkdir$3 = mkdirs$2; +const remove$1 = remove_1; + +const emptyDir = u$6(async function emptyDir (dir) { + let items; + try { + items = await fs$9.readdir(dir); + } catch { + return mkdir$3.mkdirs(dir) + } + + return Promise.all(items.map(item => remove$1.remove(path$8.join(dir, item)))) +}); + +function emptyDirSync (dir) { + let items; + try { + items = fs$9.readdirSync(dir); + } catch { + return mkdir$3.mkdirsSync(dir) + } + + items.forEach(item => { + item = path$8.join(dir, item); + remove$1.removeSync(item); + }); +} + +var empty = { + emptyDirSync, + emptydirSync: emptyDirSync, + emptyDir, + emptydir: emptyDir +}; + +const u$5 = universalify$1.fromCallback; +const path$7 = require$$1__default$1.default; +const fs$8 = gracefulFs; +const mkdir$2 = mkdirs$2; + +function createFile (file, callback) { + function makeFile () { + fs$8.writeFile(file, '', err => { + if (err) return callback(err) + callback(); + }); + } + + fs$8.stat(file, (err, stats) => { // eslint-disable-line handle-callback-err + if (!err && stats.isFile()) return callback() + const dir = path$7.dirname(file); + fs$8.stat(dir, (err, stats) => { + if (err) { + // if the directory doesn't exist, make it + if (err.code === 'ENOENT') { + return mkdir$2.mkdirs(dir, err => { + if (err) return callback(err) + makeFile(); + }) + } + return callback(err) + } + + if (stats.isDirectory()) makeFile(); + else { + // parent is not a directory + // This is just to cause an internal ENOTDIR error to be thrown + fs$8.readdir(dir, err => { + if (err) return callback(err) + }); + } + }); + }); +} + +function createFileSync (file) { + let stats; + try { + stats = fs$8.statSync(file); + } catch {} + if (stats && stats.isFile()) return + + const dir = path$7.dirname(file); + try { + if (!fs$8.statSync(dir).isDirectory()) { + // parent is not a directory + // This is just to cause an internal ENOTDIR error to be thrown + fs$8.readdirSync(dir); + } + } catch (err) { + // If the stat call above failed because the directory doesn't exist, create it + if (err && err.code === 'ENOENT') mkdir$2.mkdirsSync(dir); + else throw err + } + + fs$8.writeFileSync(file, ''); +} + +var file$1 = { + createFile: u$5(createFile), + createFileSync +}; + +const u$4 = universalify$1.fromCallback; +const path$6 = require$$1__default$1.default; +const fs$7 = gracefulFs; +const mkdir$1 = mkdirs$2; +const pathExists$4 = pathExists_1.pathExists; +const { areIdentical: areIdentical$1 } = stat$4; + +function createLink (srcpath, dstpath, callback) { + function makeLink (srcpath, dstpath) { + fs$7.link(srcpath, dstpath, err => { + if (err) return callback(err) + callback(null); + }); + } + + fs$7.lstat(dstpath, (_, dstStat) => { + fs$7.lstat(srcpath, (err, srcStat) => { + if (err) { + err.message = err.message.replace('lstat', 'ensureLink'); + return callback(err) + } + if (dstStat && areIdentical$1(srcStat, dstStat)) return callback(null) + + const dir = path$6.dirname(dstpath); + pathExists$4(dir, (err, dirExists) => { + if (err) return callback(err) + if (dirExists) return makeLink(srcpath, dstpath) + mkdir$1.mkdirs(dir, err => { + if (err) return callback(err) + makeLink(srcpath, dstpath); + }); + }); + }); + }); +} + +function createLinkSync (srcpath, dstpath) { + let dstStat; + try { + dstStat = fs$7.lstatSync(dstpath); + } catch {} + + try { + const srcStat = fs$7.lstatSync(srcpath); + if (dstStat && areIdentical$1(srcStat, dstStat)) return + } catch (err) { + err.message = err.message.replace('lstat', 'ensureLink'); + throw err + } + + const dir = path$6.dirname(dstpath); + const dirExists = fs$7.existsSync(dir); + if (dirExists) return fs$7.linkSync(srcpath, dstpath) + mkdir$1.mkdirsSync(dir); + + return fs$7.linkSync(srcpath, dstpath) +} + +var link$1 = { + createLink: u$4(createLink), + createLinkSync +}; + +const path$5 = require$$1__default$1.default; +const fs$6 = gracefulFs; +const pathExists$3 = pathExists_1.pathExists; + +/** + * Function that returns two types of paths, one relative to symlink, and one + * relative to the current working directory. Checks if path is absolute or + * relative. If the path is relative, this function checks if the path is + * relative to symlink or relative to current working directory. This is an + * initiative to find a smarter `srcpath` to supply when building symlinks. + * This allows you to determine which path to use out of one of three possible + * types of source paths. The first is an absolute path. This is detected by + * `path.isAbsolute()`. When an absolute path is provided, it is checked to + * see if it exists. If it does it's used, if not an error is returned + * (callback)/ thrown (sync). The other two options for `srcpath` are a + * relative url. By default Node's `fs.symlink` works by creating a symlink + * using `dstpath` and expects the `srcpath` to be relative to the newly + * created symlink. If you provide a `srcpath` that does not exist on the file + * system it results in a broken symlink. To minimize this, the function + * checks to see if the 'relative to symlink' source file exists, and if it + * does it will use it. If it does not, it checks if there's a file that + * exists that is relative to the current working directory, if does its used. + * This preserves the expectations of the original fs.symlink spec and adds + * the ability to pass in `relative to current working direcotry` paths. + */ + +function symlinkPaths$1 (srcpath, dstpath, callback) { + if (path$5.isAbsolute(srcpath)) { + return fs$6.lstat(srcpath, (err) => { + if (err) { + err.message = err.message.replace('lstat', 'ensureSymlink'); + return callback(err) + } + return callback(null, { + toCwd: srcpath, + toDst: srcpath + }) + }) + } else { + const dstdir = path$5.dirname(dstpath); + const relativeToDst = path$5.join(dstdir, srcpath); + return pathExists$3(relativeToDst, (err, exists) => { + if (err) return callback(err) + if (exists) { + return callback(null, { + toCwd: relativeToDst, + toDst: srcpath + }) + } else { + return fs$6.lstat(srcpath, (err) => { + if (err) { + err.message = err.message.replace('lstat', 'ensureSymlink'); + return callback(err) + } + return callback(null, { + toCwd: srcpath, + toDst: path$5.relative(dstdir, srcpath) + }) + }) + } + }) + } +} + +function symlinkPathsSync$1 (srcpath, dstpath) { + let exists; + if (path$5.isAbsolute(srcpath)) { + exists = fs$6.existsSync(srcpath); + if (!exists) throw new Error('absolute srcpath does not exist') + return { + toCwd: srcpath, + toDst: srcpath + } + } else { + const dstdir = path$5.dirname(dstpath); + const relativeToDst = path$5.join(dstdir, srcpath); + exists = fs$6.existsSync(relativeToDst); + if (exists) { + return { + toCwd: relativeToDst, + toDst: srcpath + } + } else { + exists = fs$6.existsSync(srcpath); + if (!exists) throw new Error('relative srcpath does not exist') + return { + toCwd: srcpath, + toDst: path$5.relative(dstdir, srcpath) + } + } + } +} + +var symlinkPaths_1 = { + symlinkPaths: symlinkPaths$1, + symlinkPathsSync: symlinkPathsSync$1 +}; + +const fs$5 = gracefulFs; + +function symlinkType$1 (srcpath, type, callback) { + callback = (typeof type === 'function') ? type : callback; + type = (typeof type === 'function') ? false : type; + if (type) return callback(null, type) + fs$5.lstat(srcpath, (err, stats) => { + if (err) return callback(null, 'file') + type = (stats && stats.isDirectory()) ? 'dir' : 'file'; + callback(null, type); + }); +} + +function symlinkTypeSync$1 (srcpath, type) { + let stats; + + if (type) return type + try { + stats = fs$5.lstatSync(srcpath); + } catch { + return 'file' + } + return (stats && stats.isDirectory()) ? 'dir' : 'file' +} + +var symlinkType_1 = { + symlinkType: symlinkType$1, + symlinkTypeSync: symlinkTypeSync$1 +}; + +const u$3 = universalify$1.fromCallback; +const path$4 = require$$1__default$1.default; +const fs$4 = fs$j; +const _mkdirs = mkdirs$2; +const mkdirs = _mkdirs.mkdirs; +const mkdirsSync = _mkdirs.mkdirsSync; + +const _symlinkPaths = symlinkPaths_1; +const symlinkPaths = _symlinkPaths.symlinkPaths; +const symlinkPathsSync = _symlinkPaths.symlinkPathsSync; + +const _symlinkType = symlinkType_1; +const symlinkType = _symlinkType.symlinkType; +const symlinkTypeSync = _symlinkType.symlinkTypeSync; + +const pathExists$2 = pathExists_1.pathExists; + +const { areIdentical } = stat$4; + +function createSymlink (srcpath, dstpath, type, callback) { + callback = (typeof type === 'function') ? type : callback; + type = (typeof type === 'function') ? false : type; + + fs$4.lstat(dstpath, (err, stats) => { + if (!err && stats.isSymbolicLink()) { + Promise.all([ + fs$4.stat(srcpath), + fs$4.stat(dstpath) + ]).then(([srcStat, dstStat]) => { + if (areIdentical(srcStat, dstStat)) return callback(null) + _createSymlink(srcpath, dstpath, type, callback); + }); + } else _createSymlink(srcpath, dstpath, type, callback); + }); +} + +function _createSymlink (srcpath, dstpath, type, callback) { + symlinkPaths(srcpath, dstpath, (err, relative) => { + if (err) return callback(err) + srcpath = relative.toDst; + symlinkType(relative.toCwd, type, (err, type) => { + if (err) return callback(err) + const dir = path$4.dirname(dstpath); + pathExists$2(dir, (err, dirExists) => { + if (err) return callback(err) + if (dirExists) return fs$4.symlink(srcpath, dstpath, type, callback) + mkdirs(dir, err => { + if (err) return callback(err) + fs$4.symlink(srcpath, dstpath, type, callback); + }); + }); + }); + }); +} + +function createSymlinkSync (srcpath, dstpath, type) { + let stats; + try { + stats = fs$4.lstatSync(dstpath); + } catch {} + if (stats && stats.isSymbolicLink()) { + const srcStat = fs$4.statSync(srcpath); + const dstStat = fs$4.statSync(dstpath); + if (areIdentical(srcStat, dstStat)) return + } + + const relative = symlinkPathsSync(srcpath, dstpath); + srcpath = relative.toDst; + type = symlinkTypeSync(relative.toCwd, type); + const dir = path$4.dirname(dstpath); + const exists = fs$4.existsSync(dir); + if (exists) return fs$4.symlinkSync(srcpath, dstpath, type) + mkdirsSync(dir); + return fs$4.symlinkSync(srcpath, dstpath, type) +} + +var symlink$1 = { + createSymlink: u$3(createSymlink), + createSymlinkSync +}; + +const file = file$1; +const link = link$1; +const symlink = symlink$1; + +var ensure = { + // file + createFile: file.createFile, + createFileSync: file.createFileSync, + ensureFile: file.createFile, + ensureFileSync: file.createFileSync, + // link + createLink: link.createLink, + createLinkSync: link.createLinkSync, + ensureLink: link.createLink, + ensureLinkSync: link.createLinkSync, + // symlink + createSymlink: symlink.createSymlink, + createSymlinkSync: symlink.createSymlinkSync, + ensureSymlink: symlink.createSymlink, + ensureSymlinkSync: symlink.createSymlinkSync +}; + +function stringify$5 (obj, { EOL = '\n', finalEOL = true, replacer = null, spaces } = {}) { + const EOF = finalEOL ? EOL : ''; + const str = JSON.stringify(obj, replacer, spaces); + + return str.replace(/\n/g, EOL) + EOF +} + +function stripBom$1 (content) { + // we do this because JSON.parse would convert it to a utf8 string if encoding wasn't specified + if (Buffer.isBuffer(content)) content = content.toString('utf8'); + return content.replace(/^\uFEFF/, '') +} + +var utils = { stringify: stringify$5, stripBom: stripBom$1 }; + +let _fs; +try { + _fs = gracefulFs; +} catch (_) { + _fs = require$$1__default.default; +} +const universalify = universalify$1; +const { stringify: stringify$4, stripBom } = utils; + +async function _readFile (file, options = {}) { + if (typeof options === 'string') { + options = { encoding: options }; + } + + const fs = options.fs || _fs; + + const shouldThrow = 'throws' in options ? options.throws : true; + + let data = await universalify.fromCallback(fs.readFile)(file, options); + + data = stripBom(data); + + let obj; + try { + obj = JSON.parse(data, options ? options.reviver : null); + } catch (err) { + if (shouldThrow) { + err.message = `${file}: ${err.message}`; + throw err + } else { + return null + } + } + + return obj +} + +const readFile = universalify.fromPromise(_readFile); + +function readFileSync (file, options = {}) { + if (typeof options === 'string') { + options = { encoding: options }; + } + + const fs = options.fs || _fs; + + const shouldThrow = 'throws' in options ? options.throws : true; + + try { + let content = fs.readFileSync(file, options); + content = stripBom(content); + return JSON.parse(content, options.reviver) + } catch (err) { + if (shouldThrow) { + err.message = `${file}: ${err.message}`; + throw err + } else { + return null + } + } +} + +async function _writeFile (file, obj, options = {}) { + const fs = options.fs || _fs; + + const str = stringify$4(obj, options); + + await universalify.fromCallback(fs.writeFile)(file, str, options); +} + +const writeFile = universalify.fromPromise(_writeFile); + +function writeFileSync (file, obj, options = {}) { + const fs = options.fs || _fs; + + const str = stringify$4(obj, options); + // not sure if fs.writeFileSync returns anything, but just in case + return fs.writeFileSync(file, str, options) +} + +const jsonfile$1 = { + readFile, + readFileSync, + writeFile, + writeFileSync +}; + +var jsonfile_1 = jsonfile$1; + +const jsonFile$1 = jsonfile_1; + +var jsonfile = { + // jsonfile exports + readJson: jsonFile$1.readFile, + readJsonSync: jsonFile$1.readFileSync, + writeJson: jsonFile$1.writeFile, + writeJsonSync: jsonFile$1.writeFileSync +}; + +const u$2 = universalify$1.fromCallback; +const fs$3 = gracefulFs; +const path$3 = require$$1__default$1.default; +const mkdir = mkdirs$2; +const pathExists$1 = pathExists_1.pathExists; + +function outputFile$1 (file, data, encoding, callback) { + if (typeof encoding === 'function') { + callback = encoding; + encoding = 'utf8'; + } + + const dir = path$3.dirname(file); + pathExists$1(dir, (err, itDoes) => { + if (err) return callback(err) + if (itDoes) return fs$3.writeFile(file, data, encoding, callback) + + mkdir.mkdirs(dir, err => { + if (err) return callback(err) + + fs$3.writeFile(file, data, encoding, callback); + }); + }); +} + +function outputFileSync$1 (file, ...args) { + const dir = path$3.dirname(file); + if (fs$3.existsSync(dir)) { + return fs$3.writeFileSync(file, ...args) + } + mkdir.mkdirsSync(dir); + fs$3.writeFileSync(file, ...args); +} + +var output = { + outputFile: u$2(outputFile$1), + outputFileSync: outputFileSync$1 +}; + +const { stringify: stringify$3 } = utils; +const { outputFile } = output; + +async function outputJson (file, data, options = {}) { + const str = stringify$3(data, options); + + await outputFile(file, str, options); +} + +var outputJson_1 = outputJson; + +const { stringify: stringify$2 } = utils; +const { outputFileSync } = output; + +function outputJsonSync (file, data, options) { + const str = stringify$2(data, options); + + outputFileSync(file, str, options); +} + +var outputJsonSync_1 = outputJsonSync; + +const u$1 = universalify$1.fromPromise; +const jsonFile = jsonfile; + +jsonFile.outputJson = u$1(outputJson_1); +jsonFile.outputJsonSync = outputJsonSync_1; +// aliases +jsonFile.outputJSON = jsonFile.outputJson; +jsonFile.outputJSONSync = jsonFile.outputJsonSync; +jsonFile.writeJSON = jsonFile.writeJson; +jsonFile.writeJSONSync = jsonFile.writeJsonSync; +jsonFile.readJSON = jsonFile.readJson; +jsonFile.readJSONSync = jsonFile.readJsonSync; + +var json = jsonFile; + +const fs$2 = gracefulFs; +const path$2 = require$$1__default$1.default; +const copySync = copySync$1.copySync; +const removeSync = remove_1.removeSync; +const mkdirpSync = mkdirs$2.mkdirpSync; +const stat$1 = stat$4; + +function moveSync$1 (src, dest, opts) { + opts = opts || {}; + const overwrite = opts.overwrite || opts.clobber || false; + + const { srcStat, isChangingCase = false } = stat$1.checkPathsSync(src, dest, 'move', opts); + stat$1.checkParentPathsSync(src, srcStat, dest, 'move'); + if (!isParentRoot$1(dest)) mkdirpSync(path$2.dirname(dest)); + return doRename$1(src, dest, overwrite, isChangingCase) +} + +function isParentRoot$1 (dest) { + const parent = path$2.dirname(dest); + const parsedPath = path$2.parse(parent); + return parsedPath.root === parent +} + +function doRename$1 (src, dest, overwrite, isChangingCase) { + if (isChangingCase) return rename$1(src, dest, overwrite) + if (overwrite) { + removeSync(dest); + return rename$1(src, dest, overwrite) + } + if (fs$2.existsSync(dest)) throw new Error('dest already exists.') + return rename$1(src, dest, overwrite) +} + +function rename$1 (src, dest, overwrite) { + try { + fs$2.renameSync(src, dest); + } catch (err) { + if (err.code !== 'EXDEV') throw err + return moveAcrossDevice$1(src, dest, overwrite) + } +} + +function moveAcrossDevice$1 (src, dest, overwrite) { + const opts = { + overwrite, + errorOnExist: true + }; + copySync(src, dest, opts); + return removeSync(src) +} + +var moveSync_1 = moveSync$1; + +var moveSync = { + moveSync: moveSync_1 +}; + +const fs$1 = gracefulFs; +const path$1 = require$$1__default$1.default; +const copy$1 = copy$2.copy; +const remove = remove_1.remove; +const mkdirp = mkdirs$2.mkdirp; +const pathExists = pathExists_1.pathExists; +const stat = stat$4; + +function move$1 (src, dest, opts, cb) { + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + + const overwrite = opts.overwrite || opts.clobber || false; + + stat.checkPaths(src, dest, 'move', opts, (err, stats) => { + if (err) return cb(err) + const { srcStat, isChangingCase = false } = stats; + stat.checkParentPaths(src, srcStat, dest, 'move', err => { + if (err) return cb(err) + if (isParentRoot(dest)) return doRename(src, dest, overwrite, isChangingCase, cb) + mkdirp(path$1.dirname(dest), err => { + if (err) return cb(err) + return doRename(src, dest, overwrite, isChangingCase, cb) + }); + }); + }); +} + +function isParentRoot (dest) { + const parent = path$1.dirname(dest); + const parsedPath = path$1.parse(parent); + return parsedPath.root === parent +} + +function doRename (src, dest, overwrite, isChangingCase, cb) { + if (isChangingCase) return rename(src, dest, overwrite, cb) + if (overwrite) { + return remove(dest, err => { + if (err) return cb(err) + return rename(src, dest, overwrite, cb) + }) + } + pathExists(dest, (err, destExists) => { + if (err) return cb(err) + if (destExists) return cb(new Error('dest already exists.')) + return rename(src, dest, overwrite, cb) + }); +} + +function rename (src, dest, overwrite, cb) { + fs$1.rename(src, dest, err => { + if (!err) return cb() + if (err.code !== 'EXDEV') return cb(err) + return moveAcrossDevice(src, dest, overwrite, cb) + }); +} + +function moveAcrossDevice (src, dest, overwrite, cb) { + const opts = { + overwrite, + errorOnExist: true + }; + copy$1(src, dest, opts, err => { + if (err) return cb(err) + return remove(src, cb) + }); +} + +var move_1 = move$1; + +const u = universalify$1.fromCallback; +var move = { + move: u(move_1) +}; + +var lib = { + // Export promiseified graceful-fs: + ...fs$j, + // Export extra methods: + ...copySync$1, + ...copy$2, + ...empty, + ...ensure, + ...json, + ...mkdirs$2, + ...moveSync, + ...move, + ...output, + ...pathExists_1, + ...remove_1 +}; + +var esprimaExports = {}; +var esprima$1 = { + get exports(){ return esprimaExports; }, + set exports(v){ esprimaExports = v; }, +}; + +(function (module, exports) { + (function webpackUniversalModuleDefinition(root, factory) { + /* istanbul ignore next */ + module.exports = factory(); + })(commonjsGlobal, function() { + return /******/ (function(modules) { // webpackBootstrap + /******/ // The module cache + /******/ var installedModules = {}; + + /******/ // The require function + /******/ function __webpack_require__(moduleId) { + + /******/ // Check if module is in cache + /* istanbul ignore if */ + /******/ if(installedModules[moduleId]) + /******/ return installedModules[moduleId].exports; + + /******/ // Create a new module (and put it into the cache) + /******/ var module = installedModules[moduleId] = { + /******/ exports: {}, + /******/ id: moduleId, + /******/ loaded: false + /******/ }; + + /******/ // Execute the module function + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + + /******/ // Flag the module as loaded + /******/ module.loaded = true; + + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ } + + + /******/ // expose the modules object (__webpack_modules__) + /******/ __webpack_require__.m = modules; + + /******/ // expose the module cache + /******/ __webpack_require__.c = installedModules; + + /******/ // __webpack_public_path__ + /******/ __webpack_require__.p = ""; + + /******/ // Load entry module and return exports + /******/ return __webpack_require__(0); + /******/ }) + /************************************************************************/ + /******/ ([ + /* 0 */ + /***/ function(module, exports, __webpack_require__) { + /* + Copyright JS Foundation and other contributors, https://js.foundation/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + Object.defineProperty(exports, "__esModule", { value: true }); + var comment_handler_1 = __webpack_require__(1); + var jsx_parser_1 = __webpack_require__(3); + var parser_1 = __webpack_require__(8); + var tokenizer_1 = __webpack_require__(15); + function parse(code, options, delegate) { + var commentHandler = null; + var proxyDelegate = function (node, metadata) { + if (delegate) { + delegate(node, metadata); + } + if (commentHandler) { + commentHandler.visit(node, metadata); + } + }; + var parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null; + var collectComment = false; + if (options) { + collectComment = (typeof options.comment === 'boolean' && options.comment); + var attachComment = (typeof options.attachComment === 'boolean' && options.attachComment); + if (collectComment || attachComment) { + commentHandler = new comment_handler_1.CommentHandler(); + commentHandler.attach = attachComment; + options.comment = true; + parserDelegate = proxyDelegate; + } + } + var isModule = false; + if (options && typeof options.sourceType === 'string') { + isModule = (options.sourceType === 'module'); + } + var parser; + if (options && typeof options.jsx === 'boolean' && options.jsx) { + parser = new jsx_parser_1.JSXParser(code, options, parserDelegate); + } + else { + parser = new parser_1.Parser(code, options, parserDelegate); + } + var program = isModule ? parser.parseModule() : parser.parseScript(); + var ast = program; + if (collectComment && commentHandler) { + ast.comments = commentHandler.comments; + } + if (parser.config.tokens) { + ast.tokens = parser.tokens; + } + if (parser.config.tolerant) { + ast.errors = parser.errorHandler.errors; + } + return ast; + } + exports.parse = parse; + function parseModule(code, options, delegate) { + var parsingOptions = options || {}; + parsingOptions.sourceType = 'module'; + return parse(code, parsingOptions, delegate); + } + exports.parseModule = parseModule; + function parseScript(code, options, delegate) { + var parsingOptions = options || {}; + parsingOptions.sourceType = 'script'; + return parse(code, parsingOptions, delegate); + } + exports.parseScript = parseScript; + function tokenize(code, options, delegate) { + var tokenizer = new tokenizer_1.Tokenizer(code, options); + var tokens; + tokens = []; + try { + while (true) { + var token = tokenizer.getNextToken(); + if (!token) { + break; + } + if (delegate) { + token = delegate(token); + } + tokens.push(token); + } + } + catch (e) { + tokenizer.errorHandler.tolerate(e); + } + if (tokenizer.errorHandler.tolerant) { + tokens.errors = tokenizer.errors(); + } + return tokens; + } + exports.tokenize = tokenize; + var syntax_1 = __webpack_require__(2); + exports.Syntax = syntax_1.Syntax; + // Sync with *.json manifests. + exports.version = '4.0.1'; + + + /***/ }, + /* 1 */ + /***/ function(module, exports, __webpack_require__) { + Object.defineProperty(exports, "__esModule", { value: true }); + var syntax_1 = __webpack_require__(2); + var CommentHandler = (function () { + function CommentHandler() { + this.attach = false; + this.comments = []; + this.stack = []; + this.leading = []; + this.trailing = []; + } + CommentHandler.prototype.insertInnerComments = function (node, metadata) { + // innnerComments for properties empty block + // `function a() {/** comments **\/}` + if (node.type === syntax_1.Syntax.BlockStatement && node.body.length === 0) { + var innerComments = []; + for (var i = this.leading.length - 1; i >= 0; --i) { + var entry = this.leading[i]; + if (metadata.end.offset >= entry.start) { + innerComments.unshift(entry.comment); + this.leading.splice(i, 1); + this.trailing.splice(i, 1); + } + } + if (innerComments.length) { + node.innerComments = innerComments; + } + } + }; + CommentHandler.prototype.findTrailingComments = function (metadata) { + var trailingComments = []; + if (this.trailing.length > 0) { + for (var i = this.trailing.length - 1; i >= 0; --i) { + var entry_1 = this.trailing[i]; + if (entry_1.start >= metadata.end.offset) { + trailingComments.unshift(entry_1.comment); + } + } + this.trailing.length = 0; + return trailingComments; + } + var entry = this.stack[this.stack.length - 1]; + if (entry && entry.node.trailingComments) { + var firstComment = entry.node.trailingComments[0]; + if (firstComment && firstComment.range[0] >= metadata.end.offset) { + trailingComments = entry.node.trailingComments; + delete entry.node.trailingComments; + } + } + return trailingComments; + }; + CommentHandler.prototype.findLeadingComments = function (metadata) { + var leadingComments = []; + var target; + while (this.stack.length > 0) { + var entry = this.stack[this.stack.length - 1]; + if (entry && entry.start >= metadata.start.offset) { + target = entry.node; + this.stack.pop(); + } + else { + break; + } + } + if (target) { + var count = target.leadingComments ? target.leadingComments.length : 0; + for (var i = count - 1; i >= 0; --i) { + var comment = target.leadingComments[i]; + if (comment.range[1] <= metadata.start.offset) { + leadingComments.unshift(comment); + target.leadingComments.splice(i, 1); + } + } + if (target.leadingComments && target.leadingComments.length === 0) { + delete target.leadingComments; + } + return leadingComments; + } + for (var i = this.leading.length - 1; i >= 0; --i) { + var entry = this.leading[i]; + if (entry.start <= metadata.start.offset) { + leadingComments.unshift(entry.comment); + this.leading.splice(i, 1); + } + } + return leadingComments; + }; + CommentHandler.prototype.visitNode = function (node, metadata) { + if (node.type === syntax_1.Syntax.Program && node.body.length > 0) { + return; + } + this.insertInnerComments(node, metadata); + var trailingComments = this.findTrailingComments(metadata); + var leadingComments = this.findLeadingComments(metadata); + if (leadingComments.length > 0) { + node.leadingComments = leadingComments; + } + if (trailingComments.length > 0) { + node.trailingComments = trailingComments; + } + this.stack.push({ + node: node, + start: metadata.start.offset + }); + }; + CommentHandler.prototype.visitComment = function (node, metadata) { + var type = (node.type[0] === 'L') ? 'Line' : 'Block'; + var comment = { + type: type, + value: node.value + }; + if (node.range) { + comment.range = node.range; + } + if (node.loc) { + comment.loc = node.loc; + } + this.comments.push(comment); + if (this.attach) { + var entry = { + comment: { + type: type, + value: node.value, + range: [metadata.start.offset, metadata.end.offset] + }, + start: metadata.start.offset + }; + if (node.loc) { + entry.comment.loc = node.loc; + } + node.type = type; + this.leading.push(entry); + this.trailing.push(entry); + } + }; + CommentHandler.prototype.visit = function (node, metadata) { + if (node.type === 'LineComment') { + this.visitComment(node, metadata); + } + else if (node.type === 'BlockComment') { + this.visitComment(node, metadata); + } + else if (this.attach) { + this.visitNode(node, metadata); + } + }; + return CommentHandler; + }()); + exports.CommentHandler = CommentHandler; + + + /***/ }, + /* 2 */ + /***/ function(module, exports) { + Object.defineProperty(exports, "__esModule", { value: true }); + exports.Syntax = { + AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', + ArrayExpression: 'ArrayExpression', + ArrayPattern: 'ArrayPattern', + ArrowFunctionExpression: 'ArrowFunctionExpression', + AwaitExpression: 'AwaitExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ClassBody: 'ClassBody', + ClassDeclaration: 'ClassDeclaration', + ClassExpression: 'ClassExpression', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExportAllDeclaration: 'ExportAllDeclaration', + ExportDefaultDeclaration: 'ExportDefaultDeclaration', + ExportNamedDeclaration: 'ExportNamedDeclaration', + ExportSpecifier: 'ExportSpecifier', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForOfStatement: 'ForOfStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + ImportDeclaration: 'ImportDeclaration', + ImportDefaultSpecifier: 'ImportDefaultSpecifier', + ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', + ImportSpecifier: 'ImportSpecifier', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + MetaProperty: 'MetaProperty', + MethodDefinition: 'MethodDefinition', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', + Program: 'Program', + Property: 'Property', + RestElement: 'RestElement', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SpreadElement: 'SpreadElement', + Super: 'Super', + SwitchCase: 'SwitchCase', + SwitchStatement: 'SwitchStatement', + TaggedTemplateExpression: 'TaggedTemplateExpression', + TemplateElement: 'TemplateElement', + TemplateLiteral: 'TemplateLiteral', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement', + YieldExpression: 'YieldExpression' + }; + + + /***/ }, + /* 3 */ + /***/ function(module, exports, __webpack_require__) { + /* istanbul ignore next */ + var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + var character_1 = __webpack_require__(4); + var JSXNode = __webpack_require__(5); + var jsx_syntax_1 = __webpack_require__(6); + var Node = __webpack_require__(7); + var parser_1 = __webpack_require__(8); + var token_1 = __webpack_require__(13); + var xhtml_entities_1 = __webpack_require__(14); + token_1.TokenName[100 /* Identifier */] = 'JSXIdentifier'; + token_1.TokenName[101 /* Text */] = 'JSXText'; + // Fully qualified element name, e.g. returns "svg:path" + function getQualifiedElementName(elementName) { + var qualifiedName; + switch (elementName.type) { + case jsx_syntax_1.JSXSyntax.JSXIdentifier: + var id = elementName; + qualifiedName = id.name; + break; + case jsx_syntax_1.JSXSyntax.JSXNamespacedName: + var ns = elementName; + qualifiedName = getQualifiedElementName(ns.namespace) + ':' + + getQualifiedElementName(ns.name); + break; + case jsx_syntax_1.JSXSyntax.JSXMemberExpression: + var expr = elementName; + qualifiedName = getQualifiedElementName(expr.object) + '.' + + getQualifiedElementName(expr.property); + break; + } + return qualifiedName; + } + var JSXParser = (function (_super) { + __extends(JSXParser, _super); + function JSXParser(code, options, delegate) { + return _super.call(this, code, options, delegate) || this; + } + JSXParser.prototype.parsePrimaryExpression = function () { + return this.match('<') ? this.parseJSXRoot() : _super.prototype.parsePrimaryExpression.call(this); + }; + JSXParser.prototype.startJSX = function () { + // Unwind the scanner before the lookahead token. + this.scanner.index = this.startMarker.index; + this.scanner.lineNumber = this.startMarker.line; + this.scanner.lineStart = this.startMarker.index - this.startMarker.column; + }; + JSXParser.prototype.finishJSX = function () { + // Prime the next lookahead. + this.nextToken(); + }; + JSXParser.prototype.reenterJSX = function () { + this.startJSX(); + this.expectJSX('}'); + // Pop the closing '}' added from the lookahead. + if (this.config.tokens) { + this.tokens.pop(); + } + }; + JSXParser.prototype.createJSXNode = function () { + this.collectComments(); + return { + index: this.scanner.index, + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + }; + }; + JSXParser.prototype.createJSXChildNode = function () { + return { + index: this.scanner.index, + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + }; + }; + JSXParser.prototype.scanXHTMLEntity = function (quote) { + var result = '&'; + var valid = true; + var terminated = false; + var numeric = false; + var hex = false; + while (!this.scanner.eof() && valid && !terminated) { + var ch = this.scanner.source[this.scanner.index]; + if (ch === quote) { + break; + } + terminated = (ch === ';'); + result += ch; + ++this.scanner.index; + if (!terminated) { + switch (result.length) { + case 2: + // e.g. '{' + numeric = (ch === '#'); + break; + case 3: + if (numeric) { + // e.g. 'A' + hex = (ch === 'x'); + valid = hex || character_1.Character.isDecimalDigit(ch.charCodeAt(0)); + numeric = numeric && !hex; + } + break; + default: + valid = valid && !(numeric && !character_1.Character.isDecimalDigit(ch.charCodeAt(0))); + valid = valid && !(hex && !character_1.Character.isHexDigit(ch.charCodeAt(0))); + break; + } + } + } + if (valid && terminated && result.length > 2) { + // e.g. 'A' becomes just '#x41' + var str = result.substr(1, result.length - 2); + if (numeric && str.length > 1) { + result = String.fromCharCode(parseInt(str.substr(1), 10)); + } + else if (hex && str.length > 2) { + result = String.fromCharCode(parseInt('0' + str.substr(1), 16)); + } + else if (!numeric && !hex && xhtml_entities_1.XHTMLEntities[str]) { + result = xhtml_entities_1.XHTMLEntities[str]; + } + } + return result; + }; + // Scan the next JSX token. This replaces Scanner#lex when in JSX mode. + JSXParser.prototype.lexJSX = function () { + var cp = this.scanner.source.charCodeAt(this.scanner.index); + // < > / : = { } + if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) { + var value = this.scanner.source[this.scanner.index++]; + return { + type: 7 /* Punctuator */, + value: value, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: this.scanner.index - 1, + end: this.scanner.index + }; + } + // " ' + if (cp === 34 || cp === 39) { + var start = this.scanner.index; + var quote = this.scanner.source[this.scanner.index++]; + var str = ''; + while (!this.scanner.eof()) { + var ch = this.scanner.source[this.scanner.index++]; + if (ch === quote) { + break; + } + else if (ch === '&') { + str += this.scanXHTMLEntity(quote); + } + else { + str += ch; + } + } + return { + type: 8 /* StringLiteral */, + value: str, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + } + // ... or . + if (cp === 46) { + var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1); + var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2); + var value = (n1 === 46 && n2 === 46) ? '...' : '.'; + var start = this.scanner.index; + this.scanner.index += value.length; + return { + type: 7 /* Punctuator */, + value: value, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + } + // ` + if (cp === 96) { + // Only placeholder, since it will be rescanned as a real assignment expression. + return { + type: 10 /* Template */, + value: '', + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: this.scanner.index, + end: this.scanner.index + }; + } + // Identifer can not contain backslash (char code 92). + if (character_1.Character.isIdentifierStart(cp) && (cp !== 92)) { + var start = this.scanner.index; + ++this.scanner.index; + while (!this.scanner.eof()) { + var ch = this.scanner.source.charCodeAt(this.scanner.index); + if (character_1.Character.isIdentifierPart(ch) && (ch !== 92)) { + ++this.scanner.index; + } + else if (ch === 45) { + // Hyphen (char code 45) can be part of an identifier. + ++this.scanner.index; + } + else { + break; + } + } + var id = this.scanner.source.slice(start, this.scanner.index); + return { + type: 100 /* Identifier */, + value: id, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + } + return this.scanner.lex(); + }; + JSXParser.prototype.nextJSXToken = function () { + this.collectComments(); + this.startMarker.index = this.scanner.index; + this.startMarker.line = this.scanner.lineNumber; + this.startMarker.column = this.scanner.index - this.scanner.lineStart; + var token = this.lexJSX(); + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + if (this.config.tokens) { + this.tokens.push(this.convertToken(token)); + } + return token; + }; + JSXParser.prototype.nextJSXText = function () { + this.startMarker.index = this.scanner.index; + this.startMarker.line = this.scanner.lineNumber; + this.startMarker.column = this.scanner.index - this.scanner.lineStart; + var start = this.scanner.index; + var text = ''; + while (!this.scanner.eof()) { + var ch = this.scanner.source[this.scanner.index]; + if (ch === '{' || ch === '<') { + break; + } + ++this.scanner.index; + text += ch; + if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { + ++this.scanner.lineNumber; + if (ch === '\r' && this.scanner.source[this.scanner.index] === '\n') { + ++this.scanner.index; + } + this.scanner.lineStart = this.scanner.index; + } + } + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + var token = { + type: 101 /* Text */, + value: text, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + if ((text.length > 0) && this.config.tokens) { + this.tokens.push(this.convertToken(token)); + } + return token; + }; + JSXParser.prototype.peekJSXToken = function () { + var state = this.scanner.saveState(); + this.scanner.scanComments(); + var next = this.lexJSX(); + this.scanner.restoreState(state); + return next; + }; + // Expect the next JSX token to match the specified punctuator. + // If not, an exception will be thrown. + JSXParser.prototype.expectJSX = function (value) { + var token = this.nextJSXToken(); + if (token.type !== 7 /* Punctuator */ || token.value !== value) { + this.throwUnexpectedToken(token); + } + }; + // Return true if the next JSX token matches the specified punctuator. + JSXParser.prototype.matchJSX = function (value) { + var next = this.peekJSXToken(); + return next.type === 7 /* Punctuator */ && next.value === value; + }; + JSXParser.prototype.parseJSXIdentifier = function () { + var node = this.createJSXNode(); + var token = this.nextJSXToken(); + if (token.type !== 100 /* Identifier */) { + this.throwUnexpectedToken(token); + } + return this.finalize(node, new JSXNode.JSXIdentifier(token.value)); + }; + JSXParser.prototype.parseJSXElementName = function () { + var node = this.createJSXNode(); + var elementName = this.parseJSXIdentifier(); + if (this.matchJSX(':')) { + var namespace = elementName; + this.expectJSX(':'); + var name_1 = this.parseJSXIdentifier(); + elementName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_1)); + } + else if (this.matchJSX('.')) { + while (this.matchJSX('.')) { + var object = elementName; + this.expectJSX('.'); + var property = this.parseJSXIdentifier(); + elementName = this.finalize(node, new JSXNode.JSXMemberExpression(object, property)); + } + } + return elementName; + }; + JSXParser.prototype.parseJSXAttributeName = function () { + var node = this.createJSXNode(); + var attributeName; + var identifier = this.parseJSXIdentifier(); + if (this.matchJSX(':')) { + var namespace = identifier; + this.expectJSX(':'); + var name_2 = this.parseJSXIdentifier(); + attributeName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_2)); + } + else { + attributeName = identifier; + } + return attributeName; + }; + JSXParser.prototype.parseJSXStringLiteralAttribute = function () { + var node = this.createJSXNode(); + var token = this.nextJSXToken(); + if (token.type !== 8 /* StringLiteral */) { + this.throwUnexpectedToken(token); + } + var raw = this.getTokenRaw(token); + return this.finalize(node, new Node.Literal(token.value, raw)); + }; + JSXParser.prototype.parseJSXExpressionAttribute = function () { + var node = this.createJSXNode(); + this.expectJSX('{'); + this.finishJSX(); + if (this.match('}')) { + this.tolerateError('JSX attributes must only be assigned a non-empty expression'); + } + var expression = this.parseAssignmentExpression(); + this.reenterJSX(); + return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); + }; + JSXParser.prototype.parseJSXAttributeValue = function () { + return this.matchJSX('{') ? this.parseJSXExpressionAttribute() : + this.matchJSX('<') ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute(); + }; + JSXParser.prototype.parseJSXNameValueAttribute = function () { + var node = this.createJSXNode(); + var name = this.parseJSXAttributeName(); + var value = null; + if (this.matchJSX('=')) { + this.expectJSX('='); + value = this.parseJSXAttributeValue(); + } + return this.finalize(node, new JSXNode.JSXAttribute(name, value)); + }; + JSXParser.prototype.parseJSXSpreadAttribute = function () { + var node = this.createJSXNode(); + this.expectJSX('{'); + this.expectJSX('...'); + this.finishJSX(); + var argument = this.parseAssignmentExpression(); + this.reenterJSX(); + return this.finalize(node, new JSXNode.JSXSpreadAttribute(argument)); + }; + JSXParser.prototype.parseJSXAttributes = function () { + var attributes = []; + while (!this.matchJSX('/') && !this.matchJSX('>')) { + var attribute = this.matchJSX('{') ? this.parseJSXSpreadAttribute() : + this.parseJSXNameValueAttribute(); + attributes.push(attribute); + } + return attributes; + }; + JSXParser.prototype.parseJSXOpeningElement = function () { + var node = this.createJSXNode(); + this.expectJSX('<'); + var name = this.parseJSXElementName(); + var attributes = this.parseJSXAttributes(); + var selfClosing = this.matchJSX('/'); + if (selfClosing) { + this.expectJSX('/'); + } + this.expectJSX('>'); + return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); + }; + JSXParser.prototype.parseJSXBoundaryElement = function () { + var node = this.createJSXNode(); + this.expectJSX('<'); + if (this.matchJSX('/')) { + this.expectJSX('/'); + var name_3 = this.parseJSXElementName(); + this.expectJSX('>'); + return this.finalize(node, new JSXNode.JSXClosingElement(name_3)); + } + var name = this.parseJSXElementName(); + var attributes = this.parseJSXAttributes(); + var selfClosing = this.matchJSX('/'); + if (selfClosing) { + this.expectJSX('/'); + } + this.expectJSX('>'); + return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); + }; + JSXParser.prototype.parseJSXEmptyExpression = function () { + var node = this.createJSXChildNode(); + this.collectComments(); + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + return this.finalize(node, new JSXNode.JSXEmptyExpression()); + }; + JSXParser.prototype.parseJSXExpressionContainer = function () { + var node = this.createJSXNode(); + this.expectJSX('{'); + var expression; + if (this.matchJSX('}')) { + expression = this.parseJSXEmptyExpression(); + this.expectJSX('}'); + } + else { + this.finishJSX(); + expression = this.parseAssignmentExpression(); + this.reenterJSX(); + } + return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); + }; + JSXParser.prototype.parseJSXChildren = function () { + var children = []; + while (!this.scanner.eof()) { + var node = this.createJSXChildNode(); + var token = this.nextJSXText(); + if (token.start < token.end) { + var raw = this.getTokenRaw(token); + var child = this.finalize(node, new JSXNode.JSXText(token.value, raw)); + children.push(child); + } + if (this.scanner.source[this.scanner.index] === '{') { + var container = this.parseJSXExpressionContainer(); + children.push(container); + } + else { + break; + } + } + return children; + }; + JSXParser.prototype.parseComplexJSXElement = function (el) { + var stack = []; + while (!this.scanner.eof()) { + el.children = el.children.concat(this.parseJSXChildren()); + var node = this.createJSXChildNode(); + var element = this.parseJSXBoundaryElement(); + if (element.type === jsx_syntax_1.JSXSyntax.JSXOpeningElement) { + var opening = element; + if (opening.selfClosing) { + var child = this.finalize(node, new JSXNode.JSXElement(opening, [], null)); + el.children.push(child); + } + else { + stack.push(el); + el = { node: node, opening: opening, closing: null, children: [] }; + } + } + if (element.type === jsx_syntax_1.JSXSyntax.JSXClosingElement) { + el.closing = element; + var open_1 = getQualifiedElementName(el.opening.name); + var close_1 = getQualifiedElementName(el.closing.name); + if (open_1 !== close_1) { + this.tolerateError('Expected corresponding JSX closing tag for %0', open_1); + } + if (stack.length > 0) { + var child = this.finalize(el.node, new JSXNode.JSXElement(el.opening, el.children, el.closing)); + el = stack[stack.length - 1]; + el.children.push(child); + stack.pop(); + } + else { + break; + } + } + } + return el; + }; + JSXParser.prototype.parseJSXElement = function () { + var node = this.createJSXNode(); + var opening = this.parseJSXOpeningElement(); + var children = []; + var closing = null; + if (!opening.selfClosing) { + var el = this.parseComplexJSXElement({ node: node, opening: opening, closing: closing, children: children }); + children = el.children; + closing = el.closing; + } + return this.finalize(node, new JSXNode.JSXElement(opening, children, closing)); + }; + JSXParser.prototype.parseJSXRoot = function () { + // Pop the opening '<' added from the lookahead. + if (this.config.tokens) { + this.tokens.pop(); + } + this.startJSX(); + var element = this.parseJSXElement(); + this.finishJSX(); + return element; + }; + JSXParser.prototype.isStartOfExpression = function () { + return _super.prototype.isStartOfExpression.call(this) || this.match('<'); + }; + return JSXParser; + }(parser_1.Parser)); + exports.JSXParser = JSXParser; + + + /***/ }, + /* 4 */ + /***/ function(module, exports) { + Object.defineProperty(exports, "__esModule", { value: true }); + // See also tools/generate-unicode-regex.js. + var Regex = { + // Unicode v8.0.0 NonAsciiIdentifierStart: + NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/, + // Unicode v8.0.0 NonAsciiIdentifierPart: + NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ + }; + exports.Character = { + /* tslint:disable:no-bitwise */ + fromCodePoint: function (cp) { + return (cp < 0x10000) ? String.fromCharCode(cp) : + String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) + + String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023)); + }, + // https://tc39.github.io/ecma262/#sec-white-space + isWhiteSpace: function (cp) { + return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) || + (cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0); + }, + // https://tc39.github.io/ecma262/#sec-line-terminators + isLineTerminator: function (cp) { + return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029); + }, + // https://tc39.github.io/ecma262/#sec-names-and-keywords + isIdentifierStart: function (cp) { + return (cp === 0x24) || (cp === 0x5F) || + (cp >= 0x41 && cp <= 0x5A) || + (cp >= 0x61 && cp <= 0x7A) || + (cp === 0x5C) || + ((cp >= 0x80) && Regex.NonAsciiIdentifierStart.test(exports.Character.fromCodePoint(cp))); + }, + isIdentifierPart: function (cp) { + return (cp === 0x24) || (cp === 0x5F) || + (cp >= 0x41 && cp <= 0x5A) || + (cp >= 0x61 && cp <= 0x7A) || + (cp >= 0x30 && cp <= 0x39) || + (cp === 0x5C) || + ((cp >= 0x80) && Regex.NonAsciiIdentifierPart.test(exports.Character.fromCodePoint(cp))); + }, + // https://tc39.github.io/ecma262/#sec-literals-numeric-literals + isDecimalDigit: function (cp) { + return (cp >= 0x30 && cp <= 0x39); // 0..9 + }, + isHexDigit: function (cp) { + return (cp >= 0x30 && cp <= 0x39) || + (cp >= 0x41 && cp <= 0x46) || + (cp >= 0x61 && cp <= 0x66); // a..f + }, + isOctalDigit: function (cp) { + return (cp >= 0x30 && cp <= 0x37); // 0..7 + } + }; + + + /***/ }, + /* 5 */ + /***/ function(module, exports, __webpack_require__) { + Object.defineProperty(exports, "__esModule", { value: true }); + var jsx_syntax_1 = __webpack_require__(6); + /* tslint:disable:max-classes-per-file */ + var JSXClosingElement = (function () { + function JSXClosingElement(name) { + this.type = jsx_syntax_1.JSXSyntax.JSXClosingElement; + this.name = name; + } + return JSXClosingElement; + }()); + exports.JSXClosingElement = JSXClosingElement; + var JSXElement = (function () { + function JSXElement(openingElement, children, closingElement) { + this.type = jsx_syntax_1.JSXSyntax.JSXElement; + this.openingElement = openingElement; + this.children = children; + this.closingElement = closingElement; + } + return JSXElement; + }()); + exports.JSXElement = JSXElement; + var JSXEmptyExpression = (function () { + function JSXEmptyExpression() { + this.type = jsx_syntax_1.JSXSyntax.JSXEmptyExpression; + } + return JSXEmptyExpression; + }()); + exports.JSXEmptyExpression = JSXEmptyExpression; + var JSXExpressionContainer = (function () { + function JSXExpressionContainer(expression) { + this.type = jsx_syntax_1.JSXSyntax.JSXExpressionContainer; + this.expression = expression; + } + return JSXExpressionContainer; + }()); + exports.JSXExpressionContainer = JSXExpressionContainer; + var JSXIdentifier = (function () { + function JSXIdentifier(name) { + this.type = jsx_syntax_1.JSXSyntax.JSXIdentifier; + this.name = name; + } + return JSXIdentifier; + }()); + exports.JSXIdentifier = JSXIdentifier; + var JSXMemberExpression = (function () { + function JSXMemberExpression(object, property) { + this.type = jsx_syntax_1.JSXSyntax.JSXMemberExpression; + this.object = object; + this.property = property; + } + return JSXMemberExpression; + }()); + exports.JSXMemberExpression = JSXMemberExpression; + var JSXAttribute = (function () { + function JSXAttribute(name, value) { + this.type = jsx_syntax_1.JSXSyntax.JSXAttribute; + this.name = name; + this.value = value; + } + return JSXAttribute; + }()); + exports.JSXAttribute = JSXAttribute; + var JSXNamespacedName = (function () { + function JSXNamespacedName(namespace, name) { + this.type = jsx_syntax_1.JSXSyntax.JSXNamespacedName; + this.namespace = namespace; + this.name = name; + } + return JSXNamespacedName; + }()); + exports.JSXNamespacedName = JSXNamespacedName; + var JSXOpeningElement = (function () { + function JSXOpeningElement(name, selfClosing, attributes) { + this.type = jsx_syntax_1.JSXSyntax.JSXOpeningElement; + this.name = name; + this.selfClosing = selfClosing; + this.attributes = attributes; + } + return JSXOpeningElement; + }()); + exports.JSXOpeningElement = JSXOpeningElement; + var JSXSpreadAttribute = (function () { + function JSXSpreadAttribute(argument) { + this.type = jsx_syntax_1.JSXSyntax.JSXSpreadAttribute; + this.argument = argument; + } + return JSXSpreadAttribute; + }()); + exports.JSXSpreadAttribute = JSXSpreadAttribute; + var JSXText = (function () { + function JSXText(value, raw) { + this.type = jsx_syntax_1.JSXSyntax.JSXText; + this.value = value; + this.raw = raw; + } + return JSXText; + }()); + exports.JSXText = JSXText; + + + /***/ }, + /* 6 */ + /***/ function(module, exports) { + Object.defineProperty(exports, "__esModule", { value: true }); + exports.JSXSyntax = { + JSXAttribute: 'JSXAttribute', + JSXClosingElement: 'JSXClosingElement', + JSXElement: 'JSXElement', + JSXEmptyExpression: 'JSXEmptyExpression', + JSXExpressionContainer: 'JSXExpressionContainer', + JSXIdentifier: 'JSXIdentifier', + JSXMemberExpression: 'JSXMemberExpression', + JSXNamespacedName: 'JSXNamespacedName', + JSXOpeningElement: 'JSXOpeningElement', + JSXSpreadAttribute: 'JSXSpreadAttribute', + JSXText: 'JSXText' + }; + + + /***/ }, + /* 7 */ + /***/ function(module, exports, __webpack_require__) { + Object.defineProperty(exports, "__esModule", { value: true }); + var syntax_1 = __webpack_require__(2); + /* tslint:disable:max-classes-per-file */ + var ArrayExpression = (function () { + function ArrayExpression(elements) { + this.type = syntax_1.Syntax.ArrayExpression; + this.elements = elements; + } + return ArrayExpression; + }()); + exports.ArrayExpression = ArrayExpression; + var ArrayPattern = (function () { + function ArrayPattern(elements) { + this.type = syntax_1.Syntax.ArrayPattern; + this.elements = elements; + } + return ArrayPattern; + }()); + exports.ArrayPattern = ArrayPattern; + var ArrowFunctionExpression = (function () { + function ArrowFunctionExpression(params, body, expression) { + this.type = syntax_1.Syntax.ArrowFunctionExpression; + this.id = null; + this.params = params; + this.body = body; + this.generator = false; + this.expression = expression; + this.async = false; + } + return ArrowFunctionExpression; + }()); + exports.ArrowFunctionExpression = ArrowFunctionExpression; + var AssignmentExpression = (function () { + function AssignmentExpression(operator, left, right) { + this.type = syntax_1.Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + } + return AssignmentExpression; + }()); + exports.AssignmentExpression = AssignmentExpression; + var AssignmentPattern = (function () { + function AssignmentPattern(left, right) { + this.type = syntax_1.Syntax.AssignmentPattern; + this.left = left; + this.right = right; + } + return AssignmentPattern; + }()); + exports.AssignmentPattern = AssignmentPattern; + var AsyncArrowFunctionExpression = (function () { + function AsyncArrowFunctionExpression(params, body, expression) { + this.type = syntax_1.Syntax.ArrowFunctionExpression; + this.id = null; + this.params = params; + this.body = body; + this.generator = false; + this.expression = expression; + this.async = true; + } + return AsyncArrowFunctionExpression; + }()); + exports.AsyncArrowFunctionExpression = AsyncArrowFunctionExpression; + var AsyncFunctionDeclaration = (function () { + function AsyncFunctionDeclaration(id, params, body) { + this.type = syntax_1.Syntax.FunctionDeclaration; + this.id = id; + this.params = params; + this.body = body; + this.generator = false; + this.expression = false; + this.async = true; + } + return AsyncFunctionDeclaration; + }()); + exports.AsyncFunctionDeclaration = AsyncFunctionDeclaration; + var AsyncFunctionExpression = (function () { + function AsyncFunctionExpression(id, params, body) { + this.type = syntax_1.Syntax.FunctionExpression; + this.id = id; + this.params = params; + this.body = body; + this.generator = false; + this.expression = false; + this.async = true; + } + return AsyncFunctionExpression; + }()); + exports.AsyncFunctionExpression = AsyncFunctionExpression; + var AwaitExpression = (function () { + function AwaitExpression(argument) { + this.type = syntax_1.Syntax.AwaitExpression; + this.argument = argument; + } + return AwaitExpression; + }()); + exports.AwaitExpression = AwaitExpression; + var BinaryExpression = (function () { + function BinaryExpression(operator, left, right) { + var logical = (operator === '||' || operator === '&&'); + this.type = logical ? syntax_1.Syntax.LogicalExpression : syntax_1.Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + } + return BinaryExpression; + }()); + exports.BinaryExpression = BinaryExpression; + var BlockStatement = (function () { + function BlockStatement(body) { + this.type = syntax_1.Syntax.BlockStatement; + this.body = body; + } + return BlockStatement; + }()); + exports.BlockStatement = BlockStatement; + var BreakStatement = (function () { + function BreakStatement(label) { + this.type = syntax_1.Syntax.BreakStatement; + this.label = label; + } + return BreakStatement; + }()); + exports.BreakStatement = BreakStatement; + var CallExpression = (function () { + function CallExpression(callee, args) { + this.type = syntax_1.Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + } + return CallExpression; + }()); + exports.CallExpression = CallExpression; + var CatchClause = (function () { + function CatchClause(param, body) { + this.type = syntax_1.Syntax.CatchClause; + this.param = param; + this.body = body; + } + return CatchClause; + }()); + exports.CatchClause = CatchClause; + var ClassBody = (function () { + function ClassBody(body) { + this.type = syntax_1.Syntax.ClassBody; + this.body = body; + } + return ClassBody; + }()); + exports.ClassBody = ClassBody; + var ClassDeclaration = (function () { + function ClassDeclaration(id, superClass, body) { + this.type = syntax_1.Syntax.ClassDeclaration; + this.id = id; + this.superClass = superClass; + this.body = body; + } + return ClassDeclaration; + }()); + exports.ClassDeclaration = ClassDeclaration; + var ClassExpression = (function () { + function ClassExpression(id, superClass, body) { + this.type = syntax_1.Syntax.ClassExpression; + this.id = id; + this.superClass = superClass; + this.body = body; + } + return ClassExpression; + }()); + exports.ClassExpression = ClassExpression; + var ComputedMemberExpression = (function () { + function ComputedMemberExpression(object, property) { + this.type = syntax_1.Syntax.MemberExpression; + this.computed = true; + this.object = object; + this.property = property; + } + return ComputedMemberExpression; + }()); + exports.ComputedMemberExpression = ComputedMemberExpression; + var ConditionalExpression = (function () { + function ConditionalExpression(test, consequent, alternate) { + this.type = syntax_1.Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + } + return ConditionalExpression; + }()); + exports.ConditionalExpression = ConditionalExpression; + var ContinueStatement = (function () { + function ContinueStatement(label) { + this.type = syntax_1.Syntax.ContinueStatement; + this.label = label; + } + return ContinueStatement; + }()); + exports.ContinueStatement = ContinueStatement; + var DebuggerStatement = (function () { + function DebuggerStatement() { + this.type = syntax_1.Syntax.DebuggerStatement; + } + return DebuggerStatement; + }()); + exports.DebuggerStatement = DebuggerStatement; + var Directive = (function () { + function Directive(expression, directive) { + this.type = syntax_1.Syntax.ExpressionStatement; + this.expression = expression; + this.directive = directive; + } + return Directive; + }()); + exports.Directive = Directive; + var DoWhileStatement = (function () { + function DoWhileStatement(body, test) { + this.type = syntax_1.Syntax.DoWhileStatement; + this.body = body; + this.test = test; + } + return DoWhileStatement; + }()); + exports.DoWhileStatement = DoWhileStatement; + var EmptyStatement = (function () { + function EmptyStatement() { + this.type = syntax_1.Syntax.EmptyStatement; + } + return EmptyStatement; + }()); + exports.EmptyStatement = EmptyStatement; + var ExportAllDeclaration = (function () { + function ExportAllDeclaration(source) { + this.type = syntax_1.Syntax.ExportAllDeclaration; + this.source = source; + } + return ExportAllDeclaration; + }()); + exports.ExportAllDeclaration = ExportAllDeclaration; + var ExportDefaultDeclaration = (function () { + function ExportDefaultDeclaration(declaration) { + this.type = syntax_1.Syntax.ExportDefaultDeclaration; + this.declaration = declaration; + } + return ExportDefaultDeclaration; + }()); + exports.ExportDefaultDeclaration = ExportDefaultDeclaration; + var ExportNamedDeclaration = (function () { + function ExportNamedDeclaration(declaration, specifiers, source) { + this.type = syntax_1.Syntax.ExportNamedDeclaration; + this.declaration = declaration; + this.specifiers = specifiers; + this.source = source; + } + return ExportNamedDeclaration; + }()); + exports.ExportNamedDeclaration = ExportNamedDeclaration; + var ExportSpecifier = (function () { + function ExportSpecifier(local, exported) { + this.type = syntax_1.Syntax.ExportSpecifier; + this.exported = exported; + this.local = local; + } + return ExportSpecifier; + }()); + exports.ExportSpecifier = ExportSpecifier; + var ExpressionStatement = (function () { + function ExpressionStatement(expression) { + this.type = syntax_1.Syntax.ExpressionStatement; + this.expression = expression; + } + return ExpressionStatement; + }()); + exports.ExpressionStatement = ExpressionStatement; + var ForInStatement = (function () { + function ForInStatement(left, right, body) { + this.type = syntax_1.Syntax.ForInStatement; + this.left = left; + this.right = right; + this.body = body; + this.each = false; + } + return ForInStatement; + }()); + exports.ForInStatement = ForInStatement; + var ForOfStatement = (function () { + function ForOfStatement(left, right, body) { + this.type = syntax_1.Syntax.ForOfStatement; + this.left = left; + this.right = right; + this.body = body; + } + return ForOfStatement; + }()); + exports.ForOfStatement = ForOfStatement; + var ForStatement = (function () { + function ForStatement(init, test, update, body) { + this.type = syntax_1.Syntax.ForStatement; + this.init = init; + this.test = test; + this.update = update; + this.body = body; + } + return ForStatement; + }()); + exports.ForStatement = ForStatement; + var FunctionDeclaration = (function () { + function FunctionDeclaration(id, params, body, generator) { + this.type = syntax_1.Syntax.FunctionDeclaration; + this.id = id; + this.params = params; + this.body = body; + this.generator = generator; + this.expression = false; + this.async = false; + } + return FunctionDeclaration; + }()); + exports.FunctionDeclaration = FunctionDeclaration; + var FunctionExpression = (function () { + function FunctionExpression(id, params, body, generator) { + this.type = syntax_1.Syntax.FunctionExpression; + this.id = id; + this.params = params; + this.body = body; + this.generator = generator; + this.expression = false; + this.async = false; + } + return FunctionExpression; + }()); + exports.FunctionExpression = FunctionExpression; + var Identifier = (function () { + function Identifier(name) { + this.type = syntax_1.Syntax.Identifier; + this.name = name; + } + return Identifier; + }()); + exports.Identifier = Identifier; + var IfStatement = (function () { + function IfStatement(test, consequent, alternate) { + this.type = syntax_1.Syntax.IfStatement; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + } + return IfStatement; + }()); + exports.IfStatement = IfStatement; + var ImportDeclaration = (function () { + function ImportDeclaration(specifiers, source) { + this.type = syntax_1.Syntax.ImportDeclaration; + this.specifiers = specifiers; + this.source = source; + } + return ImportDeclaration; + }()); + exports.ImportDeclaration = ImportDeclaration; + var ImportDefaultSpecifier = (function () { + function ImportDefaultSpecifier(local) { + this.type = syntax_1.Syntax.ImportDefaultSpecifier; + this.local = local; + } + return ImportDefaultSpecifier; + }()); + exports.ImportDefaultSpecifier = ImportDefaultSpecifier; + var ImportNamespaceSpecifier = (function () { + function ImportNamespaceSpecifier(local) { + this.type = syntax_1.Syntax.ImportNamespaceSpecifier; + this.local = local; + } + return ImportNamespaceSpecifier; + }()); + exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier; + var ImportSpecifier = (function () { + function ImportSpecifier(local, imported) { + this.type = syntax_1.Syntax.ImportSpecifier; + this.local = local; + this.imported = imported; + } + return ImportSpecifier; + }()); + exports.ImportSpecifier = ImportSpecifier; + var LabeledStatement = (function () { + function LabeledStatement(label, body) { + this.type = syntax_1.Syntax.LabeledStatement; + this.label = label; + this.body = body; + } + return LabeledStatement; + }()); + exports.LabeledStatement = LabeledStatement; + var Literal = (function () { + function Literal(value, raw) { + this.type = syntax_1.Syntax.Literal; + this.value = value; + this.raw = raw; + } + return Literal; + }()); + exports.Literal = Literal; + var MetaProperty = (function () { + function MetaProperty(meta, property) { + this.type = syntax_1.Syntax.MetaProperty; + this.meta = meta; + this.property = property; + } + return MetaProperty; + }()); + exports.MetaProperty = MetaProperty; + var MethodDefinition = (function () { + function MethodDefinition(key, computed, value, kind, isStatic) { + this.type = syntax_1.Syntax.MethodDefinition; + this.key = key; + this.computed = computed; + this.value = value; + this.kind = kind; + this.static = isStatic; + } + return MethodDefinition; + }()); + exports.MethodDefinition = MethodDefinition; + var Module = (function () { + function Module(body) { + this.type = syntax_1.Syntax.Program; + this.body = body; + this.sourceType = 'module'; + } + return Module; + }()); + exports.Module = Module; + var NewExpression = (function () { + function NewExpression(callee, args) { + this.type = syntax_1.Syntax.NewExpression; + this.callee = callee; + this.arguments = args; + } + return NewExpression; + }()); + exports.NewExpression = NewExpression; + var ObjectExpression = (function () { + function ObjectExpression(properties) { + this.type = syntax_1.Syntax.ObjectExpression; + this.properties = properties; + } + return ObjectExpression; + }()); + exports.ObjectExpression = ObjectExpression; + var ObjectPattern = (function () { + function ObjectPattern(properties) { + this.type = syntax_1.Syntax.ObjectPattern; + this.properties = properties; + } + return ObjectPattern; + }()); + exports.ObjectPattern = ObjectPattern; + var Property = (function () { + function Property(kind, key, computed, value, method, shorthand) { + this.type = syntax_1.Syntax.Property; + this.key = key; + this.computed = computed; + this.value = value; + this.kind = kind; + this.method = method; + this.shorthand = shorthand; + } + return Property; + }()); + exports.Property = Property; + var RegexLiteral = (function () { + function RegexLiteral(value, raw, pattern, flags) { + this.type = syntax_1.Syntax.Literal; + this.value = value; + this.raw = raw; + this.regex = { pattern: pattern, flags: flags }; + } + return RegexLiteral; + }()); + exports.RegexLiteral = RegexLiteral; + var RestElement = (function () { + function RestElement(argument) { + this.type = syntax_1.Syntax.RestElement; + this.argument = argument; + } + return RestElement; + }()); + exports.RestElement = RestElement; + var ReturnStatement = (function () { + function ReturnStatement(argument) { + this.type = syntax_1.Syntax.ReturnStatement; + this.argument = argument; + } + return ReturnStatement; + }()); + exports.ReturnStatement = ReturnStatement; + var Script = (function () { + function Script(body) { + this.type = syntax_1.Syntax.Program; + this.body = body; + this.sourceType = 'script'; + } + return Script; + }()); + exports.Script = Script; + var SequenceExpression = (function () { + function SequenceExpression(expressions) { + this.type = syntax_1.Syntax.SequenceExpression; + this.expressions = expressions; + } + return SequenceExpression; + }()); + exports.SequenceExpression = SequenceExpression; + var SpreadElement = (function () { + function SpreadElement(argument) { + this.type = syntax_1.Syntax.SpreadElement; + this.argument = argument; + } + return SpreadElement; + }()); + exports.SpreadElement = SpreadElement; + var StaticMemberExpression = (function () { + function StaticMemberExpression(object, property) { + this.type = syntax_1.Syntax.MemberExpression; + this.computed = false; + this.object = object; + this.property = property; + } + return StaticMemberExpression; + }()); + exports.StaticMemberExpression = StaticMemberExpression; + var Super = (function () { + function Super() { + this.type = syntax_1.Syntax.Super; + } + return Super; + }()); + exports.Super = Super; + var SwitchCase = (function () { + function SwitchCase(test, consequent) { + this.type = syntax_1.Syntax.SwitchCase; + this.test = test; + this.consequent = consequent; + } + return SwitchCase; + }()); + exports.SwitchCase = SwitchCase; + var SwitchStatement = (function () { + function SwitchStatement(discriminant, cases) { + this.type = syntax_1.Syntax.SwitchStatement; + this.discriminant = discriminant; + this.cases = cases; + } + return SwitchStatement; + }()); + exports.SwitchStatement = SwitchStatement; + var TaggedTemplateExpression = (function () { + function TaggedTemplateExpression(tag, quasi) { + this.type = syntax_1.Syntax.TaggedTemplateExpression; + this.tag = tag; + this.quasi = quasi; + } + return TaggedTemplateExpression; + }()); + exports.TaggedTemplateExpression = TaggedTemplateExpression; + var TemplateElement = (function () { + function TemplateElement(value, tail) { + this.type = syntax_1.Syntax.TemplateElement; + this.value = value; + this.tail = tail; + } + return TemplateElement; + }()); + exports.TemplateElement = TemplateElement; + var TemplateLiteral = (function () { + function TemplateLiteral(quasis, expressions) { + this.type = syntax_1.Syntax.TemplateLiteral; + this.quasis = quasis; + this.expressions = expressions; + } + return TemplateLiteral; + }()); + exports.TemplateLiteral = TemplateLiteral; + var ThisExpression = (function () { + function ThisExpression() { + this.type = syntax_1.Syntax.ThisExpression; + } + return ThisExpression; + }()); + exports.ThisExpression = ThisExpression; + var ThrowStatement = (function () { + function ThrowStatement(argument) { + this.type = syntax_1.Syntax.ThrowStatement; + this.argument = argument; + } + return ThrowStatement; + }()); + exports.ThrowStatement = ThrowStatement; + var TryStatement = (function () { + function TryStatement(block, handler, finalizer) { + this.type = syntax_1.Syntax.TryStatement; + this.block = block; + this.handler = handler; + this.finalizer = finalizer; + } + return TryStatement; + }()); + exports.TryStatement = TryStatement; + var UnaryExpression = (function () { + function UnaryExpression(operator, argument) { + this.type = syntax_1.Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + } + return UnaryExpression; + }()); + exports.UnaryExpression = UnaryExpression; + var UpdateExpression = (function () { + function UpdateExpression(operator, argument, prefix) { + this.type = syntax_1.Syntax.UpdateExpression; + this.operator = operator; + this.argument = argument; + this.prefix = prefix; + } + return UpdateExpression; + }()); + exports.UpdateExpression = UpdateExpression; + var VariableDeclaration = (function () { + function VariableDeclaration(declarations, kind) { + this.type = syntax_1.Syntax.VariableDeclaration; + this.declarations = declarations; + this.kind = kind; + } + return VariableDeclaration; + }()); + exports.VariableDeclaration = VariableDeclaration; + var VariableDeclarator = (function () { + function VariableDeclarator(id, init) { + this.type = syntax_1.Syntax.VariableDeclarator; + this.id = id; + this.init = init; + } + return VariableDeclarator; + }()); + exports.VariableDeclarator = VariableDeclarator; + var WhileStatement = (function () { + function WhileStatement(test, body) { + this.type = syntax_1.Syntax.WhileStatement; + this.test = test; + this.body = body; + } + return WhileStatement; + }()); + exports.WhileStatement = WhileStatement; + var WithStatement = (function () { + function WithStatement(object, body) { + this.type = syntax_1.Syntax.WithStatement; + this.object = object; + this.body = body; + } + return WithStatement; + }()); + exports.WithStatement = WithStatement; + var YieldExpression = (function () { + function YieldExpression(argument, delegate) { + this.type = syntax_1.Syntax.YieldExpression; + this.argument = argument; + this.delegate = delegate; + } + return YieldExpression; + }()); + exports.YieldExpression = YieldExpression; + + + /***/ }, + /* 8 */ + /***/ function(module, exports, __webpack_require__) { + Object.defineProperty(exports, "__esModule", { value: true }); + var assert_1 = __webpack_require__(9); + var error_handler_1 = __webpack_require__(10); + var messages_1 = __webpack_require__(11); + var Node = __webpack_require__(7); + var scanner_1 = __webpack_require__(12); + var syntax_1 = __webpack_require__(2); + var token_1 = __webpack_require__(13); + var ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder'; + var Parser = (function () { + function Parser(code, options, delegate) { + if (options === void 0) { options = {}; } + this.config = { + range: (typeof options.range === 'boolean') && options.range, + loc: (typeof options.loc === 'boolean') && options.loc, + source: null, + tokens: (typeof options.tokens === 'boolean') && options.tokens, + comment: (typeof options.comment === 'boolean') && options.comment, + tolerant: (typeof options.tolerant === 'boolean') && options.tolerant + }; + if (this.config.loc && options.source && options.source !== null) { + this.config.source = String(options.source); + } + this.delegate = delegate; + this.errorHandler = new error_handler_1.ErrorHandler(); + this.errorHandler.tolerant = this.config.tolerant; + this.scanner = new scanner_1.Scanner(code, this.errorHandler); + this.scanner.trackComment = this.config.comment; + this.operatorPrecedence = { + ')': 0, + ';': 0, + ',': 0, + '=': 0, + ']': 0, + '||': 1, + '&&': 2, + '|': 3, + '^': 4, + '&': 5, + '==': 6, + '!=': 6, + '===': 6, + '!==': 6, + '<': 7, + '>': 7, + '<=': 7, + '>=': 7, + '<<': 8, + '>>': 8, + '>>>': 8, + '+': 9, + '-': 9, + '*': 11, + '/': 11, + '%': 11 + }; + this.lookahead = { + type: 2 /* EOF */, + value: '', + lineNumber: this.scanner.lineNumber, + lineStart: 0, + start: 0, + end: 0 + }; + this.hasLineTerminator = false; + this.context = { + isModule: false, + await: false, + allowIn: true, + allowStrictDirective: true, + allowYield: true, + firstCoverInitializedNameError: null, + isAssignmentTarget: false, + isBindingElement: false, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + labelSet: {}, + strict: false + }; + this.tokens = []; + this.startMarker = { + index: 0, + line: this.scanner.lineNumber, + column: 0 + }; + this.lastMarker = { + index: 0, + line: this.scanner.lineNumber, + column: 0 + }; + this.nextToken(); + this.lastMarker = { + index: this.scanner.index, + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + }; + } + Parser.prototype.throwError = function (messageFormat) { + var args = Array.prototype.slice.call(arguments, 1); + var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { + assert_1.assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + }); + var index = this.lastMarker.index; + var line = this.lastMarker.line; + var column = this.lastMarker.column + 1; + throw this.errorHandler.createError(index, line, column, msg); + }; + Parser.prototype.tolerateError = function (messageFormat) { + var args = Array.prototype.slice.call(arguments, 1); + var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { + assert_1.assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + }); + var index = this.lastMarker.index; + var line = this.scanner.lineNumber; + var column = this.lastMarker.column + 1; + this.errorHandler.tolerateError(index, line, column, msg); + }; + // Throw an exception because of the token. + Parser.prototype.unexpectedTokenError = function (token, message) { + var msg = message || messages_1.Messages.UnexpectedToken; + var value; + if (token) { + if (!message) { + msg = (token.type === 2 /* EOF */) ? messages_1.Messages.UnexpectedEOS : + (token.type === 3 /* Identifier */) ? messages_1.Messages.UnexpectedIdentifier : + (token.type === 6 /* NumericLiteral */) ? messages_1.Messages.UnexpectedNumber : + (token.type === 8 /* StringLiteral */) ? messages_1.Messages.UnexpectedString : + (token.type === 10 /* Template */) ? messages_1.Messages.UnexpectedTemplate : + messages_1.Messages.UnexpectedToken; + if (token.type === 4 /* Keyword */) { + if (this.scanner.isFutureReservedWord(token.value)) { + msg = messages_1.Messages.UnexpectedReserved; + } + else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) { + msg = messages_1.Messages.StrictReservedWord; + } + } + } + value = token.value; + } + else { + value = 'ILLEGAL'; + } + msg = msg.replace('%0', value); + if (token && typeof token.lineNumber === 'number') { + var index = token.start; + var line = token.lineNumber; + var lastMarkerLineStart = this.lastMarker.index - this.lastMarker.column; + var column = token.start - lastMarkerLineStart + 1; + return this.errorHandler.createError(index, line, column, msg); + } + else { + var index = this.lastMarker.index; + var line = this.lastMarker.line; + var column = this.lastMarker.column + 1; + return this.errorHandler.createError(index, line, column, msg); + } + }; + Parser.prototype.throwUnexpectedToken = function (token, message) { + throw this.unexpectedTokenError(token, message); + }; + Parser.prototype.tolerateUnexpectedToken = function (token, message) { + this.errorHandler.tolerate(this.unexpectedTokenError(token, message)); + }; + Parser.prototype.collectComments = function () { + if (!this.config.comment) { + this.scanner.scanComments(); + } + else { + var comments = this.scanner.scanComments(); + if (comments.length > 0 && this.delegate) { + for (var i = 0; i < comments.length; ++i) { + var e = comments[i]; + var node = void 0; + node = { + type: e.multiLine ? 'BlockComment' : 'LineComment', + value: this.scanner.source.slice(e.slice[0], e.slice[1]) + }; + if (this.config.range) { + node.range = e.range; + } + if (this.config.loc) { + node.loc = e.loc; + } + var metadata = { + start: { + line: e.loc.start.line, + column: e.loc.start.column, + offset: e.range[0] + }, + end: { + line: e.loc.end.line, + column: e.loc.end.column, + offset: e.range[1] + } + }; + this.delegate(node, metadata); + } + } + } + }; + // From internal representation to an external structure + Parser.prototype.getTokenRaw = function (token) { + return this.scanner.source.slice(token.start, token.end); + }; + Parser.prototype.convertToken = function (token) { + var t = { + type: token_1.TokenName[token.type], + value: this.getTokenRaw(token) + }; + if (this.config.range) { + t.range = [token.start, token.end]; + } + if (this.config.loc) { + t.loc = { + start: { + line: this.startMarker.line, + column: this.startMarker.column + }, + end: { + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + } + }; + } + if (token.type === 9 /* RegularExpression */) { + var pattern = token.pattern; + var flags = token.flags; + t.regex = { pattern: pattern, flags: flags }; + } + return t; + }; + Parser.prototype.nextToken = function () { + var token = this.lookahead; + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + this.collectComments(); + if (this.scanner.index !== this.startMarker.index) { + this.startMarker.index = this.scanner.index; + this.startMarker.line = this.scanner.lineNumber; + this.startMarker.column = this.scanner.index - this.scanner.lineStart; + } + var next = this.scanner.lex(); + this.hasLineTerminator = (token.lineNumber !== next.lineNumber); + if (next && this.context.strict && next.type === 3 /* Identifier */) { + if (this.scanner.isStrictModeReservedWord(next.value)) { + next.type = 4 /* Keyword */; + } + } + this.lookahead = next; + if (this.config.tokens && next.type !== 2 /* EOF */) { + this.tokens.push(this.convertToken(next)); + } + return token; + }; + Parser.prototype.nextRegexToken = function () { + this.collectComments(); + var token = this.scanner.scanRegExp(); + if (this.config.tokens) { + // Pop the previous token, '/' or '/=' + // This is added from the lookahead token. + this.tokens.pop(); + this.tokens.push(this.convertToken(token)); + } + // Prime the next lookahead. + this.lookahead = token; + this.nextToken(); + return token; + }; + Parser.prototype.createNode = function () { + return { + index: this.startMarker.index, + line: this.startMarker.line, + column: this.startMarker.column + }; + }; + Parser.prototype.startNode = function (token, lastLineStart) { + if (lastLineStart === void 0) { lastLineStart = 0; } + var column = token.start - token.lineStart; + var line = token.lineNumber; + if (column < 0) { + column += lastLineStart; + line--; + } + return { + index: token.start, + line: line, + column: column + }; + }; + Parser.prototype.finalize = function (marker, node) { + if (this.config.range) { + node.range = [marker.index, this.lastMarker.index]; + } + if (this.config.loc) { + node.loc = { + start: { + line: marker.line, + column: marker.column, + }, + end: { + line: this.lastMarker.line, + column: this.lastMarker.column + } + }; + if (this.config.source) { + node.loc.source = this.config.source; + } + } + if (this.delegate) { + var metadata = { + start: { + line: marker.line, + column: marker.column, + offset: marker.index + }, + end: { + line: this.lastMarker.line, + column: this.lastMarker.column, + offset: this.lastMarker.index + } + }; + this.delegate(node, metadata); + } + return node; + }; + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + Parser.prototype.expect = function (value) { + var token = this.nextToken(); + if (token.type !== 7 /* Punctuator */ || token.value !== value) { + this.throwUnexpectedToken(token); + } + }; + // Quietly expect a comma when in tolerant mode, otherwise delegates to expect(). + Parser.prototype.expectCommaSeparator = function () { + if (this.config.tolerant) { + var token = this.lookahead; + if (token.type === 7 /* Punctuator */ && token.value === ',') { + this.nextToken(); + } + else if (token.type === 7 /* Punctuator */ && token.value === ';') { + this.nextToken(); + this.tolerateUnexpectedToken(token); + } + else { + this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken); + } + } + else { + this.expect(','); + } + }; + // Expect the next token to match the specified keyword. + // If not, an exception will be thrown. + Parser.prototype.expectKeyword = function (keyword) { + var token = this.nextToken(); + if (token.type !== 4 /* Keyword */ || token.value !== keyword) { + this.throwUnexpectedToken(token); + } + }; + // Return true if the next token matches the specified punctuator. + Parser.prototype.match = function (value) { + return this.lookahead.type === 7 /* Punctuator */ && this.lookahead.value === value; + }; + // Return true if the next token matches the specified keyword + Parser.prototype.matchKeyword = function (keyword) { + return this.lookahead.type === 4 /* Keyword */ && this.lookahead.value === keyword; + }; + // Return true if the next token matches the specified contextual keyword + // (where an identifier is sometimes a keyword depending on the context) + Parser.prototype.matchContextualKeyword = function (keyword) { + return this.lookahead.type === 3 /* Identifier */ && this.lookahead.value === keyword; + }; + // Return true if the next token is an assignment operator + Parser.prototype.matchAssign = function () { + if (this.lookahead.type !== 7 /* Punctuator */) { + return false; + } + var op = this.lookahead.value; + return op === '=' || + op === '*=' || + op === '**=' || + op === '/=' || + op === '%=' || + op === '+=' || + op === '-=' || + op === '<<=' || + op === '>>=' || + op === '>>>=' || + op === '&=' || + op === '^=' || + op === '|='; + }; + // Cover grammar support. + // + // When an assignment expression position starts with an left parenthesis, the determination of the type + // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) + // or the first comma. This situation also defers the determination of all the expressions nested in the pair. + // + // There are three productions that can be parsed in a parentheses pair that needs to be determined + // after the outermost pair is closed. They are: + // + // 1. AssignmentExpression + // 2. BindingElements + // 3. AssignmentTargets + // + // In order to avoid exponential backtracking, we use two flags to denote if the production can be + // binding element or assignment target. + // + // The three productions have the relationship: + // + // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression + // + // with a single exception that CoverInitializedName when used directly in an Expression, generates + // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the + // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. + // + // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not + // effect the current flags. This means the production the parser parses is only used as an expression. Therefore + // the CoverInitializedName check is conducted. + // + // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates + // the flags outside of the parser. This means the production the parser parses is used as a part of a potential + // pattern. The CoverInitializedName check is deferred. + Parser.prototype.isolateCoverGrammar = function (parseFunction) { + var previousIsBindingElement = this.context.isBindingElement; + var previousIsAssignmentTarget = this.context.isAssignmentTarget; + var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; + this.context.isBindingElement = true; + this.context.isAssignmentTarget = true; + this.context.firstCoverInitializedNameError = null; + var result = parseFunction.call(this); + if (this.context.firstCoverInitializedNameError !== null) { + this.throwUnexpectedToken(this.context.firstCoverInitializedNameError); + } + this.context.isBindingElement = previousIsBindingElement; + this.context.isAssignmentTarget = previousIsAssignmentTarget; + this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError; + return result; + }; + Parser.prototype.inheritCoverGrammar = function (parseFunction) { + var previousIsBindingElement = this.context.isBindingElement; + var previousIsAssignmentTarget = this.context.isAssignmentTarget; + var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; + this.context.isBindingElement = true; + this.context.isAssignmentTarget = true; + this.context.firstCoverInitializedNameError = null; + var result = parseFunction.call(this); + this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement; + this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget; + this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError; + return result; + }; + Parser.prototype.consumeSemicolon = function () { + if (this.match(';')) { + this.nextToken(); + } + else if (!this.hasLineTerminator) { + if (this.lookahead.type !== 2 /* EOF */ && !this.match('}')) { + this.throwUnexpectedToken(this.lookahead); + } + this.lastMarker.index = this.startMarker.index; + this.lastMarker.line = this.startMarker.line; + this.lastMarker.column = this.startMarker.column; + } + }; + // https://tc39.github.io/ecma262/#sec-primary-expression + Parser.prototype.parsePrimaryExpression = function () { + var node = this.createNode(); + var expr; + var token, raw; + switch (this.lookahead.type) { + case 3 /* Identifier */: + if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') { + this.tolerateUnexpectedToken(this.lookahead); + } + expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value)); + break; + case 6 /* NumericLiteral */: + case 8 /* StringLiteral */: + if (this.context.strict && this.lookahead.octal) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case 1 /* BooleanLiteral */: + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(token.value === 'true', raw)); + break; + case 5 /* NullLiteral */: + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(null, raw)); + break; + case 10 /* Template */: + expr = this.parseTemplateLiteral(); + break; + case 7 /* Punctuator */: + switch (this.lookahead.value) { + case '(': + this.context.isBindingElement = false; + expr = this.inheritCoverGrammar(this.parseGroupExpression); + break; + case '[': + expr = this.inheritCoverGrammar(this.parseArrayInitializer); + break; + case '{': + expr = this.inheritCoverGrammar(this.parseObjectInitializer); + break; + case '/': + case '/=': + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + this.scanner.index = this.startMarker.index; + token = this.nextRegexToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.RegexLiteral(token.regex, raw, token.pattern, token.flags)); + break; + default: + expr = this.throwUnexpectedToken(this.nextToken()); + } + break; + case 4 /* Keyword */: + if (!this.context.strict && this.context.allowYield && this.matchKeyword('yield')) { + expr = this.parseIdentifierName(); + } + else if (!this.context.strict && this.matchKeyword('let')) { + expr = this.finalize(node, new Node.Identifier(this.nextToken().value)); + } + else { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + if (this.matchKeyword('function')) { + expr = this.parseFunctionExpression(); + } + else if (this.matchKeyword('this')) { + this.nextToken(); + expr = this.finalize(node, new Node.ThisExpression()); + } + else if (this.matchKeyword('class')) { + expr = this.parseClassExpression(); + } + else { + expr = this.throwUnexpectedToken(this.nextToken()); + } + } + break; + default: + expr = this.throwUnexpectedToken(this.nextToken()); + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-array-initializer + Parser.prototype.parseSpreadElement = function () { + var node = this.createNode(); + this.expect('...'); + var arg = this.inheritCoverGrammar(this.parseAssignmentExpression); + return this.finalize(node, new Node.SpreadElement(arg)); + }; + Parser.prototype.parseArrayInitializer = function () { + var node = this.createNode(); + var elements = []; + this.expect('['); + while (!this.match(']')) { + if (this.match(',')) { + this.nextToken(); + elements.push(null); + } + else if (this.match('...')) { + var element = this.parseSpreadElement(); + if (!this.match(']')) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + this.expect(','); + } + elements.push(element); + } + else { + elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); + if (!this.match(']')) { + this.expect(','); + } + } + } + this.expect(']'); + return this.finalize(node, new Node.ArrayExpression(elements)); + }; + // https://tc39.github.io/ecma262/#sec-object-initializer + Parser.prototype.parsePropertyMethod = function (params) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = params.simple; + var body = this.isolateCoverGrammar(this.parseFunctionSourceElements); + if (this.context.strict && params.firstRestricted) { + this.tolerateUnexpectedToken(params.firstRestricted, params.message); + } + if (this.context.strict && params.stricted) { + this.tolerateUnexpectedToken(params.stricted, params.message); + } + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + return body; + }; + Parser.prototype.parsePropertyMethodFunction = function () { + var isGenerator = false; + var node = this.createNode(); + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var params = this.parseFormalParameters(); + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); + }; + Parser.prototype.parsePropertyMethodAsyncFunction = function () { + var node = this.createNode(); + var previousAllowYield = this.context.allowYield; + var previousAwait = this.context.await; + this.context.allowYield = false; + this.context.await = true; + var params = this.parseFormalParameters(); + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + this.context.await = previousAwait; + return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method)); + }; + Parser.prototype.parseObjectPropertyKey = function () { + var node = this.createNode(); + var token = this.nextToken(); + var key; + switch (token.type) { + case 8 /* StringLiteral */: + case 6 /* NumericLiteral */: + if (this.context.strict && token.octal) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral); + } + var raw = this.getTokenRaw(token); + key = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case 3 /* Identifier */: + case 1 /* BooleanLiteral */: + case 5 /* NullLiteral */: + case 4 /* Keyword */: + key = this.finalize(node, new Node.Identifier(token.value)); + break; + case 7 /* Punctuator */: + if (token.value === '[') { + key = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.expect(']'); + } + else { + key = this.throwUnexpectedToken(token); + } + break; + default: + key = this.throwUnexpectedToken(token); + } + return key; + }; + Parser.prototype.isPropertyKey = function (key, value) { + return (key.type === syntax_1.Syntax.Identifier && key.name === value) || + (key.type === syntax_1.Syntax.Literal && key.value === value); + }; + Parser.prototype.parseObjectProperty = function (hasProto) { + var node = this.createNode(); + var token = this.lookahead; + var kind; + var key = null; + var value = null; + var computed = false; + var method = false; + var shorthand = false; + var isAsync = false; + if (token.type === 3 /* Identifier */) { + var id = token.value; + this.nextToken(); + computed = this.match('['); + isAsync = !this.hasLineTerminator && (id === 'async') && + !this.match(':') && !this.match('(') && !this.match('*') && !this.match(','); + key = isAsync ? this.parseObjectPropertyKey() : this.finalize(node, new Node.Identifier(id)); + } + else if (this.match('*')) { + this.nextToken(); + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + } + var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); + if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'get' && lookaheadPropertyKey) { + kind = 'get'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.context.allowYield = false; + value = this.parseGetterMethod(); + } + else if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'set' && lookaheadPropertyKey) { + kind = 'set'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseSetterMethod(); + } + else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { + kind = 'init'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseGeneratorMethod(); + method = true; + } + else { + if (!key) { + this.throwUnexpectedToken(this.lookahead); + } + kind = 'init'; + if (this.match(':') && !isAsync) { + if (!computed && this.isPropertyKey(key, '__proto__')) { + if (hasProto.value) { + this.tolerateError(messages_1.Messages.DuplicateProtoProperty); + } + hasProto.value = true; + } + this.nextToken(); + value = this.inheritCoverGrammar(this.parseAssignmentExpression); + } + else if (this.match('(')) { + value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); + method = true; + } + else if (token.type === 3 /* Identifier */) { + var id = this.finalize(node, new Node.Identifier(token.value)); + if (this.match('=')) { + this.context.firstCoverInitializedNameError = this.lookahead; + this.nextToken(); + shorthand = true; + var init = this.isolateCoverGrammar(this.parseAssignmentExpression); + value = this.finalize(node, new Node.AssignmentPattern(id, init)); + } + else { + shorthand = true; + value = id; + } + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + } + return this.finalize(node, new Node.Property(kind, key, computed, value, method, shorthand)); + }; + Parser.prototype.parseObjectInitializer = function () { + var node = this.createNode(); + this.expect('{'); + var properties = []; + var hasProto = { value: false }; + while (!this.match('}')) { + properties.push(this.parseObjectProperty(hasProto)); + if (!this.match('}')) { + this.expectCommaSeparator(); + } + } + this.expect('}'); + return this.finalize(node, new Node.ObjectExpression(properties)); + }; + // https://tc39.github.io/ecma262/#sec-template-literals + Parser.prototype.parseTemplateHead = function () { + assert_1.assert(this.lookahead.head, 'Template literal must start with a template head'); + var node = this.createNode(); + var token = this.nextToken(); + var raw = token.value; + var cooked = token.cooked; + return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); + }; + Parser.prototype.parseTemplateElement = function () { + if (this.lookahead.type !== 10 /* Template */) { + this.throwUnexpectedToken(); + } + var node = this.createNode(); + var token = this.nextToken(); + var raw = token.value; + var cooked = token.cooked; + return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); + }; + Parser.prototype.parseTemplateLiteral = function () { + var node = this.createNode(); + var expressions = []; + var quasis = []; + var quasi = this.parseTemplateHead(); + quasis.push(quasi); + while (!quasi.tail) { + expressions.push(this.parseExpression()); + quasi = this.parseTemplateElement(); + quasis.push(quasi); + } + return this.finalize(node, new Node.TemplateLiteral(quasis, expressions)); + }; + // https://tc39.github.io/ecma262/#sec-grouping-operator + Parser.prototype.reinterpretExpressionAsPattern = function (expr) { + switch (expr.type) { + case syntax_1.Syntax.Identifier: + case syntax_1.Syntax.MemberExpression: + case syntax_1.Syntax.RestElement: + case syntax_1.Syntax.AssignmentPattern: + break; + case syntax_1.Syntax.SpreadElement: + expr.type = syntax_1.Syntax.RestElement; + this.reinterpretExpressionAsPattern(expr.argument); + break; + case syntax_1.Syntax.ArrayExpression: + expr.type = syntax_1.Syntax.ArrayPattern; + for (var i = 0; i < expr.elements.length; i++) { + if (expr.elements[i] !== null) { + this.reinterpretExpressionAsPattern(expr.elements[i]); + } + } + break; + case syntax_1.Syntax.ObjectExpression: + expr.type = syntax_1.Syntax.ObjectPattern; + for (var i = 0; i < expr.properties.length; i++) { + this.reinterpretExpressionAsPattern(expr.properties[i].value); + } + break; + case syntax_1.Syntax.AssignmentExpression: + expr.type = syntax_1.Syntax.AssignmentPattern; + delete expr.operator; + this.reinterpretExpressionAsPattern(expr.left); + break; + } + }; + Parser.prototype.parseGroupExpression = function () { + var expr; + this.expect('('); + if (this.match(')')) { + this.nextToken(); + if (!this.match('=>')) { + this.expect('=>'); + } + expr = { + type: ArrowParameterPlaceHolder, + params: [], + async: false + }; + } + else { + var startToken = this.lookahead; + var params = []; + if (this.match('...')) { + expr = this.parseRestElement(params); + this.expect(')'); + if (!this.match('=>')) { + this.expect('=>'); + } + expr = { + type: ArrowParameterPlaceHolder, + params: [expr], + async: false + }; + } + else { + var arrow = false; + this.context.isBindingElement = true; + expr = this.inheritCoverGrammar(this.parseAssignmentExpression); + if (this.match(',')) { + var expressions = []; + this.context.isAssignmentTarget = false; + expressions.push(expr); + while (this.lookahead.type !== 2 /* EOF */) { + if (!this.match(',')) { + break; + } + this.nextToken(); + if (this.match(')')) { + this.nextToken(); + for (var i = 0; i < expressions.length; i++) { + this.reinterpretExpressionAsPattern(expressions[i]); + } + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: expressions, + async: false + }; + } + else if (this.match('...')) { + if (!this.context.isBindingElement) { + this.throwUnexpectedToken(this.lookahead); + } + expressions.push(this.parseRestElement(params)); + this.expect(')'); + if (!this.match('=>')) { + this.expect('=>'); + } + this.context.isBindingElement = false; + for (var i = 0; i < expressions.length; i++) { + this.reinterpretExpressionAsPattern(expressions[i]); + } + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: expressions, + async: false + }; + } + else { + expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); + } + if (arrow) { + break; + } + } + if (!arrow) { + expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); + } + } + if (!arrow) { + this.expect(')'); + if (this.match('=>')) { + if (expr.type === syntax_1.Syntax.Identifier && expr.name === 'yield') { + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: [expr], + async: false + }; + } + if (!arrow) { + if (!this.context.isBindingElement) { + this.throwUnexpectedToken(this.lookahead); + } + if (expr.type === syntax_1.Syntax.SequenceExpression) { + for (var i = 0; i < expr.expressions.length; i++) { + this.reinterpretExpressionAsPattern(expr.expressions[i]); + } + } + else { + this.reinterpretExpressionAsPattern(expr); + } + var parameters = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]); + expr = { + type: ArrowParameterPlaceHolder, + params: parameters, + async: false + }; + } + } + this.context.isBindingElement = false; + } + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-left-hand-side-expressions + Parser.prototype.parseArguments = function () { + this.expect('('); + var args = []; + if (!this.match(')')) { + while (true) { + var expr = this.match('...') ? this.parseSpreadElement() : + this.isolateCoverGrammar(this.parseAssignmentExpression); + args.push(expr); + if (this.match(')')) { + break; + } + this.expectCommaSeparator(); + if (this.match(')')) { + break; + } + } + } + this.expect(')'); + return args; + }; + Parser.prototype.isIdentifierName = function (token) { + return token.type === 3 /* Identifier */ || + token.type === 4 /* Keyword */ || + token.type === 1 /* BooleanLiteral */ || + token.type === 5 /* NullLiteral */; + }; + Parser.prototype.parseIdentifierName = function () { + var node = this.createNode(); + var token = this.nextToken(); + if (!this.isIdentifierName(token)) { + this.throwUnexpectedToken(token); + } + return this.finalize(node, new Node.Identifier(token.value)); + }; + Parser.prototype.parseNewExpression = function () { + var node = this.createNode(); + var id = this.parseIdentifierName(); + assert_1.assert(id.name === 'new', 'New expression must start with `new`'); + var expr; + if (this.match('.')) { + this.nextToken(); + if (this.lookahead.type === 3 /* Identifier */ && this.context.inFunctionBody && this.lookahead.value === 'target') { + var property = this.parseIdentifierName(); + expr = new Node.MetaProperty(id, property); + } + else { + this.throwUnexpectedToken(this.lookahead); + } + } + else { + var callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression); + var args = this.match('(') ? this.parseArguments() : []; + expr = new Node.NewExpression(callee, args); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + return this.finalize(node, expr); + }; + Parser.prototype.parseAsyncArgument = function () { + var arg = this.parseAssignmentExpression(); + this.context.firstCoverInitializedNameError = null; + return arg; + }; + Parser.prototype.parseAsyncArguments = function () { + this.expect('('); + var args = []; + if (!this.match(')')) { + while (true) { + var expr = this.match('...') ? this.parseSpreadElement() : + this.isolateCoverGrammar(this.parseAsyncArgument); + args.push(expr); + if (this.match(')')) { + break; + } + this.expectCommaSeparator(); + if (this.match(')')) { + break; + } + } + } + this.expect(')'); + return args; + }; + Parser.prototype.parseLeftHandSideExpressionAllowCall = function () { + var startToken = this.lookahead; + var maybeAsync = this.matchContextualKeyword('async'); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + var expr; + if (this.matchKeyword('super') && this.context.inFunctionBody) { + expr = this.createNode(); + this.nextToken(); + expr = this.finalize(expr, new Node.Super()); + if (!this.match('(') && !this.match('.') && !this.match('[')) { + this.throwUnexpectedToken(this.lookahead); + } + } + else { + expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); + } + while (true) { + if (this.match('.')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('.'); + var property = this.parseIdentifierName(); + expr = this.finalize(this.startNode(startToken), new Node.StaticMemberExpression(expr, property)); + } + else if (this.match('(')) { + var asyncArrow = maybeAsync && (startToken.lineNumber === this.lookahead.lineNumber); + this.context.isBindingElement = false; + this.context.isAssignmentTarget = false; + var args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments(); + expr = this.finalize(this.startNode(startToken), new Node.CallExpression(expr, args)); + if (asyncArrow && this.match('=>')) { + for (var i = 0; i < args.length; ++i) { + this.reinterpretExpressionAsPattern(args[i]); + } + expr = { + type: ArrowParameterPlaceHolder, + params: args, + async: true + }; + } + } + else if (this.match('[')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('['); + var property = this.isolateCoverGrammar(this.parseExpression); + this.expect(']'); + expr = this.finalize(this.startNode(startToken), new Node.ComputedMemberExpression(expr, property)); + } + else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { + var quasi = this.parseTemplateLiteral(); + expr = this.finalize(this.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi)); + } + else { + break; + } + } + this.context.allowIn = previousAllowIn; + return expr; + }; + Parser.prototype.parseSuper = function () { + var node = this.createNode(); + this.expectKeyword('super'); + if (!this.match('[') && !this.match('.')) { + this.throwUnexpectedToken(this.lookahead); + } + return this.finalize(node, new Node.Super()); + }; + Parser.prototype.parseLeftHandSideExpression = function () { + assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.'); + var node = this.startNode(this.lookahead); + var expr = (this.matchKeyword('super') && this.context.inFunctionBody) ? this.parseSuper() : + this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); + while (true) { + if (this.match('[')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('['); + var property = this.isolateCoverGrammar(this.parseExpression); + this.expect(']'); + expr = this.finalize(node, new Node.ComputedMemberExpression(expr, property)); + } + else if (this.match('.')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('.'); + var property = this.parseIdentifierName(); + expr = this.finalize(node, new Node.StaticMemberExpression(expr, property)); + } + else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { + var quasi = this.parseTemplateLiteral(); + expr = this.finalize(node, new Node.TaggedTemplateExpression(expr, quasi)); + } + else { + break; + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-update-expressions + Parser.prototype.parseUpdateExpression = function () { + var expr; + var startToken = this.lookahead; + if (this.match('++') || this.match('--')) { + var node = this.startNode(startToken); + var token = this.nextToken(); + expr = this.inheritCoverGrammar(this.parseUnaryExpression); + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { + this.tolerateError(messages_1.Messages.StrictLHSPrefix); + } + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + var prefix = true; + expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix)); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else { + expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + if (!this.hasLineTerminator && this.lookahead.type === 7 /* Punctuator */) { + if (this.match('++') || this.match('--')) { + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { + this.tolerateError(messages_1.Messages.StrictLHSPostfix); + } + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var operator = this.nextToken().value; + var prefix = false; + expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix)); + } + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-unary-operators + Parser.prototype.parseAwaitExpression = function () { + var node = this.createNode(); + this.nextToken(); + var argument = this.parseUnaryExpression(); + return this.finalize(node, new Node.AwaitExpression(argument)); + }; + Parser.prototype.parseUnaryExpression = function () { + var expr; + if (this.match('+') || this.match('-') || this.match('~') || this.match('!') || + this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) { + var node = this.startNode(this.lookahead); + var token = this.nextToken(); + expr = this.inheritCoverGrammar(this.parseUnaryExpression); + expr = this.finalize(node, new Node.UnaryExpression(token.value, expr)); + if (this.context.strict && expr.operator === 'delete' && expr.argument.type === syntax_1.Syntax.Identifier) { + this.tolerateError(messages_1.Messages.StrictDelete); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else if (this.context.await && this.matchContextualKeyword('await')) { + expr = this.parseAwaitExpression(); + } + else { + expr = this.parseUpdateExpression(); + } + return expr; + }; + Parser.prototype.parseExponentiationExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseUnaryExpression); + if (expr.type !== syntax_1.Syntax.UnaryExpression && this.match('**')) { + this.nextToken(); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var left = expr; + var right = this.isolateCoverGrammar(this.parseExponentiationExpression); + expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right)); + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-exp-operator + // https://tc39.github.io/ecma262/#sec-multiplicative-operators + // https://tc39.github.io/ecma262/#sec-additive-operators + // https://tc39.github.io/ecma262/#sec-bitwise-shift-operators + // https://tc39.github.io/ecma262/#sec-relational-operators + // https://tc39.github.io/ecma262/#sec-equality-operators + // https://tc39.github.io/ecma262/#sec-binary-bitwise-operators + // https://tc39.github.io/ecma262/#sec-binary-logical-operators + Parser.prototype.binaryPrecedence = function (token) { + var op = token.value; + var precedence; + if (token.type === 7 /* Punctuator */) { + precedence = this.operatorPrecedence[op] || 0; + } + else if (token.type === 4 /* Keyword */) { + precedence = (op === 'instanceof' || (this.context.allowIn && op === 'in')) ? 7 : 0; + } + else { + precedence = 0; + } + return precedence; + }; + Parser.prototype.parseBinaryExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseExponentiationExpression); + var token = this.lookahead; + var prec = this.binaryPrecedence(token); + if (prec > 0) { + this.nextToken(); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var markers = [startToken, this.lookahead]; + var left = expr; + var right = this.isolateCoverGrammar(this.parseExponentiationExpression); + var stack = [left, token.value, right]; + var precedences = [prec]; + while (true) { + prec = this.binaryPrecedence(this.lookahead); + if (prec <= 0) { + break; + } + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= precedences[precedences.length - 1])) { + right = stack.pop(); + var operator = stack.pop(); + precedences.pop(); + left = stack.pop(); + markers.pop(); + var node = this.startNode(markers[markers.length - 1]); + stack.push(this.finalize(node, new Node.BinaryExpression(operator, left, right))); + } + // Shift. + stack.push(this.nextToken().value); + precedences.push(prec); + markers.push(this.lookahead); + stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression)); + } + // Final reduce to clean-up the stack. + var i = stack.length - 1; + expr = stack[i]; + var lastMarker = markers.pop(); + while (i > 1) { + var marker = markers.pop(); + var lastLineStart = lastMarker && lastMarker.lineStart; + var node = this.startNode(marker, lastLineStart); + var operator = stack[i - 1]; + expr = this.finalize(node, new Node.BinaryExpression(operator, stack[i - 2], expr)); + i -= 2; + lastMarker = marker; + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-conditional-operator + Parser.prototype.parseConditionalExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseBinaryExpression); + if (this.match('?')) { + this.nextToken(); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + var consequent = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.context.allowIn = previousAllowIn; + this.expect(':'); + var alternate = this.isolateCoverGrammar(this.parseAssignmentExpression); + expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate)); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-assignment-operators + Parser.prototype.checkPatternParam = function (options, param) { + switch (param.type) { + case syntax_1.Syntax.Identifier: + this.validateParam(options, param, param.name); + break; + case syntax_1.Syntax.RestElement: + this.checkPatternParam(options, param.argument); + break; + case syntax_1.Syntax.AssignmentPattern: + this.checkPatternParam(options, param.left); + break; + case syntax_1.Syntax.ArrayPattern: + for (var i = 0; i < param.elements.length; i++) { + if (param.elements[i] !== null) { + this.checkPatternParam(options, param.elements[i]); + } + } + break; + case syntax_1.Syntax.ObjectPattern: + for (var i = 0; i < param.properties.length; i++) { + this.checkPatternParam(options, param.properties[i].value); + } + break; + } + options.simple = options.simple && (param instanceof Node.Identifier); + }; + Parser.prototype.reinterpretAsCoverFormalsList = function (expr) { + var params = [expr]; + var options; + var asyncArrow = false; + switch (expr.type) { + case syntax_1.Syntax.Identifier: + break; + case ArrowParameterPlaceHolder: + params = expr.params; + asyncArrow = expr.async; + break; + default: + return null; + } + options = { + simple: true, + paramSet: {} + }; + for (var i = 0; i < params.length; ++i) { + var param = params[i]; + if (param.type === syntax_1.Syntax.AssignmentPattern) { + if (param.right.type === syntax_1.Syntax.YieldExpression) { + if (param.right.argument) { + this.throwUnexpectedToken(this.lookahead); + } + param.right.type = syntax_1.Syntax.Identifier; + param.right.name = 'yield'; + delete param.right.argument; + delete param.right.delegate; + } + } + else if (asyncArrow && param.type === syntax_1.Syntax.Identifier && param.name === 'await') { + this.throwUnexpectedToken(this.lookahead); + } + this.checkPatternParam(options, param); + params[i] = param; + } + if (this.context.strict || !this.context.allowYield) { + for (var i = 0; i < params.length; ++i) { + var param = params[i]; + if (param.type === syntax_1.Syntax.YieldExpression) { + this.throwUnexpectedToken(this.lookahead); + } + } + } + if (options.message === messages_1.Messages.StrictParamDupe) { + var token = this.context.strict ? options.stricted : options.firstRestricted; + this.throwUnexpectedToken(token, options.message); + } + return { + simple: options.simple, + params: params, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + }; + Parser.prototype.parseAssignmentExpression = function () { + var expr; + if (!this.context.allowYield && this.matchKeyword('yield')) { + expr = this.parseYieldExpression(); + } + else { + var startToken = this.lookahead; + var token = startToken; + expr = this.parseConditionalExpression(); + if (token.type === 3 /* Identifier */ && (token.lineNumber === this.lookahead.lineNumber) && token.value === 'async') { + if (this.lookahead.type === 3 /* Identifier */ || this.matchKeyword('yield')) { + var arg = this.parsePrimaryExpression(); + this.reinterpretExpressionAsPattern(arg); + expr = { + type: ArrowParameterPlaceHolder, + params: [arg], + async: true + }; + } + } + if (expr.type === ArrowParameterPlaceHolder || this.match('=>')) { + // https://tc39.github.io/ecma262/#sec-arrow-function-definitions + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var isAsync = expr.async; + var list = this.reinterpretAsCoverFormalsList(expr); + if (list) { + if (this.hasLineTerminator) { + this.tolerateUnexpectedToken(this.lookahead); + } + this.context.firstCoverInitializedNameError = null; + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = list.simple; + var previousAllowYield = this.context.allowYield; + var previousAwait = this.context.await; + this.context.allowYield = true; + this.context.await = isAsync; + var node = this.startNode(startToken); + this.expect('=>'); + var body = void 0; + if (this.match('{')) { + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + body = this.parseFunctionSourceElements(); + this.context.allowIn = previousAllowIn; + } + else { + body = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + var expression = body.type !== syntax_1.Syntax.BlockStatement; + if (this.context.strict && list.firstRestricted) { + this.throwUnexpectedToken(list.firstRestricted, list.message); + } + if (this.context.strict && list.stricted) { + this.tolerateUnexpectedToken(list.stricted, list.message); + } + expr = isAsync ? this.finalize(node, new Node.AsyncArrowFunctionExpression(list.params, body, expression)) : + this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression)); + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + this.context.allowYield = previousAllowYield; + this.context.await = previousAwait; + } + } + else { + if (this.matchAssign()) { + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier) { + var id = expr; + if (this.scanner.isRestrictedWord(id.name)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment); + } + if (this.scanner.isStrictModeReservedWord(id.name)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + } + if (!this.match('=')) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else { + this.reinterpretExpressionAsPattern(expr); + } + token = this.nextToken(); + var operator = token.value; + var right = this.isolateCoverGrammar(this.parseAssignmentExpression); + expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(operator, expr, right)); + this.context.firstCoverInitializedNameError = null; + } + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-comma-operator + Parser.prototype.parseExpression = function () { + var startToken = this.lookahead; + var expr = this.isolateCoverGrammar(this.parseAssignmentExpression); + if (this.match(',')) { + var expressions = []; + expressions.push(expr); + while (this.lookahead.type !== 2 /* EOF */) { + if (!this.match(',')) { + break; + } + this.nextToken(); + expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); + } + expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-block + Parser.prototype.parseStatementListItem = function () { + var statement; + this.context.isAssignmentTarget = true; + this.context.isBindingElement = true; + if (this.lookahead.type === 4 /* Keyword */) { + switch (this.lookahead.value) { + case 'export': + if (!this.context.isModule) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration); + } + statement = this.parseExportDeclaration(); + break; + case 'import': + if (!this.context.isModule) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration); + } + statement = this.parseImportDeclaration(); + break; + case 'const': + statement = this.parseLexicalDeclaration({ inFor: false }); + break; + case 'function': + statement = this.parseFunctionDeclaration(); + break; + case 'class': + statement = this.parseClassDeclaration(); + break; + case 'let': + statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement(); + break; + default: + statement = this.parseStatement(); + break; + } + } + else { + statement = this.parseStatement(); + } + return statement; + }; + Parser.prototype.parseBlock = function () { + var node = this.createNode(); + this.expect('{'); + var block = []; + while (true) { + if (this.match('}')) { + break; + } + block.push(this.parseStatementListItem()); + } + this.expect('}'); + return this.finalize(node, new Node.BlockStatement(block)); + }; + // https://tc39.github.io/ecma262/#sec-let-and-const-declarations + Parser.prototype.parseLexicalBinding = function (kind, options) { + var node = this.createNode(); + var params = []; + var id = this.parsePattern(params, kind); + if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord(id.name)) { + this.tolerateError(messages_1.Messages.StrictVarName); + } + } + var init = null; + if (kind === 'const') { + if (!this.matchKeyword('in') && !this.matchContextualKeyword('of')) { + if (this.match('=')) { + this.nextToken(); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + else { + this.throwError(messages_1.Messages.DeclarationMissingInitializer, 'const'); + } + } + } + else if ((!options.inFor && id.type !== syntax_1.Syntax.Identifier) || this.match('=')) { + this.expect('='); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + return this.finalize(node, new Node.VariableDeclarator(id, init)); + }; + Parser.prototype.parseBindingList = function (kind, options) { + var list = [this.parseLexicalBinding(kind, options)]; + while (this.match(',')) { + this.nextToken(); + list.push(this.parseLexicalBinding(kind, options)); + } + return list; + }; + Parser.prototype.isLexicalDeclaration = function () { + var state = this.scanner.saveState(); + this.scanner.scanComments(); + var next = this.scanner.lex(); + this.scanner.restoreState(state); + return (next.type === 3 /* Identifier */) || + (next.type === 7 /* Punctuator */ && next.value === '[') || + (next.type === 7 /* Punctuator */ && next.value === '{') || + (next.type === 4 /* Keyword */ && next.value === 'let') || + (next.type === 4 /* Keyword */ && next.value === 'yield'); + }; + Parser.prototype.parseLexicalDeclaration = function (options) { + var node = this.createNode(); + var kind = this.nextToken().value; + assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const'); + var declarations = this.parseBindingList(kind, options); + this.consumeSemicolon(); + return this.finalize(node, new Node.VariableDeclaration(declarations, kind)); + }; + // https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns + Parser.prototype.parseBindingRestElement = function (params, kind) { + var node = this.createNode(); + this.expect('...'); + var arg = this.parsePattern(params, kind); + return this.finalize(node, new Node.RestElement(arg)); + }; + Parser.prototype.parseArrayPattern = function (params, kind) { + var node = this.createNode(); + this.expect('['); + var elements = []; + while (!this.match(']')) { + if (this.match(',')) { + this.nextToken(); + elements.push(null); + } + else { + if (this.match('...')) { + elements.push(this.parseBindingRestElement(params, kind)); + break; + } + else { + elements.push(this.parsePatternWithDefault(params, kind)); + } + if (!this.match(']')) { + this.expect(','); + } + } + } + this.expect(']'); + return this.finalize(node, new Node.ArrayPattern(elements)); + }; + Parser.prototype.parsePropertyPattern = function (params, kind) { + var node = this.createNode(); + var computed = false; + var shorthand = false; + var method = false; + var key; + var value; + if (this.lookahead.type === 3 /* Identifier */) { + var keyToken = this.lookahead; + key = this.parseVariableIdentifier(); + var init = this.finalize(node, new Node.Identifier(keyToken.value)); + if (this.match('=')) { + params.push(keyToken); + shorthand = true; + this.nextToken(); + var expr = this.parseAssignmentExpression(); + value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr)); + } + else if (!this.match(':')) { + params.push(keyToken); + shorthand = true; + value = init; + } + else { + this.expect(':'); + value = this.parsePatternWithDefault(params, kind); + } + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.expect(':'); + value = this.parsePatternWithDefault(params, kind); + } + return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand)); + }; + Parser.prototype.parseObjectPattern = function (params, kind) { + var node = this.createNode(); + var properties = []; + this.expect('{'); + while (!this.match('}')) { + properties.push(this.parsePropertyPattern(params, kind)); + if (!this.match('}')) { + this.expect(','); + } + } + this.expect('}'); + return this.finalize(node, new Node.ObjectPattern(properties)); + }; + Parser.prototype.parsePattern = function (params, kind) { + var pattern; + if (this.match('[')) { + pattern = this.parseArrayPattern(params, kind); + } + else if (this.match('{')) { + pattern = this.parseObjectPattern(params, kind); + } + else { + if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding); + } + params.push(this.lookahead); + pattern = this.parseVariableIdentifier(kind); + } + return pattern; + }; + Parser.prototype.parsePatternWithDefault = function (params, kind) { + var startToken = this.lookahead; + var pattern = this.parsePattern(params, kind); + if (this.match('=')) { + this.nextToken(); + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var right = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.context.allowYield = previousAllowYield; + pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right)); + } + return pattern; + }; + // https://tc39.github.io/ecma262/#sec-variable-statement + Parser.prototype.parseVariableIdentifier = function (kind) { + var node = this.createNode(); + var token = this.nextToken(); + if (token.type === 4 /* Keyword */ && token.value === 'yield') { + if (this.context.strict) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + else if (!this.context.allowYield) { + this.throwUnexpectedToken(token); + } + } + else if (token.type !== 3 /* Identifier */) { + if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + else { + if (this.context.strict || token.value !== 'let' || kind !== 'var') { + this.throwUnexpectedToken(token); + } + } + } + else if ((this.context.isModule || this.context.await) && token.type === 3 /* Identifier */ && token.value === 'await') { + this.tolerateUnexpectedToken(token); + } + return this.finalize(node, new Node.Identifier(token.value)); + }; + Parser.prototype.parseVariableDeclaration = function (options) { + var node = this.createNode(); + var params = []; + var id = this.parsePattern(params, 'var'); + if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord(id.name)) { + this.tolerateError(messages_1.Messages.StrictVarName); + } + } + var init = null; + if (this.match('=')) { + this.nextToken(); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) { + this.expect('='); + } + return this.finalize(node, new Node.VariableDeclarator(id, init)); + }; + Parser.prototype.parseVariableDeclarationList = function (options) { + var opt = { inFor: options.inFor }; + var list = []; + list.push(this.parseVariableDeclaration(opt)); + while (this.match(',')) { + this.nextToken(); + list.push(this.parseVariableDeclaration(opt)); + } + return list; + }; + Parser.prototype.parseVariableStatement = function () { + var node = this.createNode(); + this.expectKeyword('var'); + var declarations = this.parseVariableDeclarationList({ inFor: false }); + this.consumeSemicolon(); + return this.finalize(node, new Node.VariableDeclaration(declarations, 'var')); + }; + // https://tc39.github.io/ecma262/#sec-empty-statement + Parser.prototype.parseEmptyStatement = function () { + var node = this.createNode(); + this.expect(';'); + return this.finalize(node, new Node.EmptyStatement()); + }; + // https://tc39.github.io/ecma262/#sec-expression-statement + Parser.prototype.parseExpressionStatement = function () { + var node = this.createNode(); + var expr = this.parseExpression(); + this.consumeSemicolon(); + return this.finalize(node, new Node.ExpressionStatement(expr)); + }; + // https://tc39.github.io/ecma262/#sec-if-statement + Parser.prototype.parseIfClause = function () { + if (this.context.strict && this.matchKeyword('function')) { + this.tolerateError(messages_1.Messages.StrictFunction); + } + return this.parseStatement(); + }; + Parser.prototype.parseIfStatement = function () { + var node = this.createNode(); + var consequent; + var alternate = null; + this.expectKeyword('if'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + consequent = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + consequent = this.parseIfClause(); + if (this.matchKeyword('else')) { + this.nextToken(); + alternate = this.parseIfClause(); + } + } + return this.finalize(node, new Node.IfStatement(test, consequent, alternate)); + }; + // https://tc39.github.io/ecma262/#sec-do-while-statement + Parser.prototype.parseDoWhileStatement = function () { + var node = this.createNode(); + this.expectKeyword('do'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + var body = this.parseStatement(); + this.context.inIteration = previousInIteration; + this.expectKeyword('while'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + } + else { + this.expect(')'); + if (this.match(';')) { + this.nextToken(); + } + } + return this.finalize(node, new Node.DoWhileStatement(body, test)); + }; + // https://tc39.github.io/ecma262/#sec-while-statement + Parser.prototype.parseWhileStatement = function () { + var node = this.createNode(); + var body; + this.expectKeyword('while'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + body = this.parseStatement(); + this.context.inIteration = previousInIteration; + } + return this.finalize(node, new Node.WhileStatement(test, body)); + }; + // https://tc39.github.io/ecma262/#sec-for-statement + // https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements + Parser.prototype.parseForStatement = function () { + var init = null; + var test = null; + var update = null; + var forIn = true; + var left, right; + var node = this.createNode(); + this.expectKeyword('for'); + this.expect('('); + if (this.match(';')) { + this.nextToken(); + } + else { + if (this.matchKeyword('var')) { + init = this.createNode(); + this.nextToken(); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + var declarations = this.parseVariableDeclarationList({ inFor: true }); + this.context.allowIn = previousAllowIn; + if (declarations.length === 1 && this.matchKeyword('in')) { + var decl = declarations[0]; + if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) { + this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in'); + } + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.nextToken(); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.expect(';'); + } + } + else if (this.matchKeyword('const') || this.matchKeyword('let')) { + init = this.createNode(); + var kind = this.nextToken().value; + if (!this.context.strict && this.lookahead.value === 'in') { + init = this.finalize(init, new Node.Identifier(kind)); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else { + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + var declarations = this.parseBindingList(kind, { inFor: true }); + this.context.allowIn = previousAllowIn; + if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + this.nextToken(); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + this.consumeSemicolon(); + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + } + } + } + else { + var initStartToken = this.lookahead; + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + init = this.inheritCoverGrammar(this.parseAssignmentExpression); + this.context.allowIn = previousAllowIn; + if (this.matchKeyword('in')) { + if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { + this.tolerateError(messages_1.Messages.InvalidLHSInForIn); + } + this.nextToken(); + this.reinterpretExpressionAsPattern(init); + left = init; + right = this.parseExpression(); + init = null; + } + else if (this.matchContextualKeyword('of')) { + if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { + this.tolerateError(messages_1.Messages.InvalidLHSInForLoop); + } + this.nextToken(); + this.reinterpretExpressionAsPattern(init); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + if (this.match(',')) { + var initSeq = [init]; + while (this.match(',')) { + this.nextToken(); + initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); + } + init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq)); + } + this.expect(';'); + } + } + } + if (typeof left === 'undefined') { + if (!this.match(';')) { + test = this.parseExpression(); + } + this.expect(';'); + if (!this.match(')')) { + update = this.parseExpression(); + } + } + var body; + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + body = this.isolateCoverGrammar(this.parseStatement); + this.context.inIteration = previousInIteration; + } + return (typeof left === 'undefined') ? + this.finalize(node, new Node.ForStatement(init, test, update, body)) : + forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) : + this.finalize(node, new Node.ForOfStatement(left, right, body)); + }; + // https://tc39.github.io/ecma262/#sec-continue-statement + Parser.prototype.parseContinueStatement = function () { + var node = this.createNode(); + this.expectKeyword('continue'); + var label = null; + if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { + var id = this.parseVariableIdentifier(); + label = id; + var key = '$' + id.name; + if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.UnknownLabel, id.name); + } + } + this.consumeSemicolon(); + if (label === null && !this.context.inIteration) { + this.throwError(messages_1.Messages.IllegalContinue); + } + return this.finalize(node, new Node.ContinueStatement(label)); + }; + // https://tc39.github.io/ecma262/#sec-break-statement + Parser.prototype.parseBreakStatement = function () { + var node = this.createNode(); + this.expectKeyword('break'); + var label = null; + if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { + var id = this.parseVariableIdentifier(); + var key = '$' + id.name; + if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.UnknownLabel, id.name); + } + label = id; + } + this.consumeSemicolon(); + if (label === null && !this.context.inIteration && !this.context.inSwitch) { + this.throwError(messages_1.Messages.IllegalBreak); + } + return this.finalize(node, new Node.BreakStatement(label)); + }; + // https://tc39.github.io/ecma262/#sec-return-statement + Parser.prototype.parseReturnStatement = function () { + if (!this.context.inFunctionBody) { + this.tolerateError(messages_1.Messages.IllegalReturn); + } + var node = this.createNode(); + this.expectKeyword('return'); + var hasArgument = (!this.match(';') && !this.match('}') && + !this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */) || + this.lookahead.type === 8 /* StringLiteral */ || + this.lookahead.type === 10 /* Template */; + var argument = hasArgument ? this.parseExpression() : null; + this.consumeSemicolon(); + return this.finalize(node, new Node.ReturnStatement(argument)); + }; + // https://tc39.github.io/ecma262/#sec-with-statement + Parser.prototype.parseWithStatement = function () { + if (this.context.strict) { + this.tolerateError(messages_1.Messages.StrictModeWith); + } + var node = this.createNode(); + var body; + this.expectKeyword('with'); + this.expect('('); + var object = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + body = this.parseStatement(); + } + return this.finalize(node, new Node.WithStatement(object, body)); + }; + // https://tc39.github.io/ecma262/#sec-switch-statement + Parser.prototype.parseSwitchCase = function () { + var node = this.createNode(); + var test; + if (this.matchKeyword('default')) { + this.nextToken(); + test = null; + } + else { + this.expectKeyword('case'); + test = this.parseExpression(); + } + this.expect(':'); + var consequent = []; + while (true) { + if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) { + break; + } + consequent.push(this.parseStatementListItem()); + } + return this.finalize(node, new Node.SwitchCase(test, consequent)); + }; + Parser.prototype.parseSwitchStatement = function () { + var node = this.createNode(); + this.expectKeyword('switch'); + this.expect('('); + var discriminant = this.parseExpression(); + this.expect(')'); + var previousInSwitch = this.context.inSwitch; + this.context.inSwitch = true; + var cases = []; + var defaultFound = false; + this.expect('{'); + while (true) { + if (this.match('}')) { + break; + } + var clause = this.parseSwitchCase(); + if (clause.test === null) { + if (defaultFound) { + this.throwError(messages_1.Messages.MultipleDefaultsInSwitch); + } + defaultFound = true; + } + cases.push(clause); + } + this.expect('}'); + this.context.inSwitch = previousInSwitch; + return this.finalize(node, new Node.SwitchStatement(discriminant, cases)); + }; + // https://tc39.github.io/ecma262/#sec-labelled-statements + Parser.prototype.parseLabelledStatement = function () { + var node = this.createNode(); + var expr = this.parseExpression(); + var statement; + if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) { + this.nextToken(); + var id = expr; + var key = '$' + id.name; + if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name); + } + this.context.labelSet[key] = true; + var body = void 0; + if (this.matchKeyword('class')) { + this.tolerateUnexpectedToken(this.lookahead); + body = this.parseClassDeclaration(); + } + else if (this.matchKeyword('function')) { + var token = this.lookahead; + var declaration = this.parseFunctionDeclaration(); + if (this.context.strict) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunction); + } + else if (declaration.generator) { + this.tolerateUnexpectedToken(token, messages_1.Messages.GeneratorInLegacyContext); + } + body = declaration; + } + else { + body = this.parseStatement(); + } + delete this.context.labelSet[key]; + statement = new Node.LabeledStatement(id, body); + } + else { + this.consumeSemicolon(); + statement = new Node.ExpressionStatement(expr); + } + return this.finalize(node, statement); + }; + // https://tc39.github.io/ecma262/#sec-throw-statement + Parser.prototype.parseThrowStatement = function () { + var node = this.createNode(); + this.expectKeyword('throw'); + if (this.hasLineTerminator) { + this.throwError(messages_1.Messages.NewlineAfterThrow); + } + var argument = this.parseExpression(); + this.consumeSemicolon(); + return this.finalize(node, new Node.ThrowStatement(argument)); + }; + // https://tc39.github.io/ecma262/#sec-try-statement + Parser.prototype.parseCatchClause = function () { + var node = this.createNode(); + this.expectKeyword('catch'); + this.expect('('); + if (this.match(')')) { + this.throwUnexpectedToken(this.lookahead); + } + var params = []; + var param = this.parsePattern(params); + var paramMap = {}; + for (var i = 0; i < params.length; i++) { + var key = '$' + params[i].value; + if (Object.prototype.hasOwnProperty.call(paramMap, key)) { + this.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value); + } + paramMap[key] = true; + } + if (this.context.strict && param.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord(param.name)) { + this.tolerateError(messages_1.Messages.StrictCatchVariable); + } + } + this.expect(')'); + var body = this.parseBlock(); + return this.finalize(node, new Node.CatchClause(param, body)); + }; + Parser.prototype.parseFinallyClause = function () { + this.expectKeyword('finally'); + return this.parseBlock(); + }; + Parser.prototype.parseTryStatement = function () { + var node = this.createNode(); + this.expectKeyword('try'); + var block = this.parseBlock(); + var handler = this.matchKeyword('catch') ? this.parseCatchClause() : null; + var finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null; + if (!handler && !finalizer) { + this.throwError(messages_1.Messages.NoCatchOrFinally); + } + return this.finalize(node, new Node.TryStatement(block, handler, finalizer)); + }; + // https://tc39.github.io/ecma262/#sec-debugger-statement + Parser.prototype.parseDebuggerStatement = function () { + var node = this.createNode(); + this.expectKeyword('debugger'); + this.consumeSemicolon(); + return this.finalize(node, new Node.DebuggerStatement()); + }; + // https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations + Parser.prototype.parseStatement = function () { + var statement; + switch (this.lookahead.type) { + case 1 /* BooleanLiteral */: + case 5 /* NullLiteral */: + case 6 /* NumericLiteral */: + case 8 /* StringLiteral */: + case 10 /* Template */: + case 9 /* RegularExpression */: + statement = this.parseExpressionStatement(); + break; + case 7 /* Punctuator */: + var value = this.lookahead.value; + if (value === '{') { + statement = this.parseBlock(); + } + else if (value === '(') { + statement = this.parseExpressionStatement(); + } + else if (value === ';') { + statement = this.parseEmptyStatement(); + } + else { + statement = this.parseExpressionStatement(); + } + break; + case 3 /* Identifier */: + statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement(); + break; + case 4 /* Keyword */: + switch (this.lookahead.value) { + case 'break': + statement = this.parseBreakStatement(); + break; + case 'continue': + statement = this.parseContinueStatement(); + break; + case 'debugger': + statement = this.parseDebuggerStatement(); + break; + case 'do': + statement = this.parseDoWhileStatement(); + break; + case 'for': + statement = this.parseForStatement(); + break; + case 'function': + statement = this.parseFunctionDeclaration(); + break; + case 'if': + statement = this.parseIfStatement(); + break; + case 'return': + statement = this.parseReturnStatement(); + break; + case 'switch': + statement = this.parseSwitchStatement(); + break; + case 'throw': + statement = this.parseThrowStatement(); + break; + case 'try': + statement = this.parseTryStatement(); + break; + case 'var': + statement = this.parseVariableStatement(); + break; + case 'while': + statement = this.parseWhileStatement(); + break; + case 'with': + statement = this.parseWithStatement(); + break; + default: + statement = this.parseExpressionStatement(); + break; + } + break; + default: + statement = this.throwUnexpectedToken(this.lookahead); + } + return statement; + }; + // https://tc39.github.io/ecma262/#sec-function-definitions + Parser.prototype.parseFunctionSourceElements = function () { + var node = this.createNode(); + this.expect('{'); + var body = this.parseDirectivePrologues(); + var previousLabelSet = this.context.labelSet; + var previousInIteration = this.context.inIteration; + var previousInSwitch = this.context.inSwitch; + var previousInFunctionBody = this.context.inFunctionBody; + this.context.labelSet = {}; + this.context.inIteration = false; + this.context.inSwitch = false; + this.context.inFunctionBody = true; + while (this.lookahead.type !== 2 /* EOF */) { + if (this.match('}')) { + break; + } + body.push(this.parseStatementListItem()); + } + this.expect('}'); + this.context.labelSet = previousLabelSet; + this.context.inIteration = previousInIteration; + this.context.inSwitch = previousInSwitch; + this.context.inFunctionBody = previousInFunctionBody; + return this.finalize(node, new Node.BlockStatement(body)); + }; + Parser.prototype.validateParam = function (options, param, name) { + var key = '$' + name; + if (this.context.strict) { + if (this.scanner.isRestrictedWord(name)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamDupe; + } + } + else if (!options.firstRestricted) { + if (this.scanner.isRestrictedWord(name)) { + options.firstRestricted = param; + options.message = messages_1.Messages.StrictParamName; + } + else if (this.scanner.isStrictModeReservedWord(name)) { + options.firstRestricted = param; + options.message = messages_1.Messages.StrictReservedWord; + } + else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamDupe; + } + } + /* istanbul ignore next */ + if (typeof Object.defineProperty === 'function') { + Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true }); + } + else { + options.paramSet[key] = true; + } + }; + Parser.prototype.parseRestElement = function (params) { + var node = this.createNode(); + this.expect('...'); + var arg = this.parsePattern(params); + if (this.match('=')) { + this.throwError(messages_1.Messages.DefaultRestParameter); + } + if (!this.match(')')) { + this.throwError(messages_1.Messages.ParameterAfterRestParameter); + } + return this.finalize(node, new Node.RestElement(arg)); + }; + Parser.prototype.parseFormalParameter = function (options) { + var params = []; + var param = this.match('...') ? this.parseRestElement(params) : this.parsePatternWithDefault(params); + for (var i = 0; i < params.length; i++) { + this.validateParam(options, params[i], params[i].value); + } + options.simple = options.simple && (param instanceof Node.Identifier); + options.params.push(param); + }; + Parser.prototype.parseFormalParameters = function (firstRestricted) { + var options; + options = { + simple: true, + params: [], + firstRestricted: firstRestricted + }; + this.expect('('); + if (!this.match(')')) { + options.paramSet = {}; + while (this.lookahead.type !== 2 /* EOF */) { + this.parseFormalParameter(options); + if (this.match(')')) { + break; + } + this.expect(','); + if (this.match(')')) { + break; + } + } + } + this.expect(')'); + return { + simple: options.simple, + params: options.params, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + }; + Parser.prototype.matchAsyncFunction = function () { + var match = this.matchContextualKeyword('async'); + if (match) { + var state = this.scanner.saveState(); + this.scanner.scanComments(); + var next = this.scanner.lex(); + this.scanner.restoreState(state); + match = (state.lineNumber === next.lineNumber) && (next.type === 4 /* Keyword */) && (next.value === 'function'); + } + return match; + }; + Parser.prototype.parseFunctionDeclaration = function (identifierIsOptional) { + var node = this.createNode(); + var isAsync = this.matchContextualKeyword('async'); + if (isAsync) { + this.nextToken(); + } + this.expectKeyword('function'); + var isGenerator = isAsync ? false : this.match('*'); + if (isGenerator) { + this.nextToken(); + } + var message; + var id = null; + var firstRestricted = null; + if (!identifierIsOptional || !this.match('(')) { + var token = this.lookahead; + id = this.parseVariableIdentifier(); + if (this.context.strict) { + if (this.scanner.isRestrictedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); + } + } + else { + if (this.scanner.isRestrictedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictFunctionName; + } + else if (this.scanner.isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictReservedWord; + } + } + } + var previousAllowAwait = this.context.await; + var previousAllowYield = this.context.allowYield; + this.context.await = isAsync; + this.context.allowYield = !isGenerator; + var formalParameters = this.parseFormalParameters(firstRestricted); + var params = formalParameters.params; + var stricted = formalParameters.stricted; + firstRestricted = formalParameters.firstRestricted; + if (formalParameters.message) { + message = formalParameters.message; + } + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = formalParameters.simple; + var body = this.parseFunctionSourceElements(); + if (this.context.strict && firstRestricted) { + this.throwUnexpectedToken(firstRestricted, message); + } + if (this.context.strict && stricted) { + this.tolerateUnexpectedToken(stricted, message); + } + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + this.context.await = previousAllowAwait; + this.context.allowYield = previousAllowYield; + return isAsync ? this.finalize(node, new Node.AsyncFunctionDeclaration(id, params, body)) : + this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator)); + }; + Parser.prototype.parseFunctionExpression = function () { + var node = this.createNode(); + var isAsync = this.matchContextualKeyword('async'); + if (isAsync) { + this.nextToken(); + } + this.expectKeyword('function'); + var isGenerator = isAsync ? false : this.match('*'); + if (isGenerator) { + this.nextToken(); + } + var message; + var id = null; + var firstRestricted; + var previousAllowAwait = this.context.await; + var previousAllowYield = this.context.allowYield; + this.context.await = isAsync; + this.context.allowYield = !isGenerator; + if (!this.match('(')) { + var token = this.lookahead; + id = (!this.context.strict && !isGenerator && this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier(); + if (this.context.strict) { + if (this.scanner.isRestrictedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); + } + } + else { + if (this.scanner.isRestrictedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictFunctionName; + } + else if (this.scanner.isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictReservedWord; + } + } + } + var formalParameters = this.parseFormalParameters(firstRestricted); + var params = formalParameters.params; + var stricted = formalParameters.stricted; + firstRestricted = formalParameters.firstRestricted; + if (formalParameters.message) { + message = formalParameters.message; + } + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = formalParameters.simple; + var body = this.parseFunctionSourceElements(); + if (this.context.strict && firstRestricted) { + this.throwUnexpectedToken(firstRestricted, message); + } + if (this.context.strict && stricted) { + this.tolerateUnexpectedToken(stricted, message); + } + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + this.context.await = previousAllowAwait; + this.context.allowYield = previousAllowYield; + return isAsync ? this.finalize(node, new Node.AsyncFunctionExpression(id, params, body)) : + this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator)); + }; + // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive + Parser.prototype.parseDirective = function () { + var token = this.lookahead; + var node = this.createNode(); + var expr = this.parseExpression(); + var directive = (expr.type === syntax_1.Syntax.Literal) ? this.getTokenRaw(token).slice(1, -1) : null; + this.consumeSemicolon(); + return this.finalize(node, directive ? new Node.Directive(expr, directive) : new Node.ExpressionStatement(expr)); + }; + Parser.prototype.parseDirectivePrologues = function () { + var firstRestricted = null; + var body = []; + while (true) { + var token = this.lookahead; + if (token.type !== 8 /* StringLiteral */) { + break; + } + var statement = this.parseDirective(); + body.push(statement); + var directive = statement.directive; + if (typeof directive !== 'string') { + break; + } + if (directive === 'use strict') { + this.context.strict = true; + if (firstRestricted) { + this.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral); + } + if (!this.context.allowStrictDirective) { + this.tolerateUnexpectedToken(token, messages_1.Messages.IllegalLanguageModeDirective); + } + } + else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + return body; + }; + // https://tc39.github.io/ecma262/#sec-method-definitions + Parser.prototype.qualifiedPropertyName = function (token) { + switch (token.type) { + case 3 /* Identifier */: + case 8 /* StringLiteral */: + case 1 /* BooleanLiteral */: + case 5 /* NullLiteral */: + case 6 /* NumericLiteral */: + case 4 /* Keyword */: + return true; + case 7 /* Punctuator */: + return token.value === '['; + } + return false; + }; + Parser.prototype.parseGetterMethod = function () { + var node = this.createNode(); + var isGenerator = false; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = !isGenerator; + var formalParameters = this.parseFormalParameters(); + if (formalParameters.params.length > 0) { + this.tolerateError(messages_1.Messages.BadGetterArity); + } + var method = this.parsePropertyMethod(formalParameters); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); + }; + Parser.prototype.parseSetterMethod = function () { + var node = this.createNode(); + var isGenerator = false; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = !isGenerator; + var formalParameters = this.parseFormalParameters(); + if (formalParameters.params.length !== 1) { + this.tolerateError(messages_1.Messages.BadSetterArity); + } + else if (formalParameters.params[0] instanceof Node.RestElement) { + this.tolerateError(messages_1.Messages.BadSetterRestParameter); + } + var method = this.parsePropertyMethod(formalParameters); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); + }; + Parser.prototype.parseGeneratorMethod = function () { + var node = this.createNode(); + var isGenerator = true; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var params = this.parseFormalParameters(); + this.context.allowYield = false; + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); + }; + // https://tc39.github.io/ecma262/#sec-generator-function-definitions + Parser.prototype.isStartOfExpression = function () { + var start = true; + var value = this.lookahead.value; + switch (this.lookahead.type) { + case 7 /* Punctuator */: + start = (value === '[') || (value === '(') || (value === '{') || + (value === '+') || (value === '-') || + (value === '!') || (value === '~') || + (value === '++') || (value === '--') || + (value === '/') || (value === '/='); // regular expression literal + break; + case 4 /* Keyword */: + start = (value === 'class') || (value === 'delete') || + (value === 'function') || (value === 'let') || (value === 'new') || + (value === 'super') || (value === 'this') || (value === 'typeof') || + (value === 'void') || (value === 'yield'); + break; + } + return start; + }; + Parser.prototype.parseYieldExpression = function () { + var node = this.createNode(); + this.expectKeyword('yield'); + var argument = null; + var delegate = false; + if (!this.hasLineTerminator) { + var previousAllowYield = this.context.allowYield; + this.context.allowYield = false; + delegate = this.match('*'); + if (delegate) { + this.nextToken(); + argument = this.parseAssignmentExpression(); + } + else if (this.isStartOfExpression()) { + argument = this.parseAssignmentExpression(); + } + this.context.allowYield = previousAllowYield; + } + return this.finalize(node, new Node.YieldExpression(argument, delegate)); + }; + // https://tc39.github.io/ecma262/#sec-class-definitions + Parser.prototype.parseClassElement = function (hasConstructor) { + var token = this.lookahead; + var node = this.createNode(); + var kind = ''; + var key = null; + var value = null; + var computed = false; + var method = false; + var isStatic = false; + var isAsync = false; + if (this.match('*')) { + this.nextToken(); + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + var id = key; + if (id.name === 'static' && (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) { + token = this.lookahead; + isStatic = true; + computed = this.match('['); + if (this.match('*')) { + this.nextToken(); + } + else { + key = this.parseObjectPropertyKey(); + } + } + if ((token.type === 3 /* Identifier */) && !this.hasLineTerminator && (token.value === 'async')) { + var punctuator = this.lookahead.value; + if (punctuator !== ':' && punctuator !== '(' && punctuator !== '*') { + isAsync = true; + token = this.lookahead; + key = this.parseObjectPropertyKey(); + if (token.type === 3 /* Identifier */ && token.value === 'constructor') { + this.tolerateUnexpectedToken(token, messages_1.Messages.ConstructorIsAsync); + } + } + } + } + var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); + if (token.type === 3 /* Identifier */) { + if (token.value === 'get' && lookaheadPropertyKey) { + kind = 'get'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.context.allowYield = false; + value = this.parseGetterMethod(); + } + else if (token.value === 'set' && lookaheadPropertyKey) { + kind = 'set'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseSetterMethod(); + } + } + else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { + kind = 'init'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseGeneratorMethod(); + method = true; + } + if (!kind && key && this.match('(')) { + kind = 'init'; + value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); + method = true; + } + if (!kind) { + this.throwUnexpectedToken(this.lookahead); + } + if (kind === 'init') { + kind = 'method'; + } + if (!computed) { + if (isStatic && this.isPropertyKey(key, 'prototype')) { + this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype); + } + if (!isStatic && this.isPropertyKey(key, 'constructor')) { + if (kind !== 'method' || !method || (value && value.generator)) { + this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod); + } + if (hasConstructor.value) { + this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor); + } + else { + hasConstructor.value = true; + } + kind = 'constructor'; + } + } + return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic)); + }; + Parser.prototype.parseClassElementList = function () { + var body = []; + var hasConstructor = { value: false }; + this.expect('{'); + while (!this.match('}')) { + if (this.match(';')) { + this.nextToken(); + } + else { + body.push(this.parseClassElement(hasConstructor)); + } + } + this.expect('}'); + return body; + }; + Parser.prototype.parseClassBody = function () { + var node = this.createNode(); + var elementList = this.parseClassElementList(); + return this.finalize(node, new Node.ClassBody(elementList)); + }; + Parser.prototype.parseClassDeclaration = function (identifierIsOptional) { + var node = this.createNode(); + var previousStrict = this.context.strict; + this.context.strict = true; + this.expectKeyword('class'); + var id = (identifierIsOptional && (this.lookahead.type !== 3 /* Identifier */)) ? null : this.parseVariableIdentifier(); + var superClass = null; + if (this.matchKeyword('extends')) { + this.nextToken(); + superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + } + var classBody = this.parseClassBody(); + this.context.strict = previousStrict; + return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody)); + }; + Parser.prototype.parseClassExpression = function () { + var node = this.createNode(); + var previousStrict = this.context.strict; + this.context.strict = true; + this.expectKeyword('class'); + var id = (this.lookahead.type === 3 /* Identifier */) ? this.parseVariableIdentifier() : null; + var superClass = null; + if (this.matchKeyword('extends')) { + this.nextToken(); + superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + } + var classBody = this.parseClassBody(); + this.context.strict = previousStrict; + return this.finalize(node, new Node.ClassExpression(id, superClass, classBody)); + }; + // https://tc39.github.io/ecma262/#sec-scripts + // https://tc39.github.io/ecma262/#sec-modules + Parser.prototype.parseModule = function () { + this.context.strict = true; + this.context.isModule = true; + this.scanner.isModule = true; + var node = this.createNode(); + var body = this.parseDirectivePrologues(); + while (this.lookahead.type !== 2 /* EOF */) { + body.push(this.parseStatementListItem()); + } + return this.finalize(node, new Node.Module(body)); + }; + Parser.prototype.parseScript = function () { + var node = this.createNode(); + var body = this.parseDirectivePrologues(); + while (this.lookahead.type !== 2 /* EOF */) { + body.push(this.parseStatementListItem()); + } + return this.finalize(node, new Node.Script(body)); + }; + // https://tc39.github.io/ecma262/#sec-imports + Parser.prototype.parseModuleSpecifier = function () { + var node = this.createNode(); + if (this.lookahead.type !== 8 /* StringLiteral */) { + this.throwError(messages_1.Messages.InvalidModuleSpecifier); + } + var token = this.nextToken(); + var raw = this.getTokenRaw(token); + return this.finalize(node, new Node.Literal(token.value, raw)); + }; + // import {} ...; + Parser.prototype.parseImportSpecifier = function () { + var node = this.createNode(); + var imported; + var local; + if (this.lookahead.type === 3 /* Identifier */) { + imported = this.parseVariableIdentifier(); + local = imported; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + local = this.parseVariableIdentifier(); + } + } + else { + imported = this.parseIdentifierName(); + local = imported; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + local = this.parseVariableIdentifier(); + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + } + return this.finalize(node, new Node.ImportSpecifier(local, imported)); + }; + // {foo, bar as bas} + Parser.prototype.parseNamedImports = function () { + this.expect('{'); + var specifiers = []; + while (!this.match('}')) { + specifiers.push(this.parseImportSpecifier()); + if (!this.match('}')) { + this.expect(','); + } + } + this.expect('}'); + return specifiers; + }; + // import ...; + Parser.prototype.parseImportDefaultSpecifier = function () { + var node = this.createNode(); + var local = this.parseIdentifierName(); + return this.finalize(node, new Node.ImportDefaultSpecifier(local)); + }; + // import <* as foo> ...; + Parser.prototype.parseImportNamespaceSpecifier = function () { + var node = this.createNode(); + this.expect('*'); + if (!this.matchContextualKeyword('as')) { + this.throwError(messages_1.Messages.NoAsAfterImportNamespace); + } + this.nextToken(); + var local = this.parseIdentifierName(); + return this.finalize(node, new Node.ImportNamespaceSpecifier(local)); + }; + Parser.prototype.parseImportDeclaration = function () { + if (this.context.inFunctionBody) { + this.throwError(messages_1.Messages.IllegalImportDeclaration); + } + var node = this.createNode(); + this.expectKeyword('import'); + var src; + var specifiers = []; + if (this.lookahead.type === 8 /* StringLiteral */) { + // import 'foo'; + src = this.parseModuleSpecifier(); + } + else { + if (this.match('{')) { + // import {bar} + specifiers = specifiers.concat(this.parseNamedImports()); + } + else if (this.match('*')) { + // import * as foo + specifiers.push(this.parseImportNamespaceSpecifier()); + } + else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword('default')) { + // import foo + specifiers.push(this.parseImportDefaultSpecifier()); + if (this.match(',')) { + this.nextToken(); + if (this.match('*')) { + // import foo, * as foo + specifiers.push(this.parseImportNamespaceSpecifier()); + } + else if (this.match('{')) { + // import foo, {bar} + specifiers = specifiers.concat(this.parseNamedImports()); + } + else { + this.throwUnexpectedToken(this.lookahead); + } + } + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + if (!this.matchContextualKeyword('from')) { + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + this.nextToken(); + src = this.parseModuleSpecifier(); + } + this.consumeSemicolon(); + return this.finalize(node, new Node.ImportDeclaration(specifiers, src)); + }; + // https://tc39.github.io/ecma262/#sec-exports + Parser.prototype.parseExportSpecifier = function () { + var node = this.createNode(); + var local = this.parseIdentifierName(); + var exported = local; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + exported = this.parseIdentifierName(); + } + return this.finalize(node, new Node.ExportSpecifier(local, exported)); + }; + Parser.prototype.parseExportDeclaration = function () { + if (this.context.inFunctionBody) { + this.throwError(messages_1.Messages.IllegalExportDeclaration); + } + var node = this.createNode(); + this.expectKeyword('export'); + var exportDeclaration; + if (this.matchKeyword('default')) { + // export default ... + this.nextToken(); + if (this.matchKeyword('function')) { + // export default function foo () {} + // export default function () {} + var declaration = this.parseFunctionDeclaration(true); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else if (this.matchKeyword('class')) { + // export default class foo {} + var declaration = this.parseClassDeclaration(true); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else if (this.matchContextualKeyword('async')) { + // export default async function f () {} + // export default async function () {} + // export default async x => x + var declaration = this.matchAsyncFunction() ? this.parseFunctionDeclaration(true) : this.parseAssignmentExpression(); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else { + if (this.matchContextualKeyword('from')) { + this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value); + } + // export default {}; + // export default []; + // export default (1 + 2); + var declaration = this.match('{') ? this.parseObjectInitializer() : + this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression(); + this.consumeSemicolon(); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + } + else if (this.match('*')) { + // export * from 'foo'; + this.nextToken(); + if (!this.matchContextualKeyword('from')) { + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + this.nextToken(); + var src = this.parseModuleSpecifier(); + this.consumeSemicolon(); + exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src)); + } + else if (this.lookahead.type === 4 /* Keyword */) { + // export var f = 1; + var declaration = void 0; + switch (this.lookahead.value) { + case 'let': + case 'const': + declaration = this.parseLexicalDeclaration({ inFor: false }); + break; + case 'var': + case 'class': + case 'function': + declaration = this.parseStatementListItem(); + break; + default: + this.throwUnexpectedToken(this.lookahead); + } + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); + } + else if (this.matchAsyncFunction()) { + var declaration = this.parseFunctionDeclaration(); + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); + } + else { + var specifiers = []; + var source = null; + var isExportFromIdentifier = false; + this.expect('{'); + while (!this.match('}')) { + isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword('default'); + specifiers.push(this.parseExportSpecifier()); + if (!this.match('}')) { + this.expect(','); + } + } + this.expect('}'); + if (this.matchContextualKeyword('from')) { + // export {default} from 'foo'; + // export {foo} from 'foo'; + this.nextToken(); + source = this.parseModuleSpecifier(); + this.consumeSemicolon(); + } + else if (isExportFromIdentifier) { + // export {default}; // missing fromClause + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + else { + // export {foo}; + this.consumeSemicolon(); + } + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source)); + } + return exportDeclaration; + }; + return Parser; + }()); + exports.Parser = Parser; + + + /***/ }, + /* 9 */ + /***/ function(module, exports) { + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + Object.defineProperty(exports, "__esModule", { value: true }); + function assert(condition, message) { + /* istanbul ignore if */ + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + exports.assert = assert; + + + /***/ }, + /* 10 */ + /***/ function(module, exports) { + /* tslint:disable:max-classes-per-file */ + Object.defineProperty(exports, "__esModule", { value: true }); + var ErrorHandler = (function () { + function ErrorHandler() { + this.errors = []; + this.tolerant = false; + } + ErrorHandler.prototype.recordError = function (error) { + this.errors.push(error); + }; + ErrorHandler.prototype.tolerate = function (error) { + if (this.tolerant) { + this.recordError(error); + } + else { + throw error; + } + }; + ErrorHandler.prototype.constructError = function (msg, column) { + var error = new Error(msg); + try { + throw error; + } + catch (base) { + /* istanbul ignore else */ + if (Object.create && Object.defineProperty) { + error = Object.create(base); + Object.defineProperty(error, 'column', { value: column }); + } + } + /* istanbul ignore next */ + return error; + }; + ErrorHandler.prototype.createError = function (index, line, col, description) { + var msg = 'Line ' + line + ': ' + description; + var error = this.constructError(msg, col); + error.index = index; + error.lineNumber = line; + error.description = description; + return error; + }; + ErrorHandler.prototype.throwError = function (index, line, col, description) { + throw this.createError(index, line, col, description); + }; + ErrorHandler.prototype.tolerateError = function (index, line, col, description) { + var error = this.createError(index, line, col, description); + if (this.tolerant) { + this.recordError(error); + } + else { + throw error; + } + }; + return ErrorHandler; + }()); + exports.ErrorHandler = ErrorHandler; + + + /***/ }, + /* 11 */ + /***/ function(module, exports) { + Object.defineProperty(exports, "__esModule", { value: true }); + // Error messages should be identical to V8. + exports.Messages = { + BadGetterArity: 'Getter must not have any formal parameters', + BadSetterArity: 'Setter must have exactly one formal parameter', + BadSetterRestParameter: 'Setter function argument must not be a rest parameter', + ConstructorIsAsync: 'Class constructor may not be an async method', + ConstructorSpecialMethod: 'Class constructor may not be an accessor', + DeclarationMissingInitializer: 'Missing initializer in %0 declaration', + DefaultRestParameter: 'Unexpected token =', + DuplicateBinding: 'Duplicate binding %0', + DuplicateConstructor: 'A class may only have one constructor', + DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals', + ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer', + GeneratorInLegacyContext: 'Generator declarations are not allowed in legacy contexts', + IllegalBreak: 'Illegal break statement', + IllegalContinue: 'Illegal continue statement', + IllegalExportDeclaration: 'Unexpected token', + IllegalImportDeclaration: 'Unexpected token', + IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list', + IllegalReturn: 'Illegal return statement', + InvalidEscapedReservedWord: 'Keyword must not contain escaped characters', + InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + InvalidLHSInForLoop: 'Invalid left-hand side in for-loop', + InvalidModuleSpecifier: 'Unexpected token', + InvalidRegExp: 'Invalid regular expression', + LetInLexicalBinding: 'let is disallowed as a lexically bound name', + MissingFromClause: 'Unexpected token', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NewlineAfterThrow: 'Illegal newline after throw', + NoAsAfterImportNamespace: 'Unexpected token', + NoCatchOrFinally: 'Missing catch or finally after try', + ParameterAfterRestParameter: 'Rest parameter must be last formal parameter', + Redeclaration: '%0 \'%1\' has already been declared', + StaticPrototype: 'Classes may not have static property named prototype', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictFunction: 'In strict mode code, functions can only be declared at top level or inside a block', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + TemplateOctalLiteral: 'Octal literals are not allowed in template strings.', + UnexpectedEOS: 'Unexpected end of input', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedNumber: 'Unexpected number', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedString: 'Unexpected string', + UnexpectedTemplate: 'Unexpected quasi %0', + UnexpectedToken: 'Unexpected token %0', + UnexpectedTokenIllegal: 'Unexpected token ILLEGAL', + UnknownLabel: 'Undefined label \'%0\'', + UnterminatedRegExp: 'Invalid regular expression: missing /' + }; + + + /***/ }, + /* 12 */ + /***/ function(module, exports, __webpack_require__) { + Object.defineProperty(exports, "__esModule", { value: true }); + var assert_1 = __webpack_require__(9); + var character_1 = __webpack_require__(4); + var messages_1 = __webpack_require__(11); + function hexValue(ch) { + return '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + function octalValue(ch) { + return '01234567'.indexOf(ch); + } + var Scanner = (function () { + function Scanner(code, handler) { + this.source = code; + this.errorHandler = handler; + this.trackComment = false; + this.isModule = false; + this.length = code.length; + this.index = 0; + this.lineNumber = (code.length > 0) ? 1 : 0; + this.lineStart = 0; + this.curlyStack = []; + } + Scanner.prototype.saveState = function () { + return { + index: this.index, + lineNumber: this.lineNumber, + lineStart: this.lineStart + }; + }; + Scanner.prototype.restoreState = function (state) { + this.index = state.index; + this.lineNumber = state.lineNumber; + this.lineStart = state.lineStart; + }; + Scanner.prototype.eof = function () { + return this.index >= this.length; + }; + Scanner.prototype.throwUnexpectedToken = function (message) { + if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } + return this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); + }; + Scanner.prototype.tolerateUnexpectedToken = function (message) { + if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } + this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); + }; + // https://tc39.github.io/ecma262/#sec-comments + Scanner.prototype.skipSingleLineComment = function (offset) { + var comments = []; + var start, loc; + if (this.trackComment) { + comments = []; + start = this.index - offset; + loc = { + start: { + line: this.lineNumber, + column: this.index - this.lineStart - offset + }, + end: {} + }; + } + while (!this.eof()) { + var ch = this.source.charCodeAt(this.index); + ++this.index; + if (character_1.Character.isLineTerminator(ch)) { + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart - 1 + }; + var entry = { + multiLine: false, + slice: [start + offset, this.index - 1], + range: [start, this.index - 1], + loc: loc + }; + comments.push(entry); + } + if (ch === 13 && this.source.charCodeAt(this.index) === 10) { + ++this.index; + } + ++this.lineNumber; + this.lineStart = this.index; + return comments; + } + } + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: false, + slice: [start + offset, this.index], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + return comments; + }; + Scanner.prototype.skipMultiLineComment = function () { + var comments = []; + var start, loc; + if (this.trackComment) { + comments = []; + start = this.index - 2; + loc = { + start: { + line: this.lineNumber, + column: this.index - this.lineStart - 2 + }, + end: {} + }; + } + while (!this.eof()) { + var ch = this.source.charCodeAt(this.index); + if (character_1.Character.isLineTerminator(ch)) { + if (ch === 0x0D && this.source.charCodeAt(this.index + 1) === 0x0A) { + ++this.index; + } + ++this.lineNumber; + ++this.index; + this.lineStart = this.index; + } + else if (ch === 0x2A) { + // Block comment ends with '*/'. + if (this.source.charCodeAt(this.index + 1) === 0x2F) { + this.index += 2; + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: true, + slice: [start + 2, this.index - 2], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + return comments; + } + ++this.index; + } + else { + ++this.index; + } + } + // Ran off the end of the file - the whole thing is a comment + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: true, + slice: [start + 2, this.index], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + this.tolerateUnexpectedToken(); + return comments; + }; + Scanner.prototype.scanComments = function () { + var comments; + if (this.trackComment) { + comments = []; + } + var start = (this.index === 0); + while (!this.eof()) { + var ch = this.source.charCodeAt(this.index); + if (character_1.Character.isWhiteSpace(ch)) { + ++this.index; + } + else if (character_1.Character.isLineTerminator(ch)) { + ++this.index; + if (ch === 0x0D && this.source.charCodeAt(this.index) === 0x0A) { + ++this.index; + } + ++this.lineNumber; + this.lineStart = this.index; + start = true; + } + else if (ch === 0x2F) { + ch = this.source.charCodeAt(this.index + 1); + if (ch === 0x2F) { + this.index += 2; + var comment = this.skipSingleLineComment(2); + if (this.trackComment) { + comments = comments.concat(comment); + } + start = true; + } + else if (ch === 0x2A) { + this.index += 2; + var comment = this.skipMultiLineComment(); + if (this.trackComment) { + comments = comments.concat(comment); + } + } + else { + break; + } + } + else if (start && ch === 0x2D) { + // U+003E is '>' + if ((this.source.charCodeAt(this.index + 1) === 0x2D) && (this.source.charCodeAt(this.index + 2) === 0x3E)) { + // '-->' is a single-line comment + this.index += 3; + var comment = this.skipSingleLineComment(3); + if (this.trackComment) { + comments = comments.concat(comment); + } + } + else { + break; + } + } + else if (ch === 0x3C && !this.isModule) { + if (this.source.slice(this.index + 1, this.index + 4) === '!--') { + this.index += 4; // `|!>)", + exec : "|!>)", + include : "(.*)|!>)", + 'include-static' : "(.*)|!>)", + exclude : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + }, + extend : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + }, + extendable : "|!>)", + if : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + }, + else : "[ \t]*|!>)(?:[ \t]*\n)?", + foreach : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + } + }, + js : { + echo : [ + "/\\*[ \t]*#echo[ \t]+(.*?)[ \t]*\\*(?:\\*|/)", + "//[ \t]*#echo[ \t]+(.*?)[ \t]*$" + ], + exec : "(?://|/\\*)[ \t]*#exec[ \t]+(\\S+?)[ \t]*\\((.*)\\)[ \t]*(?:\\*(?:\\*|/))?", + include : [ + "^(.*)/\\*[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*\\*(?:\\*|/)", + "^(.*)//[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*$" + ], + 'include-static': [ + "^(.*)/\\*[ \t]*#include-static[ \t]+(.*?)[ \t]*\\*(?:\\*|/)", + "^(.*)//[ \t]*#include-static[ \t]+(.*?)[ \t]*$" + ], + exclude : { + start : "[ \t]*(?://|/\\*)[ \t]*#exclude(?:[ \t]+([^\n*]*))?[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endexclude[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + }, + extend : { + start : "[ \t]*(?://|/\\*)[ \t]*#extend(?!able)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endextend[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + }, + extendable : "[ \t]*(?://|/\\*)[ \t]*#extendable[ \t]*(?:\\*/)?", + if : { + start : "[ \t]*(?://|/\\*)[ \t]*#(ifndef|ifdef|if)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endif[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + }, + else : "[ \t]*(?://|/\\*)[ \t]*#else[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?", + foreach : { + start : "[ \t]*(?://|/\\*)[ \t]*#foreach[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endfor[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + } + }, + coffee : { + echo : [ + "###+[ \t]*#echo[ \t]+(.*?)[ \t]###", + "#+[ \t]*#echo[ \t]+(.*?)[ \t]*$" + ], + exec : "#+[ \t]*#exec[ \t]+(\\S+)[ \t]*\\((.*)\\)[ \t]*$", + include : "^(.*?)#+[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*$", + 'include-static' : "^(.*?)#+[ \t]*#include-static[ \t]+(.*?)[ \t]*$", + exclude : { + start : "^[ \t]*#+[ \t]*#exclude(?:[ \t]+(.*?))?[ \t]*\n+", + end : "^[ \t]*#+[ \t]*#endexclude[ \t]*\n?" + }, + extend : { + start : "^[ \t]*#+[ \t]*#extend(?!able)[ \t]+(.*?)\n+", + end : "^[ \t]*#+[ \t]*#endextend[ \t]*\n?" + }, + extendable : "^[ \t]*#+[ \t]*#extendable[ \t]*$", + if : { + start : "^[ \t]*#+[ \t]*#(ifndef|ifdef|if)[ \t]+(.*?)[ \t]*\n+", + end : "^[ \t]*#+[ \t]*#endif[ \t]*\n?" + }, + else : "^[ \t]*#+[ \t]*#else[ \t]*\n?", + foreach : { + start : "^[ \t]*#+[ \t]*#foreach[ \t]+(.*?)[ \t]*\n+", + end : "^[ \t]*#+[ \t]*#endfor[ \t]*\n?" + } + } + }; + + module.exports.xml = module.exports.html; + + module.exports.javascript = module.exports.js; + module.exports.jsx = module.exports.js; + module.exports.json = module.exports.js; + module.exports.c = module.exports.js; + module.exports.cc = module.exports.js; + module.exports.cpp = module.exports.js; + module.exports.cs = module.exports.js; + module.exports.csharp = module.exports.js; + module.exports.java = module.exports.js; + module.exports.less = module.exports.js; + module.exports.sass = module.exports.js; + module.exports.scss = module.exports.js; + module.exports.css = module.exports.js; + module.exports.php = module.exports.js; + module.exports.ts = module.exports.js; + module.exports.tsx = module.exports.js; + module.exports.peg = module.exports.js; + module.exports.pegjs = module.exports.js; + module.exports.jade = module.exports.js; + module.exports.styl = module.exports.js; + module.exports.go = module.exports.js; + + module.exports.bash = module.exports.coffee; + module.exports.shell = module.exports.coffee; + module.exports.sh = module.exports.coffee; +} (regexrules)); + +/*! + * XRegExp 3.1.0 + * + * Steven Levithan (c) 2007-2016 MIT License + */ + +/* ============================== + * Private stuff + * ============================== */ + + // Property name used for extended regex instance data + var REGEX_DATA = 'xregexp'; + // Optional features that can be installed and uninstalled + var features = { + astral: false, + natives: false + }; + // Native methods to use and restore ('native' is an ES3 reserved keyword) + var nativ = { + exec: RegExp.prototype.exec, + test: RegExp.prototype.test, + match: String.prototype.match, + replace: String.prototype.replace, + split: String.prototype.split + }; + // Storage for fixed/extended native methods + var fixed = {}; + // Storage for regexes cached by `XRegExp.cache` + var regexCache = {}; + // Storage for pattern details cached by the `XRegExp` constructor + var patternCache = {}; + // Storage for regex syntax tokens added internally or by `XRegExp.addToken` + var tokens = []; + // Token scopes + var defaultScope = 'default'; + var classScope = 'class'; + // Regexes that match native regex syntax, including octals + var nativeTokens = { + // Any native multicharacter token in default scope, or any single character + 'default': /\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??|[\s\S]/, + // Any native multicharacter token in character class scope, or any single character + 'class': /\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|[\s\S]/ + }; + // Any backreference or dollar-prefixed character in replacement strings + var replacementToken = /\$(?:{([\w$]+)}|(\d\d?|[\s\S]))/g; + // Check for correct `exec` handling of nonparticipating capturing groups + var correctExecNpcg = nativ.exec.call(/()??/, '')[1] === undefined; + // Check for ES6 `flags` prop support + var hasFlagsProp = /x/.flags !== undefined; + // Shortcut to `Object.prototype.toString` + var toString = {}.toString; + + function hasNativeFlag(flag) { + // Can't check based on the presense of properties/getters since + // browsers might support such properties even when don't support the + // corresponding flag in regex construction (tested in Chrome 48, where + // `'unicode' in /x/` is true but trying to construct a regex with flag + // `u` throws an error). + var isSupported = true; + try { + new RegExp('', flag); + } catch (exception) { + isSupported = false; + } + return isSupported; + } + // Check for ES6 `u` flag support + var hasNativeU = hasNativeFlag('u'); + // Check for ES6 `y` flag support + var hasNativeY = hasNativeFlag('y'); + // Tracker for known flags, including addon flags + var registeredFlags = { + g: true, + i: true, + m: true, + u: hasNativeU, + y: hasNativeY + }; + +/** + * Attaches extended data and `XRegExp.prototype` properties to a regex object. + * + * @private + * @param {RegExp} regex Regex to augment. + * @param {Array} captureNames Array with capture names, or `null`. + * @param {String} xSource XRegExp pattern used to generate `regex`, or `null` if N/A. + * @param {String} xFlags XRegExp flags used to generate `regex`, or `null` if N/A. + * @param {Boolean} [isInternalOnly=false] Whether the regex will be used only for internal + * operations, and never exposed to users. For internal-only regexes, we can improve perf by + * skipping some operations like attaching `XRegExp.prototype` properties. + * @returns {RegExp} Augmented regex. + */ + function augment(regex, captureNames, xSource, xFlags, isInternalOnly) { + var p; + + regex[REGEX_DATA] = { + captureNames: captureNames + }; + + if (isInternalOnly) { + return regex; + } + + // Can't auto-inherit these since the XRegExp constructor returns a nonprimitive value + if (regex.__proto__) { + regex.__proto__ = XRegExp$2.prototype; + } else { + for (p in XRegExp$2.prototype) { + // An `XRegExp.prototype.hasOwnProperty(p)` check wouldn't be worth it here, since + // this is performance sensitive, and enumerable `Object.prototype` or + // `RegExp.prototype` extensions exist on `regex.prototype` anyway + regex[p] = XRegExp$2.prototype[p]; + } + } + + regex[REGEX_DATA].source = xSource; + // Emulate the ES6 `flags` prop by ensuring flags are in alphabetical order + regex[REGEX_DATA].flags = xFlags ? xFlags.split('').sort().join('') : xFlags; + + return regex; + } + +/** + * Removes any duplicate characters from the provided string. + * + * @private + * @param {String} str String to remove duplicate characters from. + * @returns {String} String with any duplicate characters removed. + */ + function clipDuplicates(str) { + return nativ.replace.call(str, /([\s\S])(?=[\s\S]*\1)/g, ''); + } + +/** + * Copies a regex object while preserving extended data and augmenting with `XRegExp.prototype` + * properties. The copy has a fresh `lastIndex` property (set to zero). Allows adding and removing + * flags g and y while copying the regex. + * + * @private + * @param {RegExp} regex Regex to copy. + * @param {Object} [options] Options object with optional properties: + *
  • `addG` {Boolean} Add flag g while copying the regex. + *
  • `addY` {Boolean} Add flag y while copying the regex. + *
  • `removeG` {Boolean} Remove flag g while copying the regex. + *
  • `removeY` {Boolean} Remove flag y while copying the regex. + *
  • `isInternalOnly` {Boolean} Whether the copied regex will be used only for internal + * operations, and never exposed to users. For internal-only regexes, we can improve perf by + * skipping some operations like attaching `XRegExp.prototype` properties. + * @returns {RegExp} Copy of the provided regex, possibly with modified flags. + */ + function copyRegex(regex, options) { + if (!XRegExp$2.isRegExp(regex)) { + throw new TypeError('Type RegExp expected'); + } + + var xData = regex[REGEX_DATA] || {}, + flags = getNativeFlags(regex), + flagsToAdd = '', + flagsToRemove = '', + xregexpSource = null, + xregexpFlags = null; + + options = options || {}; + + if (options.removeG) {flagsToRemove += 'g';} + if (options.removeY) {flagsToRemove += 'y';} + if (flagsToRemove) { + flags = nativ.replace.call(flags, new RegExp('[' + flagsToRemove + ']+', 'g'), ''); + } + + if (options.addG) {flagsToAdd += 'g';} + if (options.addY) {flagsToAdd += 'y';} + if (flagsToAdd) { + flags = clipDuplicates(flags + flagsToAdd); + } + + if (!options.isInternalOnly) { + if (xData.source !== undefined) { + xregexpSource = xData.source; + } + // null or undefined; don't want to add to `flags` if the previous value was null, since + // that indicates we're not tracking original precompilation flags + if (xData.flags != null) { + // Flags are only added for non-internal regexes by `XRegExp.globalize`. Flags are + // never removed for non-internal regexes, so don't need to handle it + xregexpFlags = flagsToAdd ? clipDuplicates(xData.flags + flagsToAdd) : xData.flags; + } + } + + // Augment with `XRegExp.prototype` properties, but use the native `RegExp` constructor to + // avoid searching for special tokens. That would be wrong for regexes constructed by + // `RegExp`, and unnecessary for regexes constructed by `XRegExp` because the regex has + // already undergone the translation to native regex syntax + regex = augment( + new RegExp(regex.source, flags), + hasNamedCapture(regex) ? xData.captureNames.slice(0) : null, + xregexpSource, + xregexpFlags, + options.isInternalOnly + ); + + return regex; + } + +/** + * Converts hexadecimal to decimal. + * + * @private + * @param {String} hex + * @returns {Number} + */ + function dec(hex) { + return parseInt(hex, 16); + } + +/** + * Returns native `RegExp` flags used by a regex object. + * + * @private + * @param {RegExp} regex Regex to check. + * @returns {String} Native flags in use. + */ + function getNativeFlags(regex) { + return hasFlagsProp ? + regex.flags : + // Explicitly using `RegExp.prototype.toString` (rather than e.g. `String` or + // concatenation with an empty string) allows this to continue working predictably when + // `XRegExp.proptotype.toString` is overriden + nativ.exec.call(/\/([a-z]*)$/i, RegExp.prototype.toString.call(regex))[1]; + } + +/** + * Determines whether a regex has extended instance data used to track capture names. + * + * @private + * @param {RegExp} regex Regex to check. + * @returns {Boolean} Whether the regex uses named capture. + */ + function hasNamedCapture(regex) { + return !!(regex[REGEX_DATA] && regex[REGEX_DATA].captureNames); + } + +/** + * Converts decimal to hexadecimal. + * + * @private + * @param {Number|String} dec + * @returns {String} + */ + function hex(dec) { + return parseInt(dec, 10).toString(16); + } + +/** + * Returns the first index at which a given value can be found in an array. + * + * @private + * @param {Array} array Array to search. + * @param {*} value Value to locate in the array. + * @returns {Number} Zero-based index at which the item is found, or -1. + */ + function indexOf(array, value) { + var len = array.length, i; + + for (i = 0; i < len; ++i) { + if (array[i] === value) { + return i; + } + } + + return -1; + } + +/** + * Determines whether a value is of the specified type, by resolving its internal [[Class]]. + * + * @private + * @param {*} value Object to check. + * @param {String} type Type to check for, in TitleCase. + * @returns {Boolean} Whether the object matches the type. + */ + function isType(value, type) { + return toString.call(value) === '[object ' + type + ']'; + } + +/** + * Checks whether the next nonignorable token after the specified position is a quantifier. + * + * @private + * @param {String} pattern Pattern to search within. + * @param {Number} pos Index in `pattern` to search at. + * @param {String} flags Flags used by the pattern. + * @returns {Boolean} Whether the next token is a quantifier. + */ + function isQuantifierNext(pattern, pos, flags) { + return nativ.test.call( + flags.indexOf('x') > -1 ? + // Ignore any leading whitespace, line comments, and inline comments + /^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/ : + // Ignore any leading inline comments + /^(?:\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/, + pattern.slice(pos) + ); + } + +/** + * Pads the provided string with as many leading zeros as needed to get to length 4. Used to produce + * fixed-length hexadecimal values. + * + * @private + * @param {String} str + * @returns {String} + */ + function pad4(str) { + while (str.length < 4) { + str = '0' + str; + } + return str; + } + +/** + * Checks for flag-related errors, and strips/applies flags in a leading mode modifier. Offloads + * the flag preparation logic from the `XRegExp` constructor. + * + * @private + * @param {String} pattern Regex pattern, possibly with a leading mode modifier. + * @param {String} flags Any combination of flags. + * @returns {Object} Object with properties `pattern` and `flags`. + */ + function prepareFlags(pattern, flags) { + var i; + + // Recent browsers throw on duplicate flags, so copy this behavior for nonnative flags + if (clipDuplicates(flags) !== flags) { + throw new SyntaxError('Invalid duplicate regex flag ' + flags); + } + + // Strip and apply a leading mode modifier with any combination of flags except g or y + pattern = nativ.replace.call(pattern, /^\(\?([\w$]+)\)/, function($0, $1) { + if (nativ.test.call(/[gy]/, $1)) { + throw new SyntaxError('Cannot use flag g or y in mode modifier ' + $0); + } + // Allow duplicate flags within the mode modifier + flags = clipDuplicates(flags + $1); + return ''; + }); + + // Throw on unknown native or nonnative flags + for (i = 0; i < flags.length; ++i) { + if (!registeredFlags[flags.charAt(i)]) { + throw new SyntaxError('Unknown regex flag ' + flags.charAt(i)); + } + } + + return { + pattern: pattern, + flags: flags + }; + } + +/** + * Prepares an options object from the given value. + * + * @private + * @param {String|Object} value Value to convert to an options object. + * @returns {Object} Options object. + */ + function prepareOptions(value) { + var options = {}; + + if (isType(value, 'String')) { + XRegExp$2.forEach(value, /[^\s,]+/, function(match) { + options[match] = true; + }); + + return options; + } + + return value; + } + +/** + * Registers a flag so it doesn't throw an 'unknown flag' error. + * + * @private + * @param {String} flag Single-character flag to register. + */ + function registerFlag(flag) { + if (!/^[\w$]$/.test(flag)) { + throw new Error('Flag must be a single character A-Za-z0-9_$'); + } + + registeredFlags[flag] = true; + } + +/** + * Runs built-in and custom regex syntax tokens in reverse insertion order at the specified + * position, until a match is found. + * + * @private + * @param {String} pattern Original pattern from which an XRegExp object is being built. + * @param {String} flags Flags being used to construct the regex. + * @param {Number} pos Position to search for tokens within `pattern`. + * @param {Number} scope Regex scope to apply: 'default' or 'class'. + * @param {Object} context Context object to use for token handler functions. + * @returns {Object} Object with properties `matchLength`, `output`, and `reparse`; or `null`. + */ + function runTokens(pattern, flags, pos, scope, context) { + var i = tokens.length, + leadChar = pattern.charAt(pos), + result = null, + match, + t; + + // Run in reverse insertion order + while (i--) { + t = tokens[i]; + if ( + (t.leadChar && t.leadChar !== leadChar) || + (t.scope !== scope && t.scope !== 'all') || + (t.flag && flags.indexOf(t.flag) === -1) + ) { + continue; + } + + match = XRegExp$2.exec(pattern, t.regex, pos, 'sticky'); + if (match) { + result = { + matchLength: match[0].length, + output: t.handler.call(context, match, scope, flags), + reparse: t.reparse + }; + // Finished with token tests + break; + } + } + + return result; + } + +/** + * Enables or disables implicit astral mode opt-in. When enabled, flag A is automatically added to + * all new regexes created by XRegExp. This causes an error to be thrown when creating regexes if + * the Unicode Base addon is not available, since flag A is registered by that addon. + * + * @private + * @param {Boolean} on `true` to enable; `false` to disable. + */ + function setAstral(on) { + features.astral = on; + } + +/** + * Enables or disables native method overrides. + * + * @private + * @param {Boolean} on `true` to enable; `false` to disable. + */ + function setNatives(on) { + RegExp.prototype.exec = (on ? fixed : nativ).exec; + RegExp.prototype.test = (on ? fixed : nativ).test; + String.prototype.match = (on ? fixed : nativ).match; + String.prototype.replace = (on ? fixed : nativ).replace; + String.prototype.split = (on ? fixed : nativ).split; + + features.natives = on; + } + +/** + * Returns the object, or throws an error if it is `null` or `undefined`. This is used to follow + * the ES5 abstract operation `ToObject`. + * + * @private + * @param {*} value Object to check and return. + * @returns {*} The provided object. + */ + function toObject(value) { + // null or undefined + if (value == null) { + throw new TypeError('Cannot convert null or undefined to object'); + } + + return value; + } + +/* ============================== + * Constructor + * ============================== */ + +/** + * Creates an extended regular expression object for matching text with a pattern. Differs from a + * native regular expression in that additional syntax and flags are supported. The returned object + * is in fact a native `RegExp` and works with all native methods. + * + * @class XRegExp + * @constructor + * @param {String|RegExp} pattern Regex pattern string, or an existing regex object to copy. + * @param {String} [flags] Any combination of flags. + * Native flags: + *
  • `g` - global + *
  • `i` - ignore case + *
  • `m` - multiline anchors + *
  • `u` - unicode (ES6) + *
  • `y` - sticky (Firefox 3+, ES6) + * Additional XRegExp flags: + *
  • `n` - explicit capture + *
  • `s` - dot matches all (aka singleline) + *
  • `x` - free-spacing and line comments (aka extended) + *
  • `A` - astral (requires the Unicode Base addon) + * Flags cannot be provided when constructing one `RegExp` from another. + * @returns {RegExp} Extended regular expression object. + * @example + * + * // With named capture and flag x + * XRegExp('(? [0-9]{4} ) -? # year \n\ + * (? [0-9]{2} ) -? # month \n\ + * (? [0-9]{2} ) # day ', 'x'); + * + * // Providing a regex object copies it. Native regexes are recompiled using native (not XRegExp) + * // syntax. Copies maintain extended data, are augmented with `XRegExp.prototype` properties, and + * // have fresh `lastIndex` properties (set to zero). + * XRegExp(/regex/); + */ + function XRegExp$2(pattern, flags) { + var context = { + hasNamedCapture: false, + captureNames: [] + }, + scope = defaultScope, + output = '', + pos = 0, + result, + token, + generated, + appliedPattern, + appliedFlags; + + if (XRegExp$2.isRegExp(pattern)) { + if (flags !== undefined) { + throw new TypeError('Cannot supply flags when copying a RegExp'); + } + return copyRegex(pattern); + } + + // Copy the argument behavior of `RegExp` + pattern = pattern === undefined ? '' : String(pattern); + flags = flags === undefined ? '' : String(flags); + + if (XRegExp$2.isInstalled('astral') && flags.indexOf('A') === -1) { + // This causes an error to be thrown if the Unicode Base addon is not available + flags += 'A'; + } + + if (!patternCache[pattern]) { + patternCache[pattern] = {}; + } + + if (!patternCache[pattern][flags]) { + // Check for flag-related errors, and strip/apply flags in a leading mode modifier + result = prepareFlags(pattern, flags); + appliedPattern = result.pattern; + appliedFlags = result.flags; + + // Use XRegExp's tokens to translate the pattern to a native regex pattern. + // `appliedPattern.length` may change on each iteration if tokens use `reparse` + while (pos < appliedPattern.length) { + do { + // Check for custom tokens at the current position + result = runTokens(appliedPattern, appliedFlags, pos, scope, context); + // If the matched token used the `reparse` option, splice its output into the + // pattern before running tokens again at the same position + if (result && result.reparse) { + appliedPattern = appliedPattern.slice(0, pos) + + result.output + + appliedPattern.slice(pos + result.matchLength); + } + } while (result && result.reparse); + + if (result) { + output += result.output; + pos += (result.matchLength || 1); + } else { + // Get the native token at the current position + token = XRegExp$2.exec(appliedPattern, nativeTokens[scope], pos, 'sticky')[0]; + output += token; + pos += token.length; + if (token === '[' && scope === defaultScope) { + scope = classScope; + } else if (token === ']' && scope === classScope) { + scope = defaultScope; + } + } + } + + patternCache[pattern][flags] = { + pattern: output, + // Strip all but native flags + flags: nativ.replace.call(appliedFlags, /[^gimuy]+/g, ''), + // `context.captureNames` has an item for each capturing group, even if unnamed + captures: context.hasNamedCapture ? context.captureNames : null + }; + } + + generated = patternCache[pattern][flags]; + return augment( + new RegExp(generated.pattern, generated.flags), + generated.captures, + pattern, + flags + ); + } +// Add `RegExp.prototype` to the prototype chain + XRegExp$2.prototype = new RegExp(); + +/* ============================== + * Public properties + * ============================== */ + +/** + * The XRegExp version number as a string containing three dot-separated parts. For example, + * '2.0.0-beta-3'. + * + * @static + * @memberOf XRegExp + * @type String + */ + XRegExp$2.version = '3.1.0'; + +/* ============================== + * Public methods + * ============================== */ + +// Intentionally undocumented + XRegExp$2._hasNativeFlag = hasNativeFlag; + +/** + * Extends XRegExp syntax and allows custom flags. This is used internally and can be used to + * create XRegExp addons. If more than one token can match the same string, the last added wins. + * + * @memberOf XRegExp + * @param {RegExp} regex Regex object that matches the new token. + * @param {Function} handler Function that returns a new pattern string (using native regex syntax) + * to replace the matched token within all future XRegExp regexes. Has access to persistent + * properties of the regex being built, through `this`. Invoked with three arguments: + *
  • The match array, with named backreference properties. + *
  • The regex scope where the match was found: 'default' or 'class'. + *
  • The flags used by the regex, including any flags in a leading mode modifier. + * The handler function becomes part of the XRegExp construction process, so be careful not to + * construct XRegExps within the function or you will trigger infinite recursion. + * @param {Object} [options] Options object with optional properties: + *
  • `scope` {String} Scope where the token applies: 'default', 'class', or 'all'. + *
  • `flag` {String} Single-character flag that triggers the token. This also registers the + * flag, which prevents XRegExp from throwing an 'unknown flag' error when the flag is used. + *
  • `optionalFlags` {String} Any custom flags checked for within the token `handler` that are + * not required to trigger the token. This registers the flags, to prevent XRegExp from + * throwing an 'unknown flag' error when any of the flags are used. + *
  • `reparse` {Boolean} Whether the `handler` function's output should not be treated as + * final, and instead be reparseable by other tokens (including the current token). Allows + * token chaining or deferring. + *
  • `leadChar` {String} Single character that occurs at the beginning of any successful match + * of the token (not always applicable). This doesn't change the behavior of the token unless + * you provide an erroneous value. However, providing it can increase the token's performance + * since the token can be skipped at any positions where this character doesn't appear. + * @example + * + * // Basic usage: Add \a for the ALERT control code + * XRegExp.addToken( + * /\\a/, + * function() {return '\\x07';}, + * {scope: 'all'} + * ); + * XRegExp('\\a[\\a-\\n]+').test('\x07\n\x07'); // -> true + * + * // Add the U (ungreedy) flag from PCRE and RE2, which reverses greedy and lazy quantifiers. + * // Since `scope` is not specified, it uses 'default' (i.e., transformations apply outside of + * // character classes only) + * XRegExp.addToken( + * /([?*+]|{\d+(?:,\d*)?})(\??)/, + * function(match) {return match[1] + (match[2] ? '' : '?');}, + * {flag: 'U'} + * ); + * XRegExp('a+', 'U').exec('aaa')[0]; // -> 'a' + * XRegExp('a+?', 'U').exec('aaa')[0]; // -> 'aaa' + */ + XRegExp$2.addToken = function(regex, handler, options) { + options = options || {}; + var optionalFlags = options.optionalFlags, i; + + if (options.flag) { + registerFlag(options.flag); + } + + if (optionalFlags) { + optionalFlags = nativ.split.call(optionalFlags, ''); + for (i = 0; i < optionalFlags.length; ++i) { + registerFlag(optionalFlags[i]); + } + } + + // Add to the private list of syntax tokens + tokens.push({ + regex: copyRegex(regex, { + addG: true, + addY: hasNativeY, + isInternalOnly: true + }), + handler: handler, + scope: options.scope || defaultScope, + flag: options.flag, + reparse: options.reparse, + leadChar: options.leadChar + }); + + // Reset the pattern cache used by the `XRegExp` constructor, since the same pattern and + // flags might now produce different results + XRegExp$2.cache.flush('patterns'); + }; + +/** + * Caches and returns the result of calling `XRegExp(pattern, flags)`. On any subsequent call with + * the same pattern and flag combination, the cached copy of the regex is returned. + * + * @memberOf XRegExp + * @param {String} pattern Regex pattern string. + * @param {String} [flags] Any combination of XRegExp flags. + * @returns {RegExp} Cached XRegExp object. + * @example + * + * while (match = XRegExp.cache('.', 'gs').exec(str)) { + * // The regex is compiled once only + * } + */ + XRegExp$2.cache = function(pattern, flags) { + if (!regexCache[pattern]) { + regexCache[pattern] = {}; + } + return regexCache[pattern][flags] || ( + regexCache[pattern][flags] = XRegExp$2(pattern, flags) + ); + }; + +// Intentionally undocumented + XRegExp$2.cache.flush = function(cacheName) { + if (cacheName === 'patterns') { + // Flush the pattern cache used by the `XRegExp` constructor + patternCache = {}; + } else { + // Flush the regex cache populated by `XRegExp.cache` + regexCache = {}; + } + }; + +/** + * Escapes any regular expression metacharacters, for use when matching literal strings. The result + * can safely be used at any point within a regex that uses any flags. + * + * @memberOf XRegExp + * @param {String} str String to escape. + * @returns {String} String with regex metacharacters escaped. + * @example + * + * XRegExp.escape('Escaped? <.>'); + * // -> 'Escaped\?\ <\.>' + */ + XRegExp$2.escape = function(str) { + return nativ.replace.call(toObject(str), /[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + }; + +/** + * Executes a regex search in a specified string. Returns a match array or `null`. If the provided + * regex uses named capture, named backreference properties are included on the match array. + * Optional `pos` and `sticky` arguments specify the search start position, and whether the match + * must start at the specified position only. The `lastIndex` property of the provided regex is not + * used, but is updated for compatibility. Also fixes browser bugs compared to the native + * `RegExp.prototype.exec` and can be used reliably cross-browser. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {RegExp} regex Regex to search with. + * @param {Number} [pos=0] Zero-based index at which to start the search. + * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position + * only. The string `'sticky'` is accepted as an alternative to `true`. + * @returns {Array} Match array with named backreference properties, or `null`. + * @example + * + * // Basic use, with named backreference + * var match = XRegExp.exec('U+2620', XRegExp('U\\+(?[0-9A-F]{4})')); + * match.hex; // -> '2620' + * + * // With pos and sticky, in a loop + * var pos = 2, result = [], match; + * while (match = XRegExp.exec('<1><2><3><4>5<6>', /<(\d)>/, pos, 'sticky')) { + * result.push(match[1]); + * pos = match.index + match[0].length; + * } + * // result -> ['2', '3', '4'] + */ + XRegExp$2.exec = function(str, regex, pos, sticky) { + var cacheKey = 'g', + addY = false, + match, + r2; + + addY = hasNativeY && !!(sticky || (regex.sticky && sticky !== false)); + if (addY) { + cacheKey += 'y'; + } + + regex[REGEX_DATA] = regex[REGEX_DATA] || {}; + + // Shares cached copies with `XRegExp.match`/`replace` + r2 = regex[REGEX_DATA][cacheKey] || ( + regex[REGEX_DATA][cacheKey] = copyRegex(regex, { + addG: true, + addY: addY, + removeY: sticky === false, + isInternalOnly: true + }) + ); + + r2.lastIndex = pos = pos || 0; + + // Fixed `exec` required for `lastIndex` fix, named backreferences, etc. + match = fixed.exec.call(r2, str); + + if (sticky && match && match.index !== pos) { + match = null; + } + + if (regex.global) { + regex.lastIndex = match ? r2.lastIndex : 0; + } + + return match; + }; + +/** + * Executes a provided function once per regex match. Searches always start at the beginning of the + * string and continue until the end, regardless of the state of the regex's `global` property and + * initial `lastIndex`. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {RegExp} regex Regex to search with. + * @param {Function} callback Function to execute for each match. Invoked with four arguments: + *
  • The match array, with named backreference properties. + *
  • The zero-based match index. + *
  • The string being traversed. + *
  • The regex object being used to traverse the string. + * @example + * + * // Extracts every other digit from a string + * var evens = []; + * XRegExp.forEach('1a2345', /\d/, function(match, i) { + * if (i % 2) evens.push(+match[0]); + * }); + * // evens -> [2, 4] + */ + XRegExp$2.forEach = function(str, regex, callback) { + var pos = 0, + i = -1, + match; + + while ((match = XRegExp$2.exec(str, regex, pos))) { + // Because `regex` is provided to `callback`, the function could use the deprecated/ + // nonstandard `RegExp.prototype.compile` to mutate the regex. However, since + // `XRegExp.exec` doesn't use `lastIndex` to set the search position, this can't lead + // to an infinite loop, at least. Actually, because of the way `XRegExp.exec` caches + // globalized versions of regexes, mutating the regex will not have any effect on the + // iteration or matched strings, which is a nice side effect that brings extra safety + callback(match, ++i, str, regex); + + pos = match.index + (match[0].length || 1); + } + }; + +/** + * Copies a regex object and adds flag `g`. The copy maintains extended data, is augmented with + * `XRegExp.prototype` properties, and has a fresh `lastIndex` property (set to zero). Native + * regexes are not recompiled using XRegExp syntax. + * + * @memberOf XRegExp + * @param {RegExp} regex Regex to globalize. + * @returns {RegExp} Copy of the provided regex with flag `g` added. + * @example + * + * var globalCopy = XRegExp.globalize(/regex/); + * globalCopy.global; // -> true + */ + XRegExp$2.globalize = function(regex) { + return copyRegex(regex, {addG: true}); + }; + +/** + * Installs optional features according to the specified options. Can be undone using + * `XRegExp.uninstall`. + * + * @memberOf XRegExp + * @param {Object|String} options Options object or string. + * @example + * + * // With an options object + * XRegExp.install({ + * // Enables support for astral code points in Unicode addons (implicitly sets flag A) + * astral: true, + * + * // DEPRECATED: Overrides native regex methods with fixed/extended versions + * natives: true + * }); + * + * // With an options string + * XRegExp.install('astral natives'); + */ + XRegExp$2.install = function(options) { + options = prepareOptions(options); + + if (!features.astral && options.astral) { + setAstral(true); + } + + if (!features.natives && options.natives) { + setNatives(true); + } + }; + +/** + * Checks whether an individual optional feature is installed. + * + * @memberOf XRegExp + * @param {String} feature Name of the feature to check. One of: + *
  • `astral` + *
  • `natives` + * @returns {Boolean} Whether the feature is installed. + * @example + * + * XRegExp.isInstalled('astral'); + */ + XRegExp$2.isInstalled = function(feature) { + return !!(features[feature]); + }; + +/** + * Returns `true` if an object is a regex; `false` if it isn't. This works correctly for regexes + * created in another frame, when `instanceof` and `constructor` checks would fail. + * + * @memberOf XRegExp + * @param {*} value Object to check. + * @returns {Boolean} Whether the object is a `RegExp` object. + * @example + * + * XRegExp.isRegExp('string'); // -> false + * XRegExp.isRegExp(/regex/i); // -> true + * XRegExp.isRegExp(RegExp('^', 'm')); // -> true + * XRegExp.isRegExp(XRegExp('(?s).')); // -> true + */ + XRegExp$2.isRegExp = function(value) { + return toString.call(value) === '[object RegExp]'; + //return isType(value, 'RegExp'); + }; + +/** + * Returns the first matched string, or in global mode, an array containing all matched strings. + * This is essentially a more convenient re-implementation of `String.prototype.match` that gives + * the result types you actually want (string instead of `exec`-style array in match-first mode, + * and an empty array instead of `null` when no matches are found in match-all mode). It also lets + * you override flag g and ignore `lastIndex`, and fixes browser bugs. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {RegExp} regex Regex to search with. + * @param {String} [scope='one'] Use 'one' to return the first match as a string. Use 'all' to + * return an array of all matched strings. If not explicitly specified and `regex` uses flag g, + * `scope` is 'all'. + * @returns {String|Array} In match-first mode: First match as a string, or `null`. In match-all + * mode: Array of all matched strings, or an empty array. + * @example + * + * // Match first + * XRegExp.match('abc', /\w/); // -> 'a' + * XRegExp.match('abc', /\w/g, 'one'); // -> 'a' + * XRegExp.match('abc', /x/g, 'one'); // -> null + * + * // Match all + * XRegExp.match('abc', /\w/g); // -> ['a', 'b', 'c'] + * XRegExp.match('abc', /\w/, 'all'); // -> ['a', 'b', 'c'] + * XRegExp.match('abc', /x/, 'all'); // -> [] + */ + XRegExp$2.match = function(str, regex, scope) { + var global = (regex.global && scope !== 'one') || scope === 'all', + cacheKey = ((global ? 'g' : '') + (regex.sticky ? 'y' : '')) || 'noGY', + result, + r2; + + regex[REGEX_DATA] = regex[REGEX_DATA] || {}; + + // Shares cached copies with `XRegExp.exec`/`replace` + r2 = regex[REGEX_DATA][cacheKey] || ( + regex[REGEX_DATA][cacheKey] = copyRegex(regex, { + addG: !!global, + removeG: scope === 'one', + isInternalOnly: true + }) + ); + + result = nativ.match.call(toObject(str), r2); + + if (regex.global) { + regex.lastIndex = ( + (scope === 'one' && result) ? + // Can't use `r2.lastIndex` since `r2` is nonglobal in this case + (result.index + result[0].length) : 0 + ); + } + + return global ? (result || []) : (result && result[0]); + }; + +/** + * Retrieves the matches from searching a string using a chain of regexes that successively search + * within previous matches. The provided `chain` array can contain regexes and or objects with + * `regex` and `backref` properties. When a backreference is specified, the named or numbered + * backreference is passed forward to the next regex or returned. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {Array} chain Regexes that each search for matches within preceding results. + * @returns {Array} Matches by the last regex in the chain, or an empty array. + * @example + * + * // Basic usage; matches numbers within tags + * XRegExp.matchChain('1 2 3 4 a 56', [ + * XRegExp('(?is).*?'), + * /\d+/ + * ]); + * // -> ['2', '4', '56'] + * + * // Passing forward and returning specific backreferences + * html = 'XRegExp\ + * Google'; + * XRegExp.matchChain(html, [ + * {regex: //i, backref: 1}, + * {regex: XRegExp('(?i)^https?://(?[^/?#]+)'), backref: 'domain'} + * ]); + * // -> ['xregexp.com', 'www.google.com'] + */ + XRegExp$2.matchChain = function(str, chain) { + return (function recurseChain(values, level) { + var item = chain[level].regex ? chain[level] : {regex: chain[level]}, + matches = [], + addMatch = function(match) { + if (item.backref) { + /* Safari 4.0.5 (but not 5.0.5+) inappropriately uses sparse arrays to hold + * the `undefined`s for backreferences to nonparticipating capturing + * groups. In such cases, a `hasOwnProperty` or `in` check on its own would + * inappropriately throw the exception, so also check if the backreference + * is a number that is within the bounds of the array. + */ + if (!(match.hasOwnProperty(item.backref) || +item.backref < match.length)) { + throw new ReferenceError('Backreference to undefined group: ' + item.backref); + } + + matches.push(match[item.backref] || ''); + } else { + matches.push(match[0]); + } + }, + i; + + for (i = 0; i < values.length; ++i) { + XRegExp$2.forEach(values[i], item.regex, addMatch); + } + + return ((level === chain.length - 1) || !matches.length) ? + matches : + recurseChain(matches, level + 1); + }([str], 0)); + }; + +/** + * Returns a new string with one or all matches of a pattern replaced. The pattern can be a string + * or regex, and the replacement can be a string or a function to be called for each match. To + * perform a global search and replace, use the optional `scope` argument or include flag g if using + * a regex. Replacement strings can use `${n}` for named and numbered backreferences. Replacement + * functions can use named backreferences via `arguments[0].name`. Also fixes browser bugs compared + * to the native `String.prototype.replace` and can be used reliably cross-browser. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {RegExp|String} search Search pattern to be replaced. + * @param {String|Function} replacement Replacement string or a function invoked to create it. + * Replacement strings can include special replacement syntax: + *
  • $$ - Inserts a literal $ character. + *
  • $&, $0 - Inserts the matched substring. + *
  • $` - Inserts the string that precedes the matched substring (left context). + *
  • $' - Inserts the string that follows the matched substring (right context). + *
  • $n, $nn - Where n/nn are digits referencing an existent capturing group, inserts + * backreference n/nn. + *
  • ${n} - Where n is a name or any number of digits that reference an existent capturing + * group, inserts backreference n. + * Replacement functions are invoked with three or more arguments: + *
  • The matched substring (corresponds to $& above). Named backreferences are accessible as + * properties of this first argument. + *
  • 0..n arguments, one for each backreference (corresponding to $1, $2, etc. above). + *
  • The zero-based index of the match within the total search string. + *
  • The total string being searched. + * @param {String} [scope='one'] Use 'one' to replace the first match only, or 'all'. If not + * explicitly specified and using a regex with flag g, `scope` is 'all'. + * @returns {String} New string with one or all matches replaced. + * @example + * + * // Regex search, using named backreferences in replacement string + * var name = XRegExp('(?\\w+) (?\\w+)'); + * XRegExp.replace('John Smith', name, '${last}, ${first}'); + * // -> 'Smith, John' + * + * // Regex search, using named backreferences in replacement function + * XRegExp.replace('John Smith', name, function(match) { + * return match.last + ', ' + match.first; + * }); + * // -> 'Smith, John' + * + * // String search, with replace-all + * XRegExp.replace('RegExp builds RegExps', 'RegExp', 'XRegExp', 'all'); + * // -> 'XRegExp builds XRegExps' + */ + XRegExp$2.replace = function(str, search, replacement, scope) { + var isRegex = XRegExp$2.isRegExp(search), + global = (search.global && scope !== 'one') || scope === 'all', + cacheKey = ((global ? 'g' : '') + (search.sticky ? 'y' : '')) || 'noGY', + s2 = search, + result; + + if (isRegex) { + search[REGEX_DATA] = search[REGEX_DATA] || {}; + + // Shares cached copies with `XRegExp.exec`/`match`. Since a copy is used, `search`'s + // `lastIndex` isn't updated *during* replacement iterations + s2 = search[REGEX_DATA][cacheKey] || ( + search[REGEX_DATA][cacheKey] = copyRegex(search, { + addG: !!global, + removeG: scope === 'one', + isInternalOnly: true + }) + ); + } else if (global) { + s2 = new RegExp(XRegExp$2.escape(String(search)), 'g'); + } + + // Fixed `replace` required for named backreferences, etc. + result = fixed.replace.call(toObject(str), s2, replacement); + + if (isRegex && search.global) { + // Fixes IE, Safari bug (last tested IE 9, Safari 5.1) + search.lastIndex = 0; + } + + return result; + }; + +/** + * Performs batch processing of string replacements. Used like `XRegExp.replace`, but accepts an + * array of replacement details. Later replacements operate on the output of earlier replacements. + * Replacement details are accepted as an array with a regex or string to search for, the + * replacement string or function, and an optional scope of 'one' or 'all'. Uses the XRegExp + * replacement text syntax, which supports named backreference properties via `${name}`. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {Array} replacements Array of replacement detail arrays. + * @returns {String} New string with all replacements. + * @example + * + * str = XRegExp.replaceEach(str, [ + * [XRegExp('(?a)'), 'z${name}'], + * [/b/gi, 'y'], + * [/c/g, 'x', 'one'], // scope 'one' overrides /g + * [/d/, 'w', 'all'], // scope 'all' overrides lack of /g + * ['e', 'v', 'all'], // scope 'all' allows replace-all for strings + * [/f/g, function($0) { + * return $0.toUpperCase(); + * }] + * ]); + */ + XRegExp$2.replaceEach = function(str, replacements) { + var i, r; + + for (i = 0; i < replacements.length; ++i) { + r = replacements[i]; + str = XRegExp$2.replace(str, r[0], r[1], r[2]); + } + + return str; + }; + +/** + * Splits a string into an array of strings using a regex or string separator. Matches of the + * separator are not included in the result array. However, if `separator` is a regex that contains + * capturing groups, backreferences are spliced into the result each time `separator` is matched. + * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably + * cross-browser. + * + * @memberOf XRegExp + * @param {String} str String to split. + * @param {RegExp|String} separator Regex or string to use for separating the string. + * @param {Number} [limit] Maximum number of items to include in the result array. + * @returns {Array} Array of substrings. + * @example + * + * // Basic use + * XRegExp.split('a b c', ' '); + * // -> ['a', 'b', 'c'] + * + * // With limit + * XRegExp.split('a b c', ' ', 2); + * // -> ['a', 'b'] + * + * // Backreferences in result array + * XRegExp.split('..word1..', /([a-z]+)(\d+)/i); + * // -> ['..', 'word', '1', '..'] + */ + XRegExp$2.split = function(str, separator, limit) { + return fixed.split.call(toObject(str), separator, limit); + }; + +/** + * Executes a regex search in a specified string. Returns `true` or `false`. Optional `pos` and + * `sticky` arguments specify the search start position, and whether the match must start at the + * specified position only. The `lastIndex` property of the provided regex is not used, but is + * updated for compatibility. Also fixes browser bugs compared to the native + * `RegExp.prototype.test` and can be used reliably cross-browser. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {RegExp} regex Regex to search with. + * @param {Number} [pos=0] Zero-based index at which to start the search. + * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position + * only. The string `'sticky'` is accepted as an alternative to `true`. + * @returns {Boolean} Whether the regex matched the provided value. + * @example + * + * // Basic use + * XRegExp.test('abc', /c/); // -> true + * + * // With pos and sticky + * XRegExp.test('abc', /c/, 0, 'sticky'); // -> false + * XRegExp.test('abc', /c/, 2, 'sticky'); // -> true + */ + XRegExp$2.test = function(str, regex, pos, sticky) { + // Do this the easy way :-) + return !!XRegExp$2.exec(str, regex, pos, sticky); + }; + +/** + * Uninstalls optional features according to the specified options. All optional features start out + * uninstalled, so this is used to undo the actions of `XRegExp.install`. + * + * @memberOf XRegExp + * @param {Object|String} options Options object or string. + * @example + * + * // With an options object + * XRegExp.uninstall({ + * // Disables support for astral code points in Unicode addons + * astral: true, + * + * // DEPRECATED: Restores native regex methods + * natives: true + * }); + * + * // With an options string + * XRegExp.uninstall('astral natives'); + */ + XRegExp$2.uninstall = function(options) { + options = prepareOptions(options); + + if (features.astral && options.astral) { + setAstral(false); + } + + if (features.natives && options.natives) { + setNatives(false); + } + }; + +/** + * Returns an XRegExp object that is the union of the given patterns. Patterns can be provided as + * regex objects or strings. Metacharacters are escaped in patterns provided as strings. + * Backreferences in provided regex objects are automatically renumbered to work correctly within + * the larger combined pattern. Native flags used by provided regexes are ignored in favor of the + * `flags` argument. + * + * @memberOf XRegExp + * @param {Array} patterns Regexes and strings to combine. + * @param {String} [flags] Any combination of XRegExp flags. + * @returns {RegExp} Union of the provided regexes and strings. + * @example + * + * XRegExp.union(['a+b*c', /(dogs)\1/, /(cats)\1/], 'i'); + * // -> /a\+b\*c|(dogs)\1|(cats)\2/i + */ + XRegExp$2.union = function(patterns, flags) { + var parts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*]/g, + output = [], + numCaptures = 0, + numPriorCaptures, + captureNames, + pattern, + rewrite = function(match, paren, backref) { + var name = captureNames[numCaptures - numPriorCaptures]; + + // Capturing group + if (paren) { + ++numCaptures; + // If the current capture has a name, preserve the name + if (name) { + return '(?<' + name + '>'; + } + // Backreference + } else if (backref) { + // Rewrite the backreference + return '\\' + (+backref + numPriorCaptures); + } + + return match; + }, + i; + + if (!(isType(patterns, 'Array') && patterns.length)) { + throw new TypeError('Must provide a nonempty array of patterns to merge'); + } + + for (i = 0; i < patterns.length; ++i) { + pattern = patterns[i]; + + if (XRegExp$2.isRegExp(pattern)) { + numPriorCaptures = numCaptures; + captureNames = (pattern[REGEX_DATA] && pattern[REGEX_DATA].captureNames) || []; + + // Rewrite backreferences. Passing to XRegExp dies on octals and ensures patterns + // are independently valid; helps keep this simple. Named captures are put back + output.push(nativ.replace.call(XRegExp$2(pattern.source).source, parts, rewrite)); + } else { + output.push(XRegExp$2.escape(pattern)); + } + } + + return XRegExp$2(output.join('|'), flags); + }; + +/* ============================== + * Fixed/extended native methods + * ============================== */ + +/** + * Adds named capture support (with backreferences returned as `result.name`), and fixes browser + * bugs in the native `RegExp.prototype.exec`. Calling `XRegExp.install('natives')` uses this to + * override the native method. Use via `XRegExp.exec` without overriding natives. + * + * @private + * @param {String} str String to search. + * @returns {Array} Match array with named backreference properties, or `null`. + */ + fixed.exec = function(str) { + var origLastIndex = this.lastIndex, + match = nativ.exec.apply(this, arguments), + name, + r2, + i; + + if (match) { + // Fix browsers whose `exec` methods don't return `undefined` for nonparticipating + // capturing groups. This fixes IE 5.5-8, but not IE 9's quirks mode or emulation of + // older IEs. IE 9 in standards mode follows the spec + if (!correctExecNpcg && match.length > 1 && indexOf(match, '') > -1) { + r2 = copyRegex(this, { + removeG: true, + isInternalOnly: true + }); + // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed + // matching due to characters outside the match + nativ.replace.call(String(str).slice(match.index), r2, function() { + var len = arguments.length, i; + // Skip index 0 and the last 2 + for (i = 1; i < len - 2; ++i) { + if (arguments[i] === undefined) { + match[i] = undefined; + } + } + }); + } + + // Attach named capture properties + if (this[REGEX_DATA] && this[REGEX_DATA].captureNames) { + // Skip index 0 + for (i = 1; i < match.length; ++i) { + name = this[REGEX_DATA].captureNames[i - 1]; + if (name) { + match[name] = match[i]; + } + } + } + + // Fix browsers that increment `lastIndex` after zero-length matches + if (this.global && !match[0].length && (this.lastIndex > match.index)) { + this.lastIndex = match.index; + } + } + + if (!this.global) { + // Fixes IE, Opera bug (last tested IE 9, Opera 11.6) + this.lastIndex = origLastIndex; + } + + return match; + }; + +/** + * Fixes browser bugs in the native `RegExp.prototype.test`. Calling `XRegExp.install('natives')` + * uses this to override the native method. + * + * @private + * @param {String} str String to search. + * @returns {Boolean} Whether the regex matched the provided value. + */ + fixed.test = function(str) { + // Do this the easy way :-) + return !!fixed.exec.call(this, str); + }; + +/** + * Adds named capture support (with backreferences returned as `result.name`), and fixes browser + * bugs in the native `String.prototype.match`. Calling `XRegExp.install('natives')` uses this to + * override the native method. + * + * @private + * @param {RegExp|*} regex Regex to search with. If not a regex object, it is passed to `RegExp`. + * @returns {Array} If `regex` uses flag g, an array of match strings or `null`. Without flag g, + * the result of calling `regex.exec(this)`. + */ + fixed.match = function(regex) { + var result; + + if (!XRegExp$2.isRegExp(regex)) { + // Use the native `RegExp` rather than `XRegExp` + regex = new RegExp(regex); + } else if (regex.global) { + result = nativ.match.apply(this, arguments); + // Fixes IE bug + regex.lastIndex = 0; + + return result; + } + + return fixed.exec.call(regex, toObject(this)); + }; + +/** + * Adds support for `${n}` tokens for named and numbered backreferences in replacement text, and + * provides named backreferences to replacement functions as `arguments[0].name`. Also fixes browser + * bugs in replacement text syntax when performing a replacement using a nonregex search value, and + * the value of a replacement regex's `lastIndex` property during replacement iterations and upon + * completion. Calling `XRegExp.install('natives')` uses this to override the native method. Note + * that this doesn't support SpiderMonkey's proprietary third (`flags`) argument. Use via + * `XRegExp.replace` without overriding natives. + * + * @private + * @param {RegExp|String} search Search pattern to be replaced. + * @param {String|Function} replacement Replacement string or a function invoked to create it. + * @returns {String} New string with one or all matches replaced. + */ + fixed.replace = function(search, replacement) { + var isRegex = XRegExp$2.isRegExp(search), + origLastIndex, + captureNames, + result; + + if (isRegex) { + if (search[REGEX_DATA]) { + captureNames = search[REGEX_DATA].captureNames; + } + // Only needed if `search` is nonglobal + origLastIndex = search.lastIndex; + } else { + search += ''; // Type-convert + } + + // Don't use `typeof`; some older browsers return 'function' for regex objects + if (isType(replacement, 'Function')) { + // Stringifying `this` fixes a bug in IE < 9 where the last argument in replacement + // functions isn't type-converted to a string + result = nativ.replace.call(String(this), search, function() { + var args = arguments, i; + if (captureNames) { + // Change the `arguments[0]` string primitive to a `String` object that can + // store properties. This really does need to use `String` as a constructor + args[0] = new String(args[0]); + // Store named backreferences on the first argument + for (i = 0; i < captureNames.length; ++i) { + if (captureNames[i]) { + args[0][captureNames[i]] = args[i + 1]; + } + } + } + // Update `lastIndex` before calling `replacement`. Fixes IE, Chrome, Firefox, + // Safari bug (last tested IE 9, Chrome 17, Firefox 11, Safari 5.1) + if (isRegex && search.global) { + search.lastIndex = args[args.length - 2] + args[0].length; + } + // ES6 specs the context for replacement functions as `undefined` + return replacement.apply(undefined, args); + }); + } else { + // Ensure that the last value of `args` will be a string when given nonstring `this`, + // while still throwing on null or undefined context + result = nativ.replace.call(this == null ? this : String(this), search, function() { + // Keep this function's `arguments` available through closure + var args = arguments; + return nativ.replace.call(String(replacement), replacementToken, function($0, $1, $2) { + var n; + // Named or numbered backreference with curly braces + if ($1) { + // XRegExp behavior for `${n}`: + // 1. Backreference to numbered capture, if `n` is an integer. Use `0` for + // for the entire match. Any number of leading zeros may be used. + // 2. Backreference to named capture `n`, if it exists and is not an + // integer overridden by numbered capture. In practice, this does not + // overlap with numbered capture since XRegExp does not allow named + // capture to use a bare integer as the name. + // 3. If the name or number does not refer to an existing capturing group, + // it's an error. + n = +$1; // Type-convert; drop leading zeros + if (n <= args.length - 3) { + return args[n] || ''; + } + // Groups with the same name is an error, else would need `lastIndexOf` + n = captureNames ? indexOf(captureNames, $1) : -1; + if (n < 0) { + throw new SyntaxError('Backreference to undefined group ' + $0); + } + return args[n + 1] || ''; + } + // Else, special variable or numbered backreference without curly braces + if ($2 === '$') { // $$ + return '$'; + } + if ($2 === '&' || +$2 === 0) { // $&, $0 (not followed by 1-9), $00 + return args[0]; + } + if ($2 === '`') { // $` (left context) + return args[args.length - 1].slice(0, args[args.length - 2]); + } + if ($2 === "'") { // $' (right context) + return args[args.length - 1].slice(args[args.length - 2] + args[0].length); + } + // Else, numbered backreference without curly braces + $2 = +$2; // Type-convert; drop leading zero + // XRegExp behavior for `$n` and `$nn`: + // - Backrefs end after 1 or 2 digits. Use `${..}` for more digits. + // - `$1` is an error if no capturing groups. + // - `$10` is an error if less than 10 capturing groups. Use `${1}0` instead. + // - `$01` is `$1` if at least one capturing group, else it's an error. + // - `$0` (not followed by 1-9) and `$00` are the entire match. + // Native behavior, for comparison: + // - Backrefs end after 1 or 2 digits. Cannot reference capturing group 100+. + // - `$1` is a literal `$1` if no capturing groups. + // - `$10` is `$1` followed by a literal `0` if less than 10 capturing groups. + // - `$01` is `$1` if at least one capturing group, else it's a literal `$01`. + // - `$0` is a literal `$0`. + if (!isNaN($2)) { + if ($2 > args.length - 3) { + throw new SyntaxError('Backreference to undefined group ' + $0); + } + return args[$2] || ''; + } + // `$` followed by an unsupported char is an error, unlike native JS + throw new SyntaxError('Invalid token ' + $0); + }); + }); + } + + if (isRegex) { + if (search.global) { + // Fixes IE, Safari bug (last tested IE 9, Safari 5.1) + search.lastIndex = 0; + } else { + // Fixes IE, Opera bug (last tested IE 9, Opera 11.6) + search.lastIndex = origLastIndex; + } + } + + return result; + }; + +/** + * Fixes browser bugs in the native `String.prototype.split`. Calling `XRegExp.install('natives')` + * uses this to override the native method. Use via `XRegExp.split` without overriding natives. + * + * @private + * @param {RegExp|String} separator Regex or string to use for separating the string. + * @param {Number} [limit] Maximum number of items to include in the result array. + * @returns {Array} Array of substrings. + */ + fixed.split = function(separator, limit) { + if (!XRegExp$2.isRegExp(separator)) { + // Browsers handle nonregex split correctly, so use the faster native method + return nativ.split.apply(this, arguments); + } + + var str = String(this), + output = [], + origLastIndex = separator.lastIndex, + lastLastIndex = 0, + lastLength; + + // Values for `limit`, per the spec: + // If undefined: pow(2,32) - 1 + // If 0, Infinity, or NaN: 0 + // If positive number: limit = floor(limit); if (limit >= pow(2,32)) limit -= pow(2,32); + // If negative number: pow(2,32) - floor(abs(limit)) + // If other: Type-convert, then use the above rules + // This line fails in very strange ways for some values of `limit` in Opera 10.5-10.63, + // unless Opera Dragonfly is open (go figure). It works in at least Opera 9.5-10.1 and 11+ + limit = (limit === undefined ? -1 : limit) >>> 0; + + XRegExp$2.forEach(str, separator, function(match) { + // This condition is not the same as `if (match[0].length)` + if ((match.index + match[0].length) > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + if (match.length > 1 && match.index < str.length) { + Array.prototype.push.apply(output, match.slice(1)); + } + lastLength = match[0].length; + lastLastIndex = match.index + lastLength; + } + }); + + if (lastLastIndex === str.length) { + if (!nativ.test.call(separator, '') || lastLength) { + output.push(''); + } + } else { + output.push(str.slice(lastLastIndex)); + } + + separator.lastIndex = origLastIndex; + return output.length > limit ? output.slice(0, limit) : output; + }; + +/* ============================== + * Built-in syntax/flag tokens + * ============================== */ + +/* + * Letter escapes that natively match literal characters: `\a`, `\A`, etc. These should be + * SyntaxErrors but are allowed in web reality. XRegExp makes them errors for cross-browser + * consistency and to reserve their syntax, but lets them be superseded by addons. + */ + XRegExp$2.addToken( + /\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\dA-Fa-f]{4}|{[\dA-Fa-f]+})|x(?![\dA-Fa-f]{2}))/, + function(match, scope) { + // \B is allowed in default scope only + if (match[1] === 'B' && scope === defaultScope) { + return match[0]; + } + throw new SyntaxError('Invalid escape ' + match[0]); + }, + { + scope: 'all', + leadChar: '\\' + } + ); + +/* + * Unicode code point escape with curly braces: `\u{N..}`. `N..` is any one or more digit + * hexadecimal number from 0-10FFFF, and can include leading zeros. Requires the native ES6 `u` flag + * to support code points greater than U+FFFF. Avoids converting code points above U+FFFF to + * surrogate pairs (which could be done without flag `u`), since that could lead to broken behavior + * if you follow a `\u{N..}` token that references a code point above U+FFFF with a quantifier, or + * if you use the same in a character class. + */ + XRegExp$2.addToken( + /\\u{([\dA-Fa-f]+)}/, + function(match, scope, flags) { + var code = dec(match[1]); + if (code > 0x10FFFF) { + throw new SyntaxError('Invalid Unicode code point ' + match[0]); + } + if (code <= 0xFFFF) { + // Converting to \uNNNN avoids needing to escape the literal character and keep it + // separate from preceding tokens + return '\\u' + pad4(hex(code)); + } + // If `code` is between 0xFFFF and 0x10FFFF, require and defer to native handling + if (hasNativeU && flags.indexOf('u') > -1) { + return match[0]; + } + throw new SyntaxError('Cannot use Unicode code point above \\u{FFFF} without flag u'); + }, + { + scope: 'all', + leadChar: '\\' + } + ); + +/* + * Empty character class: `[]` or `[^]`. This fixes a critical cross-browser syntax inconsistency. + * Unless this is standardized (per the ES spec), regex syntax can't be accurately parsed because + * character class endings can't be determined. + */ + XRegExp$2.addToken( + /\[(\^?)]/, + function(match) { + // For cross-browser compatibility with ES3, convert [] to \b\B and [^] to [\s\S]. + // (?!) should work like \b\B, but is unreliable in some versions of Firefox + return match[1] ? '[\\s\\S]' : '\\b\\B'; + }, + {leadChar: '['} + ); + +/* + * Comment pattern: `(?# )`. Inline comments are an alternative to the line comments allowed in + * free-spacing mode (flag x). + */ + XRegExp$2.addToken( + /\(\?#[^)]*\)/, + function(match, scope, flags) { + // Keep tokens separated unless the following token is a quantifier + return isQuantifierNext(match.input, match.index + match[0].length, flags) ? + '' : '(?:)'; + }, + {leadChar: '('} + ); + +/* + * Whitespace and line comments, in free-spacing mode (aka extended mode, flag x) only. + */ + XRegExp$2.addToken( + /\s+|#.*/, + function(match, scope, flags) { + // Keep tokens separated unless the following token is a quantifier + return isQuantifierNext(match.input, match.index + match[0].length, flags) ? + '' : '(?:)'; + }, + {flag: 'x'} + ); + +/* + * Dot, in dotall mode (aka singleline mode, flag s) only. + */ + XRegExp$2.addToken( + /\./, + function() { + return '[\\s\\S]'; + }, + { + flag: 's', + leadChar: '.' + } + ); + +/* + * Named backreference: `\k`. Backreference names can use the characters A-Z, a-z, 0-9, _, + * and $ only. Also allows numbered backreferences as `\k`. + */ + XRegExp$2.addToken( + /\\k<([\w$]+)>/, + function(match) { + // Groups with the same name is an error, else would need `lastIndexOf` + var index = isNaN(match[1]) ? (indexOf(this.captureNames, match[1]) + 1) : +match[1], + endIndex = match.index + match[0].length; + if (!index || index > this.captureNames.length) { + throw new SyntaxError('Backreference to undefined group ' + match[0]); + } + // Keep backreferences separate from subsequent literal numbers + return '\\' + index + ( + endIndex === match.input.length || isNaN(match.input.charAt(endIndex)) ? + '' : '(?:)' + ); + }, + {leadChar: '\\'} + ); + +/* + * Numbered backreference or octal, plus any following digits: `\0`, `\11`, etc. Octals except `\0` + * not followed by 0-9 and backreferences to unopened capture groups throw an error. Other matches + * are returned unaltered. IE < 9 doesn't support backreferences above `\99` in regex syntax. + */ + XRegExp$2.addToken( + /\\(\d+)/, + function(match, scope) { + if ( + !( + scope === defaultScope && + /^[1-9]/.test(match[1]) && + +match[1] <= this.captureNames.length + ) && + match[1] !== '0' + ) { + throw new SyntaxError('Cannot use octal escape or backreference to undefined group ' + + match[0]); + } + return match[0]; + }, + { + scope: 'all', + leadChar: '\\' + } + ); + +/* + * Named capturing group; match the opening delimiter only: `(?`. Capture names can use the + * characters A-Z, a-z, 0-9, _, and $ only. Names can't be integers. Supports Python-style + * `(?P` as an alternate syntax to avoid issues in some older versions of Opera which natively + * supported the Python-style syntax. Otherwise, XRegExp might treat numbered backreferences to + * Python-style named capture as octals. + */ + XRegExp$2.addToken( + /\(\?P?<([\w$]+)>/, + function(match) { + // Disallow bare integers as names because named backreferences are added to match + // arrays and therefore numeric properties may lead to incorrect lookups + if (!isNaN(match[1])) { + throw new SyntaxError('Cannot use integer as capture name ' + match[0]); + } + if (match[1] === 'length' || match[1] === '__proto__') { + throw new SyntaxError('Cannot use reserved word as capture name ' + match[0]); + } + if (indexOf(this.captureNames, match[1]) > -1) { + throw new SyntaxError('Cannot use same name for multiple groups ' + match[0]); + } + this.captureNames.push(match[1]); + this.hasNamedCapture = true; + return '('; + }, + {leadChar: '('} + ); + +/* + * Capturing group; match the opening parenthesis only. Required for support of named capturing + * groups. Also adds explicit capture mode (flag n). + */ + XRegExp$2.addToken( + /\((?!\?)/, + function(match, scope, flags) { + if (flags.indexOf('n') > -1) { + return '(?:'; + } + this.captureNames.push(null); + return '('; + }, + { + optionalFlags: 'n', + leadChar: '(' + } + ); + +/* ============================== + * Expose XRegExp + * ============================== */ + + var xregexp = XRegExp$2; + +/*! + * XRegExp.build 3.1.0 + * + * Steven Levithan (c) 2012-2016 MIT License + * Inspired by Lea Verou's RegExp.create + */ + +var build = function(XRegExp) { + + var REGEX_DATA = 'xregexp', + subParts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*]/g, + parts = XRegExp.union([/\({{([\w$]+)}}\)|{{([\w$]+)}}/, subParts], 'g'); + +/** + * Strips a leading `^` and trailing unescaped `$`, if both are present. + * + * @private + * @param {String} pattern Pattern to process. + * @returns {String} Pattern with edge anchors removed. + */ + function deanchor(pattern) { + // Allow any number of empty noncapturing groups before/after anchors, because regexes + // built/generated by XRegExp sometimes include them + var leadingAnchor = /^(?:\(\?:\))*\^/, + trailingAnchor = /\$(?:\(\?:\))*$/; + + if ( + leadingAnchor.test(pattern) && + trailingAnchor.test(pattern) && + // Ensure that the trailing `$` isn't escaped + trailingAnchor.test(pattern.replace(/\\[\s\S]/g, '')) + ) { + return pattern.replace(leadingAnchor, '').replace(trailingAnchor, ''); + } + + return pattern; + } + +/** + * Converts the provided value to an XRegExp. Native RegExp flags are not preserved. + * + * @private + * @param {String|RegExp} value Value to convert. + * @returns {RegExp} XRegExp object with XRegExp syntax applied. + */ + function asXRegExp(value) { + return XRegExp.isRegExp(value) ? + (value[REGEX_DATA] && value[REGEX_DATA].captureNames ? + // Don't recompile, to preserve capture names + value : + // Recompile as XRegExp + XRegExp(value.source) + ) : + // Compile string as XRegExp + XRegExp(value); + } + +/** + * Builds regexes using named subpatterns, for readability and pattern reuse. Backreferences in the + * outer pattern and provided subpatterns are automatically renumbered to work correctly. Native + * flags used by provided subpatterns are ignored in favor of the `flags` argument. + * + * @memberOf XRegExp + * @param {String} pattern XRegExp pattern using `{{name}}` for embedded subpatterns. Allows + * `({{name}})` as shorthand for `(?{{name}})`. Patterns cannot be embedded within + * character classes. + * @param {Object} subs Lookup object for named subpatterns. Values can be strings or regexes. A + * leading `^` and trailing unescaped `$` are stripped from subpatterns, if both are present. + * @param {String} [flags] Any combination of XRegExp flags. + * @returns {RegExp} Regex with interpolated subpatterns. + * @example + * + * var time = XRegExp.build('(?x)^ {{hours}} ({{minutes}}) $', { + * hours: XRegExp.build('{{h12}} : | {{h24}}', { + * h12: /1[0-2]|0?[1-9]/, + * h24: /2[0-3]|[01][0-9]/ + * }, 'x'), + * minutes: /^[0-5][0-9]$/ + * }); + * time.test('10:59'); // -> true + * XRegExp.exec('10:59', time).minutes; // -> '59' + */ + XRegExp.build = function(pattern, subs, flags) { + var inlineFlags = /^\(\?([\w$]+)\)/.exec(pattern), + data = {}, + numCaps = 0, // 'Caps' is short for captures + numPriorCaps, + numOuterCaps = 0, + outerCapsMap = [0], + outerCapNames, + sub, + p; + + // Add flags within a leading mode modifier to the overall pattern's flags + if (inlineFlags) { + flags = flags || ''; + inlineFlags[1].replace(/./g, function(flag) { + // Don't add duplicates + flags += (flags.indexOf(flag) > -1 ? '' : flag); + }); + } + + for (p in subs) { + if (subs.hasOwnProperty(p)) { + // Passing to XRegExp enables extended syntax and ensures independent validity, + // lest an unescaped `(`, `)`, `[`, or trailing `\` breaks the `(?:)` wrapper. For + // subpatterns provided as native regexes, it dies on octals and adds the property + // used to hold extended regex instance data, for simplicity + sub = asXRegExp(subs[p]); + data[p] = { + // Deanchoring allows embedding independently useful anchored regexes. If you + // really need to keep your anchors, double them (i.e., `^^...$$`) + pattern: deanchor(sub.source), + names: sub[REGEX_DATA].captureNames || [] + }; + } + } + + // Passing to XRegExp dies on octals and ensures the outer pattern is independently valid; + // helps keep this simple. Named captures will be put back + pattern = asXRegExp(pattern); + outerCapNames = pattern[REGEX_DATA].captureNames || []; + pattern = pattern.source.replace(parts, function($0, $1, $2, $3, $4) { + var subName = $1 || $2, + capName, + intro, + localCapIndex; + // Named subpattern + if (subName) { + if (!data.hasOwnProperty(subName)) { + throw new ReferenceError('Undefined property ' + $0); + } + // Named subpattern was wrapped in a capturing group + if ($1) { + capName = outerCapNames[numOuterCaps]; + outerCapsMap[++numOuterCaps] = ++numCaps; + // If it's a named group, preserve the name. Otherwise, use the subpattern name + // as the capture name + intro = '(?<' + (capName || subName) + '>'; + } else { + intro = '(?:'; + } + numPriorCaps = numCaps; + return intro + data[subName].pattern.replace(subParts, function(match, paren, backref) { + // Capturing group + if (paren) { + capName = data[subName].names[numCaps - numPriorCaps]; + ++numCaps; + // If the current capture has a name, preserve the name + if (capName) { + return '(?<' + capName + '>'; + } + // Backreference + } else if (backref) { + localCapIndex = +backref - 1; + // Rewrite the backreference + return data[subName].names[localCapIndex] ? + // Need to preserve the backreference name in case using flag `n` + '\\k<' + data[subName].names[localCapIndex] + '>' : + '\\' + (+backref + numPriorCaps); + } + return match; + }) + ')'; + } + // Capturing group + if ($3) { + capName = outerCapNames[numOuterCaps]; + outerCapsMap[++numOuterCaps] = ++numCaps; + // If the current capture has a name, preserve the name + if (capName) { + return '(?<' + capName + '>'; + } + // Backreference + } else if ($4) { + localCapIndex = +$4 - 1; + // Rewrite the backreference + return outerCapNames[localCapIndex] ? + // Need to preserve the backreference name in case using flag `n` + '\\k<' + outerCapNames[localCapIndex] + '>' : + '\\' + outerCapsMap[+$4]; + } + return $0; + }); + + return XRegExp(pattern, flags); + }; + +}; + +/*! + * XRegExp.matchRecursive 3.1.0 + * + * Steven Levithan (c) 2009-2016 MIT License + */ + +var matchrecursive = function(XRegExp) { + +/** + * Returns a match detail object composed of the provided values. + * + * @private + */ + function row(name, value, start, end) { + return { + name: name, + value: value, + start: start, + end: end + }; + } + +/** + * Returns an array of match strings between outermost left and right delimiters, or an array of + * objects with detailed match parts and position data. An error is thrown if delimiters are + * unbalanced within the data. + * + * @memberOf XRegExp + * @param {String} str String to search. + * @param {String} left Left delimiter as an XRegExp pattern. + * @param {String} right Right delimiter as an XRegExp pattern. + * @param {String} [flags] Any native or XRegExp flags, used for the left and right delimiters. + * @param {Object} [options] Lets you specify `valueNames` and `escapeChar` options. + * @returns {Array} Array of matches, or an empty array. + * @example + * + * // Basic usage + * var str = '(t((e))s)t()(ing)'; + * XRegExp.matchRecursive(str, '\\(', '\\)', 'g'); + * // -> ['t((e))s', '', 'ing'] + * + * // Extended information mode with valueNames + * str = 'Here is
    an
    example'; + * XRegExp.matchRecursive(str, '', '
  • ', 'gi', { + * valueNames: ['between', 'left', 'match', 'right'] + * }); + * // -> [ + * // {name: 'between', value: 'Here is ', start: 0, end: 8}, + * // {name: 'left', value: '
    ', start: 8, end: 13}, + * // {name: 'match', value: '
    an
    ', start: 13, end: 27}, + * // {name: 'right', value: '
    ', start: 27, end: 33}, + * // {name: 'between', value: ' example', start: 33, end: 41} + * // ] + * + * // Omitting unneeded parts with null valueNames, and using escapeChar + * str = '...{1}.\\{{function(x,y){return {y:x}}}'; + * XRegExp.matchRecursive(str, '{', '}', 'g', { + * valueNames: ['literal', null, 'value', null], + * escapeChar: '\\' + * }); + * // -> [ + * // {name: 'literal', value: '...', start: 0, end: 3}, + * // {name: 'value', value: '1', start: 4, end: 5}, + * // {name: 'literal', value: '.\\{', start: 6, end: 9}, + * // {name: 'value', value: 'function(x,y){return {y:x}}', start: 10, end: 37} + * // ] + * + * // Sticky mode via flag y + * str = '<1><<<2>>><3>4<5>'; + * XRegExp.matchRecursive(str, '<', '>', 'gy'); + * // -> ['1', '<<2>>', '3'] + */ + XRegExp.matchRecursive = function(str, left, right, flags, options) { + flags = flags || ''; + options = options || {}; + var global = flags.indexOf('g') > -1, + sticky = flags.indexOf('y') > -1, + // Flag `y` is controlled internally + basicFlags = flags.replace(/y/g, ''), + escapeChar = options.escapeChar, + vN = options.valueNames, + output = [], + openTokens = 0, + delimStart = 0, + delimEnd = 0, + lastOuterEnd = 0, + outerStart, + innerStart, + leftMatch, + rightMatch, + esc; + left = XRegExp(left, basicFlags); + right = XRegExp(right, basicFlags); + + if (escapeChar) { + if (escapeChar.length > 1) { + throw new Error('Cannot use more than one escape character'); + } + escapeChar = XRegExp.escape(escapeChar); + // Using `XRegExp.union` safely rewrites backreferences in `left` and `right` + esc = new RegExp( + '(?:' + escapeChar + '[\\S\\s]|(?:(?!' + + XRegExp.union([left, right]).source + + ')[^' + escapeChar + '])+)+', + // Flags `gy` not needed here + flags.replace(/[^imu]+/g, '') + ); + } + + while (true) { + // If using an escape character, advance to the delimiter's next starting position, + // skipping any escaped characters in between + if (escapeChar) { + delimEnd += (XRegExp.exec(str, esc, delimEnd, 'sticky') || [''])[0].length; + } + leftMatch = XRegExp.exec(str, left, delimEnd); + rightMatch = XRegExp.exec(str, right, delimEnd); + // Keep the leftmost match only + if (leftMatch && rightMatch) { + if (leftMatch.index <= rightMatch.index) { + rightMatch = null; + } else { + leftMatch = null; + } + } + // Paths (LM: leftMatch, RM: rightMatch, OT: openTokens): + // LM | RM | OT | Result + // 1 | 0 | 1 | loop + // 1 | 0 | 0 | loop + // 0 | 1 | 1 | loop + // 0 | 1 | 0 | throw + // 0 | 0 | 1 | throw + // 0 | 0 | 0 | break + // The paths above don't include the sticky mode special case. The loop ends after the + // first completed match if not `global`. + if (leftMatch || rightMatch) { + delimStart = (leftMatch || rightMatch).index; + delimEnd = delimStart + (leftMatch || rightMatch)[0].length; + } else if (!openTokens) { + break; + } + if (sticky && !openTokens && delimStart > lastOuterEnd) { + break; + } + if (leftMatch) { + if (!openTokens) { + outerStart = delimStart; + innerStart = delimEnd; + } + ++openTokens; + } else if (rightMatch && openTokens) { + if (!--openTokens) { + if (vN) { + if (vN[0] && outerStart > lastOuterEnd) { + output.push(row(vN[0], str.slice(lastOuterEnd, outerStart), lastOuterEnd, outerStart)); + } + if (vN[1]) { + output.push(row(vN[1], str.slice(outerStart, innerStart), outerStart, innerStart)); + } + if (vN[2]) { + output.push(row(vN[2], str.slice(innerStart, delimStart), innerStart, delimStart)); + } + if (vN[3]) { + output.push(row(vN[3], str.slice(delimStart, delimEnd), delimStart, delimEnd)); + } + } else { + output.push(str.slice(innerStart, delimStart)); + } + lastOuterEnd = delimEnd; + if (!global) { + break; + } + } + } else { + throw new Error('Unbalanced delimiter found in string'); + } + // If the delimiter matched an empty string, avoid an infinite loop + if (delimStart === delimEnd) { + ++delimEnd; + } + } + + if (global && !sticky && vN && vN[0] && str.length > lastOuterEnd) { + output.push(row(vN[0], str.slice(lastOuterEnd), lastOuterEnd, str.length)); + } + + return output; + }; + +}; + +/*! + * XRegExp Unicode Base 3.1.0 + * + * Steven Levithan (c) 2008-2016 MIT License + */ + +/** + * Adds base support for Unicode matching: + * - Adds syntax `\p{..}` for matching Unicode tokens. Tokens can be inverted using `\P{..}` or + * `\p{^..}`. Token names ignore case, spaces, hyphens, and underscores. You can omit the braces + * for token names that are a single letter (e.g. `\pL` or `PL`). + * - Adds flag A (astral), which enables 21-bit Unicode support. + * - Adds the `XRegExp.addUnicodeData` method used by other addons to provide character data. + * + * Unicode Base relies on externally provided Unicode character data. Official addons are available + * to provide data for Unicode categories, scripts, blocks, and properties. + * + * @requires XRegExp + */ +var unicodeBase = function(XRegExp) { + +// Storage for Unicode data + var unicode = {}; + +/* ============================== + * Private functions + * ============================== */ + +// Generates a token lookup name: lowercase, with hyphens, spaces, and underscores removed + function normalize(name) { + return name.replace(/[- _]+/g, '').toLowerCase(); + } + +// Adds leading zeros if shorter than four characters + function pad4(str) { + while (str.length < 4) { + str = '0' + str; + } + return str; + } + +// Converts a hexadecimal number to decimal + function dec(hex) { + return parseInt(hex, 16); + } + +// Converts a decimal number to hexadecimal + function hex(dec) { + return parseInt(dec, 10).toString(16); + } + +// Gets the decimal code of a literal code unit, \xHH, \uHHHH, or a backslash-escaped literal + function charCode(chr) { + var esc = /^\\[xu](.+)/.exec(chr); + return esc ? + dec(esc[1]) : + chr.charCodeAt(chr.charAt(0) === '\\' ? 1 : 0); + } + +// Inverts a list of ordered BMP characters and ranges + function invertBmp(range) { + var output = '', + lastEnd = -1, + start; + XRegExp.forEach(range, /(\\x..|\\u....|\\?[\s\S])(?:-(\\x..|\\u....|\\?[\s\S]))?/, function(m) { + start = charCode(m[1]); + if (start > (lastEnd + 1)) { + output += '\\u' + pad4(hex(lastEnd + 1)); + if (start > (lastEnd + 2)) { + output += '-\\u' + pad4(hex(start - 1)); + } + } + lastEnd = charCode(m[2] || m[1]); + }); + if (lastEnd < 0xFFFF) { + output += '\\u' + pad4(hex(lastEnd + 1)); + if (lastEnd < 0xFFFE) { + output += '-\\uFFFF'; + } + } + return output; + } + +// Generates an inverted BMP range on first use + function cacheInvertedBmp(slug) { + var prop = 'b!'; + return unicode[slug][prop] || ( + unicode[slug][prop] = invertBmp(unicode[slug].bmp) + ); + } + +// Combines and optionally negates BMP and astral data + function buildAstral(slug, isNegated) { + var item = unicode[slug], + combined = ''; + if (item.bmp && !item.isBmpLast) { + combined = '[' + item.bmp + ']' + (item.astral ? '|' : ''); + } + if (item.astral) { + combined += item.astral; + } + if (item.isBmpLast && item.bmp) { + combined += (item.astral ? '|' : '') + '[' + item.bmp + ']'; + } + // Astral Unicode tokens always match a code point, never a code unit + return isNegated ? + '(?:(?!' + combined + ')(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[\0-\uFFFF]))' : + '(?:' + combined + ')'; + } + +// Builds a complete astral pattern on first use + function cacheAstral(slug, isNegated) { + var prop = isNegated ? 'a!' : 'a='; + return unicode[slug][prop] || ( + unicode[slug][prop] = buildAstral(slug, isNegated) + ); + } + +/* ============================== + * Core functionality + * ============================== */ + +/* + * Add Unicode token syntax: \p{..}, \P{..}, \p{^..}. Also add astral mode (flag A). + */ + XRegExp.addToken( + // Use `*` instead of `+` to avoid capturing `^` as the token name in `\p{^}` + /\\([pP])(?:{(\^?)([^}]*)}|([A-Za-z]))/, + function(match, scope, flags) { + var ERR_DOUBLE_NEG = 'Invalid double negation ', + ERR_UNKNOWN_NAME = 'Unknown Unicode token ', + ERR_UNKNOWN_REF = 'Unicode token missing data ', + ERR_ASTRAL_ONLY = 'Astral mode required for Unicode token ', + ERR_ASTRAL_IN_CLASS = 'Astral mode does not support Unicode tokens within character classes', + // Negated via \P{..} or \p{^..} + isNegated = match[1] === 'P' || !!match[2], + // Switch from BMP (0-FFFF) to astral (0-10FFFF) mode via flag A + isAstralMode = flags.indexOf('A') > -1, + // Token lookup name. Check `[4]` first to avoid passing `undefined` via `\p{}` + slug = normalize(match[4] || match[3]), + // Token data object + item = unicode[slug]; + + if (match[1] === 'P' && match[2]) { + throw new SyntaxError(ERR_DOUBLE_NEG + match[0]); + } + if (!unicode.hasOwnProperty(slug)) { + throw new SyntaxError(ERR_UNKNOWN_NAME + match[0]); + } + + // Switch to the negated form of the referenced Unicode token + if (item.inverseOf) { + slug = normalize(item.inverseOf); + if (!unicode.hasOwnProperty(slug)) { + throw new ReferenceError(ERR_UNKNOWN_REF + match[0] + ' -> ' + item.inverseOf); + } + item = unicode[slug]; + isNegated = !isNegated; + } + + if (!(item.bmp || isAstralMode)) { + throw new SyntaxError(ERR_ASTRAL_ONLY + match[0]); + } + if (isAstralMode) { + if (scope === 'class') { + throw new SyntaxError(ERR_ASTRAL_IN_CLASS); + } + + return cacheAstral(slug, isNegated); + } + + return scope === 'class' ? + (isNegated ? cacheInvertedBmp(slug) : item.bmp) : + (isNegated ? '[^' : '[') + item.bmp + ']'; + }, + { + scope: 'all', + optionalFlags: 'A', + leadChar: '\\' + } + ); + +/** + * Adds to the list of Unicode tokens that XRegExp regexes can match via `\p` or `\P`. + * + * @memberOf XRegExp + * @param {Array} data Objects with named character ranges. Each object may have properties `name`, + * `alias`, `isBmpLast`, `inverseOf`, `bmp`, and `astral`. All but `name` are optional, although + * one of `bmp` or `astral` is required (unless `inverseOf` is set). If `astral` is absent, the + * `bmp` data is used for BMP and astral modes. If `bmp` is absent, the name errors in BMP mode + * but works in astral mode. If both `bmp` and `astral` are provided, the `bmp` data only is used + * in BMP mode, and the combination of `bmp` and `astral` data is used in astral mode. + * `isBmpLast` is needed when a token matches orphan high surrogates *and* uses surrogate pairs + * to match astral code points. The `bmp` and `astral` data should be a combination of literal + * characters and `\xHH` or `\uHHHH` escape sequences, with hyphens to create ranges. Any regex + * metacharacters in the data should be escaped, apart from range-creating hyphens. The `astral` + * data can additionally use character classes and alternation, and should use surrogate pairs to + * represent astral code points. `inverseOf` can be used to avoid duplicating character data if a + * Unicode token is defined as the exact inverse of another token. + * @example + * + * // Basic use + * XRegExp.addUnicodeData([{ + * name: 'XDigit', + * alias: 'Hexadecimal', + * bmp: '0-9A-Fa-f' + * }]); + * XRegExp('\\p{XDigit}:\\p{Hexadecimal}+').test('0:3D'); // -> true + */ + XRegExp.addUnicodeData = function(data) { + var ERR_NO_NAME = 'Unicode token requires name', + ERR_NO_DATA = 'Unicode token has no character data ', + item, + i; + + for (i = 0; i < data.length; ++i) { + item = data[i]; + if (!item.name) { + throw new Error(ERR_NO_NAME); + } + if (!(item.inverseOf || item.bmp || item.astral)) { + throw new Error(ERR_NO_DATA + item.name); + } + unicode[normalize(item.name)] = item; + if (item.alias) { + unicode[normalize(item.alias)] = item; + } + } + + // Reset the pattern cache used by the `XRegExp` constructor, since the same pattern and + // flags might now produce different results + XRegExp.cache.flush('patterns'); + }; + +}; + +/*! + * XRegExp Unicode Blocks 3.1.0 + * + * Steven Levithan (c) 2010-2016 MIT License + * Unicode data by Mathias Bynens + */ + +/** + * Adds support for all Unicode blocks. Block names use the prefix 'In'. E.g., `\p{InBasicLatin}`. + * Token names are case insensitive, and any spaces, hyphens, and underscores are ignored. + * + * Uses Unicode 8.0.0. + * + * @requires XRegExp, Unicode Base + */ +var unicodeBlocks = function(XRegExp) { + + if (!XRegExp.addUnicodeData) { + throw new ReferenceError('Unicode Base must be loaded before Unicode Blocks'); + } + + XRegExp.addUnicodeData([ + { + name: 'InAegean_Numbers', + astral: '\uD800[\uDD00-\uDD3F]' + }, + { + name: 'InAhom', + astral: '\uD805[\uDF00-\uDF3F]' + }, + { + name: 'InAlchemical_Symbols', + astral: '\uD83D[\uDF00-\uDF7F]' + }, + { + name: 'InAlphabetic_Presentation_Forms', + bmp: '\uFB00-\uFB4F' + }, + { + name: 'InAnatolian_Hieroglyphs', + astral: '\uD811[\uDC00-\uDE7F]' + }, + { + name: 'InAncient_Greek_Musical_Notation', + astral: '\uD834[\uDE00-\uDE4F]' + }, + { + name: 'InAncient_Greek_Numbers', + astral: '\uD800[\uDD40-\uDD8F]' + }, + { + name: 'InAncient_Symbols', + astral: '\uD800[\uDD90-\uDDCF]' + }, + { + name: 'InArabic', + bmp: '\u0600-\u06FF' + }, + { + name: 'InArabic_Extended_A', + bmp: '\u08A0-\u08FF' + }, + { + name: 'InArabic_Mathematical_Alphabetic_Symbols', + astral: '\uD83B[\uDE00-\uDEFF]' + }, + { + name: 'InArabic_Presentation_Forms_A', + bmp: '\uFB50-\uFDFF' + }, + { + name: 'InArabic_Presentation_Forms_B', + bmp: '\uFE70-\uFEFF' + }, + { + name: 'InArabic_Supplement', + bmp: '\u0750-\u077F' + }, + { + name: 'InArmenian', + bmp: '\u0530-\u058F' + }, + { + name: 'InArrows', + bmp: '\u2190-\u21FF' + }, + { + name: 'InAvestan', + astral: '\uD802[\uDF00-\uDF3F]' + }, + { + name: 'InBalinese', + bmp: '\u1B00-\u1B7F' + }, + { + name: 'InBamum', + bmp: '\uA6A0-\uA6FF' + }, + { + name: 'InBamum_Supplement', + astral: '\uD81A[\uDC00-\uDE3F]' + }, + { + name: 'InBasic_Latin', + bmp: '\0-\x7F' + }, + { + name: 'InBassa_Vah', + astral: '\uD81A[\uDED0-\uDEFF]' + }, + { + name: 'InBatak', + bmp: '\u1BC0-\u1BFF' + }, + { + name: 'InBengali', + bmp: '\u0980-\u09FF' + }, + { + name: 'InBlock_Elements', + bmp: '\u2580-\u259F' + }, + { + name: 'InBopomofo', + bmp: '\u3100-\u312F' + }, + { + name: 'InBopomofo_Extended', + bmp: '\u31A0-\u31BF' + }, + { + name: 'InBox_Drawing', + bmp: '\u2500-\u257F' + }, + { + name: 'InBrahmi', + astral: '\uD804[\uDC00-\uDC7F]' + }, + { + name: 'InBraille_Patterns', + bmp: '\u2800-\u28FF' + }, + { + name: 'InBuginese', + bmp: '\u1A00-\u1A1F' + }, + { + name: 'InBuhid', + bmp: '\u1740-\u175F' + }, + { + name: 'InByzantine_Musical_Symbols', + astral: '\uD834[\uDC00-\uDCFF]' + }, + { + name: 'InCJK_Compatibility', + bmp: '\u3300-\u33FF' + }, + { + name: 'InCJK_Compatibility_Forms', + bmp: '\uFE30-\uFE4F' + }, + { + name: 'InCJK_Compatibility_Ideographs', + bmp: '\uF900-\uFAFF' + }, + { + name: 'InCJK_Compatibility_Ideographs_Supplement', + astral: '\uD87E[\uDC00-\uDE1F]' + }, + { + name: 'InCJK_Radicals_Supplement', + bmp: '\u2E80-\u2EFF' + }, + { + name: 'InCJK_Strokes', + bmp: '\u31C0-\u31EF' + }, + { + name: 'InCJK_Symbols_and_Punctuation', + bmp: '\u3000-\u303F' + }, + { + name: 'InCJK_Unified_Ideographs', + bmp: '\u4E00-\u9FFF' + }, + { + name: 'InCJK_Unified_Ideographs_Extension_A', + bmp: '\u3400-\u4DBF' + }, + { + name: 'InCJK_Unified_Ideographs_Extension_B', + astral: '[\uD840-\uD868][\uDC00-\uDFFF]|\uD869[\uDC00-\uDEDF]' + }, + { + name: 'InCJK_Unified_Ideographs_Extension_C', + astral: '\uD86D[\uDC00-\uDF3F]|[\uD86A-\uD86C][\uDC00-\uDFFF]|\uD869[\uDF00-\uDFFF]' + }, + { + name: 'InCJK_Unified_Ideographs_Extension_D', + astral: '\uD86D[\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1F]' + }, + { + name: 'InCJK_Unified_Ideographs_Extension_E', + astral: '[\uD86F-\uD872][\uDC00-\uDFFF]|\uD873[\uDC00-\uDEAF]|\uD86E[\uDC20-\uDFFF]' + }, + { + name: 'InCarian', + astral: '\uD800[\uDEA0-\uDEDF]' + }, + { + name: 'InCaucasian_Albanian', + astral: '\uD801[\uDD30-\uDD6F]' + }, + { + name: 'InChakma', + astral: '\uD804[\uDD00-\uDD4F]' + }, + { + name: 'InCham', + bmp: '\uAA00-\uAA5F' + }, + { + name: 'InCherokee', + bmp: '\u13A0-\u13FF' + }, + { + name: 'InCherokee_Supplement', + bmp: '\uAB70-\uABBF' + }, + { + name: 'InCombining_Diacritical_Marks', + bmp: '\u0300-\u036F' + }, + { + name: 'InCombining_Diacritical_Marks_Extended', + bmp: '\u1AB0-\u1AFF' + }, + { + name: 'InCombining_Diacritical_Marks_Supplement', + bmp: '\u1DC0-\u1DFF' + }, + { + name: 'InCombining_Diacritical_Marks_for_Symbols', + bmp: '\u20D0-\u20FF' + }, + { + name: 'InCombining_Half_Marks', + bmp: '\uFE20-\uFE2F' + }, + { + name: 'InCommon_Indic_Number_Forms', + bmp: '\uA830-\uA83F' + }, + { + name: 'InControl_Pictures', + bmp: '\u2400-\u243F' + }, + { + name: 'InCoptic', + bmp: '\u2C80-\u2CFF' + }, + { + name: 'InCoptic_Epact_Numbers', + astral: '\uD800[\uDEE0-\uDEFF]' + }, + { + name: 'InCounting_Rod_Numerals', + astral: '\uD834[\uDF60-\uDF7F]' + }, + { + name: 'InCuneiform', + astral: '\uD808[\uDC00-\uDFFF]' + }, + { + name: 'InCuneiform_Numbers_and_Punctuation', + astral: '\uD809[\uDC00-\uDC7F]' + }, + { + name: 'InCurrency_Symbols', + bmp: '\u20A0-\u20CF' + }, + { + name: 'InCypriot_Syllabary', + astral: '\uD802[\uDC00-\uDC3F]' + }, + { + name: 'InCyrillic', + bmp: '\u0400-\u04FF' + }, + { + name: 'InCyrillic_Extended_A', + bmp: '\u2DE0-\u2DFF' + }, + { + name: 'InCyrillic_Extended_B', + bmp: '\uA640-\uA69F' + }, + { + name: 'InCyrillic_Supplement', + bmp: '\u0500-\u052F' + }, + { + name: 'InDeseret', + astral: '\uD801[\uDC00-\uDC4F]' + }, + { + name: 'InDevanagari', + bmp: '\u0900-\u097F' + }, + { + name: 'InDevanagari_Extended', + bmp: '\uA8E0-\uA8FF' + }, + { + name: 'InDingbats', + bmp: '\u2700-\u27BF' + }, + { + name: 'InDomino_Tiles', + astral: '\uD83C[\uDC30-\uDC9F]' + }, + { + name: 'InDuployan', + astral: '\uD82F[\uDC00-\uDC9F]' + }, + { + name: 'InEarly_Dynastic_Cuneiform', + astral: '\uD809[\uDC80-\uDD4F]' + }, + { + name: 'InEgyptian_Hieroglyphs', + astral: '\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F]' + }, + { + name: 'InElbasan', + astral: '\uD801[\uDD00-\uDD2F]' + }, + { + name: 'InEmoticons', + astral: '\uD83D[\uDE00-\uDE4F]' + }, + { + name: 'InEnclosed_Alphanumeric_Supplement', + astral: '\uD83C[\uDD00-\uDDFF]' + }, + { + name: 'InEnclosed_Alphanumerics', + bmp: '\u2460-\u24FF' + }, + { + name: 'InEnclosed_CJK_Letters_and_Months', + bmp: '\u3200-\u32FF' + }, + { + name: 'InEnclosed_Ideographic_Supplement', + astral: '\uD83C[\uDE00-\uDEFF]' + }, + { + name: 'InEthiopic', + bmp: '\u1200-\u137F' + }, + { + name: 'InEthiopic_Extended', + bmp: '\u2D80-\u2DDF' + }, + { + name: 'InEthiopic_Extended_A', + bmp: '\uAB00-\uAB2F' + }, + { + name: 'InEthiopic_Supplement', + bmp: '\u1380-\u139F' + }, + { + name: 'InGeneral_Punctuation', + bmp: '\u2000-\u206F' + }, + { + name: 'InGeometric_Shapes', + bmp: '\u25A0-\u25FF' + }, + { + name: 'InGeometric_Shapes_Extended', + astral: '\uD83D[\uDF80-\uDFFF]' + }, + { + name: 'InGeorgian', + bmp: '\u10A0-\u10FF' + }, + { + name: 'InGeorgian_Supplement', + bmp: '\u2D00-\u2D2F' + }, + { + name: 'InGlagolitic', + bmp: '\u2C00-\u2C5F' + }, + { + name: 'InGothic', + astral: '\uD800[\uDF30-\uDF4F]' + }, + { + name: 'InGrantha', + astral: '\uD804[\uDF00-\uDF7F]' + }, + { + name: 'InGreek_Extended', + bmp: '\u1F00-\u1FFF' + }, + { + name: 'InGreek_and_Coptic', + bmp: '\u0370-\u03FF' + }, + { + name: 'InGujarati', + bmp: '\u0A80-\u0AFF' + }, + { + name: 'InGurmukhi', + bmp: '\u0A00-\u0A7F' + }, + { + name: 'InHalfwidth_and_Fullwidth_Forms', + bmp: '\uFF00-\uFFEF' + }, + { + name: 'InHangul_Compatibility_Jamo', + bmp: '\u3130-\u318F' + }, + { + name: 'InHangul_Jamo', + bmp: '\u1100-\u11FF' + }, + { + name: 'InHangul_Jamo_Extended_A', + bmp: '\uA960-\uA97F' + }, + { + name: 'InHangul_Jamo_Extended_B', + bmp: '\uD7B0-\uD7FF' + }, + { + name: 'InHangul_Syllables', + bmp: '\uAC00-\uD7AF' + }, + { + name: 'InHanunoo', + bmp: '\u1720-\u173F' + }, + { + name: 'InHatran', + astral: '\uD802[\uDCE0-\uDCFF]' + }, + { + name: 'InHebrew', + bmp: '\u0590-\u05FF' + }, + { + name: 'InHigh_Private_Use_Surrogates', + bmp: '\uDB80-\uDBFF' + }, + { + name: 'InHigh_Surrogates', + bmp: '\uD800-\uDB7F' + }, + { + name: 'InHiragana', + bmp: '\u3040-\u309F' + }, + { + name: 'InIPA_Extensions', + bmp: '\u0250-\u02AF' + }, + { + name: 'InIdeographic_Description_Characters', + bmp: '\u2FF0-\u2FFF' + }, + { + name: 'InImperial_Aramaic', + astral: '\uD802[\uDC40-\uDC5F]' + }, + { + name: 'InInscriptional_Pahlavi', + astral: '\uD802[\uDF60-\uDF7F]' + }, + { + name: 'InInscriptional_Parthian', + astral: '\uD802[\uDF40-\uDF5F]' + }, + { + name: 'InJavanese', + bmp: '\uA980-\uA9DF' + }, + { + name: 'InKaithi', + astral: '\uD804[\uDC80-\uDCCF]' + }, + { + name: 'InKana_Supplement', + astral: '\uD82C[\uDC00-\uDCFF]' + }, + { + name: 'InKanbun', + bmp: '\u3190-\u319F' + }, + { + name: 'InKangxi_Radicals', + bmp: '\u2F00-\u2FDF' + }, + { + name: 'InKannada', + bmp: '\u0C80-\u0CFF' + }, + { + name: 'InKatakana', + bmp: '\u30A0-\u30FF' + }, + { + name: 'InKatakana_Phonetic_Extensions', + bmp: '\u31F0-\u31FF' + }, + { + name: 'InKayah_Li', + bmp: '\uA900-\uA92F' + }, + { + name: 'InKharoshthi', + astral: '\uD802[\uDE00-\uDE5F]' + }, + { + name: 'InKhmer', + bmp: '\u1780-\u17FF' + }, + { + name: 'InKhmer_Symbols', + bmp: '\u19E0-\u19FF' + }, + { + name: 'InKhojki', + astral: '\uD804[\uDE00-\uDE4F]' + }, + { + name: 'InKhudawadi', + astral: '\uD804[\uDEB0-\uDEFF]' + }, + { + name: 'InLao', + bmp: '\u0E80-\u0EFF' + }, + { + name: 'InLatin_Extended_Additional', + bmp: '\u1E00-\u1EFF' + }, + { + name: 'InLatin_Extended_A', + bmp: '\u0100-\u017F' + }, + { + name: 'InLatin_Extended_B', + bmp: '\u0180-\u024F' + }, + { + name: 'InLatin_Extended_C', + bmp: '\u2C60-\u2C7F' + }, + { + name: 'InLatin_Extended_D', + bmp: '\uA720-\uA7FF' + }, + { + name: 'InLatin_Extended_E', + bmp: '\uAB30-\uAB6F' + }, + { + name: 'InLatin_1_Supplement', + bmp: '\x80-\xFF' + }, + { + name: 'InLepcha', + bmp: '\u1C00-\u1C4F' + }, + { + name: 'InLetterlike_Symbols', + bmp: '\u2100-\u214F' + }, + { + name: 'InLimbu', + bmp: '\u1900-\u194F' + }, + { + name: 'InLinear_A', + astral: '\uD801[\uDE00-\uDF7F]' + }, + { + name: 'InLinear_B_Ideograms', + astral: '\uD800[\uDC80-\uDCFF]' + }, + { + name: 'InLinear_B_Syllabary', + astral: '\uD800[\uDC00-\uDC7F]' + }, + { + name: 'InLisu', + bmp: '\uA4D0-\uA4FF' + }, + { + name: 'InLow_Surrogates', + bmp: '\uDC00-\uDFFF' + }, + { + name: 'InLycian', + astral: '\uD800[\uDE80-\uDE9F]' + }, + { + name: 'InLydian', + astral: '\uD802[\uDD20-\uDD3F]' + }, + { + name: 'InMahajani', + astral: '\uD804[\uDD50-\uDD7F]' + }, + { + name: 'InMahjong_Tiles', + astral: '\uD83C[\uDC00-\uDC2F]' + }, + { + name: 'InMalayalam', + bmp: '\u0D00-\u0D7F' + }, + { + name: 'InMandaic', + bmp: '\u0840-\u085F' + }, + { + name: 'InManichaean', + astral: '\uD802[\uDEC0-\uDEFF]' + }, + { + name: 'InMathematical_Alphanumeric_Symbols', + astral: '\uD835[\uDC00-\uDFFF]' + }, + { + name: 'InMathematical_Operators', + bmp: '\u2200-\u22FF' + }, + { + name: 'InMeetei_Mayek', + bmp: '\uABC0-\uABFF' + }, + { + name: 'InMeetei_Mayek_Extensions', + bmp: '\uAAE0-\uAAFF' + }, + { + name: 'InMende_Kikakui', + astral: '\uD83A[\uDC00-\uDCDF]' + }, + { + name: 'InMeroitic_Cursive', + astral: '\uD802[\uDDA0-\uDDFF]' + }, + { + name: 'InMeroitic_Hieroglyphs', + astral: '\uD802[\uDD80-\uDD9F]' + }, + { + name: 'InMiao', + astral: '\uD81B[\uDF00-\uDF9F]' + }, + { + name: 'InMiscellaneous_Mathematical_Symbols_A', + bmp: '\u27C0-\u27EF' + }, + { + name: 'InMiscellaneous_Mathematical_Symbols_B', + bmp: '\u2980-\u29FF' + }, + { + name: 'InMiscellaneous_Symbols', + bmp: '\u2600-\u26FF' + }, + { + name: 'InMiscellaneous_Symbols_and_Arrows', + bmp: '\u2B00-\u2BFF' + }, + { + name: 'InMiscellaneous_Symbols_and_Pictographs', + astral: '\uD83D[\uDC00-\uDDFF]|\uD83C[\uDF00-\uDFFF]' + }, + { + name: 'InMiscellaneous_Technical', + bmp: '\u2300-\u23FF' + }, + { + name: 'InModi', + astral: '\uD805[\uDE00-\uDE5F]' + }, + { + name: 'InModifier_Tone_Letters', + bmp: '\uA700-\uA71F' + }, + { + name: 'InMongolian', + bmp: '\u1800-\u18AF' + }, + { + name: 'InMro', + astral: '\uD81A[\uDE40-\uDE6F]' + }, + { + name: 'InMultani', + astral: '\uD804[\uDE80-\uDEAF]' + }, + { + name: 'InMusical_Symbols', + astral: '\uD834[\uDD00-\uDDFF]' + }, + { + name: 'InMyanmar', + bmp: '\u1000-\u109F' + }, + { + name: 'InMyanmar_Extended_A', + bmp: '\uAA60-\uAA7F' + }, + { + name: 'InMyanmar_Extended_B', + bmp: '\uA9E0-\uA9FF' + }, + { + name: 'InNKo', + bmp: '\u07C0-\u07FF' + }, + { + name: 'InNabataean', + astral: '\uD802[\uDC80-\uDCAF]' + }, + { + name: 'InNew_Tai_Lue', + bmp: '\u1980-\u19DF' + }, + { + name: 'InNumber_Forms', + bmp: '\u2150-\u218F' + }, + { + name: 'InOgham', + bmp: '\u1680-\u169F' + }, + { + name: 'InOl_Chiki', + bmp: '\u1C50-\u1C7F' + }, + { + name: 'InOld_Hungarian', + astral: '\uD803[\uDC80-\uDCFF]' + }, + { + name: 'InOld_Italic', + astral: '\uD800[\uDF00-\uDF2F]' + }, + { + name: 'InOld_North_Arabian', + astral: '\uD802[\uDE80-\uDE9F]' + }, + { + name: 'InOld_Permic', + astral: '\uD800[\uDF50-\uDF7F]' + }, + { + name: 'InOld_Persian', + astral: '\uD800[\uDFA0-\uDFDF]' + }, + { + name: 'InOld_South_Arabian', + astral: '\uD802[\uDE60-\uDE7F]' + }, + { + name: 'InOld_Turkic', + astral: '\uD803[\uDC00-\uDC4F]' + }, + { + name: 'InOptical_Character_Recognition', + bmp: '\u2440-\u245F' + }, + { + name: 'InOriya', + bmp: '\u0B00-\u0B7F' + }, + { + name: 'InOrnamental_Dingbats', + astral: '\uD83D[\uDE50-\uDE7F]' + }, + { + name: 'InOsmanya', + astral: '\uD801[\uDC80-\uDCAF]' + }, + { + name: 'InPahawh_Hmong', + astral: '\uD81A[\uDF00-\uDF8F]' + }, + { + name: 'InPalmyrene', + astral: '\uD802[\uDC60-\uDC7F]' + }, + { + name: 'InPau_Cin_Hau', + astral: '\uD806[\uDEC0-\uDEFF]' + }, + { + name: 'InPhags_pa', + bmp: '\uA840-\uA87F' + }, + { + name: 'InPhaistos_Disc', + astral: '\uD800[\uDDD0-\uDDFF]' + }, + { + name: 'InPhoenician', + astral: '\uD802[\uDD00-\uDD1F]' + }, + { + name: 'InPhonetic_Extensions', + bmp: '\u1D00-\u1D7F' + }, + { + name: 'InPhonetic_Extensions_Supplement', + bmp: '\u1D80-\u1DBF' + }, + { + name: 'InPlaying_Cards', + astral: '\uD83C[\uDCA0-\uDCFF]' + }, + { + name: 'InPrivate_Use_Area', + bmp: '\uE000-\uF8FF' + }, + { + name: 'InPsalter_Pahlavi', + astral: '\uD802[\uDF80-\uDFAF]' + }, + { + name: 'InRejang', + bmp: '\uA930-\uA95F' + }, + { + name: 'InRumi_Numeral_Symbols', + astral: '\uD803[\uDE60-\uDE7F]' + }, + { + name: 'InRunic', + bmp: '\u16A0-\u16FF' + }, + { + name: 'InSamaritan', + bmp: '\u0800-\u083F' + }, + { + name: 'InSaurashtra', + bmp: '\uA880-\uA8DF' + }, + { + name: 'InSharada', + astral: '\uD804[\uDD80-\uDDDF]' + }, + { + name: 'InShavian', + astral: '\uD801[\uDC50-\uDC7F]' + }, + { + name: 'InShorthand_Format_Controls', + astral: '\uD82F[\uDCA0-\uDCAF]' + }, + { + name: 'InSiddham', + astral: '\uD805[\uDD80-\uDDFF]' + }, + { + name: 'InSinhala', + bmp: '\u0D80-\u0DFF' + }, + { + name: 'InSinhala_Archaic_Numbers', + astral: '\uD804[\uDDE0-\uDDFF]' + }, + { + name: 'InSmall_Form_Variants', + bmp: '\uFE50-\uFE6F' + }, + { + name: 'InSora_Sompeng', + astral: '\uD804[\uDCD0-\uDCFF]' + }, + { + name: 'InSpacing_Modifier_Letters', + bmp: '\u02B0-\u02FF' + }, + { + name: 'InSpecials', + bmp: '\uFFF0-\uFFFF' + }, + { + name: 'InSundanese', + bmp: '\u1B80-\u1BBF' + }, + { + name: 'InSundanese_Supplement', + bmp: '\u1CC0-\u1CCF' + }, + { + name: 'InSuperscripts_and_Subscripts', + bmp: '\u2070-\u209F' + }, + { + name: 'InSupplemental_Arrows_A', + bmp: '\u27F0-\u27FF' + }, + { + name: 'InSupplemental_Arrows_B', + bmp: '\u2900-\u297F' + }, + { + name: 'InSupplemental_Arrows_C', + astral: '\uD83E[\uDC00-\uDCFF]' + }, + { + name: 'InSupplemental_Mathematical_Operators', + bmp: '\u2A00-\u2AFF' + }, + { + name: 'InSupplemental_Punctuation', + bmp: '\u2E00-\u2E7F' + }, + { + name: 'InSupplemental_Symbols_and_Pictographs', + astral: '\uD83E[\uDD00-\uDDFF]' + }, + { + name: 'InSupplementary_Private_Use_Area_A', + astral: '[\uDB80-\uDBBF][\uDC00-\uDFFF]' + }, + { + name: 'InSupplementary_Private_Use_Area_B', + astral: '[\uDBC0-\uDBFF][\uDC00-\uDFFF]' + }, + { + name: 'InSutton_SignWriting', + astral: '\uD836[\uDC00-\uDEAF]' + }, + { + name: 'InSyloti_Nagri', + bmp: '\uA800-\uA82F' + }, + { + name: 'InSyriac', + bmp: '\u0700-\u074F' + }, + { + name: 'InTagalog', + bmp: '\u1700-\u171F' + }, + { + name: 'InTagbanwa', + bmp: '\u1760-\u177F' + }, + { + name: 'InTags', + astral: '\uDB40[\uDC00-\uDC7F]' + }, + { + name: 'InTai_Le', + bmp: '\u1950-\u197F' + }, + { + name: 'InTai_Tham', + bmp: '\u1A20-\u1AAF' + }, + { + name: 'InTai_Viet', + bmp: '\uAA80-\uAADF' + }, + { + name: 'InTai_Xuan_Jing_Symbols', + astral: '\uD834[\uDF00-\uDF5F]' + }, + { + name: 'InTakri', + astral: '\uD805[\uDE80-\uDECF]' + }, + { + name: 'InTamil', + bmp: '\u0B80-\u0BFF' + }, + { + name: 'InTelugu', + bmp: '\u0C00-\u0C7F' + }, + { + name: 'InThaana', + bmp: '\u0780-\u07BF' + }, + { + name: 'InThai', + bmp: '\u0E00-\u0E7F' + }, + { + name: 'InTibetan', + bmp: '\u0F00-\u0FFF' + }, + { + name: 'InTifinagh', + bmp: '\u2D30-\u2D7F' + }, + { + name: 'InTirhuta', + astral: '\uD805[\uDC80-\uDCDF]' + }, + { + name: 'InTransport_and_Map_Symbols', + astral: '\uD83D[\uDE80-\uDEFF]' + }, + { + name: 'InUgaritic', + astral: '\uD800[\uDF80-\uDF9F]' + }, + { + name: 'InUnified_Canadian_Aboriginal_Syllabics', + bmp: '\u1400-\u167F' + }, + { + name: 'InUnified_Canadian_Aboriginal_Syllabics_Extended', + bmp: '\u18B0-\u18FF' + }, + { + name: 'InVai', + bmp: '\uA500-\uA63F' + }, + { + name: 'InVariation_Selectors', + bmp: '\uFE00-\uFE0F' + }, + { + name: 'InVariation_Selectors_Supplement', + astral: '\uDB40[\uDD00-\uDDEF]' + }, + { + name: 'InVedic_Extensions', + bmp: '\u1CD0-\u1CFF' + }, + { + name: 'InVertical_Forms', + bmp: '\uFE10-\uFE1F' + }, + { + name: 'InWarang_Citi', + astral: '\uD806[\uDCA0-\uDCFF]' + }, + { + name: 'InYi_Radicals', + bmp: '\uA490-\uA4CF' + }, + { + name: 'InYi_Syllables', + bmp: '\uA000-\uA48F' + }, + { + name: 'InYijing_Hexagram_Symbols', + bmp: '\u4DC0-\u4DFF' + } + ]); + +}; + +/*! + * XRegExp Unicode Categories 3.1.0 + * + * Steven Levithan (c) 2010-2016 MIT License + * Unicode data by Mathias Bynens + */ + +/** + * Adds support for Unicode's general categories. E.g., `\p{Lu}` or `\p{Uppercase Letter}`. See + * category descriptions in UAX #44 . Token names + * are case insensitive, and any spaces, hyphens, and underscores are ignored. + * + * Uses Unicode 8.0.0. + * + * @requires XRegExp, Unicode Base + */ +var unicodeCategories = function(XRegExp) { + + if (!XRegExp.addUnicodeData) { + throw new ReferenceError('Unicode Base must be loaded before Unicode Categories'); + } + + XRegExp.addUnicodeData([ + { + name: 'C', + alias: 'Other', + isBmpLast: true, + bmp: '\0-\x1F\x7F-\x9F\xAD\u0378\u0379\u0380-\u0383\u038B\u038D\u03A2\u0530\u0557\u0558\u0560\u0588\u058B\u058C\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08B5-\u08E2\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0AF8\u0AFA-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0BFF\u0C04\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D00\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5E\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F6\u13F7\u13FE\u13FF\u169D-\u169F\u16F9-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180E\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE\u1AAF\u1ABF-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7\u1CFA-\u1CFF\u1DF6-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BF-\u20CF\u20F1-\u20FF\u218C-\u218F\u23FB-\u23FF\u2427-\u243F\u244B-\u245F\u2B74\u2B75\u2B96\u2B97\u2BBA-\u2BBC\u2BC9\u2BD2-\u2BEB\u2BF0-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E43-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FD6-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA6F8-\uA6FF\uA7AE\uA7AF\uA7B8-\uA7F6\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FE\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB66-\uAB6F\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF', + astral: '\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDD73-\uDD7A\uDDE9-\uDDFF\uDE46-\uDEFF\uDF57-\uDF5F\uDF72-\uDFFF]|\uD836[\uDE8C-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCC0\uDCD0\uDCF6-\uDCFF\uDD0D-\uDD0F\uDD2F\uDD6C-\uDD6F\uDD9B-\uDDE5\uDE03-\uDE0F\uDE3B-\uDE3F\uDE49-\uDE4F\uDE52-\uDEFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDE6D\uDE70-\uDECF\uDEEE\uDEEF\uDEF6-\uDEFF\uDF46-\uDF4F\uDF5A\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD809[\uDC6F\uDC75-\uDC7F\uDD44-\uDFFF]|\uD81B[\uDC00-\uDEFF\uDF45-\uDF4F\uDF7F-\uDF8E\uDFA0-\uDFFF]|\uD86E[\uDC1E\uDC1F]|\uD83D[\uDD7A\uDDA4\uDED1-\uDEDF\uDEED-\uDEEF\uDEF4-\uDEFF\uDF74-\uDF7F\uDFD5-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCFF\uDD28-\uDD2F\uDD64-\uDD6E\uDD70-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8D-\uDD8F\uDD9C-\uDD9F\uDDA1-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEFC-\uDEFF\uDF24-\uDF2F\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD869[\uDED7-\uDEFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC70-\uDC7E\uDCBD\uDCC2-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD44-\uDD4F\uDD77-\uDD7F\uDDCE\uDDCF\uDDE0\uDDF5-\uDDFF\uDE12\uDE3E-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEAA-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF3B\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD83A[\uDCC5\uDCC6\uDCD7-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD86D[\uDF35-\uDF3F]|[\uD807\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD81C-\uD82B\uD82D\uD82E\uD830-\uD833\uD837-\uD839\uD83F\uD874-\uD87D\uD87F-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD806[\uDC00-\uDC9F\uDCF3-\uDCFE\uDD00-\uDEBF\uDEF9-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCF9\uDD00-\uDE5F\uDE7F-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD805[\uDC00-\uDC7F\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDDE-\uDDFF\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB8-\uDEBF\uDECA-\uDEFF\uDF1A-\uDF1C\uDF2C-\uDF2F\uDF40-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC9F-\uDCA6\uDCB0-\uDCDF\uDCF3\uDCF6-\uDCFA\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBB\uDDD0\uDDD1\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE34-\uDE37\uDE3B-\uDE3E\uDE48-\uDE4F\uDE59-\uDE5F\uDEA0-\uDEBF\uDEE7-\uDEEA\uDEF7-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF92-\uDF98\uDF9D-\uDFA8\uDFB0-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A\uDC9B\uDCA0-\uDFFF]|\uD82C[\uDC02-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE-\uDD0F\uDD19-\uDD7F\uDD85-\uDDBF\uDDC1-\uDFFF]|\uD873[\uDEA2-\uDFFF]' + }, + { + name: 'Cc', + alias: 'Control', + bmp: '\0-\x1F\x7F-\x9F' + }, + { + name: 'Cf', + alias: 'Format', + bmp: '\xAD\u0600-\u0605\u061C\u06DD\u070F\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB', + astral: '\uDB40[\uDC01\uDC20-\uDC7F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uD804\uDCBD' + }, + { + name: 'Cn', + alias: 'Unassigned', + bmp: '\u0378\u0379\u0380-\u0383\u038B\u038D\u03A2\u0530\u0557\u0558\u0560\u0588\u058B\u058C\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u05FF\u061D\u070E\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08B5-\u08E2\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0AF8\u0AFA-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0BFF\u0C04\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D00\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5E\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F6\u13F7\u13FE\u13FF\u169D-\u169F\u16F9-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE\u1AAF\u1ABF-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7\u1CFA-\u1CFF\u1DF6-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u2065\u2072\u2073\u208F\u209D-\u209F\u20BF-\u20CF\u20F1-\u20FF\u218C-\u218F\u23FB-\u23FF\u2427-\u243F\u244B-\u245F\u2B74\u2B75\u2B96\u2B97\u2BBA-\u2BBC\u2BC9\u2BD2-\u2BEB\u2BF0-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E43-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FD6-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA6F8-\uA6FF\uA7AE\uA7AF\uA7B8-\uA7F6\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FE\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB66-\uAB6F\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD\uFEFE\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFF8\uFFFE\uFFFF', + astral: '\uDB40[\uDC00\uDC02-\uDC1F\uDC80-\uDCFF\uDDF0-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDDE9-\uDDFF\uDE46-\uDEFF\uDF57-\uDF5F\uDF72-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCC0\uDCD0\uDCF6-\uDCFF\uDD0D-\uDD0F\uDD2F\uDD6C-\uDD6F\uDD9B-\uDDE5\uDE03-\uDE0F\uDE3B-\uDE3F\uDE49-\uDE4F\uDE52-\uDEFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDE6D\uDE70-\uDECF\uDEEE\uDEEF\uDEF6-\uDEFF\uDF46-\uDF4F\uDF5A\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD809[\uDC6F\uDC75-\uDC7F\uDD44-\uDFFF]|\uD81B[\uDC00-\uDEFF\uDF45-\uDF4F\uDF7F-\uDF8E\uDFA0-\uDFFF]|\uD86E[\uDC1E\uDC1F]|\uD83D[\uDD7A\uDDA4\uDED1-\uDEDF\uDEED-\uDEEF\uDEF4-\uDEFF\uDF74-\uDF7F\uDFD5-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCFF\uDD28-\uDD2F\uDD64-\uDD6E\uDD70-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8D-\uDD8F\uDD9C-\uDD9F\uDDA1-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEFC-\uDEFF\uDF24-\uDF2F\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD869[\uDED7-\uDEFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|[\uDBBF\uDBFF][\uDFFE\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A\uDC9B\uDCA4-\uDFFF]|\uD83A[\uDCC5\uDCC6\uDCD7-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD86D[\uDF35-\uDF3F]|[\uD807\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD81C-\uD82B\uD82D\uD82E\uD830-\uD833\uD837-\uD839\uD83F\uD874-\uD87D\uD87F-\uDB3F\uDB41-\uDB7F][\uDC00-\uDFFF]|\uD806[\uDC00-\uDC9F\uDCF3-\uDCFE\uDD00-\uDEBF\uDEF9-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCF9\uDD00-\uDE5F\uDE7F-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD836[\uDE8C-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD805[\uDC00-\uDC7F\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDDE-\uDDFF\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB8-\uDEBF\uDECA-\uDEFF\uDF1A-\uDF1C\uDF2C-\uDF2F\uDF40-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC9F-\uDCA6\uDCB0-\uDCDF\uDCF3\uDCF6-\uDCFA\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBB\uDDD0\uDDD1\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE34-\uDE37\uDE3B-\uDE3E\uDE48-\uDE4F\uDE59-\uDE5F\uDEA0-\uDEBF\uDEE7-\uDEEA\uDEF7-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF92-\uDF98\uDF9D-\uDFA8\uDFB0-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC70-\uDC7E\uDCC2-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD44-\uDD4F\uDD77-\uDD7F\uDDCE\uDDCF\uDDE0\uDDF5-\uDDFF\uDE12\uDE3E-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEAA-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF3B\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD82C[\uDC02-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE-\uDD0F\uDD19-\uDD7F\uDD85-\uDDBF\uDDC1-\uDFFF]|\uD873[\uDEA2-\uDFFF]' + }, + { + name: 'Co', + alias: 'Private_Use', + bmp: '\uE000-\uF8FF', + astral: '[\uDB80-\uDBBE\uDBC0-\uDBFE][\uDC00-\uDFFF]|[\uDBBF\uDBFF][\uDC00-\uDFFD]' + }, + { + name: 'Cs', + alias: 'Surrogate', + bmp: '\uD800-\uDFFF' + }, + { + name: 'L', + alias: 'Letter', + bmp: 'A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC', + astral: '\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD83A[\uDC00-\uDCC4]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD80D[\uDC00-\uDC2E]|\uD87E[\uDC00-\uDE1D]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD809[\uDC80-\uDD43]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD808[\uDC00-\uDF99]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD811[\uDC00-\uDE46]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD82C[\uDC00\uDC01]|\uD873[\uDC00-\uDEA1]' + }, + { + name: 'Ll', + alias: 'Lowercase_Letter', + bmp: 'a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A', + astral: '\uD803[\uDCC0-\uDCF2]|\uD835[\uDC1A-\uDC33\uDC4E-\uDC54\uDC56-\uDC67\uDC82-\uDC9B\uDCB6-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDCEA-\uDD03\uDD1E-\uDD37\uDD52-\uDD6B\uDD86-\uDD9F\uDDBA-\uDDD3\uDDEE-\uDE07\uDE22-\uDE3B\uDE56-\uDE6F\uDE8A-\uDEA5\uDEC2-\uDEDA\uDEDC-\uDEE1\uDEFC-\uDF14\uDF16-\uDF1B\uDF36-\uDF4E\uDF50-\uDF55\uDF70-\uDF88\uDF8A-\uDF8F\uDFAA-\uDFC2\uDFC4-\uDFC9\uDFCB]|\uD801[\uDC28-\uDC4F]|\uD806[\uDCC0-\uDCDF]' + }, + { + name: 'Lm', + alias: 'Modifier_Letter', + bmp: '\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5\u06E6\u07F4\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C\uA69D\uA717-\uA71F\uA770\uA788\uA7F8\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E\uFF9F', + astral: '\uD81A[\uDF40-\uDF43]|\uD81B[\uDF93-\uDF9F]' + }, + { + name: 'Lo', + alias: 'Other_Letter', + bmp: '\xAA\xBA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05F0-\u05F2\u0620-\u063F\u0641-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E45\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10D0-\u10FA\u10FD-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC', + astral: '\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD83A[\uDC00-\uDCC4]|\uD803[\uDC00-\uDC48]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD80D[\uDC00-\uDC2E]|\uD87E[\uDC00-\uDE1D]|\uD81B[\uDF00-\uDF44\uDF50]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCFF\uDEC0-\uDEF8]|\uD809[\uDC80-\uDD43]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD808[\uDC00-\uDF99]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF63-\uDF77\uDF7D-\uDF8F]|\uD801[\uDC50-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD811[\uDC00-\uDE46]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD82C[\uDC00\uDC01]|\uD873[\uDC00-\uDEA1]' + }, + { + name: 'Lt', + alias: 'Titlecase_Letter', + bmp: '\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC' + }, + { + name: 'Lu', + alias: 'Uppercase_Letter', + bmp: 'A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A', + astral: '\uD806[\uDCA0-\uDCBF]|\uD803[\uDC80-\uDCB2]|\uD801[\uDC00-\uDC27]|\uD835[\uDC00-\uDC19\uDC34-\uDC4D\uDC68-\uDC81\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB5\uDCD0-\uDCE9\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD38\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD6C-\uDD85\uDDA0-\uDDB9\uDDD4-\uDDED\uDE08-\uDE21\uDE3C-\uDE55\uDE70-\uDE89\uDEA8-\uDEC0\uDEE2-\uDEFA\uDF1C-\uDF34\uDF56-\uDF6E\uDF90-\uDFA8\uDFCA]' + }, + { + name: 'M', + alias: 'Mark', + bmp: '\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F', + astral: '\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDDDC\uDDDD\uDE30-\uDE40\uDEAB-\uDEB7\uDF1D-\uDF2B]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDDCA-\uDDCC\uDE2C-\uDE37\uDEDF-\uDEEA\uDF00-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD82F[\uDC9D\uDC9E]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]' + }, + { + name: 'Mc', + alias: 'Spacing_Mark', + bmp: '\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E\u094F\u0982\u0983\u09BE-\u09C0\u09C7\u09C8\u09CB\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB\u0ACC\u0B02\u0B03\u0B3E\u0B40\u0B47\u0B48\u0B4B\u0B4C\u0B57\u0BBE\u0BBF\u0BC1\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7\u0CC8\u0CCA\u0CCB\u0CD5\u0CD6\u0D02\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2\u0DF3\u0F3E\u0F3F\u0F7F\u102B\u102C\u1031\u1038\u103B\u103C\u1056\u1057\u1062-\u1064\u1067-\u106D\u1083\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7\u17C8\u1923-\u1926\u1929-\u192B\u1930\u1931\u1933-\u1938\u1A19\u1A1A\u1A55\u1A57\u1A61\u1A63\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43\u1B44\u1B82\u1BA1\u1BA6\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2\u1BF3\u1C24-\u1C2B\u1C34\u1C35\u1CE1\u1CF2\u1CF3\u302E\u302F\uA823\uA824\uA827\uA880\uA881\uA8B4-\uA8C3\uA952\uA953\uA983\uA9B4\uA9B5\uA9BA\uA9BB\uA9BD-\uA9C0\uAA2F\uAA30\uAA33\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE\uAAEF\uAAF5\uABE3\uABE4\uABE6\uABE7\uABE9\uABEA\uABEC', + astral: '\uD834[\uDD65\uDD66\uDD6D-\uDD72]|\uD804[\uDC00\uDC02\uDC82\uDCB0-\uDCB2\uDCB7\uDCB8\uDD2C\uDD82\uDDB3-\uDDB5\uDDBF\uDDC0\uDE2C-\uDE2E\uDE32\uDE33\uDE35\uDEE0-\uDEE2\uDF02\uDF03\uDF3E\uDF3F\uDF41-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63]|\uD805[\uDCB0-\uDCB2\uDCB9\uDCBB-\uDCBE\uDCC1\uDDAF-\uDDB1\uDDB8-\uDDBB\uDDBE\uDE30-\uDE32\uDE3B\uDE3C\uDE3E\uDEAC\uDEAE\uDEAF\uDEB6\uDF20\uDF21\uDF26]|\uD81B[\uDF51-\uDF7E]' + }, + { + name: 'Me', + alias: 'Enclosing_Mark', + bmp: '\u0488\u0489\u1ABE\u20DD-\u20E0\u20E2-\u20E4\uA670-\uA672' + }, + { + name: 'Mn', + alias: 'Nonspacing_Mark', + bmp: '\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2\u09E3\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC\u0CCD\u0CE2\u0CE3\u0D01\u0D41-\u0D44\u0D4D\u0D62\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099\u309A\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F', + astral: '\uD805[\uDCB3-\uDCB8\uDCBA\uDCBF\uDCC0\uDCC2\uDCC3\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD834[\uDD67-\uDD69\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC01\uDC38-\uDC46\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDCA-\uDDCC\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3C\uDF40\uDF66-\uDF6C\uDF70-\uDF74]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]' + }, + { + name: 'N', + alias: 'Number', + bmp: '0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19', + astral: '\uD800[\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDEE1-\uDEFB\uDF20-\uDF23\uDF41\uDF4A\uDFD1-\uDFD5]|\uD801[\uDCA0-\uDCA9]|\uD803[\uDCFA-\uDCFF\uDE60-\uDE7E]|\uD835[\uDFCE-\uDFFF]|\uD83A[\uDCC7-\uDCCF]|\uD81A[\uDE60-\uDE69\uDF50-\uDF59\uDF5B-\uDF61]|\uD806[\uDCE0-\uDCF2]|\uD804[\uDC52-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9\uDDE1-\uDDF4\uDEF0-\uDEF9]|\uD834[\uDF60-\uDF71]|\uD83C[\uDD00-\uDD0C]|\uD809[\uDC00-\uDC6E]|\uD802[\uDC58-\uDC5F\uDC79-\uDC7F\uDCA7-\uDCAF\uDCFB-\uDCFF\uDD16-\uDD1B\uDDBC\uDDBD\uDDC0-\uDDCF\uDDD2-\uDDFF\uDE40-\uDE47\uDE7D\uDE7E\uDE9D-\uDE9F\uDEEB-\uDEEF\uDF58-\uDF5F\uDF78-\uDF7F\uDFA9-\uDFAF]|\uD805[\uDCD0-\uDCD9\uDE50-\uDE59\uDEC0-\uDEC9\uDF30-\uDF3B]' + }, + { + name: 'Nd', + alias: 'Decimal_Number', + bmp: '0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19', + astral: '\uD801[\uDCA0-\uDCA9]|\uD835[\uDFCE-\uDFFF]|\uD805[\uDCD0-\uDCD9\uDE50-\uDE59\uDEC0-\uDEC9\uDF30-\uDF39]|\uD806[\uDCE0-\uDCE9]|\uD804[\uDC66-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9\uDEF0-\uDEF9]|\uD81A[\uDE60-\uDE69\uDF50-\uDF59]' + }, + { + name: 'Nl', + alias: 'Letter_Number', + bmp: '\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF', + astral: '\uD809[\uDC00-\uDC6E]|\uD800[\uDD40-\uDD74\uDF41\uDF4A\uDFD1-\uDFD5]' + }, + { + name: 'No', + alias: 'Other_Number', + bmp: '\xB2\xB3\xB9\xBC-\xBE\u09F4-\u09F9\u0B72-\u0B77\u0BF0-\u0BF2\u0C78-\u0C7E\u0D70-\u0D75\u0F2A-\u0F33\u1369-\u137C\u17F0-\u17F9\u19DA\u2070\u2074-\u2079\u2080-\u2089\u2150-\u215F\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA830-\uA835', + astral: '\uD804[\uDC52-\uDC65\uDDE1-\uDDF4]|\uD803[\uDCFA-\uDCFF\uDE60-\uDE7E]|\uD83C[\uDD00-\uDD0C]|\uD806[\uDCEA-\uDCF2]|\uD83A[\uDCC7-\uDCCF]|\uD802[\uDC58-\uDC5F\uDC79-\uDC7F\uDCA7-\uDCAF\uDCFB-\uDCFF\uDD16-\uDD1B\uDDBC\uDDBD\uDDC0-\uDDCF\uDDD2-\uDDFF\uDE40-\uDE47\uDE7D\uDE7E\uDE9D-\uDE9F\uDEEB-\uDEEF\uDF58-\uDF5F\uDF78-\uDF7F\uDFA9-\uDFAF]|\uD805[\uDF3A\uDF3B]|\uD81A[\uDF5B-\uDF61]|\uD834[\uDF60-\uDF71]|\uD800[\uDD07-\uDD33\uDD75-\uDD78\uDD8A\uDD8B\uDEE1-\uDEFB\uDF20-\uDF23]' + }, + { + name: 'P', + alias: 'Punctuation', + bmp: '\x21-\x23\x25-\\x2A\x2C-\x2F\x3A\x3B\\x3F\x40\\x5B-\\x5D\x5F\\x7B\x7D\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65', + astral: '\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD809[\uDC70-\uDC74]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD836[\uDE87-\uDE8B]|\uD801\uDD6F|\uD82F\uDC9F|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]' + }, + { + name: 'Pc', + alias: 'Connector_Punctuation', + bmp: '\x5F\u203F\u2040\u2054\uFE33\uFE34\uFE4D-\uFE4F\uFF3F' + }, + { + name: 'Pd', + alias: 'Dash_Punctuation', + bmp: '\\x2D\u058A\u05BE\u1400\u1806\u2010-\u2015\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D' + }, + { + name: 'Pe', + alias: 'Close_Punctuation', + bmp: '\\x29\\x5D\x7D\u0F3B\u0F3D\u169C\u2046\u207E\u208E\u2309\u230B\u232A\u2769\u276B\u276D\u276F\u2771\u2773\u2775\u27C6\u27E7\u27E9\u27EB\u27ED\u27EF\u2984\u2986\u2988\u298A\u298C\u298E\u2990\u2992\u2994\u2996\u2998\u29D9\u29DB\u29FD\u2E23\u2E25\u2E27\u2E29\u3009\u300B\u300D\u300F\u3011\u3015\u3017\u3019\u301B\u301E\u301F\uFD3E\uFE18\uFE36\uFE38\uFE3A\uFE3C\uFE3E\uFE40\uFE42\uFE44\uFE48\uFE5A\uFE5C\uFE5E\uFF09\uFF3D\uFF5D\uFF60\uFF63' + }, + { + name: 'Pf', + alias: 'Final_Punctuation', + bmp: '\xBB\u2019\u201D\u203A\u2E03\u2E05\u2E0A\u2E0D\u2E1D\u2E21' + }, + { + name: 'Pi', + alias: 'Initial_Punctuation', + bmp: '\xAB\u2018\u201B\u201C\u201F\u2039\u2E02\u2E04\u2E09\u2E0C\u2E1C\u2E20' + }, + { + name: 'Po', + alias: 'Other_Punctuation', + bmp: '\x21-\x23\x25-\x27\\x2A\x2C\\x2E\x2F\x3A\x3B\\x3F\x40\\x5C\xA1\xA7\xB6\xB7\xBF\u037E\u0387\u055A-\u055F\u0589\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u166D\u166E\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u1805\u1807-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2016\u2017\u2020-\u2027\u2030-\u2038\u203B-\u203E\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205E\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00\u2E01\u2E06-\u2E08\u2E0B\u2E0E-\u2E16\u2E18\u2E19\u2E1B\u2E1E\u2E1F\u2E2A-\u2E2E\u2E30-\u2E39\u2E3C-\u2E3F\u2E41\u3001-\u3003\u303D\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFE10-\uFE16\uFE19\uFE30\uFE45\uFE46\uFE49-\uFE4C\uFE50-\uFE52\uFE54-\uFE57\uFE5F-\uFE61\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF07\uFF0A\uFF0C\uFF0E\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3C\uFF61\uFF64\uFF65', + astral: '\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD809[\uDC70-\uDC74]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD836[\uDE87-\uDE8B]|\uD801\uDD6F|\uD82F\uDC9F|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]' + }, + { + name: 'Ps', + alias: 'Open_Punctuation', + bmp: '\\x28\\x5B\\x7B\u0F3A\u0F3C\u169B\u201A\u201E\u2045\u207D\u208D\u2308\u230A\u2329\u2768\u276A\u276C\u276E\u2770\u2772\u2774\u27C5\u27E6\u27E8\u27EA\u27EC\u27EE\u2983\u2985\u2987\u2989\u298B\u298D\u298F\u2991\u2993\u2995\u2997\u29D8\u29DA\u29FC\u2E22\u2E24\u2E26\u2E28\u2E42\u3008\u300A\u300C\u300E\u3010\u3014\u3016\u3018\u301A\u301D\uFD3F\uFE17\uFE35\uFE37\uFE39\uFE3B\uFE3D\uFE3F\uFE41\uFE43\uFE47\uFE59\uFE5B\uFE5D\uFF08\uFF3B\uFF5B\uFF5F\uFF62' + }, + { + name: 'S', + alias: 'Symbol', + bmp: '\\x24\\x2B\x3C-\x3E\\x5E\x60\\x7C\x7E\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20BE\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u23FA\u2400-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B98-\u2BB9\u2BBD-\u2BC8\u2BCA-\u2BD1\u2BEC-\u2BEF\u2CE5-\u2CEA\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u32FE\u3300-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uFB29\uFBB2-\uFBC1\uFDFC\uFDFD\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD', + astral: '\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDD10-\uDD18\uDD80-\uDD84\uDDC0]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD10-\uDD2E\uDD30-\uDD6B\uDD70-\uDD9A\uDDE6-\uDE02\uDE10-\uDE3A\uDE40-\uDE48\uDE50\uDE51\uDF00-\uDFFF]|\uD83D[\uDC00-\uDD79\uDD7B-\uDDA3\uDDA5-\uDED0\uDEE0-\uDEEC\uDEF0-\uDEF3\uDF00-\uDF73\uDF80-\uDFD4]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C\uDD90-\uDD9B\uDDA0\uDDD0-\uDDFC]|\uD82F\uDC9C|\uD805\uDF3F|\uD802[\uDC77\uDC78\uDEC8]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD83B[\uDEF0\uDEF1]' + }, + { + name: 'Sc', + alias: 'Currency_Symbol', + bmp: '\\x24\xA2-\xA5\u058F\u060B\u09F2\u09F3\u09FB\u0AF1\u0BF9\u0E3F\u17DB\u20A0-\u20BE\uA838\uFDFC\uFE69\uFF04\uFFE0\uFFE1\uFFE5\uFFE6' + }, + { + name: 'Sk', + alias: 'Modifier_Symbol', + bmp: '\\x5E\x60\xA8\xAF\xB4\xB8\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u309B\u309C\uA700-\uA716\uA720\uA721\uA789\uA78A\uAB5B\uFBB2-\uFBC1\uFF3E\uFF40\uFFE3', + astral: '\uD83C[\uDFFB-\uDFFF]' + }, + { + name: 'Sm', + alias: 'Math_Symbol', + bmp: '\\x2B\x3C-\x3E\\x7C\x7E\xAC\xB1\xD7\xF7\u03F6\u0606-\u0608\u2044\u2052\u207A-\u207C\u208A-\u208C\u2118\u2140-\u2144\u214B\u2190-\u2194\u219A\u219B\u21A0\u21A3\u21A6\u21AE\u21CE\u21CF\u21D2\u21D4\u21F4-\u22FF\u2320\u2321\u237C\u239B-\u23B3\u23DC-\u23E1\u25B7\u25C1\u25F8-\u25FF\u266F\u27C0-\u27C4\u27C7-\u27E5\u27F0-\u27FF\u2900-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2AFF\u2B30-\u2B44\u2B47-\u2B4C\uFB29\uFE62\uFE64-\uFE66\uFF0B\uFF1C-\uFF1E\uFF5C\uFF5E\uFFE2\uFFE9-\uFFEC', + astral: '\uD83B[\uDEF0\uDEF1]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]' + }, + { + name: 'So', + alias: 'Other_Symbol', + bmp: '\xA6\xA9\xAE\xB0\u0482\u058D\u058E\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u09FA\u0B70\u0BF3-\u0BF8\u0BFA\u0C7F\u0D79\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116\u2117\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u214A\u214C\u214D\u214F\u218A\u218B\u2195-\u2199\u219C-\u219F\u21A1\u21A2\u21A4\u21A5\u21A7-\u21AD\u21AF-\u21CD\u21D0\u21D1\u21D3\u21D5-\u21F3\u2300-\u2307\u230C-\u231F\u2322-\u2328\u232B-\u237B\u237D-\u239A\u23B4-\u23DB\u23E2-\u23FA\u2400-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u25B6\u25B8-\u25C0\u25C2-\u25F7\u2600-\u266E\u2670-\u2767\u2794-\u27BF\u2800-\u28FF\u2B00-\u2B2F\u2B45\u2B46\u2B4D-\u2B73\u2B76-\u2B95\u2B98-\u2BB9\u2BBD-\u2BC8\u2BCA-\u2BD1\u2BEC-\u2BEF\u2CE5-\u2CEA\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u32FE\u3300-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA828-\uA82B\uA836\uA837\uA839\uAA77-\uAA79\uFDFD\uFFE4\uFFE8\uFFED\uFFEE\uFFFC\uFFFD', + astral: '\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDD10-\uDD18\uDD80-\uDD84\uDDC0]|\uD83D[\uDC00-\uDD79\uDD7B-\uDDA3\uDDA5-\uDED0\uDEE0-\uDEEC\uDEF0-\uDEF3\uDF00-\uDF73\uDF80-\uDFD4]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD10-\uDD2E\uDD30-\uDD6B\uDD70-\uDD9A\uDDE6-\uDE02\uDE10-\uDE3A\uDE40-\uDE48\uDE50\uDE51\uDF00-\uDFFA]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C\uDD90-\uDD9B\uDDA0\uDDD0-\uDDFC]|\uD82F\uDC9C|\uD805\uDF3F|\uD802[\uDC77\uDC78\uDEC8]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDE00-\uDE41\uDE45\uDF00-\uDF56]' + }, + { + name: 'Z', + alias: 'Separator', + bmp: '\x20\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000' + }, + { + name: 'Zl', + alias: 'Line_Separator', + bmp: '\u2028' + }, + { + name: 'Zp', + alias: 'Paragraph_Separator', + bmp: '\u2029' + }, + { + name: 'Zs', + alias: 'Space_Separator', + bmp: '\x20\xA0\u1680\u2000-\u200A\u202F\u205F\u3000' + } + ]); + +}; + +/*! + * XRegExp Unicode Properties 3.1.0 + * + * Steven Levithan (c) 2012-2016 MIT License + * Unicode data by Mathias Bynens + */ + +/** + * Adds properties to meet the UTS #18 Level 1 RL1.2 requirements for Unicode regex support. See + * . Following are definitions of these properties from UAX + * #44 : + * + * - Alphabetic + * Characters with the Alphabetic property. Generated from: Lowercase + Uppercase + Lt + Lm + Lo + + * Nl + Other_Alphabetic. + * + * - Default_Ignorable_Code_Point + * For programmatic determination of default ignorable code points. New characters that should be + * ignored in rendering (unless explicitly supported) will be assigned in these ranges, permitting + * programs to correctly handle the default rendering of such characters when not otherwise + * supported. + * + * - Lowercase + * Characters with the Lowercase property. Generated from: Ll + Other_Lowercase. + * + * - Noncharacter_Code_Point + * Code points permanently reserved for internal use. + * + * - Uppercase + * Characters with the Uppercase property. Generated from: Lu + Other_Uppercase. + * + * - White_Space + * Spaces, separator characters and other control characters which should be treated by + * programming languages as "white space" for the purpose of parsing elements. + * + * The properties ASCII, Any, and Assigned are also included but are not defined in UAX #44. UTS #18 + * RL1.2 additionally requires support for Unicode scripts and general categories. These are + * included in XRegExp's Unicode Categories and Unicode Scripts addons. + * + * Token names are case insensitive, and any spaces, hyphens, and underscores are ignored. + * + * Uses Unicode 8.0.0. + * + * @requires XRegExp, Unicode Base + */ +var unicodeProperties = function(XRegExp) { + + if (!XRegExp.addUnicodeData) { + throw new ReferenceError('Unicode Base must be loaded before Unicode Properties'); + } + + var unicodeData = [ + { + name: 'ASCII', + bmp: '\0-\x7F' + }, + { + name: 'Alphabetic', + bmp: 'A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0345\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05B0-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0657\u0659-\u065F\u066E-\u06D3\u06D5-\u06DC\u06E1-\u06E8\u06ED-\u06EF\u06FA-\u06FC\u06FF\u0710-\u073F\u074D-\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0817\u081A-\u082C\u0840-\u0858\u08A0-\u08B4\u08E3-\u08E9\u08F0-\u093B\u093D-\u094C\u094E-\u0950\u0955-\u0963\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD-\u09C4\u09C7\u09C8\u09CB\u09CC\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09F0\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3E-\u0A42\u0A47\u0A48\u0A4B\u0A4C\u0A51\u0A59-\u0A5C\u0A5E\u0A70-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD-\u0AC5\u0AC7-\u0AC9\u0ACB\u0ACC\u0AD0\u0AE0-\u0AE3\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D-\u0B44\u0B47\u0B48\u0B4B\u0B4C\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD0\u0BD7\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4C\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCC\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4C\u0D4E\u0D57\u0D5F-\u0D63\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E46\u0E4D\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0ECD\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F71-\u0F81\u0F88-\u0F97\u0F99-\u0FBC\u1000-\u1036\u1038\u103B-\u103F\u1050-\u1062\u1065-\u1068\u106E-\u1086\u108E\u109C\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1713\u1720-\u1733\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17B3\u17B6-\u17C8\u17D7\u17DC\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u1938\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A1B\u1A20-\u1A5E\u1A61-\u1A74\u1AA7\u1B00-\u1B33\u1B35-\u1B43\u1B45-\u1B4B\u1B80-\u1BA9\u1BAC-\u1BAF\u1BBA-\u1BE5\u1BE7-\u1BF1\u1C00-\u1C35\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1D00-\u1DBF\u1DE7-\u1DF4\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u24B6-\u24E9\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA674-\uA67B\uA67F-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA827\uA840-\uA873\uA880-\uA8C3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA92A\uA930-\uA952\uA960-\uA97C\uA980-\uA9B2\uA9B4-\uA9BF\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA60-\uAA76\uAA7A\uAA7E-\uAABE\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF5\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC', + astral: '\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD804[\uDC00-\uDC45\uDC82-\uDCB8\uDCD0-\uDCE8\uDD00-\uDD32\uDD50-\uDD72\uDD76\uDD80-\uDDBF\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE34\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEE8\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D-\uDF44\uDF47\uDF48\uDF4B\uDF4C\uDF50\uDF57\uDF5D-\uDF63]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD83A[\uDC00-\uDCC4]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF36\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD83C[\uDD30-\uDD49\uDD50-\uDD69\uDD70-\uDD89]|\uD80D[\uDC00-\uDC2E]|\uD87E[\uDC00-\uDE1D]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9E]|\uD808[\uDC00-\uDF99]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD805[\uDC80-\uDCC1\uDCC4\uDCC5\uDCC7\uDD80-\uDDB5\uDDB8-\uDDBE\uDDD8-\uDDDD\uDE00-\uDE3E\uDE40\uDE44\uDE80-\uDEB5\uDF00-\uDF19\uDF1D-\uDF2A]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD811[\uDC00-\uDE46]|\uD82C[\uDC00\uDC01]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF93-\uDF9F]|\uD873[\uDC00-\uDEA1]' + }, + { + name: 'Any', + isBmpLast: true, + bmp: '\0-\uFFFF', + astral: '[\uD800-\uDBFF][\uDC00-\uDFFF]' + }, + { + name: 'Default_Ignorable_Code_Point', + bmp: '\xAD\u034F\u061C\u115F\u1160\u17B4\u17B5\u180B-\u180E\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8', + astral: '[\uDB40-\uDB43][\uDC00-\uDFFF]|\uD834[\uDD73-\uDD7A]|\uD82F[\uDCA0-\uDCA3]' + }, + { + name: 'Lowercase', + bmp: 'a-z\xAA\xB5\xBA\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02B8\u02C0\u02C1\u02E0-\u02E4\u0345\u0371\u0373\u0377\u037A-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1DBF\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u2071\u207F\u2090-\u209C\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2170-\u217F\u2184\u24D0-\u24E9\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7D\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B-\uA69D\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7F8-\uA7FA\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A', + astral: '\uD803[\uDCC0-\uDCF2]|\uD835[\uDC1A-\uDC33\uDC4E-\uDC54\uDC56-\uDC67\uDC82-\uDC9B\uDCB6-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDCEA-\uDD03\uDD1E-\uDD37\uDD52-\uDD6B\uDD86-\uDD9F\uDDBA-\uDDD3\uDDEE-\uDE07\uDE22-\uDE3B\uDE56-\uDE6F\uDE8A-\uDEA5\uDEC2-\uDEDA\uDEDC-\uDEE1\uDEFC-\uDF14\uDF16-\uDF1B\uDF36-\uDF4E\uDF50-\uDF55\uDF70-\uDF88\uDF8A-\uDF8F\uDFAA-\uDFC2\uDFC4-\uDFC9\uDFCB]|\uD801[\uDC28-\uDC4F]|\uD806[\uDCC0-\uDCDF]' + }, + { + name: 'Noncharacter_Code_Point', + bmp: '\uFDD0-\uFDEF\uFFFE\uFFFF', + astral: '[\uDB3F\uDB7F\uDBBF\uDBFF\uD83F\uD87F\uD8BF\uDAFF\uD97F\uD9BF\uD9FF\uDA3F\uD8FF\uDABF\uDA7F\uD93F][\uDFFE\uDFFF]' + }, + { + name: 'Uppercase', + bmp: 'A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2160-\u216F\u2183\u24B6-\u24CF\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A', + astral: '\uD806[\uDCA0-\uDCBF]|\uD803[\uDC80-\uDCB2]|\uD835[\uDC00-\uDC19\uDC34-\uDC4D\uDC68-\uDC81\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB5\uDCD0-\uDCE9\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD38\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD6C-\uDD85\uDDA0-\uDDB9\uDDD4-\uDDED\uDE08-\uDE21\uDE3C-\uDE55\uDE70-\uDE89\uDEA8-\uDEC0\uDEE2-\uDEFA\uDF1C-\uDF34\uDF56-\uDF6E\uDF90-\uDFA8\uDFCA]|\uD801[\uDC00-\uDC27]|\uD83C[\uDD30-\uDD49\uDD50-\uDD69\uDD70-\uDD89]' + }, + { + name: 'White_Space', + bmp: '\x09-\x0D\x20\x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000' + } + ]; + + // Add non-generated data + unicodeData.push({ + name: 'Assigned', + // Since this is defined as the inverse of Unicode category Cn (Unassigned), the Unicode + // Categories addon is required to use this property + inverseOf: 'Cn' + }); + + XRegExp.addUnicodeData(unicodeData); + +}; + +/*! + * XRegExp Unicode Scripts 3.1.0 + * + * Steven Levithan (c) 2010-2016 MIT License + * Unicode data by Mathias Bynens + */ + +/** + * Adds support for all Unicode scripts. E.g., `\p{Latin}`. Token names are case insensitive, and + * any spaces, hyphens, and underscores are ignored. + * + * Uses Unicode 8.0.0. + * + * @requires XRegExp, Unicode Base + */ +var unicodeScripts = function(XRegExp) { + + if (!XRegExp.addUnicodeData) { + throw new ReferenceError('Unicode Base must be loaded before Unicode Scripts'); + } + + XRegExp.addUnicodeData([ + { + name: 'Ahom', + astral: '\uD805[\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF3F]' + }, + { + name: 'Anatolian_Hieroglyphs', + astral: '\uD811[\uDC00-\uDE46]' + }, + { + name: 'Arabic', + bmp: '\u0600-\u0604\u0606-\u060B\u060D-\u061A\u061E\u0620-\u063F\u0641-\u064A\u0656-\u066F\u0671-\u06DC\u06DE-\u06FF\u0750-\u077F\u08A0-\u08B4\u08E3-\u08FF\uFB50-\uFBC1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFD\uFE70-\uFE74\uFE76-\uFEFC', + astral: '\uD803[\uDE60-\uDE7E]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB\uDEF0\uDEF1]' + }, + { + name: 'Armenian', + bmp: '\u0531-\u0556\u0559-\u055F\u0561-\u0587\u058A\u058D-\u058F\uFB13-\uFB17' + }, + { + name: 'Avestan', + astral: '\uD802[\uDF00-\uDF35\uDF39-\uDF3F]' + }, + { + name: 'Balinese', + bmp: '\u1B00-\u1B4B\u1B50-\u1B7C' + }, + { + name: 'Bamum', + bmp: '\uA6A0-\uA6F7', + astral: '\uD81A[\uDC00-\uDE38]' + }, + { + name: 'Bassa_Vah', + astral: '\uD81A[\uDED0-\uDEED\uDEF0-\uDEF5]' + }, + { + name: 'Batak', + bmp: '\u1BC0-\u1BF3\u1BFC-\u1BFF' + }, + { + name: 'Bengali', + bmp: '\u0980-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09FB' + }, + { + name: 'Bopomofo', + bmp: '\u02EA\u02EB\u3105-\u312D\u31A0-\u31BA' + }, + { + name: 'Brahmi', + astral: '\uD804[\uDC00-\uDC4D\uDC52-\uDC6F\uDC7F]' + }, + { + name: 'Braille', + bmp: '\u2800-\u28FF' + }, + { + name: 'Buginese', + bmp: '\u1A00-\u1A1B\u1A1E\u1A1F' + }, + { + name: 'Buhid', + bmp: '\u1740-\u1753' + }, + { + name: 'Canadian_Aboriginal', + bmp: '\u1400-\u167F\u18B0-\u18F5' + }, + { + name: 'Carian', + astral: '\uD800[\uDEA0-\uDED0]' + }, + { + name: 'Caucasian_Albanian', + astral: '\uD801[\uDD30-\uDD63\uDD6F]' + }, + { + name: 'Chakma', + astral: '\uD804[\uDD00-\uDD34\uDD36-\uDD43]' + }, + { + name: 'Cham', + bmp: '\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA5C-\uAA5F' + }, + { + name: 'Cherokee', + bmp: '\u13A0-\u13F5\u13F8-\u13FD\uAB70-\uABBF' + }, + { + name: 'Common', + bmp: '\0-\x40\\x5B-\x60\\x7B-\xA9\xAB-\xB9\xBB-\xBF\xD7\xF7\u02B9-\u02DF\u02E5-\u02E9\u02EC-\u02FF\u0374\u037E\u0385\u0387\u0589\u0605\u060C\u061B\u061C\u061F\u0640\u06DD\u0964\u0965\u0E3F\u0FD5-\u0FD8\u10FB\u16EB-\u16ED\u1735\u1736\u1802\u1803\u1805\u1CD3\u1CE1\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u2000-\u200B\u200E-\u2064\u2066-\u2070\u2074-\u207E\u2080-\u208E\u20A0-\u20BE\u2100-\u2125\u2127-\u2129\u212C-\u2131\u2133-\u214D\u214F-\u215F\u2189-\u218B\u2190-\u23FA\u2400-\u2426\u2440-\u244A\u2460-\u27FF\u2900-\u2B73\u2B76-\u2B95\u2B98-\u2BB9\u2BBD-\u2BC8\u2BCA-\u2BD1\u2BEC-\u2BEF\u2E00-\u2E42\u2FF0-\u2FFB\u3000-\u3004\u3006\u3008-\u3020\u3030-\u3037\u303C-\u303F\u309B\u309C\u30A0\u30FB\u30FC\u3190-\u319F\u31C0-\u31E3\u3220-\u325F\u327F-\u32CF\u3358-\u33FF\u4DC0-\u4DFF\uA700-\uA721\uA788-\uA78A\uA830-\uA839\uA92E\uA9CF\uAB5B\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFEFF\uFF01-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFF70\uFF9E\uFF9F\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFF9-\uFFFD', + astral: '\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDD10-\uDD18\uDD80-\uDD84\uDDC0]|\uD82F[\uDCA0-\uDCA3]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDFCB\uDFCE-\uDFFF]|\uDB40[\uDC01\uDC20-\uDC7F]|\uD83D[\uDC00-\uDD79\uDD7B-\uDDA3\uDDA5-\uDED0\uDEE0-\uDEEC\uDEF0-\uDEF3\uDF00-\uDF73\uDF80-\uDFD4]|\uD800[\uDD00-\uDD02\uDD07-\uDD33\uDD37-\uDD3F\uDD90-\uDD9B\uDDD0-\uDDFC\uDEE1-\uDEFB]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD66\uDD6A-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDF00-\uDF56\uDF60-\uDF71]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD00-\uDD0C\uDD10-\uDD2E\uDD30-\uDD6B\uDD70-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE10-\uDE3A\uDE40-\uDE48\uDE50\uDE51\uDF00-\uDFFF]' + }, + { + name: 'Coptic', + bmp: '\u03E2-\u03EF\u2C80-\u2CF3\u2CF9-\u2CFF' + }, + { + name: 'Cuneiform', + astral: '\uD809[\uDC00-\uDC6E\uDC70-\uDC74\uDC80-\uDD43]|\uD808[\uDC00-\uDF99]' + }, + { + name: 'Cypriot', + astral: '\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F]' + }, + { + name: 'Cyrillic', + bmp: '\u0400-\u0484\u0487-\u052F\u1D2B\u1D78\u2DE0-\u2DFF\uA640-\uA69F\uFE2E\uFE2F' + }, + { + name: 'Deseret', + astral: '\uD801[\uDC00-\uDC4F]' + }, + { + name: 'Devanagari', + bmp: '\u0900-\u0950\u0953-\u0963\u0966-\u097F\uA8E0-\uA8FD' + }, + { + name: 'Duployan', + astral: '\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9C-\uDC9F]' + }, + { + name: 'Egyptian_Hieroglyphs', + astral: '\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]' + }, + { + name: 'Elbasan', + astral: '\uD801[\uDD00-\uDD27]' + }, + { + name: 'Ethiopic', + bmp: '\u1200-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u137C\u1380-\u1399\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E' + }, + { + name: 'Georgian', + bmp: '\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u10FF\u2D00-\u2D25\u2D27\u2D2D' + }, + { + name: 'Glagolitic', + bmp: '\u2C00-\u2C2E\u2C30-\u2C5E' + }, + { + name: 'Gothic', + astral: '\uD800[\uDF30-\uDF4A]' + }, + { + name: 'Grantha', + astral: '\uD804[\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]' + }, + { + name: 'Greek', + bmp: '\u0370-\u0373\u0375-\u0377\u037A-\u037D\u037F\u0384\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03E1\u03F0-\u03FF\u1D26-\u1D2A\u1D5D-\u1D61\u1D66-\u1D6A\u1DBF\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FC4\u1FC6-\u1FD3\u1FD6-\u1FDB\u1FDD-\u1FEF\u1FF2-\u1FF4\u1FF6-\u1FFE\u2126\uAB65', + astral: '\uD800[\uDD40-\uDD8C\uDDA0]|\uD834[\uDE00-\uDE45]' + }, + { + name: 'Gujarati', + bmp: '\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AF1\u0AF9' + }, + { + name: 'Gurmukhi', + bmp: '\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75' + }, + { + name: 'Han', + bmp: '\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FD5\uF900-\uFA6D\uFA70-\uFAD9', + astral: '\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD87E[\uDC00-\uDE1D]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD873[\uDC00-\uDEA1]' + }, + { + name: 'Hangul', + bmp: '\u1100-\u11FF\u302E\u302F\u3131-\u318E\u3200-\u321E\u3260-\u327E\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC' + }, + { + name: 'Hanunoo', + bmp: '\u1720-\u1734' + }, + { + name: 'Hatran', + astral: '\uD802[\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDCFF]' + }, + { + name: 'Hebrew', + bmp: '\u0591-\u05C7\u05D0-\u05EA\u05F0-\u05F4\uFB1D-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFB4F' + }, + { + name: 'Hiragana', + bmp: '\u3041-\u3096\u309D-\u309F', + astral: '\uD82C\uDC01|\uD83C\uDE00' + }, + { + name: 'Imperial_Aramaic', + astral: '\uD802[\uDC40-\uDC55\uDC57-\uDC5F]' + }, + { + name: 'Inherited', + bmp: '\u0300-\u036F\u0485\u0486\u064B-\u0655\u0670\u0951\u0952\u1AB0-\u1ABE\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u200C\u200D\u20D0-\u20F0\u302A-\u302D\u3099\u309A\uFE00-\uFE0F\uFE20-\uFE2D', + astral: '\uD834[\uDD67-\uDD69\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD]|\uD800[\uDDFD\uDEE0]|\uDB40[\uDD00-\uDDEF]' + }, + { + name: 'Inscriptional_Pahlavi', + astral: '\uD802[\uDF60-\uDF72\uDF78-\uDF7F]' + }, + { + name: 'Inscriptional_Parthian', + astral: '\uD802[\uDF40-\uDF55\uDF58-\uDF5F]' + }, + { + name: 'Javanese', + bmp: '\uA980-\uA9CD\uA9D0-\uA9D9\uA9DE\uA9DF' + }, + { + name: 'Kaithi', + astral: '\uD804[\uDC80-\uDCC1]' + }, + { + name: 'Kannada', + bmp: '\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2' + }, + { + name: 'Katakana', + bmp: '\u30A1-\u30FA\u30FD-\u30FF\u31F0-\u31FF\u32D0-\u32FE\u3300-\u3357\uFF66-\uFF6F\uFF71-\uFF9D', + astral: '\uD82C\uDC00' + }, + { + name: 'Kayah_Li', + bmp: '\uA900-\uA92D\uA92F' + }, + { + name: 'Kharoshthi', + astral: '\uD802[\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F-\uDE47\uDE50-\uDE58]' + }, + { + name: 'Khmer', + bmp: '\u1780-\u17DD\u17E0-\u17E9\u17F0-\u17F9\u19E0-\u19FF' + }, + { + name: 'Khojki', + astral: '\uD804[\uDE00-\uDE11\uDE13-\uDE3D]' + }, + { + name: 'Khudawadi', + astral: '\uD804[\uDEB0-\uDEEA\uDEF0-\uDEF9]' + }, + { + name: 'Lao', + bmp: '\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF' + }, + { + name: 'Latin', + bmp: 'A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A' + }, + { + name: 'Lepcha', + bmp: '\u1C00-\u1C37\u1C3B-\u1C49\u1C4D-\u1C4F' + }, + { + name: 'Limbu', + bmp: '\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1940\u1944-\u194F' + }, + { + name: 'Linear_A', + astral: '\uD801[\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]' + }, + { + name: 'Linear_B', + astral: '\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA]' + }, + { + name: 'Lisu', + bmp: '\uA4D0-\uA4FF' + }, + { + name: 'Lycian', + astral: '\uD800[\uDE80-\uDE9C]' + }, + { + name: 'Lydian', + astral: '\uD802[\uDD20-\uDD39\uDD3F]' + }, + { + name: 'Mahajani', + astral: '\uD804[\uDD50-\uDD76]' + }, + { + name: 'Malayalam', + bmp: '\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D75\u0D79-\u0D7F' + }, + { + name: 'Mandaic', + bmp: '\u0840-\u085B\u085E' + }, + { + name: 'Manichaean', + astral: '\uD802[\uDEC0-\uDEE6\uDEEB-\uDEF6]' + }, + { + name: 'Meetei_Mayek', + bmp: '\uAAE0-\uAAF6\uABC0-\uABED\uABF0-\uABF9' + }, + { + name: 'Mende_Kikakui', + astral: '\uD83A[\uDC00-\uDCC4\uDCC7-\uDCD6]' + }, + { + name: 'Meroitic_Cursive', + astral: '\uD802[\uDDA0-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDDFF]' + }, + { + name: 'Meroitic_Hieroglyphs', + astral: '\uD802[\uDD80-\uDD9F]' + }, + { + name: 'Miao', + astral: '\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]' + }, + { + name: 'Modi', + astral: '\uD805[\uDE00-\uDE44\uDE50-\uDE59]' + }, + { + name: 'Mongolian', + bmp: '\u1800\u1801\u1804\u1806-\u180E\u1810-\u1819\u1820-\u1877\u1880-\u18AA' + }, + { + name: 'Mro', + astral: '\uD81A[\uDE40-\uDE5E\uDE60-\uDE69\uDE6E\uDE6F]' + }, + { + name: 'Multani', + astral: '\uD804[\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA9]' + }, + { + name: 'Myanmar', + bmp: '\u1000-\u109F\uA9E0-\uA9FE\uAA60-\uAA7F' + }, + { + name: 'Nabataean', + astral: '\uD802[\uDC80-\uDC9E\uDCA7-\uDCAF]' + }, + { + name: 'New_Tai_Lue', + bmp: '\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u19DE\u19DF' + }, + { + name: 'Nko', + bmp: '\u07C0-\u07FA' + }, + { + name: 'Ogham', + bmp: '\u1680-\u169C' + }, + { + name: 'Ol_Chiki', + bmp: '\u1C50-\u1C7F' + }, + { + name: 'Old_Hungarian', + astral: '\uD803[\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDCFF]' + }, + { + name: 'Old_Italic', + astral: '\uD800[\uDF00-\uDF23]' + }, + { + name: 'Old_North_Arabian', + astral: '\uD802[\uDE80-\uDE9F]' + }, + { + name: 'Old_Permic', + astral: '\uD800[\uDF50-\uDF7A]' + }, + { + name: 'Old_Persian', + astral: '\uD800[\uDFA0-\uDFC3\uDFC8-\uDFD5]' + }, + { + name: 'Old_South_Arabian', + astral: '\uD802[\uDE60-\uDE7F]' + }, + { + name: 'Old_Turkic', + astral: '\uD803[\uDC00-\uDC48]' + }, + { + name: 'Oriya', + bmp: '\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B77' + }, + { + name: 'Osmanya', + astral: '\uD801[\uDC80-\uDC9D\uDCA0-\uDCA9]' + }, + { + name: 'Pahawh_Hmong', + astral: '\uD81A[\uDF00-\uDF45\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]' + }, + { + name: 'Palmyrene', + astral: '\uD802[\uDC60-\uDC7F]' + }, + { + name: 'Pau_Cin_Hau', + astral: '\uD806[\uDEC0-\uDEF8]' + }, + { + name: 'Phags_Pa', + bmp: '\uA840-\uA877' + }, + { + name: 'Phoenician', + astral: '\uD802[\uDD00-\uDD1B\uDD1F]' + }, + { + name: 'Psalter_Pahlavi', + astral: '\uD802[\uDF80-\uDF91\uDF99-\uDF9C\uDFA9-\uDFAF]' + }, + { + name: 'Rejang', + bmp: '\uA930-\uA953\uA95F' + }, + { + name: 'Runic', + bmp: '\u16A0-\u16EA\u16EE-\u16F8' + }, + { + name: 'Samaritan', + bmp: '\u0800-\u082D\u0830-\u083E' + }, + { + name: 'Saurashtra', + bmp: '\uA880-\uA8C4\uA8CE-\uA8D9' + }, + { + name: 'Sharada', + astral: '\uD804[\uDD80-\uDDCD\uDDD0-\uDDDF]' + }, + { + name: 'Shavian', + astral: '\uD801[\uDC50-\uDC7F]' + }, + { + name: 'Siddham', + astral: '\uD805[\uDD80-\uDDB5\uDDB8-\uDDDD]' + }, + { + name: 'SignWriting', + astral: '\uD836[\uDC00-\uDE8B\uDE9B-\uDE9F\uDEA1-\uDEAF]' + }, + { + name: 'Sinhala', + bmp: '\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2-\u0DF4', + astral: '\uD804[\uDDE1-\uDDF4]' + }, + { + name: 'Sora_Sompeng', + astral: '\uD804[\uDCD0-\uDCE8\uDCF0-\uDCF9]' + }, + { + name: 'Sundanese', + bmp: '\u1B80-\u1BBF\u1CC0-\u1CC7' + }, + { + name: 'Syloti_Nagri', + bmp: '\uA800-\uA82B' + }, + { + name: 'Syriac', + bmp: '\u0700-\u070D\u070F-\u074A\u074D-\u074F' + }, + { + name: 'Tagalog', + bmp: '\u1700-\u170C\u170E-\u1714' + }, + { + name: 'Tagbanwa', + bmp: '\u1760-\u176C\u176E-\u1770\u1772\u1773' + }, + { + name: 'Tai_Le', + bmp: '\u1950-\u196D\u1970-\u1974' + }, + { + name: 'Tai_Tham', + bmp: '\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA0-\u1AAD' + }, + { + name: 'Tai_Viet', + bmp: '\uAA80-\uAAC2\uAADB-\uAADF' + }, + { + name: 'Takri', + astral: '\uD805[\uDE80-\uDEB7\uDEC0-\uDEC9]' + }, + { + name: 'Tamil', + bmp: '\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BFA' + }, + { + name: 'Telugu', + bmp: '\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C78-\u0C7F' + }, + { + name: 'Thaana', + bmp: '\u0780-\u07B1' + }, + { + name: 'Thai', + bmp: '\u0E01-\u0E3A\u0E40-\u0E5B' + }, + { + name: 'Tibetan', + bmp: '\u0F00-\u0F47\u0F49-\u0F6C\u0F71-\u0F97\u0F99-\u0FBC\u0FBE-\u0FCC\u0FCE-\u0FD4\u0FD9\u0FDA' + }, + { + name: 'Tifinagh', + bmp: '\u2D30-\u2D67\u2D6F\u2D70\u2D7F' + }, + { + name: 'Tirhuta', + astral: '\uD805[\uDC80-\uDCC7\uDCD0-\uDCD9]' + }, + { + name: 'Ugaritic', + astral: '\uD800[\uDF80-\uDF9D\uDF9F]' + }, + { + name: 'Vai', + bmp: '\uA500-\uA62B' + }, + { + name: 'Warang_Citi', + astral: '\uD806[\uDCA0-\uDCF2\uDCFF]' + }, + { + name: 'Yi', + bmp: '\uA000-\uA48C\uA490-\uA4C6' + } + ]); + +}; + +var XRegExp$1 = xregexp; + +build(XRegExp$1); +matchrecursive(XRegExp$1); +unicodeBase(XRegExp$1); +unicodeBlocks(XRegExp$1); +unicodeCategories(XRegExp$1); +unicodeProperties(XRegExp$1); +unicodeScripts(XRegExp$1); + +var src = XRegExp$1; + +/* + * preprocess + * https://github.com/onehealth/preprocess + * + * Copyright (c) 2012 OneHealth Solutions, Inc. + * Written by Jarrod Overson - http://jarrodoverson.com/ + * Licensed under the Apache 2.0 license. + */ + +var preprocess_2 = preprocess; + +var path = require$$1__default$1.default, + fs = require$$1__default.default, + os = require$$2__default.default, + delim = regexrulesExports, + XRegExp = src; + +function preprocess(src, context, typeOrOptions) { + src = src.toString(); + context = context || process.env; + + // default values + var options = { + fileNotFoundSilentFail: false, + srcDir: process.cwd(), + srcEol: getEolType(src), + type: delim['html'] + }; + + // needed for backward compatibility with 2.x.x series + if (typeof typeOrOptions === 'string') { + typeOrOptions = { + type: typeOrOptions + }; + } + + // needed for backward compatibility with 2.x.x series + if (typeof context.srcDir === "string") { + typeOrOptions = typeOrOptions || {}; + typeOrOptions.srcDir = context.srcDir; + } + + if (typeOrOptions && typeof typeOrOptions === 'object') { + options.srcDir = typeOrOptions.srcDir || options.srcDir; + options.fileNotFoundSilentFail = typeOrOptions.fileNotFoundSilentFail || options.fileNotFoundSilentFail; + options.srcEol = typeOrOptions.srcEol || options.srcEol; + options.type = delim[typeOrOptions.type] || options.type; + } + + context = copy(context); + + return preprocessor(src, context, options); +} + +function preprocessor(src, context, opts, noRestoreEol) { + src = normalizeEol(src); + + var rv = src; + + rv = replace(rv, opts.type.include, processIncludeDirective.bind(null, false, context, opts)); + + if (opts.type.extend) { + rv = replaceRecursive(rv, opts.type.extend, function(startMatches, endMatches, include, recurse) { + var file = (startMatches[1] || '').trim(); + var extendedContext = copy(context); + var extendedOpts = copy(opts); + extendedContext.src = path.join(opts.srcDir, file); + extendedOpts.srcDir = path.dirname(extendedContext.src); + + var fileContents = getFileContents(extendedContext.src, opts.fileNotFoundSilentFail, context.src); + if (fileContents.error) { + return fileContents.contents; + } + + var extendedSource = preprocessor(fileContents.contents, extendedContext, extendedOpts, true).trim(); + + if (extendedSource) { + include = include.replace(/^\n?|\n?$/g, ''); + return replace(extendedSource, opts.type.extendable, recurse(include)); + } else { + return ''; + } + }); + } + + if (opts.type.foreach) { + rv = replaceRecursive(rv, opts.type.foreach, function(startMatches, endMatches, include, recurse) { + var variable = (startMatches[1] || '').trim(); + var forParams = variable.split(' '); + if (forParams.length === 3) { + var contextVar = forParams[2]; + var arrString = getDeepPropFromObj(context, contextVar); + var eachArr; + if (arrString.match(/\{(.*)\}/)) { + eachArr = JSON.parse(arrString); + } else if (arrString.match(/\[(.*)\]/)) { + eachArr = arrString.slice(1, -1); + eachArr = eachArr.split(','); + eachArr = eachArr.map(function(arrEntry){ + return arrEntry.replace(/\s*(['"])(.*)\1\s*/, '$2'); + }); + } else { + eachArr = arrString.split(','); + } + + var replaceToken = new RegExp(XRegExp.escape(forParams[0]), 'g'); + var recursedInclude = recurse(include); + + return Object.keys(eachArr).reduce(function(stringBuilder, arrKey){ + var arrEntry = eachArr[arrKey]; + return stringBuilder + recursedInclude.replace(replaceToken, arrEntry); + }, ''); + } else { + return ''; + } + }); + } + + if (opts.type.exclude) { + rv = replaceRecursive(rv, opts.type.exclude, function(startMatches, endMatches, include, recurse){ + var test = (startMatches[1] || '').trim(); + return testPasses(test,context) ? '' : recurse(include); + }); + } + + if (opts.type.if) { + rv = replaceRecursive(rv, opts.type.if, function (startMatches, endMatches, include, recurse) { + // I need to recurse first, so I don't catch "inner" else-directives + var recursed = recurse(include); + + // look for the first else-directive + var matches = opts.type.else && recursed.match(new RegExp(opts.type.else)); + var match = (matches || [""])[0]; + var index = match ? recursed.indexOf(match) : recursed.length; + + var ifBlock = recursed.substring(0, index); + var elseBlock = recursed.substring(index + match.length); // empty string if no else-directive + + var variant = startMatches[1]; + var test = (startMatches[2] || '').trim(); + // fixed by xxxxxx + var startLine = padContent(startMatches.input); + var endLine = padContent(endMatches.input); + switch(variant) { + case 'if': + case 'ifdef': // fixed by xxxxxx + return testPasses(test, context) ? (startLine + ifBlock + endLine) : (startLine + padContent(ifBlock) + padContent(match || '') + elseBlock + endLine); + case 'ifndef': + return !testPasses(test, context) ? (startLine + ifBlock + endLine) : (startLine + padContent(ifBlock) + padContent(match || '') + elseBlock + endLine); + // case 'ifdef': + // return typeof getDeepPropFromObj(context, test) !== 'undefined' ? ifBlock : elseBlock; + // case 'ifndef': + // return typeof getDeepPropFromObj(context, test) === 'undefined' ? ifBlock : elseBlock; + default: + throw new Error('Unknown if variant ' + variant + '.'); + } + }); + } + + rv = replace(rv, opts.type.echo, function (match, variable) { + variable = (variable || '').trim(); + // if we are surrounded by quotes, echo as a string + var stringMatch = variable.match(/^(['"])(.*)\1$/); + if (stringMatch) return stringMatch[2]; + + var arrString = getDeepPropFromObj(context, variable); + return typeof arrString !== 'undefined' ? arrString : ''; + }); + + rv = replace(rv, opts.type.exec, function (match, name, value) { + name = (name || '').trim(); + value = value || ''; + + var params = value.split(','); + var stringRegex = /^['"](.*)['"]$/; + + params = params.map(function(param){ + param = param.trim(); + if (stringRegex.test(param)) { // handle string parameter + return param.replace(stringRegex, '$1'); + } else { // handle variable parameter + return getDeepPropFromObj(context, param); + } + }); + + var fn = getDeepPropFromObj(context, name); + if (!fn || typeof fn !== 'function') return ''; + + return fn.apply(context, params); + }); + + rv = replace(rv, opts.type['include-static'], processIncludeDirective.bind(null, true, context, opts)); + + if (!noRestoreEol) { + rv = restoreEol(rv, opts.srcEol); + } + + return rv; +} + +function getEolType(source) { + var eol; + var foundEolTypeCnt = 0; + + if (source.indexOf('\r\n') >= 0) { + eol = '\r\n'; + foundEolTypeCnt++; + } + if (/\r[^\n]/.test(source)) { + eol = '\r'; + foundEolTypeCnt++; + } + if (/[^\r]\n/.test(source)) { + eol = '\n'; + foundEolTypeCnt++; + } + + if (eol == null || foundEolTypeCnt > 1) { + eol = os.EOL; + } + + return eol; +} + +function normalizeEol(source, indent) { + // only process any kind of EOL if indentation has to be added, otherwise replace only non \n EOLs + if (indent) { + source = source.replace(/(?:\r?\n)|\r/g, '\n' + indent); + } else { + source = source.replace(/(?:\r\n)|\r/g, '\n'); + } + + return source; +} + +function restoreEol(normalizedSource, originalEol) { + if (originalEol !== '\n') { + normalizedSource = normalizedSource.replace(/\n/g, originalEol); + } + + return normalizedSource; +} + +function replace(rv, rule, processor) { + var isRegex = typeof rule === 'string' || rule instanceof RegExp; + var isArray = Array.isArray(rule); + + if (isRegex) { + rule = [new RegExp(rule,'gmi')]; + } else if (isArray) { + rule = rule.map(function(subRule){ + return new RegExp(subRule,'gmi'); + }); + } else { + throw new Error('Rule must be a String, a RegExp, or an Array.'); + } + + return rule.reduce(function(rv, rule){ + return rv.replace(rule, processor); + }, rv); +} + +function replaceRecursive(rv, rule, processor) { + if(!rule.start || !rule.end) { + throw new Error('Recursive rule must have start and end.'); + } + + var startRegex = new RegExp(rule.start, 'mi'); + var endRegex = new RegExp(rule.end, 'mi'); + + function matchReplacePass(content) { + var matches = XRegExp.matchRecursive(content, rule.start, rule.end, 'gmi', { + valueNames: ['between', 'left', 'match', 'right'] + }); + + var matchGroup = { + left: null, + match: null, + right: null + }; + + return matches.reduce(function (builder, match) { + switch(match.name) { + case 'between': + builder += match.value; + break; + case 'left': + matchGroup.left = startRegex.exec(match.value); + break; + case 'match': + matchGroup.match = match.value; + break; + case 'right': + matchGroup.right = endRegex.exec(match.value); + builder += processor(matchGroup.left, matchGroup.right, matchGroup.match, matchReplacePass); + break; + } + return builder; + }, ''); + } + + return matchReplacePass(rv); +} + + +function processIncludeDirective(isStatic, context, opts, match, linePrefix, file) { + file = (file || '').trim(); + var indent = linePrefix.replace(/\S/g, ' '); + var includedContext = copy(context); + var includedOpts = copy(opts); + includedContext.src = path.join(opts.srcDir,file); + includedOpts.srcDir = path.dirname(includedContext.src); + + var fileContents = getFileContents(includedContext.src, opts.fileNotFoundSilentFail, context.src); + if (fileContents.error) { + return linePrefix + fileContents.contents; + } + + var includedSource = fileContents.contents; + if (isStatic) { + includedSource = fileContents.contents; + } else { + includedSource = preprocessor(fileContents.contents, includedContext, includedOpts, true); + } + + includedSource = normalizeEol(includedSource, indent); + + if (includedSource) { + return linePrefix + includedSource; + } else { + return linePrefix; + } +} + +function getTestTemplate(test) { + /*jshint evil:true*/ + test = test || 'true'; + test = test.trim(); + + // force single equals replacement + test = test.replace(/([^=!])=([^=])/g, '$1==$2'); + // fixed by xxxxxx + test = test.replace(/-/g, '_'); + return new Function("context", "with (context||{}){ return ( " + test + " ); }"); +} + +// fixed by xxxxxx +function testPasses(test, context) { + var testFn = getTestTemplate(test); + try { + return testFn(context, getDeepPropFromObj) + } catch (e) {} + return false +} + +function getFileContents(path, failSilent, requesterPath) { + try { + fs.statSync(path); + } catch (e) { + if (failSilent) { + return {error: true, contents: path + ' not found!'}; + } else { + var errMsg = path; + errMsg = requesterPath ? errMsg + ' requested from ' + requesterPath : errMsg; + errMsg += ' not found!'; + throw new Error(errMsg); + } + } + return {error: false, contents: fs.readFileSync(path).toString()}; +} + +function copy(obj) { + return Object.keys(obj).reduce(function (copyObj, objKey) { + copyObj[objKey] = obj[objKey]; + return copyObj; + }, {}); +} + +function getDeepPropFromObj(obj, propPath) { + propPath.replace(/\[([^\]+?])\]/g, '.$1'); + propPath = propPath.split('.'); + + // fast path, no need to loop if structurePath contains only a single segment + if (propPath.length === 1) { + return obj[propPath[0]]; + } + + // loop only as long as possible (no exceptions for null/undefined property access) + propPath.some(function (pathSegment) { + obj = obj[pathSegment]; + return (obj == null); + }); + + return obj; +} +// fixed by xxxxxx +const splitRE = /\r?\n/g; +function padContent(content) { + return Array(content.split(splitRE).length).join('\n') +} + +function preJs(jsCode) { + return preprocess_2(jsCode, getPreVueContext(), { type: 'js' }); +} +const preJson = preJs; + +function uniWeiboSpecialPlugin() { + return { + name: 'uni:weibo', + enforce: 'pre', + buildEnd() { + const fileDIR = require$$1__default$1.default.join(process.env.UNI_OUTPUT_DIR, '../', '../', '../'); + lib.emptyDirSync(fileDIR); + // 复制文件夹 + lib.copySync(require$$1__default$1.default.resolve('node_modules/@dcloudio/uni-mp-weibo/template'), fileDIR); + // STAER: 读取用户在 manifest.json 中配置的 appid 并修改微博 wbox.config.json 中配置的 appid。 + const manifestJsonPath = require$$1__default$1.default.join(process.env.UNI_INPUT_DIR, 'manifest.json'); + const manifestJson = CJSON.parse(lib.readFileSync(manifestJsonPath, 'utf8')); + if (manifestJson['mp-weibo'] && manifestJson['mp-weibo'].appid) { + const mpWeiboAppid = manifestJson['mp-weibo'].appid; + const wboxConfigJsonPath = require$$1__default$1.default.join(fileDIR, 'wbox.config.json'); + const wboxConfigJson = CJSON.parse(lib.readFileSync(wboxConfigJsonPath, 'utf8')); + wboxConfigJson.appId = mpWeiboAppid; + lib.writeFileSync(wboxConfigJsonPath, CJSON.stringify(wboxConfigJson, null, 2)); + } + // END: 读取用户在 manifest.json 中配置的 appid 并修改微博 wbox.config.json 中配置的 appid。 + // STAER: 解析 pages.json 中的内容,生成 page 页面及 app.json 文件。 + const pagesJsonPath = require$$1__default$1.default.join(process.env.UNI_INPUT_DIR, 'pages.json'); + const pagesJsonStr = lib.readFileSync(pagesJsonPath, 'utf8'); + // preJson 处理 page.json 中的条件编译 + const pagesJson = CJSON.parse(preJson(pagesJsonStr)); + let pageOptions = pagesJson.pages; + if (pagesJson.subPackages && pagesJson.subPackages.length) { + pagesJson.subPackages.forEach((subPackage) => { + pageOptions = pageOptions.concat(subPackage.pages.map((item) => (Object.assign(Object.assign({}, item), { path: `${subPackage.root}/${item.path}` })))); + }); + } + // ==> STAER: 根据 pages.json 生成 app.json + const appPages = pageOptions.map((item) => item.path); + const appJsonPath = require$$1__default$1.default.join(fileDIR, 'src', 'app.json'); + const appJson = CJSON.parse(lib.readFileSync(appJsonPath, 'utf8')); + appJson.pages = appPages; + if (pagesJson.globalStyle) { + appJson.window = Object.assign(appJson.window, pagesJson.globalStyle); + } + lib.writeFileSync(appJsonPath, CJSON.stringify(appJson, null, 2)); + // ==> END: 根据 pages.json 生成 app.json + // ==> STAER: 根据 pages.json 生成 pages 目录 + const templatePagePath = require$$1__default$1.default.resolve('node_modules/@dcloudio/uni-mp-weibo/template/src/pages/index/index'); + const pageFileSuffixs = ['.vue', '.css', '.json']; + pageOptions.forEach((pageInfo) => { + const targetPagePath = require$$1__default$1.default.resolve(fileDIR, 'src', pageInfo.path); + pageFileSuffixs.forEach((suffix) => { + lib.copySync(`${templatePagePath}${suffix}`, `${targetPagePath}${suffix}`); + // 覆写 page.json 配置文件 + if (suffix === '.json' && + pageInfo.style && + Object.keys(pageInfo.style).length > 0) { + let pageJson = CJSON.parse(lib.readFileSync(`${targetPagePath}${suffix}`, 'utf8')); + pageJson = Object.assign(pageJson, pageInfo.style); + lib.writeFileSync(`${targetPagePath}${suffix}`, CJSON.stringify(pageJson, null, 2)); + } + }); + }); + // ==> END: 根据 pages.json 生成 pages 目录 + // END: 解析 pages.json 中的内容,生成 page 页面及 app.json 文件。 + }, + }; +} + +uniMpWeiboVite__namespace.default.push(uniWeiboSpecialPlugin()); + +module.exports = uniMpWeiboVite__namespace; diff --git a/packages/uni-mp-weibo/lib/automator.js b/packages/uni-mp-weibo/lib/automator.js new file mode 100644 index 00000000000..46f07663a9d --- /dev/null +++ b/packages/uni-mp-weibo/lib/automator.js @@ -0,0 +1,15 @@ +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +function e(){for(var e=0,t=0,n=arguments.length;t]*>)(]*>[^<]*<\/span>)(.*?<\/uni-text>)/g,"$1$3").replace(/<\/?[^>]*>/g,(function(e){return-1":""===e?"":0!==e.indexOf("{if("tag"===e.type){const t=e.value;e.value="page"===t?"uni-page-body":"uni-"+t}}))}const i=["Page.getElement","Page.getElements","Element.getElement","Element.getElements"];function c(e){try{return require(e)}catch(t){return require(require.resolve(e,{paths:[process.cwd()]}))}}/^win/.test(process.platform);const p=["chromium","firefox","webkit"];let l=!1;try{l=!!c("playwright")}catch(e){}const u=new Map;function f(e="chromium"){const t=e&&p.includes(e)?e:p[0];let o=u.get(t);return o||(o=function(e){if("webkit"===e)return h("webkit");if("firefox"===e)return h("firefox");return l?h("chromium"):function(){const e=c("puppeteer");let t,o;return{type:"chromium",provider:"puppeteer",async open(n,r,a){t=await e.launch(r.options);const i=t.process();i?s("%s %o",i.spawnfile,r.options):s("%o",r.options),o=await t.newPage(),o.on("console",(e=>{a.emit("App.logAdded",{type:e.type(),args:[e.text()]})})),o.on("pageerror",(e=>{a.emit("App.exceptionThrown",e)})),await o.goto(r.url||n),await o.waitFor(1e3)},close:()=>t.close(),screenshot:(e=!1)=>o.screenshot({encoding:"base64",fullPage:e})}}()}(t),u.set(t,o)),o}function h(e){const t=c("playwright");let o,n;return{type:e,provider:"playwright",async open(r,a,i){o=await t[e].launch(a.options),"firefox"===e&&(a.contextOptions.isMobile=!1),s(`browser.newContext ${JSON.stringify(a.contextOptions)}`);const c=await o.newContext(a.contextOptions);n=await c.newPage(),n.on("console",(e=>{i.emit("App.logAdded",{type:e.type(),args:[e.text()]})})),n.on("pageerror",(e=>{i.emit("App.exceptionThrown",e)})),await n.goto(a.url||r),await n.waitForTimeout(1e3)},close:()=>o.close(),screenshot:(e=!1)=>n.screenshot({fullPage:e}).then((e=>e.toString("base64")))}}let w;const g={"Tool.close":{reflect:async()=>{await w.close()}},"App.exit":{reflect:async()=>{}},"App.enableLog":{reflect:()=>Promise.resolve()},"App.captureScreenshot":{reflect:async(e,t)=>{const o=await w.screenshot(!!t.fullPage);return s(`App.captureScreenshot ${o.length}`),{data:o}}}};!function(e){i.forEach((t=>{e[t]=function(e){return{reflect:async(t,o)=>t(e,o,!1),params:e=>(e.selector&&(e.selector=r.default(a).processSync(e.selector)),e)}}(t)}))}(g);const d={devtools:{name:"browser",paths:[],validate:async function(e){return e.options=e.options||{},e.executablePath&&!e.options.executablePath&&(e.options.executablePath=e.executablePath),e.contextOptions={viewport:Object.assign({width:375,height:667},e.options.defaultViewport||{}),hasTouch:!0,isMobile:!0,deviceScaleFactor:2},e.options.defaultViewport=Object.assign({width:375,height:667,deviceScaleFactor:2,hasTouch:!0,isMobile:!0},e.options.defaultViewport||{}),e.teardown||(e.teardown=!1===e.options.headless?"disconnect":"close"),e},create:async function(e,t,o){w=f(process.env.BROWSER),s("createDevtools "+(w.provider+" "+w.type+" "+JSON.stringify(t))),await w.open(e,t,o)}},shouldCompile:(e,t)=>!t.url,adapter:g};module.exports=d; diff --git a/packages/uni-mp-weibo/package.json b/packages/uni-mp-weibo/package.json new file mode 100644 index 00000000000..520841adc8e --- /dev/null +++ b/packages/uni-mp-weibo/package.json @@ -0,0 +1,60 @@ +{ + "name": "@dcloudio/uni-mp-weibo", + "version": "3.0.0-alpha-3080220230428002", + "description": "@dcloudio/uni-mp-weibo", + "main": "./dist/uni-mp-weibo.cjs.js", + "module": "./dist/uni-mp-weibo.es.js", + "files": [ + "dist", + "lib", + "style", + "template" + ], + "sideEffects": [ + "lib/automator.js" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/dcloudio/uni-app.git", + "directory": "packages/uni-mp-weibo" + }, + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/dcloudio/uni-app/issues" + }, + "uni-app": { + "name": "uni-mp-weibo", + "apply": [ + "mp-weibo" + ], + "main": "dist/uni.compiler.js" + }, + "dependencies": { + "@dcloudio/uni-h5-vue": "3.0.0-alpha-3080220230428002", + "@dcloudio/uni-i18n": "3.0.0-alpha-3080220230428002", + "@dcloudio/uni-mp-weibo-vite": "3.0.0-alpha-3080220230428002", + "@dcloudio/uni-shared": "3.0.0-alpha-3080220230428002", + "@vue/server-renderer": "3.2.47", + "@vue/shared": "3.2.47", + "comment-json": "^4.2.3", + "debug": "^4.3.3", + "fs-extra": "^10.0.0", + "localstorage-polyfill": "^1.0.1", + "postcss-selector-parser": "^6.0.6", + "safe-area-insets": "^1.4.1", + "vue-router": "^4.1.6", + "xmlhttprequest": "^1.8.0", + "xregexp": "3.1.0" + }, + "gitHead": "33e807d66e1fe47e2ee08ad9c59247e37b8884da", + "devDependencies": { + "@amap/amap-jsapi-types": "^0.0.8", + "@dcloudio/uni-cli-shared": "3.0.0-alpha-3080220230428002", + "@types/estree": "^0.0.51", + "@types/google.maps": "^3.45.6", + "acorn-loose": "^8.2.1", + "acorn-walk": "^8.2.0", + "estree-walker": "^2.0.2", + "vue": "3.2.47" + } +} diff --git a/packages/uni-mp-weibo/src/compiler/index.ts b/packages/uni-mp-weibo/src/compiler/index.ts new file mode 100644 index 00000000000..bea99d333d7 --- /dev/null +++ b/packages/uni-mp-weibo/src/compiler/index.ts @@ -0,0 +1,6 @@ +import * as uniMpWeiboVite from '@dcloudio/uni-mp-weibo-vite' +import weiboSpecial from './weiboTemplate' + +uniMpWeiboVite.default.push(weiboSpecial()) + +export default uniMpWeiboVite diff --git a/packages/uni-mp-weibo/src/compiler/preprocess/context.ts b/packages/uni-mp-weibo/src/compiler/preprocess/context.ts new file mode 100644 index 00000000000..a5d902383a5 --- /dev/null +++ b/packages/uni-mp-weibo/src/compiler/preprocess/context.ts @@ -0,0 +1,112 @@ +import { extend, isString, isPlainObject } from '@vue/shared' +const DEFAULT_KEYS = [ + 'APP', + 'APP_NVUE', + 'APP_PLUS', + 'APP_PLUS_NVUE', + 'APP_VUE', + 'APP_ANDROID', + 'APP_IOS', + 'H5', + 'MP', + 'MP_360', + 'MP_ALIPAY', + 'MP_BAIDU', + 'MP_QQ', + 'MP_LARK', + 'MP_TOUTIAO', + 'MP_WEIXIN', + 'MP_KUAISHOU', + 'MP_JD', + 'MP_WB', + 'QUICKAPP_NATIVE', + 'QUICKAPP_WEBVIEW', + 'QUICKAPP_WEBVIEW_HUAWEI', + 'QUICKAPP_WEBVIEW_UNION', + 'VUE2', + 'VUE3', + 'WEB', +] as const + +const preVueContext = Object.create(null) +const preNVueContext = Object.create(null) +const preUVueContext = Object.create(null) + +export function getPreVueContext() { + return preVueContext +} + +export function getPreNVueContext() { + return preNVueContext +} + +export function getPreUVueContext() { + return preUVueContext +} + +export function initPreContext( + platform: UniApp.PLATFORM, + userPreContext?: Record | string, + utsPlatform?: typeof process.env.UNI_UTS_PLATFORM +) { + const vueContext = Object.create(null) + const nvueContext = Object.create(null) + const uvueContext = Object.create(null) + + const defaultContext = Object.create(null) + DEFAULT_KEYS.forEach((key) => { + defaultContext[key] = false + }) + + defaultContext[normalizeKey(platform)] = true + + vueContext.VUE3 = true + nvueContext.VUE3 = true + uvueContext.VUE3 = true + + if (platform === 'app' || platform === 'app-plus') { + defaultContext.APP = true + defaultContext.APP_PLUS = true + + vueContext.APP_VUE = true + + nvueContext.APP_NVUE = true + nvueContext.APP_PLUS_NVUE = true + + uvueContext.APP_UVUE = true + + if (utsPlatform === 'app-android') { + uvueContext.APP_ANDROID = true + } else if (utsPlatform === 'app-ios') { + uvueContext.APP_IOS = true + } + } else if (platform.startsWith('mp-') && platform !== 'mp-weibo') { + defaultContext.MP = true + } else if (platform.startsWith('quickapp-webview')) { + defaultContext.QUICKAPP_WEBVIEW = true + } else if (platform === 'h5' || platform === 'mp-weibo') { + defaultContext.WEB = true + } + + if (userPreContext) { + if (isString(userPreContext)) { + try { + userPreContext = JSON.parse(userPreContext) + } catch (e) {} + } + if (isPlainObject(userPreContext)) { + Object.keys(userPreContext).forEach((key) => { + defaultContext[normalizeKey(key)] = !!( + userPreContext as Record + )[key] + }) + } + } + extend(preVueContext, defaultContext, vueContext) + extend(preNVueContext, defaultContext, nvueContext) + extend(preUVueContext, defaultContext, uvueContext) +} + +function normalizeKey(name: string) { + return name.replace(/-/g, '_').toUpperCase() +} diff --git a/packages/uni-mp-weibo/src/compiler/preprocess/index.ts b/packages/uni-mp-weibo/src/compiler/preprocess/index.ts new file mode 100644 index 00000000000..2030fdea1cc --- /dev/null +++ b/packages/uni-mp-weibo/src/compiler/preprocess/index.ts @@ -0,0 +1,42 @@ +import { + getPreNVueContext, + getPreUVueContext, + getPreVueContext, +} from './context' +/* eslint-disable no-restricted-globals */ +import { preprocess } from './preprocess' + +export { initPreContext } from './context' + +export function preJs(jsCode: string) { + return preprocess(jsCode, getPreVueContext(), { type: 'js' }) +} + +export function preHtml(htmlCode: string) { + return preprocess(htmlCode, getPreVueContext(), { type: 'html' }) +} + +export const preCss = preJs +export const preJson = preJs + +export function preNVueJs(jsCode: string) { + return preprocess(jsCode, getPreNVueContext(), { type: 'js' }) +} + +export function preNVueHtml(htmlCode: string) { + return preprocess(htmlCode, getPreNVueContext(), { type: 'html' }) +} + +export const preNVueCss = preNVueJs +export const preNVueJson = preNVueJs + +export function preUVueJs(jsCode: string) { + return preprocess(jsCode, getPreUVueContext(), { type: 'js' }) +} + +export function preUVueHtml(htmlCode: string) { + return preprocess(htmlCode, getPreUVueContext(), { type: 'html' }) +} + +export const preUVueCss = preUVueJs +export const preUVueJson = preUVueJs diff --git a/packages/uni-mp-weibo/src/compiler/preprocess/preprocess.js b/packages/uni-mp-weibo/src/compiler/preprocess/preprocess.js new file mode 100755 index 00000000000..bd4ff904a75 --- /dev/null +++ b/packages/uni-mp-weibo/src/compiler/preprocess/preprocess.js @@ -0,0 +1,437 @@ +/* + * preprocess + * https://github.com/onehealth/preprocess + * + * Copyright (c) 2012 OneHealth Solutions, Inc. + * Written by Jarrod Overson - http://jarrodoverson.com/ + * Licensed under the Apache 2.0 license. + */ + +'use strict'; + +exports.preprocess = preprocess; +exports.preprocessFile = preprocessFile; +exports.preprocessFileSync = preprocessFileSync; + +var path = require('path'), + fs = require('fs'), + os = require('os'), + delim = require('./regexrules'), + XRegExp = require('xregexp'); + +function preprocessFile(srcFile, destFile, context, callback, options) { + options = getOptionsForFile(srcFile, options); + context.src = srcFile; + + fs.readFile(srcFile, function (err, data) { + if (err) return callback(err, data); + var parsed = preprocess(data, context, options); + fs.writeFile(destFile, parsed, callback); + }); +} + +function preprocessFileSync(srcFile, destFile, context, options) { + options = getOptionsForFile(srcFile, options); + context.src = srcFile; + + var data = fs.readFileSync(srcFile); + var parsed = preprocess(data, context, options); + return fs.writeFileSync(destFile, parsed); +} + +function getOptionsForFile(srcFile, options) { + options = options || {}; + options.srcDir = options.srcDir || path.dirname(srcFile); + options.type = options.type || getExtension(srcFile); + + return options; +} + +function getExtension(filename) { + var ext = path.extname(filename||'').split('.'); + return ext[ext.length - 1]; +} + +function preprocess(src, context, typeOrOptions) { + src = src.toString(); + context = context || process.env; + + // default values + var options = { + fileNotFoundSilentFail: false, + srcDir: process.cwd(), + srcEol: getEolType(src), + type: delim['html'] + }; + + // needed for backward compatibility with 2.x.x series + if (typeof typeOrOptions === 'string') { + typeOrOptions = { + type: typeOrOptions + }; + } + + // needed for backward compatibility with 2.x.x series + if (typeof context.srcDir === "string") { + typeOrOptions = typeOrOptions || {}; + typeOrOptions.srcDir = context.srcDir; + } + + if (typeOrOptions && typeof typeOrOptions === 'object') { + options.srcDir = typeOrOptions.srcDir || options.srcDir; + options.fileNotFoundSilentFail = typeOrOptions.fileNotFoundSilentFail || options.fileNotFoundSilentFail; + options.srcEol = typeOrOptions.srcEol || options.srcEol; + options.type = delim[typeOrOptions.type] || options.type; + } + + context = copy(context); + + return preprocessor(src, context, options); +} + +function preprocessor(src, context, opts, noRestoreEol) { + src = normalizeEol(src); + + var rv = src; + + rv = replace(rv, opts.type.include, processIncludeDirective.bind(null, false, context, opts)); + + if (opts.type.extend) { + rv = replaceRecursive(rv, opts.type.extend, function(startMatches, endMatches, include, recurse) { + var file = (startMatches[1] || '').trim(); + var extendedContext = copy(context); + var extendedOpts = copy(opts); + extendedContext.src = path.join(opts.srcDir, file); + extendedOpts.srcDir = path.dirname(extendedContext.src); + + var fileContents = getFileContents(extendedContext.src, opts.fileNotFoundSilentFail, context.src); + if (fileContents.error) { + return fileContents.contents; + } + + var extendedSource = preprocessor(fileContents.contents, extendedContext, extendedOpts, true).trim(); + + if (extendedSource) { + include = include.replace(/^\n?|\n?$/g, ''); + return replace(extendedSource, opts.type.extendable, recurse(include)); + } else { + return ''; + } + }); + } + + if (opts.type.foreach) { + rv = replaceRecursive(rv, opts.type.foreach, function(startMatches, endMatches, include, recurse) { + var variable = (startMatches[1] || '').trim(); + var forParams = variable.split(' '); + if (forParams.length === 3) { + var contextVar = forParams[2]; + var arrString = getDeepPropFromObj(context, contextVar); + var eachArr; + if (arrString.match(/\{(.*)\}/)) { + eachArr = JSON.parse(arrString); + } else if (arrString.match(/\[(.*)\]/)) { + eachArr = arrString.slice(1, -1); + eachArr = eachArr.split(','); + eachArr = eachArr.map(function(arrEntry){ + return arrEntry.replace(/\s*(['"])(.*)\1\s*/, '$2'); + }); + } else { + eachArr = arrString.split(','); + } + + var replaceToken = new RegExp(XRegExp.escape(forParams[0]), 'g'); + var recursedInclude = recurse(include); + + return Object.keys(eachArr).reduce(function(stringBuilder, arrKey){ + var arrEntry = eachArr[arrKey]; + return stringBuilder + recursedInclude.replace(replaceToken, arrEntry); + }, ''); + } else { + return ''; + } + }); + } + + if (opts.type.exclude) { + rv = replaceRecursive(rv, opts.type.exclude, function(startMatches, endMatches, include, recurse){ + var test = (startMatches[1] || '').trim(); + return testPasses(test,context) ? '' : recurse(include); + }); + } + + if (opts.type.if) { + rv = replaceRecursive(rv, opts.type.if, function (startMatches, endMatches, include, recurse) { + // I need to recurse first, so I don't catch "inner" else-directives + var recursed = recurse(include); + + // look for the first else-directive + var matches = opts.type.else && recursed.match(new RegExp(opts.type.else)); + var match = (matches || [""])[0]; + var index = match ? recursed.indexOf(match) : recursed.length; + + var ifBlock = recursed.substring(0, index); + var elseBlock = recursed.substring(index + match.length); // empty string if no else-directive + + var variant = startMatches[1]; + var test = (startMatches[2] || '').trim(); + // fixed by xxxxxx + var startLine = padContent(startMatches.input) + var endLine = padContent(endMatches.input) + switch(variant) { + case 'if': + case 'ifdef': // fixed by xxxxxx + return testPasses(test, context) ? (startLine + ifBlock + endLine) : (startLine + padContent(ifBlock) + padContent(match || '') + elseBlock + endLine); + case 'ifndef': + return !testPasses(test, context) ? (startLine + ifBlock + endLine) : (startLine + padContent(ifBlock) + padContent(match || '') + elseBlock + endLine); + // case 'ifdef': + // return typeof getDeepPropFromObj(context, test) !== 'undefined' ? ifBlock : elseBlock; + // case 'ifndef': + // return typeof getDeepPropFromObj(context, test) === 'undefined' ? ifBlock : elseBlock; + default: + throw new Error('Unknown if variant ' + variant + '.'); + } + }); + } + + rv = replace(rv, opts.type.echo, function (match, variable) { + variable = (variable || '').trim(); + // if we are surrounded by quotes, echo as a string + var stringMatch = variable.match(/^(['"])(.*)\1$/); + if (stringMatch) return stringMatch[2]; + + var arrString = getDeepPropFromObj(context, variable); + return typeof arrString !== 'undefined' ? arrString : ''; + }); + + rv = replace(rv, opts.type.exec, function (match, name, value) { + name = (name || '').trim(); + value = value || ''; + + var params = value.split(','); + var stringRegex = /^['"](.*)['"]$/; + + params = params.map(function(param){ + param = param.trim(); + if (stringRegex.test(param)) { // handle string parameter + return param.replace(stringRegex, '$1'); + } else { // handle variable parameter + return getDeepPropFromObj(context, param); + } + }); + + var fn = getDeepPropFromObj(context, name); + if (!fn || typeof fn !== 'function') return ''; + + return fn.apply(context, params); + }); + + rv = replace(rv, opts.type['include-static'], processIncludeDirective.bind(null, true, context, opts)); + + if (!noRestoreEol) { + rv = restoreEol(rv, opts.srcEol); + } + + return rv; +} + +function getEolType(source) { + var eol; + var foundEolTypeCnt = 0; + + if (source.indexOf('\r\n') >= 0) { + eol = '\r\n'; + foundEolTypeCnt++; + } + if (/\r[^\n]/.test(source)) { + eol = '\r'; + foundEolTypeCnt++; + } + if (/[^\r]\n/.test(source)) { + eol = '\n'; + foundEolTypeCnt++; + } + + if (eol == null || foundEolTypeCnt > 1) { + eol = os.EOL; + } + + return eol; +} + +function normalizeEol(source, indent) { + // only process any kind of EOL if indentation has to be added, otherwise replace only non \n EOLs + if (indent) { + source = source.replace(/(?:\r?\n)|\r/g, '\n' + indent); + } else { + source = source.replace(/(?:\r\n)|\r/g, '\n'); + } + + return source; +} + +function restoreEol(normalizedSource, originalEol) { + if (originalEol !== '\n') { + normalizedSource = normalizedSource.replace(/\n/g, originalEol); + } + + return normalizedSource; +} + +function replace(rv, rule, processor) { + var isRegex = typeof rule === 'string' || rule instanceof RegExp; + var isArray = Array.isArray(rule); + + if (isRegex) { + rule = [new RegExp(rule,'gmi')]; + } else if (isArray) { + rule = rule.map(function(subRule){ + return new RegExp(subRule,'gmi'); + }); + } else { + throw new Error('Rule must be a String, a RegExp, or an Array.'); + } + + return rule.reduce(function(rv, rule){ + return rv.replace(rule, processor); + }, rv); +} + +function replaceRecursive(rv, rule, processor) { + if(!rule.start || !rule.end) { + throw new Error('Recursive rule must have start and end.'); + } + + var startRegex = new RegExp(rule.start, 'mi'); + var endRegex = new RegExp(rule.end, 'mi'); + + function matchReplacePass(content) { + var matches = XRegExp.matchRecursive(content, rule.start, rule.end, 'gmi', { + valueNames: ['between', 'left', 'match', 'right'] + }); + + var matchGroup = { + left: null, + match: null, + right: null + }; + + return matches.reduce(function (builder, match) { + switch(match.name) { + case 'between': + builder += match.value; + break; + case 'left': + matchGroup.left = startRegex.exec(match.value); + break; + case 'match': + matchGroup.match = match.value; + break; + case 'right': + matchGroup.right = endRegex.exec(match.value); + builder += processor(matchGroup.left, matchGroup.right, matchGroup.match, matchReplacePass); + break; + } + return builder; + }, ''); + } + + return matchReplacePass(rv); +} + + +function processIncludeDirective(isStatic, context, opts, match, linePrefix, file) { + file = (file || '').trim(); + var indent = linePrefix.replace(/\S/g, ' '); + var includedContext = copy(context); + var includedOpts = copy(opts); + includedContext.src = path.join(opts.srcDir,file); + includedOpts.srcDir = path.dirname(includedContext.src); + + var fileContents = getFileContents(includedContext.src, opts.fileNotFoundSilentFail, context.src); + if (fileContents.error) { + return linePrefix + fileContents.contents; + } + + var includedSource = fileContents.contents; + if (isStatic) { + includedSource = fileContents.contents; + } else { + includedSource = preprocessor(fileContents.contents, includedContext, includedOpts, true); + } + + includedSource = normalizeEol(includedSource, indent); + + if (includedSource) { + return linePrefix + includedSource; + } else { + return linePrefix; + } +} + +function getTestTemplate(test) { + /*jshint evil:true*/ + test = test || 'true'; + test = test.trim(); + + // force single equals replacement + test = test.replace(/([^=!])=([^=])/g, '$1==$2'); + // fixed by xxxxxx + test = test.replace(/-/g, '_') + return new Function("context", "with (context||{}){ return ( " + test + " ); }"); +} + +// fixed by xxxxxx +function testPasses(test, context) { + var testFn = getTestTemplate(test) + try { + return testFn(context, getDeepPropFromObj) + } catch (e) {} + return false +} + +function getFileContents(path, failSilent, requesterPath) { + try { + fs.statSync(path); + } catch (e) { + if (failSilent) { + return {error: true, contents: path + ' not found!'}; + } else { + var errMsg = path; + errMsg = requesterPath ? errMsg + ' requested from ' + requesterPath : errMsg; + errMsg += ' not found!'; + throw new Error(errMsg); + } + } + return {error: false, contents: fs.readFileSync(path).toString()}; +} + +function copy(obj) { + return Object.keys(obj).reduce(function (copyObj, objKey) { + copyObj[objKey] = obj[objKey]; + return copyObj; + }, {}); +} + +function getDeepPropFromObj(obj, propPath) { + propPath.replace(/\[([^\]+?])\]/g, '.$1'); + propPath = propPath.split('.'); + + // fast path, no need to loop if structurePath contains only a single segment + if (propPath.length === 1) { + return obj[propPath[0]]; + } + + // loop only as long as possible (no exceptions for null/undefined property access) + propPath.some(function (pathSegment) { + obj = obj[pathSegment]; + return (obj == null); + }); + + return obj; +} +// fixed by xxxxxx +const splitRE = /\r?\n/g +function padContent(content) { + return Array(content.split(splitRE).length).join('\n') +} \ No newline at end of file diff --git a/packages/uni-mp-weibo/src/compiler/preprocess/regexrules.js b/packages/uni-mp-weibo/src/compiler/preprocess/regexrules.js new file mode 100755 index 00000000000..2372654da03 --- /dev/null +++ b/packages/uni-mp-weibo/src/compiler/preprocess/regexrules.js @@ -0,0 +1,121 @@ + +module.exports = { + simple : { + echo : "^#echo[ \t]+(.*?)[ \t]*$", + exec : "^#exec[ \t]+(\\S+)[ \t]*\\((.*)\\)[ \t]*$", + include : "^(.*)#include(?!-)[ \t]+(.*?)[ \t]*$", // allow prefix characters to specify the indent level of included file + 'include-static' : "^(.*)#include-static[ \t]+(.*?)[ \t]*$" + }, + html : { + echo : "|!>)", + exec : "|!>)", + include : "(.*)|!>)", + 'include-static' : "(.*)|!>)", + exclude : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + }, + extend : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + }, + extendable : "|!>)", + if : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + }, + else : "[ \t]*|!>)(?:[ \t]*\n)?", + foreach : { + start : "[ \t]*|!>)(?:[ \t]*\n+)?", + end : "[ \t]*|!>)(?:[ \t]*\n)?" + } + }, + js : { + echo : [ + "/\\*[ \t]*#echo[ \t]+(.*?)[ \t]*\\*(?:\\*|/)", + "//[ \t]*#echo[ \t]+(.*?)[ \t]*$" + ], + exec : "(?://|/\\*)[ \t]*#exec[ \t]+(\\S+?)[ \t]*\\((.*)\\)[ \t]*(?:\\*(?:\\*|/))?", + include : [ + "^(.*)/\\*[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*\\*(?:\\*|/)", + "^(.*)//[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*$" + ], + 'include-static': [ + "^(.*)/\\*[ \t]*#include-static[ \t]+(.*?)[ \t]*\\*(?:\\*|/)", + "^(.*)//[ \t]*#include-static[ \t]+(.*?)[ \t]*$" + ], + exclude : { + start : "[ \t]*(?://|/\\*)[ \t]*#exclude(?:[ \t]+([^\n*]*))?[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endexclude[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + }, + extend : { + start : "[ \t]*(?://|/\\*)[ \t]*#extend(?!able)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endextend[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + }, + extendable : "[ \t]*(?://|/\\*)[ \t]*#extendable[ \t]*(?:\\*/)?", + if : { + start : "[ \t]*(?://|/\\*)[ \t]*#(ifndef|ifdef|if)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endif[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + }, + else : "[ \t]*(?://|/\\*)[ \t]*#else[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?", + foreach : { + start : "[ \t]*(?://|/\\*)[ \t]*#foreach[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?", + end : "[ \t]*(?://|/\\*)[ \t]*#endfor[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?" + } + }, + coffee : { + echo : [ + "###+[ \t]*#echo[ \t]+(.*?)[ \t]###", + "#+[ \t]*#echo[ \t]+(.*?)[ \t]*$" + ], + exec : "#+[ \t]*#exec[ \t]+(\\S+)[ \t]*\\((.*)\\)[ \t]*$", + include : "^(.*?)#+[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*$", + 'include-static' : "^(.*?)#+[ \t]*#include-static[ \t]+(.*?)[ \t]*$", + exclude : { + start : "^[ \t]*#+[ \t]*#exclude(?:[ \t]+(.*?))?[ \t]*\n+", + end : "^[ \t]*#+[ \t]*#endexclude[ \t]*\n?" + }, + extend : { + start : "^[ \t]*#+[ \t]*#extend(?!able)[ \t]+(.*?)\n+", + end : "^[ \t]*#+[ \t]*#endextend[ \t]*\n?" + }, + extendable : "^[ \t]*#+[ \t]*#extendable[ \t]*$", + if : { + start : "^[ \t]*#+[ \t]*#(ifndef|ifdef|if)[ \t]+(.*?)[ \t]*\n+", + end : "^[ \t]*#+[ \t]*#endif[ \t]*\n?" + }, + else : "^[ \t]*#+[ \t]*#else[ \t]*\n?", + foreach : { + start : "^[ \t]*#+[ \t]*#foreach[ \t]+(.*?)[ \t]*\n+", + end : "^[ \t]*#+[ \t]*#endfor[ \t]*\n?" + } + } +}; + +module.exports.xml = module.exports.html; + +module.exports.javascript = module.exports.js; +module.exports.jsx = module.exports.js; +module.exports.json = module.exports.js; +module.exports.c = module.exports.js; +module.exports.cc = module.exports.js; +module.exports.cpp = module.exports.js; +module.exports.cs = module.exports.js; +module.exports.csharp = module.exports.js; +module.exports.java = module.exports.js; +module.exports.less = module.exports.js; +module.exports.sass = module.exports.js; +module.exports.scss = module.exports.js; +module.exports.css = module.exports.js; +module.exports.php = module.exports.js; +module.exports.ts = module.exports.js; +module.exports.tsx = module.exports.js; +module.exports.peg = module.exports.js; +module.exports.pegjs = module.exports.js; +module.exports.jade = module.exports.js; +module.exports.styl = module.exports.js; +module.exports.go = module.exports.js; + +module.exports.bash = module.exports.coffee; +module.exports.shell = module.exports.coffee; +module.exports.sh = module.exports.coffee; diff --git a/packages/uni-mp-weibo/src/compiler/weiboTemplate.ts b/packages/uni-mp-weibo/src/compiler/weiboTemplate.ts new file mode 100644 index 00000000000..992e7025ae6 --- /dev/null +++ b/packages/uni-mp-weibo/src/compiler/weiboTemplate.ts @@ -0,0 +1,100 @@ +import path from 'path' +import type { Plugin } from 'vite' +// @ts-ignore +import { copySync, emptyDirSync, readFileSync, writeFileSync } from 'fs-extra' +import CJSON from 'comment-json' +import { preJson } from './preprocess' + +export default function uniWeiboSpecialPlugin(): Plugin { + return { + name: 'uni:weibo', + enforce: 'pre', + buildEnd() { + const fileDIR = path.join(process.env.UNI_OUTPUT_DIR, '../', '../', '../') + emptyDirSync(fileDIR) + // 复制文件夹 + copySync( + path.resolve('node_modules/@dcloudio/uni-mp-weibo/template'), + fileDIR + ) + // STAER: 读取用户在 manifest.json 中配置的 appid 并修改微博 wbox.config.json 中配置的 appid。 + const manifestJsonPath = path.join( + process.env.UNI_INPUT_DIR, + 'manifest.json' + ) + const manifestJson: any = CJSON.parse( + readFileSync(manifestJsonPath, 'utf8') + ) + if (manifestJson['mp-weibo'] && manifestJson['mp-weibo'].appid) { + const mpWeiboAppid = manifestJson['mp-weibo'].appid + const wboxConfigJsonPath = path.join(fileDIR, 'wbox.config.json') + const wboxConfigJson: any = CJSON.parse( + readFileSync(wboxConfigJsonPath, 'utf8') + ) + wboxConfigJson.appId = mpWeiboAppid + writeFileSync( + wboxConfigJsonPath, + CJSON.stringify(wboxConfigJson, null, 2) + ) + } + // END: 读取用户在 manifest.json 中配置的 appid 并修改微博 wbox.config.json 中配置的 appid。 + + // STAER: 解析 pages.json 中的内容,生成 page 页面及 app.json 文件。 + const pagesJsonPath = path.join(process.env.UNI_INPUT_DIR, 'pages.json') + const pagesJsonStr = readFileSync(pagesJsonPath, 'utf8') + // preJson 处理 page.json 中的条件编译 + const pagesJson: any = CJSON.parse(preJson(pagesJsonStr)) + let pageOptions = pagesJson.pages + if (pagesJson.subPackages && pagesJson.subPackages.length) { + pagesJson.subPackages.forEach((subPackage: any) => { + pageOptions = pageOptions.concat( + subPackage.pages.map((item: any) => ({ + // eslint-disable-next-line no-restricted-syntax + ...item, + path: `${subPackage.root}/${item.path}`, + })) + ) + }) + } + // ==> STAER: 根据 pages.json 生成 app.json + const appPages = pageOptions.map((item: any) => item.path) + const appJsonPath = path.join(fileDIR, 'src', 'app.json') + const appJson: any = CJSON.parse(readFileSync(appJsonPath, 'utf8')) + appJson.pages = appPages + if (pagesJson.globalStyle) { + appJson.window = Object.assign(appJson.window, pagesJson.globalStyle) + } + writeFileSync(appJsonPath, CJSON.stringify(appJson, null, 2)) + // ==> END: 根据 pages.json 生成 app.json + + // ==> STAER: 根据 pages.json 生成 pages 目录 + const templatePagePath = path.resolve( + 'node_modules/@dcloudio/uni-mp-weibo/template/src/pages/index/index' + ) + const pageFileSuffixs = ['.vue', '.css', '.json'] + pageOptions.forEach((pageInfo: any) => { + const targetPagePath = path.resolve(fileDIR, 'src', pageInfo.path) + pageFileSuffixs.forEach((suffix) => { + copySync(`${templatePagePath}${suffix}`, `${targetPagePath}${suffix}`) + // 覆写 page.json 配置文件 + if ( + suffix === '.json' && + pageInfo.style && + Object.keys(pageInfo.style).length > 0 + ) { + let pageJson: any = CJSON.parse( + readFileSync(`${targetPagePath}${suffix}`, 'utf8') + ) + pageJson = Object.assign(pageJson, pageInfo.style) + writeFileSync( + `${targetPagePath}${suffix}`, + CJSON.stringify(pageJson, null, 2) + ) + } + }) + }) + // ==> END: 根据 pages.json 生成 pages 目录 + // END: 解析 pages.json 中的内容,生成 page 页面及 app.json 文件。 + }, + } +} diff --git a/packages/uni-mp-weibo/src/framework/components/async-error/index.tsx b/packages/uni-mp-weibo/src/framework/components/async-error/index.tsx new file mode 100644 index 00000000000..8d611a533ca --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/async-error/index.tsx @@ -0,0 +1,19 @@ +import { defineSystemComponent } from '@dcloudio/uni-components' +import { useI18n, initI18nAsyncMsgsOnce } from '@dcloudio/uni-core' + +function reload() { + window.location.reload() +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'AsyncError', + setup() { + initI18nAsyncMsgsOnce() + const { t } = useI18n() + return () => ( +
    + {t('uni.async.error')} +
    + ) + }, +}) diff --git a/packages/uni-mp-weibo/src/framework/components/async-loading/index.ts b/packages/uni-mp-weibo/src/framework/components/async-loading/index.ts new file mode 100644 index 00000000000..85601c2fff5 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/async-loading/index.ts @@ -0,0 +1,16 @@ +import { createBlock, createVNode, openBlock } from 'vue' +import { defineSystemComponent } from '@dcloudio/uni-components' +const clazz = { class: 'uni-async-loading' } +const loadingVNode = /*#__PURE__*/ createVNode( + 'i', + { class: 'uni-loading' }, + null, + -1 /* HOISTED */ +) + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'AsyncLoading', + render() { + return openBlock(), createBlock('div', clazz, [loadingVNode]) + }, +}) diff --git a/packages/uni-mp-weibo/src/framework/components/layout/index.tsx b/packages/uni-mp-weibo/src/framework/components/layout/index.tsx new file mode 100644 index 00000000000..30b70c8a0f8 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/index.tsx @@ -0,0 +1,574 @@ +import { + ref, + withCtx, + computed, + ComputedRef, + KeepAlive, + openBlock, + createBlock, + createVNode, + SetupContext, + resolveDynamicComponent, + defineComponent, + reactive, + onMounted, + ComponentPublicInstance, + Ref, + watch, + nextTick, +} from 'vue' + +import { RouterView } from 'vue-router' + +import { defineSystemComponent } from '@dcloudio/uni-components' +import { getRouteOptions, updateCssVar } from '@dcloudio/uni-core' +import { useTabBar } from '../../setup/state' +import { useKeepAliveRoute } from '../../setup/page' +import { + resolveOwnerEl, + RESPONSIVE_MIN_WIDTH, + ON_NAVIGATION_BAR_CHANGE, +} from '@dcloudio/uni-shared' +import { checkMinWidth } from '../../../helpers/dom' +import { hasOwn } from '@vue/shared' + +import TabBar from './tabBar' +import { usePageRoute } from '../../setup/provide' + +type KeepAliveRoute = ReturnType + +const DEFAULT_CSS_VAR_VALUE = '0px' + +let globalLayoutState: LayoutState | undefined = undefined +export function getLayoutState() { + return globalLayoutState +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'Layout', + setup(_props, { emit }) { + const rootRef: Ref = ref(null) + !__NODE_JS__ && initCssVar() + const keepAliveRoute = (__UNI_FEATURE_PAGES__ && + useKeepAliveRoute()) as KeepAliveRoute + const { layoutState, windowState } = useState() + useMaxWidth(layoutState, rootRef) + const topWindow = __UNI_FEATURE_TOPWINDOW__ && useTopWindow(layoutState!) + const leftWindow = __UNI_FEATURE_LEFTWINDOW__ && useLeftWindow(layoutState!) + const rightWindow = + __UNI_FEATURE_RIGHTWINDOW__ && useRightWindow(layoutState!) + const showTabBar = (__UNI_FEATURE_TABBAR__ && + useShowTabBar(emit)) as ComputedRef + const clazz = useAppClass(showTabBar) + globalLayoutState = layoutState + return () => { + const layoutTsx = createLayoutTsx( + keepAliveRoute, + layoutState, + windowState, + topWindow, + leftWindow, + rightWindow + ) + const tabBarTsx = __UNI_FEATURE_TABBAR__ && createTabBarTsx(showTabBar) + return ( + + {layoutTsx} + {tabBarTsx} + + ) + } + }, +}) + +function useAppClass(showTabBar?: ComputedRef) { + const showMaxWidth = ref(false) + return computed(() => { + return { + 'uni-app--showtabbar': showTabBar && showTabBar.value, + 'uni-app--maxwidth': showMaxWidth.value, + } + }) +} + +function initCssVar() { + updateCssVar({ + '--status-bar-height': DEFAULT_CSS_VAR_VALUE, + '--top-window-height': DEFAULT_CSS_VAR_VALUE, + '--window-left': DEFAULT_CSS_VAR_VALUE, + '--window-right': DEFAULT_CSS_VAR_VALUE, + '--window-margin': DEFAULT_CSS_VAR_VALUE, + '--tab-bar-height': DEFAULT_CSS_VAR_VALUE, + }) +} +interface LayoutState { + topWindowMediaQuery: boolean + showTopWindow: boolean + apiShowTopWindow: boolean + leftWindowMediaQuery: boolean + showLeftWindow: boolean + apiShowLeftWindow: boolean + rightWindowMediaQuery: boolean + showRightWindow: boolean + apiShowRightWindow: boolean + topWindowHeight: number + marginWidth: number + leftWindowWidth: number + rightWindowWidth: number + navigationBarTitleText: string + topWindowStyle: unknown + leftWindowStyle: unknown + rightWindowStyle: unknown +} +interface WindowState { + matchTopWindow?: boolean + showTopWindow?: boolean + matchLeftWindow?: boolean + showLeftWindow?: boolean + matchRightWindow?: boolean + showRightWindow?: boolean +} + +function initMediaQuery( + minWidth: number, + callback: (ev: MediaQueryListEvent) => void +) { + if (__NODE_JS__) { + return false + } + const mediaQueryList = window.matchMedia('(min-width: ' + minWidth + 'px)') + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener('change', callback) + } else { + mediaQueryList.addListener(callback) + } + return mediaQueryList.matches +} + +function useMaxWidth( + layoutState: LayoutState, + rootRef: Ref +) { + const route = usePageRoute() + function checkMaxWidth() { + const windowWidth = document.body.clientWidth + + const pages = getCurrentPages() + let meta = {} as UniApp.PageRouteMeta + if (pages.length > 0) { + const curPage = pages[pages.length - 1] + meta = curPage.$page.meta + } else { + const routeOptions = getRouteOptions(route.path, true) + if (routeOptions) { + meta = routeOptions.meta + } + } + + const maxWidth = parseInt( + String( + (hasOwn(meta, 'maxWidth') + ? meta.maxWidth + : __uniConfig.globalStyle.maxWidth) || Number.MAX_SAFE_INTEGER + ) + ) + let showMaxWidth = false + if (windowWidth > maxWidth) { + showMaxWidth = true + } else { + showMaxWidth = false + } + if (showMaxWidth && maxWidth) { + layoutState.marginWidth = (windowWidth - maxWidth) / 2 + nextTick(() => { + const rootEl = rootRef.value + if (rootEl) { + rootEl.setAttribute( + 'style', + 'max-width:' + maxWidth + 'px;margin:0 auto;' + ) + } + }) + } else { + layoutState.marginWidth = 0 + nextTick(() => { + const rootEl = rootRef.value + if (rootEl) { + rootEl.removeAttribute('style') + } + }) + } + } + watch([() => route.path], checkMaxWidth) + onMounted(() => { + checkMaxWidth() + window.addEventListener('resize', checkMaxWidth) + }) +} + +function useState() { + const route = usePageRoute() + if (!__UNI_FEATURE_RESPONSIVE__) { + // max width + const layoutState = reactive({ + marginWidth: 0, + leftWindowWidth: 0, + rightWindowWidth: 0, + }) as LayoutState + watch( + () => layoutState.marginWidth, + (value) => updateCssVar({ '--window-margin': value + 'px' }) + ) + watch( + () => layoutState.leftWindowWidth + layoutState.marginWidth, + (value) => { + updateCssVar({ '--window-left': value + 'px' }) + } + ) + watch( + () => layoutState.rightWindowWidth + layoutState.marginWidth, + (value) => { + updateCssVar({ '--window-right': value + 'px' }) + } + ) + return { + layoutState, + windowState: computed(() => ({})), + } + } + const topWindowMediaQuery = ref(false) + const leftWindowMediaQuery = ref(false) + const rightWindowMediaQuery = ref(false) + const showTopWindow = computed( + () => + __UNI_FEATURE_TOPWINDOW__ && + route.meta.topWindow !== false && + topWindowMediaQuery.value + ) + const showLeftWindow = computed( + () => + __UNI_FEATURE_LEFTWINDOW__ && + route.meta.leftWindow !== false && + leftWindowMediaQuery.value + ) + const showRightWindow = computed( + () => + __UNI_FEATURE_RIGHTWINDOW__ && + route.meta.rightWindow !== false && + rightWindowMediaQuery.value + ) + const layoutState: LayoutState = reactive({ + topWindowMediaQuery, + showTopWindow, + apiShowTopWindow: false, + leftWindowMediaQuery, + showLeftWindow, + apiShowLeftWindow: false, + rightWindowMediaQuery, + showRightWindow, + apiShowRightWindow: false, + topWindowHeight: 0, + marginWidth: 0, + leftWindowWidth: 0, + rightWindowWidth: 0, + navigationBarTitleText: '', + topWindowStyle: {}, + leftWindowStyle: {}, + rightWindowStyle: {}, + }) + const props: Array<'topWindow' | 'leftWindow' | 'rightWindow'> = [ + 'topWindow', + 'leftWindow', + 'rightWindow', + ] + type StateProps = + | 'topWindowMediaQuery' + | 'leftWindowMediaQuery' + | 'rightWindowMediaQuery' + props.forEach((prop) => { + const matchMedia = __uniConfig[prop]?.matchMedia + let topWindowMinWidth = RESPONSIVE_MIN_WIDTH + if (matchMedia && hasOwn(matchMedia, 'minWidth')) { + const minWidth = matchMedia.minWidth! + topWindowMinWidth = checkMinWidth(minWidth) ? minWidth : topWindowMinWidth + } + const matches = initMediaQuery(topWindowMinWidth, (ev) => { + layoutState[`${prop}MediaQuery` as StateProps] = ev.matches + }) + layoutState[`${prop}MediaQuery` as StateProps] = matches + }) + watch( + () => layoutState.topWindowHeight, + (value) => updateCssVar({ '--top-window-height': value + 'px' }) + ) + watch( + () => layoutState.marginWidth, + (value) => updateCssVar({ '--window-margin': value + 'px' }) + ) + watch( + () => layoutState.leftWindowWidth + layoutState.marginWidth, + (value) => { + updateCssVar({ '--window-left': value + 'px' }) + } + ) + watch( + () => layoutState.rightWindowWidth + layoutState.marginWidth, + (value) => { + updateCssVar({ '--window-right': value + 'px' }) + } + ) + UniServiceJSBridge.on(ON_NAVIGATION_BAR_CHANGE, (navigationBar) => { + layoutState.navigationBarTitleText = navigationBar.titleText + }) + const windowState = computed(() => ({ + matchTopWindow: layoutState.topWindowMediaQuery, + showTopWindow: layoutState.showTopWindow || layoutState.apiShowTopWindow, + matchLeftWindow: layoutState.leftWindowMediaQuery, + showLeftWindow: layoutState.showLeftWindow || layoutState.apiShowLeftWindow, + matchRightWindow: layoutState.rightWindowMediaQuery, + showRightWindow: + layoutState.showRightWindow || layoutState.apiShowRightWindow, + })) + return { + layoutState, + windowState, + } +} + +function createLayoutTsx( + keepAliveRoute: KeepAliveRoute, + layoutState: LayoutState, + windowState: ComputedRef, + topWindow?: unknown, + leftWindow?: unknown, + rightWindow?: unknown +) { + const routerVNode = __UNI_FEATURE_PAGES__ + ? createRouterViewVNode(keepAliveRoute) + : createPageVNode() + // 非响应式 + if (!__UNI_FEATURE_RESPONSIVE__) { + return routerVNode + } + const topWindowTsx = __UNI_FEATURE_TOPWINDOW__ + ? createTopWindowTsx(topWindow, layoutState, windowState.value) + : null + const leftWindowTsx = __UNI_FEATURE_LEFTWINDOW__ + ? createLeftWindowTsx(leftWindow, layoutState, windowState.value) + : null + const rightWindowTsx = __UNI_FEATURE_RIGHTWINDOW__ + ? createRightWindowTsx(rightWindow, layoutState, windowState.value) + : null + return ( + + {topWindowTsx} + + {routerVNode} + {leftWindowTsx} + {rightWindowTsx} + + + ) +} + +function useShowTabBar(emit: SetupContext<['change']>['emit']) { + const route = usePageRoute() + const tabBar = useTabBar()! + // TODO meida query + const showTabBar = computed(() => route.meta.isTabBar && tabBar.shown) + !__NODE_JS__ && + updateCssVar({ + '--tab-bar-height': tabBar.height!, + }) + return showTabBar +} + +function createTabBarTsx(showTabBar: ComputedRef) { + return +} + +function createPageVNode() { + return createVNode(__uniRoutes[0].component) +} + +function createRouterViewVNode({ + routeKey, + isTabBar, + routeCache, +}: ReturnType) { + return createVNode(RouterView, null, { + default: withCtx(({ Component }: { Component: unknown }) => [ + (openBlock(), + createBlock( + KeepAlive, + { matchBy: 'key', cache: routeCache }, + [ + (openBlock(), + createBlock(resolveDynamicComponent(Component), { + type: isTabBar.value ? 'tabBar' : '', + key: routeKey.value, + })), + ], + 1032 /* PROPS, DYNAMIC_SLOTS */, + ['cache'] + )), + ]), + _: 1 /* STABLE */, + }) +} + +interface WindowComponentInfo { + component: ReturnType + windowRef: Ref +} + +function useTopWindow(layoutState: LayoutState): WindowComponentInfo { + const { component, style } = __uniConfig.topWindow! + const windowRef: Ref = ref(null) + function updateWindow() { + const instance = windowRef.value as ComponentPublicInstance + const el = resolveOwnerEl(instance.$) as HTMLElement + const height = el.getBoundingClientRect().height + layoutState.topWindowHeight = height + } + onMounted(updateWindow) + watch( + () => layoutState.showTopWindow || layoutState.apiShowTopWindow, + () => nextTick(updateWindow) + ) + layoutState.topWindowStyle = style + return { + component, + windowRef, + } +} +function useLeftWindow(layoutState: LayoutState): WindowComponentInfo { + const { component, style } = __uniConfig.leftWindow! + const windowRef: Ref = ref(null) + function updateWindow() { + const instance = windowRef.value as ComponentPublicInstance + const el = resolveOwnerEl(instance.$) as HTMLElement + const width = el.getBoundingClientRect().width + layoutState.leftWindowWidth = width + } + onMounted(updateWindow) + watch( + () => layoutState.showLeftWindow || layoutState.apiShowLeftWindow, + () => nextTick(updateWindow) + ) + layoutState.leftWindowStyle = style + return { + component, + windowRef, + } +} +function useRightWindow(layoutState: LayoutState): WindowComponentInfo { + const { component, style } = __uniConfig.rightWindow! + const windowRef: Ref = ref(null) + function updateWindow() { + const instance = windowRef.value as ComponentPublicInstance + const el = resolveOwnerEl(instance.$) as HTMLElement + const width = el.getBoundingClientRect().width + layoutState.rightWindowWidth = width + } + onMounted(updateWindow) + watch( + () => layoutState.showRightWindow || layoutState.apiShowRightWindow, + () => nextTick(updateWindow) + ) + layoutState.rightWindowStyle = style + return { + component, + windowRef, + } +} + +function createTopWindowTsx( + topWindow: unknown, + layoutState: LayoutState, + windowState: WindowState +) { + if (topWindow) { + const { component: TopWindow, windowRef } = topWindow as WindowComponentInfo + return ( + +
    + +
    +
    + + ) + } +} +function createLeftWindowTsx( + leftWindow: unknown, + layoutState: LayoutState, + windowState: WindowState +) { + if (leftWindow) { + const { component: LeftWindow, windowRef } = + leftWindow as WindowComponentInfo + return ( + + {layoutState.apiShowLeftWindow ? ( +
    (layoutState.apiShowLeftWindow = false)} + /> + ) : null} +
    + +
    + + ) + } +} +function createRightWindowTsx( + rightWindow: unknown, + layoutState: LayoutState, + windowState: WindowState +) { + if (rightWindow) { + const { component: RightWindow, windowRef } = + rightWindow as WindowComponentInfo + return ( + + {layoutState.apiShowRightWindow ? ( +
    (layoutState.apiShowRightWindow = false)} + /> + ) : null} +
    + +
    + + ) + } +} diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/actionSheet.vue b/packages/uni-mp-weibo/src/framework/components/layout/popup/actionSheet.vue new file mode 100644 index 00000000000..2862efeccca --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/actionSheet.vue @@ -0,0 +1,335 @@ + + + diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/index.js b/packages/uni-mp-weibo/src/framework/components/layout/popup/index.js new file mode 100644 index 00000000000..866d78a28a3 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/index.js @@ -0,0 +1,9 @@ +import Toast from './toast' +import Modal from './modal' +import ActionSheet from './actionSheet' + +export default { + Toast, + Modal, + ActionSheet, +} diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/action-sheet.js b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/action-sheet.js new file mode 100644 index 00000000000..c85b4e48835 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/action-sheet.js @@ -0,0 +1,28 @@ +import { isFn } from 'uni-shared' + +export default { + data() { + return { + showActionSheet: { + visible: false, + }, + } + }, + created() { + UniServiceJSBridge.on('onShowActionSheet', (args, callback) => { + this.showActionSheet = args + this.onActionSheetCloseCallback = callback + }) + UniServiceJSBridge.on('onHidePopup', (args) => { + this.showActionSheet.visible = false + }) + }, + methods: { + // 处理 actionSheet close 回调 + _onActionSheetClose(type) { + this.showActionSheet.visible = false + isFn(this.onActionSheetCloseCallback) && + this.onActionSheetCloseCallback(type) + }, + }, +} diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/index.js b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/index.js new file mode 100644 index 00000000000..61084cf1252 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/index.js @@ -0,0 +1,8 @@ +const mixins = [] +const context = require.context('./', false, /\.js$/) +context.keys().forEach(function (key) { + if (key !== './index.js') { + mixins.push(context(key).default) + } +}) +export default mixins diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/modal.js b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/modal.js new file mode 100644 index 00000000000..f84ce6991a4 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/modal.js @@ -0,0 +1,27 @@ +import { isFn } from 'uni-shared' + +export default { + data() { + return { + showModal: { + visible: false, + }, + } + }, + created() { + UniServiceJSBridge.on('onShowModal', (args, callback) => { + this.showModal = args + this.onModalCloseCallback = callback + }) + UniServiceJSBridge.on('onHidePopup', (args) => { + this.showModal.visible = false + }) + }, + methods: { + // 处理 modal close 回调 + _onModalClose(type) { + this.showModal.visible = false + isFn(this.onModalCloseCallback) && this.onModalCloseCallback(type) + }, + }, +} diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/popup.js b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/popup.js new file mode 100644 index 00000000000..d76cb2ae558 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/popup.js @@ -0,0 +1,70 @@ +export default { + data() { + return { + popupWidth: 0, + popupHeight: 0, + } + }, + computed: { + isDesktop() { + return this.popupWidth >= 500 && this.popupHeight >= 500 + }, + popupStyle() { + const style = {} + const contentStyle = (style.content = {}) + const triangleStyle = (style.triangle = {}) + const popover = this.popover + function getNumber(value) { + return Number(value) || 0 + } + if (this.isDesktop && popover) { + Object.assign(triangleStyle, { + position: 'absolute', + width: '0', + height: '0', + 'margin-left': '-6px', + 'border-style': 'solid', + }) + const popoverLeft = getNumber(popover.left) + const popoverWidth = getNumber(popover.width) + const popoverTop = getNumber(popover.top) + const popoverHeight = getNumber(popover.height) + const center = popoverLeft + popoverWidth / 2 + contentStyle.transform = 'none !important' + const contentLeft = Math.max(0, center - 300 / 2) + contentStyle.left = `${contentLeft}px` + let triangleLeft = Math.max(12, center - contentLeft) + triangleLeft = Math.min(300 - 12, triangleLeft) + triangleStyle.left = `${triangleLeft}px` + const vcl = this.popupHeight / 2 + if (popoverTop + popoverHeight - vcl > vcl - popoverTop) { + contentStyle.top = 'auto' + contentStyle.bottom = `${this.popupHeight - popoverTop + 6}px` + triangleStyle.bottom = '-6px' + triangleStyle['border-width'] = '6px 6px 0 6px' + triangleStyle['border-color'] = + '#fcfcfd transparent transparent transparent' + } else { + contentStyle.top = `${popoverTop + popoverHeight + 6}px` + triangleStyle.top = '-6px' + triangleStyle['border-width'] = '0 6px 6px 6px' + triangleStyle['border-color'] = + 'transparent transparent #fcfcfd transparent' + } + } + return style + }, + }, + mounted() { + const fixSize = () => { + const { windowWidth, windowHeight, windowTop } = uni.getSystemInfoSync() + this.popupWidth = windowWidth + this.popupHeight = windowHeight + windowTop + } + window.addEventListener('resize', fixSize) + fixSize() + this.$once('hook:beforeDestroy', () => { + window.removeEventListener('resize', fixSize) + }) + }, +} diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/toast.js b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/toast.js new file mode 100644 index 00000000000..07fd60273fc --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/toast.js @@ -0,0 +1,52 @@ +import { t } from 'uni-core/helpers/i18n' +export default { + data() { + return { + showToast: { + visible: false, + }, + } + }, + created() { + let showType = '' + + const createOnShow = (type) => { + return (args) => { + showType = type + setTimeout(() => { + // 延迟一下 show 可解决窗口打开前调用 showToast 在 onHidePopup 之后触发 + this.showToast = args + }, 10) + } + } + + UniServiceJSBridge.on('onShowToast', createOnShow('onShowToast')) + UniServiceJSBridge.on('onShowLoading', createOnShow('onShowLoading')) + + const createOnHide = (type) => { + return () => { + if (!showType) { + return + } + let warnMsg = '' + if (type === 'onHideToast' && showType !== 'onShowToast') { + warnMsg = t('uni.showToast.unpaired') + } else if (type === 'onHideLoading' && showType !== 'onShowLoading') { + warnMsg = t('uni.showLoading.unpaired') + } + if (warnMsg) { + return console.warn(warnMsg) + } + showType = '' + setTimeout(() => { + // 与 show 对应延迟10ms,避免快速调用 show,hide 导致无法关闭 + this.showToast.visible = false + }, 10) + } + } + + UniServiceJSBridge.on('onHidePopup', createOnHide('onHidePopup')) + UniServiceJSBridge.on('onHideToast', createOnHide('onHideToast')) + UniServiceJSBridge.on('onHideLoading', createOnHide('onHideLoading')) + }, +} diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/transition.js b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/transition.js new file mode 100644 index 00000000000..c641ec929e3 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/mixins/transition.js @@ -0,0 +1,6 @@ +export default { + methods: { + beforeTransition() {}, + afterTransition() {}, + }, +} diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/modal.vue b/packages/uni-mp-weibo/src/framework/components/layout/popup/modal.vue new file mode 100644 index 00000000000..2a82a945049 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/modal.vue @@ -0,0 +1,217 @@ + + + diff --git a/packages/uni-mp-weibo/src/framework/components/layout/popup/toast.vue b/packages/uni-mp-weibo/src/framework/components/layout/popup/toast.vue new file mode 100644 index 00000000000..052bbec714d --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/popup/toast.vue @@ -0,0 +1,181 @@ + + + diff --git a/packages/uni-mp-weibo/src/framework/components/layout/tabBar.tsx b/packages/uni-mp-weibo/src/framework/components/layout/tabBar.tsx new file mode 100644 index 00000000000..23e74dad080 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/layout/tabBar.tsx @@ -0,0 +1,450 @@ +import { + watch, + watchEffect, + computed, + ref, + Ref, + onMounted, + reactive, +} from 'vue' +import { extend } from '@vue/shared' +import { RouteLocationNormalizedLoaded, useRoute } from 'vue-router' +import { invokeHook, updatePageCssVar } from '@dcloudio/uni-core' +import { + API_ON_TAB_BAR_MID_BUTTON_TAP, + OnTabBarMidButtonTap, +} from '@dcloudio/uni-api' +import { addLeadingSlash } from '@dcloudio/uni-shared' +import { defineSystemComponent } from '@dcloudio/uni-components' +import { getRealPath } from '../../../platform' +import { useTabBar } from '../../setup/state' +import { cssBackdropFilter } from '../../../service/api/base/canIUse' +import { loadFontFace } from '../../../service/api/ui/loadFontFace' +import { normalizeWindowBottom } from '../../../helpers/cssVar' +import { parseTheme, onThemeChange } from '../../../helpers/theme' + +const UNI_TABBAR_ICON_FONT = 'UniTabbarIconFont' + +const _middleButton = { + width: '50px', + height: '50px', + iconWidth: '24px', +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'TabBar', + setup() { + const visibleList = ref([]) + const _tabBar = useTabBar()! + const tabBar = reactive(parseTheme(_tabBar)) + useVisibleList(tabBar, visibleList) + useTabBarCssVar(tabBar) + const onSwitchTab = useSwitchTab(useRoute(), tabBar, visibleList) + const { style, borderStyle, placeholderStyle } = useTabBarStyle(tabBar) + + onThemeChange(() => { + const tabBarStyle = parseTheme(_tabBar) + tabBar.backgroundColor = tabBarStyle.backgroundColor + tabBar.borderStyle = tabBarStyle.borderStyle + tabBar.color = tabBarStyle.color + tabBar.selectedColor = tabBarStyle.selectedColor + tabBar.blurEffect = tabBarStyle.blurEffect + if (tabBarStyle.list && tabBarStyle.list.length) { + tabBarStyle.list.forEach((item, index) => { + tabBar.list[index].iconPath = item.iconPath + tabBar.list[index].selectedIconPath = item.selectedIconPath + }) + } + }) + + onMounted(() => { + if (tabBar.iconfontSrc) { + loadFontFace({ + family: UNI_TABBAR_ICON_FONT, + source: `url("${tabBar.iconfontSrc}")`, + }) + } + }) + + return () => { + const tabBarItemsTsx = createTabBarItemsTsx( + tabBar, + onSwitchTab, + visibleList + ) + return ( + +
    +
    + {tabBarItemsTsx} +
    +
    +
    + ) + } + }, +}) + +function useTabBarCssVar(tabBar: UniApp.TabBarOptions) { + watch( + () => tabBar.shown, + (value) => { + updatePageCssVar({ + '--window-bottom': normalizeWindowBottom( + value ? parseInt(tabBar.height!) : 0 + ), + }) + } + ) +} + +function useVisibleList( + tabBar: UniApp.TabBarOptions, + visibleList: Ref +) { + const internalMidButton = ref( + extend({ type: 'midButton' }, tabBar.midButton) + ) + function setVisibleList() { + let tempList = [] + tempList = tabBar.list.filter((item) => item.visible !== false) + + if (__UNI_FEATURE_TABBAR_MIDBUTTON__ && tabBar.midButton) { + internalMidButton.value = extend( + {}, + _middleButton, + internalMidButton.value, + tabBar.midButton + ) + tempList = tempList.filter((item) => !isMidButton(item)) + + if (tempList.length % 2 === 0) { + tempList.splice( + Math.floor(tempList.length / 2), + 0, + internalMidButton.value + ) + } + } + + visibleList.value = tempList + } + + watchEffect(setVisibleList) +} + +function useSwitchTab( + route: RouteLocationNormalizedLoaded, + tabBar: UniApp.TabBarOptions, + visibleList: Ref +) { + watchEffect(() => { + const meta = route.meta + if (meta.isTabBar) { + const pagePath = meta.route + const index = visibleList.value.findIndex( + (item) => item.pagePath === pagePath + ) + tabBar.selectedIndex = index + } + }) + return (tabBarItem: UniApp.TabBarItemOptions, index: number) => { + const { type } = tabBarItem + return () => { + if (__UNI_FEATURE_TABBAR_MIDBUTTON__ && type === 'midButton') { + return UniServiceJSBridge.invokeOnCallback( + API_ON_TAB_BAR_MID_BUTTON_TAP + ) + } + const { pagePath, text } = tabBarItem + let url = addLeadingSlash(pagePath) + if (url === __uniRoutes[0].alias) { + url = '/' + } + if (route.path !== url) { + uni.switchTab({ from: 'tabBar', url, tabBarText: text } as any) + } else { + invokeHook('onTabItemTap', { + index, + text, + pagePath, + }) + } + } + } +} + +type OnSwtichTab = ReturnType + +const DEFAULT_BG_COLOR = '#f7f7fa' + +const BLUR_EFFECT_COLOR_DARK = 'rgb(0, 0, 0, 0.8)' +const BLUR_EFFECT_COLOR_LIGHT = 'rgb(250, 250, 250, 0.8)' +const BLUR_EFFECT_COLORS = { + dark: BLUR_EFFECT_COLOR_DARK, + light: BLUR_EFFECT_COLOR_LIGHT, + extralight: BLUR_EFFECT_COLOR_LIGHT, +} + +const BORDER_COLORS = { + white: 'rgba(255, 255, 255, 0.33)', + black: 'rgba(0, 0, 0, 0.33)', +} +function useTabBarStyle(tabBar: UniApp.TabBarOptions) { + const style = computed(() => { + let backgroundColor = tabBar.backgroundColor + const blurEffect = tabBar.blurEffect + if (!backgroundColor) { + if (cssBackdropFilter && blurEffect && blurEffect !== 'none') { + backgroundColor = BLUR_EFFECT_COLORS[blurEffect] + } + } + return { + backgroundColor: backgroundColor || DEFAULT_BG_COLOR, + backdropFilter: blurEffect !== 'none' ? 'blur(10px)' : blurEffect, + } + }) + const borderStyle = computed(() => { + const { borderStyle } = tabBar + return { + backgroundColor: BORDER_COLORS[borderStyle!] || borderStyle, + } + }) + const placeholderStyle = computed(() => { + return { + height: tabBar.height!, + } + }) + return { + style, + borderStyle, + placeholderStyle, + } +} + +function isMidButton(item: unknown): item is UniApp.TabBarMidButtonOptions { + return (item as any).type === 'midButton' +} + +function createTabBarItemsTsx( + tabBar: UniApp.TabBarOptions, + onSwitchTab: OnSwtichTab, + visibleList: Ref +) { + const { selectedIndex, selectedColor, color } = tabBar + return visibleList.value.map((item, index) => { + const selected = selectedIndex === index + const textColor = selected ? selectedColor : color + const iconPath = + (selected ? item.selectedIconPath || item.iconPath : item.iconPath) || '' + const iconfontText = item.iconfont + ? selected + ? item.iconfont.selectedText || item.iconfont.text + : item.iconfont.text + : undefined + const iconfontColor = item.iconfont + ? selected + ? item.iconfont.selectedColor || item.iconfont.color + : item.iconfont.color + : undefined + if (!__UNI_FEATURE_TABBAR_MIDBUTTON__) { + return createTabBarItemTsx( + textColor, + iconPath, + iconfontText, + iconfontColor, + item, + tabBar, + index, + onSwitchTab + ) + } + return isMidButton(item) + ? createTabBarMidButtonTsx( + textColor, + iconPath, + iconfontText, + iconfontColor, + item, + tabBar, + index, + onSwitchTab + ) + : createTabBarItemTsx( + textColor, + iconPath, + iconfontText, + iconfontColor, + item, + tabBar, + index, + onSwitchTab + ) + }) +} + +function createTabBarItemTsx( + color: string, + iconPath: string, + iconfontText: string | undefined, + iconfontColor: string | undefined, + tabBarItem: UniApp.TabBarItemOptions, + tabBar: UniApp.TabBarOptions, + index: number, + onSwitchTab: OnSwtichTab +) { + return ( +
    + {createTabBarItemBdTsx( + color, + iconPath || '', + iconfontText, + iconfontColor, + tabBarItem, + tabBar + )} +
    + ) +} + +function createTabBarItemBdTsx( + color: string, + iconPath: string, + iconfontText: string | undefined, + iconfontColor: string | undefined, + tabBarItem: UniApp.TabBarItemOptions, + tabBar: UniApp.TabBarOptions +) { + const { height } = tabBar + return ( +
    + {iconfontText + ? createTabBarItemIconfontTsx( + iconfontText, + iconfontColor || BLUR_EFFECT_COLOR_DARK, + tabBarItem, + tabBar + ) + : iconPath && createTabBarItemIconTsx(iconPath, tabBarItem, tabBar)} + {tabBarItem.text && createTabBarItemTextTsx(color, tabBarItem, tabBar)} + {tabBarItem.redDot && createTabBarItemRedDotTsx(tabBarItem.badge)} +
    + ) +} + +function createTabBarItemIconTsx( + iconPath: string, + tabBarItem: UniApp.TabBarItemOptions, + tabBar: UniApp.TabBarOptions +) { + const { type, text } = tabBarItem + const { iconWidth } = tabBar + const clazz = 'uni-tabbar__icon' + (text ? ' uni-tabbar__icon__diff' : '') + const style = { width: iconWidth, height: iconWidth } + return ( +
    + {type !== 'midButton' && } +
    + ) +} + +function createTabBarItemIconfontTsx( + iconfontText: string, + iconfontColor: string, + tabBarItem: UniApp.TabBarItemOptions, + tabBar: UniApp.TabBarOptions +) { + const { type, text } = tabBarItem + const { iconWidth } = tabBar + const clazz = 'uni-tabbar__icon' + (text ? ' uni-tabbar__icon__diff' : '') + const style = { width: iconWidth, height: iconWidth } + const iconfontStyle = { + fontSize: tabBarItem.iconfont?.fontSize || iconWidth, + color: iconfontColor, + } + return ( +
    + {type !== 'midButton' && ( +
    + {iconfontText} +
    + )} +
    + ) +} + +function createTabBarItemTextTsx( + color: string, + tabBarItem: UniApp.TabBarItemOptions, + tabBar: UniApp.TabBarOptions +) { + const { iconPath, text } = tabBarItem + const { fontSize, spacing } = tabBar + const style = { + color, + fontSize: fontSize, + lineHeight: !iconPath ? 1.8 : 'normal', + marginTop: !iconPath ? 'inherit' : spacing, + } + return ( +
    + {text} +
    + ) +} + +function createTabBarItemRedDotTsx(badge?: string) { + const clazz = 'uni-tabbar__reddot' + (badge ? ' uni-tabbar__badge' : '') + return
    {badge}
    +} + +function createTabBarMidButtonTsx( + color: string, + iconPath: string, + iconfontText: string | undefined, + iconfontColor: string | undefined, + midButton: UniApp.TabBarMidButtonOptions, + tabBar: UniApp.TabBarOptions, + index: number, + onSwitchTab: OnSwtichTab +) { + const { width, height, backgroundImage, iconWidth } = midButton + return ( +
    +
    + {iconPath && ( + + )} +
    + {createTabBarItemBdTsx( + color, + iconPath, + iconfontText, + iconfontColor, + midButton, + tabBar + )} +
    + ) +} diff --git a/packages/uni-mp-weibo/src/framework/components/page/index.ts b/packages/uni-mp-weibo/src/framework/components/page/index.ts new file mode 100644 index 00000000000..ceb52028e2f --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/page/index.ts @@ -0,0 +1,46 @@ +import { + withCtx, + openBlock, + renderSlot, + createVNode, + createBlock, + SetupContext, +} from 'vue' +import { defineSystemComponent } from '@dcloudio/uni-components' +import { useDocumentTitle } from '../../../helpers/useDocumentTitle' + +import PageHead from './pageHead' +import PageBody from './pageBody' +import { providePageMeta } from '../../setup/provide' +import { getStateId } from '../../../helpers/dom' + +export default defineSystemComponent({ + name: 'Page', + setup(_props, ctx) { + const pageMeta = providePageMeta(getStateId()) + const navigationBar = pageMeta.navigationBar + useDocumentTitle(pageMeta) + return () => + createVNode( + 'uni-page', + { 'data-page': pageMeta.route }, + __UNI_FEATURE_NAVIGATIONBAR__ && navigationBar.style !== 'custom' + ? [createVNode(PageHead), createPageBodyVNode(ctx)] + : [createPageBodyVNode(ctx)] + ) + }, +}) + +function createPageBodyVNode(ctx: SetupContext) { + return ( + openBlock(), + createBlock( + PageBody, + { key: 0 }, + { + default: withCtx(() => [renderSlot(ctx.slots, 'page')]), + _: 3 /* FORWARDED */, + } + ) + ) +} diff --git a/packages/uni-mp-weibo/src/framework/components/page/page-refresh/component.vue b/packages/uni-mp-weibo/src/framework/components/page/page-refresh/component.vue new file mode 100644 index 00000000000..039733dfffe --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/page/page-refresh/component.vue @@ -0,0 +1,50 @@ + + diff --git a/packages/uni-mp-weibo/src/framework/components/page/page-refresh/index.ts b/packages/uni-mp-weibo/src/framework/components/page/page-refresh/index.ts new file mode 100644 index 00000000000..4e001a7f8ad --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/page/page-refresh/index.ts @@ -0,0 +1,279 @@ +import { onMounted, Ref } from 'vue' +import { invokeHook } from '@dcloudio/uni-core' +import { + API_START_PULL_DOWN_REFRESH, + API_STOP_PULL_DOWN_REFRESH, +} from '@dcloudio/uni-api' +import { useSubscribe, withWebEvent } from '@dcloudio/uni-components' +import { usePageMeta } from '../../../setup/provide' +import { ON_PULL_DOWN_REFRESH } from '@dcloudio/uni-shared' + +function processDeltaY( + ev: TouchEvent, + identifier: number | null, + startY: number +) { + const touch = Array.prototype.slice + .call(ev.changedTouches) + .filter((touch) => touch.identifier === identifier)[0] + if (!touch) { + return false + } + ;(ev as any).deltaY = touch.pageY - startY + return true +} + +// const ratio = 2.2 + +const PULLING = 'pulling' +const REACHED = 'reached' + +const ABORTING = 'aborting' +const REFRESHING = 'refreshing' +const RESTORING = 'restoring' + +export function usePageRefresh(refreshRef: Ref) { + const { id, pullToRefresh } = usePageMeta() + const { range, height } = pullToRefresh! + let refreshContainerElem: HTMLDivElement + let refreshControllerElem: HTMLDivElement + let refreshControllerElemStyle: CSSStyleDeclaration + let refreshInnerElemStyle: CSSStyleDeclaration + useSubscribe( + () => { + if (!state) { + state = REFRESHING + addClass() + setTimeout(() => { + refreshing() + }, 50) + } + }, + API_START_PULL_DOWN_REFRESH, + false, + id + ) + useSubscribe( + () => { + if (state === REFRESHING) { + removeClass() + state = RESTORING + addClass() + + restoring(() => { + removeClass() + state = distance = offset = null + }) + } + }, + API_STOP_PULL_DOWN_REFRESH, + false, + id + ) + onMounted(() => { + refreshContainerElem = refreshRef.value.$el + refreshControllerElem = + refreshContainerElem.querySelector('.uni-page-refresh')! + refreshControllerElemStyle = refreshControllerElem.style + refreshInnerElemStyle = ( + refreshControllerElem.querySelector( + '.uni-page-refresh-inner' + ) as HTMLDivElement + ).style + }) + let touchId: number | null + let startY: number + let canRefresh: boolean + let state: + | typeof PULLING + | typeof REACHED + | typeof ABORTING + | typeof REFRESHING + | typeof RESTORING + | null + + let distance: number | null = null + let offset: number | null = null + + function toggleClass(type: 'add' | 'remove') { + if (!state) { + return + } + if (refreshContainerElem) { + refreshContainerElem.classList[type]('uni-page-refresh--' + state) + } + } + function addClass() { + toggleClass('add') + } + function removeClass() { + toggleClass('remove') + } + function pulling(deltaY: number) { + if (!refreshControllerElem) { + return + } + + let rotate = deltaY / range! + + if (rotate > 1) { + rotate = 1 + } else { + rotate = rotate * rotate * rotate + } + + const y = Math.round(deltaY / (range! / height!)) || 0 + + refreshInnerElemStyle.transform = 'rotate(' + 360 * rotate + 'deg)' + refreshControllerElemStyle.clip = 'rect(' + (45 - y) + 'px,45px,45px,-5px)' + refreshControllerElemStyle.transform = 'translate3d(-50%, ' + y + 'px, 0)' + } + + const onTouchstartPassive = withWebEvent((ev: TouchEvent) => { + const touch = ev.changedTouches[0] + touchId = touch.identifier + startY = touch.pageY + if ([ABORTING, REFRESHING, RESTORING].indexOf(state!) >= 0) { + canRefresh = false + } else { + canRefresh = true + } + }) + + const onTouchmove = withWebEvent((ev: TouchEvent) => { + if (!canRefresh) { + return + } + if (!processDeltaY(ev, touchId, startY)) { + return + } + let { deltaY } = ev as any + if ((document.documentElement.scrollTop || document.body.scrollTop) !== 0) { + touchId = null + return + } + + if (deltaY < 0 && !state) { + return + } + + ev.preventDefault() + + if (distance === null) { + offset = deltaY + state = PULLING + addClass() + } + + deltaY = deltaY - offset! + + if (deltaY < 0) { + deltaY = 0 + } + + distance = deltaY + + const isReached = deltaY >= range! && state !== REACHED + const isPulling = deltaY < range! && state !== PULLING + + if (isReached || isPulling) { + removeClass() + state = state === REACHED ? PULLING : REACHED + addClass() + } + + pulling(deltaY!) + }) + + const onTouchend = withWebEvent((ev: TouchEvent) => { + if (!processDeltaY(ev, touchId, startY)) { + return + } + if (state === null) { + return + } + if (state === PULLING) { + removeClass() + state = ABORTING + addClass() + aborting(() => { + removeClass() + state = distance = offset = null + }) + } else if (state === REACHED) { + removeClass() + state = REFRESHING + addClass() + refreshing() + } + }) + + function aborting(callback: Function) { + if (!refreshControllerElem) { + return + } + + if (refreshControllerElemStyle.transform) { + refreshControllerElemStyle.transition = '-webkit-transform 0.3s' + refreshControllerElemStyle.transform = 'translate3d(-50%, 0, 0)' + const abortTransitionEnd = function () { + timeout && clearTimeout(timeout) + refreshControllerElem.removeEventListener( + 'webkitTransitionEnd', + abortTransitionEnd + ) + refreshControllerElemStyle.transition = '' + callback() + } + refreshControllerElem.addEventListener( + 'webkitTransitionEnd', + abortTransitionEnd + ) + const timeout = setTimeout(abortTransitionEnd, 350) // 部分手机,部分情况webkitTransitionEnd不触发 + } else { + callback() + } + } + + function refreshing() { + if (!refreshControllerElem) { + return + } + refreshControllerElemStyle.transition = '-webkit-transform 0.2s' + refreshControllerElemStyle.transform = + 'translate3d(-50%, ' + height + 'px, 0)' + invokeHook(id!, ON_PULL_DOWN_REFRESH) + } + + function restoring(callback: Function) { + if (!refreshControllerElem) { + return + } + + refreshControllerElemStyle.transition = '-webkit-transform 0.3s' + refreshControllerElemStyle.transform += ' scale(0.01)' + + const restoreTransitionEnd = function () { + timeout && clearTimeout(timeout) + refreshControllerElem.removeEventListener( + 'webkitTransitionEnd', + restoreTransitionEnd + ) + refreshControllerElemStyle.transition = '' + refreshControllerElemStyle.transform = 'translate3d(-50%, 0, 0)' + callback() + } + refreshControllerElem.addEventListener( + 'webkitTransitionEnd', + restoreTransitionEnd + ) + const timeout = setTimeout(restoreTransitionEnd, 350) // 部分手机,部分情况webkitTransitionEnd不触发 + } + + return { + onTouchstartPassive, + onTouchmove, + onTouchend, + onTouchcancel: onTouchend, + } +} diff --git a/packages/uni-mp-weibo/src/framework/components/page/pageBody.tsx b/packages/uni-mp-weibo/src/framework/components/page/pageBody.tsx new file mode 100644 index 00000000000..252367354eb --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/page/pageBody.tsx @@ -0,0 +1,48 @@ +import { ref, renderSlot, Ref } from 'vue' + +import { defineSystemComponent } from '@dcloudio/uni-components' + +import { usePageMeta } from '../../setup/provide' + +import PageRefresh from './page-refresh/component.vue' + +import { usePageRefresh } from './page-refresh' + +export default defineSystemComponent({ + name: 'PageBody', + setup(props, ctx) { + const pageMeta = (__UNI_FEATURE_PULL_DOWN_REFRESH__ && + usePageMeta()) as UniApp.PageRouteMeta + + const refreshRef = (__UNI_FEATURE_PULL_DOWN_REFRESH__ && + ref(null)) as Ref + + const pageRefresh = + !__NODE_JS__ && + __UNI_FEATURE_PULL_DOWN_REFRESH__ && + pageMeta.enablePullDownRefresh + ? usePageRefresh(refreshRef) + : null + + return () => { + const pageRefreshTsx = + __UNI_FEATURE_PULL_DOWN_REFRESH__ && + createPageRefreshTsx(refreshRef, pageMeta) + return ( + <> + {pageRefreshTsx} + + {renderSlot(ctx.slots, 'default')} + + + ) + } + }, +}) + +function createPageRefreshTsx(refreshRef: Ref, pageMeta: UniApp.PageRouteMeta) { + if (!__UNI_FEATURE_PULL_DOWN_REFRESH__ || !pageMeta.enablePullDownRefresh) { + return null + } + return +} diff --git a/packages/uni-mp-weibo/src/framework/components/page/pageHead.tsx b/packages/uni-mp-weibo/src/framework/components/page/pageHead.tsx new file mode 100644 index 00000000000..919f6db5324 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/page/pageHead.tsx @@ -0,0 +1,463 @@ +import { computed, onBeforeMount, ref, reactive } from 'vue' +import { extend, isArray } from '@vue/shared' +import { defineSystemComponent, Input } from '@dcloudio/uni-components' +import { getRealPath } from '@dcloudio/uni-platform' +import { + invokeHook, + updateStyle, + createSvgIconVNode, + ICON_PATH_SEARCH, + ICON_PATH_BACK, + ICON_PATH_CLOSE, +} from '@dcloudio/uni-core' +import { + ON_NAVIGATION_BAR_BUTTON_TAP, + ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, + ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, + ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, + ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, +} from '@dcloudio/uni-shared' +import { usePageMeta } from '../../setup/provide' +import { + usePageHeadTransparent, + usePageHeadTransparentBackgroundColor, +} from './transparent' +import { parseTheme, onThemeChange } from '../../../helpers/theme' + +const ICON_PATHS = { + none: '', + forward: + 'M11 7.844q-0.25-0.219-0.25-0.578t0.25-0.578q0.219-0.25 0.563-0.25t0.563 0.25l9.656 9.125q0.125 0.125 0.188 0.297t0.063 0.328q0 0.188-0.063 0.359t-0.188 0.297l-9.656 9.125q-0.219 0.25-0.563 0.25t-0.563-0.25q-0.25-0.219-0.25-0.578t0.25-0.609l9.063-8.594-9.063-8.594z', + back: ICON_PATH_BACK, + select: ICON_PATH_BACK, + share: + 'M26.563 24.844q0 0.125-0.109 0.234t-0.234 0.109h-17.938q-0.125 0-0.219-0.109t-0.094-0.234v-13.25q0-0.156 0.094-0.25t0.219-0.094h5.5v-1.531h-6q-0.531 0-0.906 0.391t-0.375 0.922v14.375q0 0.531 0.375 0.922t0.906 0.391h18.969q0.531 0 0.891-0.391t0.359-0.953v-5.156h-1.438v4.625zM29.813 10.969l-5.125-5.375-1.031 1.094 3.438 3.594-3.719 0.031q-2.313 0.188-4.344 1.125t-3.578 2.422-2.5 3.453-1.109 4.188l-0.031 0.25h1.469v-0.219q0.156-1.875 1-3.594t2.25-3.063 3.234-2.125 3.828-0.906l0.188-0.031 3.313-0.031-3.438 3.625 1.031 1.063 5.125-5.375-0.031-0.063 0.031-0.063z', + favorite: + 'M27.594 13.375q-0.063-0.188-0.219-0.313t-0.344-0.156l-7.094-0.969-3.219-6.406q-0.094-0.188-0.25-0.281t-0.375-0.094q-0.188 0-0.344 0.094t-0.25 0.281l-3.125 6.438-7.094 1.094q-0.188 0.031-0.344 0.156t-0.219 0.313q-0.031 0.188 0.016 0.375t0.172 0.313l5.156 4.969-1.156 7.063q-0.031 0.188 0.047 0.375t0.234 0.313q0.094 0.063 0.188 0.094t0.219 0.031q0.063 0 0.141-0.031t0.172-0.063l6.313-3.375 6.375 3.313q0.063 0.031 0.141 0.047t0.172 0.016q0.188 0 0.344-0.094t0.25-0.281q0.063-0.094 0.078-0.234t-0.016-0.234q0-0.031 0-0.063l-1.25-6.938 5.094-5.031q0.156-0.156 0.203-0.344t-0.016-0.375zM11.469 19.063q0.031-0.188-0.016-0.344t-0.172-0.281l-4.406-4.25 6.063-0.906q0.156-0.031 0.297-0.125t0.203-0.25l2.688-5.531 2.75 5.5q0.063 0.156 0.203 0.25t0.297 0.125l6.094 0.844-4.375 4.281q-0.125 0.125-0.172 0.297t-0.016 0.328l1.063 6.031-5.438-2.813q-0.156-0.094-0.328-0.078t-0.297 0.078l-5.438 2.875 1-6.031z', + home: 'M23.719 16.5q-0.313 0-0.531 0.219t-0.219 0.5v7.063q0 0.219-0.172 0.391t-0.391 0.172h-12.344q-0.25 0-0.422-0.172t-0.172-0.391v-7.063q0-0.281-0.219-0.5t-0.531-0.219q-0.281 0-0.516 0.219t-0.234 0.5v7.063q0.031 0.844 0.625 1.453t1.438 0.609h12.375q0.844 0 1.453-0.609t0.609-1.453v-7.063q0-0.125-0.063-0.266t-0.156-0.234q-0.094-0.125-0.234-0.172t-0.297-0.047zM26.5 14.875l-8.813-8.813q-0.313-0.313-0.688-0.453t-0.781-0.141-0.781 0.141-0.656 0.422l-8.813 8.844q-0.188 0.219-0.188 0.516t0.219 0.484q0.094 0.125 0.234 0.172t0.297 0.047q0.125 0 0.25-0.047t0.25-0.141l8.781-8.781q0.156-0.156 0.406-0.156t0.406 0.156l8.813 8.781q0.219 0.188 0.516 0.188t0.516-0.219q0.188-0.188 0.203-0.484t-0.172-0.516z', + menu: 'M8.938 18.313q0.875 0 1.484-0.609t0.609-1.453-0.609-1.453-1.484-0.609q-0.844 0-1.453 0.609t-0.609 1.453 0.609 1.453 1.453 0.609zM16.188 18.313q0.875 0 1.484-0.609t0.609-1.453-0.609-1.453-1.484-0.609q-0.844 0-1.453 0.609t-0.609 1.453 0.609 1.453 1.453 0.609zM23.469 18.313q0.844 0 1.453-0.609t0.609-1.453-0.609-1.453-1.453-0.609q-0.875 0-1.484 0.609t-0.609 1.453 0.609 1.453 1.484 0.609z', + close: ICON_PATH_CLOSE, +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'PageHead', + setup() { + // @ts-ignore + if (window.weibo) { + // const pageMeta = usePageMeta(); + // // @ts-ignore + // window.weibo.setNavigationBarTitle({ + // title: pageMeta.navigationBar.titleText || '' + // }) + return + } + const headRef = ref(null) + const pageMeta = usePageMeta() + const navigationBar = reactive(parseTheme(pageMeta.navigationBar)) + // UniServiceJSBridge.emit('onNavigationBarChange', navigationBar.titleText) + const { clazz, style } = usePageHead(navigationBar) + + onThemeChange(() => { + const _navigationBar = parseTheme(pageMeta.navigationBar) + navigationBar.backgroundColor = _navigationBar.backgroundColor + navigationBar.titleColor = _navigationBar.titleColor + }) + + const buttons = (__UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ && + usePageHeadButtons(pageMeta)) as PageHeadButtons + + const searchInput = (__UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__ && + navigationBar.searchInput && + usePageHeadSearchInput(pageMeta)) as PageHeadSearchInput + + __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ && + navigationBar.type === 'transparent' && + usePageHeadTransparent(headRef, pageMeta) + + return () => { + // 单页面无需back按钮 + const backButtonTsx = __UNI_FEATURE_PAGES__ + ? createBackButtonTsx(navigationBar, pageMeta.isQuit) + : null + const leftButtonsTsx = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ + ? createButtonsTsx(buttons.left) + : [] + const rightButtonsTsx = __UNI_FEATURE_NAVIGATIONBAR_BUTTONS__ + ? createButtonsTsx(buttons.right) + : [] + const type = navigationBar.type || 'default' + const placeholderTsx = type !== 'transparent' && type !== 'float' && ( +
    + ) + return ( + +
    +
    + {backButtonTsx} + {...leftButtonsTsx} +
    + {createPageHeadBdTsx(navigationBar, searchInput)} +
    {...rightButtonsTsx}
    +
    + {placeholderTsx} +
    + ) + } + }, +}) + +function createBackButtonTsx( + navigationBar: UniApp.PageNavigationBar, + isQuit?: Boolean +) { + if (!isQuit) { + return ( +
    + {createSvgIconVNode( + ICON_PATH_BACK, + navigationBar.type === 'transparent' + ? '#fff' + : navigationBar.titleColor!, + 27 + )} +
    + ) + } +} + +function createButtonsTsx(btns: PageHeadButton[]) { + return btns.map( + ( + { + onClick, + btnClass, + btnStyle, + btnText, + btnIconPath, + badgeText, + iconStyle, + btnSelect, + }, + index + ) => { + return ( +
    + {btnIconPath ? ( + createSvgIconVNode(btnIconPath, iconStyle.color, iconStyle.fontSize) + ) : btnSelect ? ( + + + {createSvgIconVNode(ICON_PATHS['select'], '#000', 14)} + + ) : ( + + )} +
    + ) + } + ) +} + +function createPageHeadBdTsx( + navigationBar: UniApp.PageNavigationBar, + searchInput: PageHeadSearchInput +) { + if ( + !__UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__ || + !navigationBar.searchInput + ) { + return createPageHeadTitleTextTsx(navigationBar) + } + return createPageHeadSearchInputTsx(navigationBar, searchInput) +} + +function createPageHeadTitleTextTsx({ + type, + loading, + titleSize, + titleText, + titleImage, +}: UniApp.PageNavigationBar) { + return ( +
    +
    + {loading ? ( + + ) : titleImage ? ( + + ) : ( + titleText + )} +
    +
    + ) +} + +function createPageHeadSearchInputTsx( + navigationBar: UniApp.PageNavigationBar, + { + text, + focus, + composing, + onBlur, + onFocus, + onInput, + onConfirm, + onClick, + }: PageHeadSearchInput +) { + const { + color, + align, + autoFocus, + disabled, + borderRadius, + backgroundColor, + placeholder, + placeholderColor, + } = navigationBar.searchInput! + const searchStyle = { + borderRadius, + backgroundColor, + } + const placeholderClass = [ + 'uni-page-head-search-placeholder', + `uni-page-head-search-placeholder-${ + focus.value || text.value ? 'left' : align + }`, + ] + return ( + + ) +} + +function onPageHeadBackButton() { + if (getCurrentPages().length === 1) { + uni.reLaunch({ + url: '/', + }) + } else { + uni.navigateBack({ + from: 'backbutton', + success() {}, // 传入空方法,避免返回Promise,因为onBackPress可能导致fail + } as UniApp.NavigateBackOptions) + } +} + +function usePageHead(navigationBar: UniApp.PageNavigationBar) { + const clazz = computed(() => { + const { type, titlePenetrate, shadowColorType } = navigationBar + const clazz: Record = { + 'uni-page-head': true, + 'uni-page-head-transparent': type === 'transparent', + 'uni-page-head-titlePenetrate': titlePenetrate === 'YES', + 'uni-page-head-shadow': !!shadowColorType, + } + if (shadowColorType) { + clazz[`uni-page-head-shadow-${shadowColorType}`] = true + } + return clazz + }) + const style = computed(() => { + const backgroundColor = + __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ && + navigationBar.type === 'transparent' + ? usePageHeadTransparentBackgroundColor(navigationBar.backgroundColor!) + : navigationBar.backgroundColor + return { + backgroundColor, + color: navigationBar.titleColor, + transitionDuration: navigationBar.duration, + transitionTimingFunction: navigationBar.timingFunc, + } + }) + return { + clazz, + style, + } +} + +type PageHeadButton = ReturnType +type PageHeadButtons = ReturnType + +function usePageHeadButtons({ id, navigationBar }: UniApp.PageRouteMeta) { + const left: PageHeadButton[] = [] + const right: PageHeadButton[] = [] + const { buttons } = navigationBar + if (isArray(buttons)) { + const { type } = navigationBar + const isTransparent = type === 'transparent' + const fonts = Object.create(null) + buttons.forEach((btn, index) => { + if (btn.fontSrc && !btn.fontFamily) { + const fontSrc = getRealPath(btn.fontSrc) + let fontFamily = fonts[fontSrc] + if (!fontFamily) { + fontFamily = `font${Date.now()}` + fonts[fontSrc] = fontFamily + onBeforeMount(() => + updateStyle( + 'uni-btn-' + fontFamily, + `@font-face{font-family: "${fontFamily}";src: url("${fontSrc}") format("truetype")}` + ) + ) + } + btn.fontFamily = fontFamily + } + const pageHeadBtn = usePageHeadButton(id!, index, btn, isTransparent) + if (btn.float === 'left') { + left.push(pageHeadBtn) + } else { + right.push(pageHeadBtn) + } + }) + } + return { left, right } +} + +function usePageHeadButton( + pageId: number, + index: number, + btn: UniApp.PageNavigationBarButton, + isTransparent: boolean +) { + const iconStyle: UniApp.StyleObj = { + color: btn.color, + fontSize: btn.fontSize, + fontWeight: btn.fontWeight, + } + if (btn.fontFamily) { + iconStyle.fontFamily = btn.fontFamily + } + return new Proxy( + { + btnClass: { + // 类似这样的大量重复的字符串,会在gzip时压缩大小,无需在代码层考虑优化相同字符串 + 'uni-page-head-btn': true, + 'uni-page-head-btn-red-dot': !!(btn.redDot || btn.badgeText), + 'uni-page-head-btn-select': !!btn.select, + }, + btnStyle: { + backgroundColor: isTransparent ? btn.background : 'transparent', + width: btn.width, + }, + btnText: '', + btnIconPath: ICON_PATHS[btn.type], + badgeText: btn.badgeText, + iconStyle, + onClick() { + invokeHook(pageId, ON_NAVIGATION_BAR_BUTTON_TAP, extend({ index }, btn)) + }, + btnSelect: btn.select, + }, + { + get(target, key, receiver) { + if (['btnText'].includes(key as string)) { + return btn.fontSrc && btn.fontFamily + ? btn.text.replace('\\u', '&#x') + : btn.text + } else { + return Reflect.get(target, key, receiver) + } + }, + } + ) +} + +type PageHeadSearchInput = ReturnType + +function usePageHeadSearchInput({ + id, + navigationBar: { searchInput }, +}: UniApp.PageRouteMeta) { + const focus = ref(false) + const text = ref('') + const composing = ref(false) + const { disabled } = searchInput! + if (disabled) { + const onClick = () => { + invokeHook(id!, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED) + } + return { + focus, + text, + composing, + onClick, + } + } + const onFocus = () => { + focus.value = true + invokeHook(id!, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, { + focus: true, + }) + } + const onBlur = () => { + focus.value = false + invokeHook(id!, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, { + focus: false, + }) + } + const onInput = (evt: { detail: { value: string } }) => { + text.value = evt.detail.value + invokeHook(id!, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, { + text: text.value, + }) + } + const onConfirm = (evt: KeyboardEvent) => { + invokeHook(id!, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, { + text: text.value, + }) + } + return { + focus, + text, + composing, + onFocus, + onBlur, + onInput, + onConfirm, + } +} diff --git a/packages/uni-mp-weibo/src/framework/components/page/transparent.ts b/packages/uni-mp-weibo/src/framework/components/page/transparent.ts new file mode 100644 index 00000000000..3766926a60f --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/components/page/transparent.ts @@ -0,0 +1,73 @@ +import { computed, onMounted, Ref } from 'vue' +import { useOn } from '@dcloudio/uni-components' +import { hexToRgba } from '../../../helpers/hexToRgba' + +export function usePageHeadTransparentBackgroundColor(backgroundColor: string) { + const { r, g, b } = hexToRgba(backgroundColor) + return `rgba(${r},${g},${b},0)` +} + +export function usePageHeadTransparent( + headRef: Ref, + { + id, + navigationBar: { titleColor, coverage, backgroundColor }, + }: UniApp.PageRouteMeta +) { + let A = 0 + const rgb = computed(() => hexToRgba(backgroundColor!)) + const offset = parseInt(coverage!) + let titleElem: HTMLDivElement + let transparentElemStyle: CSSStyleDeclaration + const iconElemsPaths: SVGPathElement[] = [] + const borderRadiusElemsStyles: CSSStyleDeclaration[] = [] + const oldColors: string[] = [] + onMounted(() => { + const $el = headRef.value as unknown as HTMLDivElement + transparentElemStyle = $el.style + titleElem = $el.querySelector('.uni-page-head__title')! + const borderRadiusElems = $el.querySelectorAll( + '.uni-page-head-btn' + ) as NodeListOf + const iconSvgElems = $el.querySelectorAll( + 'svg path' + ) as NodeListOf + for (let i = 0; i < iconSvgElems.length; i++) { + iconElemsPaths.push(iconSvgElems[i]) + } + for (let i = 0; i < borderRadiusElems.length; i++) { + const borderRadiusElem = borderRadiusElems[i] + oldColors.push(getComputedStyle(borderRadiusElem).backgroundColor) + borderRadiusElemsStyles.push(borderRadiusElem.style) + } + }) + useOn(id + '.onPageScroll', ({ scrollTop }: { scrollTop: number }) => { + const alpha = Math.min(scrollTop / offset, 1) + if (alpha === 1 && A === 1) { + return + } + if (alpha > 0.5 && A <= 0.5) { + iconElemsPaths.forEach(function (iconElemPath) { + iconElemPath.setAttribute('fill', titleColor!) + }) + } else if (alpha <= 0.5 && A > 0.5) { + iconElemsPaths.forEach(function (iconElemPath) { + iconElemPath.setAttribute('fill', '#fff') + }) + } + A = alpha + // TODO 暂时仅处理背景色 + if (titleElem) { + titleElem.style.opacity = alpha as unknown as string + } + const bg = rgb.value + transparentElemStyle.backgroundColor = `rgba(${bg.r},${bg.g},${bg.b},${alpha})` + borderRadiusElemsStyles.forEach(function (borderRadiusElemStyle, index) { + const oldColor = oldColors[index] + const rgba = oldColor.match(/[\d+\.]+/g)! + rgba[3] = ((1 - alpha) * + ((rgba.length === 4 ? rgba[3] : 1) as number)) as unknown as string + borderRadiusElemStyle.backgroundColor = `rgba(${rgba})` + }) + }) +} diff --git a/packages/uni-mp-weibo/src/framework/index.ts b/packages/uni-mp-weibo/src/framework/index.ts new file mode 100644 index 00000000000..edda961dacf --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/index.ts @@ -0,0 +1,2 @@ +export { getApp } from './setup/app' +export { getCurrentPages } from './setup/page' diff --git a/packages/uni-mp-weibo/src/framework/plugin/index.ts b/packages/uni-mp-weibo/src/framework/plugin/index.ts new file mode 100644 index 00000000000..00bf029657c --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/plugin/index.ts @@ -0,0 +1,45 @@ +import { App, ComponentPublicInstance } from 'vue' + +import { initApp } from '@dcloudio/uni-vue' +import { initViewPlugin, initServicePlugin } from '@dcloudio/uni-core' + +import { initRouter } from './router' + +export default { + install(app: App) { + initApp(app) + initViewPlugin(app) + initServicePlugin(app) + + if (!app.config.warnHandler) { + app.config.warnHandler = warnHandler + } + + if (__UNI_FEATURE_PAGES__) { + initRouter(app) + } + }, +} + +function warnHandler( + msg: string, + instance: ComponentPublicInstance | null, + trace: string +) { + if (instance) { + // ignore ssr warning + const name = instance.$.type.name + if ('PageMetaHead' === name) { + return + } + const parent = instance.$.parent + if (parent && parent.type.name === 'PageMeta') { + return + } + } + const warnArgs = [`[Vue warn]: ${msg}`] + if (trace.length) { + warnArgs.push(`\n`, trace) + } + console.warn(...warnArgs) +} diff --git a/packages/uni-mp-weibo/src/framework/plugin/router.ts b/packages/uni-mp-weibo/src/framework/plugin/router.ts new file mode 100644 index 00000000000..145a4b1a0eb --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/plugin/router.ts @@ -0,0 +1,65 @@ +import { App } from 'vue' +import { RouterOptions, RouteRecordRaw } from 'vue-router' +import { + createRouter, + createWebHistory, + createWebHashHistory, + createMemoryHistory, +} from 'vue-router' +import { getCurrentPages, normalizeRouteKey, removePage } from '../setup/page' + +export function initRouter(app: App) { + const router = createRouter(createRouterOptions()) + ;(app as any).router = router // 挂在app上,方便ssr获取 + app.use(router) +} + +const scrollBehavior: RouterOptions['scrollBehavior'] = ( + _to, + _from, + savedPosition +) => { + if (savedPosition) { + return savedPosition + } + // TODO tabBar? +} + +function createRouterOptions(): RouterOptions { + return { + history: initHistory(), + strict: !!__uniConfig.router!.strict, + routes: __uniRoutes as unknown as RouteRecordRaw[], + scrollBehavior, + } +} + +function removeCurrentPages(delta: number = 1) { + const keys = getCurrentPages() + const start = keys.length - 1 + const end = start - delta + for (let i = start; i > end; i--) { + const page = keys[i].$page + removePage(normalizeRouteKey(page.path, page.id), false) + } +} + +function initHistory() { + let { routerBase } = __uniConfig.router! + if (routerBase === '/') { + routerBase = '' + } + if (__NODE_JS__) { + return createMemoryHistory(routerBase) + } + const history = + __UNI_FEATURE_ROUTER_MODE__ === 'history' + ? createWebHistory(routerBase) + : createWebHashHistory(routerBase) + history.listen((_to, _from, info) => { + if (info.direction === 'back') { + removeCurrentPages(Math.abs(info.delta)) + } + }) + return history +} diff --git a/packages/uni-mp-weibo/src/framework/setup/app.ts b/packages/uni-mp-weibo/src/framework/setup/app.ts new file mode 100644 index 00000000000..1d0b29bb494 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/app.ts @@ -0,0 +1,38 @@ +import { ComponentPublicInstance } from 'vue' +import AsyncLoadingComponent from '../components/async-loading' +import AsyncErrorComponent from '../components/async-error' +import { + initAppVm, + initService, + initView, + defineGlobalData, +} from '@dcloudio/uni-core' + +let appVm: ComponentPublicInstance + +export function getApp() { + return appVm +} + +export function initApp(vm: ComponentPublicInstance) { + appVm = vm + + // 定制 App 的 $children 为 devtools 服务 __VUE_PROD_DEVTOOLS__ + Object.defineProperty((appVm.$ as any).ctx, '$children', { + get() { + return getCurrentPages().map((page) => page.$vm) + }, + }) + + const app = appVm.$.appContext.app + if (!app.component(AsyncLoadingComponent.name)) { + app.component(AsyncLoadingComponent.name, AsyncLoadingComponent) + } + if (!app.component(AsyncErrorComponent.name)) { + app.component(AsyncErrorComponent.name, AsyncErrorComponent) + } + initAppVm(appVm) + defineGlobalData(appVm) + initService() + initView() +} diff --git a/packages/uni-mp-weibo/src/framework/setup/index.ts b/packages/uni-mp-weibo/src/framework/setup/index.ts new file mode 100644 index 00000000000..1fb31695a7a --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/index.ts @@ -0,0 +1,315 @@ +import { extend, invokeArrayFns, isPlainObject, isFunction } from '@vue/shared' +import { + ComponentInternalInstance, + ComponentPublicInstance, + createBlock, + DefineComponent, + getCurrentInstance, + onMounted, + openBlock, + onBeforeActivate, + onBeforeDeactivate, + onBeforeMount, + onBeforeUnmount, + nextTick, +} from 'vue' +import { + debounce, + decodedQuery, + ON_APP_ENTER_BACKGROUND, + ON_APP_ENTER_FOREGROUND, + ON_RESIZE, + ON_WEB_INVOKE_APP_SERVICE, + WEB_INVOKE_APPSERVICE, + ON_THEME_CHANGE, +} from '@dcloudio/uni-shared' +import { injectAppHooks } from '@dcloudio/uni-api' +import { + subscribeViewMethod, + unsubscribeViewMethod, + invokeHook, +} from '@dcloudio/uni-core' +import { LayoutComponent } from '../..' +import { initApp } from './app' +import { initPage, onPageShow, onPageReady } from './page' +import { usePageMeta, usePageRoute } from './provide' +import { initLaunchOptions, getEnterOptions } from './utils' +import type { RouteLocationNormalizedLoaded } from 'vue-router' +import { useRouter } from 'vue-router' + +interface SetupComponentOptions { + clone?: boolean + init: (vm: ComponentPublicInstance) => void + setup: (instance: ComponentInternalInstance) => Record | void + before?: (comp: DefineComponent) => void +} + +function wrapperComponentSetup( + comp: DefineComponent, + { clone, init, setup, before }: SetupComponentOptions +) { + if (clone) { + comp = extend({}, comp) + } + before && before(comp) + const oldSetup = comp.setup + comp.setup = (props, ctx) => { + const instance = getCurrentInstance()! + init(instance.proxy!) + const query = setup(instance) + if (oldSetup) { + return oldSetup(query || props, ctx) + } + } + return comp +} + +function setupComponent(comp: any, options: SetupComponentOptions) { + if (comp && (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) { + return wrapperComponentSetup(comp.default, options) + } + return wrapperComponentSetup(comp, options) +} + +export function setupWindow(comp: any, id: number) { + return setupComponent(comp, { + init: (vm) => { + vm.$page = { + id, + } as Page.PageInstance['$page'] + }, + setup(instance) { + instance.$pageInstance = instance // window 的页面实例 $pageInstance 指向自己 + }, + }) +} + +export function setupPage(comp: any) { + const weiboMixin = { + onShow() { + // @ts-ignore + let onShareAppMessage = this.$options.onShareAppMessage + if (onShareAppMessage && typeof onShareAppMessage === 'function') { + // @ts-ignore + window.weibo.sendShareMessage({ + data: onShareAppMessage.call(this), + }) + } else { + // @ts-ignore + window.weibo.sendShareMessage({ + data: null, + }) + } + }, + } + // @ts-ignore + if (window.weibo && typeof window.weibo.sendShareMessage === 'function') { + comp.mixins = [weiboMixin] + } + if (__DEV__) { + comp.__mpType = 'page' + } + return setupComponent(comp, { + clone: true, // 页面组件可能会被其他地方手动引用,比如 windows 等,需要 clone 一份新的作为页面组件 + init: initPage, + setup(instance) { + // instance.root = instance // 组件 root 指向页面 + // 修改 root 会影响 vue devtools + instance.$pageInstance = instance // 组件 $pageInstance 指向页面 + // 组件的 $pageInstance 赋值,是在 vue 内核 createComponentInstance 中 root 赋值的地方实现 + const route = usePageRoute() + // 存储参数,让 initHooks 中执行 onLoad 时,可以访问到 + const query = decodedQuery(route.query) + instance.attrs.__pageQuery = query + instance.proxy!.$page.options = query + if (__NODE_JS__) { + return query + } + const pageMeta = usePageMeta() + onBeforeMount(() => { + onPageShow(instance, pageMeta) + }) + onMounted(() => { + onPageReady(instance) + const { onReady } = instance + onReady && invokeArrayFns(onReady) + invokeOnTabItemTap(route) + }) + onBeforeActivate(() => { + if (!instance.__isVisible) { + onPageShow(instance, pageMeta) + instance.__isVisible = true + const { onShow } = instance + onShow && invokeArrayFns(onShow) + nextTick(() => { + invokeOnTabItemTap(route) + }) + } + }) + onBeforeDeactivate(() => { + if (instance.__isVisible && !instance.__isUnload) { + instance.__isVisible = false + const { onHide } = instance + onHide && invokeArrayFns(onHide) + } + }) + + subscribeViewMethod(pageMeta.id!) + onBeforeUnmount(() => { + unsubscribeViewMethod(pageMeta.id!) + }) + + return query + }, + }) +} + +export function setupApp(comp: any) { + if (__DEV__) { + comp.__mpType = 'app' + } + return setupComponent(comp, { + init: initApp, + setup(instance) { + const route = usePageRoute() + // node环境不触发App生命周期 + if (__NODE_JS__) { + return route.query + } + const onLaunch = () => { + injectAppHooks(instance) + const { onLaunch, onShow, onPageNotFound, onError } = instance + const path = route.path.slice(1) + const launchOptions = initLaunchOptions({ + path: path || __uniRoutes[0].meta.route, + query: decodedQuery(route.query), + }) + onLaunch && invokeArrayFns(onLaunch, launchOptions) + onShow && invokeArrayFns(onShow, launchOptions) + if (__UNI_FEATURE_PAGES__) { + if (!route.matched.length) { + const pageNotFoundOptions = { + notFound: true, + openType: 'appLaunch', + path: route.path, + query: {}, + scene: 1001, + } + onPageNotFound && + invokeArrayFns(onPageNotFound, pageNotFoundOptions) + } + } + if (onError) { + instance.appContext.config.errorHandler = (err) => { + invokeArrayFns(onError, err) + } + } + } + if (__UNI_FEATURE_PAGES__) { + // 等待ready后,再onLaunch,否则直达非首页无法获取到正确的path和query + useRouter().isReady().then(onLaunch) + } else { + onBeforeMount(onLaunch) + } + + onMounted(() => { + window.addEventListener( + 'resize', + debounce(onResize, 50, { setTimeout, clearTimeout }) + ) + window.addEventListener('message', onMessage) + document.addEventListener('visibilitychange', onVisibilityChange) + onThemeChange() + }) + return route.query + }, + before(comp) { + comp.mpType = 'app' + const { setup } = comp + const render = () => { + return openBlock(), createBlock(LayoutComponent) + } + comp.setup = (props, ctx) => { + const res = setup && setup(props, ctx) + return isFunction(res) ? render : res + } + comp.render = render + }, + }) +} + +function onResize() { + const { windowWidth, windowHeight, screenWidth, screenHeight } = + uni.getSystemInfoSync() + const landscape = Math.abs(Number(window.orientation)) === 90 + const deviceOrientation = landscape ? 'landscape' : 'portrait' + UniServiceJSBridge.emit(ON_RESIZE, { + deviceOrientation, + size: { + windowWidth, + windowHeight, + screenWidth, + screenHeight, + }, + }) +} +function onMessage(evt: { + data?: { type: string; data: any; pageId: number } +}) { + if (isPlainObject(evt.data) && evt.data.type === WEB_INVOKE_APPSERVICE) { + UniServiceJSBridge.emit( + ON_WEB_INVOKE_APP_SERVICE, + evt.data.data, + evt.data.pageId + ) + } +} +function onVisibilityChange() { + const { emit } = UniServiceJSBridge + if (document.visibilityState === 'visible') { + emit(ON_APP_ENTER_FOREGROUND, getEnterOptions()) + } else { + emit(ON_APP_ENTER_BACKGROUND) + } +} +function onThemeChange() { + let mediaQueryList: MediaQueryList | null = null + + try { + mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)') + } catch (error) {} + + if (mediaQueryList) { + let callback = (e: MediaQueryListEvent) => { + UniServiceJSBridge.emit(ON_THEME_CHANGE, { + theme: e.matches ? 'dark' : 'light', + }) + } + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener('change', callback) + } else { + mediaQueryList.addListener(callback) + } + } +} +function invokeOnTabItemTap( + route: + | RouteLocationNormalizedLoaded + | { + meta: UniApp.PageRouteMeta + query: {} + path: string + matched: { + path: string + }[] + } +) { + const { tabBarText, tabBarIndex, route: pagePath } = route.meta + if (tabBarText) { + invokeHook('onTabItemTap', { + index: tabBarIndex, + text: tabBarText, + pagePath, + }) + } +} diff --git a/packages/uni-mp-weibo/src/framework/setup/page.ts b/packages/uni-mp-weibo/src/framework/setup/page.ts new file mode 100644 index 00000000000..e50850fbe63 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/page.ts @@ -0,0 +1,284 @@ +import { + VNode, + nextTick, + computed, + ConcreteComponent, + ComponentPublicInstance, + ComponentInternalInstance, +} from 'vue' +import { useRoute, RouteLocationNormalizedLoaded } from 'vue-router' +import { + invokeHook, + disableScrollListener, + createScrollListener, + CreateScrollListenerOptions, + initPageInternalInstance, + initPageVm, +} from '@dcloudio/uni-core' +import { + ON_PAGE_SCROLL, + ON_REACH_BOTTOM, + ON_REACH_BOTTOM_DISTANCE, + ON_UNLOAD, +} from '@dcloudio/uni-shared' +import { usePageMeta } from './provide' +import { NavigateType } from '../../service/api/route/utils' +import { updateCurPageCssVar } from '../../helpers/cssVar' +import { getStateId } from '../../helpers/dom' + +const SEP = '$$' + +const currentPagesMap = new Map() + +function pruneCurrentPages() { + currentPagesMap.forEach((page, id) => { + if ((page as unknown as ComponentPublicInstance).$.isUnmounted) { + currentPagesMap.delete(id) + } + }) +} + +export function getCurrentPagesMap() { + return currentPagesMap +} + +export function getCurrentPages() { + const curPages: ComponentPublicInstance[] = [] + const pages = currentPagesMap.values() + for (const page of pages) { + if (page.$.__isTabBar) { + if (page.$.__isActive) { + curPages.push(page) + } + } else { + curPages.push(page) + } + } + return curPages +} + +function removeRouteCache(routeKey: string) { + const vnode = pageCacheMap.get(routeKey) + if (vnode) { + pageCacheMap.delete(routeKey) + routeCache.pruneCacheEntry!(vnode) + } +} + +export function removePage(routeKey: string, removeRouteCaches = true) { + const pageVm = currentPagesMap.get(routeKey) as ComponentPublicInstance + pageVm.$.__isUnload = true + invokeHook(pageVm, ON_UNLOAD) + currentPagesMap.delete(routeKey) + removeRouteCaches && removeRouteCache(routeKey) +} + +let id = /*#__PURE__*/ getStateId() + +export function createPageState(type: NavigateType, __id__?: number) { + return { + __id__: __id__ || ++id, + __type__: type, + } +} + +function initPublicPage(route: RouteLocationNormalizedLoaded) { + const meta = usePageMeta() + + if (!__UNI_FEATURE_PAGES__) { + return initPageInternalInstance('navigateTo', __uniRoutes[0].path, {}, meta) + } + let fullPath = route.fullPath + if (route.meta.isEntry && fullPath.indexOf(route.meta.route) === -1) { + fullPath = '/' + route.meta.route + fullPath.replace('/', '') + } + return initPageInternalInstance('navigateTo', fullPath, {}, meta) +} + +export function initPage(vm: ComponentPublicInstance) { + const route = vm.$route + const page = initPublicPage(route) + initPageVm(vm, page) + currentPagesMap.set(normalizeRouteKey(page.path, page.id), vm) +} + +export function normalizeRouteKey(path: string, id: number) { + return path + SEP + id +} + +export function useKeepAliveRoute() { + const route = useRoute() + const routeKey = computed(() => + normalizeRouteKey('/' + route.meta.route, getStateId()) + ) + const isTabBar = computed(() => route.meta.isTabBar) + return { + routeKey, + isTabBar, + routeCache, + } +} + +// https://github.com/vuejs/rfcs/pull/284 +// https://github.com/vuejs/vue-next/pull/3414 + +type CacheKey = string | number | ConcreteComponent +interface KeepAliveCache { + get(key: CacheKey): VNode | void + set(key: CacheKey, value: VNode): void + delete(key: CacheKey): void + forEach( + fn: (value: VNode, key: CacheKey, map: Map) => void, + thisArg?: any + ): void + pruneCacheEntry?: (cached: VNode) => void +} +const pageCacheMap = new Map() +const routeCache: KeepAliveCache = { + get(key) { + return pageCacheMap.get(key) + }, + set(key, value) { + pruneRouteCache(key as string) + pageCacheMap.set(key, value) + }, + delete(key) { + const vnode = pageCacheMap.get(key) + if (!vnode) { + return + } + pageCacheMap.delete(key) + }, + forEach(fn) { + pageCacheMap.forEach(fn) + }, +} + +function isTabBarVNode(vnode: VNode): boolean { + return vnode.props!.type === 'tabBar' +} + +function pruneRouteCache(key: string) { + const pageId = parseInt(key.split(SEP)[1]) + if (!pageId) { + return + } + routeCache.forEach((vnode, key) => { + const cPageId = parseInt((key as string).split(SEP)[1]) + if (cPageId && cPageId > pageId) { + if (__UNI_FEATURE_TABBAR__ && isTabBarVNode(vnode)) { + // tabBar keep alive + return + } + routeCache.delete(key) + routeCache.pruneCacheEntry!(vnode) + nextTick(() => pruneCurrentPages()) + } + }) +} + +function updateCurPageAttrs(pageMeta: UniApp.PageRouteMeta) { + const nvueDirKey = 'nvue-dir-' + __uniConfig.nvue!['flex-direction'] + if (pageMeta.isNVue) { + document.body.setAttribute('nvue', '') + document.body.setAttribute(nvueDirKey, '') + } else { + document.body.removeAttribute('nvue') + document.body.removeAttribute(nvueDirKey) + } +} + +export function onPageShow( + instance: ComponentInternalInstance, + pageMeta: UniApp.PageRouteMeta +) { + updateBodyScopeId(instance) + updateCurPageCssVar(pageMeta) + updateCurPageAttrs(pageMeta) + initPageScrollListener(instance, pageMeta) +} + +export function onPageReady(instance: ComponentInternalInstance) { + const scopeId = getScopeId(instance) + scopeId && updateCurPageBodyScopeId(scopeId) +} + +function updateCurPageBodyScopeId(scopeId: string) { + const pageBodyEl = document.querySelector('uni-page-body') + if (pageBodyEl) { + pageBodyEl.setAttribute(scopeId, '') + } else if (__DEV__) { + console.warn('uni-page-body not found') + } +} + +function getScopeId(instance: ComponentInternalInstance) { + return (instance.type as any).__scopeId +} + +let curScopeId: string +function updateBodyScopeId(instance: ComponentInternalInstance) { + const scopeId = getScopeId(instance) + const { body } = document + curScopeId && body.removeAttribute(curScopeId!) + scopeId && body.setAttribute(scopeId, '') + curScopeId = scopeId! +} + +let curScrollListener: (evt: Event) => any +// TODO 当动态渲染的组件内监听onPageScroll时 +function initPageScrollListener( + instance: ComponentInternalInstance, + pageMeta: UniApp.PageRouteMeta +) { + document.removeEventListener('touchmove', disableScrollListener) + if (curScrollListener) { + document.removeEventListener('scroll', curScrollListener) + } + if (pageMeta.disableScroll) { + return document.addEventListener('touchmove', disableScrollListener) + } + + const { onPageScroll, onReachBottom } = instance + const navigationBarTransparent = pageMeta.navigationBar.type === 'transparent' + if (!onPageScroll && !onReachBottom && !navigationBarTransparent) { + return + } + const opts: CreateScrollListenerOptions = {} + const pageId = instance.proxy!.$page.id + if (onPageScroll || navigationBarTransparent) { + opts.onPageScroll = createOnPageScroll( + pageId, + onPageScroll, + navigationBarTransparent + ) + } + if (onReachBottom) { + opts.onReachBottomDistance = + pageMeta.onReachBottomDistance || ON_REACH_BOTTOM_DISTANCE + opts.onReachBottom = () => + UniViewJSBridge.publishHandler(ON_REACH_BOTTOM, {}, pageId) + } + curScrollListener = createScrollListener(opts) + // 避免监听太早,直接触发了 scroll + requestAnimationFrame(() => + document.addEventListener('scroll', curScrollListener) + ) +} + +function createOnPageScroll( + pageId: number, + onPageScroll: unknown, + navigationBarTransparent: boolean +) { + return (scrollTop: number) => { + if (onPageScroll) { + UniViewJSBridge.publishHandler(ON_PAGE_SCROLL, { scrollTop }, pageId) + } + if (navigationBarTransparent) { + UniViewJSBridge.emit(pageId + '.' + ON_PAGE_SCROLL, { + scrollTop, + }) + } + } +} diff --git a/packages/uni-mp-weibo/src/framework/setup/provide/index.ts b/packages/uni-mp-weibo/src/framework/setup/provide/index.ts new file mode 100644 index 00000000000..133dafb8539 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/provide/index.ts @@ -0,0 +1,2 @@ +export * from './page' +export * from './layout' diff --git a/packages/uni-mp-weibo/src/framework/setup/provide/layout.ts b/packages/uni-mp-weibo/src/framework/setup/provide/layout.ts new file mode 100644 index 00000000000..15e52aa873f --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/provide/layout.ts @@ -0,0 +1,111 @@ +import { computed, inject, nextTick, provide, Ref, ref } from 'vue' +import { Router } from 'vue-router' +import { hasOwn } from '@vue/shared' +import { RESPONSIVE_MIN_WIDTH } from '@dcloudio/uni-shared' +import { PolySymbol } from '@dcloudio/uni-core' + +import { checkMinWidth } from '../../../helpers/dom' + +const layoutKey = PolySymbol(__DEV__ ? 'layout' : 'l') + +interface ProvideLayout {} + +// const windowTypes = ['top', 'left', 'right'] + +export function useLayout() { + return inject(layoutKey) +} + +export function provideLayout(router?: Router) { + provide(layoutKey, initLayout(router)) +} +// 1. 查找minWidth,确认是否需要responsive +function initLayout(router?: Router): ProvideLayout { + if (!__UNI_FEATURE_RESPONSIVE__) { + return {} + } + initTopWindow(router) + initLeftWindow() + initRightWindow() + return {} +} + +function initMediaQuery( + minWidth: number, + callback: (ev: MediaQueryListEvent) => void +) { + const mediaQueryList = window.matchMedia('(min-width: ' + minWidth + 'px)') + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener('change', callback) + } else { + mediaQueryList.addListener(callback) + } +} + +interface TopWindowRes { + matchTopWindow: Ref + topWindowStyle: Ref> + showTopWindow: Ref +} + +function initTopWindow(router?: Router) { + const res: TopWindowRes = { + matchTopWindow: ref(false), + topWindowStyle: ref({}), + showTopWindow: ref(false), + } + if (__UNI_FEATURE_TOPWINDOW__) { + return _initTopWindow(res, router) + } + return res +} + +function _initTopWindow(res: TopWindowRes, router?: Router) { + let topWindowMinWidth = RESPONSIVE_MIN_WIDTH + const { matchMedia, style } = __uniConfig.topWindow! + if (matchMedia && hasOwn(matchMedia, 'minWidth')) { + topWindowMinWidth = matchMedia.minWidth! + } + if (checkMinWidth(topWindowMinWidth)) { + initMediaQuery(topWindowMinWidth, (ev) => { + res.matchTopWindow.value = ev.matches + nextTick(() => {}) + }) + } + res.topWindowStyle = ref(style!) + res.showTopWindow = computed(() => { + if (!res.matchTopWindow.value) { + // 未match + return false + } + if (router && !router.currentRoute.value.meta.topWindow) { + // 当前路由不支持 + return false + } + // TODO API + return true + }) + return res +} + +function initLeftWindow() { + let leftWindowMinWidth = RESPONSIVE_MIN_WIDTH + if (__UNI_FEATURE_LEFTWINDOW__) { + const { matchMedia } = __uniConfig.leftWindow! + if (matchMedia && hasOwn(matchMedia, 'minWidth')) { + leftWindowMinWidth = matchMedia.minWidth! + } + } + return { leftWindowMinWidth } +} + +function initRightWindow() { + let rightWindowMinWidth = RESPONSIVE_MIN_WIDTH + if (__UNI_FEATURE_RIGHTWINDOW__) { + const { matchMedia } = __uniConfig.rightWindow! + if (matchMedia && hasOwn(matchMedia, 'minWidth')) { + rightWindowMinWidth = matchMedia.minWidth! + } + } + return { rightWindowMinWidth } +} diff --git a/packages/uni-mp-weibo/src/framework/setup/provide/page.ts b/packages/uni-mp-weibo/src/framework/setup/provide/page.ts new file mode 100644 index 00000000000..74f81daee1f --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/provide/page.ts @@ -0,0 +1,122 @@ +import { extend } from '@vue/shared' +import { reactive, provide, inject } from 'vue' +import { useRoute } from 'vue-router' + +import { + addLeadingSlash, + NAVBAR_HEIGHT, + parseQuery, +} from '@dcloudio/uni-shared' +import { + initNavigationBarI18n, + initRouteMeta, + normalizePullToRefreshRpx, + PolySymbol, +} from '@dcloudio/uni-core' + +import safeAreaInsets from 'safe-area-insets' + +const pageMetaKey = PolySymbol(__DEV__ ? 'UniPageMeta' : 'upm') + +export function usePageMeta() { + return inject(pageMetaKey)! +} + +export function providePageMeta(id: number) { + const pageMeta = initPageMeta(id) + provide(pageMetaKey, pageMeta) + return pageMeta +} +export function usePageRoute() { + if (__UNI_FEATURE_PAGES__) { + return useRoute() + } + const url = location.href + const searchPos = url.indexOf('?') + const hashPos = url.indexOf('#', searchPos > -1 ? searchPos : 0) + let query = {} + if (searchPos > -1) { + query = parseQuery( + url.slice(searchPos + 1, hashPos > -1 ? hashPos : url.length) + ) + } + const { meta } = __uniRoutes[0] + const path = addLeadingSlash(meta.route) + return { + meta, + query: query, + path, + matched: [{ path }], + } +} +function initPageMeta(id: number) { + if (__UNI_FEATURE_PAGES__) { + return reactive( + normalizePageMeta( + JSON.parse( + JSON.stringify( + initRouteMeta( + useRoute().meta as unknown as UniApp.PageRouteMeta, + id + ) + ) + ) + ) + ) + } + return reactive( + normalizePageMeta( + JSON.parse(JSON.stringify(initRouteMeta(__uniRoutes[0].meta, id))) + ) + ) +} + +function normalizePageMeta(pageMeta: UniApp.PageRouteMeta) { + if (__UNI_FEATURE_PULL_DOWN_REFRESH__) { + const { enablePullDownRefresh, navigationBar } = pageMeta + if (enablePullDownRefresh) { + const pullToRefresh = normalizePullToRefreshRpx( + extend( + { + support: true, + color: '#2BD009', + style: 'circle', + height: 70, + range: 150, + offset: 0, + }, + pageMeta.pullToRefresh + ) + ) + const { type, style } = navigationBar + if (style !== 'custom' && type !== 'transparent') { + pullToRefresh.offset! += + NAVBAR_HEIGHT + (__NODE_JS__ ? 0 : safeAreaInsets.top) + } + pageMeta.pullToRefresh = pullToRefresh + } + } + if (__UNI_FEATURE_NAVIGATIONBAR__) { + const { navigationBar } = pageMeta + const { titleSize, titleColor, backgroundColor } = navigationBar + navigationBar.titleText = navigationBar.titleText || '' + navigationBar.type = navigationBar.type || 'default' + navigationBar.titleSize = titleSize || '16px' + navigationBar.titleColor = titleColor || '#ffffff' + navigationBar.backgroundColor = backgroundColor || '#F7F7F7' + __UNI_FEATURE_I18N_LOCALE__ && initNavigationBarI18n(navigationBar) + } + if (!__NODE_JS__ && __UNI_FEATURE_PAGES__ && history.state) { + // 首页执行了redirectTo + const type = history.state.__type__ + if ( + (type === 'redirectTo' || type === 'reLaunch') && + getCurrentPages().length === 0 + ) { + pageMeta.isEntry = true + pageMeta.isQuit = true + } + } + + return pageMeta +} diff --git a/packages/uni-mp-weibo/src/framework/setup/state.ts b/packages/uni-mp-weibo/src/framework/setup/state.ts new file mode 100644 index 00000000000..bc4cfd85b49 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/state.ts @@ -0,0 +1,13 @@ +import { reactive } from 'vue' +import { initTabBarI18n } from '@dcloudio/uni-core' + +let tabBar: UniApp.TabBarOptions | undefined + +export function useTabBar() { + if (!tabBar) { + tabBar = + __uniConfig.tabBar && + reactive(initTabBarI18n(__uniConfig.tabBar)) + } + return tabBar +} diff --git a/packages/uni-mp-weibo/src/framework/setup/utils.ts b/packages/uni-mp-weibo/src/framework/setup/utils.ts new file mode 100644 index 00000000000..17fe27b6440 --- /dev/null +++ b/packages/uni-mp-weibo/src/framework/setup/utils.ts @@ -0,0 +1,29 @@ +import { extend } from '@vue/shared' +import { createLaunchOptions, LaunchOptions } from '@dcloudio/uni-core' + +const launchOptions: LaunchOptions = /*#__PURE__*/ createLaunchOptions() + +const enterOptions: LaunchOptions = /*#__PURE__*/ createLaunchOptions() + +export function getEnterOptions() { + return extend({}, enterOptions) +} + +export function getLaunchOptions() { + return extend({}, launchOptions) +} + +export function initLaunchOptions({ + path, + query, +}: { + path: string + query: Record +}) { + extend(launchOptions, { + path, + query, + }) + extend(enterOptions, launchOptions) + return extend({}, launchOptions) +} diff --git a/packages/uni-mp-weibo/src/helpers/cssVar.ts b/packages/uni-mp-weibo/src/helpers/cssVar.ts new file mode 100644 index 00000000000..b11643402e5 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/cssVar.ts @@ -0,0 +1,39 @@ +import { NAVBAR_HEIGHT } from '@dcloudio/uni-shared' +import { updatePageCssVar } from '@dcloudio/uni-core' +import { useTabBar } from '../framework/setup/state' +import { cssEnv, cssConstant } from '../service/api/base/canIUse' + +const envMethod = /*#__PURE__*/ (() => + cssEnv ? 'env' : cssConstant ? 'constant' : '')() + +export function updateCurPageCssVar(pageMeta: UniApp.PageRouteMeta) { + let windowTopValue = 0 + let windowBottomValue = 0 + if ( + __UNI_FEATURE_NAVIGATIONBAR__ && + pageMeta.navigationBar.style !== 'custom' && + ['default', 'float'].indexOf(pageMeta.navigationBar.type!) > -1 + ) { + windowTopValue = NAVBAR_HEIGHT + } + if (__UNI_FEATURE_TABBAR__ && pageMeta.isTabBar) { + const tabBar = useTabBar()! + tabBar.shown && (windowBottomValue = parseInt(tabBar.height!)) + } + updatePageCssVar({ + '--window-top': normalizeWindowTop(windowTopValue), + '--window-bottom': normalizeWindowBottom(windowBottomValue), + }) +} + +export function normalizeWindowTop(windowTop: number) { + return envMethod + ? `calc(${windowTop}px + ${envMethod}(safe-area-inset-top))` + : `${windowTop}px` +} + +export function normalizeWindowBottom(windowBottom: number) { + return envMethod + ? `calc(${windowBottom}px + ${envMethod}(safe-area-inset-bottom))` + : `${windowBottom}px` +} diff --git a/packages/uni-mp-weibo/src/helpers/dom.ts b/packages/uni-mp-weibo/src/helpers/dom.ts new file mode 100644 index 00000000000..018ffc6e75b --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/dom.ts @@ -0,0 +1,24 @@ +const screen = window.screen +const documentElement = document.documentElement + +export function checkMinWidth(minWidth: number) { + if (__NODE_JS__) { + return false + } + const sizes = [ + window.outerWidth, + window.outerHeight, + screen.width, + screen.height, + documentElement.clientWidth, + documentElement.clientHeight, + ] + return Math.max.apply(null, sizes) > minWidth +} + +export function getStateId() { + if (__NODE_JS__) { + return 1 + } + return (history.state && history.state.__id__) || 1 +} diff --git a/packages/uni-mp-weibo/src/helpers/file.ts b/packages/uni-mp-weibo/src/helpers/file.ts new file mode 100644 index 00000000000..66789e1d884 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/file.ts @@ -0,0 +1,131 @@ +import { hasOwn } from '@vue/shared' + +/** + * 暂存的文件对象 + */ +const files: { [key: string]: File } = {} +/** + * 从url读取File + * @param {string} url + * @param {boolean} local + * @param {Promise} + */ +export function urlToFile(url: string, local?: boolean): Promise { + const file = files[url] + if (file) { + return Promise.resolve(file) + } + if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) { + return Promise.resolve(base64ToFile(url)) + } + if (local) { + return Promise.reject(new Error('not find')) + } + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest() + xhr.open('GET', url, true) + xhr.responseType = 'blob' + xhr.onload = function () { + resolve(this.response) + } + xhr.onerror = reject + xhr.send() + }) +} +/** + * base64转File + * @param {string} base64 + * @return {File} + */ +export function base64ToFile(base64: string): File { + const base64Array = base64.split(',') + const res = base64Array[0].match(/:(.*?);/) + const type = res ? res[1] : '' + const str = atob(base64Array[1]) + let n = str.length + const array = new Uint8Array(n) + while (n--) { + array[n] = str.charCodeAt(n) + } + return blobToFile(array, type) +} +/** + * 简易获取扩展名 + * @param {string} type + * @return {string} + */ +function getExtname(type: string): string { + const extname = type.split('/')[1] + return extname ? `.${extname}` : '' +} +/** + * 简易获取文件名 + * @param {string} url + */ +export function getFileName(url: string): string { + url = url.split('#')[0].split('?')[0] + const array = url.split('/') + return array[array.length - 1] +} +interface FileLike extends Blob { + name?: string +} +/** + * blob转File + * @param {Blob} blob + * @param {string} type + * @return {File} + */ +export function blobToFile( + blob: Blob | Uint8Array | File, + type?: string +): File { + let file: File | FileLike + if (blob instanceof File) { + file = blob + } else { + type = type || (blob).type || '' + const filename = `${Date.now()}${getExtname(type)}` + try { + file = new File([blob], filename, { type }) + } catch (error) { + blob = blob instanceof Blob ? blob : new Blob([blob], { type }) + file = blob + file.name = file.name || filename + } + } + return file +} +/** + * 从本地file或者blob对象创建url + * @param {Blob|File} file + * @return {string} + */ +export function fileToUrl(file: Blob | File): string { + for (const key in files) { + if (hasOwn(files, key)) { + const oldFile = files[key] + if (oldFile === file) { + return key + } + } + } + var url = (window.URL || window.webkitURL).createObjectURL(file) + files[url] = file + return url +} + +export function getSameOriginUrl(url: string): Promise { + const a = document.createElement('a') + a.href = url + if (a.origin === location.origin) { + return Promise.resolve(url) + } + return urlToFile(url).then(fileToUrl) +} + +export function revokeObjectURL(url: string): void { + const URL = window.URL || window.webkitURL + URL.revokeObjectURL(url) + delete files[url] +} diff --git a/packages/uni-mp-weibo/src/helpers/getJSONP.ts b/packages/uni-mp-weibo/src/helpers/getJSONP.ts new file mode 100644 index 00000000000..08b104395b2 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/getJSONP.ts @@ -0,0 +1,44 @@ +import { isFunction } from '@vue/shared' +interface Options { + callback?: string + timeout?: number +} +let index = 0 +export function getJSONP( + url: string, + options: Options, + success: Function, + error: Function +) { + var js = document.createElement('script') + var callbackKey = options.callback || 'callback' + var callbackName = '__uni_jsonp_callback_' + index++ + var timeout = options.timeout || 30000 + var timing: ReturnType + function end() { + clearTimeout(timing) + delete (window as any)[callbackName] + js.remove() + } + ;(window as any)[callbackName] = (res: any) => { + if (isFunction(success)) { + success(res) + } + end() + } + js.onerror = () => { + if (isFunction(error)) { + error() + } + end() + } + timing = setTimeout(function () { + if (isFunction(error)) { + error() + } + end() + }, timeout) + js.src = + url + (url.indexOf('?') >= 0 ? '&' : '?') + callbackKey + '=' + callbackName + document.body.appendChild(js) +} diff --git a/packages/uni-mp-weibo/src/helpers/hexToRgba.ts b/packages/uni-mp-weibo/src/helpers/hexToRgba.ts new file mode 100644 index 00000000000..6dc9ffdda10 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/hexToRgba.ts @@ -0,0 +1,56 @@ +/** + * 从 16 进制的色值解析成 rgba 格式的色值 + * @param { string } hex, #000、#000A、#000000、#000000AA,参数只能是这四种格式 + */ +export function hexToRgba(hex: string): RGBA { + // 异常情况 + if (!hex) { + return { + r: 0, + g: 0, + b: 0, + a: 0, + } + } + // 去掉 # + let tmpHex = hex.slice(1) + const tmpHexLen = tmpHex.length + // 处理 16 进制色值位数异常的情况 + if (![3, 4, 6, 8].includes(tmpHexLen)) { + return { + r: 0, + g: 0, + b: 0, + a: 0, + } + } + // 格式化 tmpHex,使其变成 rrggbb 或 rrggbbaa + if (tmpHexLen === 3 || tmpHexLen === 4) { + // rgb => rrggbb || rgba => rrggbbaa + tmpHex = tmpHex.replace(/(\w{1})/g, '$1$1') + } + // rgba + let [sr, sg, sb, sa] = tmpHex.match(/(\w{2})/g) as string[] + // rgb + const r = parseInt(sr, 16), + g = parseInt(sg, 16), + b = parseInt(sb, 16) + + if (!sa) { + return { r, g, b, a: 1 } + } + + return { + r, + g, + b, + a: ((`0x100${sa}` as unknown as number) - 0x10000) / 255, + } +} + +export interface RGBA { + r: number + g: number + b: number + a: number +} diff --git a/packages/uni-mp-weibo/src/helpers/location.ts b/packages/uni-mp-weibo/src/helpers/location.ts new file mode 100644 index 00000000000..29eca4c3d0e --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/location.ts @@ -0,0 +1,142 @@ +import { getJSONP } from './getJSONP' +import { loadMaps } from '../view/components/map/maps' + +export interface Point { + latitude: number + longitude: number +} + +export const ICON_PATH_LOCTAION = + 'M13.3334375 16 q0.033125 1.1334375 0.783125 1.8834375 q0.75 0.75 1.8834375 0.75 q1.1334375 0 1.8834375 -0.75 q0.75 -0.75 0.75 -1.8834375 q0 -1.1334375 -0.75 -1.8834375 q-0.75 -0.75 -1.8834375 -0.75 q-1.1334375 0 -1.8834375 0.75 q-0.75 0.75 -0.783125 1.8834375 ZM30.9334375 14.9334375 l-1.1334375 0 q-0.5 -5.2 -4.0165625 -8.716875 q-3.516875 -3.5165625 -8.716875 -4.0165625 l0 -1.1334375 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 l0 1.1334375 q-5.2 0.5 -8.716875 4.0165625 q-3.5165625 3.516875 -4.0165625 8.716875 l-1.1334375 0 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 l1.1334375 0 q0.5 5.2 4.0165625 8.716875 q3.516875 3.5165625 8.716875 4.0165625 l0 1.1334375 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 l0 -1.1334375 q5.2 -0.5 8.716875 -4.0165625 q3.5165625 -3.516875 4.0165625 -8.716875 l1.1334375 0 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 ZM17.0665625 27.6665625 l0 -2.0665625 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 l0 2.0665625 q-4.3 -0.4665625 -7.216875 -3.383125 q-2.916875 -2.916875 -3.3834375 -7.216875 l2.0665625 0 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 q0 -0.4665625 -0.3 -0.7665625 q-0.3 -0.3 -0.7665625 -0.3 l-2.0665625 0 q0.4665625 -4.3 3.3834375 -7.216875 q2.9165625 -2.916875 7.216875 -3.3834375 l0 2.0665625 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 q0.4665625 0 0.7665625 -0.3 q0.3 -0.3 0.3 -0.7665625 l0 -2.0665625 q4.3 0.4665625 7.216875 3.3834375 q2.9165625 2.9165625 3.383125 7.216875 l-2.0665625 0 q-0.4665625 0 -0.7665625 0.3 q-0.3 0.3 -0.3 0.7665625 q0 0.4665625 0.3 0.7665625 q0.3 0.3 0.7665625 0.3 l2.0665625 0 q-0.4665625 4.3 -3.383125 7.216875 q-2.916875 2.9165625 -7.216875 3.383125 Z' + +export const ICON_PATH_ORIGIN = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAACECAMAAABmmnOVAAAC01BMVEUAAAAAef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef8Aef96quGStdqStdpbnujMzMzCyM7Gyc7Ky83MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMwAef8GfP0yjfNWnOp0qOKKsdyYt9mju9aZt9mMstx1qeJYnekyjvIIfP0qivVmouaWttnMzMyat9lppOUujPQKffxhoOfNzc3Y2Njh4eHp6enu7u7y8vL19fXv7+/i4uLZ2dnOzs6auNgOf/sKff15quHR0dHx8fH9/f3////j4+N6quFdn+iywdPb29vw8PD+/v7c3NyywtLa2tr29vbS0tLd3d38/Pzf39/o6Ojc7f+q0v+HwP9rsf9dqv9Hnv9Vpv/q6urj8P+Vx/9Am/8Pgf8Iff/z8/OAvP95uf/n5+c5l//V6f+52v+y1//7+/vt7e0rkP/09PTQ0NDq9P8Whf+cy//W1tbe3t7A3v/m5ubs7OxOov/r6+vk5OQiaPjKAAAAknRSTlMACBZ9oB71/jiqywJBZATT6hBukRXv+zDCAVrkDIf4JbQsTb7eVeJLbwfa8Rh4G/OlPS/6/kxQ9/xdmZudoJxNVhng7B6wtWdzAtQOipcF1329wS44doK/BAkyP1pvgZOsrbnGXArAg34G2IsD1eMRe7bi7k5YnqFT9V0csyPedQyYD3p/Fje+hDpskq/MwpRBC6yKp2MAAAQdSURBVHja7Zn1exMxGIAPHbrhDsPdneHuNtzd3d3dIbjLh93o2o4i7TpgG1Jk0g0mMNwd/gTa5rq129reHnK5e/bk/TFNk/dJ7r5894XjGAwGg8GgTZasCpDIll1+hxw5vXLJLpEboTx5ZXbIhyzkl9fB28cqUaCgrBKFkI3CcjoUKYolihWXUSI7EihRUjaHXF52CVRKLoe8eZIdUOkyMknkRw6UlcehYAFHiXK+skgURk6Ul8OhQjFnCVRRBolKqRxQ5SzUHaqgNGSj7VCmalqJnDkoS5RF6ZCbroNvufQkUD6qEuXTdUA+3hQdqiEXVKfnUKOmK4latalJ1EEuoZZ6162HJ9x/4OChw0eOHj12/MTJU6dxG7XUu751tjNnz4ET5y9ctLZTSr0beKFLl89bpuUDrqgC1RqNWqsKuqqzNFw7e51S6u3tc+OmZUJ9kCHY6ECwOkRvab51iUrqXej2HYDQsHBjWgx3Ae7dppB6N2wEcF9jdMGDUIDGTaR2aNoM9FqjG7QmaN5CWgc/gIePjG559BigpZQOrYB/4jBfRGRUtDkmJjY6KjLCofkpD62lc2gDfMpWPIuLdwyV8XEpHgaddBZ+wBuSFcwJqSN2ovmZ/dfnOvCTxqGtwzq8SEjv4EhISn48eWgnhUP7DvDSvgzxrs6vV6+FLiro2EkCic4QKkzwJsH1KYreCp0eQhfyDl1B/w4P/xa5JVJ4U03QjbRD9x7wXlgH5IE3wmMBHXoSlugFAcI6f/AkkSi8q6HQm6xDn77wEQ8djTwSj3tqAMguRTe4ikeOQyJ4YV+KfkQl+oNW5GbY4gWOWgbwJ+kwAD6Fi90MK2ZsrIeBBCUGwRXbqJ+/iJMQliIEBhOU6AJhtlG/IpHE2bqrYQg5h6HA4yQiRqwEfkGCdTCMmMRw+IbPDCQaHCsCYAQxiZHw3TbmD/ESOHgHwShiEqPhp/gggYkSztIxxCRawy/bmEniJaJtfwiEscQkxkFgRqJESqQwwHhiEuMBp3Vm8RK/cZoHEzKXhCK2QxEPpiJe0YlKCFaKCNv/cYBNUsBRPlkJSc0U+dM7E9H0ThGJbgZT/iR7yj+VqMS06Qr4+OFm2JdCxIa8lugzkJs5K6MfxAaYPUcBpYG5khZJEkUUSb7DPCnKRfPBXj6M8FwuegoLpCgXcQszVjhbJFUJUee2hBhLoYTIcYtB57KY+opSMdVqwatSlZVj05aV//CwJLMX2DluaUcwhXm4ali2XOoLjxUrPV26zFtF4f5p0Gp310+z13BUWNvbehEXona6iAtX/zVZmtfN4WixfsNky4S6gCCVVq3RPLdfSfpv3MRRZfPoLc6Xs/5bt3EyMGzE9h07/Xft2t15z6i9+zgGg8FgMBgMBoPBYDAYDAYj8/APG67Rie8pUDsAAAAASUVORK5CYII=' +export const ICON_PATH_TARGET = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAACcCAMAAAC3Fl5oAAAB3VBMVEVMaXH/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/EhL/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/Dw//AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/GRn/NTX/Dw//Fhb/AAD/AAD/AAD/GRn/GRn/Y2P/AAD/AAD/ExP/Ghr/AAD/AAD/MzP/GRn/AAD/Hh7/AAD/RUX/AAD/AAD/AAD/AAD/AAD/AAD/Dg7/AAD/HR3/Dw//FRX/SUn/AAD/////kJD/DQ3/Zmb/+/v/wMD/mJj/6en/vb3/1NT//Pz/ODj/+fn/3Nz/nJz/j4//9/f/7e3/9vb/7Oz/2Nj/x8f/Ozv/+Pj/3d3/nZ3/2dn//f3/6Oj/2tr/v7//09P/vr7/mZn/l5cdSvP3AAAAe3RSTlMAAhLiZgTb/vztB/JMRhlp6lQW86g8mQ4KFPs3UCH5U8huwlesWtTYGI7RsdVeJGfTW5rxnutLsvXWF8vQNdo6qQbuz7D4hgVIx2xtw8GC1TtZaIw0i84P98tU0/fsj7PKaAgiZZxeVfo8Z52eg1P0nESrENnjXVPUgw/uuSmDAAADsUlEQVR42u3aZ3cTRxgF4GtbYleSLdnGcsENG2ODjbExEHrvhAQCIb1Bem+QdkeuuFMNBBJIfmuOckzZI8/srHYmH3Lm+QNXK632LTvQ03Tu/IWeU/tTGTKT2n+q58L5c00wpXJd47DHEt5w47pKxLbhdLdPKb/7dBYxVLxw1GcI/2h1BcpzKNFHLX2JQ4gumaiitqpEEhEdOMJI9h5AFC3feYzI+7IF2tpSLEOqDXpObPRYFm/jCWho/4Ble7MdoT7fzhhq9yHEz28wltU1UPrJZ0wd66HwicfYvEFIfePTAP8tSLTupBHvtGJFH9bSkNrNWEHzERrT34xSH9Ogr1CijkbVAUH1KRqVqkdQAw07iIAaGlcTqI+/0LjeJJ5J0IIEnkpXMdzs4sTtW9dnZq7fuj2xOMtwVWk88RHDjBYejYvnjD8qjOpfQsUqhvj7oSjxcJIhVj3pyKqpNjYvVjQ/RrXq5YABKi3MCYm5BSrtWO5v11DlmlC4RpU1WRS9SJU7QukOVbpQ9JLu549+Dd0AUOlTbkGEuk85vxLAK5QbuytC3R2j3HoAjZSbFxrmKTcCoJdSk0LLJKV6gSaPMqNTQsvUKGW8JrxKqUWhaZFSeWyh1LTQNE2pHF6mzOy40DQ+S5mLimJcENoKlOnBWsr8KbRNUGYt5LXgd6HtD3lNQIoyN4S2G5RJIUOZm0LbTcqsBqVmhLYZSlkPsP4VWf+Rrd+m1v9o9h8Vv5p42C1R5qL1x7WRglOgVN52yfwNOBu76P+lLPoYidu23KPciIHGa07ZeIW1jvcNtI7q5vexCPGYCmf+m/Y9a3sAwQ5bI9T7ukPgPcn9GToEao+xk1OixJT+GIsvNAbx6eAgPq0xiF+KtkpYKhRXCQ8eFFcJhSWGu3rZ8jJkCM8kz9K4TUnrC6mAgzTsB9tLwQ2W15qfosQ2GrQNpZr7aczbzVjBZsvLcaC1g0bsbIVEnU8DOr6H1KDH2LwtUBi0/JII6Dxm9zUXkH+XMWzfh1Dte1i2Pe3QkC77Zel7aehpO8wyHG6Dtt0NjKxhN6I4uSli/TqJiJJDUQ4NDCURXTrXRy1XcumyD24M+AzhD1RXIIZsl/LoyZmurJHDM7s8lvB2FQ/PmPJ6PseAXP5HGMYAAC7ABbgAF+ACXIALcAEuwAW4ABfgAlyAC3ABLsAFuID/d8Cx4NEt8/byOf0wLnis8zjMq9/Kp7bWw4JOj8u8TlhRl+G/Mp2wpOX48GffvvZ1CyL4B53LAS6zb08EAAAAAElFTkSuQmCC' + +export const enum MapType { + QQ = 'qq', + GOOGLE = 'google', + AMAP = 'AMap', + UNKNOWN = '', +} + +export type TranslateCoordinateSystemOptions = ({ + coords, + skip, +}: { + coords: GeolocationCoordinates + skip?: boolean +}) => void + +export function getMapInfo() { + if (__uniConfig.qqMapKey) { + return { + type: MapType.QQ, + key: __uniConfig.qqMapKey, + } + } + if (__uniConfig.googleMapKey) { + return { + type: MapType.GOOGLE, + key: __uniConfig.googleMapKey, + } + } + if (__uniConfig.aMapKey) { + return { + type: MapType.AMAP, + key: __uniConfig.aMapKey, + securityJsCode: __uniConfig.aMapSecurityJsCode, + serviceHost: __uniConfig.aMapServiceHost, + } + } + return { + type: MapType.UNKNOWN, + key: '', + } +} + +let IS_AMAP = false +let hasGetIsAMap = false +export const getIsAMap = () => { + if (hasGetIsAMap) { + return IS_AMAP + } else { + hasGetIsAMap = true + return (IS_AMAP = getMapInfo().type === MapType.AMAP) + } +} + +export function translateCoordinateSystem( + type: string | undefined, + coords: GeolocationCoordinates, + skip?: boolean +) { + const mapInfo = getMapInfo() + const wgs84Map = [MapType.GOOGLE] + if ( + (type && type.toUpperCase() === 'WGS84') || + wgs84Map.includes(mapInfo.type) || + skip + ) { + return Promise.resolve(coords) + } + if (mapInfo.type === MapType.QQ) { + return new Promise((resolve: GeolocationCoordinates | any) => { + getJSONP( + `https://apis.map.qq.com/jsapi?qt=translate&type=1&points=${coords.longitude},${coords.latitude}&key=${mapInfo.key}&output=jsonp&pf=jsapi&ref=jsapi`, + { + callback: 'cb', + }, + (res: any) => { + if ( + 'detail' in res && + 'points' in res.detail && + res.detail.points.length + ) { + const { lng, lat } = res.detail.points[0] + resolve({ + longitude: lng, + latitude: lat, + altitude: coords.altitude, + accuracy: coords.accuracy, + altitudeAccuracy: coords.altitudeAccuracy, + heading: coords.heading, + speed: coords.speed, + }) + } else { + resolve(coords) + } + }, + () => resolve(coords) + ) + }) + } + if (mapInfo.type === MapType.AMAP) { + return new Promise((resolve: GeolocationCoordinates | any) => { + loadMaps([], () => { + window.AMap.convertFrom( + [coords.longitude, coords.latitude], + 'gps', + (_: string, res: any) => { + if (res.info === 'ok' && res.locations.length) { + const { lat, lng } = res.locations[0] + resolve({ + longitude: lng, + latitude: lat, + altitude: coords.altitude, + accuracy: coords.accuracy, + altitudeAccuracy: coords.altitudeAccuracy, + heading: coords.heading, + speed: coords.speed, + }) + } else { + resolve(coords) + } + } + ) + }) + }) + } + return Promise.reject(new Error('translate coordinate system faild')) +} diff --git a/packages/uni-mp-weibo/src/helpers/theme.ts b/packages/uni-mp-weibo/src/helpers/theme.ts new file mode 100644 index 00000000000..186cae09392 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/theme.ts @@ -0,0 +1,29 @@ +import { getTheme } from '../service/api/base/getBrowserInfo' +import { normalizeStyles, ON_THEME_CHANGE } from '@dcloudio/uni-shared' + +export { getTheme } + +export function onThemeChange( + callback: (res: { theme: UniApp.ThemeMode }) => void +) { + if (__uniConfig.darkmode) { + UniServiceJSBridge.on(ON_THEME_CHANGE, callback as UniApp.CallbackFunction) + } +} + +export function offThemeChange(callback: UniApp.CallbackFunction) { + UniServiceJSBridge.off(ON_THEME_CHANGE, callback) +} + +export function parseTheme(pageStyle: T): T { + let parsedStyle = {} as T + if (__uniConfig.darkmode) { + parsedStyle = normalizeStyles( + pageStyle, + __uniConfig.themeConfig, + getTheme() + ) + } + + return __uniConfig.darkmode ? parsedStyle : pageStyle +} diff --git a/packages/uni-mp-weibo/src/helpers/useDocumentTitle.ts b/packages/uni-mp-weibo/src/helpers/useDocumentTitle.ts new file mode 100644 index 00000000000..922e7ae16eb --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/useDocumentTitle.ts @@ -0,0 +1,24 @@ +import { watchEffect, onActivated, ssrContextKey } from 'vue' +import { UNI_SSR_TITLE, ON_NAVIGATION_BAR_CHANGE } from '@dcloudio/uni-shared' +import { getApp } from '../framework/setup/app' + +export function updateDocumentTitle(title: string) { + if (__NODE_JS__) { + // setNavigationBarTitle 可能是异步调用,此时使用 useSSRContext 获取,可能没有 instance + const ssrContext = getApp().$.appContext.provides[ssrContextKey] + if (ssrContext) { + ssrContext[UNI_SSR_TITLE] = title + } + } else { + document.title = title + } + UniServiceJSBridge.emit(ON_NAVIGATION_BAR_CHANGE, { titleText: title }) +} + +export function useDocumentTitle(pageMeta: UniApp.PageRouteMeta) { + function update() { + updateDocumentTitle(pageMeta.navigationBar.titleText!) + } + watchEffect(update) + onActivated(update) +} diff --git a/packages/uni-mp-weibo/src/helpers/useKeyboard.ts b/packages/uni-mp-weibo/src/helpers/useKeyboard.ts new file mode 100644 index 00000000000..f2e29ea0dfa --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/useKeyboard.ts @@ -0,0 +1,42 @@ +import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue' + +const KEY_MAPS = { + esc: ['Esc', 'Escape'], + // tab: ['Tab'], + enter: ['Enter'], + // space: [' ', 'Spacebar'], + // up: ['Up', 'ArrowUp'], + // left: ['Left', 'ArrowLeft'], + // right: ['Right', 'ArrowRight'], + // down: ['Down', 'ArrowDown'], + // delete: ['Backspace', 'Delete', 'Del'], +} + +const KEYS = Object.keys(KEY_MAPS) +export function useKeyboard() { + const key = ref('') + const disable = ref(false) + const onKeyup = (evt: KeyboardEvent) => { + if (disable.value) { + return + } + const res = KEYS.find( + (key) => KEY_MAPS[key as keyof typeof KEY_MAPS].indexOf(evt.key) !== -1 + ) + if (res) { + key.value = res + } + // reset key.value + nextTick(() => (key.value = '')) + } + onMounted(() => { + document.addEventListener('keyup', onKeyup) + }) + onBeforeUnmount(() => { + document.removeEventListener('keyup', onKeyup) + }) + return { + key, + disable, + } +} diff --git a/packages/uni-mp-weibo/src/helpers/usePopupStyle.ts b/packages/uni-mp-weibo/src/helpers/usePopupStyle.ts new file mode 100644 index 00000000000..be88c568078 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/usePopupStyle.ts @@ -0,0 +1,112 @@ +import { extend } from '@vue/shared' +import { onMounted, computed, ref, onUnmounted } from 'vue' + +type Popover = { + left: number + width: number + top: number + height: number +} + +export type popupStyleType = { + content: { + transform: string + left: string + top: string + bottom: string + } + triangle: { + 'border-width': string + 'border-color': string + left: string + top: string + bottom: string + } +} + +export function usePopupStyle(props: Data) { + const popupWidth = ref(0) + const popupHeight = ref(0) + + const isDesktop = computed( + () => popupWidth.value >= 500 && popupHeight.value >= 500 + ) + const popupStyle = computed(() => { + const style: popupStyleType = { + content: { + transform: '', + left: '', + top: '', + bottom: '', + }, + triangle: { + left: '', + top: '', + bottom: '', + 'border-width': '', + 'border-color': '', + }, + } + const contentStyle = style.content + const triangleStyle = style.triangle + const popover: Popover = props.popover as Popover + function getNumber(value: number | string) { + return Number(value) || 0 + } + if (isDesktop.value && popover) { + extend(triangleStyle, { + position: 'absolute', + width: '0', + height: '0', + 'margin-left': '-6px', + 'border-style': 'solid', + }) + const popoverLeft = getNumber(popover.left) + const popoverWidth = getNumber(popover.width) + const popoverTop = getNumber(popover.top) + const popoverHeight = getNumber(popover.height) + const center = popoverLeft + popoverWidth / 2 + contentStyle.transform = 'none !important' + const contentLeft = Math.max(0, center - 300 / 2) + contentStyle.left = `${contentLeft}px` + let triangleLeft = Math.max(12, center - contentLeft) + triangleLeft = Math.min(300 - 12, triangleLeft) + triangleStyle.left = `${triangleLeft}px` + const vcl = popupHeight.value / 2 + if (popoverTop + popoverHeight - vcl > vcl - popoverTop) { + contentStyle.top = 'auto' + contentStyle.bottom = `${popupHeight.value - popoverTop + 6}px` + triangleStyle.bottom = '-6px' + triangleStyle['border-width'] = '6px 6px 0 6px' + triangleStyle['border-color'] = + '#fcfcfd transparent transparent transparent' + } else { + contentStyle.top = `${popoverTop + popoverHeight + 6}px` + triangleStyle.top = '-6px' + triangleStyle['border-width'] = '0 6px 6px 6px' + triangleStyle['border-color'] = + 'transparent transparent #fcfcfd transparent' + } + } + return style + }) + + onMounted(() => { + const fixSize = () => { + const { windowWidth, windowHeight, windowTop } = uni.getSystemInfoSync() + popupWidth.value = windowWidth + popupHeight.value = windowHeight + (windowTop || 0) + } + window.addEventListener('resize', fixSize) + fixSize() + + onUnmounted(() => { + window.removeEventListener('resize', fixSize) + }) + }) + + return { + isDesktop, + popupStyle, + } +} diff --git a/packages/uni-mp-weibo/src/helpers/usePreventScroll.ts b/packages/uni-mp-weibo/src/helpers/usePreventScroll.ts new file mode 100644 index 00000000000..76afd3c7ba0 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/usePreventScroll.ts @@ -0,0 +1,24 @@ +import { onMounted, onUnmounted } from 'vue' + +let index = 0 +let overflow = '' + +export function preventScroll(prevent: boolean) { + let before = index + index += prevent ? 1 : -1 + index = Math.max(0, index) + if (index > 0) { + if (before === 0) { + overflow = document.body.style.overflow + document.body.style.overflow = 'hidden' + } + } else { + document.body.style.overflow = overflow + overflow = '' + } +} + +export function usePreventScroll() { + onMounted(() => preventScroll(true)) + onUnmounted(() => preventScroll(false)) +} diff --git a/packages/uni-mp-weibo/src/helpers/utils.ts b/packages/uni-mp-weibo/src/helpers/utils.ts new file mode 100644 index 00000000000..50f03876759 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/utils.ts @@ -0,0 +1,14 @@ +import { ComponentPublicInstance } from 'vue' + +const WINDOW_NAMES = ['VUniLeftWindow', 'VUniTopWindow', 'VUniRightWindow'] + +export function isInWindows(vm: ComponentPublicInstance) { + while (vm) { + const name = vm.$options.name + if (name && WINDOW_NAMES.indexOf(name) !== -1) { + return true + } + vm = vm.$parent! + } + return false +} diff --git a/packages/uni-mp-weibo/src/helpers/uuid.ts b/packages/uni-mp-weibo/src/helpers/uuid.ts new file mode 100644 index 00000000000..8ab14acfcf5 --- /dev/null +++ b/packages/uni-mp-weibo/src/helpers/uuid.ts @@ -0,0 +1,16 @@ +const UUID_KEY = '__DC_STAT_UUID' +const storage: Record = + (navigator.cookieEnabled && (window.localStorage || window.sessionStorage)) || + {} +let deviceId: string + +export default function () { + deviceId = deviceId || storage[UUID_KEY] + if (!deviceId) { + deviceId = Date.now() + '' + Math.floor(Math.random() * 1e7) + try { + storage[UUID_KEY] = deviceId + } catch (error) {} + } + return deviceId +} diff --git a/packages/uni-mp-weibo/src/index.ts b/packages/uni-mp-weibo/src/index.ts new file mode 100644 index 00000000000..98045725b2c --- /dev/null +++ b/packages/uni-mp-weibo/src/index.ts @@ -0,0 +1,53 @@ +export { + Button, + Canvas, + Checkbox, + CheckboxGroup, + Editor, + Form, + Icon, + Image, + Input, + Label, + MovableArea, + MovableView, + Navigator, + PickerView, + PickerViewColumn, + Progress, + Radio, + RadioGroup, + ResizeSensor, + RichText, + ScrollView, + Slider, + Swiper, + SwiperItem, + Switch, + Text, + Textarea, + View, +} from '@dcloudio/uni-components' + +export { useI18n } from '@dcloudio/uni-core' + +export { default as plugin } from './framework/plugin' + +export * from './framework/setup' + +export * from './view/components' + +export * from './view/bridge' + +export * from './service/api' +export * from './service/api/uni' +export * from './service/bridge' + +export { getApp, getCurrentPages } from './framework' + +export { default as LayoutComponent } from './framework/components/layout/index' +export { default as PageComponent } from './framework/components/page/index' +export { default as AsyncErrorComponent } from './framework/components/async-error/index' +export { default as AsyncLoadingComponent } from './framework/components/async-loading' +export * from './framework/setup/state' +export { getRealPath } from './platform' diff --git a/packages/uni-mp-weibo/src/platform/constants.ts b/packages/uni-mp-weibo/src/platform/constants.ts new file mode 100644 index 00000000000..79344672e5b --- /dev/null +++ b/packages/uni-mp-weibo/src/platform/constants.ts @@ -0,0 +1 @@ +export const TEMP_PATH = '' diff --git a/packages/uni-mp-weibo/src/platform/dom.ts b/packages/uni-mp-weibo/src/platform/dom.ts new file mode 100644 index 00000000000..2caa7f5b6cb --- /dev/null +++ b/packages/uni-mp-weibo/src/platform/dom.ts @@ -0,0 +1,65 @@ +import { ComponentPublicInstance } from 'vue' +import { getRealRoute } from '@dcloudio/uni-core' +import { addLeadingSlash, DATA_RE, SCHEME_RE } from '@dcloudio/uni-shared' +declare global { + interface ImportMeta { + env: { + BASE_URL: string + } + } +} + +export function findElem(vm: ComponentPublicInstance) { + if (__APP_VIEW__) { + // App 端,传入的是 nodeId + return (window as any).__$__(vm).$ + } + return vm.$el +} + +// const baseUrl = __IMPORT_META_ENV_BASE_URL__ +function addBase(filePath: string) { + const { base: baseUrl } = __uniConfig.router! + // filepath可能已经被补充了baseUrl + if (addLeadingSlash(filePath).indexOf(baseUrl) === 0) { + return addLeadingSlash(filePath) + } + return baseUrl + filePath +} + +export function getRealPath(filePath: string) { + // 相对路径模式对静态资源路径特殊处理 + const { base, assets } = __uniConfig.router! + if (base === './') { + if ( + filePath.indexOf('./static/') === 0 || + (assets && filePath.indexOf('./' + assets + '/') === 0) + ) { + filePath = filePath.slice(1) + } + } + if (filePath.indexOf('/') === 0) { + if (filePath.indexOf('//') === 0) { + filePath = 'https:' + filePath + } else { + return addBase(filePath.slice(1)) + } + } + // 网络资源或base64 + if ( + SCHEME_RE.test(filePath) || + DATA_RE.test(filePath) || + filePath.indexOf('blob:') === 0 + ) { + return filePath + } + + const pages = getCurrentPages() + if (pages.length) { + return addBase( + getRealRoute(pages[pages.length - 1].$page.route, filePath).slice(1) + ) + } + + return filePath +} diff --git a/packages/uni-mp-weibo/src/platform/index.ts b/packages/uni-mp-weibo/src/platform/index.ts new file mode 100644 index 00000000000..1ba32b29862 --- /dev/null +++ b/packages/uni-mp-weibo/src/platform/index.ts @@ -0,0 +1,21 @@ +export * from './dom' +export { getBaseSystemInfo } from '../service/api/base/getBaseSystemInfo' +export { operateVideoPlayer } from '../service/api/context/operateVideoPlayer' +export { operateMap } from '../service/api/context/operateMap' +export { requestComponentInfo } from '../service/api/ui/requestComponentInfo' +export { setCurrentPageMeta } from '../service/api/ui/setPageMeta' +export { + addIntersectionObserver, + removeIntersectionObserver, +} from '../service/api/ui/intersectionObserver' +export { + addMediaQueryObserver, + removeMediaQueryObserver, +} from '../service/api/ui/mediaQueryObserver' +export * from './saveImage' +export * from './constants' +export { getSameOriginUrl } from '../helpers/file' +export { getEnterOptions, getLaunchOptions } from '../framework/setup/utils' + +export const inflateRaw = (...args: any[]): any => {} +export const deflateRaw = (...args: any[]): any => {} diff --git a/packages/uni-mp-weibo/src/platform/saveImage.ts b/packages/uni-mp-weibo/src/platform/saveImage.ts new file mode 100644 index 00000000000..07ea58a4de2 --- /dev/null +++ b/packages/uni-mp-weibo/src/platform/saveImage.ts @@ -0,0 +1,7 @@ +export function saveImage( + base64: string, + dirname: string, + callback: (error: Error | null, tempFilePath: string) => void +) { + callback(null, base64) +} diff --git a/packages/uni-mp-weibo/src/service/api/base/canIUse.ts b/packages/uni-mp-weibo/src/service/api/base/canIUse.ts new file mode 100644 index 00000000000..e5e841d15b0 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/base/canIUse.ts @@ -0,0 +1,46 @@ +import { hasOwn } from '@vue/shared' + +import { + API_CAN_I_USE, + API_TYPE_CAN_I_USE, + CanIUseProtocol, + defineSyncApi, +} from '@dcloudio/uni-api' + +const supports = window.CSS && window.CSS.supports + +function cssSupports(css: string) { + return ( + supports && + (supports(css) || supports.apply(window.CSS, css.split(':') as any)) + ) +} + +export const cssVar = __NODE_JS__ ? true : /*#__PURE__*/ cssSupports('--a:0') +export const cssEnv = __NODE_JS__ + ? true + : /*#__PURE__*/ cssSupports('top:env(a)') +export const cssConstant = __NODE_JS__ + ? true + : /*#__PURE__*/ cssSupports('top:constant(a)') +export const cssBackdropFilter = __NODE_JS__ + ? true + : /*#__PURE__*/ cssSupports('backdrop-filter:blur(10px)') + +const SCHEMA_CSS = { + 'css.var': cssVar, + 'css.env': cssEnv, + 'css.constant': cssConstant, + 'css.backdrop-filter': cssBackdropFilter, +} + +export const canIUse = defineSyncApi( + API_CAN_I_USE, + (schema: string) => { + if (hasOwn(SCHEMA_CSS, schema)) { + return SCHEMA_CSS[schema] + } + return true + }, + CanIUseProtocol +) diff --git a/packages/uni-mp-weibo/src/service/api/base/getBaseSystemInfo.ts b/packages/uni-mp-weibo/src/service/api/base/getBaseSystemInfo.ts new file mode 100644 index 00000000000..1bda3782983 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/base/getBaseSystemInfo.ts @@ -0,0 +1,61 @@ +export const ua = navigator.userAgent + +export const isAndroid = /*#__PURE__*/ /android/i.test(ua) + +export const isIOS = /*#__PURE__*/ /iphone|ipad|ipod/i.test(ua) + +export const isWindows = /*#__PURE__*/ ua.match(/Windows NT ([\d|\d.\d]*)/i) + +export const isMac = /*#__PURE__*/ /Macintosh|Mac/i.test(ua) + +export const isLinux = /*#__PURE__*/ /Linux|X11/i.test(ua) + +export const isIPadOS = isMac && navigator.maxTouchPoints > 0 + +export function getScreenFix() { + return ( + /^Apple/.test(navigator.vendor) && typeof window.orientation === 'number' + ) +} + +export function isLandscape(screenFix: boolean) { + return screenFix && Math.abs(window.orientation as number) === 90 +} + +export function getScreenWidth(screenFix: boolean, landscape: boolean) { + return screenFix + ? Math[landscape ? 'max' : 'min'](screen.width, screen.height) + : screen.width +} + +export function getScreenHeight(screenFix: boolean, landscape: boolean) { + return screenFix + ? Math[landscape ? 'min' : 'max'](screen.height, screen.width) + : screen.height +} + +export function getWindowWidth(screenWidth: number) { + return ( + Math.min( + window.innerWidth, + document.documentElement.clientWidth, + screenWidth + ) || screenWidth + ) +} + +/** + * 简易版systemInfo,主要为upx2px,i18n服务 + * @returns + */ +export function getBaseSystemInfo() { + const screenFix = getScreenFix() + const windowWidth = getWindowWidth( + getScreenWidth(screenFix, isLandscape(screenFix)) + ) + return { + platform: isIOS ? 'ios' : 'other', + pixelRatio: window.devicePixelRatio, + windowWidth, + } +} diff --git a/packages/uni-mp-weibo/src/service/api/base/getBrowserInfo.ts b/packages/uni-mp-weibo/src/service/api/base/getBrowserInfo.ts new file mode 100644 index 00000000000..7dc2c4128e4 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/base/getBrowserInfo.ts @@ -0,0 +1,224 @@ +import { isFunction, isString } from '@vue/shared' +import { + ua, + isIOS, + isAndroid, + isWindows, + isMac, + isLinux, + isIPadOS, +} from '../base/getBaseSystemInfo' + +function IEVersion() { + const userAgent = navigator.userAgent + const isIE = + userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1 + const isEdge = userAgent.indexOf('Edge') > -1 && !isIE + const isIE11 = + userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1 + if (isIE) { + const reIE = new RegExp('MSIE (\\d+\\.\\d+);') + reIE.test(userAgent) + const fIEVersion = parseFloat(RegExp.$1) + if (fIEVersion > 6) { + return fIEVersion + } else { + return 6 + } + } else if (isEdge) { + return -1 + } else if (isIE11) { + return 11 + } else { + return -1 + } +} + +export function getTheme() { + if (__uniConfig.darkmode !== true) + return isString(__uniConfig.darkmode) ? __uniConfig.darkmode : 'light' + try { + return ( + window.matchMedia('(prefers-color-scheme: light)').matches + ? 'light' + : 'dark' + ) as UniApp.ThemeMode + } catch (error) { + return 'light' + } +} + +export function getBrowserInfo() { + let osname + let osversion = '0' + let model = '' + let deviceType = 'phone' + const language = navigator.language + + if (isIOS) { + osname = 'iOS' + const osversionFind = ua.match(/OS\s([\w_]+)\slike/) + if (osversionFind) { + osversion = osversionFind[1].replace(/_/g, '.') + } + const modelFind = ua.match(/\(([a-zA-Z]+);/) + if (modelFind) { + model = modelFind[1] + } + } else if (isAndroid) { + osname = 'Android' + // eslint-disable-next-line no-useless-escape + const osversionFind = ua.match(/Android[\s/]([\w\.]+)[;\s]/) + if (osversionFind) { + osversion = osversionFind[1] + } + const infoFind = ua.match(/\((.+?)\)/) + const infos = infoFind ? infoFind[1].split(';') : ua.split(' ') + // eslint-disable-next-line no-useless-escape + const otherInfo = [ + /\bAndroid\b/i, + /\bLinux\b/i, + /\bU\b/i, + /^\s?[a-z][a-z]$/i, + /^\s?[a-z][a-z]-[a-z][a-z]$/i, + /\bwv\b/i, + /\/[\d\.,]+$/, + /^\s?[\d\.,]+$/, + /\bBrowser\b/i, + /\bMobile\b/i, + ] + for (let i = 0; i < infos.length; i++) { + const info = infos[i] + if (info.indexOf('Build') > 0) { + model = info.split('Build')[0].trim() + break + } + let other + for (let o = 0; o < otherInfo.length; o++) { + if (otherInfo[o].test(info)) { + other = true + break + } + } + if (!other) { + model = info.trim() + break + } + } + } else if (isIPadOS) { + model = 'iPad' + osname = 'iOS' + deviceType = 'pad' + osversion = isFunction(window.BigInt) ? '14.0' : '13.0' + } else if (isWindows || isMac || isLinux) { + model = 'PC' + osname = 'PC' + deviceType = 'pc' + osversion = '0' + + let osversionFind = ua.match(/\((.+?)\)/)![1] + + if (isWindows) { + osname = 'Windows' + switch (isWindows[1]) { + case '5.1': + osversion = 'XP' + break + case '6.0': + osversion = 'Vista' + break + case '6.1': + osversion = '7' + break + case '6.2': + osversion = '8' + break + case '6.3': + osversion = '8.1' + break + case '10.0': + osversion = '10' + break + } + + const framework = osversionFind && osversionFind.match(/[Win|WOW]([\d]+)/) + if (framework) { + osversion += ` x${framework[1]}` + } + } else if (isMac) { + osname = 'macOS' + const _osversion = + (osversionFind && osversionFind.match(/Mac OS X (.+)/)) || '' + + if (osversion) { + osversion = _osversion[1].replace(/_/g, '.') + // '10_15_7' or '10.16; rv:86.0' + if (osversion.indexOf(';') !== -1) { + osversion = osversion.split(';')[0] + } + } + } else if (isLinux) { + osname = 'Linux' + const _osversion = + (osversionFind && osversionFind.match(/Linux (.*)/)) || '' + + if (_osversion) { + osversion = _osversion[1] + // 'x86_64' or 'x86_64; rv:79.0' + if (osversion.indexOf(';') !== -1) { + osversion = osversion.split(';')[0] + } + } + } + } else { + osname = 'Other' + osversion = '0' + deviceType = 'unknown' + } + + const system = `${osname} ${osversion}` + const platform = osname.toLocaleLowerCase() + + let browserName = '' + let browserVersion = String(IEVersion()) + if (browserVersion !== '-1') { + browserName = 'IE' + } else { + const browseVendors = ['Version', 'Firefox', 'Chrome', 'Edge{0,1}'] + const vendors = ['Safari', 'Firefox', 'Chrome', 'Edge'] + for (let index = 0; index < browseVendors.length; index++) { + const vendor = browseVendors[index] + const reg = new RegExp(`(${vendor})/(\\S*)\\b`) + if (reg.test(ua)) { + browserName = vendors[index] + browserVersion = ua.match(reg)![2] + } + } + } + + // deviceOrientation + let deviceOrientation: 'portrait' | 'landscape' = 'portrait' + const orientation = + typeof window.screen.orientation === 'undefined' + ? window.orientation + : window.screen.orientation.angle + deviceOrientation = Math.abs(orientation) === 90 ? 'landscape' : 'portrait' + //TODO deviceBrand brand 要是 undeinfed + return { + deviceBrand: undefined, + brand: undefined, + deviceModel: model, + deviceOrientation, + model, + system, + platform, + browserName: browserName.toLocaleLowerCase(), + browserVersion, + language, + deviceType, + ua, + osname, + osversion, + theme: getTheme(), + } +} diff --git a/packages/uni-mp-weibo/src/service/api/context/createInnerAudioContext.ts b/packages/uni-mp-weibo/src/service/api/context/createInnerAudioContext.ts new file mode 100644 index 00000000000..24b2019f3c4 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/context/createInnerAudioContext.ts @@ -0,0 +1,283 @@ +import { isFunction } from '@vue/shared' +import { getRealPath } from '@dcloudio/uni-platform' +import { + API_CREATE_INNER_AUDIO_CONTEXT, + defineSyncApi, +} from '@dcloudio/uni-api' +import type { API_TYPE_CREATEE_INNER_AUDIO_CONTEXT } from '@dcloudio/uni-api' +import { once } from '@dcloudio/uni-shared' +import { + InnerAudioContextEvent, + innerAudioContextEventNames, + innerAudioContextOffEventNames, +} from '@dcloudio/uni-api' + +//#region types +type Property = + | 'src' + | 'autoplay' + | 'loop' + | 'duration' + | 'currentTime' + | 'paused' + | 'volume' + +type InnerAudioProperty = keyof Pick +//#endregion + +const initInnerAudioContextEventOnce = /*#__PURE__*/ once(() => { + // 批量设置音频上下文事件监听方法 + innerAudioContextEventNames.forEach((eventName) => { + InnerAudioContext.prototype[eventName] = function (callback: Function) { + if (isFunction(callback)) { + this._events[eventName]!.push(callback) + } + } + }) + + // 批量设置音频上下文事件取消监听方法 + innerAudioContextOffEventNames.forEach((eventName) => { + InnerAudioContext.prototype[eventName] = function (callback: Function) { + var handle = + this._events[eventName.replace('off', 'on') as InnerAudioContextEvent] + var index = handle!.indexOf(callback) + if (index >= 0) { + handle!.splice(index, 1) + } + } + }) +}) +/** + * 音频上下文对象 + */ +class InnerAudioContext implements UniApp.InnerAudioContext { + /** + * 当前音频的长度(单位:s),只有在当前有合法的 src 时返回 + */ + 'duration': UniApp.InnerAudioContext['duration'] + /** + * 当前音频的播放位置(单位:s),只有在当前有合法的 src 时返回 + */ + 'currentTime': UniApp.InnerAudioContext['currentTime'] + /** + * 当前是是否暂停或停止状态,true 表示暂停或停止,false 表示正在播放 + */ + 'paused': UniApp.InnerAudioContext['paused'] + /** + * 音频的数据链接,用于直接播放。 + */ + 'src': UniApp.InnerAudioContext['src'] + /** + * 音频缓冲的时间点,仅保证当前播放时间点到此时间点内容已缓冲 + */ + 'buffered': UniApp.InnerAudioContext['buffered'] + /** + * 是否自动开始播放,默认 false + */ + 'autoplay': UniApp.InnerAudioContext['autoplay'] + /** + * 是否循环播放,默认 false + */ + 'loop': UniApp.InnerAudioContext['loop'] + /** + * 是否遵循系统静音开关,当此参数为 false 时,即使用户打开了静音开关,也能继续发出声音,默认值 true + */ + 'obeyMuteSwitch': UniApp.InnerAudioContext['obeyMuteSwitch'] + /** + * 音量。范围 0~1。 + */ + 'volume': UniApp.InnerAudioContext['volume'] + /** + * 原始音频对象 + */ + _audio: HTMLAudioElement + /** + * 是否暂停中 + */ + _stoping: boolean + /** + * 开始时间 + */ + startTime: number + /** + * 事件监听 + */ + _events: Partial>> + /** + * 音频地址 + */ + _src: string = '' + /** + * 音频上下文初始化 + */ + constructor() { + var audio = (this._audio = new Audio()) + this._stoping = false + // 和audio对象同名同效果的属性 + const propertys: InnerAudioProperty[] = [ + 'src', + 'autoplay', + 'loop', + 'duration', + 'currentTime', + 'paused', + 'volume', + ] + propertys.forEach((property) => { + Object.defineProperty(this, property, { + set: + property === 'src' + ? (src) => { + audio.src = getRealPath(src) + this._src = src + return src + } + : (val) => { + ;(audio as any)[property] = val + return val + }, + get: + property === 'src' + ? () => { + return this._src + } + : () => { + return audio[property] + }, + }) + }) + this.startTime = 0 + Object.defineProperty(this, 'obeyMuteSwitch', { + set: () => false, + get: () => false, + }) + Object.defineProperty(this, 'buffered', { + get() { + var buffered = audio.buffered + if (buffered.length) { + return buffered.end(buffered.length - 1) + } else { + return 0 + } + }, + }) + // 初始化事件监听列表 + this._events = {} + innerAudioContextEventNames.forEach((eventName) => { + this._events[eventName] = [] + }) + audio.addEventListener('loadedmetadata', () => { + var startTime = Number(this.startTime) || 0 + if (startTime > 0) { + audio.currentTime = startTime + } + }) + // 和audio对象同名同效果的事件 + + var stopEventNames = ['canplay', 'pause', 'seeking', 'seeked', 'timeUpdate'] + var eventNames = stopEventNames.concat([ + 'play', + 'ended', + 'error', + 'waiting', + ]) + eventNames.forEach((eventName) => { + audio.addEventListener( + eventName.toLowerCase(), + () => { + // stop事件过滤 + if (this._stoping && stopEventNames.indexOf(eventName) >= 0) { + return + } + const EventName = `on${eventName + .slice(0, 1) + .toUpperCase()}${eventName.slice(1)}` as InnerAudioContextEvent + this._events[EventName]!.forEach((callback) => { + callback() + }) + }, + false + ) + }) + initInnerAudioContextEventOnce() + } + + /** + * 播放 + */ + play() { + this._stoping = false + this._audio.play() + } + + /** + * 暂停 + */ + pause() { + this._audio.pause() + } + + /** + * 停止 + */ + stop() { + this._stoping = true + this._audio.pause() + this._audio.currentTime = 0 + this._events.onStop!.forEach((callback) => { + callback() + }) + } + + /** + * 跳转到 + * @param {number} position + */ + seek(position: number) { + this._stoping = false + position = Number(position) + if (typeof position === 'number' && !isNaN(position)) { + this._audio.currentTime = position + } + } + + /** + * 销毁 + */ + destroy() { + this.stop() + } + + 'onCanplay': UniApp.InnerAudioContext['onCanplay'] + 'onPlay': UniApp.InnerAudioContext['onPlay'] + 'onPause': UniApp.InnerAudioContext['onPause'] + 'onStop': UniApp.InnerAudioContext['onStop'] + 'onEnded': UniApp.InnerAudioContext['onEnded'] + 'onTimeUpdate': UniApp.InnerAudioContext['onTimeUpdate'] + 'onError': UniApp.InnerAudioContext['onError'] + 'onWaiting': UniApp.InnerAudioContext['onWaiting'] + 'onSeeking': UniApp.InnerAudioContext['onSeeking'] + 'onSeeked': UniApp.InnerAudioContext['onSeeked'] + + 'offCanplay': UniApp.InnerAudioContext['offCanplay'] + 'offPlay': UniApp.InnerAudioContext['offPlay'] + 'offPause': UniApp.InnerAudioContext['offPause'] + 'offStop': UniApp.InnerAudioContext['offStop'] + 'offEnded': UniApp.InnerAudioContext['offEnded'] + 'offTimeUpdate': UniApp.InnerAudioContext['offTimeUpdate'] + 'offError': UniApp.InnerAudioContext['offError'] + 'offWaiting': UniApp.InnerAudioContext['offWaiting'] + 'offSeeking': UniApp.InnerAudioContext['offSeeking'] + 'offSeeked': UniApp.InnerAudioContext['offSeeked'] +} + +/** + * 创建音频上下文 + */ +export const createInnerAudioContext = + defineSyncApi( + API_CREATE_INNER_AUDIO_CONTEXT, + () => { + return new InnerAudioContext() + } + ) diff --git a/packages/uni-mp-weibo/src/service/api/context/operateMap.ts b/packages/uni-mp-weibo/src/service/api/context/operateMap.ts new file mode 100644 index 00000000000..bd8fc168c7b --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/context/operateMap.ts @@ -0,0 +1,17 @@ +export function operateMap( + id: string, + pageId: number, + type: string, + data?: unknown, + operateMapCallback?: (res: any) => void +) { + UniServiceJSBridge.invokeViewMethod( + 'map.' + id, + { + type, + data, + }, + pageId, + operateMapCallback + ) +} diff --git a/packages/uni-mp-weibo/src/service/api/context/operateVideoPlayer.ts b/packages/uni-mp-weibo/src/service/api/context/operateVideoPlayer.ts new file mode 100644 index 00000000000..dac17b663cc --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/context/operateVideoPlayer.ts @@ -0,0 +1,16 @@ +export function operateVideoPlayer( + videoId: string, + pageId: number, + type: string, + data?: unknown +) { + UniServiceJSBridge.invokeViewMethod( + 'video.' + videoId, + { + videoId, + type, + data, + }, + pageId + ) +} diff --git a/packages/uni-mp-weibo/src/service/api/device/accelerometer.ts b/packages/uni-mp-weibo/src/service/api/device/accelerometer.ts new file mode 100644 index 00000000000..70eb3c48562 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/accelerometer.ts @@ -0,0 +1,77 @@ +import { + defineAsyncApi, + API_ON_ACCELEROMETER, + API_TYPE_ON_ACCELEROMETER_CHANGE, + API_OFF_ACCELEROMETER, + API_TYPE_OFF_ACCELEROMETER_CHANGE, + API_START_ACCELEROMETER, + API_TYPE_START_ACCELEROMETER, + API_STOP_ACCELEROMETER, + API_TYPE_STOP_ACCELEROMETER, + defineOnApi, +} from '@dcloudio/uni-api' + +let listener: ((event: DeviceMotionEvent) => void) | null = null + +export const onAccelerometerChange = + defineOnApi(API_ON_ACCELEROMETER, () => { + startAccelerometer() + }) + +export const offAccelerometerChange = + defineOnApi(API_OFF_ACCELEROMETER, () => { + stopAccelerometer() + }) + +export const startAccelerometer = defineAsyncApi( + API_START_ACCELEROMETER, + (_, { resolve, reject }) => { + if (!window.DeviceMotionEvent) { + reject() + return + } + function addEventListener() { + listener = function (event: DeviceMotionEvent) { + const acceleration = + event.acceleration || event.accelerationIncludingGravity + UniServiceJSBridge.invokeOnCallback(API_ON_ACCELEROMETER, { + x: (acceleration && acceleration.x) || 0, + y: (acceleration && acceleration.y) || 0, + z: (acceleration && acceleration.z) || 0, + }) + } + window.addEventListener('devicemotion', listener, false) + } + if (!listener) { + if ((DeviceMotionEvent as any).requestPermission) { + ;(DeviceMotionEvent as any) + .requestPermission() + .then((res: string) => { + if (res === 'granted') { + addEventListener() + resolve() + } else { + reject(`${res}`) + } + }) + .catch((error: any) => { + reject(`${error}`) + }) + return + } + addEventListener() + } + resolve() + } +) + +export const stopAccelerometer = defineAsyncApi( + API_STOP_ACCELEROMETER, + (_, { resolve }) => { + if (listener) { + window.removeEventListener('devicemotion', listener, false) + listener = null + } + resolve() + } +) diff --git a/packages/uni-mp-weibo/src/service/api/device/clipboard.ts b/packages/uni-mp-weibo/src/service/api/device/clipboard.ts new file mode 100644 index 00000000000..2238f395387 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/clipboard.ts @@ -0,0 +1,76 @@ +import { + API_GET_CLIPBOARD_DATA, + API_SET_CLIPBOARD_DATA, + API_TYPE_GET_CLIPBOARD_DATA, + API_TYPE_SET_CLIPBOARD_DATA, + SetClipboardDataOptions, + SetClipboardDataProtocol, + defineAsyncApi, +} from '@dcloudio/uni-api' +// import { showModal } from '../../api/ui/popup/showModal' +import { + useI18n, + // initI18nSetClipboardDataMsgsOnce, + initI18nGetClipboardDataMsgsOnce, +} from '@dcloudio/uni-core' + +export const getClipboardData = defineAsyncApi( + API_GET_CLIPBOARD_DATA, + async (_, { resolve, reject }) => { + initI18nGetClipboardDataMsgsOnce() + const { t } = useI18n() + try { + const data = await navigator.clipboard.readText() + resolve({ data }) + } catch (error: any) { + _getClipboardData(resolve, () => { + reject(`${error} ${t('uni.getClipboardData.fail')}`) + }) + } + } +) + +export const setClipboardData = defineAsyncApi( + API_SET_CLIPBOARD_DATA, + async ({ data }, { resolve, reject }) => { + try { + await navigator.clipboard.writeText(data) + resolve() + } catch (error) { + _setClipboardData(data, resolve, reject) + } + }, + SetClipboardDataProtocol, + SetClipboardDataOptions +) + +function _getClipboardData(resolve: Function, reject: Function) { + const pasteText = document.getElementById('#clipboard') as HTMLInputElement + const data = pasteText ? pasteText.value : undefined + if (data) { + resolve({ data }) + } else { + reject() + } +} + +function _setClipboardData(data: string, resolve: Function, reject: Function) { + const pasteText = document.getElementById('#clipboard') + pasteText && pasteText.remove() + const textarea = document.createElement('textarea') + textarea.id = '#clipboard' + textarea.style.position = 'fixed' + textarea.style.top = '-9999px' + textarea.style.zIndex = '-9999' + document.body.appendChild(textarea) + textarea.value = data + textarea.select() + textarea.setSelectionRange(0, textarea.value.length) + const result = document.execCommand('Copy', false) + textarea.blur() + if (result) { + resolve() + } else { + reject() + } +} diff --git a/packages/uni-mp-weibo/src/service/api/device/compass.ts b/packages/uni-mp-weibo/src/service/api/device/compass.ts new file mode 100644 index 00000000000..7d701a7a8ea --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/compass.ts @@ -0,0 +1,80 @@ +import { + defineAsyncApi, + API_ON_COMPASS, + API_TYPE_ON_COMPASS_CHANGE, + API_OFF_COMPASS, + API_TYPE_OFF_COMPASS_CHANGE, + API_START_COMPASS, + API_TYPE_START_COMPASS, + API_STOP_COMPASS, + API_TYPE_STOP_COMPASS, + defineOnApi, + defineOffApi, +} from '@dcloudio/uni-api' + +let listener: ((event: DeviceOrientationEvent) => void) | null = null + +export const onCompassChange = defineOnApi( + API_ON_COMPASS, + () => { + startCompass() + } +) + +export const offCompassChange = defineOffApi( + API_OFF_COMPASS, + () => { + stopCompass() + } +) + +export const startCompass = defineAsyncApi( + API_START_COMPASS, + (_, { resolve, reject }) => { + if (!window.DeviceOrientationEvent) { + reject() + return + } + function addEventListener() { + listener = function (event) { + const direction: number = + 360 - (event.alpha !== null ? event.alpha : 360) + UniServiceJSBridge.invokeOnCallback(API_ON_COMPASS, { + direction: direction, + }) + } + window.addEventListener('deviceorientation', listener, false) + } + if (!listener) { + if ((DeviceOrientationEvent as any).requestPermission) { + ;(DeviceOrientationEvent as any) + .requestPermission() + .then((res: string) => { + if (res === 'granted') { + addEventListener() + resolve() + } else { + reject(`${res}`) + } + }) + .catch((error: any) => { + reject(`${error}`) + }) + return + } + addEventListener() + } + resolve() + } +) + +export const stopCompass = defineAsyncApi( + API_STOP_COMPASS, + (_, { resolve }) => { + if (listener) { + window.removeEventListener('deviceorientation', listener, false) + listener = null + } + resolve() + } +) diff --git a/packages/uni-mp-weibo/src/service/api/device/getSystemInfo.ts b/packages/uni-mp-weibo/src/service/api/device/getSystemInfo.ts new file mode 100644 index 00000000000..74ab7d53d8e --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/getSystemInfo.ts @@ -0,0 +1,10 @@ +import { defineAsyncApi } from '@dcloudio/uni-api' + +import { getSystemInfoSync } from './getSystemInfoSync' + +export const getSystemInfo = defineAsyncApi( + 'getSystemInfo', + (_args, { resolve }) => { + return resolve(getSystemInfoSync()) + } +) diff --git a/packages/uni-mp-weibo/src/service/api/device/getSystemInfoSync.ts b/packages/uni-mp-weibo/src/service/api/device/getSystemInfoSync.ts new file mode 100644 index 00000000000..20a3d77ad09 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/getSystemInfoSync.ts @@ -0,0 +1,129 @@ +import { defineSyncApi, getLocale } from '@dcloudio/uni-api' +import deviceId from '../../../helpers/uuid' +import { getBrowserInfo } from '../base/getBrowserInfo' +import { getWindowInfo } from './getWindowInfo' +import { extend } from '@vue/shared' +import { sortObject } from '@dcloudio/uni-shared' + +type BrowserInfo = ReturnType + +let browserInfo: BrowserInfo +let _initBrowserInfo = true + +function initBrowserInfo() { + if (__NODE_JS__) { + //TODO 临时搞一下配合 uniCloud 测试 + return (browserInfo = {} as BrowserInfo) + } + if (!_initBrowserInfo) return + browserInfo = getBrowserInfo() +} +export const getDeviceInfo = defineSyncApi( + 'getDeviceInfo', + () => { + initBrowserInfo() + const { + deviceBrand, + deviceModel, + brand, + model, + platform, + system, + deviceOrientation, + deviceType, + } = browserInfo + + return { + brand, + deviceBrand, + deviceModel, + devicePixelRatio: __NODE_JS__ ? 1 : window.devicePixelRatio, + deviceId: __NODE_JS__ + ? Date.now() + '' + Math.floor(Math.random() * 1e7) + : deviceId(), + deviceOrientation, + deviceType, + model, + platform, + system, + } + } +) +export const getAppBaseInfo = defineSyncApi( + 'getAppBaseInfo', + () => { + initBrowserInfo() + const { theme, language, browserName, browserVersion } = browserInfo + + return { + appId: __uniConfig.appId, + appName: __uniConfig.appName, + appVersion: __uniConfig.appVersion, + appVersionCode: __uniConfig.appVersionCode, + appLanguage: getLocale ? getLocale() : language, + enableDebug: false, + hostSDKVersion: undefined, + hostPackageName: undefined, + hostFontSizeSetting: undefined, + hostName: browserName, + hostVersion: browserVersion, + hostTheme: theme, + hostLanguage: language, + language, + SDKVersion: '', + theme, + version: '', + } + } +) + +/** + * 获取系统信息-同步 + */ +export const getSystemInfoSync = defineSyncApi( + 'getSystemInfoSync', + () => { + if (__NODE_JS__) { + //TODO 临时搞一下配合 uniCloud 测试 + return { + deviceId: Date.now() + '' + Math.floor(Math.random() * 1e7), + platform: 'nodejs', + } as UniApp.GetSystemInfoResult + } + + _initBrowserInfo = true + initBrowserInfo() + _initBrowserInfo = false + const windowInfo = getWindowInfo() + const deviceInfo = getDeviceInfo() + const appBaseInfo = getAppBaseInfo() + _initBrowserInfo = true + + const { ua, browserName, browserVersion, osname, osversion } = browserInfo + + const systemInfo: UniApp.GetSystemInfoResult = extend( + windowInfo, + deviceInfo, + appBaseInfo, + { + ua, + browserName, + browserVersion, + uniPlatform: 'web', + uniCompileVersion: __uniConfig.compilerVersion, + uniRuntimeVersion: __uniConfig.compilerVersion, + fontSizeSetting: undefined, + osName: osname!.toLocaleLowerCase(), + osVersion: osversion, + osLanguage: undefined, + osTheme: undefined, + } + ) + + delete (systemInfo as any).screenTop + delete (systemInfo as any).enableDebug + if (!__uniConfig.darkmode) delete (systemInfo as any).theme + + return sortObject(systemInfo) + } +) diff --git a/packages/uni-mp-weibo/src/service/api/device/getWindowInfo.ts b/packages/uni-mp-weibo/src/service/api/device/getWindowInfo.ts new file mode 100644 index 00000000000..39ddf63823c --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/getWindowInfo.ts @@ -0,0 +1,58 @@ +import safeAreaInsets from 'safe-area-insets' +import { getWindowOffset } from '@dcloudio/uni-core' +import { + isLandscape, + getScreenFix, + getScreenWidth, + getWindowWidth, + getScreenHeight, +} from '../base/getBaseSystemInfo' +import { defineSyncApi } from '@dcloudio/uni-api' + +export const getWindowInfo = defineSyncApi( + 'getWindowInfo', + () => { + const pixelRatio = window.devicePixelRatio + // 横屏时 iOS 获取的屏幕宽高颠倒,进行纠正 + const screenFix = getScreenFix() + const landscape = isLandscape(screenFix) + const screenWidth = getScreenWidth(screenFix, landscape) + const screenHeight = getScreenHeight(screenFix, landscape) + const windowWidth = getWindowWidth(screenWidth) + let windowHeight = window.innerHeight + const statusBarHeight = safeAreaInsets.top + + const safeArea = { + left: safeAreaInsets.left, + right: windowWidth - safeAreaInsets.right, + top: safeAreaInsets.top, + bottom: windowHeight - safeAreaInsets.bottom, + width: windowWidth - safeAreaInsets.left - safeAreaInsets.right, + height: windowHeight - safeAreaInsets.top - safeAreaInsets.bottom, + } + + const { top: windowTop, bottom: windowBottom } = getWindowOffset() + + windowHeight -= windowTop + windowHeight -= windowBottom + + return { + windowTop, + windowBottom, + windowWidth, + windowHeight, + pixelRatio, + screenWidth, + screenHeight, + statusBarHeight, + safeArea, + safeAreaInsets: { + top: safeAreaInsets.top, + right: safeAreaInsets.right, + bottom: safeAreaInsets.bottom, + left: safeAreaInsets.left, + }, + screenTop: screenHeight - windowHeight, + } + } +) diff --git a/packages/uni-mp-weibo/src/service/api/device/makePhoneCall.ts b/packages/uni-mp-weibo/src/service/api/device/makePhoneCall.ts new file mode 100644 index 00000000000..d29deffd297 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/makePhoneCall.ts @@ -0,0 +1,15 @@ +import { + API_MAKE_PHONE_CALL, + API_TYPE_MAKE_PHONE_CALL, + defineAsyncApi, + MakePhoneCallProtocol, +} from '@dcloudio/uni-api' + +export const makePhoneCall = defineAsyncApi( + API_MAKE_PHONE_CALL, + ({ phoneNumber }, { resolve }) => { + window.location.href = `tel:${phoneNumber}` + return resolve() + }, + MakePhoneCallProtocol +) diff --git a/packages/uni-mp-weibo/src/service/api/device/network.ts b/packages/uni-mp-weibo/src/service/api/device/network.ts new file mode 100644 index 00000000000..acf0e014b37 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/network.ts @@ -0,0 +1,69 @@ +import { defineOnApi, defineOffApi, defineAsyncApi } from '@dcloudio/uni-api' + +type OnNetworkStatusChange = typeof uni.onNetworkStatusChange + +const API_ON_NETWORK_STATUS_CHANGE = 'onNetworkStatusChange' + +function networkListener() { + getNetworkType().then(({ networkType }) => { + UniServiceJSBridge.invokeOnCallback( + API_ON_NETWORK_STATUS_CHANGE, + { + isConnected: networkType !== 'none', + networkType, + } + ) + }) +} + +function getConnection() { + return ( + (navigator as any).connection || + (navigator as any).webkitConnection || + (navigator as any).mozConnection + ) +} +// 注意:框架对on类的API已做了统一的前置处理(仅首次调用on方法时,会调用具体的平台on实现,后续调用,框架不会再调用,实现时,直接监听平台事件即可) +export const onNetworkStatusChange = defineOnApi( + API_ON_NETWORK_STATUS_CHANGE, + () => { + const connection = getConnection() + if (connection) { + connection.addEventListener('change', networkListener) + } else { + window.addEventListener('offline', networkListener) + window.addEventListener('online', networkListener) + } + } +) +// 注意:框架对off类的API已做了统一的前置处理(仅当框架内不存在对应的on监听时,会调用具体的平台off实现,若还存在事件,框架不会再调用,具体实现时,直接移除平台事件即可) +export const offNetworkStatusChange = defineOffApi< + typeof uni.offNetworkStatusChange +>('offNetworkStatusChange', () => { + const connection = getConnection() + if (connection) { + connection.removeEventListener('change', networkListener) + } else { + window.removeEventListener('offline', networkListener) + window.removeEventListener('online', networkListener) + } +}) + +export const getNetworkType = defineAsyncApi( + 'getNetworkType', + (_args, { resolve }) => { + const connection = getConnection() + let networkType = 'unknown' + if (connection) { + networkType = connection.type + if (networkType === 'cellular' && connection.effectiveType) { + networkType = connection.effectiveType.replace('slow-', '') + } else if (!['none', 'wifi'].includes(networkType)) { + networkType = 'unknown' + } + } else if (navigator.onLine === false) { + networkType = 'none' + } + return resolve({ networkType }) + } +) diff --git a/packages/uni-mp-weibo/src/service/api/device/theme.ts b/packages/uni-mp-weibo/src/service/api/device/theme.ts new file mode 100644 index 00000000000..8b7e410ff05 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/theme.ts @@ -0,0 +1,20 @@ +import { ON_THEME_CHANGE, OFF_THEME_CHANGE } from '@dcloudio/uni-shared' +import { defineOnApi, defineOffApi } from '@dcloudio/uni-api' + +const themeChangeCallBack = (res: UniApp.OnThemeChangeCallbackResult) => { + UniServiceJSBridge.invokeOnCallback(ON_THEME_CHANGE, res) +} + +export const onThemeChange = defineOnApi( + ON_THEME_CHANGE, + () => { + UniServiceJSBridge.on(ON_THEME_CHANGE, themeChangeCallBack) + } +) + +export const offThemeChange = defineOffApi( + OFF_THEME_CHANGE, + () => { + UniServiceJSBridge.off(ON_THEME_CHANGE, themeChangeCallBack) + } +) diff --git a/packages/uni-mp-weibo/src/service/api/device/vibrate.ts b/packages/uni-mp-weibo/src/service/api/device/vibrate.ts new file mode 100644 index 00000000000..5b6456b0301 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/device/vibrate.ts @@ -0,0 +1,33 @@ +import { + API_VIBRATE_SHORT, + API_VIBRATE_LONG, + defineAsyncApi, +} from '@dcloudio/uni-api' +import { + API_TYPE_VIBRATE_SHORT, + API_TYPE_VIBRATE_LONG, +} from '@dcloudio/uni-api' + +const _isSupport = !!window.navigator.vibrate + +export const vibrateShort = defineAsyncApi( + API_VIBRATE_SHORT, + (args, { resolve, reject }) => { + if (_isSupport && window.navigator.vibrate(15)) { + resolve() + } else { + reject('vibrateLong:fail') + } + } +) + +export const vibrateLong = defineAsyncApi( + API_VIBRATE_LONG, + (args, { resolve, reject }) => { + if (_isSupport && window.navigator.vibrate(400)) { + resolve() + } else { + reject('vibrateLong:fail') + } + } +) diff --git a/packages/uni-mp-weibo/src/service/api/file/getFileInfo.ts b/packages/uni-mp-weibo/src/service/api/file/getFileInfo.ts new file mode 100644 index 00000000000..04143ac6cec --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/file/getFileInfo.ts @@ -0,0 +1,26 @@ +import { + defineAsyncApi, + API_GET_FILE_INFO, + API_TYPE_GET_FILE_INFO, + GetFileInfoProtocol, + GetFileInfoOptions, +} from '@dcloudio/uni-api' +import { urlToFile } from '../../../helpers/file' + +export const getFileInfo = defineAsyncApi( + API_GET_FILE_INFO, + ({ filePath }, { resolve, reject }) => { + // TODO 计算文件摘要 + urlToFile(filePath) + .then((res) => { + resolve({ + size: res.size, + } as UniApp.GetFileInfoSuccess) + }) + .catch((err) => { + reject(String(err)) + }) + }, + GetFileInfoProtocol, + GetFileInfoOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/file/openDocument.ts b/packages/uni-mp-weibo/src/service/api/file/openDocument.ts new file mode 100644 index 00000000000..1ebe54a7dc5 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/file/openDocument.ts @@ -0,0 +1,17 @@ +import { + API_OPEN_DOCUMENT, + API_TYPE_OPEN_DOCUMENT, + defineAsyncApi, + OpenDocumentProtocol, + OpenDocumentOptions, +} from '@dcloudio/uni-api' + +export const openDocument = defineAsyncApi( + API_OPEN_DOCUMENT, + ({ filePath }, { resolve }) => { + window.open(filePath) + return resolve() + }, + OpenDocumentProtocol, + OpenDocumentOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/index.ts b/packages/uni-mp-weibo/src/service/api/index.ts new file mode 100644 index 00000000000..b9983ac042e --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/index.ts @@ -0,0 +1,119 @@ +//#if _NODE_JS_ +// 目前这几个接口主要是 uniCloud 使用了 +// 目前采用 polyfill 解决 xhr 和 storage +/* eslint-disable no-restricted-globals */ +require('localstorage-polyfill') +global.XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest +export * from './network/request' +export * from './storage/storage' +export * from './device/getSystemInfoSync' +export { setNavigationBarTitle } from './ui/navigationBar' +//#else +export * from './base/canIUse' + +export * from './context/createInnerAudioContext' + +export * from './device/makePhoneCall' +export * from './device/getSystemInfo' +export * from './device/getSystemInfoSync' +export * from './device/network' +export * from './device/accelerometer' +export * from './device/compass' +export * from './device/vibrate' +export * from './device/clipboard' +export * from './device/getWindowInfo' +export * from './device/theme' + +export * from './storage/storage' + +export * from './file/getFileInfo' +export * from './file/openDocument' + +export * from './keyboard/keyboard' + +export * from './media/getImageInfo' +export * from './media/getVideoInfo' +export * from './media/chooseFile' +export * from './media/chooseImage' +export * from './media/previewImage' +export * from './media/chooseVideo' + +export * from './network/request' +export * from './network/downloadFile' +export * from './network/uploadFile' +export * from './network/socket' + +export * from './location/getLocation' +export * from './location/openLocation' +export * from './location/chooseLocation' +export * from './location/locationChange' + +export * from './route/navigateBack' +export * from './route/navigateTo' +export * from './route/redirectTo' +export * from './route/reLaunch' +export * from './route/switchTab' +export * from './route/preloadPage' + +export * from './ui/popup/showModal' +export * from './ui/popup/showToast' +export * from './ui/popup/showActionSheet' +export * from './ui/loadFontFace' +export * from './ui/navigationBar' +export * from './ui/pageScrollTo' +export * from './ui/startPullDownRefresh' +export * from './ui/stopPullDownRefresh' +export * from './ui/tabBar' +export * from './ui/window' + +export * from './todo/index' + +export { + upx2px, + addInterceptor, + removeInterceptor, + interceptors, + arrayBufferToBase64, + base64ToArrayBuffer, + createIntersectionObserver, + createMediaQueryObserver, + createSelectorQuery, + createVideoContext, + createMapContext, + createAnimation, + onWindowResize, + offWindowResize, + onTabBarMidButtonTap, + createCanvasContext, + canvasGetImageData, + canvasPutImageData, + canvasToTempFilePath, + getSelectedTextRange, + getLocale, + setLocale, + $on, + $off, + $once, + $emit, + onCreateVueApp, + onLocaleChange, + setPageMeta, + getEnterOptionsSync, + getLaunchOptionsSync, + getPushClientId, + onPushMessage, + offPushMessage, + onAppHide, + onAppShow, + onError, + onPageNotFound, + onUnhandledRejection, + offAppHide, + offAppShow, + offError, + offPageNotFound, + offUnhandledRejection, + // 内部使用 + invokePushCallback, +} from '@dcloudio/uni-api' +//#endif diff --git a/packages/uni-mp-weibo/src/service/api/keyboard/keyboard.ts b/packages/uni-mp-weibo/src/service/api/keyboard/keyboard.ts new file mode 100644 index 00000000000..f2d4ba852dd --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/keyboard/keyboard.ts @@ -0,0 +1,37 @@ +import { API_HIDE_KEYBOARD, defineAsyncApi } from '@dcloudio/uni-api' +import type { API_TYPE_HIDE_KEYBOARD } from '@dcloudio/uni-api' + +export const hideKeyboard = defineAsyncApi( + API_HIDE_KEYBOARD, + (args, { resolve, reject }) => { + const activeElement = document.activeElement as HTMLInputElement + if ( + activeElement && + (activeElement.tagName === 'TEXTAREA' || + activeElement.tagName === 'INPUT') + ) { + activeElement.blur() + resolve() + } + } +) + +export const API_ON_KEYBOARD_HEIGHT_CHANGE = 'onKeyboardHeightChange' +type API_TYPE_ON_KEYBOARD_HEIGHT_CHANGE = typeof uni.onKeyboardHeightChange +export const onKeyboardHeightChange = + defineAsyncApi( + API_ON_KEYBOARD_HEIGHT_CHANGE, + (args, { resolve, reject }) => { + resolve() + } + ) + +export const API_OFF_KEYBOARD_HEIGHT_CHANGE = 'offKeyboardHeightChange' +type API_TYPE_OFF_KEYBOARD_HEIGHT_CHANGE = typeof uni.offKeyboardHeightChange +export const offKeyboardHeightChange = + defineAsyncApi( + API_OFF_KEYBOARD_HEIGHT_CHANGE, + (args, { resolve, reject }) => { + resolve() + } + ) diff --git a/packages/uni-mp-weibo/src/service/api/location/chooseLocation/LoctaionPicker.tsx b/packages/uni-mp-weibo/src/service/api/location/chooseLocation/LoctaionPicker.tsx new file mode 100644 index 00000000000..6641c8bbdc2 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/location/chooseLocation/LoctaionPicker.tsx @@ -0,0 +1,409 @@ +/// +import { extend } from '@vue/shared' +import { ref, ExtractPropTypes, reactive, computed, watch } from 'vue' +import { debounce } from '@dcloudio/uni-shared' +import { + createSvgIconVNode, + ICON_PATH_CLOSE, + ICON_PATH_CONFIRM, + initI18nChooseLocationMsgsOnce, + useI18n, +} from '@dcloudio/uni-core' +import { + defineSystemComponent, + Input, + ScrollView, +} from '@dcloudio/uni-components' +import { usePreventScroll } from '../../../../helpers/usePreventScroll' +import { + Point, + ICON_PATH_LOCTAION, + ICON_PATH_TARGET, + MapType, + getMapInfo, +} from '../../../../helpers/location' +import { Map } from '../../../../view/components' +import { getJSONP } from '../../../../helpers/getJSONP' +import { getLocation } from '../../location/getLocation' + +const props = { + latitude: { + type: Number, + }, + longitude: { + type: Number, + }, +} + +export type Props = ExtractPropTypes + +function distance(distance: number): string { + if (distance > 100) { + return `${ + distance > 1000 ? (distance / 1000).toFixed(1) + 'k' : distance.toFixed(0) + }m | ` + } else if (distance > 0) { + return '<100m | ' + } else { + return '' + } +} + +interface State { + latitude: number + longitude: number + keyword: string + searching: boolean +} +function useState(props: Props) { + const state: State = reactive({ + latitude: 0, + longitude: 0, + keyword: '', + searching: false, + }) + function updatePosition() { + if (props.latitude && props.longitude) { + state.latitude = props.latitude + state.longitude = props.longitude + } + } + watch([() => props.latitude, () => props.longitude], updatePosition) + updatePosition() + return state +} + +export interface Poi { + name: string + address: string + distance: number + latitude: number + longitude: number +} + +function useList(state: State) { + const key = __uniConfig.qqMapKey + const list: Poi[] = reactive([]) + const selectedIndexRef = ref(-1) + const selectedRef = computed(() => list[selectedIndexRef.value]) + const listState = reactive({ + loading: true, + // google map default + pageSize: 20, + pageIndex: 1, + hasNextPage: true, + nextPage: null as null | (() => void), + selectedIndex: selectedIndexRef, + selected: selectedRef, + }) + const adcodeRef = ref('') + const boundaryRef = computed(() => + adcodeRef.value + ? `region(${adcodeRef.value},1,${state.latitude},${state.longitude})` + : `nearby(${state.latitude},${state.longitude},5000)` + ) + function pushData(array: any[]) { + array.forEach((item) => { + list.push({ + name: item.title, + address: item.address, + distance: item._distance || item.distance, + latitude: item.location.lat, + longitude: item.location.lng, + }) + }) + } + function getList() { + listState.loading = true + const mapInfo = getMapInfo() + if (mapInfo.type === MapType.GOOGLE) { + if (listState.pageIndex > 1 && listState.nextPage) { + listState.nextPage() + return + } + const service = new google.maps.places.PlacesService( + document.createElement('div') + ) + service[state.searching ? 'textSearch' : 'nearbySearch']( + { + location: { + lat: state.latitude, + lng: state.longitude, + }, + query: state.keyword, + radius: 5000, + }, + (results, state, page) => { + listState.loading = false + if (results && results.length) { + results.forEach((item) => { + list.push({ + name: item.name || '', + address: item.vicinity || item.formatted_address || '', + distance: 0, + latitude: item.geometry!.location!.lat(), + longitude: item.geometry!.location!.lng(), + }) + }) + } + if (page) { + if (!page.hasNextPage) { + listState.hasNextPage = false + } else { + listState.nextPage = () => { + page.nextPage() + } + } + } + } + ) + } else if (mapInfo.type === MapType.QQ) { + const url = state.searching + ? `https://apis.map.qq.com/ws/place/v1/search?output=jsonp&key=${key}&boundary=${boundaryRef.value}&keyword=${state.keyword}&page_size=${listState.pageSize}&page_index=${listState.pageIndex}` + : `https://apis.map.qq.com/ws/geocoder/v1/?output=jsonp&key=${key}&location=${state.latitude},${state.longitude}&get_poi=1&poi_options=page_size=${listState.pageSize};page_index=${listState.pageIndex}` + // TODO 列表加载失败提示 + getJSONP( + url, + { + callback: 'callback', + }, + (res: any) => { + listState.loading = false + if (state.searching && 'data' in res && res.data.length) { + pushData(res.data) + } else if ('result' in res) { + const result = res.result + adcodeRef.value = result.ad_info ? result.ad_info.adcode : '' + if (result.pois) { + pushData(result.pois) + } + } + if (list.length === listState.pageSize * listState.pageIndex) { + listState.hasNextPage = false + } + }, + () => { + listState.loading = false + } + ) + } else if (mapInfo.type === MapType.AMAP) { + window.AMap.plugin('AMap.PlaceSearch', function () { + const placeSearch = new (window.AMap as any).PlaceSearch({ + city: '全国', + pageSize: 10, + pageIndex: listState.pageIndex, + }) + const keyword = state.searching ? state.keyword : '' + const radius = state.searching ? 50000 : 5000 + placeSearch.searchNearBy( + keyword, + [state.longitude, state.latitude], + radius, + function (status: string, result: any) { + if (status === 'error') { + console.error(result) + } else if (status === 'no_data') { + listState.hasNextPage = false + } else { + pushData(result.poiList.pois) + } + } + ) + listState.loading = false + }) + } + } + function loadMore() { + if (!listState.loading && listState.hasNextPage) { + listState.pageIndex++ + getList() + } + } + function reset() { + listState.selectedIndex = -1 + listState.pageIndex = 1 + listState.hasNextPage = true + listState.nextPage = null + list.splice(0, list.length) + } + return { + listState, + list, + loadMore, + reset, + getList, + } +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'LoctaionPicker', + props, + emits: ['close'], + setup(props, { emit }) { + usePreventScroll() + initI18nChooseLocationMsgsOnce() + const { t } = useI18n() + const state = useState(props) + const { list, listState, loadMore, reset, getList } = useList(state) + const search = debounce( + () => { + reset() + if (state.keyword) { + getList() + } + }, + 1000, + { setTimeout, clearTimeout } + ) + watch( + () => state.searching, + (val) => { + reset() + if (!val) { + getList() + } + } + ) + function onInput(event: { detail: { value: string } }) { + state.keyword = event.detail.value + search() + } + + function onChoose() { + emit('close', extend({}, listState.selected)) + } + + function onBack() { + emit('close') + } + + function onRegionChange(event: { detail: { centerLocation: Point } }) { + const centerLocation = event.detail.centerLocation + if (centerLocation) { + // TODO 图钉 icon 动画 + move(centerLocation) + } + } + + function moveToLocation() { + getLocation({ + type: 'gcj02', + success: move, + fail: () => { + // move({ + // latitude: 0, + // longitude: 0, + // }) + }, + }) + } + + function move({ latitude, longitude }: Point) { + state.latitude = latitude + state.longitude = longitude + if (!state.searching) { + reset() + getList() + } + } + + if (!state.latitude || !state.longitude) { + moveToLocation() + } + + return () => { + const content = list.map((item, index) => { + return ( +
    { + listState.selectedIndex = index + state.latitude = item.latitude + state.longitude = item.longitude + }} + > + {createSvgIconVNode(ICON_PATH_CONFIRM, '#007aff', 24)} +
    {item.name}
    +
    + {distance(item.distance)} + {item.address} +
    +
    + ) + }) + if (listState.loading) { + content.unshift( +
    + +
    + ) + } + return ( +
    + +
    +
    + {createSvgIconVNode(ICON_PATH_LOCTAION, '#000000', 24)} +
    + + + +
    + ) + } + }, +}) diff --git a/packages/uni-mp-weibo/src/service/api/location/chooseLocation/index.ts b/packages/uni-mp-weibo/src/service/api/location/chooseLocation/index.ts new file mode 100644 index 00000000000..2d021b45db4 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/location/chooseLocation/index.ts @@ -0,0 +1,39 @@ +import { nextTick, reactive } from 'vue' +import { + API_CHOOSE_LOCATION, + API_TYPE_CHOOSE_LOCATION, + defineAsyncApi, + ChooseLocationProtocol, +} from '@dcloudio/uni-api' +import { ensureRoot, createRootApp } from '../../ui/popup/utils' +import LoctaionPicker, { Props, Poi } from './LoctaionPicker' + +let state: Props | null = null + +export const chooseLocation = defineAsyncApi( + API_CHOOSE_LOCATION, + (args, { resolve, reject }) => { + if (!state) { + state = reactive(args) as Props + // 异步执行,避免干扰 getCurrentInstance + nextTick(() => { + const app = createRootApp( + LoctaionPicker, + state as Props, + (poi: Poi) => { + state = null + nextTick(() => { + app.unmount() + }) + poi ? resolve(poi) : reject('cancel') + } + ) + app.mount(ensureRoot('u-a-c')) + }) + } else { + // 禁止重复调用 + reject('cancel') + } + }, + ChooseLocationProtocol +) diff --git a/packages/uni-mp-weibo/src/service/api/location/getLocation.ts b/packages/uni-mp-weibo/src/service/api/location/getLocation.ts new file mode 100644 index 00000000000..27cb3e1d10e --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/location/getLocation.ts @@ -0,0 +1,149 @@ +import { + defineAsyncApi, + API_GET_LOCATION, + API_TYPE_GET_LOCATION, + GetLocationProtocol, + GetLocationOptions, +} from '@dcloudio/uni-api' +import { + MapType, + getMapInfo, + TranslateCoordinateSystemOptions, + translateCoordinateSystem, +} from '../../../helpers/location' +import { getJSONP } from '../../../helpers/getJSONP' +import { request } from '../network/request' +import { loadMaps } from '../../../view/components/map/maps' + +export const getLocation = defineAsyncApi( + API_GET_LOCATION, + ( + { type, altitude, highAccuracyExpireTime, isHighAccuracy }, + { resolve, reject } + ) => { + const mapInfo = getMapInfo() + + new Promise((resolve: TranslateCoordinateSystemOptions, reject) => { + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition( + (res) => resolve({ coords: res.coords }), + reject, + { + enableHighAccuracy: isHighAccuracy || altitude, + timeout: highAccuracyExpireTime || 1000 * 100, + } + ) + } else { + reject(new Error('device nonsupport geolocation')) + } + }) + .catch((error) => { + return new Promise( + (resolve: TranslateCoordinateSystemOptions, reject) => { + if (mapInfo.type === MapType.QQ) { + getJSONP( + `https://apis.map.qq.com/ws/location/v1/ip?output=jsonp&key=${mapInfo.key}`, + { + callback: 'callback', + }, + (res: any) => { + if ('result' in res && res.result.location) { + const location = res.result.location + resolve({ + coords: { + latitude: location.lat, + longitude: location.lng, + } as GeolocationCoordinates, + skip: true, + }) + } else { + reject(new Error(res.message || JSON.stringify(res))) + } + }, + () => reject(new Error('network error')) + ) + } else if (mapInfo.type === MapType.GOOGLE) { + request({ + method: 'POST', + url: `https://www.googleapis.com/geolocation/v1/geolocate?key=${mapInfo.key}`, + success(res) { + const data: AnyObject = res.data as AnyObject + if ('location' in data) { + resolve({ + coords: { + latitude: data.location.lat, + longitude: data.location.lng, + accuracy: data.accuracy, + } as GeolocationCoordinates, + skip: true, + }) + } else { + reject( + new Error( + (data.error && data.error.message) || + JSON.stringify(res) + ) + ) + } + }, + fail() { + reject(new Error('network error')) + }, + }) + } else if (mapInfo.type === MapType.AMAP) { + loadMaps([], () => { + window.AMap.plugin('AMap.Geolocation', () => { + const geolocation = new (window.AMap as any).Geolocation({ + enableHighAccuracy: true, + timeout: 10000, + }) + + geolocation.getCurrentPosition( + (status: string, data: any) => { + if (status === 'complete') { + resolve({ + coords: { + latitude: data.position.lat, + longitude: data.position.lng, + accuracy: data.accuracy, + } as GeolocationCoordinates, + skip: true, + }) + } else { + reject(new Error(data.message)) + } + } + ) + }) + }) + } else { + reject(error) + } + } + ) + }) + .then(({ coords, skip }) => { + translateCoordinateSystem(type, coords, skip) + .then((coords: GeolocationCoordinates | any) => { + resolve({ + latitude: coords.latitude, + longitude: coords.longitude, + accuracy: coords.accuracy, + speed: coords.altitude || 0, + altitude: coords.altitude || 0, + verticalAccuracy: coords.altitudeAccuracy || 0, + // 无专门水平精度,使用位置精度替代 + horizontalAccuracy: coords.accuracy || 0, + }) + }) + .catch((error) => { + reject(error.message) + }) + }) + .catch((error) => { + reject(error.message || JSON.stringify(error)) + }) + }, + GetLocationProtocol, + GetLocationOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/location/locationChange.ts b/packages/uni-mp-weibo/src/service/api/location/locationChange.ts new file mode 100644 index 00000000000..d70ae2ee96b --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/location/locationChange.ts @@ -0,0 +1,102 @@ +import { + defineAsyncApi, + defineOnApi, + defineOffApi, + API_START_LOCATION_UPDATE, + API_TYPE_START_LOCATION_UPDATE, + StartLocationUpdateProtocol, + StartLocationUpdateOptions, + API_ON_LOCATION_CHANGE, + API_TYPE_ON_LOCATION_CHANGE, + API_TYPE_STOP_LOCATION_UPDATE, + API_STOP_LOCATION_UPDATE, + API_TYPE_OFF_LOCATION_CHANGE, + API_OFF_LOCATION_CHANGE, + API_TYPE_OFF_LOCATION_CHANGE_ERROR, + API_OFF_LOCATION_CHANGE_ERROR, + API_TYPE_ON_LOCATION_CHANGE_ERROR, + API_ON_LOCATION_CHANGE_ERROR, +} from '@dcloudio/uni-api' +import { translateCoordinateSystem } from '../../../helpers/location' + +let started = false +let watchId: number = 0 + +export const startLocationUpdate = + defineAsyncApi( + API_START_LOCATION_UPDATE, + (options, { resolve, reject }) => { + if (!navigator.geolocation) { + reject() + return + } + + watchId = + watchId || + navigator.geolocation.watchPosition( + (res) => { + started = true + translateCoordinateSystem(options?.type, res.coords) + .then((coords) => { + UniServiceJSBridge.invokeOnCallback( + API_ON_LOCATION_CHANGE, + coords + ) + resolve() + }) + .catch((error) => { + UniServiceJSBridge.invokeOnCallback( + API_ON_LOCATION_CHANGE_ERROR, + { errMsg: `onLocationChange:fail ${error.message}` } + ) + }) + }, + (error) => { + if (!started) { + reject(error.message) + started = true + } + UniServiceJSBridge.invokeOnCallback(API_ON_LOCATION_CHANGE_ERROR, { + errMsg: `onLocationChange:fail ${error.message}`, + }) + } + ) + setTimeout(resolve, 100) + }, + StartLocationUpdateProtocol, + StartLocationUpdateOptions + ) + +export const stopLocationUpdate = defineAsyncApi( + API_STOP_LOCATION_UPDATE, + (_, { resolve }) => { + if (watchId) { + navigator.geolocation.clearWatch(watchId) + started = false + watchId = 0 + } + resolve() + } +) + +export const onLocationChange = defineOnApi( + API_ON_LOCATION_CHANGE, + () => {} +) + +export const offLocationChange = defineOffApi( + API_OFF_LOCATION_CHANGE, + () => {} +) + +export const onLocationChangeError = + defineOnApi( + API_ON_LOCATION_CHANGE_ERROR, + () => {} + ) + +export const offLocationChangeError = + defineOffApi( + API_OFF_LOCATION_CHANGE_ERROR, + () => {} + ) diff --git a/packages/uni-mp-weibo/src/service/api/location/openLocation/LocationView.tsx b/packages/uni-mp-weibo/src/service/api/location/openLocation/LocationView.tsx new file mode 100644 index 00000000000..f49746dd5a0 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/location/openLocation/LocationView.tsx @@ -0,0 +1,180 @@ +import { ExtractPropTypes, reactive, watch } from 'vue' +import { createSvgIconVNode, ICON_PATH_BACK } from '@dcloudio/uni-core' +import { defineSystemComponent } from '@dcloudio/uni-components' +import { usePreventScroll } from '../../../../helpers/usePreventScroll' +import { + Point, + ICON_PATH_LOCTAION, + ICON_PATH_ORIGIN, + ICON_PATH_TARGET, + MapType, + getMapInfo, +} from '../../../../helpers/location' +import { Map } from '../../../../view/components' +import { getLocation } from '../../location/getLocation' + +const ICON_PATH_NAV = + 'M28 17c-6.49396875 0-12.13721875 2.57040625-15 6.34840625V5.4105l6.29859375 6.29859375c0.387875 0.387875 1.02259375 0.387875 1.4105 0 0.387875-0.387875 0.387875-1.02259375 0-1.4105L12.77853125 2.36803125a0.9978125 0.9978125 0 0 0-0.0694375-0.077125c-0.1944375-0.1944375-0.45090625-0.291375-0.70721875-0.290875l-0.00184375-0.0000625-0.00184375 0.0000625c-0.2563125-0.0005-0.51278125 0.09640625-0.70721875 0.290875a0.9978125 0.9978125 0 0 0-0.0694375 0.077125l-7.930625 7.9305625c-0.387875 0.387875-0.387875 1.02259375 0 1.4105 0.387875 0.387875 1.02259375 0.387875 1.4105 0L11 5.4105V29c0 0.55 0.45 1 1 1s1-0.45 1-1c0-5.52284375 6.71571875-10 15-10 0.55228125 0 1-0.44771875 1-1 0-0.55228125-0.44771875-1-1-1z' + +const props = { + latitude: { + type: Number, + }, + longitude: { + type: Number, + }, + scale: { + type: Number, + default: 18, + }, + name: { + type: String, + default: '', + }, + address: { + type: String, + default: '', + }, +} + +export type Props = ExtractPropTypes + +interface State { + center: Point + marker: Point + location: Point +} +function useState(props: Props) { + const state: State = reactive({ + center: { + latitude: 0, + longitude: 0, + }, + marker: { + id: 1, + latitude: 0, + longitude: 0, + iconPath: ICON_PATH_TARGET, + width: 32, + height: 52, + }, + location: { + id: 2, + latitude: 0, + longitude: 0, + iconPath: ICON_PATH_ORIGIN, + width: 44, + height: 44, + }, + }) + function updatePosition() { + if (props.latitude && props.longitude) { + state.center.latitude = props.latitude + state.center.longitude = props.longitude + state.marker.latitude = props.latitude + state.marker.longitude = props.longitude + } + } + watch([() => props.latitude, () => props.longitude], updatePosition) + updatePosition() + return state +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'LocationView', + props, + emits: ['close'], + setup(props, { emit }) { + const state = useState(props) + usePreventScroll() + + getLocation({ + type: 'gcj02', + success: ({ latitude, longitude }) => { + state.location.latitude = latitude + state.location.longitude = longitude + }, + }) + + function onRegionChange(event: { detail: { centerLocation: Point } }) { + const centerLocation = event.detail.centerLocation + if (centerLocation) { + state.center.latitude = centerLocation.latitude + state.center.longitude = centerLocation.longitude + } + } + + function nav() { + const mapInfo = getMapInfo() + let url = '' + if (mapInfo.type === MapType.GOOGLE) { + const origin: string = state.location.latitude + ? `&origin=${state.location.latitude}%2C${state.location.longitude}` + : '' + url = `https://www.google.com/maps/dir/?api=1${origin}&destination=${props.latitude}%2C${props.longitude}` + } else if (mapInfo.type === MapType.QQ) { + const fromcoord: string = state.location.latitude + ? `&fromcoord=${state.location.latitude}%2C${ + state.location.longitude + }&from=${encodeURIComponent('我的位置')}` + : '' + url = `https://apis.map.qq.com/uri/v1/routeplan?type=drive${fromcoord}&tocoord=${ + props.latitude + }%2C${props.longitude}&to=${encodeURIComponent( + props.name || '目的地' + )}&ref=${mapInfo.key}` + } else if (mapInfo.type === MapType.AMAP) { + const from = state.location.latitude + ? `from=${state.location.longitude},${ + state.location.latitude + },${encodeURIComponent('我的位置')}&` + : '' + url = `https://uri.amap.com/navigation?${from}to=${props.longitude},${ + props.latitude + },${encodeURIComponent(props.name || '目的地')}` + } + window.open(url) + } + + function back() { + emit('close') + } + + function setCenter({ latitude, longitude }: Point) { + state.center.latitude = latitude + state.center.longitude = longitude + } + + return () => { + return ( +
    + +
    setCenter(state.location)}> + {createSvgIconVNode(ICON_PATH_LOCTAION, '#000000', 24)} +
    +
    +
    +
    setCenter(state.marker)}> + {props.name} +
    +
    setCenter(state.marker)}> + {props.address} +
    + +
    + +
    + ) + } + }, +}) diff --git a/packages/uni-mp-weibo/src/service/api/location/openLocation/index.ts b/packages/uni-mp-weibo/src/service/api/location/openLocation/index.ts new file mode 100644 index 00000000000..2f149cdea8a --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/location/openLocation/index.ts @@ -0,0 +1,37 @@ +import { extend } from '@vue/shared' +import { nextTick, reactive } from 'vue' +import { + API_OPEN_LOCATION, + API_TYPE_OPEN_LOCATION, + defineAsyncApi, + OpenLocationProtocol, + OpenLocationOptions, +} from '@dcloudio/uni-api' +import { ensureRoot, createRootApp } from '../../ui/popup/utils' +import LocationView, { Props } from './LocationView' + +let state: Props | null = null + +export const openLocation = defineAsyncApi( + API_OPEN_LOCATION, + (args, { resolve }) => { + if (!state) { + state = reactive(args) as Props + // 异步执行,避免干扰 getCurrentInstance + nextTick(() => { + const app = createRootApp(LocationView, state as Props, () => { + state = null + nextTick(() => { + app.unmount() + }) + }) + app.mount(ensureRoot('u-a-o')) + }) + } else { + extend(state, args) + } + resolve() + }, + OpenLocationProtocol, + OpenLocationOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/media/MIMEType.ts b/packages/uni-mp-weibo/src/service/api/media/MIMEType.ts new file mode 100644 index 00000000000..c998a41df91 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/MIMEType.ts @@ -0,0 +1,58 @@ +const MIMEType: { + image: Record + video: Record +} = { + /** + * 关于图片常见的MIME类型 + */ + image: { + jpg: 'jpeg', + jpe: 'jpeg', + pbm: 'x-portable-bitmap', + pgm: 'x-portable-graymap', + pnm: 'x-portable-anymap', + ppm: 'x-portable-pixmap', + psd: 'vnd.adobe.photoshop', + pic: 'x-pict', + rgb: 'x-rgb', + svg: 'svg+xml', + svgz: 'svg+xml', + tif: 'tiff', + xif: 'vnd.xiff', + wbmp: 'vnd.wap.wbmp', + wdp: 'vnd.ms-photo', + xbm: 'x-xbitmap', + ico: 'x-icon', + }, + /** + * 关于视频常见的MIME类型 + */ + video: { + '3g2': '3gpp2', + '3gp': '3gpp', + avi: 'x-msvideo', + f4v: 'x-f4v', + flv: 'x-flv', + jpgm: 'jpm', + jpgv: 'jpeg', + m1v: 'mpeg', + m2v: 'mpeg', + mpe: 'mpeg', + mpg: 'mpeg', + mpg4: 'mpeg', + m4v: 'x-m4v', + mkv: 'x-matroska', + mov: 'quicktime', + qt: 'quicktime', + movie: 'x-sgi-movie', + mp4v: 'mp4', + ogv: 'ogg', + smv: 'x-smv', + wm: 'x-ms-wm', + wmv: 'x-ms-wmv', + wmx: 'x-ms-wmx', + wvx: 'x-ms-wvx', + }, +} + +export default MIMEType diff --git a/packages/uni-mp-weibo/src/service/api/media/chooseFile.ts b/packages/uni-mp-weibo/src/service/api/media/chooseFile.ts new file mode 100644 index 00000000000..270a3b6d74b --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/chooseFile.ts @@ -0,0 +1,90 @@ +//#region imp functions +import { + API_CHOOSE_FILE, + ChooseFileOptions, + ChooseFileProtocol, + defineAsyncApi, +} from '@dcloudio/uni-api' +import { fileToUrl } from '../../../helpers/file' +import _createInput from './createInput' +import { getInteractStatus } from '@dcloudio/uni-components' +import { useI18n, initI18nChooseFileMsgsOnce } from '@dcloudio/uni-core' +//#endregion + +//#region types +import type { API_TYPE_CHOOSE_FILE } from '@dcloudio/uni-api' +type CallBackResultType = AsyncApiRes> +type TempFile = UniApp.ChooseFileSuccessCallbackResultFile +//#endregion + +let fileInput: HTMLInputElement = null as any + +export const chooseFile = defineAsyncApi( + API_CHOOSE_FILE, + ( + { + // sizeType, + count, + sourceType, + type, + extension, + }, + { resolve, reject } + ) => { + initI18nChooseFileMsgsOnce() + const { t } = useI18n() + // TODO handle sizeType 尝试通过 canvas 压缩 + if (fileInput) { + document.body.removeChild(fileInput) + fileInput = null as any + } + + fileInput = _createInput({ + count, + sourceType, + type, + extension, + }) + document.body.appendChild(fileInput) + + fileInput.addEventListener('change', function (event: Event) { + const eventTarget = event.target as HTMLInputElement + + const tempFiles: TempFile[] = [] + + if (eventTarget && eventTarget.files) { + const fileCount = eventTarget.files.length + for (let i = 0; i < fileCount; i++) { + const file = eventTarget.files[i] + let filePath: string + Object.defineProperty(file, 'path', { + get() { + filePath = filePath || fileToUrl(file) + return filePath + }, + }) + if (i < count!) tempFiles.push(file as any) + } + } + + const res: CallBackResultType = { + get tempFilePaths() { + return tempFiles.map(({ path }) => path) + }, + tempFiles: tempFiles, + } + + resolve(res) + + // TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。 + }) + + fileInput.click() + + if (!getInteractStatus()) { + console.warn(t('uni.chooseFile.notUserActivation')) + } + }, + ChooseFileProtocol, + ChooseFileOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/media/chooseImage.ts b/packages/uni-mp-weibo/src/service/api/media/chooseImage.ts new file mode 100644 index 00000000000..bc17b3e686d --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/chooseImage.ts @@ -0,0 +1,90 @@ +//#region functions +import { + API_CHOOSE_IMAGE, + ChooseImageProtocol, + ChooseImageOptions, + defineAsyncApi, +} from '@dcloudio/uni-api' +import { fileToUrl } from '../../../helpers/file' +import _createInput from './createInput' +import { getInteractStatus } from '@dcloudio/uni-components' +import { useI18n, initI18nChooseFileMsgsOnce } from '@dcloudio/uni-core' +//#endregion + +//#region types +import type { API_TYPE_CHOOSE_IMAGE } from '@dcloudio/uni-api' +type CallBackResult = AsyncApiRes> +type TempFile = UniApp.ChooseImageSuccessCallbackResultFile +//#endregion + +let imageInput: HTMLInputElement = null as any + +export const chooseImage = defineAsyncApi( + API_CHOOSE_IMAGE, + ( + { + count, + // sizeType, + sourceType, + extension, + }, + { resolve, reject } + ) => { + // TODO handle sizeType 尝试通过 canvas 压缩 + initI18nChooseFileMsgsOnce() + const { t } = useI18n() + + if (imageInput) { + document.body.removeChild(imageInput) + imageInput = null as any + } + imageInput = _createInput({ + count, + sourceType, + extension, + type: 'image', + }) + document.body.appendChild(imageInput) + + imageInput.addEventListener('change', function (event) { + const eventTarget = event.target as HTMLInputElement + + const tempFiles: TempFile[] = [] + + if (eventTarget && eventTarget.files) { + const fileCount = eventTarget.files.length + for (let i = 0; i < fileCount; i++) { + const file = eventTarget.files[i] + let filePath: string + + Object.defineProperty(file, 'path', { + get() { + filePath = filePath || fileToUrl(file) + return filePath + }, + }) + if (i < count!) tempFiles.push(file as any) + } + } + + const res: CallBackResult = { + get tempFilePaths() { + return tempFiles.map(({ path }) => path) + }, + tempFiles: tempFiles, + } + + resolve(res) + + // TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。 + }) + + imageInput.click() + + if (!getInteractStatus()) { + console.warn(t('uni.chooseFile.notUserActivation')) + } + }, + ChooseImageProtocol, + ChooseImageOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/media/chooseVideo.ts b/packages/uni-mp-weibo/src/service/api/media/chooseVideo.ts new file mode 100644 index 00000000000..83bad3840df --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/chooseVideo.ts @@ -0,0 +1,95 @@ +//#region functions +import { extend } from '@vue/shared' +import { + API_CHOOSE_VIDEO, + ChooseVideoOptions, + ChooseVideoProtocol, + defineAsyncApi, +} from '@dcloudio/uni-api' +import { fileToUrl, revokeObjectURL } from '../../../helpers/file' +import _createInput from './createInput' +import { getInteractStatus } from '@dcloudio/uni-components' +import { useI18n, initI18nChooseFileMsgsOnce } from '@dcloudio/uni-core' +//#endregion + +//#region types +import type { API_TYPE_CHOOSE_VIDEO } from '@dcloudio/uni-api' +type CallBackResult = AsyncApiRes> +//#endregion + +let videoInput: HTMLInputElement = null as any + +export const chooseVideo = defineAsyncApi( + API_CHOOSE_VIDEO, + ({ sourceType, extension }, { resolve, reject }) => { + initI18nChooseFileMsgsOnce() + const { t } = useI18n() + if (videoInput) { + document.body.removeChild(videoInput) + videoInput = null as any + } + + videoInput = _createInput({ + sourceType, + extension, + type: 'video', + }) + document.body.appendChild(videoInput) + + videoInput.addEventListener('change', function (event) { + const eventTarget = event.target as HTMLInputElement + + const file = eventTarget.files![0] + let filePath: string = '' + const callbackResult: CallBackResult = { + tempFilePath: filePath, + tempFile: file, + size: file.size, + duration: 0, + width: 0, + height: 0, + name: file.name, + } + Object.defineProperty(callbackResult, 'tempFilePath', { + get() { + filePath = filePath || fileToUrl(this.tempFile) + return filePath + }, + }) + + const video = document.createElement('video') + if (video.onloadedmetadata !== undefined) { + const filePath = fileToUrl(file) + // 尝试获取视频的宽高信息 + video.onloadedmetadata = function () { + revokeObjectURL(filePath) + resolve( + extend(callbackResult, { + duration: video.duration || 0, + width: video.videoWidth || 0, + height: video.videoHeight || 0, + }) + ) + } + // 部分浏览器(如微信内置浏览器)未播放无法触发loadedmetadata事件 + setTimeout(() => { + video.onloadedmetadata = null + revokeObjectURL(filePath) + resolve(callbackResult) + }, 300) + video.src = filePath + } else { + resolve(callbackResult) + } + // TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。 + }) + + videoInput.click() + + if (!getInteractStatus()) { + console.warn(t('uni.chooseFile.notUserActivation')) + } + }, + ChooseVideoProtocol, + ChooseVideoOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/media/createInput.ts b/packages/uni-mp-weibo/src/service/api/media/createInput.ts new file mode 100644 index 00000000000..6060e3fed8d --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/createInput.ts @@ -0,0 +1,73 @@ +import { updateElementStyle } from '@dcloudio/uni-shared' +import MIMEType from './MIMEType' +import { addInteractListener } from '@dcloudio/uni-components' + +export type createInputOptions = Pick< + UniApp.ChooseFileOptions, + 'count' | 'sourceType' | 'type' | 'extension' +> + +const ALL = 'all' +addInteractListener() + +function isWXEnv(): boolean { + const ua = window.navigator.userAgent.toLowerCase() + const matchUA = ua.match(/MicroMessenger/i) + return !!(matchUA && matchUA[0] === 'micromessenger') +} + +export default function ({ + count, + sourceType, + type, + extension, +}: createInputOptions): HTMLInputElement { + const inputEl = document.createElement('input') + inputEl.type = 'file' + + updateElementStyle(inputEl, { + position: 'absolute', + visibility: 'hidden', + zIndex: '-999', + width: '0', + height: '0', + top: '0', + left: '0', + }) + + /** + * 选择文件 + * chooseFile 使用后缀名 + * chooseImage、chooseVideo 使用MIME类型 + */ + inputEl.accept = extension! + .map((item) => { + if (type !== ALL) { + const MIMEKey = item.replace('.', '') + return `${type}/${MIMEType[type!][MIMEKey] || MIMEKey}` + } else { + // 在微信环境里,'.jpeg,.png' 会提示没有应用可执行此操作 + if (isWXEnv()) { + return '.' + } + return item.indexOf('.') === 0 ? item : `.${item}` + } + }) + .join(',') + + if (count && count > 1) { + inputEl.multiple = true + } + + // 经过测试,仅能限制只通过相机拍摄,不能限制只允许从相册选择。 + if ( + type !== ALL && + sourceType instanceof Array && + sourceType.length === 1 && + sourceType[0] === 'camera' + ) { + inputEl.setAttribute('capture', 'camera') + } + + return inputEl +} diff --git a/packages/uni-mp-weibo/src/service/api/media/getImageInfo.ts b/packages/uni-mp-weibo/src/service/api/media/getImageInfo.ts new file mode 100644 index 00000000000..5af820caab3 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/getImageInfo.ts @@ -0,0 +1,31 @@ +import { + API_GET_IMAGE_INFO, + API_TYPE_GET_IMAGE_INFO, + defineAsyncApi, + GetImageInfoOptions, + GetImageInfoProtocol, +} from '@dcloudio/uni-api' + +function getServiceAddress() { + return window.location.protocol + '//' + window.location.host +} + +export const getImageInfo = defineAsyncApi( + API_GET_IMAGE_INFO, + ({ src }, { resolve, reject }) => { + const img = new Image() + img.onload = function () { + resolve({ + width: img.naturalWidth, + height: img.naturalHeight, + path: src.indexOf('/') === 0 ? getServiceAddress() + src : src, + }) + } + img.onerror = function () { + reject() + } + img.src = src + }, + GetImageInfoProtocol, + GetImageInfoOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/media/getVideoInfo.ts b/packages/uni-mp-weibo/src/service/api/media/getVideoInfo.ts new file mode 100644 index 00000000000..6660098fefb --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/getVideoInfo.ts @@ -0,0 +1,57 @@ +import { + defineAsyncApi, + API_GET_VIDEO_INFO, + API_TYPE_GET_VIDEO_INFO, + GetVideoInfoOptions, + GetVideoInfoProtocol, +} from '@dcloudio/uni-api' + +import { urlToFile } from '../../../helpers/file' + +export const getVideoInfo = defineAsyncApi( + API_GET_VIDEO_INFO, + ({ src }, { resolve, reject }) => { + urlToFile(src, true) + .then((file) => { + return file + }) + .catch(() => { + return null + }) + .then((file) => { + const video = document.createElement('video') + if (video.onloadedmetadata !== undefined) { + // 部分浏览器(如微信内置浏览器)未播放无法触发loadedmetadata事件 + const handle = setTimeout( + () => { + video.onloadedmetadata = null + video.onerror = null + reject() + }, + src.startsWith('data:') || src.startsWith('blob:') ? 300 : 3000 + ) + // 尝试获取视频的宽高信息 + video.onloadedmetadata = function () { + clearTimeout(handle) + video.onerror = null + resolve({ + size: file ? file.size : 0, + duration: video.duration || 0, + width: video.videoWidth || 0, + height: video.videoHeight || 0, + }) + } + video.onerror = function () { + clearTimeout(handle) + video.onloadedmetadata = null + reject() + } + video.src = src + } else { + reject() + } + }) + }, + GetVideoInfoProtocol, + GetVideoInfoOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/media/previewImage/ImagePreview.tsx b/packages/uni-mp-weibo/src/service/api/media/previewImage/ImagePreview.tsx new file mode 100644 index 00000000000..213d5740398 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/previewImage/ImagePreview.tsx @@ -0,0 +1,146 @@ +import { + PropType, + onMounted, + Ref, + ref, + ExtractPropTypes, + watch, + nextTick, +} from 'vue' +import { StyleValue } from '@vue/runtime-dom' +import { defineSystemComponent } from '@dcloudio/uni-components' +import { Swiper, SwiperItem } from '@dcloudio/uni-components' +import { usePreventScroll } from '../../../../helpers/usePreventScroll' +import ImageView from './ImageView' +import { createSvgIconVNode, ICON_PATH_CLOSE } from '@dcloudio/uni-core' + +const props = { + urls: { + type: Array as PropType, + default() { + return [] + }, + }, + current: { + type: [Number, String], + default: 0, + }, +} + +export type Props = ExtractPropTypes + +function getIndex(props: Props): number { + let index = + typeof props.current === 'number' + ? props.current + : props.urls.indexOf(props.current) + index = index < 0 ? 0 : index + return index +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'ImagePreview', + props, + emits: ['close'], + setup(props, { emit }) { + usePreventScroll() + const rootRef: Ref = ref(null) + const indexRef = ref(getIndex(props)) + watch( + () => props.current, + () => (indexRef.value = getIndex(props)) + ) + + let preventDefault: boolean + onMounted(() => { + const el = rootRef.value as HTMLElement + const MAX_MOVE = 20 + let x = 0 + let y = 0 + el.addEventListener('mousedown', (event) => { + preventDefault = false + x = event.clientX + y = event.clientY + }) + el.addEventListener('mouseup', (event) => { + if ( + Math.abs(event.clientX - x) > MAX_MOVE || + Math.abs(event.clientY - y) > MAX_MOVE + ) { + preventDefault = true + } + }) + }) + + function onClick() { + if (!preventDefault) { + nextTick(() => { + emit('close') + }) + } + } + + function onChange(event: { detail: { current: number } }) { + indexRef.value = event.detail.current + } + + const closeBtnStyle: StyleValue = { + position: 'absolute', + 'box-sizing': 'border-box', + top: '0', + right: '0', + width: '60px', + height: '44px', + padding: '6px', + 'line-height': '32px', + 'font-size': '26px', + color: 'white', + 'text-align': 'center', + cursor: 'pointer', + } + + return () => { + return ( +
    + + {props.urls.map((src) => ( + + + + ))} + +
    + {createSvgIconVNode(ICON_PATH_CLOSE, '#ffffff', 26)} +
    +
    + ) + } + }, +}) diff --git a/packages/uni-mp-weibo/src/service/api/media/previewImage/ImageView.tsx b/packages/uni-mp-weibo/src/service/api/media/previewImage/ImageView.tsx new file mode 100644 index 00000000000..f8a7544e2b6 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/previewImage/ImageView.tsx @@ -0,0 +1,107 @@ +import { reactive } from 'vue' +import { + defineSystemComponent, + MovableArea, + MovableView, + withWebEvent, +} from '@dcloudio/uni-components' + +const props = { + src: { + type: String, + default: '', + }, +} + +export default /*#__PURE__*/ defineSystemComponent({ + name: 'ImageView', + props, + setup(props) { + const state = reactive({ + direction: 'none', + }) + let scale = 1 + let imgWidth = 0 + let imgHeight = 0 + let width = 0 + let height = 0 + function onScale({ detail }: { detail: { scale: number } }) { + scale = detail.scale + } + function onImgLoad(event: Event) { + const target = event.target as HTMLElement + const rect = target.getBoundingClientRect() + imgWidth = rect.width + imgHeight = rect.height + } + function onTouchStart(event: Event) { + const target = event.target as HTMLElement + const rect = target.getBoundingClientRect() + width = rect.width + height = rect.height + checkDirection(event) + } + function onTouchEnd(event: Event) { + const horizontal = scale * imgWidth > width + const vertical = scale * imgHeight > height + if (horizontal && vertical) { + state.direction = 'all' + } else if (horizontal) { + state.direction = 'horizontal' + } else if (vertical) { + state.direction = 'vertical' + } else { + state.direction = 'none' + } + checkDirection(event) + } + function checkDirection(event: Event) { + // 避免水平滑动和 swiper 冲突 + if (state.direction === 'all' || state.direction === 'horizontal') { + event.stopPropagation() + } + } + return () => { + const viewStyle = { + position: 'absolute', + left: '0', + top: '0', + width: '100%', + height: '100%', + } + return ( + + + + + + ) + } + }, +}) diff --git a/packages/uni-mp-weibo/src/service/api/media/previewImage/index.ts b/packages/uni-mp-weibo/src/service/api/media/previewImage/index.ts new file mode 100644 index 00000000000..0af8fd4a450 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/media/previewImage/index.ts @@ -0,0 +1,59 @@ +import { extend } from '@vue/shared' +import { nextTick, reactive } from 'vue' +import { + API_PREVIEW_IMAGE, + API_TYPE_PREVIEW_IMAGE, + defineAsyncApi, + PreviewImageProtocol, + PreviewImageOptions, + API_CLOSE_PREVIEW_IMAGE, + API_TYPE_CLOSE_PREVIEW_IMAGE, +} from '@dcloudio/uni-api' +import { ensureRoot, createRootApp } from '../../ui/popup/utils' +import ImagePreview, { Props } from './ImagePreview' + +let state: Props | null = null +let imagePreviewInstance: ReturnType | null + +const closePreviewImageView = () => { + state = null + nextTick(() => { + imagePreviewInstance?.unmount() + imagePreviewInstance = null + }) +} + +export const previewImage = defineAsyncApi( + API_PREVIEW_IMAGE, + (args, { resolve }) => { + if (!state) { + state = reactive(args) as Props + // 异步执行,避免干扰 getCurrentInstance + nextTick(() => { + imagePreviewInstance = createRootApp( + ImagePreview, + state as Props, + closePreviewImageView + ) + imagePreviewInstance.mount(ensureRoot('u-a-p')) + }) + } else { + extend(state, args) + } + resolve() + }, + PreviewImageProtocol, + PreviewImageOptions +) + +export const closePreviewImage = defineAsyncApi( + API_CLOSE_PREVIEW_IMAGE, + (_, { resolve, reject }) => { + if (imagePreviewInstance) { + closePreviewImageView() + resolve() + } else { + reject() + } + } +) diff --git a/packages/uni-mp-weibo/src/service/api/network/downloadFile.ts b/packages/uni-mp-weibo/src/service/api/network/downloadFile.ts new file mode 100644 index 00000000000..dcfd7726980 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/network/downloadFile.ts @@ -0,0 +1,126 @@ +import { isFunction } from '@vue/shared' +import { + defineTaskApi, + API_DOWNLOAD_FILE, + API_TYPE_DOWNLOAD_FILE, + DownloadFileProtocol, + DownloadFileOptions, +} from '@dcloudio/uni-api' +import { fileToUrl, getFileName } from '../../../helpers/file' +/** + * 下载任务 + */ +class DownloadTask implements UniApp.DownloadTask { + private _xhr?: XMLHttpRequest + _callbacks: Function[] = [] + constructor(xhr: XMLHttpRequest) { + this._xhr = xhr + } + + /** + * 监听下载进度 + * @param {Function} callback 回调 + */ + onProgressUpdate(callback: (result: any) => void) { + if (!isFunction(callback)) { + return + } + this._callbacks.push(callback) + } + + offProgressUpdate(callback: (result: any) => void) { + const index = this._callbacks.indexOf(callback) + if (index >= 0) { + this._callbacks.splice(index, 1) + } + } + + /** + * 停止任务 + */ + abort() { + if (this._xhr) { + this._xhr.abort() + delete this._xhr + } + } + onHeadersReceived(callback: (result: any) => void): void { + throw new Error('Method not implemented.') + } + offHeadersReceived(callback: (result: any) => void): void { + throw new Error('Method not implemented.') + } +} +/** + * 下载文件 + * @param {*} param0 + * @param {string} callbackId + * @return {DownloadTask} + */ +export const downloadFile = defineTaskApi( + API_DOWNLOAD_FILE, + ( + { url, header, timeout = __uniConfig.networkTimeout.downloadFile }, + { resolve, reject } + ) => { + var timer: ReturnType + var xhr = new XMLHttpRequest() + var downloadTask = new DownloadTask(xhr) + xhr.open('GET', url, true) + Object.keys(header).forEach((key) => { + xhr.setRequestHeader(key, header[key]) + }) + xhr.responseType = 'blob' + xhr.onload = function () { + clearTimeout(timer) + const statusCode = xhr.status + const blob = this.response + let filename + // 使用 getResponseHeader 跨域时会出现警告,但相比 getAllResponseHeaders 更方便 + const contentDisposition = xhr.getResponseHeader('content-disposition') + if (contentDisposition) { + // 暂时仅解析 filename 不解析 filename* + const res = contentDisposition.match(/filename="?(\S+)"?\b/) + if (res) { + filename = res[1] + } + } + blob.name = filename || getFileName(url) + resolve({ + statusCode, + tempFilePath: fileToUrl(blob), + }) + } + xhr.onabort = function () { + clearTimeout(timer) + reject('abort') + } + xhr.onerror = function () { + clearTimeout(timer) + reject() + } + xhr.onprogress = function (event) { + downloadTask._callbacks.forEach((callback) => { + var totalBytesWritten = event.loaded + var totalBytesExpectedToWrite = event.total + var progress = Math.round( + (totalBytesWritten / totalBytesExpectedToWrite) * 100 + ) + callback({ + progress, + totalBytesWritten, + totalBytesExpectedToWrite, + }) + }) + } + xhr.send() + timer = setTimeout(function () { + xhr.onprogress = xhr.onload = xhr.onabort = xhr.onerror = null + downloadTask.abort() + reject('timeout') + }, timeout) + return downloadTask + }, + DownloadFileProtocol, + DownloadFileOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/network/request.ts b/packages/uni-mp-weibo/src/service/api/network/request.ts new file mode 100644 index 00000000000..98d80f6107f --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/network/request.ts @@ -0,0 +1,167 @@ +import { hasOwn, isString } from '@vue/shared' +import { + API_REQUEST, + API_TYPE_REQUEST, + defineTaskApi, + RequestOptions, + RequestProtocol, +} from '@dcloudio/uni-api' +import { LINEFEED } from '@dcloudio/uni-shared' + +export const request = defineTaskApi( + API_REQUEST, + ( + { + url, + data, + header, + method, + dataType, + responseType, + withCredentials, + timeout = __uniConfig.networkTimeout.request, + }, + { resolve, reject } + ) => { + let body = null + // 根据请求类型处理数据 + const contentType = normalizeContentType(header) + if (method !== 'GET') { + if (isString(data) || data instanceof ArrayBuffer) { + body = data + } else { + if (contentType === 'json') { + try { + body = JSON.stringify(data) + } catch (error) { + body = data!.toString() + } + } else if (contentType === 'urlencoded') { + const bodyArray = [] + for (const key in data) { + if (hasOwn(data, key)) { + bodyArray.push( + encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) + ) + } + } + body = bodyArray.join('&') + } else { + body = data!.toString() + } + } + } + const xhr = new XMLHttpRequest() + const requestTask = new RequestTask(xhr) + xhr.open(method!, url) + for (const key in header) { + if (hasOwn(header, key)) { + xhr.setRequestHeader(key, header[key]) + } + } + + const timer = setTimeout(function () { + xhr.onload = xhr.onabort = xhr.onerror = null + requestTask.abort() + reject('timeout') + }, timeout) + xhr.responseType = responseType as 'arraybuffer' | 'text' + xhr.onload = function () { + clearTimeout(timer) + const statusCode = xhr.status + let res = responseType === 'text' ? xhr.responseText : xhr.response + if (responseType === 'text' && dataType === 'json') { + try { + res = JSON.parse(res) + } catch (error) { + // 和微信一致解析失败不抛出错误 + // invoke(callbackId, { + // errMsg: 'request:fail json parse error' + // }) + // return + } + } + resolve({ + data: res, + statusCode, + header: parseHeaders(xhr.getAllResponseHeaders()), + cookies: [], + }) + } + xhr.onabort = function () { + clearTimeout(timer) + reject('abort') + } + xhr.onerror = function () { + clearTimeout(timer) + reject() + } + xhr.withCredentials = withCredentials! + xhr.send(body) + return requestTask + }, + RequestProtocol, + RequestOptions +) + +function normalizeContentType(header: Record) { + const name = Object.keys(header).find( + (name) => name.toLowerCase() === 'content-type' + ) + if (!name) { + return + } + const contentType = header[name] + //#if _NODE_JS_ + // xmlhttprequest 不能正确识别 content-type + if (name !== 'Content-Type') { + header['Content-Type'] = header[name] + delete header[name] + } + //#endif + if (contentType.indexOf('application/json') === 0) { + return 'json' + } else if (contentType.indexOf('application/x-www-form-urlencoded') === 0) { + return 'urlencoded' + } + return 'string' +} + +/** + * 请求任务类 + */ +class RequestTask implements UniApp.RequestTask { + private _xhr?: XMLHttpRequest + constructor(xhr: XMLHttpRequest) { + this._xhr = xhr + } + abort() { + if (this._xhr) { + this._xhr.abort() + delete this._xhr + } + } + onHeadersReceived(callback: (result: any) => void): void { + throw new Error('Method not implemented.') + } + offHeadersReceived(callback: (result: any) => void): void { + throw new Error('Method not implemented.') + } +} + +/** + * 解析响应头 + * @param {string} headers + * @return {object} + */ +function parseHeaders(headers: string) { + const headersObject: Record = {} + headers.split(LINEFEED).forEach((header) => { + const find = header.match(/(\S+\s*):\s*(.*)/) + if (!find || find.length !== 3) { + return + } + headersObject[find[1]] = find[2] + }) + return headersObject +} diff --git a/packages/uni-mp-weibo/src/service/api/network/socket.ts b/packages/uni-mp-weibo/src/service/api/network/socket.ts new file mode 100644 index 00000000000..a8d44d15690 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/network/socket.ts @@ -0,0 +1,246 @@ +import { extend, capitalize, isFunction, isString } from '@vue/shared' +import { + defineTaskApi, + defineAsyncApi, + defineOnApi, + API_CONNECT_SOCKET, + API_TYPE_CONNECT_SOCKET, + ConnectSocketProtocol, + ConnectSocketOptions, + API_SEND_SOCKET_MESSAGE, + API_TYPE_SEND_SOCKET_MESSAGE, + SendSocketMessageProtocol, + API_CLOSE_SOCKET, + API_TYPE_CLOSE_SOCKET, + CloseSocketProtocol, +} from '@dcloudio/uni-api' +import { callOptions } from '@dcloudio/uni-shared' + +type eventName = keyof WebSocketEventMap + +const socketTasks: SocketTask[] = [] +const globalEvent: Record = { + open: '', + close: '', + error: '', + message: '', +} + +class SocketTask implements UniApp.SocketTask { + /** + * WebSocket实例 + */ + _webSocket?: WebSocket + _callbacks: Record = { + open: [], + close: [], + error: [], + message: [], + } + readonly CLOSED?: number + readonly CLOSING?: number + readonly CONNECTING?: number + readonly OPEN?: number + readonly readyState?: number + /** + * 构造函数 + * @param {string} url + * @param {Array} protocols + */ + constructor(url: string, protocols?: string[], callback?: Function) { + let error + try { + const webSocket = (this._webSocket = new WebSocket(url, protocols)) + webSocket.binaryType = 'arraybuffer' + const eventNames: eventName[] = ['open', 'close', 'error', 'message'] + eventNames.forEach((name: eventName) => { + this._callbacks[name] = [] + webSocket.addEventListener(name, (event) => { + const { data, code, reason } = event + const res = + name === 'message' + ? { data } + : name === 'close' + ? { code, reason } + : {} + this._callbacks[name].forEach((callback) => { + try { + callback(res) + } catch (e) { + console.error( + `thirdScriptError\n${e};at socketTask.on${capitalize( + name + )} callback function\n`, + e + ) + } + }) + if (this === socketTasks[0] && globalEvent[name]) { + UniServiceJSBridge.invokeOnCallback(globalEvent[name], res) + } + if (name === 'error' || name === 'close') { + const index = socketTasks.indexOf(this) + if (index >= 0) { + socketTasks.splice(index, 1) + } + } + }) + }) + const propertys: (keyof WebSocket)[] = [ + 'CLOSED', + 'CLOSING', + 'CONNECTING', + 'OPEN', + 'readyState', + ] + propertys.forEach((property) => { + Object.defineProperty(this, property, { + get() { + return webSocket[property] + }, + }) + }) + } catch (e) { + error = e + } + callback && callback(error, this) + } + + /** + * 发送 + * @param {any} data + */ + send(options: UniApp.SendSocketMessageOptions) { + const data = (options || {}).data + const ws = this._webSocket + try { + if (ws.readyState !== ws.OPEN) { + throw new Error('SocketTask.readyState is not OPEN') + } + ws.send(data) + callOptions(options, 'sendSocketMessage:ok') + } catch (error) { + callOptions(options, `sendSocketMessage:fail ${error}`) + } + } + + /** + * 关闭 + * @param {number} code + * @param {string} reason + */ + close(options: UniApp.CloseSocketOptions = {}) { + const ws = this._webSocket + try { + const code = options.code || 1000 + const reason = options.reason + if (isString(reason)) { + ws.close(code, reason) + } else { + ws.close(code) + } + callOptions(options, 'closeSocket:ok') + } catch (error) { + callOptions(options, `closeSocket:fail ${error}`) + } + } + onOpen(callback: (result: any) => void) { + this._callbacks.open.push(callback) + } + onMessage(callback: (result: any) => void) { + this._callbacks.message.push(callback) + } + onError(callback: (result: any) => void) { + this._callbacks.error.push(callback) + } + onClose(callback: (result: any) => void) { + this._callbacks.close.push(callback) + } +} + +export const connectSocket = defineTaskApi( + API_CONNECT_SOCKET, + ({ url, protocols }, { resolve, reject }) => { + return new SocketTask( + url, + protocols, + (error: Error, socketTask: SocketTask) => { + if (error) { + reject(error.toString()) + return + } + socketTasks.push(socketTask) + resolve() + } + ) + }, + ConnectSocketProtocol, + ConnectSocketOptions +) + +function callSocketTask( + socketTask: SocketTask, + method: 'send' | 'close', + option: any, + resolve: Function, + reject: Function +) { + const fn = socketTask[method] as + | typeof socketTask['send'] + | typeof socketTask['close'] + if (isFunction(fn)) { + fn.call( + socketTask, + extend({}, option, { + success() { + resolve() + }, + fail({ errMsg }: any) { + reject(errMsg.replace('sendSocketMessage:fail ', '')) + }, + complete: undefined, + }) + ) + } +} + +export const sendSocketMessage = defineAsyncApi( + API_SEND_SOCKET_MESSAGE, + (options, { resolve, reject }) => { + const socketTask = socketTasks[0] + if (socketTask && socketTask.readyState === socketTask.OPEN) { + callSocketTask(socketTask, 'send', options, resolve, reject) + } else { + reject('WebSocket is not connected') + } + }, + SendSocketMessageProtocol +) + +export const closeSocket = defineAsyncApi( + API_CLOSE_SOCKET, + (options, { resolve, reject }) => { + const socketTask = socketTasks[0] + if (socketTask) { + callSocketTask(socketTask, 'close', options, resolve, reject) + } else { + reject('WebSocket is not connected') + } + }, + CloseSocketProtocol +) + +function on(event: eventName) { + const api = `onSocket${capitalize(event)}` + return defineOnApi(api, () => { + globalEvent[event] = api + }) +} + +export const onSocketOpen = /*#__PURE__*/ on('open') + +export const onSocketError = /*#__PURE__*/ on('error') + +export const onSocketMessage = /*#__PURE__*/ on('message') + +export const onSocketClose = /*#__PURE__*/ on('close') diff --git a/packages/uni-mp-weibo/src/service/api/network/uploadFile.ts b/packages/uni-mp-weibo/src/service/api/network/uploadFile.ts new file mode 100644 index 00000000000..7d3e919a294 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/network/uploadFile.ts @@ -0,0 +1,159 @@ +import { isArray, isFunction } from '@vue/shared' + +import { + defineTaskApi, + API_UPLOAD_FILE, + API_TYPE_UPLOAD_FILE, + UploadFileProtocol, + UploadFileOptions, +} from '@dcloudio/uni-api' +import { urlToFile, blobToFile } from '../../../helpers/file' +/** + * 上传任务 + */ +class UploadTask implements UniApp.UploadTask { + _xhr?: XMLHttpRequest + _isAbort?: boolean + _callbacks: Function[] = [] + constructor(xhr?: XMLHttpRequest) { + this._xhr = xhr + } + + /** + * 监听上传进度 + * @param callback 回调 + */ + onProgressUpdate(callback: (result: any) => void) { + if (!isFunction(callback)) { + return + } + this._callbacks.push(callback) + } + + offProgressUpdate(callback: (result: any) => void) { + const index = this._callbacks.indexOf(callback) + if (index >= 0) { + this._callbacks.splice(index, 1) + } + } + + /** + * 中断上传任务 + */ + abort() { + this._isAbort = true + if (this._xhr) { + this._xhr.abort() + delete this._xhr + } + } + onHeadersReceived(callback: (result: any) => void): void { + throw new Error('Method not implemented.') + } + offHeadersReceived(callback: (result: any) => void): void { + throw new Error('Method not implemented.') + } +} + +export const uploadFile = defineTaskApi( + API_UPLOAD_FILE, + ( + { + url, + file, + filePath, + name, + files, + header, + formData, + timeout = __uniConfig.networkTimeout.uploadFile, + }, + { resolve, reject } + ) => { + var uploadTask = new UploadTask() + if (!isArray(files) || !files.length) { + files = [ + { + name, + file, + uri: filePath, + }, + ] + } + function upload(realFiles: File[]) { + var xhr = new XMLHttpRequest() + var form = new FormData() + var timer: ReturnType + Object.keys(formData).forEach((key) => { + form.append(key, formData[key]) + }) + Object.values(files).forEach(({ name }, index) => { + const file = realFiles[index] + form.append(name || 'file', file, file.name || `file-${Date.now()}`) + }) + xhr.open('POST', url) + Object.keys(header).forEach((key) => { + xhr.setRequestHeader(key, header[key]) + }) + xhr.upload.onprogress = function (event) { + uploadTask._callbacks.forEach((callback) => { + var totalBytesSent = event.loaded + var totalBytesExpectedToSend = event.total + var progress = Math.round( + (totalBytesSent / totalBytesExpectedToSend) * 100 + ) + callback({ + progress, + totalBytesSent, + totalBytesExpectedToSend, + }) + }) + } + xhr.onerror = function () { + clearTimeout(timer) + reject() + } + xhr.onabort = function () { + clearTimeout(timer) + reject('abort') + } + xhr.onload = function () { + clearTimeout(timer) + const statusCode = xhr.status + resolve({ + statusCode, + data: xhr.responseText || xhr.response, + }) + } + if (!uploadTask._isAbort) { + timer = setTimeout(function () { + xhr.upload.onprogress = xhr.onload = xhr.onabort = xhr.onerror = null + uploadTask.abort() + reject('timeout') + }, timeout) + xhr.send(form) + uploadTask._xhr = xhr + } else { + reject('abort') + } + } + + Promise.all( + files.map(({ file, uri }) => + file instanceof Blob + ? Promise.resolve(blobToFile(file)) + : urlToFile(uri) + ) + ) + .then(upload) + .catch(() => { + setTimeout(() => { + reject('file error') + }, 0) + }) + + return uploadTask + }, + UploadFileProtocol, + UploadFileOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/route/navigateBack.ts b/packages/uni-mp-weibo/src/service/api/route/navigateBack.ts new file mode 100644 index 00000000000..9e3b01fd679 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/route/navigateBack.ts @@ -0,0 +1,31 @@ +import { invokeHook } from '@dcloudio/uni-core' +import { + API_NAVIGATE_BACK, + API_TYPE_NAVIGATE_BACK, + defineAsyncApi, + NavigateBackOptions, + NavigateBackProtocol, +} from '@dcloudio/uni-api' +import { ON_BACK_PRESS } from '@dcloudio/uni-shared' + +export const navigateBack = defineAsyncApi( + API_NAVIGATE_BACK, + (args, { resolve, reject }) => { + let canBack = true + if ( + invokeHook(ON_BACK_PRESS, { + from: (args as any).from || 'navigateBack', + }) === true + ) { + canBack = false + } + if (!canBack) { + return reject(ON_BACK_PRESS) + } + + getApp().$router.go(-args!.delta!) + return resolve() + }, + NavigateBackProtocol, + NavigateBackOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/route/navigateTo.ts b/packages/uni-mp-weibo/src/service/api/route/navigateTo.ts new file mode 100644 index 00000000000..85be9873063 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/route/navigateTo.ts @@ -0,0 +1,18 @@ +import { + API_NAVIGATE_TO, + API_TYPE_NAVIGATE_TO, + defineAsyncApi, + NavigateToOptions, + NavigateToProtocol, +} from '@dcloudio/uni-api' +import { navigate } from './utils' + +export const navigateTo = defineAsyncApi( + API_NAVIGATE_TO, + ({ url, events }, { resolve, reject }) => + navigate({ type: API_NAVIGATE_TO, url, events }) + .then(resolve) + .catch(reject), + NavigateToProtocol, + NavigateToOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/route/preloadPage.ts b/packages/uni-mp-weibo/src/service/api/route/preloadPage.ts new file mode 100644 index 00000000000..2e22c1c0653 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/route/preloadPage.ts @@ -0,0 +1,32 @@ +import { + API_PRELOAD_PAGE, + API_TYPE_PRELOAD_PAGE, + PreloadPageProtocol, + defineAsyncApi, +} from '@dcloudio/uni-api' +import { getRouteOptions } from '@dcloudio/uni-core' + +export const preloadPage = defineAsyncApi( + API_PRELOAD_PAGE, + ({ url }, { resolve, reject }) => { + const path = url.split('?')[0] + const route = getRouteOptions(path) + if (!route) { + reject(`${url}}`) + return + } + route.loader && + route + .loader() + .then(() => { + resolve({ + url, + errMsg: 'preloadPage:ok', + }) + }) + .catch((err: any) => { + reject(`${url} ${String(err)}`) + }) + }, + PreloadPageProtocol +) diff --git a/packages/uni-mp-weibo/src/service/api/route/reLaunch.ts b/packages/uni-mp-weibo/src/service/api/route/reLaunch.ts new file mode 100644 index 00000000000..120f739d261 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/route/reLaunch.ts @@ -0,0 +1,28 @@ +import { + API_RE_LAUNCH, + API_TYPE_RE_LAUNCH, + defineAsyncApi, + ReLaunchOptions, + ReLaunchProtocol, +} from '@dcloudio/uni-api' +import { getCurrentPagesMap, removePage } from '../../../framework/setup/page' +import { navigate } from './utils' + +function removeAllPages() { + const keys = getCurrentPagesMap().keys() + for (const routeKey of keys) { + removePage(routeKey) + } +} + +export const reLaunch = defineAsyncApi( + API_RE_LAUNCH, + ({ url }, { resolve, reject }) => { + return ( + removeAllPages(), + navigate({ type: API_RE_LAUNCH, url }).then(resolve).catch(reject) + ) + }, + ReLaunchProtocol, + ReLaunchOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/route/redirectTo.ts b/packages/uni-mp-weibo/src/service/api/route/redirectTo.ts new file mode 100644 index 00000000000..3b4330806b2 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/route/redirectTo.ts @@ -0,0 +1,32 @@ +import { + API_REDIRECT_TO, + API_TYPE_REDIRECT_TO, + defineAsyncApi, + RedirectToOptions, + RedirectToProtocol, +} from '@dcloudio/uni-api' +import { getCurrentPage } from '@dcloudio/uni-core' +import { removePage, normalizeRouteKey } from '../../../framework/setup/page' +import { navigate } from './utils' + +function removeLastPage() { + const page = getCurrentPage() + if (!page) { + return + } + const $page = page.$page + removePage(normalizeRouteKey($page.path, $page.id)) +} + +export const redirectTo = defineAsyncApi( + API_REDIRECT_TO, + ({ url }, { resolve, reject }) => { + return ( + // TODO exists 属性未实现 + removeLastPage(), + navigate({ type: API_REDIRECT_TO, url }).then(resolve).catch(reject) + ) + }, + RedirectToProtocol, + RedirectToOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/route/switchTab.ts b/packages/uni-mp-weibo/src/service/api/route/switchTab.ts new file mode 100644 index 00000000000..978307d8f37 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/route/switchTab.ts @@ -0,0 +1,69 @@ +import { ComponentPublicInstance } from 'vue' +import { + API_SWITCH_TAB, + API_TYPE_SWITCH_TAB, + defineAsyncApi, + SwitchTabOptions, + SwitchTabProtocol, +} from '@dcloudio/uni-api' +import { getCurrentPageVm, invokeHook } from '@dcloudio/uni-core' +import { getCurrentPagesMap, removePage } from '../../../framework/setup/page' +import { navigate } from './utils' +import { ON_HIDE } from '@dcloudio/uni-shared' + +function removeNonTabBarPages() { + const curTabBarPageVm = getCurrentPageVm() + if (!curTabBarPageVm) { + return + } + const pagesMap = getCurrentPagesMap() + const keys = pagesMap.keys() + for (const routeKey of keys) { + const page = pagesMap.get(routeKey) as ComponentPublicInstance + if (!page.$.__isTabBar) { + removePage(routeKey) + } else { + page.$.__isActive = false + } + } + if (curTabBarPageVm.$.__isTabBar) { + curTabBarPageVm.$.__isVisible = false + invokeHook(curTabBarPageVm, ON_HIDE) + } +} + +/** + * 判断 url 和 page 是否为同一个页面 + * @param url 目标页 + * @param $page 页面栈中的某个页面 + * @returns boolean + */ +function isSamePage(url: string, $page: Page.PageInstance['$page']) { + return url === $page.fullPath || (url === '/' && $page.meta.isEntry) +} + +function getTabBarPageId(url: string) { + const pages = getCurrentPagesMap().values() + for (const page of pages) { + const $page = page.$page + if (isSamePage(url, $page)) { + ;(page as ComponentPublicInstance).$.__isActive = true + return $page.id + } + } +} + +export const switchTab = defineAsyncApi( + API_SWITCH_TAB, + // @ts-ignore + ({ url, tabBarText }, { resolve, reject }) => { + return ( + removeNonTabBarPages(), + navigate({ type: API_SWITCH_TAB, url, tabBarText }, getTabBarPageId(url)) + .then(resolve) + .catch(reject) + ) + }, + SwitchTabProtocol, + SwitchTabOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/route/utils.ts b/packages/uni-mp-weibo/src/service/api/route/utils.ts new file mode 100644 index 00000000000..81e0b6dd784 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/route/utils.ts @@ -0,0 +1,59 @@ +import { EventChannel, parseUrl } from '@dcloudio/uni-shared' +import { isNavigationFailure, Router } from 'vue-router' +import { createPageState } from '../../../framework/setup/page' + +export type NavigateType = + | 'navigateTo' + | 'redirectTo' + | 'reLaunch' + | 'switchTab' + +interface NavigateOptions { + type: NavigateType + url: string + tabBarText?: string + events?: Record +} +export function navigate( + { type, url, tabBarText, events }: NavigateOptions, + __id__?: number +): Promise { + const router = getApp().$router as Router + const { path, query } = parseUrl(url) + return new Promise((resolve, reject) => { + const state = createPageState(type, __id__) + router[type === 'navigateTo' ? 'push' : 'replace']({ + path, + query, + state, + force: true, + }).then((failure) => { + if (isNavigationFailure(failure)) { + return reject(failure.message) + } + if (type === 'switchTab') { + router.currentRoute.value.meta.tabBarText = tabBarText + } + if (type === 'navigateTo') { + const meta = router.currentRoute.value.meta + // if getOpenerEventChannel is called before navigateTo + if (!meta.eventChannel) { + meta.eventChannel = new EventChannel(state.__id__, events) + } else if (events) { + Object.keys(events).forEach((eventName) => { + ;(meta.eventChannel as EventChannel)._addListener( + eventName, + 'on', + events[eventName] + ) + }) + ;(meta.eventChannel as EventChannel)._clearCache() + } + return resolve({ + eventChannel: meta.eventChannel as EventChannel, + }) + } + return resolve() + }) + }) +} diff --git a/packages/uni-mp-weibo/src/service/api/storage/storage.ts b/packages/uni-mp-weibo/src/service/api/storage/storage.ts new file mode 100644 index 00000000000..17470d3b174 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/storage/storage.ts @@ -0,0 +1,189 @@ +import { isString } from '@vue/shared' + +import { + defineSyncApi, + defineAsyncApi, + API_SET_STORAGE_SYNC, + API_TYPE_SET_STORAGE_SYNC, + API_SET_STORAGE, + API_TYPE_SET_STORAGE, + SetStorageProtocol, + SetStorageSyncProtocol, + API_GET_STORAGE_SYNC, + GetStorageSyncProtocol, + API_TYPE_GET_STORAGE_SYNC, + API_GET_STORAGE, + GetStorageProtocol, + API_TYPE_GET_STORAGE, + API_TYPE_REMOVE_STORAGE_SYNC, + API_REMOVE_STORAGE, + API_TYPE_REMOVE_STORAGE, + RemoveStorageSyncProtocol, + RemoveStorageProtocol, +} from '@dcloudio/uni-api' + +const STORAGE_KEYS = 'uni-storage-keys' + +function parseValue(value: any) { + const types = ['object', 'string', 'number', 'boolean', 'undefined'] + try { + const object = isString(value) ? JSON.parse(value) : value + const type = object.type + if (types.indexOf(type) >= 0) { + const keys = Object.keys(object) + if (keys.length === 2 && 'data' in object) { + // eslint-disable-next-line valid-typeof + if (typeof object.data === type) { + return object.data + } + // eslint-disable-next-line no-useless-escape + if ( + type === 'object' && + /^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z$/.test(object.data) + ) { + // ISO 8601 格式返回 Date + return new Date(object.data) + } + } else if (keys.length === 1) { + return '' + } + } + } catch (error) {} +} + +export const setStorageSync = defineSyncApi( + API_SET_STORAGE_SYNC, + (key, data) => { + const type = typeof data + const value = + type === 'string' + ? data + : JSON.stringify({ + type, + data: data, + }) + localStorage.setItem(key, value) + }, + SetStorageSyncProtocol +) + +export const setStorage = defineAsyncApi( + API_SET_STORAGE, + ({ key, data }, { resolve, reject }) => { + try { + setStorageSync(key, data) + resolve() + } catch (error: any) { + reject(error.message) + } + }, + SetStorageProtocol +) + +function getStorageOrigin(key: string): any { + const value = localStorage && localStorage.getItem(key) + if (!isString(value)) { + throw new Error('data not found') + } + let data: any = value + try { + const object = JSON.parse(value) + const result = parseValue(object) + if (result !== undefined) { + data = result + } + } catch (error) {} + return data +} + +export const getStorageSync = defineSyncApi( + API_GET_STORAGE_SYNC, + (key: string) => { + try { + return getStorageOrigin(key) + } catch (error) { + return '' + } + }, + GetStorageSyncProtocol +) + +export const getStorage = defineAsyncApi( + API_GET_STORAGE, + ({ key }, { resolve, reject }) => { + try { + const data = getStorageOrigin(key) + resolve({ + data, + }) + } catch (error: any) { + reject(error.message) + } + }, + GetStorageProtocol +) + +export const removeStorageSync = defineSyncApi( + API_REMOVE_STORAGE, + (key) => { + if (localStorage) { + localStorage.removeItem(key) + } + }, + RemoveStorageSyncProtocol +) + +export const removeStorage = defineAsyncApi( + API_REMOVE_STORAGE, + ({ key }, { resolve }) => { + removeStorageSync(key) + resolve() + }, + RemoveStorageProtocol +) + +export const clearStorageSync = defineSyncApi( + 'clearStorageSync', + () => { + if (localStorage) { + localStorage.clear() + } + } +) + +export const clearStorage = defineAsyncApi( + 'clearStorage', + (_, { resolve }) => { + clearStorageSync() + resolve() + } +) + +export const getStorageInfoSync = defineSyncApi( + 'getStorageInfoSync', + () => { + const length = (localStorage && localStorage.length) || 0 + const keys = [] + let currentSize = 0 + for (let index = 0; index < length; index++) { + const key = localStorage.key(index) + const value = localStorage.getItem(key) || '' + currentSize += key.length + value.length + if (key !== STORAGE_KEYS) { + keys.push(key) + } + } + return { + keys, + currentSize: Math.ceil((currentSize * 2) / 1024), + limitSize: Number.MAX_VALUE, + } + } +) + +export const getStorageInfo = defineAsyncApi( + 'getStorageInfo', + (_, { resolve }) => { + resolve(getStorageInfoSync()) + } +) diff --git a/packages/uni-mp-weibo/src/service/api/todo/index.ts b/packages/uni-mp-weibo/src/service/api/todo/index.ts new file mode 100644 index 00000000000..36a85a3bb71 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/todo/index.ts @@ -0,0 +1,189 @@ +import { + API_SAVE_IMAGE_TO_PHOTOS_ALBUM, + API_SAVE_VIDEO_TO_PHOTOS_ALBUM, + API_TYPE_SAVE_IMAGE_TO_PHOTOS_ALBUM, + API_TYPE_SAVE_VIDEO_TO_PHOTOS_ALBUM, + createUnsupportedAsyncApi, + createUnsupportedOnApi, + createUnsupportedSyncApi, + defineAsyncApi, + defineOnApi, + defineSyncApi, +} from '@dcloudio/uni-api' + +export const saveImageToPhotosAlbum = + defineAsyncApi( + API_SAVE_IMAGE_TO_PHOTOS_ALBUM, + createUnsupportedAsyncApi(API_SAVE_IMAGE_TO_PHOTOS_ALBUM) + ) +const API_GET_RECORDER_MANAGER = 'getRecorderManager' +export const getRecorderManager = defineSyncApi( + API_GET_RECORDER_MANAGER, + createUnsupportedSyncApi(API_GET_RECORDER_MANAGER) +) + +export const saveVideoToPhotosAlbum = + defineAsyncApi( + API_SAVE_VIDEO_TO_PHOTOS_ALBUM, + createUnsupportedAsyncApi(API_SAVE_VIDEO_TO_PHOTOS_ALBUM) + ) + +const API_CREATE_CAMERA_CONTEXT = 'createCameraContext' +export const createCameraContext = defineSyncApi< + typeof uni.createCameraContext +>( + API_CREATE_CAMERA_CONTEXT, + createUnsupportedSyncApi(API_CREATE_CAMERA_CONTEXT) +) + +const API_CREATE_LIVE_PLAYER_CONTEXT = 'createLivePlayerContext' +export const createLivePlayerContext = defineSyncApi< + typeof uni.createLivePlayerContext +>( + API_CREATE_LIVE_PLAYER_CONTEXT, + createUnsupportedSyncApi(API_CREATE_LIVE_PLAYER_CONTEXT) +) + +const API_SAVE_FILE = 'saveFile' +export const saveFile = defineAsyncApi( + API_SAVE_FILE, + createUnsupportedAsyncApi(API_SAVE_FILE) +) +const API_GET_SAVED_FILE_LIST = 'getSavedFileList' +export const getSavedFileList = defineAsyncApi( + API_GET_SAVED_FILE_LIST, + createUnsupportedAsyncApi(API_GET_SAVED_FILE_LIST) +) +const API_GET_SAVED_FILE_INFO = 'getSavedFileInfo' +export const getSavedFileInfo = defineAsyncApi( + API_GET_SAVED_FILE_INFO, + createUnsupportedAsyncApi(API_GET_SAVED_FILE_INFO) +) +const API_REMOVE_SAVED_FILE = 'removeSavedFile' +export const removeSavedFile = defineAsyncApi( + API_REMOVE_SAVED_FILE, + createUnsupportedAsyncApi(API_REMOVE_SAVED_FILE) +) + +const API_ON_MEMORY_WARNING = 'onMemoryWarning' +export const onMemoryWarning = defineOnApi( + API_ON_MEMORY_WARNING, + createUnsupportedOnApi(API_ON_MEMORY_WARNING) +) +const API_ON_GYROSCOPE_CHANGE = 'onGyroscopeChange' +export const onGyroscopeChange = defineOnApi( + API_ON_GYROSCOPE_CHANGE, + createUnsupportedOnApi(API_ON_GYROSCOPE_CHANGE) +) +const API_START_GYROSCOPE = 'startGyroscope' +export const startGyroscope = defineAsyncApi( + API_START_GYROSCOPE, + createUnsupportedAsyncApi(API_START_GYROSCOPE) +) +const API_STOP_GYROSCOPE = 'stopGyroscope' +export const stopGyroscope = defineAsyncApi( + API_STOP_GYROSCOPE, + createUnsupportedAsyncApi(API_STOP_GYROSCOPE) +) + +const API_SCAN_CODE = 'scanCode' +export const scanCode = defineAsyncApi( + API_SCAN_CODE, + createUnsupportedAsyncApi(API_SCAN_CODE) +) + +const API_SET_SCREEN_BRIGHTNESS = 'setScreenBrightness' +export const setScreenBrightness = defineAsyncApi< + typeof uni.setScreenBrightness +>( + API_SET_SCREEN_BRIGHTNESS, + createUnsupportedAsyncApi(API_SET_SCREEN_BRIGHTNESS) +) + +const API_GET_SCREEN_BRIGHTNESS = 'getScreenBrightness' +export const getScreenBrightness = defineAsyncApi< + typeof uni.getScreenBrightness +>( + API_GET_SCREEN_BRIGHTNESS, + createUnsupportedAsyncApi(API_GET_SCREEN_BRIGHTNESS) +) + +const API_SET_KEEP_SCREEN_ON = 'setKeepScreenOn' +export const setKeepScreenOn = defineAsyncApi( + API_SET_KEEP_SCREEN_ON, + createUnsupportedAsyncApi(API_SET_KEEP_SCREEN_ON) +) +const API_ON_USER_CAPTURE_SCREEN = 'onUserCaptureScreen' +export const onUserCaptureScreen = defineOnApi( + API_ON_USER_CAPTURE_SCREEN, + createUnsupportedOnApi(API_ON_USER_CAPTURE_SCREEN) +) +const API_ADD_PHONE_CONTACT = 'addPhoneContact' +export const addPhoneContact = defineAsyncApi( + API_ADD_PHONE_CONTACT, + createUnsupportedAsyncApi(API_ADD_PHONE_CONTACT) +) + +const API_LOGIN = 'login' +export const login = defineAsyncApi( + API_LOGIN, + createUnsupportedAsyncApi(API_LOGIN) +) +const API_GET_USER_INFO = 'getUserInfo' +export const getUserInfo = defineAsyncApi( + API_GET_USER_INFO, + (args, { resolve, reject }) => { + resolve() + } +) +const API_CHECK_SESSION = 'checkSession' +export const checkSession = defineAsyncApi( + API_CHECK_SESSION, + (args, { resolve, reject }) => { + resolve() + } +) +const API_GET_PROVIDER = 'getProvider' +export const getProvider = defineAsyncApi( + API_GET_PROVIDER, + createUnsupportedAsyncApi(API_GET_PROVIDER) +) + +// TODO... + +// 'openBluetoothAdapter', +// 'startBluetoothDevicesDiscovery', +// 'onBluetoothDeviceFound', +// 'stopBluetoothDevicesDiscovery', +// 'onBluetoothAdapterStateChange', +// 'getConnectedBluetoothDevices', +// 'getBluetoothDevices', +// 'getBluetoothAdapterState', +// 'closeBluetoothAdapter', +// 'writeBLECharacteristicValue', +// 'readBLECharacteristicValue', +// 'onBLEConnectionStateChange', +// 'onBLECharacteristicValueChange', +// 'notifyBLECharacteristicValueChange', +// 'getBLEDeviceServices', +// 'getBLEDeviceCharacteristics', +// 'createBLEConnection', +// 'closeBLEConnection', +// 'onBeaconServiceChange', +// 'onBeaconUpdate', +// 'getBeacons', +// 'startBeaconDiscovery', +// 'stopBeaconDiscovery', +// 'setBackgroundColor', +// 'setBackgroundTextStyle', +// 'checkSession', +// 'getUserInfo', +// 'share', +// 'onShareAppMessage', +// 'showShareMenu', +// 'hideShareMenu', +// 'requestPayment', +// 'subscribePush', +// 'unsubscribePush', +// 'onPush', +// 'offPush' diff --git a/packages/uni-mp-weibo/src/service/api/ui/intersectionObserver.ts b/packages/uni-mp-weibo/src/service/api/ui/intersectionObserver.ts new file mode 100644 index 00000000000..94e9f99b5ab --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/intersectionObserver.ts @@ -0,0 +1,30 @@ +import { + requestComponentObserver, + AddIntersectionObserverArgs, + RemoveIntersectionObserverArgs, +} from '@dcloudio/uni-api' +import { findElem } from '../../../platform/dom' + +export function addIntersectionObserver( + { reqId, component, options, callback }: AddIntersectionObserverArgs, + _pageId?: number +) { + const $el = findElem(component) + ;($el.__io || ($el.__io = {}))[reqId] = requestComponentObserver( + $el, + options, + callback + ) +} + +export function removeIntersectionObserver( + { reqId, component }: RemoveIntersectionObserverArgs, + _pageId?: number +) { + const $el = findElem(component) + const intersectionObserver = $el.__io && $el.__io[reqId] + if (intersectionObserver) { + intersectionObserver.disconnect() + delete $el.__io[reqId] + } +} diff --git a/packages/uni-mp-weibo/src/service/api/ui/loadFontFace.ts b/packages/uni-mp-weibo/src/service/api/ui/loadFontFace.ts new file mode 100644 index 00000000000..0f34fa048ae --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/loadFontFace.ts @@ -0,0 +1,21 @@ +import { + API_LOAD_FONT_FACE, + API_TYPE_LOAD_FONT_FACE, + defineAsyncApi, + LoadFontFaceProtocol, +} from '@dcloudio/uni-api' +import { addFont } from '@dcloudio/uni-shared' + +export const loadFontFace = defineAsyncApi( + API_LOAD_FONT_FACE, + ({ family, source, desc }, { resolve, reject }) => { + addFont(family, source, desc) + .then(() => { + resolve() + }) + .catch((err) => { + reject(`loadFontFace:fail ${err}`) + }) + }, + LoadFontFaceProtocol +) diff --git a/packages/uni-mp-weibo/src/service/api/ui/mediaQueryObserver.ts b/packages/uni-mp-weibo/src/service/api/ui/mediaQueryObserver.ts new file mode 100644 index 00000000000..d64e25be963 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/mediaQueryObserver.ts @@ -0,0 +1,73 @@ +import { + AddMediaQueryObserverArgs, + RemoveMediaQueryObserverArgs, +} from '@dcloudio/uni-api' + +let mediaQueryObservers: any = {} +let listeners: any = {} + +// 拼接媒体查询条件 +function handleMediaQueryStr($props: UniApp.DescriptorOptions) { + const mediaQueryArr = [] + const propsMenu = [ + 'width', + 'minWidth', + 'maxWidth', + 'height', + 'minHeight', + 'maxHeight', + 'orientation', + ] + for (const item of propsMenu) { + if ( + item !== 'orientation' && + $props[item as keyof UniApp.DescriptorOptions] && + Number(($props[item as keyof UniApp.DescriptorOptions] as number) >= 0) + ) { + mediaQueryArr.push( + `(${humpToLine(item)}: ${Number( + $props[item as keyof UniApp.DescriptorOptions] + )}px)` + ) + } + if (item === 'orientation' && $props[item]) { + mediaQueryArr.push(`(${humpToLine(item)}: ${$props[item]})`) + } + } + const mediaQueryStr = mediaQueryArr.join(' and ') + return mediaQueryStr +} + +function humpToLine(name: string) { + return name.replace(/([A-Z])/g, '-$1').toLowerCase() +} + +// 请求媒体查询对象 +export function addMediaQueryObserver( + { reqId, component, options, callback }: AddMediaQueryObserverArgs, + _pageId?: number +) { + // 创建一个媒体查询对象 + const mediaQueryObserver = (mediaQueryObservers[reqId] = window.matchMedia( + handleMediaQueryStr(options) + )) + // 创建一个监听器 + const listener = (listeners[reqId] = (observer: any) => + callback(observer.matches as any)) + listener(mediaQueryObserver) // 监听前执行一次媒体查询 + mediaQueryObserver.addListener(listener as any) +} + +// 销毁媒体查询对象 +export function removeMediaQueryObserver( + { reqId, component }: RemoveMediaQueryObserverArgs, + _pageId?: number +) { + const listener = listeners[reqId] + const mediaQueryObserver = mediaQueryObservers[reqId] + if (mediaQueryObserver) { + mediaQueryObserver.removeListener(listener as any) // 移除监听 + delete listeners[reqId] + delete mediaQueryObservers[reqId] + } +} diff --git a/packages/uni-mp-weibo/src/service/api/ui/navigationBar.ts b/packages/uni-mp-weibo/src/service/api/ui/navigationBar.ts new file mode 100644 index 00000000000..c4a40254401 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/navigationBar.ts @@ -0,0 +1,134 @@ +import { + defineAsyncApi, + API_SET_NAVIGATION_BAR_COLOR, + API_SET_NAVIGATION_BAR_TITLE, + API_SHOW_NAVIGATION_BAR_LOADING, + API_HIDE_NAVIGATION_BAR_LOADING, + API_TYPE_SET_NAVIGATION_BAR_COLOR, + API_TYPE_SET_NAVIGATION_BAR_TITLE, + API_TYPE_SHOW_NAVIGATION_BAR_LOADING, + API_TYPE_HIDE_NAVIGATION_BAR_LOADING, + SetNavigationBarColorOptions, + SetNavigationBarColorProtocol, + SetNavigationBarTitleProtocol, +} from '@dcloudio/uni-api' +import { getCurrentPageMeta } from '@dcloudio/uni-core' +import { updateDocumentTitle } from '../../../helpers/useDocumentTitle' + +function setNavigationBar( + pageMeta: UniApp.PageRouteMeta | undefined, + type: string, + args: Record, + resolve: () => void, + reject: (err: string) => void +) { + if (!pageMeta) { + return reject('page not found') + } + const { navigationBar } = pageMeta + + switch (type) { + case API_SET_NAVIGATION_BAR_COLOR: + const { frontColor, backgroundColor, animation } = args + const { duration, timingFunc } = animation + if (frontColor) { + navigationBar.titleColor = + frontColor === '#000000' ? '#000000' : '#ffffff' + } + if (backgroundColor) { + navigationBar.backgroundColor = backgroundColor + } + navigationBar.duration = duration + 'ms' + navigationBar.timingFunc = timingFunc + // TODO + // UniServiceJSBridge.emit('onNavigationBarChange', { + // textColor: frontColor === '#000000' ? '#000' : '#fff', + // backgroundColor: navigationBar.backgroundColor, + // }) + break + case API_SHOW_NAVIGATION_BAR_LOADING: + navigationBar.loading = true + break + case API_HIDE_NAVIGATION_BAR_LOADING: + navigationBar.loading = false + break + case API_SET_NAVIGATION_BAR_TITLE: + const { title } = args + navigationBar.titleText = title + if (__NODE_JS__) { + // watch 无效,主动更新 title + updateDocumentTitle(args.title) + } + // TODO isCurrentPage逻辑主要是navigationBar组件使用 + // if (isCurrentPage(page)) { + // // 仅当前页面 + // document.title = title + // } + // TODO + // UniServiceJSBridge.emit('onNavigationBarChange', { + // titleText: title, + // }) + + break + } + resolve() +} + +export const setNavigationBarColor = + defineAsyncApi( + API_SET_NAVIGATION_BAR_COLOR, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_SET_NAVIGATION_BAR_COLOR, + args, + resolve, + reject + ) + }, + SetNavigationBarColorProtocol, + SetNavigationBarColorOptions + ) + +export const showNavigationBarLoading = + defineAsyncApi( + API_SHOW_NAVIGATION_BAR_LOADING, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_SHOW_NAVIGATION_BAR_LOADING, + args || {}, + resolve, + reject + ) + } + ) + +export const hideNavigationBarLoading = + defineAsyncApi( + API_HIDE_NAVIGATION_BAR_LOADING, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_HIDE_NAVIGATION_BAR_LOADING, + args || {}, + resolve, + reject + ) + } + ) + +export const setNavigationBarTitle = + defineAsyncApi( + API_SET_NAVIGATION_BAR_TITLE, + (args, { resolve, reject }) => { + setNavigationBar( + getCurrentPageMeta(), + API_SET_NAVIGATION_BAR_TITLE, + args, + resolve, + reject + ) + }, + SetNavigationBarTitleProtocol + ) diff --git a/packages/uni-mp-weibo/src/service/api/ui/pageScrollTo.ts b/packages/uni-mp-weibo/src/service/api/ui/pageScrollTo.ts new file mode 100644 index 00000000000..1c1019f40fd --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/pageScrollTo.ts @@ -0,0 +1,18 @@ +import { + API_PAGE_SCROLL_TO, + API_TYPE_PAGE_SCROLL_TO, + defineAsyncApi, + PageScrollToOptions, + PageScrollToProtocol, +} from '@dcloudio/uni-api' +import { scrollTo } from '@dcloudio/uni-shared' + +export const pageScrollTo = defineAsyncApi( + API_PAGE_SCROLL_TO, + ({ scrollTop, selector, duration }, { resolve }) => { + scrollTo(selector! || scrollTop! || 0, duration!, true) + resolve() + }, + PageScrollToProtocol, + PageScrollToOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/ui/popup.ts b/packages/uni-mp-weibo/src/service/api/ui/popup.ts new file mode 100644 index 00000000000..862280f8260 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/popup.ts @@ -0,0 +1,56 @@ +import { + defineAsyncApi, + API_TYPE_SHOW_MODAL, + API_SHOW_MODAL, + ShowModalProtocol, + ShowModalOptions, + API_TYPE_SHOW_TOAST, + API_SHOW_TOAST, + ShowToastProtocol, + ShowToastOptions, + API_TYPE_HIDE_TOAST, + API_HIDE_TOAST, + API_HIDE_LOADING, + API_SHOW_ACTION_SHEET, + API_SHOW_LOADING, + API_TYPE_HIDE_LOADING, + API_TYPE_SHOW_ACTION_SHEET, + API_TYPE_SHOW_LOADING, + ShowActionSheetOptions, + ShowActionSheetProtocol, + ShowLoadingOptions, + ShowLoadingProtocol, +} from '@dcloudio/uni-api' + +export const showModal = defineAsyncApi( + API_SHOW_MODAL, + () => {}, + ShowModalProtocol, + ShowModalOptions +) +export const showToast = defineAsyncApi( + API_SHOW_TOAST, + () => {}, + ShowToastProtocol, + ShowToastOptions +) +export const hideToast = defineAsyncApi( + API_HIDE_TOAST, + () => {} +) +export const showLoading = defineAsyncApi( + API_SHOW_LOADING, + () => {}, + ShowLoadingProtocol, + ShowLoadingOptions +) +export const hideLoading = defineAsyncApi( + API_HIDE_LOADING, + () => {} +) +export const showActionSheet = defineAsyncApi( + API_SHOW_ACTION_SHEET, + () => {}, + ShowActionSheetProtocol, + ShowActionSheetOptions +) diff --git a/packages/uni-mp-weibo/src/service/api/ui/popup/actionSheet.tsx b/packages/uni-mp-weibo/src/service/api/ui/popup/actionSheet.tsx new file mode 100644 index 00000000000..9ea53a938a8 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/popup/actionSheet.tsx @@ -0,0 +1,347 @@ +import { + defineComponent, + ExtractPropTypes, + onMounted, + Ref, + ref, + SetupContext, + watch, + watchEffect, + nextTick, + Transition, + reactive, +} from 'vue' +import { usePopupStyle } from '../../../../helpers/usePopupStyle' +import { useKeyboard } from '../../../../helpers/useKeyboard' +import { + onThemeChange, + offThemeChange, + getTheme, +} from '../../../../helpers/theme' +import { initI18nShowActionSheetMsgsOnce, useI18n } from '@dcloudio/uni-core' +import { useTouchtrack } from '@dcloudio/uni-components' +import { + useScroller, + Friction, + Spring, + Scroller, + initScrollBounce, + disableScrollBounce, +} from '@dcloudio/uni-components' +import { onEventPrevent } from '@dcloudio/uni-core' + +type ActionSheetTheme = { + listItemColor: string + cancelItemColor: string +} + +const ACTION_SHEET_THEME: Record = { + light: { + listItemColor: '#000000', + cancelItemColor: '#000000', + }, + dark: { + listItemColor: 'rgba(255, 255, 255, 0.8)', + cancelItemColor: 'rgba(255, 255, 255)', + }, +} + +function setActionSheetTheme( + theme: UniApp.ThemeMode, + actionSheetTheme: ActionSheetTheme +) { + const ActionSheetThemeKey: Array = [ + 'listItemColor', + 'cancelItemColor', + ] + ActionSheetThemeKey.forEach((key) => { + actionSheetTheme[key] = ACTION_SHEET_THEME[theme][key] + }) +} + +const props = { + title: { + type: String, + default: '', + }, + itemList: { + type: Array, + default() { + return [] + }, + }, + itemColor: { + type: String, + default: '#000000', + }, + popover: { + type: Object, + default: null, + }, + visible: { + type: Boolean, + default: false, + }, +} + +export type Props = ExtractPropTypes + +export default /*#__PURE__*/ defineComponent({ + name: 'ActionSheet', + props, + emits: ['close'], + setup(props, { emit }) { + initI18nShowActionSheetMsgsOnce() + const HEIGHT = ref(260) + const contentHeight = ref(0) + const titleHeight = ref(0) + const deltaY = ref(0) + const scrollTop = ref(0) + + const content: Ref = ref(null) + const main: Ref = ref(null) + const { t } = useI18n() + const { _close } = useActionSheetLoader(props, emit as SetupContext['emit']) + const { popupStyle } = usePopupStyle(props) + + let scroller: Scroller + + onMounted(() => { + const { + scroller: _scroller, + handleTouchStart, + handleTouchMove, + handleTouchEnd, + } = useScroller(content.value!, { + enableY: true, + friction: new Friction(0.0001), + spring: new Spring(2, 90, 20), + onScroll: (e) => { + scrollTop.value = e.target.scrollTop + }, + }) + + scroller = _scroller + + // 模拟滚动使用 + useTouchtrack( + content.value!, + (e) => { + if (_scroller) { + switch (e.detail.state) { + case 'start': + handleTouchStart(e) + disableScrollBounce({ + disable: true, + }) + break + case 'move': + handleTouchMove(e) + break + case 'end': + case 'cancel': + handleTouchEnd(e) + disableScrollBounce({ + disable: false, + }) + } + } + }, + true + ) + + initScrollBounce() + }) + + function _handleWheel($event: WheelEvent) { + const _deltaY = deltaY.value + $event.deltaY + if (Math.abs(_deltaY) > 10) { + scrollTop.value += _deltaY / 3 + scrollTop.value = + scrollTop.value >= contentHeight.value + ? contentHeight.value + : scrollTop.value <= 0 + ? 0 + : scrollTop.value + scroller.scrollTo(scrollTop.value) + } else { + deltaY.value = _deltaY + } + $event.preventDefault() + } + + watch( + () => props.visible, + () => { + nextTick(() => { + // title 占位 + if (props.title) { + titleHeight.value = ( + document.querySelector('.uni-actionsheet__title') as HTMLElement + ).offsetHeight + } + // 滚动条更新 + scroller.update() + // 获取contentHeight 滚动时使用 + if (content.value) + contentHeight.value = content.value.clientHeight - HEIGHT.value + // 给每一个项添加点击事件 + document + .querySelectorAll('.uni-actionsheet__cell') + .forEach((item) => { + initClick(item as HTMLElement) + }) + }) + } + ) + + const actionSheetTheme = useOnThemeChange(props) + + return () => { + return ( + + +
    _close(-1)} + /> + +
    +
    + {/* title占位 */} + {props.title ? ( + <> +
    +
    {props.title}
    + + ) : ( + '' + )} +
    +
    + {props.itemList.map((itemTitle, index) => ( +
    _close(index)} + > + {itemTitle} +
    + ))} +
    +
    +
    +
    +
    _close(-1)} + > + {t('uni.showActionSheet.cancel')} +
    +
    +
    +
    + + ) + } + }, +}) + +function useActionSheetLoader(props: Props, emit: SetupContext['emit']) { + function _close(tapIndex: number) { + emit('close', tapIndex) + } + + const { key, disable } = useKeyboard() + watch( + () => props.visible, + (value) => (disable.value = !value) + ) + watchEffect(() => { + const { value } = key + if (value === 'esc') { + _close && _close(-1) + } + }) + + return { + _close, + } +} + +// 由于模拟滚动阻止了点击,使用自定义事件来触发点击事件 +function initClick(dom: HTMLElement) { + const MAX_MOVE = 20 + let x = 0 + let y = 0 + dom.addEventListener('touchstart', (event) => { + const info = event.changedTouches[0] + x = info.clientX + y = info.clientY + }) + dom.addEventListener('touchend', (event) => { + const info = event.changedTouches[0] + if ( + Math.abs(info.clientX - x) < MAX_MOVE && + Math.abs(info.clientY - y) < MAX_MOVE + ) { + const target = event.target as HTMLElement + const currentTarget = event.currentTarget as HTMLElement + const customEvent = new CustomEvent('click', { + bubbles: true, + cancelable: true, + target, + currentTarget, + } as any) + ;['screenX', 'screenY', 'clientX', 'clientY', 'pageX', 'pageY'].forEach( + (key) => { + ;(customEvent as any)[key] = (info as any)[key] + } + ) + event.target!.dispatchEvent(customEvent) + } + }) +} + +function useOnThemeChange(props: Props) { + const actionSheetTheme = reactive({ + listItemColor: '#000', + cancelItemColor: '#000', + }) + const _onThemeChange = ({ theme }: { theme: UniApp.ThemeMode }) => { + setActionSheetTheme(theme, actionSheetTheme) + } + + watchEffect(() => { + if (props.visible) { + actionSheetTheme.listItemColor = actionSheetTheme.cancelItemColor = + props.itemColor + // #000 by default in protocols + if (props.itemColor === '#000') { + _onThemeChange({ theme: getTheme() }) + onThemeChange(_onThemeChange) + } + } else { + offThemeChange(_onThemeChange) + } + }) + + return actionSheetTheme +} diff --git a/packages/uni-mp-weibo/src/service/api/ui/popup/modal.tsx b/packages/uni-mp-weibo/src/service/api/ui/popup/modal.tsx new file mode 100644 index 00000000000..468c68385e1 --- /dev/null +++ b/packages/uni-mp-weibo/src/service/api/ui/popup/modal.tsx @@ -0,0 +1,175 @@ +import { onEventPrevent, onEventStop } from '@dcloudio/uni-core' +import { + Transition, + defineComponent, + ExtractPropTypes, + ref, + Ref, + watchEffect, +} from 'vue' +import { usePopup, VNODE_MASK } from './utils' +import { + onThemeChange, + offThemeChange, + getTheme, +} from '../../../../helpers/theme' + +type ModalTheme = Record +const ModalTheme: ModalTheme = { + light: { + cancelColor: '#000000', + }, + dark: { + cancelColor: 'rgb(170, 170, 170)', + }, +} +const setCancelColor = (theme: UniApp.ThemeMode, cancelColor: Ref) => + (cancelColor.value = ModalTheme[theme].cancelColor) + +const props = { + title: { + type: String, + default: '', + }, + content: { + type: String, + default: '', + }, + showCancel: { + type: Boolean, + default: true, + }, + cancelText: { + type: String, + default: 'Cancel', + }, + cancelColor: { + type: String, + default: '#000000', + }, + confirmText: { + type: String, + default: 'OK', + }, + confirmColor: { + type: String, + default: '#007aff', + }, + visible: { + type: Boolean, + }, + editable: { + type: Boolean, + default: false, + }, + placeholderText: { + type: String, + default: '', + }, +} +export type ModalProps = ExtractPropTypes + +export default /*#__PURE__*/ defineComponent({ + props, + setup(props, { emit }) { + const editContent = ref('') + const close = () => (visible.value = false) + const cancel = () => (close(), emit('close', 'cancel')) + const confirm = () => (close(), emit('close', 'confirm', editContent.value)) + const visible = usePopup(props, { + onEsc: cancel, + onEnter: () => { + !props.editable && confirm() + }, + }) + + const cancelColor = useOnThemeChange(props) + + return () => { + const { + title, + content, + showCancel, + confirmText, + confirmColor, + editable, + placeholderText, + } = props + editContent.value = content + // TODO vue3 似乎有bug,不指定passive时,应该默认加上passive:false,否则浏览器会报警告,先看看vue3 会不会修复,若不修复,可以考虑手动addEventListener + return ( + + + {VNODE_MASK} +
    + {title && ( +
    + +
    + )} + {editable ? ( +