Browse Source

签入代码

qmj 4 months ago
commit
deb66e7a54
100 changed files with 37224 additions and 0 deletions
  1. 16 0
      .gitignore
  2. 9 0
      AndroidManifest.xml
  3. 760 0
      App.vue
  4. 21 0
      LICENSE
  5. 15 0
      README.md
  6. BIN
      TrtcCloud/.DS_Store
  7. 736 0
      TrtcCloud/lib/TrtcCloudImpl.js
  8. 612 0
      TrtcCloud/lib/TrtcCode.js
  9. 484 0
      TrtcCloud/lib/TrtcDefines.js
  10. 10 0
      TrtcCloud/lib/constants.js
  11. 989 0
      TrtcCloud/lib/index.js
  12. 279 0
      TrtcCloud/permission.js
  13. 19 0
      TrtcCloud/view/TrtcLocalView.nvue
  14. 23 0
      TrtcCloud/view/TrtcRemoteView.nvue
  15. 36 0
      androidPrivacy.json
  16. 8 0
      changelog.md
  17. 30 0
      common/jsencrypt.js
  18. 120 0
      common/uni-ui.scss
  19. 403 0
      components/XQGeneratePoster.vue
  20. 167 0
      components/customNav/customNav.vue
  21. 67 0
      components/dachedengdai/dachedengdai.vue
  22. 207 0
      components/dachejiesuan/dachejiesuan.vue
  23. 123 0
      components/dachesijijied/dachesijijied.vue
  24. 114 0
      components/dachexingcheng/dachexingcheng.vue
  25. 192 0
      components/dachexuancx/dachexuancx.vue
  26. 250 0
      components/danxuanlist/danxuanlist.vue
  27. 241 0
      components/fenleiList/fenleiList - 副本.vue
  28. 137 0
      components/fenleiList/fenleiList.vue
  29. 148 0
      components/foodItem/foodItem.vue
  30. 253 0
      components/foodxuangou/foodxuangou.vue
  31. 78 0
      components/imageconver/imageconver.vue
  32. 548 0
      components/liupishui-pickerpolygons/liupishui-pickerpolygons.vue
  33. 1125 0
      components/liupishui-pickerpolygons/qqmap-wx-jssdk.js
  34. 77 0
      components/mapView/mapView.vue
  35. 56 0
      components/myImage/myImage.vue
  36. 77 0
      components/netImage/netImage.vue
  37. 238 0
      components/popViewGG/popViewGG.vue
  38. 46 0
      components/swiperImgs/swiperImgs.vue
  39. 78 0
      components/weizhimap/weizhimap - 副本.nvue
  40. 83 0
      components/weizhimap/weizhimap.nvue
  41. 974 0
      components/yhdsl-cropper/yhdsl-cropper.vue
  42. 110 0
      components/ysxyView/ysxyView.vue
  43. 28 0
      config/index.config.js
  44. BIN
      cteuser.keystore
  45. 5 0
      cteuser.txt
  46. 59 0
      debug/GenerateTestUserSig.js
  47. 1217 0
      debug/lib-generate-test-usersig-es.min.js
  48. 254 0
      hybrid/html/maps/css/index.css
  49. 1 0
      hybrid/html/maps/css/modules/code.css
  50. 0 0
      hybrid/html/maps/css/modules/laydate/default/laydate.css
  51. BIN
      hybrid/html/maps/css/modules/layer/default/icon-ext.png
  52. BIN
      hybrid/html/maps/css/modules/layer/default/icon.png
  53. 0 0
      hybrid/html/maps/css/modules/layer/default/layer.css
  54. BIN
      hybrid/html/maps/css/modules/layer/default/loading-0.gif
  55. BIN
      hybrid/html/maps/css/modules/layer/default/loading-1.gif
  56. BIN
      hybrid/html/maps/css/modules/layer/default/loading-2.gif
  57. 0 0
      hybrid/html/maps/css/slider.css
  58. 0 0
      hybrid/html/maps/css/vant.css
  59. BIN
      hybrid/html/maps/img/1.png
  60. BIN
      hybrid/html/maps/img/loading2.gif
  61. BIN
      hybrid/html/maps/img/positioning.png
  62. 5 0
      hybrid/html/maps/js/lib/VConsole.js
  63. 1104 0
      hybrid/html/maps/js/lib/city.js
  64. 747 0
      hybrid/html/maps/js/lib/city.json
  65. 92 0
      hybrid/html/maps/js/lib/common.js
  66. 1 0
      hybrid/html/maps/js/lib/jquery-3.2.1.min.js
  67. 26 0
      hybrid/html/maps/js/lib/rem.js
  68. 0 0
      hybrid/html/maps/js/lib/slider.js
  69. 17 0
      hybrid/html/maps/js/lib/toast.js
  70. 0 0
      hybrid/html/maps/js/lib/uniwebviewsdk.js
  71. 16810 0
      hybrid/html/maps/js/lib/vant.js
  72. 6 0
      hybrid/html/maps/js/lib/vue.js
  73. 468 0
      hybrid/html/maps/js/mapindex.js
  74. 39 0
      hybrid/html/maps/mapindex.html
  75. 404 0
      hybrid/html/voices/audio.html
  76. 74 0
      hybrid/html/voices/css/index.css
  77. 1 0
      hybrid/html/voices/css/modules/code.css
  78. 0 0
      hybrid/html/voices/css/modules/laydate/default/laydate.css
  79. BIN
      hybrid/html/voices/css/modules/layer/default/icon-ext.png
  80. BIN
      hybrid/html/voices/css/modules/layer/default/icon.png
  81. 0 0
      hybrid/html/voices/css/modules/layer/default/layer.css
  82. BIN
      hybrid/html/voices/css/modules/layer/default/loading-0.gif
  83. BIN
      hybrid/html/voices/css/modules/layer/default/loading-1.gif
  84. BIN
      hybrid/html/voices/css/modules/layer/default/loading-2.gif
  85. 0 0
      hybrid/html/voices/css/slider.css
  86. 0 0
      hybrid/html/voices/css/vant.css
  87. BIN
      hybrid/html/voices/img/guaduandd.png
  88. BIN
      hybrid/html/voices/img/jietong.png
  89. BIN
      hybrid/html/voices/img/loading2.gif
  90. BIN
      hybrid/html/voices/img/logo.png
  91. 254 0
      hybrid/html/voices/index.html
  92. 0 0
      hybrid/html/voices/js/lib/uniwebviewsdk.js
  93. 5649 0
      hybrid/html/xuanfu/css/mui.css
  94. 4 0
      hybrid/html/xuanfu/css/mui.min.css
  95. BIN
      hybrid/html/xuanfu/fonts/mui.ttf
  96. BIN
      hybrid/html/xuanfu/img/guaduandd.png
  97. BIN
      hybrid/html/xuanfu/img/jietong.png
  98. BIN
      hybrid/html/xuanfu/img/logo.png
  99. BIN
      hybrid/html/xuanfu/img/xinxi.png
  100. BIN
      hybrid/html/xuanfu/img/y800.mp3

+ 16 - 0
.gitignore

@@ -0,0 +1,16 @@
+######################################################################
+# Build Tools
+
+/unpackage/*
+/node_modules/*
+
+######################################################################
+# Development Tools
+
+/.idea/*
+/.vscode/*
+/.hbuilderx/*
+
+package-lock.json
+yarn.lock
+

+ 9 - 0
AndroidManifest.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>  
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"   
+  package="vn.com.cityexpress168.ptyh">  
+    <!--按下面方式配置需要移除的permissions-->  
+	<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" tools:node="remove"/>
+    <application>  
+        <!--meta-data-->  
+    </application>  
+</manifest>

+ 760 - 0
App.vue

@@ -0,0 +1,760 @@
+<script>
+	//com.vi1688cityexpress.user
+	// const toast = uni.requireNativePlugin('Ba-Toast'); //android
+	// const callerID = uni.requireNativePlugin('Ba-CallerID'); //android
+	// const KJPip = uni.requireNativePlugin('KJ-Pip'); //ios
+	import api from "@/pages/api/api.js"
+	export default {
+		data() {
+			return {
+				isAndroid: false,
+				androidflType: 0,
+				isInback: false,
+				isfirst: true,
+				audioObj: null,
+			}
+		},
+		globalData: {
+			_i18n: {},
+			$t: {},
+			sj: {},
+			iosfl: {},
+			baseImagurl: 'https://api.cityexpress168.com.vn', //生产环境
+			// baseImagurl:'https://api.amazeway.com.cn',//预发布
+			token: '',
+			imViewOpen: false,
+			EXViewOpen: false,
+			goEasy: null,
+			goEasycnt: false,
+			initgoEasy: {}
+		},
+		onLaunch: function() {
+			console.log('App Launch')
+			this.globalData._i18n = this.$i18n;
+			this.globalData.$t = str => this.$t(str);
+			this.globalData.sj = str => this.getTimestr();
+			this.globalData.iosfl = index => this.showpiaof(index);
+			this.globalData.token = uni.getStorageSync("token");
+			this.globalData.imViewOpen = false;
+			this.globalData.EXViewOpen = false;
+			this.globalData.goEasy = this.goEasy;
+			this.globalData.initgoEasy = str => this.connectGoEasy();
+			let systemInfo = uni.getSystemInfoSync();
+			this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
+
+			var language = uni.getStorageSync('language');
+			console.log('123', language)
+			console.log(language)
+			if ('' == language || null == language || undefined == language) {
+				uni.setStorageSync('language', "yuenan");
+				uni.setLocale('yuenan');
+				if (!this.isAndroid) {
+					this.$i18n.locale = 'yuenan';
+				}
+				this.uploadLanguagesSet('yuenan');
+			} else {
+				uni.setLocale(language);
+				if (!this.isAndroid) {
+					this.$i18n.locale = language;
+				}
+				this.uploadLanguagesSet(language);
+			}
+			// this.connectGoEasy();
+
+			uni.setStorageSync('userAddrLocation', "");
+			// uni.onPushMessage((res) => {
+			// 	console.log("收到推送消息:", res) //监听推送消息
+			// 	var payload = res.data.payload;
+			// 	if (payload.indexOf("rcuser") != -1) {
+			// 		this.updataxiaoxi(payload);
+			// 	}
+			// 	if (res.type == 'click') {
+			// 		var content = res.data.title;
+			// 		plus.runtime.setBadgeNumber(0);
+			// 		// if(content.indexOf("Call")!=-1){
+			// 		// 	if(this.globalData.imViewOpen){
+			// 		// 		return;
+			// 		// 	}
+			// 		// 	uni.setStorageSync('impayload',res.data.payload);
+			// 		// 	this.imcallrecive(res.data.payload);
+			// 		// 	return
+			// 		// }
+			// 		// if(content.indexOf("message")!=-1){
+			// 		// 	if(this.globalData.EXViewOpen){
+			// 		// 		return;
+			// 		// 	}
+			// 		// 	uni.setStorageSync('impayload',res.data.payload);
+			// 		// 	this.immessagerecive(res.data.payload);
+			// 		// 	return
+			// 		// }
+
+			// 		setTimeout(function() {
+			// 			// 这里写要延时执行的代码
+			// 			uni.switchTab({
+			// 				url: '/pages/OrderList/OrderList'
+			// 			})
+			// 		}, 1500);
+			// 		return;
+			// 	}
+			// 	if (res.type == 'receive') {
+			// 		plus.runtime.setBadgeNumber(0);
+			// 		var content = res.data.title;
+			// 		// if(content.indexOf("Call")!=-1){
+			// 		// 	if(this.globalData.imViewOpen){
+			// 		// 		return;
+			// 		// 	}
+			// 		// 	uni.setStorageSync('impayload',res.data.payload);
+			// 		// 	this.imcallrecive(res.data.payload);
+			// 		// 	return
+			// 		// }
+			// 		// if(content.indexOf("message")!=-1){
+			// 		// 	if(this.globalData.EXViewOpen){
+			// 		// 		return;
+			// 		// 	}
+			// 		// 	uni.setStorageSync('impayload',res.data.payload);
+			// 		// 	this.immessagerecive(res.data.payload);
+			// 		// 	return
+			// 		// }
+			// 		content = res.data.content;
+			// 		if (content.indexOf("骑手定位") != -1) {
+			// 			plus.runtime.setBadgeNumber(0);
+			// 			return;
+			// 		}
+			// 		uni.createPushMessage({
+			// 			content: res.data.content,
+			// 			success: (res) => {
+			// 				console.log(res);
+			// 			},
+			// 			fail(er) {}
+			// 		});
+			// 	}
+			// });
+			//-----------------------------------
+			var that = this;
+			//android---------------------------------------------
+			that.audioObj = uni.createInnerAudioContext();
+			that.audioObj.src = 'static/y800.mp3';
+			// var globalEvent = uni.requireNativePlugin('globalEvent');
+			// globalEvent.addEventListener('baCallerIdEvent', function(e) {
+			// 	console.log('baCallerIdEvent:' + JSON.stringify(e));
+			// 	console.log(e);
+			// 	if (e.tag == 'call' && e.action == 'onClick') {
+			// 		if (that.isInback) {
+			// 			plus.runtime.launchApplication({
+			// 				pname: 'com.vi1688cityexpress.user'
+			// 			});
+			// 		}
+
+			// 		if (that.androidflType == 1) {
+			// 			uni.navigateTo({
+			// 				url: '/pages/imcall/audioCall?iscaller=0'
+			// 			})
+			// 		} else if (that.androidflType == 2) {
+			// 			uni.navigateTo({
+			// 				url: '/pages/imcall/GoeasyExchange?iscaller=0'
+			// 			})
+			// 		}
+			// 		that.audioObj.pause();
+			// 		that.hideFW();
+			// 	}
+			// 	if (e.tag == 'uncall' && e.action == 'onClick') {
+			// 		that.audioObj.pause();
+			// 		that.hideFW();
+			// 	}
+			// });
+			// //ios-------------------------------------------------------------
+			// globalEvent.addEventListener('onPip', function(res) {
+			// 	console.log("onPip:" + JSON.stringify(res));
+			// 	if (res.method == "willStartPip") {
+			// 		console.log("即将开启画中画");
+			// 	} else if (res.method == "didStartPip") {
+			// 		console.log("已经开启画中画");
+			// 	} else if (res.method == "failedStartPip") {
+			// 		console.log("开启画中画失败");
+			// 	} else if (res.method == "willStopPip") {
+			// 		console.log("即将关闭画中画");
+			// 		//that.imdef();
+			// 	} else if (res.method == "didStopPip") {
+			// 		console.log("已经关闭画中画");
+
+			// 	} else if (res.method == "restorePip") {
+			// 		console.log("恢复");
+			// 	}
+			// });
+			// globalEvent.addEventListener('onWebview', function(res) {
+			// 	console.log("onWebview:" + JSON.stringify(res));
+			// 	if (res.method == "finish") {
+			// 		console.log("页面加载完成");
+			// 	} else if (res.method == "fail") {
+			// 		console.log("加载失败");
+			// 	}
+			// });
+			// if (!this.isAndroid) {
+			// 	this.onH5SendDataCallBack();
+			// }
+		},
+		onShow: function() {
+			console.log('App Show')
+			if (!this.isAndroid) {
+				//this.closePip();
+			}
+			this.isInback = false;
+			this.initflaotView();
+		},
+		onHide: function() {
+			console.log('App Hide')
+			this.isInback = true;
+		},
+
+		methods: {
+			getTimestr() {
+				var time = new Date();
+				var n, y, r, h, m, s;
+				n = time.getFullYear();
+				y = time.getMonth() + 1;
+				r = time.getDate();
+				h = time.getHours();
+				m = time.getMinutes();
+				s = time.getSeconds();
+				var timsStr = n + '-' + y + '-' + r + ' ' + h + ':' + m + ':' + s;
+				return timsStr;
+			},
+			async uploadLanguagesSet(lang) {
+				var userId = uni.getStorageSync('userId');
+				if (!userId) {
+					userId = 0
+				}
+				if (lang == 'yuenan') {
+					lang = 'vi';
+				}
+				if (lang == 'zh-Hans') {
+					lang = 'zh-CN';
+				}
+				if (lang == 'zh-Hant') {
+					lang = 'zh-TW';
+				}
+				console.log("changeLanguages");
+				api('changeLanguages', {
+					lang: lang,
+					id: userId
+				}, res => {
+					console.log('changeLanguages', res)
+				}, failc => {
+					//console.log('getadvertis----',failc)
+				})
+			},
+			updataxiaoxi(str) {
+				var xiaoxiList = uni.getStorageSync('dachexiaoxi');
+				if ('' == xiaoxiList || null == xiaoxiList || undefined == xiaoxiList) {
+					xiaoxiList = [];
+				}
+				xiaoxiList.push(str);
+				uni.setStorageSync('dachexiaoxi', xiaoxiList);
+			},
+
+			//imcall&&immessage------------------------------------------------
+			initflaotView() {
+				if (this.isAndroid) {
+					if (this.isfirst) {
+						this.isPermissionFW();
+						this.isfirst = false
+					}
+				} else { //ios
+					//this.initPip("landscape");
+				}
+			},
+			imcallrecive(str) {
+
+				if (str.indexOf("\\\"") != -1) {
+					str = str.replace(/\\\"/g, '\"');
+					str = str.replace(/\"{/g, '{');
+					str = str.replace(/}\"/g, '}');
+				}
+				var obj = JSON.parse(str)
+				console.log('imcallrecive', obj)
+				if (this.isAndroid) {
+					if (this.androidflType != 0) {
+						return;
+					}
+					var uobj = {
+						name: obj.nickName,
+						content: this.$t('audioCall.cteyhcall'),
+						call: this.$t('audioCall.jietingyy'),
+						uncall: this.$t('audioCall.jujuejieting')
+					}
+					this.androidflType = 1;
+					this.showFW(uobj, false);
+					this.audioObj.play();
+				} else { //ios
+					this.imCall();
+				}
+			},
+			immessagerecive(str) {
+				if (str.indexOf("\\\"") != -1) {
+					str = str.replace(/\\\"/g, '\"');
+					str = str.replace(/\"{/g, '{');
+					str = str.replace(/}\"/g, '}');
+				}
+				var obj = JSON.parse(str);
+				if (this.isAndroid) {
+					if (this.androidflType != 0) {
+						return;
+					}
+					var uobj = {
+						name: obj.nickName,
+						content: this.$t('exchange.cteyhmsg'),
+						call: this.$t('exchange.chakanxinxi'),
+						uncall: this.$t('exchange.quxiao')
+					}
+					this.androidflType = 2;
+					this.showFW(uobj, false);
+					this.audioObj.play();
+				} else { //ios
+					this.imMessage();
+				}
+			},
+			//android-------------------------------------------------
+			showFW(obj, isInit) { //显示
+				var that = this;
+				callerID.show({
+						gravity: 1, //显示位置:0中间 1上 2下
+						name: obj.name, //用户昵称 ,
+						content: obj.content, //说明是骑手来电、来信息
+						call: obj.call, //接听IM,查看IM信息
+						uncall: obj.uncall, //拒绝接听IM,拒绝查看IM信息
+						empty: "",
+						avatar: "/static/logo.png",
+						totalHint: "",
+						tel: "",
+						list: []
+					},
+					(res) => {
+						console.log(res);
+						if (isInit) {
+							that.hideFW()
+						}
+						// uni.showToast({
+						// 	title: res.msg,
+						// 	icon: "none",
+						// 	duration: 3000
+						// })
+					});
+			},
+			hideFW() { //隐藏
+				this.androidflType = 0;
+				callerID.hide(
+					(res) => {
+						console.log(res);
+						// uni.showToast({
+						// 	title: res.msg,
+						// 	icon: "none",
+						// 	duration: 3000
+						// })
+					});
+			},
+			permissionFW() { //申请悬浮窗权限
+				callerID.permission(
+					(res) => {
+						console.log('permissionFW', res);
+					});
+			},
+			goPermissionFW() { //跳转到悬浮窗权限页面
+				callerID.goPermission(
+					(res) => {
+						console.log('goPermissionFW', res);
+					});
+			},
+			isPermissionFW() { //是否申请悬浮窗权限
+				var that = this;
+				callerID.isPermission(
+					(res) => {
+						console.log('是否申请悬浮窗权限', res);
+						if (res.data) {
+							if (res.data.isPermission) {
+								var uobj = {
+									name: 'CTE',
+									content: '',
+									call: '',
+									uncall: ''
+								}
+								that.showFW(uobj, true);
+							} else {
+								that.goPermissionFW();
+							}
+						}
+					});
+			},
+			//ios--------------------------------------
+			showpiaof(index) {
+
+				var that = this;
+				if (index == 1) {
+					setTimeout(function() {
+						// 这里写要延时执行的代码
+						that.initPip("landscape");
+					}, 800);
+				}
+				if (index == 2) {
+					that.closePip();
+				}
+				if (index == 3) {
+					var language = uni.getStorageSync('language');
+					if (language == 'yuenan') {
+						var dic = {
+							"js": "changeImgvi()"
+						}
+						KJPip.webView_evaluateJavaScript(dic, (res) => {
+							console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+						})
+					} else {
+						var dic = {
+							"js": "changeImg()"
+						}
+						KJPip.webView_evaluateJavaScript(dic, (res) => {
+							console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+						})
+					}
+				}
+				if (index == 4) {
+					var language = uni.getStorageSync('language');
+					if (language == 'yuenan') {
+						var dic = {
+							"js": "changeImgMSvi()"
+						}
+						KJPip.webView_evaluateJavaScript(dic, (res) => {
+							console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+						})
+					} else {
+						var dic = {
+							"js": "changeImgMS()"
+						}
+						KJPip.webView_evaluateJavaScript(dic, (res) => {
+							console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+						})
+					}
+				}
+				return '';
+			},
+			initPip(shape) {
+				var dic = {
+					"shape": shape, //弹窗形状 square(正方形) landscape(横向) portrait(竖向)
+				}
+				KJPip.initPip(dic)
+
+				console.log('initPip')
+				var that = this;
+				that.iosInit = true;
+				setTimeout(function() {
+					// 这里写要延时执行的代码
+					that.openPip1();
+				}, 2000);
+			},
+			openPip1() { //打开,加载本地页面?language='+language
+				var language = uni.getStorageSync('language');
+				this.openPip(plus.io.convertLocalFileSystemURL("hybrid/html/xuanfu/index.html"));
+			},
+			openPip(url) {
+				var that = this;
+				KJPip.isPictureInPictureActive((res) => {
+					console.log("isPictureInPictureActive:" + JSON.stringify(res));
+				})
+				KJPip.isPictureInPictureSuspended((res) => {
+					console.log("isPictureInPictureSuspended:" + JSON.stringify(res));
+				})
+				KJPip.isPictureInPicturePossible((res) => {
+					console.log("isPictureInPicturePossible:" + JSON.stringify(res));
+					// if(!res.result){
+					// 	setTimeout(function() {
+					// 	  // 这里写要延时执行的代码
+					// 	  //that.initPip("landscape");
+					// 	}, 800);
+					// }
+				})
+				KJPip.isPictureInPictureSupported((res) => {
+					console.log("isPictureInPictureSupported:" + JSON.stringify(res));
+				})
+				var dic = {
+					"url": url
+				}
+				KJPip.openPip(dic, (res) => {
+					console.log("openPip:" + JSON.stringify(res));
+				})
+			},
+			closePip() { //关闭弹窗
+				KJPip.closePip()
+			},
+
+			imCall() { //收到IM语音通话请求
+
+				uni.navigateTo({
+					url: '/pages/imcall/audioCall?iscaller=0'
+				})
+
+			},
+
+			imMessage() { //收到im文字聊天请求
+
+				uni.navigateTo({
+					url: '/pages/imcall/GoeasyExchange?iscaller=0'
+				})
+
+			},
+
+			imdef() { //收到im文字聊天请求
+				var dic = {
+					"js": "changeImgdef()"
+				}
+				KJPip.webView_evaluateJavaScript(dic, (res) => {
+					console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+				})
+			},
+
+			onH5SendDataCallBack() { //注意ios16之后,弹出里的内容不能点击
+				var that = this;
+				KJPip.onH5SendDataCallBack((res) => {
+					console.log("onH5SendDataCallBack:", res);
+				})
+			},
+			//GoEasy--------------------------------------------
+			connectGoEasy() {
+				var that = this;
+				if (that.globalData.goEasycnt == true) {
+					that.goeasydisconnect();
+					return;
+				}
+				var userInfo = uni.getStorageSync('userInfo');
+				if ('' == userInfo || null == userInfo || undefined == userInfo) {
+					return;
+				}
+				console.log(userInfo);
+				this.goEasy.connect({
+					id: 'userid_' + userInfo.userId,
+					data: {
+						name: userInfo.nickName,
+						avatar: userInfo.avatar
+					},
+					onSuccess: () => {
+						console.log('GoEasy connect successfully.')
+						that.goEasyPush();
+						that.globalData.goEasycnt = true;
+					},
+					onFailed: (error) => {
+						console.log('Failed to connect GoEasy, code:' + error.code + ',error:' + error
+							.content);
+					},
+					onProgress: (attempts) => {
+						console.log('GoEasy is connecting', attempts);
+					}
+				});
+			},
+			goEasyPush() {
+				var userInfo = uni.getStorageSync('userInfo');
+				if ('' == userInfo || null == userInfo || undefined == userInfo) {
+					return;
+				}
+				//console.log(userInfo);
+				var that = this;
+				var pubsub = this.goEasy.pubsub;
+				pubsub.subscribe({
+					channel: 'userid_' + userInfo.userId,
+					onMessage: function(message) {
+						console.log("goEasyPush:", message);
+						var obj = JSON.parse(message.content);
+						if (obj.ptype == 1) {
+							if (that.globalData.imViewOpen) {
+								return;
+							}
+							uni.setStorageSync('impayload', message.content);
+							that.imcallrecive(message.content);
+						}
+						if (obj.ptype == 2) {
+							if (that.globalData.EXViewOpen) {
+								return;
+							}
+							uni.setStorageSync('impayload', message.content);
+							that.immessagerecive(message.content);
+						}
+					},
+					onSuccess: function() {
+						console.log("Subscribe successfully.")
+					},
+					onFailed: function() {
+						console.log("Subscribe onFailed.")
+					}
+
+				});
+			},
+			//断开连接
+			goeasydisconnect() {
+				var that = this;
+				this.goEasy.disconnect({
+					onSuccess: function() {
+						console.log("GoEasy disconnect successfully.")
+						that.globalData.goEasycnt = false;
+						that.connectGoEasy();
+					},
+					onFailed: function(error) {
+						console.log("Failed to disconnect GoEasy, code:" + error.code + ",error:" + error
+							.content);
+					}
+				});
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+	@font-face {
+		font-family: zrht;
+		src: url('/uni_modules/font/zrht.otf');
+	}
+
+	.container {
+		padding: 15px;
+	}
+
+	/*
+  button {
+    margin-bottom: 15px;
+  }
+  */
+	.ztextfontB1 {
+		font-size: 36rpx;
+		font-weight: bold;
+	}
+
+	.ztextfontB2 {
+		font-size: 34rpx;
+		font-weight: bold;
+	}
+
+	.ztextfontB3 {
+		font-size: 32rpx;
+		font-weight: bold;
+	}
+
+	.ztextfontB4 {
+		font-size: 30rpx;
+		font-weight: bold;
+	}
+
+	.ztextfontB5 {
+		font-size: 28rpx;
+		font-weight: bold;
+	}
+
+	.ztextfontS1 {
+		font-size: 26rpx;
+		font-weight: bold;
+	}
+
+	.ztextfontS2 {
+		font-size: 24rpx;
+		font-weight: bold;
+	}
+
+	.ztextfontS3 {
+		font-size: 22rpx;
+		font-weight: bold;
+	}
+
+	.textfontB1 {
+		font-size: 36rpx;
+	}
+
+	.textfontB2 {
+		font-size: 34rpx;
+	}
+
+	.textfontB3 {
+		font-size: 32rpx;
+	}
+
+	.textfontB4 {
+		font-size: 30rpx;
+	}
+
+	.textfontB5 {
+		font-size: 28rpx;
+	}
+
+	.textfontS1 {
+		font-size: 26rpx;
+	}
+
+	.textfontS2 {
+		font-size: 24rpx;
+	}
+
+	.textfontS3 {
+		font-size: 22rpx;
+	}
+
+	.content {
+		display: flex;
+		flex-direction: column;
+		width: 94%;
+		margin-left: 3%;
+		background-color: white;
+		border-radius: 16rpx;
+		box-shadow: 0rpx 0rpx 10rpx 0rpx lightgray;
+	}
+
+	.contentInRowL {
+		display: flex;
+		flex-direction: row;
+		justify-content: flex-start;
+	}
+
+	.contentInRowC {
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.contentInRowR {
+		display: flex;
+		flex-direction: row;
+		justify-content: flex-end;
+	}
+
+	.contentInRowS {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.contentColumn {
+		display: flex;
+		flex-direction: column;
+	}
+
+	.contentColumnC {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.text1row {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		/* #ifndef APP-PLUS-NVUE */
+		display: -webkit-box;
+		-webkit-line-clamp: 1;
+		-webkit-box-orient: vertical;
+		/* #endif */
+	}
+
+	.text2row {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		/* #ifndef APP-PLUS-NVUE */
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+		/* #endif */
+	}
+</style>

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 DCloud
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 15 - 0
README.md

@@ -0,0 +1,15 @@
+# hello-i18n
+
+# en
+
+A demo project for uni-app globalization
+
+This template include uni-framework, manifest.json, pages.json, tabbar, Page, Component, API
+
+
+# zh-hans
+
+uni-app 国际化演示
+
+包含 uni-framework、manifest.json、pages.json、tabbar、页面、组件、API
+

BIN
TrtcCloud/.DS_Store


+ 736 - 0
TrtcCloud/lib/TrtcCloudImpl.js

@@ -0,0 +1,736 @@
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+    return new (P || (P = Promise))(function (resolve, reject) {
+        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+        step((generator = generator.apply(thisArg, _arguments || [])).next());
+    });
+};
+import { NAME } from './constants';
+import { TRTCRoleType, TRTCAudioQuality, TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType, TRTCVideoStreamType, TRTCVideoEncParam, TRTCAppScene, TRTCAudioRoute, TRTCBeautyStyle, } from './TrtcDefines';
+import TrtcError, { TXLiteJSError, generateError_ } from './TrtcCode';
+const TrtcNativeTrtcCloudModule = uni.requireNativePlugin('TRTCCloudUniPlugin-TRTCCloudImpl');
+const TXAudioEffectManagerModule = uni.requireNativePlugin('TRTCCloudUniPlugin-TRTCCloudImpl-TXAudioEffectManagerModule');
+const TrtcEvent = uni.requireNativePlugin('globalEvent');
+let trtcCloud = null; // trtcCloud 单例
+export default class TrtcCloudImpl {
+    constructor() {
+        this.listenersMap_ = new Map();
+    }
+    static _createInstance() {
+        try {
+            if (trtcCloud) {
+                return trtcCloud;
+            }
+            TrtcNativeTrtcCloudModule.sharedInstance();
+            trtcCloud = new TrtcCloudImpl();
+            return trtcCloud;
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    static _getInstance() {
+        if (trtcCloud) {
+            return trtcCloud;
+        }
+        throw new TrtcError({
+            code: TXLiteJSError.INVALID_OPERATION,
+            message: 'get trtcCloud failed, please create trtcCloud first',
+        });
+    }
+    static _destroyInstance() {
+        try {
+            trtcCloud = null;
+            TrtcNativeTrtcCloudModule.destroySharedInstance();
+        }
+        catch (error) {
+            throw new TrtcError({
+                code: error.code || TXLiteJSError.UNKNOWN,
+                message: error.message,
+                name: error.name,
+            });
+        }
+    }
+    // 截图保存
+    // async saveImage_(base64Data) {
+    //   return new Promise((resolve, reject) => {
+    //     let bitmap = new plus.nativeObj.Bitmap();
+    //     bitmap.loadBase64Data(base64Data, () => {
+    //       const url = "_doc/" + new Date().getTime() + ".png";  // url为时间戳命名方式
+    //       console.log('saveHeadImgFile', url);
+    //       bitmap.save(url, { overwrite: true }, (i) => {
+    //         uni.saveImageToPhotosAlbum({
+    //           filePath: url,
+    //           success: function() {
+    //             uni.showToast({
+    //               title: '图片保存成功',
+    //               icon: 'none'
+    //             })
+    //             bitmap.clear();
+    //             resolve({ code: 0, message: '图片保存成功' });
+    //           }
+    //         });
+    //       }, (e) => {
+    //         uni.showToast({
+    //           title: '图片保存失败, 请重新截图',
+    //           icon: 'none'
+    //         })
+    //         bitmap.clear();
+    //         resolve({ code: -1, message: '图片保存失败, 请重新截图' });
+    //       });
+    //     });
+    //   });
+    // }
+    on(event, callback) {
+        if (typeof event !== NAME.STRING || typeof callback !== NAME.FUNCTION) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the on method parameter types. event type is a ${typeof event}; callback type is a ${typeof callback}`,
+            });
+        }
+        const nativeListener = (res) => __awaiter(this, void 0, void 0, function* () {
+            const { data = [] } = res;
+            const code = data[0];
+            const message = data[1];
+            const extraInfo = data[2];
+            switch (event) {
+                case 'onEnterRoom': {
+                    const result = code;
+                    callback(result);
+                    break;
+                }
+                case 'onExitRoom': {
+                    const reason = code;
+                    callback(reason);
+                    break;
+                }
+                case 'onFirstVideoFrame': {
+                    const userId = code;
+                    const streamType = data[1];
+                    const width = data[2];
+                    const height = data[3];
+                    callback({ userId, streamType, width, height });
+                    break;
+                }
+                case 'onFirstAudioFrame': {
+                    const userId = code;
+                    callback(userId);
+                    break;
+                }
+                case 'onMicDidReady': {
+                    callback();
+                    break;
+                }
+                case 'onCameraDidReady': {
+                    callback();
+                    break;
+                }
+                case 'onNetworkQuality': {
+                    const localQuality = data[0];
+                    const remoteQuality = data[1];
+                    callback({ localQuality, remoteQuality });
+                    break;
+                }
+                case 'onRemoteUserEnterRoom': {
+                    const userId = code;
+                    callback(userId);
+                    break;
+                }
+                case 'onRemoteUserLeaveRoom': {
+                    const userId = code;
+                    const reason = message;
+                    callback({ userId, reason });
+                    break;
+                }
+                case 'onSendFirstLocalAudioFrame': {
+                    callback();
+                    break;
+                }
+                case 'onSendFirstLocalVideoFrame': {
+                    const streamType = code;
+                    callback(streamType);
+                    break;
+                }
+                case 'onStatistics': {
+                    const statics = data[0];
+                    callback(statics);
+                    break;
+                }
+                case 'onUserAudioAvailable': {
+                    const userId = code;
+                    const available = message;
+                    callback({ userId, available });
+                    break;
+                }
+                case 'onUserVideoAvailable': {
+                    const userId = code;
+                    const available = message;
+                    callback({ userId, available });
+                    break;
+                }
+                case 'onUserVoiceVolume': {
+                    const userVolumes = data[0];
+                    const totalVolume = data[1];
+                    callback({ userVolumes, totalVolume });
+                    break;
+                }
+                case 'onSwitchRole': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCaptureStarted': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCapturePaused': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCaptureResumed': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCaptureStopped': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onUserSubStreamAvailable': {
+                    const userId = code;
+                    const available = message;
+                    callback({ userId, available });
+                    break;
+                }
+                case 'onSnapshotComplete': {
+                    // base64 直接保存到本地图库
+                    // const { code: snapShotCode, message: msg } = await this.saveImage_(code);
+                    // callback({ snapShotCode, message: msg });
+                    callback({ base64Data: code, message });
+                    break;
+                }
+                case 'onUserVideoSizeChanged': {
+                    callback(data);
+                    break;
+                }
+                case 'onStart': {
+                    callback({ id: code, errCode: message });
+                    break;
+                }
+                case 'onPlayProgress': {
+                    callback({ id: code, curPtsMS: message, durationMS: extraInfo });
+                    break;
+                }
+                case 'onComplete': {
+                    callback({ id: code, errCode: message });
+                    break;
+                }
+                case 'onConnectOtherRoom': {
+                    // 拿不到 userid, 为了和 native 参数保持一致,所以空字符串代替
+                    callback({ userId: '', errCode: code, errMsg: message });
+                    break;
+                }
+                case 'onDisconnectOtherRoom': {
+                    callback({ errCode: code, errMsg: message });
+                    break;
+                }
+                case 'onError': {
+                    console.error(`onError: ${code}, ${message}, ${extraInfo}`);
+                    callback(generateError_({ message }, code, extraInfo));
+                    break;
+                }
+                default: {
+                    callback({ code, message, extraInfo });
+                }
+            }
+        });
+        this.listenersMap_.set(event, nativeListener); // 多次设置同一个事件时,后面的 callback 覆盖前面
+        TrtcEvent.addEventListener(event, nativeListener);
+    }
+    off(event) {
+        if (typeof event !== NAME.STRING) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the off method parameter types. event type is a ${typeof event} not a ${NAME.STRING}`,
+            });
+        }
+        try {
+            if (event === '*') {
+                this.listenersMap_.forEach((value, key) => {
+                    TrtcEvent.removeEventListener(key, value);
+                });
+                this.listenersMap_.clear();
+            }
+            else {
+                TrtcEvent.removeEventListener(event, this.listenersMap_.get(event));
+                this.listenersMap_.delete(event);
+            }
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    enterRoom(params, scene) {
+        if (scene !== TRTCAppScene.TRTCAppSceneVideoCall && scene !== TRTCAppScene.TRTCAppSceneLIVE && scene !== TRTCAppScene.TRTCAppSceneAudioCall && scene !== TRTCAppScene.TRTCAppSceneVoiceChatRoom) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the enterRoom method parameters. scene is not of TRTCAppScene`,
+            });
+        }
+        try {
+            const enterRoomParams = Object.assign(Object.assign({}, params), { role: params.role || TRTCRoleType.TRTCRoleAnchor, appScene: scene });
+            TrtcNativeTrtcCloudModule.enterRoom(enterRoomParams);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    exitRoom() {
+        try {
+            TrtcNativeTrtcCloudModule.exitRoom();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    connectOtherRoom(params) {
+        try {
+            TrtcNativeTrtcCloudModule.connectOtherRoom(params);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    disconnectOtherRoom() {
+        try {
+            TrtcNativeTrtcCloudModule.disconnectOtherRoom();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    switchRole(role) {
+        if (role !== TRTCRoleType.TRTCRoleAnchor && role !== TRTCRoleType.TRTCRoleAudience) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the switchRole method parameter. role is not of TRTCRoleType`,
+            });
+        }
+        try {
+            role && TrtcNativeTrtcCloudModule.switchRole(role);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startLocalPreview(isFrontCamera = true, viewId) {
+        if (typeof isFrontCamera !== NAME.BOOLEAN || !viewId || typeof viewId !== NAME.STRING) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the startLocalPreview method parameters`,
+            });
+        }
+        try {
+            let param = { isFrontCamera: !!isFrontCamera };
+            param = viewId ? Object.assign(Object.assign({}, param), { userId: viewId }) : param;
+            TrtcNativeTrtcCloudModule.startLocalPreview(param);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setVideoEncoderParam(param) {
+        try {
+            TrtcNativeTrtcCloudModule.setVideoEncoderParam(param);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopLocalPreview() {
+        try {
+            TrtcNativeTrtcCloudModule.stopLocalPreview();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    switchCamera(isFrontCamera) {
+        if (typeof isFrontCamera !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the switchCamera method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.switchCamera(isFrontCamera);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setLocalRenderParams(params) {
+        try {
+            const { rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto } = params;
+            TrtcNativeTrtcCloudModule.setLocalRenderParams({
+                rotation,
+                fillMode,
+                mirrorType,
+            });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteLocalVideo(streamType, mute) {
+        if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub || typeof mute !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteLocalVideo method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteLocalVideo({ streamType, mute: !!mute });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startRemoteView(userId, streamType, viewId) {
+        if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub || !viewId) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the startRemoteView method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.startRemoteView({ userId, streamType, viewId });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopRemoteView(userId, streamType) {
+        if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the stopRemoteView method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.stopRemoteView({ userId, streamType });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 远端渲染设置
+    setRemoteRenderParams(userId, streamType, params) {
+        try {
+            if (!userId || (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub)) {
+                throw new TrtcError({
+                    code: TXLiteJSError.INVALID_PARAMETER,
+                    message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`,
+                });
+            }
+            const { rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto } = params;
+            TrtcNativeTrtcCloudModule.setRemoteRenderParams({
+                userId,
+                streamType,
+                rotation,
+                fillMode,
+                mirrorType
+            });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 设置视频编码器输出的画面方向
+    setVideoEncoderRotation(rotation) {
+        if (typeof rotation !== NAME.NUMBER) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setVideoEncoderRotation method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setVideoEncoderRotation(rotation);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 设置编码器输出的画面镜像模式
+    setVideoEncoderMirror(mirror) {
+        if (typeof mirror !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setVideoEncoderMirror method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setVideoEncoderMirror(mirror);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 设置重力感应的适配模式
+    setGSensorMode(mode) {
+        if (typeof mode !== NAME.NUMBER) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setGSensorMode method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setGSensorMode(mode);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 截图
+    snapshotVideo(userId, streamType, sourceType) {
+        if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.snapshotVideo({ userId: userId || null, streamType, sourceType });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startLocalAudio(quality = TRTCAudioQuality.TRTCAudioQualityDefault) {
+        if (quality !== TRTCAudioQuality.TRTCAudioQualitySpeech && quality !== TRTCAudioQuality.TRTCAudioQualityDefault && quality !== TRTCAudioQuality.TRTCAudioQualityMusic) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the startLocalAudio method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.startLocalAudio(quality);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopLocalAudio() {
+        try {
+            TrtcNativeTrtcCloudModule.stopLocalAudio();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteLocalAudio(mute) {
+        if (typeof mute !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteLocalAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteLocalAudio(!!mute);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteRemoteAudio(userId, mute) {
+        if (typeof mute !== NAME.BOOLEAN || !userId) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteRemoteAudio method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteRemoteAudio({ userId, mute: !!mute });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteAllRemoteAudio(mute) {
+        if (typeof mute !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteAllRemoteAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteAllRemoteAudio(!!mute);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setAudioRoute(route) {
+        if (route !== TRTCAudioRoute.TRTCAudioRouteSpeaker && route !== TRTCAudioRoute.TRTCAudioRouteEarpiece) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setAudioRoute method parameter, route is not of TRTCAudioRoute`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setAudioRoute(route);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    enableAudioVolumeEvaluation(interval) {
+        if (typeof interval !== NAME.NUMBER) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the enableAudioVolumeEvaluation method parameter, interval type is a ${typeof interval} not a ${NAME.NUMBER}`,
+            });
+        }
+        try {
+            interval > 0 && TrtcNativeTrtcCloudModule.enableAudioVolumeEvaluation(interval);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // ///////////////////////////////////////////////////////////////////////////////
+    //
+    //                      美颜 + 水印
+    //
+    // ///////////////////////////////////////////////////////////////////////////////
+    setBeautyStyle(beautyStyle) {
+        if (beautyStyle !== TRTCBeautyStyle.TRTCBeautyStyleSmooth && beautyStyle !== TRTCBeautyStyle.TRTCBeautyStyleNature && beautyStyle !== TRTCBeautyStyle.TRTCBeautyStylePitu) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setBeautyStyle method parameter, beautyStyle is not of TRTCBeautyStyle`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setBeautyStyle(beautyStyle);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setBeautyLevel(beautyLevel) {
+        if (typeof beautyLevel !== NAME.NUMBER || (beautyLevel < 0 || beautyLevel > 9)) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setBeautyLevel method parameter, beautyLevel should in the range 0-9`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setBeautyLevel(beautyLevel);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // ///////////////////////////////////////////////////////////////////////////////
+    //
+    //                      背景音效
+    //
+    // ///////////////////////////////////////////////////////////////////////////////
+    startPlayMusic(musicParam) {
+        try {
+            const { id = 0 } = musicParam || {};
+            TXAudioEffectManagerModule.startPlayMusic(Object.assign(Object.assign({}, musicParam), { ID: id })); // v1.2.0 的 iOS 解析的是 ID, v1.2.1 插件进行了修复
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopPlayMusic(id) {
+        try {
+            TXAudioEffectManagerModule.stopPlayMusic(id);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    pausePlayMusic(id) {
+        try {
+            TXAudioEffectManagerModule.pausePlayMusic(id);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    resumePlayMusic(id) {
+        try {
+            TXAudioEffectManagerModule.resumePlayMusic(id);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // ///////////////////////////////////////////////////////////////////////////////
+    //
+    //                      屏幕分享
+    //
+    // ///////////////////////////////////////////////////////////////////////////////
+    setSubStreamEncoderParam(param) {
+        try {
+            TrtcNativeTrtcCloudModule.setSubStreamEncoderParam(param);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startScreenCapture(streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams = {}, shareParams = {}) {
+        try {
+            let platform = uni.getSystemInfoSync().platform;
+            if ((streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig)) {
+                streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub;
+            }
+            const { enableForegroundService = true } = shareParams; // 默认开启前台服务, 避免退后台后进程被杀
+            const screenCaptureParams = Object.assign({ streamType }, encParams);
+            if (platform === NAME.ANDROID) {
+                TrtcNativeTrtcCloudModule.startScreenCapture(Object.assign(Object.assign({}, screenCaptureParams), { enableForegroundService }));
+            }
+            if (platform === NAME.IOS) {
+                // 开始应用内的屏幕分享(仅支持 iOS 13.0 及以上系统)
+                TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams);
+                // if (shareSource === TRTCShareSource.InApp) {
+                //   TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams);
+                // }
+                // // 开始全系统的屏幕分享(仅支持 iOS 11.0 及以上系统)
+                // if (shareSource === TRTCShareSource.ByReplaykit) {
+                //   TrtcNativeTrtcCloudModule.startScreenCaptureByReplaykit({ ...screenCaptureParams, appGroup: null });
+                // }
+            }
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopScreenCapture() {
+        try {
+            TrtcNativeTrtcCloudModule.stopScreenCapture();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    pauseScreenCapture() {
+        try {
+            TrtcNativeTrtcCloudModule.pauseScreenCapture();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    resumeScreenCapture() {
+        try {
+            TrtcNativeTrtcCloudModule.resumeScreenCapture();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+}

+ 612 - 0
TrtcCloud/lib/TrtcCode.js

@@ -0,0 +1,612 @@
+import { NAME, errorCodeUrl } from './constants';
+/**
+ * @namespace ErrorCode
+ *
+ * @description 错误码、警告码和事件列表
+ */
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                     (一)错误码(严重)
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * @memberof ErrorCode
+ * @typedef 错误码(严重)
+ * @description SDK 错误码(严重)对照表
+ * | 符号 | 值 | 含义 |
+ * |---|---|---|
+ * |ERR_NULL|0|无错误|
+ * |ERR_ROOM_ENTER_FAIL|-3301|进入房间失败|
+ * |ERR_ENTER_ROOM_PARAM_NULL|-3316|进房参数为空,请检查 enterRoom:appScene: 接口调用是否传入有效的 param|
+ * |ERR_SDK_APPID_INVALID|-3317|进房参数 sdkAppId 错误|
+ * |ERR_ROOM_ID_INVALID|-3318|进房参数 roomId 错误|
+ * |ERR_USER_ID_INVALID|-3319|进房参数 userID 不正确|
+ * |ERR_USER_SIG_INVALID|-3320|进房参数 userSig 不正确|
+ * |ERR_ROOM_REQUEST_ENTER_ROOM_TIMEOUT|-3308|请求进房超时,请检查网络|
+ * |ERR_SERVER_INFO_SERVICE_SUSPENDED|-100013|服务不可用。请检查:套餐包剩余分钟数是否大于0,腾讯云账号是否欠费|
+ * |ERR_ROOM_REQUEST_QUIT_ROOM_TIMEOUT|-3325|请求退房超时|
+ * |ERR_CAMERA_START_FAIL|-1301|打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序|
+ * |ERR_CAMERA_NOT_AUTHORIZED|-1314|摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了|
+ * |ERR_CAMERA_SET_PARAM_FAIL|-1315|摄像头参数设置出错(参数不支持或其它)|
+ * |ERR_CAMERA_OCCUPY|-1316|摄像头正在被占用中,可尝试打开其他摄像头|
+ * |ERR_MIC_START_FAIL|-1302|打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序|
+ * |ERR_MIC_NOT_AUTHORIZED|-1317|麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了|
+ * |ERR_MIC_SET_PARAM_FAIL|-1318|麦克风设置参数失败|
+ * |ERR_MIC_OCCUPY|-1319|麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败|
+ * |ERR_MIC_STOP_FAIL|-1320|停止麦克风失败|
+ * |ERR_SPEAKER_START_FAIL|-1321|打开扬声器失败,例如在 Windows 或 Mac 设备,扬声器的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序|
+ * |ERR_SPEAKER_SET_PARAM_FAIL|-1322|扬声器设置参数失败|
+ * |ERR_SPEAKER_STOP_FAIL|-1323|停止扬声器失败|
+ * |ERR_SCREEN_CAPTURE_START_FAIL|-1308|开始录屏失败,如果在移动设备出现,可能是权限被用户拒绝了,如果在 Windows 或 Mac 系统的设备出现,请检查录屏接口的参数是否符合要求|
+ * |ERR_SCREEN_CAPTURE_UNSURPORT|-1309|录屏失败,在 Android 平台,需要5.0以上的系统|
+ * |ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_SUB_VIDEO|-102015|没有权限上行辅路|
+ * |ERR_SERVER_CENTER_ANOTHER_USER_PUSH_SUB_VIDEO|-102016|其他用户正在上行辅路|
+ * |ERR_VIDEO_ENCODE_FAIL|-1303|视频帧编码失败,例如 iOS 设备切换到其他应用时,硬编码器可能被系统释放,再切换回来时,硬编码器重启前,可能会抛出|
+ * |ERR_UNSUPPORTED_RESOLUTION|-1305|不支持的视频分辨率|
+ * |ERR_AUDIO_ENCODE_FAIL|-1304|音频帧编码失败,例如传入自定义音频数据,SDK 无法处理|
+ * |ERR_UNSUPPORTED_SAMPLERATE|-1306|不支持的音频采样率|
+ * |ERR_PIXEL_FORMAT_UNSUPPORTED|-1327|设置的 pixel format 不支持|
+ * |ERR_BUFFER_TYPE_UNSUPPORTED|-1328|设置的 buffer type 不支持|
+ * |ERR_PUBLISH_CDN_STREAM_REQUEST_TIME_OUT|-3321|旁路转推请求超时|
+ * |ERR_CLOUD_MIX_TRANSCODING_REQUEST_TIME_OUT|-3322|云端混流请求超时|
+ * |ERR_PUBLISH_CDN_STREAM_SERVER_FAILED|-3323|旁路转推回包异常|
+ * |ERR_CLOUD_MIX_TRANSCODING_SERVER_FAILED|-3324|云端混流回包异常|
+ * |ERR_ROOM_REQUEST_START_PUBLISHING_TIMEOUT|-3333|开始向腾讯云的直播 CDN 推流信令超时|
+ * |ERR_ROOM_REQUEST_START_PUBLISHING_ERROR|-3334|开始向腾讯云的直播 CDN 推流信令异常|
+ * |ERR_ROOM_REQUEST_STOP_PUBLISHING_TIMEOUT|-3335|停止向腾讯云的直播 CDN 推流信令超时|
+ * |ERR_ROOM_REQUEST_STOP_PUBLISHING_ERROR|-3336|停止向腾讯云的直播 CDN 推流信令异常|
+ * |ERR_ROOM_REQUEST_CONN_ROOM_TIMEOUT|-3326|请求连麦超时|
+ * |ERR_ROOM_REQUEST_DISCONN_ROOM_TIMEOUT|-3327|请求退出连麦超时|
+ * |ERR_ROOM_REQUEST_CONN_ROOM_INVALID_PARAM|-3328|无效参数|
+ * |ERR_CONNECT_OTHER_ROOM_AS_AUDIENCE|-3330|当前是观众角色,不能请求或断开跨房连麦,需要先 switchRole() 到主播|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NOT_SUPPORT|-102031|不支持跨房间连麦|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_NUM|-102032|达到跨房间连麦上限|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_RETRY_TIMES|-102033|跨房间连麦重试次数耗尽|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REQ_TIMEOUT|-102034|跨房间连麦请求超时|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REQ|-102035|跨房间连麦请求格式错误|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NO_SIG|-102036|跨房间连麦无签名|
+ * |ERR_SERVER_CENTER_CONN_ROOM_DECRYPT_SIG|-102037|跨房间连麦签名解密失败|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NO_KEY|-102038|未找到跨房间连麦签名解密密钥|
+ * |ERR_SERVER_CENTER_CONN_ROOM_PARSE_SIG|-102039|跨房间连麦签名解析错误|
+ * |ERR_SERVER_CENTER_CONN_ROOM_INVALID_SIG_TIME|-102040|跨房间连麦签名时间戳错误|
+ * |ERR_SERVER_CENTER_CONN_ROOM_SIG_GROUPID|-102041|跨房间连麦签名不匹配|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NOT_CONNED|-102042|本房间无连麦|
+ * |ERR_SERVER_CENTER_CONN_ROOM_USER_NOT_CONNED|-102043|本用户未发起连麦|
+ * |ERR_SERVER_CENTER_CONN_ROOM_FAILED|-102044|跨房间连麦失败|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CANCEL_FAILED|-102045|取消跨房间连麦失败|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_ROOM_NOT_EXIST|-102046|被连麦房间不存在|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_REACH_MAX_ROOM|-102047|被连麦房间达到连麦上限|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_NOT_EXIST|-102048|被连麦用户不存在|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_DELETED|-102049|被连麦用户已被删除|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_FULL|-102050|被连麦用户达到资源上限|
+ * |ERR_SERVER_CENTER_CONN_ROOM_INVALID_SEQ|-102051|连麦请求序号错乱|
+ */
+export const TXLiteAVError = {
+    /** 无错误 */
+    ERR_NULL: 0,
+    /** 进入房间失败 */
+    ERR_ROOM_ENTER_FAIL: -3301,
+    /** 进房参数为空,请检查 enterRoom:appScene: 接口调用是否传入有效的 param */
+    ERR_ENTER_ROOM_PARAM_NULL: -3316,
+    /** 进房参数 sdkAppId 错误 */
+    ERR_SDK_APPID_INVALID: -3317,
+    /** 进房参数 roomId 错误 */
+    ERR_ROOM_ID_INVALID: -3318,
+    /** 进房参数 userID 不正确 */
+    ERR_USER_ID_INVALID: -3319,
+    /** 进房参数 userSig 不正确 */
+    ERR_USER_SIG_INVALID: -3320,
+    /** 请求进房超时,请检查网络 */
+    ERR_ROOM_REQUEST_ENTER_ROOM_TIMEOUT: -3308,
+    /** 服务不可用。请检查:套餐包剩余分钟数是否大于0,腾讯云账号是否欠费 */
+    ERR_SERVER_INFO_SERVICE_SUSPENDED: -100013,
+    /** 请求退房超时 */
+    ERR_ROOM_REQUEST_QUIT_ROOM_TIMEOUT: -3325,
+    /** 打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */
+    ERR_CAMERA_START_FAIL: -1301,
+    /** 摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 */
+    ERR_CAMERA_NOT_AUTHORIZED: -1314,
+    /** 摄像头参数设置出错(参数不支持或其它) */
+    ERR_CAMERA_SET_PARAM_FAIL: -1315,
+    /** 摄像头正在被占用中,可尝试打开其他摄像头 */
+    ERR_CAMERA_OCCUPY: -1316,
+    /** 打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */
+    ERR_MIC_START_FAIL: -1302,
+    /** 麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 */
+    ERR_MIC_NOT_AUTHORIZED: -1317,
+    /** 麦克风设置参数失败 */
+    ERR_MIC_SET_PARAM_FAIL: -1318,
+    /** 麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败 */
+    ERR_MIC_OCCUPY: -1319,
+    /** 停止麦克风失败 */
+    ERR_MIC_STOP_FAIL: -1320,
+    /** 打开扬声器失败,例如在 Windows 或 Mac 设备,扬声器的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */
+    ERR_SPEAKER_START_FAIL: -1321,
+    /** 扬声器设置参数失败 */
+    ERR_SPEAKER_SET_PARAM_FAIL: -1322,
+    /** 停止扬声器失败 */
+    ERR_SPEAKER_STOP_FAIL: -1323,
+    /** 开始录屏失败,如果在移动设备出现,可能是权限被用户拒绝了,如果在 Windows 或 Mac 系统的设备出现,请检查录屏接口的参数是否符合要求 */
+    ERR_SCREEN_CAPTURE_START_FAIL: -1308,
+    /** 录屏失败,在 Android 平台,需要5.0以上的系统 */
+    ERR_SCREEN_CAPTURE_UNSURPORT: -1309,
+    /** 没有权限上行辅路 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_SUB_VIDEO: -102015,
+    /** 其他用户正在上行辅路 */
+    ERR_SERVER_CENTER_ANOTHER_USER_PUSH_SUB_VIDEO: -102016,
+    /** 视频帧编码失败,例如 iOS 设备切换到其他应用时,硬编码器可能被系统释放,再切换回来时,硬编码器重启前,可能会抛出 */
+    ERR_VIDEO_ENCODE_FAIL: -1303,
+    /** 音频帧编码失败,例如传入自定义音频数据,SDK 无法处理 */
+    ERR_AUDIO_ENCODE_FAIL: -1304,
+    /** 不支持的视频分辨率 */
+    ERR_UNSUPPORTED_RESOLUTION: -1305,
+    /** 不支持的音频采样率 */
+    ERR_UNSUPPORTED_SAMPLERATE: -1306,
+    /** 设置的 pixel format 不支持 */
+    ERR_PIXEL_FORMAT_UNSUPPORTED: -1327,
+    /** 设置的 buffer type 不支持 */
+    ERR_BUFFER_TYPE_UNSUPPORTED: -1328,
+    /** 旁路转推请求超时 */
+    ERR_PUBLISH_CDN_STREAM_REQUEST_TIME_OUT: -3321,
+    /** 云端混流请求超时 */
+    ERR_CLOUD_MIX_TRANSCODING_REQUEST_TIME_OUT: -3322,
+    /** 旁路转推回包异常 */
+    ERR_PUBLISH_CDN_STREAM_SERVER_FAILED: -3323,
+    /** 云端混流回包异常 */
+    ERR_CLOUD_MIX_TRANSCODING_SERVER_FAILED: -3324,
+    /** 开始向腾讯云的直播 CDN 推流信令超时 */
+    ERR_ROOM_REQUEST_START_PUBLISHING_TIMEOUT: -3333,
+    /** 开始向腾讯云的直播 CDN 推流信令异常 */
+    ERR_ROOM_REQUEST_START_PUBLISHING_ERROR: -3334,
+    /** 停止向腾讯云的直播 CDN 推流信令超时 */
+    ERR_ROOM_REQUEST_STOP_PUBLISHING_TIMEOUT: -3335,
+    /** 停止向腾讯云的直播 CDN 推流信令异常 */
+    ERR_ROOM_REQUEST_STOP_PUBLISHING_ERROR: -3336,
+    /** 请求连麦超时 */
+    ERR_ROOM_REQUEST_CONN_ROOM_TIMEOUT: -3326,
+    /** 请求退出连麦超时 */
+    ERR_ROOM_REQUEST_DISCONN_ROOM_TIMEOUT: -3327,
+    /** 无效参数 */
+    ERR_ROOM_REQUEST_CONN_ROOM_INVALID_PARAM: -3328,
+    /** 当前是观众角色,不能请求或断开跨房连麦,需要先 switchRole() 到主播 */
+    ERR_CONNECT_OTHER_ROOM_AS_AUDIENCE: -3330,
+    /** 不支持跨房间连麦 */
+    ERR_SERVER_CENTER_CONN_ROOM_NOT_SUPPORT: -102031,
+    /** 达到跨房间连麦上限 */
+    ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_NUM: -102032,
+    /** 跨房间连麦重试次数耗尽 */
+    ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_RETRY_TIMES: -102033,
+    /** 跨房间连麦请求超时 */
+    ERR_SERVER_CENTER_CONN_ROOM_REQ_TIMEOUT: -102034,
+    /** 跨房间连麦请求格式错误 */
+    ERR_SERVER_CENTER_CONN_ROOM_REQ: -102035,
+    /** 跨房间连麦无签名 */
+    ERR_SERVER_CENTER_CONN_ROOM_NO_SIG: -102036,
+    /** 跨房间连麦签名解密失败 */
+    ERR_SERVER_CENTER_CONN_ROOM_DECRYPT_SIG: -102037,
+    /** 未找到跨房间连麦签名解密密钥 */
+    ERR_SERVER_CENTER_CONN_ROOM_NO_KEY: -102038,
+    /** 跨房间连麦签名解析错误 */
+    ERR_SERVER_CENTER_CONN_ROOM_PARSE_SIG: -102039,
+    /** 跨房间连麦签名时间戳错误 */
+    ERR_SERVER_CENTER_CONN_ROOM_INVALID_SIG_TIME: -102040,
+    /** 跨房间连麦签名不匹配 */
+    ERR_SERVER_CENTER_CONN_ROOM_SIG_GROUPID: -102041,
+    /** 本房间无连麦 */
+    ERR_SERVER_CENTER_CONN_ROOM_NOT_CONNED: -102042,
+    /** 本用户未发起连麦 */
+    ERR_SERVER_CENTER_CONN_ROOM_USER_NOT_CONNED: -102043,
+    /** 跨房间连麦失败 */
+    ERR_SERVER_CENTER_CONN_ROOM_FAILED: -102044,
+    /** 取消跨房间连麦失败 */
+    ERR_SERVER_CENTER_CONN_ROOM_CANCEL_FAILED: -102045,
+    /** 被连麦房间不存在 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_ROOM_NOT_EXIST: -102046,
+    /** 被连麦房间达到连麦上限 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_REACH_MAX_ROOM: -102047,
+    /** 被连麦用户不存在 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_NOT_EXIST: -102048,
+    /** 被连麦用户已被删除 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_DELETED: -102049,
+    /** 被连麦用户达到资源上限 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_FULL: -102050,
+    /** 连麦请求序号错乱 */
+    ERR_SERVER_CENTER_CONN_ROOM_INVALID_SEQ: -102051,
+    /** 直播,推流出现网络断开,且经过多次重试无法恢复 */
+    ERR_RTMP_PUSH_NET_DISCONNECT: -1307,
+    /** 直播,推流地址非法,例如不是 RTMP 协议的地址 */
+    ERR_RTMP_PUSH_INVALID_ADDRESS: -1313,
+    /** 直播,连接推流服务器失败(若支持智能选路,IP 全部失败) */
+    ERR_RTMP_PUSH_NET_ALLADDRESS_FAIL: -1324,
+    /** 直播,网络不可用,请确认 WiFi、移动数据或者有线网络是否正常 */
+    ERR_RTMP_PUSH_NO_NETWORK: -1325,
+    /** 直播,服务器拒绝连接请求,可能是该推流地址已经被占用,或者 TXSecret 校验失败,或者是过期了,或者是欠费了 */
+    ERR_RTMP_PUSH_SERVER_REFUSE: -1326,
+    /** 直播,网络断连,且经多次重连抢救无效,可以放弃治疗,更多重试请自行重启播放 */
+    ERR_PLAY_LIVE_STREAM_NET_DISCONNECT: -2301,
+    /** 直播,获取加速拉流的地址失败 */
+    ERR_GET_RTMP_ACC_URL_FAIL: -2302,
+    /** 播放的文件不存在 */
+    ERR_FILE_NOT_FOUND: -2303,
+    /** H265 解码失败 */
+    ERR_HEVC_DECODE_FAIL: -2304,
+    /** 点播,音视频流解密失败 */
+    ERR_VOD_DECRYPT_FAIL: -2305,
+    /** 点播,获取点播文件信息失败 */
+    ERR_GET_VODFILE_MEDIAINFO_FAIL: -2306,
+    /** 直播,切流失败(切流可以播放不同画面大小的视频) */
+    ERR_PLAY_LIVE_STREAM_SWITCH_FAIL: -2307,
+    /** 直播,服务器拒绝连接请求 */
+    ERR_PLAY_LIVE_STREAM_SERVER_REFUSE: -2308,
+    /** 直播,RTMPACC 低延时拉流失败,且经过多次重试无法恢复 */
+    ERR_RTMP_ACC_FETCH_STREAM_FAIL: -2309,
+    /** 心跳失败,客户端定时向服务器发送数据包,告诉服务器自己活着,这个错误通常是发包超时 */
+    ERR_ROOM_HEARTBEAT_FAIL: -3302,
+    /** 拉取接口机服务器地址失败 */
+    ERR_ROOM_REQUEST_IP_FAIL: -3303,
+    /** 连接接口机服务器失败 */
+    ERR_ROOM_CONNECT_FAIL: -3304,
+    /** 请求视频位失败 */
+    ERR_ROOM_REQUEST_AVSEAT_FAIL: -3305,
+    /** 请求 token https 超时,请检查网络是否正常,或网络防火墙是否放行 https 访问 official.opensso.tencent-cloud.com:443 */
+    ERR_ROOM_REQUEST_TOKEN_HTTPS_TIMEOUT: -3306,
+    /** 请求 IP 和 sig 超时,请检查网络是否正常,或网络防火墙是否放行 UDP 访问下列 IP 和域名 query.tencent-cloud.com:8000 162.14.23.140:8000 162.14.7.49:8000 */
+    ERR_ROOM_REQUEST_IP_TIMEOUT: -3307,
+    /** 请求视频位超时 */
+    ERR_ROOM_REQUEST_VIDEO_FLAG_TIMEOUT: -3309,
+    /** 请求视频数据超时 */
+    ERR_ROOM_REQUEST_VIDEO_DATA_ROOM_TIMEOUT: -3310,
+    /** 请求修改视频能力项超时 */
+    ERR_ROOM_REQUEST_CHANGE_ABILITY_TIMEOUT: -3311,
+    /** 请求状态上报超时 */
+    ERR_ROOM_REQUEST_STATUS_REPORT_TIMEOUT: -3312,
+    /** 请求关闭视频超时 */
+    ERR_ROOM_REQUEST_CLOSE_VIDEO_TIMEOUT: -3313,
+    /** 请求接收视频项超时 */
+    ERR_ROOM_REQUEST_SET_RECEIVE_TIMEOUT: -3314,
+    /** 请求 token 无效参数,请检查 TRTCParams.userSig 是否填写正确 */
+    ERR_ROOM_REQUEST_TOKEN_INVALID_PARAMETER: -3315,
+    /** 请求 AES TOKEN 时,server 返回的内容是空的 */
+    ERR_ROOM_REQUEST_AES_TOKEN_RETURN_ERROR: -3329,
+    /** 请求接口机 IP 返回的列表为空的 */
+    ERR_ACCIP_LIST_EMPTY: -3331,
+    /** 请求发送 Json 信令超时 */
+    ERR_ROOM_REQUEST_SEND_JSON_CMD_TIMEOUT: -3332,
+    // Info 服务器(查询接口机 IP), 服务器错误码,数值范围[-100000, -110000]
+    /** server 解包错误,可能请求数据被篡改 */
+    ERR_SERVER_INFO_UNPACKING_ERROR: -100000,
+    /** TOKEN 错误 */
+    ERR_SERVER_INFO_TOKEN_ERROR: -100001,
+    /** 分配接口机错误 */
+    ERR_SERVER_INFO_ALLOCATE_ACCESS_FAILED: -100002,
+    /** 生成签名错误 */
+    ERR_SERVER_INFO_GENERATE_SIGN_FAILED: -100003,
+    /** https token 超时 */
+    ERR_SERVER_INFO_TOKEN_TIMEOUT: -100004,
+    /** 无效的命令字 */
+    ERR_SERVER_INFO_INVALID_COMMAND: -100005,
+    /** 权限位校验失败 */
+    ERR_SERVER_INFO_PRIVILEGE_FLAG_ERROR: -100006,
+    /** https 请求时,生成加密 key 错误 */
+    ERR_SERVER_INFO_GENERATE_KEN_ERROR: -100007,
+    /** https 请求时,生成 token 错误 */
+    ERR_SERVER_INFO_GENERATE_TOKEN_ERROR: -100008,
+    /** 数据库查询失败(房间相关存储信息) */
+    ERR_SERVER_INFO_DATABASE: -100009,
+    /** 房间号错误 */
+    ERR_SERVER_INFO_BAD_ROOMID: -100010,
+    /** 场景或角色错误 */
+    ERR_SERVER_INFO_BAD_SCENE_OR_ROLE: -100011,
+    /** 房间号转换出错 */
+    ERR_SERVER_INFO_ROOMID_EXCHANGE_FAILED: -100012,
+    /** 房间号非法 */
+    ERR_SERVER_INFO_STRGROUP_HAS_INVALID_CHARS: -100014,
+    /** 非法SDKAppid */
+    ERR_SERVER_INFO_LACK_SDKAPPID: -100015,
+    /** 无效请求, 旧版 0x1 要求带 Token; ECDH 要求带 ECDH Publich Key; 两个都没有就按报错 */
+    ERR_SERVER_INFO_INVALID: -100016,
+    /** 生成公钥失败 */
+    ERR_SERVER_INFO_ECDH_GET_KEY: -100017,
+    /** 获取tinyid失败 */
+    ERR_SERVER_INFO_ECDH_GET_TINYID: -100018,
+    // Access 接口机
+    /** token 过期 */
+    ERR_SERVER_ACC_TOKEN_TIMEOUT: -101000,
+    /** 签名错误 */
+    ERR_SERVER_ACC_SIGN_ERROR: -101001,
+    /** 签名超时 */
+    ERR_SERVER_ACC_SIGN_TIMEOUT: -101002,
+    /** 房间不存在 */
+    ERR_SERVER_ACC_ROOM_NOT_EXIST: -101003,
+    /** 后台房间标识 roomId 错误 */
+    ERR_SERVER_ACC_ROOMID: -101004,
+    /** 后台用户位置标识 locationId 错误 */
+    ERR_SERVER_ACC_LOCATIONID: -101005,
+    // center 服务器(信令和流控处理等任务)
+    /** 后台错误 */
+    ERR_SERVER_CENTER_SYSTEM_ERROR: -102000,
+    /** 无效的房间 Id */
+    ERR_SERVER_CENTER_INVALID_ROOMID: -102001,
+    /** 创建房间失败 */
+    ERR_SERVER_CENTER_CREATE_ROOM_FAILED: -102002,
+    /** 签名错误 */
+    ERR_SERVER_CENTER_SIGN_ERROR: -102003,
+    /** 签名过期 */
+    ERR_SERVER_CENTER_SIGN_TIMEOUT: -102004,
+    /** 房间不存在 */
+    ERR_SERVER_CENTER_ROOM_NOT_EXIST: -102005,
+    /** 房间添加用户失败 */
+    ERR_SERVER_CENTER_ADD_USER_FAILED: -102006,
+    /** 查找用户失败 */
+    ERR_SERVER_CENTER_FIND_USER_FAILED: -102007,
+    /** 频繁切换终端 */
+    ERR_SERVER_CENTER_SWITCH_TERMINATION_FREQUENTLY: -102008,
+    /** locationid 错误 */
+    ERR_SERVER_CENTER_LOCATION_NOT_EXIST: -102009,
+    /** 没有权限创建房间 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_CREATE_ROOM: -102010,
+    /** 没有权限进入房间 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_ENTER_ROOM: -102011,
+    /** 辅路抢视频位、申请辅路请求类型参数错误 */
+    ERR_SERVER_CENTER_INVALID_PARAMETER_SUB_VIDEO: -102012,
+    /** 没有权限上视频 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_VIDEO: -102013,
+    /** 没有空闲路由表 */
+    ERR_SERVER_CENTER_ROUTE_TABLE_ERROR: -102014,
+    /** 当前用户没有上行辅路 */
+    ERR_SERVER_CENTER_NOT_PUSH_SUB_VIDEO: -102017,
+    /** 用户被删除状态 */
+    ERR_SERVER_CENTER_USER_WAS_DELETED: -102018,
+    /** 没有权限请求视频 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_REQUEST_VIDEO: -102019,
+    /** 进房参数 bussInfo 错误 */
+    ERR_SERVER_CENTER_INVALID_PARAMETER: -102023,
+    /** 请求 I 帧未知 opType */
+    ERR_SERVER_CENTER_I_FRAME_UNKNOW_TYPE: -102024,
+    /** 请求 I 帧包格式错误 */
+    ERR_SERVER_CENTER_I_FRAME_INVALID_PACKET: -102025,
+    /** 请求 I 帧目标用户不存在 */
+    ERR_SERVER_CENTER_I_FRAME_DEST_USER_NOT_EXIST: -102026,
+    /** 请求 I 帧房间用户太多 */
+    ERR_SERVER_CENTER_I_FRAME_ROOM_TOO_BIG: -102027,
+    /** 请求 I 帧参数错误 */
+    ERR_SERVER_CENTER_I_FRAME_RPS_INVALID_PARAMETER: -102028,
+    /** 房间号非法 */
+    ERR_SERVER_CENTER_INVALID_ROOM_ID: -102029,
+    /** 房间号超过限制 */
+    ERR_SERVER_CENTER_ROOM_ID_TOO_LONG: -102030,
+    /** 房间满员 */
+    ERR_SERVER_CENTER_ROOM_FULL: -102052,
+    /** json串解析失败 */
+    ERR_SERVER_CENTER_DECODE_JSON_FAIL: -102053,
+    /** 未定义命令字 */
+    ERR_SERVER_CENTER_UNKNOWN_SUB_CMD: -102054,
+    /** 未定义角色 */
+    ERR_SERVER_CENTER_INVALID_ROLE: -102055,
+    /** 代理机超出限制 */
+    ERR_SERVER_CENTER_REACH_PROXY_MAX: -102056,
+    //add by sunlitwang begin
+    /** 无法保存用户自定义recordId */
+    ERR_SERVER_CENTER_RECORDID_STORE: -102057,
+    /** Protobuf序列化错误 */
+    ERR_SERVER_CENTER_PB_SERIALIZE: -102058,
+    // https://cloud.tencent.com/document/product/269/1671#.E5.B8.90.E5.8F.B7.E7.B3.BB.E7.BB.9F , 帐号系统, 主要是70000 - 79999之间.
+    // 在请求 token 过程中,出现账号错误,SSO 返回的错误码,原为正数,现将其转换为负数。
+    /** sig 过期,请尝试重新生成。如果是刚生成,就过期,请检查有效期填写的是否过小,或者填的 0 */
+    ERR_SERVER_SSO_SIG_EXPIRED: -70001,
+    /** sig 校验失败,请确认下 sig 内容是否被截断,如缓冲区长度不够导致的内容截断 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_1: -70003,
+    /** sig 校验失败,请确认下 sig 内容是否被截断,如缓冲区长度不够导致的内容截断 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_2: -70004,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_3: -70005,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_4: -70006,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_5: -70007,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_6: -70008,
+    /** 用业务公钥验证 sig 失败,请确认生成的 usersig 使用的私钥和 sdkAppId 是否对应 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_7: -70009,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_8: -70010,
+    /** sig 中 identifier 与请求时的 identifier 不匹配,请检查登录时填写的 identifier 与 sig 中的是否一致 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_ID_NOT_MATCH: -70013,
+    /** sig 中 sdkAppId 与请求时的 sdkAppId 不匹配,请检查登录时填写的 sdkAppId 与 sig 中的是否一致 */
+    ERR_SERVER_SSO_APPID_NOT_MATCH: -70014,
+    /** 内部第三方票据验证超时,请重试,如多次重试不成功,请@TLS 帐号支持,QQ 3268519604 */
+    ERR_SERVER_SSO_VERIFICATION_EXPIRED: -70017,
+    /** 内部第三方票据验证超时,请重试,如多次重试不成功,请@TLS 帐号支持,QQ 3268519604 */
+    ERR_SERVER_SSO_VERIFICATION_FAILED: -70018,
+    /** sdkAppId 未找到,请确认是否已经在腾讯云上配置 */
+    ERR_SERVER_SSO_APPID_NOT_FOUND: -70020,
+    /** 帐号已被拉入黑名单,请联系 TLS 帐号支持 QQ 3268519604 */
+    ERR_SERVER_SSO_ACCOUNT_IN_BLACKLIST: -70051,
+    /** usersig 已经失效,请重新生成,再次尝试 */
+    ERR_SERVER_SSO_SIG_INVALID: -70052,
+    /** 安全原因被限制 */
+    ERR_SERVER_SSO_LIMITED_BY_SECURITY: -70114,
+    /** 登录状态无效,请使用 usersig 重新鉴权 */
+    ERR_SERVER_SSO_INVALID_LOGIN_STATUS: -70221,
+    /** sdkAppId 填写错误 */
+    ERR_SERVER_SSO_APPID_ERROR: -70252,
+    /** 票据校验失败,请检查各项参数是否正确 */
+    ERR_SERVER_SSO_TICKET_VERIFICATION_FAILED: -70346,
+    /** 票据因过期原因校验失败 */
+    ERR_SERVER_SSO_TICKET_EXPIRED: -70347,
+    /** 创建账号数量超过已购买预付费数量限制 */
+    ERR_SERVER_SSO_ACCOUNT_EXCEED_PURCHASES: -70398,
+    /** 服务器内部错误,请重试 */
+    ERR_SERVER_SSO_INTERNAL_ERROR: -70500,
+};
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                     (二)错误码(警告)
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * @memberof ErrorCode
+ * @typedef 错误码(警告)
+ * @description SDK 错误码(警告)对照表
+ * | 符号 | 值 | 含义 |
+ * |---|---|---|
+ * |WARNING_HW_ENCODER_START_FAIL|1103|硬编码启动出现问题,自动切换到软编码|
+ * |WARNING_VIDEO_ENCODER_SW_TO_HW|1107|当前 CPU 使用率太高,无法满足软件编码需求,自动切换到硬件编码|
+ * |WARNING_INSUFFICIENT_CAPTURE_FPS|1108|摄像头采集帧率不足,部分自带美颜算法的 Android 手机上会出现|
+ * |WARNING_SW_ENCODER_START_FAIL|1109|软编码启动失败|
+ * |WARNING_REDUCE_CAPTURE_RESOLUTION|1110|摄像头采集分辨率被降低,以满足当前帧率和性能最优解。|
+ * |WARNING_VIDEO_FRAME_DECODE_FAIL|2101|当前视频帧解码失败|
+ * |WARNING_AUDIO_FRAME_DECODE_FAIL|2102|当前音频帧解码失败|
+ * |WARNING_VIDEO_PLAY_LAG|2105|当前视频播放出现卡顿|
+ * |WARNING_HW_DECODER_START_FAIL|2106|硬解启动失败,采用软解码|
+ * |WARNING_VIDEO_DECODER_HW_TO_SW|2108|当前流硬解第一个 I 帧失败,SDK 自动切软解|
+ * |WARNING_SW_DECODER_START_FAIL|2109|软解码器启动失败|
+ * |WARNING_VIDEO_RENDER_FAIL|2110|视频渲染失败|
+ * |WARNING_AUDIO_RECORDING_WRITE_FAIL|7001|音频录制写入文件失败|
+ * |WARNING_ROOM_DISCONNECT|5101|网络断开连接|
+ * |WARNING_IGNORE_UPSTREAM_FOR_AUDIENCE|6001|当前是观众角色,忽略上行音视频数据|
+ */
+export const TXLiteAVWarning = {
+    /** 硬编码启动出现问题,自动切换到软编码 */
+    WARNING_HW_ENCODER_START_FAIL: 1103,
+    /** 当前 CPU 使用率太高,无法满足软件编码需求,自动切换到硬件编码 */
+    WARNING_VIDEO_ENCODER_SW_TO_HW: 1107,
+    /** 摄像头采集帧率不足,部分自带美颜算法的 Android 手机上会出现 */
+    WARNING_INSUFFICIENT_CAPTURE_FPS: 1108,
+    /** 软编码启动失败 */
+    WARNING_SW_ENCODER_START_FAIL: 1109,
+    /** 摄像头采集分辨率被降低,以满足当前帧率和性能最优解。 */
+    WARNING_REDUCE_CAPTURE_RESOLUTION: 1110,
+    /** 当前视频帧解码失败 */
+    WARNING_VIDEO_FRAME_DECODE_FAIL: 2101,
+    /** 当前音频帧解码失败 */
+    WARNING_AUDIO_FRAME_DECODE_FAIL: 2102,
+    /** 当前视频播放出现卡顿 */
+    WARNING_VIDEO_PLAY_LAG: 2105,
+    /** 硬解启动失败,采用软解码 */
+    WARNING_HW_DECODER_START_FAIL: 2106,
+    /** 当前流硬解第一个 I 帧失败,SDK 自动切软解 */
+    WARNING_VIDEO_DECODER_HW_TO_SW: 2108,
+    /** 软解码器启动失败 */
+    WARNING_SW_DECODER_START_FAIL: 2109,
+    /** 视频渲染失败 */
+    WARNING_VIDEO_RENDER_FAIL: 2110,
+    /** 音频录制写入文件失败 */
+    WARNING_AUDIO_RECORDING_WRITE_FAIL: 7001,
+    /** 网络断开连接 */
+    WARNING_ROOM_DISCONNECT: 5101,
+    /** 当前是观众角色,忽略上行音视频数据 */
+    WARNING_IGNORE_UPSTREAM_FOR_AUDIENCE: 6001,
+    /** 网络状况不佳:上行带宽太小,上传数据受阻 */
+    WARNING_NET_BUSY: 1101,
+    /** 直播,网络断连, 已启动自动重连(自动重连连续失败超过三次会放弃) */
+    WARNING_RTMP_SERVER_RECONNECT: 1102,
+    /** 直播,网络断连, 已启动自动重连(自动重连连续失败超过三次会放弃) */
+    WARNING_LIVE_STREAM_SERVER_RECONNECT: 2103,
+    /** 网络来包不稳:可能是下行带宽不足,或由于主播端出流不均匀 */
+    WARNING_RECV_DATA_LAG: 2104,
+    /** 直播,DNS 解析失败 */
+    WARNING_RTMP_DNS_FAIL: 3001,
+    /** 直播,服务器连接失败 */
+    WARNING_RTMP_SEVER_CONN_FAIL: 3002,
+    /** 直播,与 RTMP 服务器握手失败 */
+    WARNING_RTMP_SHAKE_FAIL: 3003,
+    /** 直播,服务器主动断开 */
+    WARNING_RTMP_SERVER_BREAK_CONNECT: 3004,
+    /** 直播,RTMP 读/写失败,将会断开连接 */
+    WARNING_RTMP_READ_WRITE_FAIL: 3005,
+    /** 直播,RTMP 写失败(SDK 内部错误码,不会对外抛出) */
+    WARNING_RTMP_WRITE_FAIL: 3006,
+    /** 直播,RTMP 读失败(SDK 内部错误码,不会对外抛出) */
+    WARNING_RTMP_READ_FAIL: 3007,
+    /** 直播,超过30s 没有数据发送,主动断开连接 */
+    WARNING_RTMP_NO_DATA: 3008,
+    /** 直播,connect 服务器调用失败(SDK 内部错误码,不会对外抛出) */
+    WARNING_PLAY_LIVE_STREAM_INFO_CONNECT_FAIL: 3009,
+    /** 直播,连接失败,该流地址无视频(SDK 内部错误码,不会对外抛出) */
+    WARNING_NO_STEAM_SOURCE_FAIL: 3010,
+    /** 网络断连,已启动自动重连 */
+    WARNING_ROOM_RECONNECT: 5102,
+    /** 网络状况不佳:上行带宽太小,上传数据受阻 */
+    WARNING_ROOM_NET_BUSY: 5103,
+};
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                     (三)JS 封装层抛出的异常(严重)
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * @namespace ErrorCode
+ * @description 错误码
+ */
+export const TXLiteJSError = {
+    /**
+     * 未知错误
+     * @default 0xFFFF
+     * @memberof module:ErrorCode
+     */
+    UNKNOWN: 0xffff,
+    /**
+     * 无效参数
+     *
+     * @default 0x1000
+     * @memberof module:ErrorCode
+     */
+    INVALID_PARAMETER: 0x1000,
+    /**
+     * 非法操作
+     *
+     * @default 0x1001
+     * @memberof module:ErrorCode
+     */
+    INVALID_OPERATION: 0x1001,
+};
+const getErrorName = function (code) {
+    for (let key in TXLiteJSError) {
+        if (TXLiteJSError[key] === code) {
+            return key;
+        }
+    }
+    return 'UNKNOWN';
+};
+/**
+ * TrtcError 错误对象<br>
+ * @extends Error
+ * @namespace ErrorCode
+ */
+class TrtcError extends Error {
+    constructor({ code = TXLiteJSError.UNKNOWN, message, extraInfo }) {
+        if (extraInfo) {
+            const tempError = {
+                errCode: code,
+                errMsg: message,
+                extraInfo: Object.assign(Object.assign({}, extraInfo), { errCodeUrl: errorCodeUrl }),
+            };
+            super(JSON.stringify(tempError));
+        }
+        else {
+            super(message +
+                ` <${getErrorName(code)} 0x${code.toString(16)}>. Refer to: ${errorCodeUrl}`);
+        }
+        this.errCode = code;
+        this.errMsg = message;
+        this.extraInfo = Object.assign(Object.assign({}, extraInfo), { errCodeUrl: errorCodeUrl });
+    }
+    /**
+     * 获取错误码<br>
+     * 详细错误码列表参见 {@link module:ErrorCode ErrorCode}
+     * @memberof TrtcError
+     */
+    getCode() {
+        return this.errCode;
+    }
+}
+export default TrtcError;
+export function generateError_(error, code = TXLiteJSError.UNKNOWN, extraInfo) {
+    return new TrtcError({
+        code: error.code || code,
+        message: `${NAME.LOG_PREFIX}${error.message}`,
+        extraInfo,
+    });
+}
+;

+ 484 - 0
TrtcCloud/lib/TrtcDefines.js

@@ -0,0 +1,484 @@
+/**
+ * TRTC 关键类型定义<br>
+ * @description 分辨率、质量等级等枚举和常量值的定义
+ */
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【(一)视频相关枚举值定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 视频分辨率<br>
+ * 此处仅定义横屏分辨率(如 640 × 360),如需使用竖屏分辨率(如 360 × 640),需要同时指定 VideoResolutionMode 为 Portrait
+ * @enum {Number}
+ */
+const TRTCVideoResolution_HACK_JSDOC = {
+    /** 宽高比 1:1;分辨率 120x120;建议码率(VideoCall)80kbps; 建议码率(LIVE)120kbps */
+    TRTCVideoResolution_120_120: 1,
+    /** 宽高比 1:1 分辨率 160x160;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps */
+    TRTCVideoResolution_160_160: 3,
+    /** 宽高比 1:1;分辨率 270x270;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */
+    TRTCVideoResolution_270_270: 5,
+    /** 宽高比 1:1;分辨率 480x480;建议码率(VideoCall)350kbps; 建议码率(LIVE)500kbps */
+    TRTCVideoResolution_480_480: 7,
+    /** 宽高比4:3;分辨率 160x120;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps */
+    TRTCVideoResolution_160_120: 50,
+    /** 宽高比 4:3;分辨率 240x180;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps */
+    TRTCVideoResolution_240_180: 52,
+    /** 宽高比 4:3;分辨率 280x210;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */
+    TRTCVideoResolution_280_210: 54,
+    /** 宽高比 4:3;分辨率 320x240;建议码率(VideoCall)250kbps; 建议码率(LIVE)375kbps */
+    TRTCVideoResolution_320_240: 56,
+    /** 宽高比 4:3;分辨率 400x300;建议码率(VideoCall)300kbps; 建议码率(LIVE)450kbps */
+    TRTCVideoResolution_400_300: 58,
+    /** 宽高比 4:3;分辨率 480x360;建议码率(VideoCall)400kbps; 建议码率(LIVE)600kbps */
+    TRTCVideoResolution_480_360: 60,
+    /** 宽高比 4:3;分辨率 640x480;建议码率(VideoCall)600kbps; 建议码率(LIVE)900kbps */
+    TRTCVideoResolution_640_480: 62,
+    /** 宽高比 4:3;分辨率 960x720;建议码率(VideoCall)1000kbps; 建议码率(LIVE)1500kbps */
+    TRTCVideoResolution_960_720: 64,
+    /** 宽高比 16:9;分辨率 160x90;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps */
+    TRTCVideoResolution_160_90: 100,
+    /** 宽高比 16:9;分辨率 256x144;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */
+    TRTCVideoResolution_256_144: 102,
+    /** 宽高比 16:9;分辨率 320x180;建议码率(VideoCall)250kbps; 建议码率(LIVE)400kbps */
+    TRTCVideoResolution_320_180: 104,
+    /** 宽高比 16:9;分辨率 480x270;建议码率(VideoCall)350kbps; 建议码率(LIVE)550kbps */
+    TRTCVideoResolution_480_270: 106,
+    /** 宽高比 16:9;分辨率 640x360;建议码率(VideoCall)500kbps; 建议码率(LIVE)900kbps */
+    TRTCVideoResolution_640_360: 108,
+    /** 宽高比 16:9;分辨率 960x540;建议码率(VideoCall)850kbps; 建议码率(LIVE)1300kbps */
+    TRTCVideoResolution_960_540: 110,
+    /** 宽高比 16:9;分辨率 1280x720;建议码率(VideoCall)1200kbps; 建议码率(LIVE)1800kbps */
+    TRTCVideoResolution_1280_720: 112,
+    /** 宽高比 16:9;分辨率 1920x1080;建议码率(VideoCall)2000kbps; 建议码率(LIVE)3000kbps */
+    TRTCVideoResolution_1920_1080: 114,
+};
+export var TRTCVideoResolution;
+(function (TRTCVideoResolution) {
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_120_120"] = 1] = "TRTCVideoResolution_120_120";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_160"] = 3] = "TRTCVideoResolution_160_160";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_270_270"] = 5] = "TRTCVideoResolution_270_270";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_480"] = 7] = "TRTCVideoResolution_480_480";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_120"] = 50] = "TRTCVideoResolution_160_120";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_240_180"] = 52] = "TRTCVideoResolution_240_180";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_280_210"] = 54] = "TRTCVideoResolution_280_210";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_320_240"] = 56] = "TRTCVideoResolution_320_240";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_400_300"] = 58] = "TRTCVideoResolution_400_300";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_360"] = 60] = "TRTCVideoResolution_480_360";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_640_480"] = 62] = "TRTCVideoResolution_640_480";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_960_720"] = 64] = "TRTCVideoResolution_960_720";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_90"] = 100] = "TRTCVideoResolution_160_90";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_256_144"] = 102] = "TRTCVideoResolution_256_144";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_320_180"] = 104] = "TRTCVideoResolution_320_180";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_270"] = 106] = "TRTCVideoResolution_480_270";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_640_360"] = 108] = "TRTCVideoResolution_640_360";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_960_540"] = 110] = "TRTCVideoResolution_960_540";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1280_720"] = 112] = "TRTCVideoResolution_1280_720";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1920_1080"] = 114] = "TRTCVideoResolution_1920_1080";
+})(TRTCVideoResolution || (TRTCVideoResolution = {}));
+/**
+ * 视频分辨率模式<br>
+ * TRTCVideoResolution 中仅定义了横屏分辨率(如 640 × 360),如需使用竖屏分辨率(如 360 × 640),需要同时指定 TRTCVideoResolutionMode 为 Portrait
+ * @enum {Number}
+ */
+const TRTCVideoResolutionMode_HACK_JSDOC = {
+    /** 横屏分辨率 */
+    TRTCVideoResolutionModeLandscape: 0,
+    /** 竖屏分辨率 */
+    TRTCVideoResolutionModePortrait: 1,
+};
+export var TRTCVideoResolutionMode;
+(function (TRTCVideoResolutionMode) {
+    TRTCVideoResolutionMode[TRTCVideoResolutionMode["TRTCVideoResolutionModeLandscape"] = 0] = "TRTCVideoResolutionModeLandscape";
+    TRTCVideoResolutionMode[TRTCVideoResolutionMode["TRTCVideoResolutionModePortrait"] = 1] = "TRTCVideoResolutionModePortrait";
+})(TRTCVideoResolutionMode || (TRTCVideoResolutionMode = {}));
+;
+/**
+ * 视频流类型<br>
+ * TRTC 内部有三种不同的音视频流,分别是:
+ * - 高清大画面:一般用来传输摄像头的视频数据
+ * - 低清小画面:小画面和大画面的内容相互,但是分辨率和码率都比大画面低,因此清晰度也更低
+ * - 辅流画面:一般用于屏幕分享,同一时间在同一个房间中只允许一个用户发布辅流视频,其他用户必须要等该用户关闭之后才能发布自己的辅流
+ *
+ * **Note:**
+ * - 不支持单独开启低清小画面,小画面必须依附于大画面而存在,SDK 会自动设定低清小画面的分辨率和码率
+ * @enum {Number}
+ */
+const TRTCVideoStreamType_HACK_JSDOC = {
+    /** 大画面视频流 */
+    TRTCVideoStreamTypeBig: 0,
+    /** 小画面视频流 */
+    TRTCVideoStreamTypeSmall: 1,
+    /** 辅流(屏幕分享) */
+    TRTCVideoStreamTypeSub: 2,
+};
+export var TRTCVideoStreamType;
+(function (TRTCVideoStreamType) {
+    TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeBig"] = 0] = "TRTCVideoStreamTypeBig";
+    TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeSmall"] = 1] = "TRTCVideoStreamTypeSmall";
+    TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeSub"] = 2] = "TRTCVideoStreamTypeSub";
+})(TRTCVideoStreamType || (TRTCVideoStreamType = {}));
+/**
+ * 画面来源<br>
+ * TRTC 内部有两种不同的画面来源,分别是:
+ * - TRTCSnapshotSourceTypeStream: 视频流画面
+ * - TRTCSnapshotSourceTypeView: 视频渲染画面
+ *
+ * **Note:**
+ * - 截取视频流画面(TRTCSnapshotSourceTypeStream)一般更清晰。
+ * @enum {Number}
+ */
+const TRTCSnapshotSourceType_HACK_JSDOC = {
+    /** 视频流画面 */
+    TRTCSnapshotSourceTypeStream: 0,
+    /** 视频渲染画面 */
+    TRTCSnapshotSourceTypeView: 1,
+};
+export var TRTCSnapshotSourceType;
+(function (TRTCSnapshotSourceType) {
+    TRTCSnapshotSourceType[TRTCSnapshotSourceType["TRTCSnapshotSourceTypeStream"] = 0] = "TRTCSnapshotSourceTypeStream";
+    TRTCSnapshotSourceType[TRTCSnapshotSourceType["TRTCSnapshotSourceTypeView"] = 1] = "TRTCSnapshotSourceTypeView";
+})(TRTCSnapshotSourceType || (TRTCSnapshotSourceType = {}));
+/**
+ * 视频画面填充模式<br>
+ * 如果画面的显示分辨率不等于画面的原始分辨率,就需要您设置画面的填充模式:
+ * - TRTCVideoFillMode_Fill,图像铺满屏幕,超出显示视窗的视频部分将被截掉,所以画面显示可能不完整。
+ * - TRTCVideoFillMode_Fit,图像长边填满屏幕,短边区域会被填充黑色,但画面的内容肯定是完整的。
+ * @enum {Number}
+ */
+const TRTCVideoFillMode_HACK_JSDOC = {
+    /** 图像铺满屏幕,超出显示视窗的视频部分将被截掉 */
+    TRTCVideoFillMode_Fill: 0,
+    /** 图像长边填满屏幕,短边区域会被填充黑色 */
+    TRTCVideoFillMode_Fit: 1,
+};
+export var TRTCVideoFillMode;
+(function (TRTCVideoFillMode) {
+    TRTCVideoFillMode[TRTCVideoFillMode["TRTCVideoFillMode_Fill"] = 0] = "TRTCVideoFillMode_Fill";
+    TRTCVideoFillMode[TRTCVideoFillMode["TRTCVideoFillMode_Fit"] = 1] = "TRTCVideoFillMode_Fit";
+})(TRTCVideoFillMode || (TRTCVideoFillMode = {}));
+;
+/**
+ * 视频画面旋转方向<br>
+ * TRTC SDK 提供了对本地和远程画面的旋转角度设置 API,如下的旋转角度都是指顺时针方向的。
+ * @enum {Number}
+ */
+const TRTCVideoRotation_HACK_JSDOC = {
+    /** 顺时针旋转0度 */
+    TRTCVideoRotation_0: 0,
+    /** 顺时针旋转90度 */
+    TRTCVideoRotation_90: 1,
+    /** 顺时针旋转180度 */
+    TRTCVideoRotation_180: 2,
+    /** 顺时针旋转270度 */
+    TRTCVideoRotation_270: 3,
+};
+export var TRTCVideoRotation;
+(function (TRTCVideoRotation) {
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_0"] = 0] = "TRTCVideoRotation_0";
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_90"] = 1] = "TRTCVideoRotation_90";
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_180"] = 2] = "TRTCVideoRotation_180";
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_270"] = 3] = "TRTCVideoRotation_270";
+})(TRTCVideoRotation || (TRTCVideoRotation = {}));
+/**
+ * 画面渲染镜像类型<br>
+ * TRTC 的画面镜像提供下列设置模式
+ * @enum {Number}
+ */
+const TRTCVideoMirrorType_HACK_JSDOC = {
+    /** 只适用于移动端, 本地预览时,前置摄像头镜像,后置摄像头不镜像 */
+    TRTCVideoMirrorType_Auto: 0,
+    /** 所有画面均镜像 */
+    TRTCVideoMirrorType_Enable: 1,
+    /** 所有画面均不镜像 */
+    TRTCVideoMirrorType_Disable: 2
+};
+export var TRTCVideoMirrorType;
+(function (TRTCVideoMirrorType) {
+    TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Auto"] = 0] = "TRTCVideoMirrorType_Auto";
+    TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Enable"] = 1] = "TRTCVideoMirrorType_Enable";
+    TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Disable"] = 2] = "TRTCVideoMirrorType_Disable";
+})(TRTCVideoMirrorType || (TRTCVideoMirrorType = {}));
+/**
+ * 美颜(磨皮)算法<br>
+ * TRTC SDK 内置了多种不同的磨皮算法,您可以选择最适合您产品定位的方案。
+ * @enum {Number}
+ */
+const TRTCBeautyStyle_HACK_JSDOC = {
+    /** 光滑,算法比较激进,磨皮效果比较明显,适用于秀场直播 */
+    TRTCBeautyStyleSmooth: 0,
+    /** 自然,算法更多地保留了面部细节,磨皮效果更加自然,适用于绝大多数直播场景 */
+    TRTCBeautyStyleNature: 1,
+    /** 优图,由优图实验室提供,磨皮效果介于光滑和自然之间,比光滑保留更多皮肤细节,比自然磨皮程度更高 */
+    TRTCBeautyStylePitu: 2,
+};
+export var TRTCBeautyStyle;
+(function (TRTCBeautyStyle) {
+    TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStyleSmooth"] = 0] = "TRTCBeautyStyleSmooth";
+    TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStyleNature"] = 1] = "TRTCBeautyStyleNature";
+    TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStylePitu"] = 2] = "TRTCBeautyStylePitu";
+})(TRTCBeautyStyle || (TRTCBeautyStyle = {}));
+/**
+ * 背景音效<br>
+ * @enum {Number}
+ */
+export class AudioMusicParam {
+    constructor(id, path, loopCount, publish, isShortFile, startTimeMS, endTimeMS) {
+        this.id = id;
+        this.path = path;
+        this.loopCount = loopCount;
+        this.publish = publish;
+        this.isShortFile = isShortFile;
+        this.startTimeMS = startTimeMS;
+        this.endTimeMS = endTimeMS;
+    }
+}
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【(二)网络相关枚举值定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 应用场景<br>
+ * TRTC 可用于视频会议和在线直播等多种应用场景,针对不同的应用场景,TRTC SDK 的内部会进行不同的优化配置:
+ * - TRTCAppSceneVideoCall    :视频通话场景,适合[1对1视频通话]、[300人视频会议]、[在线问诊]、[视频聊天]、[远程面试]等。
+ * - TRTCAppSceneLIVE         :视频互动直播,适合[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。
+ * - TRTCAppSceneAudioCall    :语音通话场景,适合[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。
+ * - TRTCAppSceneVoiceChatRoom:语音互动直播,适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。
+ * @enum {Number}
+ */
+const TRTCAppScene_HACK_JSDOC = {
+    /**
+     * 视频通话场景,支持720P、1080P高清画质,单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     * 适合:[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。<br>
+     * 注意:此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。
+     */
+    TRTCAppSceneVideoCall: 0,
+    /**
+     * 视频互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     * 在线直播场景,内部编码器和网络协议优化侧重性能和兼容性,性能和清晰度表现更佳。
+     */
+    TRTCAppSceneLIVE: 1,
+    /**
+     * 语音通话场景,支持 48kHz,支持双声道。单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     * 适合:[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。
+     */
+    TRTCAppSceneAudioCall: 2,
+    /**
+     * 语音互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     * 适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。<br>
+     * 注意:此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。
+     */
+    TRTCAppSceneVoiceChatRoom: 3,
+};
+export var TRTCAppScene;
+(function (TRTCAppScene) {
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneVideoCall"] = 0] = "TRTCAppSceneVideoCall";
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneLIVE"] = 1] = "TRTCAppSceneLIVE";
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneAudioCall"] = 2] = "TRTCAppSceneAudioCall";
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneVoiceChatRoom"] = 3] = "TRTCAppSceneVoiceChatRoom";
+})(TRTCAppScene || (TRTCAppScene = {}));
+/**
+ * 角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom)<br>
+ * 在直播场景中,多数用户只是观众,只有个别用户是主播,这种角色区分可以有利于 TRTC 进行更好的定向优化。
+ * - Anchor:主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。
+ * - Audience:观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。
+ *
+ * @enum {Number}
+ */
+const TRTCRoleType_HACK_JSDOC = {
+    /** 主播 */
+    TRTCRoleAnchor: 20,
+    /** 观众 */
+    TRTCRoleAudience: 21,
+};
+export var TRTCRoleType;
+(function (TRTCRoleType) {
+    TRTCRoleType[TRTCRoleType["TRTCRoleAnchor"] = 20] = "TRTCRoleAnchor";
+    TRTCRoleType[TRTCRoleType["TRTCRoleAudience"] = 21] = "TRTCRoleAudience";
+})(TRTCRoleType || (TRTCRoleType = {}));
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【(三)音频相关枚举值定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 音频质量<br>
+ * @enum {Number}
+ */
+const TRTCAudioQuality_HACK_JSDOC = {
+    /** 人声模式:适用于以人声沟通为主的应用场景,该模式下音频传输的抗性较强,TRTC 会通过各种人声处理技术保障在弱网络环境下的流畅度最佳 */
+    TRTCAudioQualitySpeech: 1,
+    /** 标准模式(或者默认模式):介于 Speech 和 Music 之间的档位,对音乐的还原度比人声模式要好,但传输数据量比音乐模式要低很多,对各种场景均有不错的适应性,如无特殊需求推荐选择之。 */
+    TRTCAudioQualityDefault: 2,
+    /** 音乐模式:适用于对声乐要求很苛刻的场景,该模式下音频传输的数据量很大,TRTC 会通过各项技术确保音乐信号在各频段均能获得高保真的细节还原度 */
+    TRTCAudioQualityMusic: 3
+};
+export var TRTCAudioQuality;
+(function (TRTCAudioQuality) {
+    TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualitySpeech"] = 1] = "TRTCAudioQualitySpeech";
+    TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualityDefault"] = 2] = "TRTCAudioQualityDefault";
+    TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualityMusic"] = 3] = "TRTCAudioQualityMusic";
+})(TRTCAudioQuality || (TRTCAudioQuality = {}));
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                      【(四)TRTC 核心类型定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 进房相关参数<br>
+ * 只有该参数填写正确,才能顺利调用 enterRoom 进入 roomId 所指定的音视频房间。
+ * @param {Number}       sdkAppId      - 【字段含义】应用标识(必填),腾讯视频云基于 sdkAppId 完成计费统计。<br>
+ *                                       【推荐取值】在腾讯云 [TRTC 控制台](https://console.cloud.tencent.com/rav/) 中创建应用,之后可以在账号信息页面中得到该 ID。<br>
+ * @param {String}       userId        - 【字段含义】用户标识(必填)。当前用户的 userId,相当于用户名,UTF-8编码。<br>
+ *                                       【推荐取值】如果一个用户在您的账号系统中的 ID 为“abc”,则 userId 即可设置为“abc”。<br>
+ * @param {String}       userSig       - 【字段含义】用户签名(必填),当前 userId 对应的验证签名,相当于登录密码。<br>
+ *                                       【推荐取值】请参考 [如何计算UserSig](https://cloud.tencent.com/document/product/647/17275)。<br>
+ * @param {Number}       roomId        - 【字段含义】房间号码(必填),指定房间号,在同一个房间里的用户(userId)可以彼此看到对方并进行视频通话, roomId 和 strRoomId 必须填一个, 若您选用 strRoomId,则 roomId 需要填写为0。<br>
+ *                                       【推荐取值】您可以随意指定,但请不要重复,如果您的用户账号 ID 是数字类型的,可以直接用创建者的用户 ID 作为 roomId。<br>
+ * @param {String}       strRoomId     - 【字段含义】字符串房间号码(选填),roomId 和 strRoomId 必须填一个。若两者都填,则优先选择 roomId。<br>
+ *                                       【推荐取值】您可以随意指定,但请不要重复。<br>
+ * @param {TRTCRoleType} role          - 【字段含义】直播场景下的角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom),视频通话场景下指定无效。<br>
+ *                                       【推荐取值】默认值:主播(TRTCRoleAnchor)<br>
+ * @param {String}       privateMapKey - 【字段含义】房间签名(非必填),如果您希望某个房间只能让特定的某些 userId 进入,就需要使用 privateMapKey 进行权限保护。<br>
+ *                                       【推荐取值】仅建议有高级别安全需求的客户使用,参考文档:[进房权限保护](https://cloud.tencent.com/document/product/647/32240)<br>
+ * @param {String}       businessInfo  - 【字段含义】业务数据(非必填),某些非常用的高级特性才需要用到此字段。<br>
+ *                                       【推荐取值】不建议使用<br>
+ * @param {String}       streamId      - 【字段含义】绑定腾讯云直播 CDN 流 ID[非必填],设置之后,您就可以在腾讯云直播 CDN 上通过标准直播方案(FLV或HLS)播放该用户的音视频流。<br>
+ *                                       【推荐取值】限制长度为64字节,可以不填写,一种推荐的方案是使用 “sdkappid_roomid_userid_main” 作为 streamid,这样比较好辨认且不会在您的多个应用中发生冲突。<br>
+ *                                       【特殊说明】要使用腾讯云直播 CDN,您需要先在[控制台](https://console.cloud.tencent.com/trtc/) 中的功能配置页开启“启动自动旁路直播”开关。<br>
+ *                                       【参考文档】[CDN 旁路直播](https://cloud.tencent.com/document/product/647/16826)。
+ * @param {String}       userDefineRecordId - 【字段含义】设置云端录制完成后的回调消息中的 "userdefinerecordid"  字段内容,便于您更方便的识别录制回调。<br>
+ *                                            【推荐取值】限制长度为64字节,只允许包含大小写英文字母(a-zA-Z)、数字(0-9)及下划线和连词符。<br>
+ *                                            【参考文档】[云端录制](https://cloud.tencent.com/document/product/647/16823)。
+ */
+export class TRTCParams {
+    constructor(sdkAppId, userId, roomId, userSig, strRoomId, privateMapKey, role, businessInfo, streamId, userDefineRecordId) {
+        this.sdkAppId = sdkAppId;
+        this.userId = userId;
+        this.roomId = roomId;
+        this.userSig = userSig;
+        this.strRoomId = strRoomId;
+        this.privateMapKey = privateMapKey;
+        this.role = role;
+        this.businessInfo = businessInfo;
+        this.streamId = streamId;
+        this.userDefineRecordId = userDefineRecordId;
+    }
+}
+/**
+ * 视频编码参数<br>
+ * 该设置决定了远端用户看到的画面质量(同时也是云端录制出的视频文件的画面质量)。
+ * @param {TRTCVideoResolution}     videoResolution - 【字段含义】 视频分辨率<br>
+ *                                                    【推荐取值】 <br>
+ *                                                     - 视频通话建议选择360 × 640及以下分辨率,resMode 选择 Portrait。<br>
+ *                                                     - 手机直播建议选择 540 × 960,resMode 选择 Portrait。<br>
+ *                                                     - Window 和 iMac 建议选择 640 × 360 及以上分辨率,resMode 选择 Landscape。
+ *                                                    【特别说明】 TRTCVideoResolution 默认只能横屏模式的分辨率,例如640 × 360。<br>
+ *                                                                如需使用竖屏分辨率,请指定 resMode 为 Portrait,例如640 × 360结合 Portrait 则为360 × 640。<br>
+ * @param {TRTCVideoResolutionMode} resMode         - 【字段含义】分辨率模式(横屏分辨率 - 竖屏分辨率)<br>
+ *                                                    【推荐取值】手机直播建议选择 Portrait,Window 和 Mac 建议选择 Landscape。<br>
+ *                                                    【特别说明】如果 videoResolution 指定分辨率 640 × 360,resMode 指定模式为 Portrait,则最终编码出的分辨率为360 × 640。<br>
+ * @param {Number}                  videoFps        - 【字段含义】视频采集帧率<br>
+ *                                                    【推荐取值】15fps 或 20fps,10fps 以下会有轻微卡顿感,5fps 以下卡顿感明显,20fps 以上的帧率则过于浪费(电影的帧率也只有 24fps)。<br>
+ *                                                    【特别说明】很多 Android 手机的前置摄像头并不支持15fps以上的采集帧率,部分过于突出美颜功能的 Android 手机前置摄像头的采集帧率可能低于10fps。<br>
+ * @param {Number}                  videoBitrate    - 【字段含义】视频上行码率<br>
+ *                                                    【推荐取值】推荐设置请参考本文件前半部分 TRTCVideoResolution 定义处的注释说明<br>
+ *                                                    【特别说明】码率太低会导致视频中有很多的马赛克<br>
+ * @param {Number}                  minVideoBitrate  -【字段含义】最低视频码率,SDK 会在网络不佳的情况下主动降低视频码率,最低会降至 minVideoBitrate 所设定的数值。
+ *                                                    【推荐取值】<br>
+ *                                                      - 如果您追求“允许卡顿但要保持清晰”的效果,可以设置 minVideoBitrate 为 videoBitrate 的 60%;
+ *                                                      - 如果您追求“允许模糊但要保持流畅”的效果,可以设置 minVideoBitrate 为 200kbps;
+ *                                                      - 如果您将 videoBitrate 和 minVideoBitrate 设置为同一个值,等价于关闭 SDK 的自适应调节能力;
+ *                                                      - 默认值:0,此时最低码率由 SDK 根据分辨率情况,自动设置合适的数值。<br>
+ *                                                    【特别说明】<br>
+ *                                                     - 当您把分辨率设置的比较高时,minVideoBitrate 不适合设置的太低,否则会出现画面模糊和大范围的马赛克宏块。
+ *                                                       比如把分辨率设置为 720p,把码率设置为 200kbps,那么编码出的画面将会出现大范围区域性马赛克。
+ * @param {Boolean}                 enableAdjustRes - 【字段含义】是否允许调整分辨率<br>
+ *                                                    【推荐取值】 <br>
+ *                                                     - 手机直播建议选择 NO。<br>
+ *                                                     - 视频通话模式,若更关注流畅性,建议选择 YES,此时若遇到带宽有限的弱网,SDK 会自动降低分辨率以保障更好的流畅度(仅针对 TRTCVideoStreamTypeBig 生效)。
+ *                                                     - 默认值:NO。<br>
+ *                                                    【特别说明】若有录制需求,选择 YES 时,请确保通话过程中,调整分辨率不会影响您的录制效果。<br>
+ */
+export class TRTCVideoEncParam {
+    constructor(videoResolution = TRTCVideoResolution.TRTCVideoResolution_640_360, resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait, videoFps = 15, videoBitrate = 550, minVideoBitrate = 0, enableAdjustRes = false) {
+        this.videoResolution = videoResolution;
+        this.videoResolutionMode = resMode;
+        this.videoFps = videoFps;
+        this.videoBitrate = videoBitrate;
+        this.minVideoBitrate = minVideoBitrate;
+        this.enableAdjustRes = enableAdjustRes;
+    }
+}
+;
+/**
+ * 画面渲染参数<br>
+ * 您可以通过设置此参数来控制画面的旋转、填充、镜像模式
+ * @param {TRTCVideoRotation} rotation  - 【字段含义】视频画面旋转方向
+ * @param {TRTCVideoFillMode} fillMode  - 【字段含义】视频画面填充模式
+ * @param {TRTCVideoMirrorType} mirrorType  - 【字段含义】画面渲染镜像类型
+ */
+export class TRTCRenderParams {
+    constructor(rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fit, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Disable) {
+        this.rotation = rotation;
+        this.fillMode = fillMode;
+        this.mirrorType = mirrorType;
+    }
+}
+/**
+ * 屏幕分享参数(仅适用于 Android 平台)<br>
+ * 该设置决定了远端用户看到的画面质量(同时也是云端录制出的视频文件的画面质量)。
+ * @param {Boolean} enableForegroundService - 是否同时启用 SDK 内置的前台服务,停止屏幕分享时会停止该服务。
+ * 从 Android 10 开始,如果 APP 的 targetSdkVersion 大于等于 29 时,
+ * 需要有 mediaProjection 类型的前台服务才能成功开始,否则会报 SecurityException。您可以自己启动一个前台服务,也可以使用 SDK 内置的前台服务。当使用内置的前台服务时 ** 您需要在 manifest.json 中添加以下内容:<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />**
+ */
+export class TRTCScreenShareParams {
+    constructor(enableForegroundService) {
+        this.enableForegroundService = enableForegroundService;
+    }
+}
+;
+/**
+ * 音频路由(即声音的播放模式)<br>
+ * @enum {Number}
+ */
+const TRTCAudioRoute_HACK_JSDOC = {
+    /** 使用扬声器播放(即“免提”),扬声器位于手机底部,声音偏大,适合外放音乐 */
+    TRTCAudioRouteSpeaker: 0,
+    /** 使用听筒播放,听筒位于手机顶部,声音偏小,适合需要保护隐私的通话场景 */
+    TRTCAudioRouteEarpiece: 1,
+};
+export var TRTCAudioRoute;
+(function (TRTCAudioRoute) {
+    TRTCAudioRoute[TRTCAudioRoute["TRTCAudioRouteSpeaker"] = 0] = "TRTCAudioRouteSpeaker";
+    TRTCAudioRoute[TRTCAudioRoute["TRTCAudioRouteEarpiece"] = 1] = "TRTCAudioRouteEarpiece";
+})(TRTCAudioRoute || (TRTCAudioRoute = {}));
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【其它参数】
+//
+/////////////////////////////////////////////////////////////////////////////////
+export var TRTCShareSource;
+(function (TRTCShareSource) {
+    TRTCShareSource["InApp"] = "InApp";
+    TRTCShareSource["ByReplaykit"] = "ByReplaykit";
+})(TRTCShareSource || (TRTCShareSource = {}));
+/**
+ * 重力感应开关(仅适用于移动端)<br>
+ * @enum {Number}
+ */
+const TRTCGSensorMode_HACK_JSDOC = {
+    /** 不适配重力感应,该模式是桌面平台上的默认值,该模式下,当前用户发布出去的视频画面不受重力感应方向变化的影响。 */
+    TRTC_GSENSOR_MODE_DISABLE: 0,
+    /** 适配重力感应,该模式是移动平台上的默认值,该模式下,当前用户发布出去的视频画面会跟随设备的重力感应方向进行相应的调整,同时本地预览画面保持方向不变。
+      SDK 目前支持的一种适配模式是:当手机或 Pad 上下颠倒时,为了保证远端用户看到的画面方向正常,SDK 会自动将发布出去的画面上下旋转180度。如果您的 APP 的界面层开启了重力感应自适应,推荐使用 UIFixLayout 模式。
+    */
+    TRTC_GSENSOR_MODE_UIAUTOLAYOUT: 1,
+};
+export var TRTCGSensorMode;
+(function (TRTCGSensorMode) {
+    TRTCGSensorMode[TRTCGSensorMode["TRTC_GSENSOR_MODE_DISABLE"] = 0] = "TRTC_GSENSOR_MODE_DISABLE";
+    TRTCGSensorMode[TRTCGSensorMode["TRTC_GSENSOR_MODE_UIAUTOLAYOUT"] = 1] = "TRTC_GSENSOR_MODE_UIAUTOLAYOUT";
+})(TRTCGSensorMode || (TRTCGSensorMode = {}));

+ 10 - 0
TrtcCloud/lib/constants.js

@@ -0,0 +1,10 @@
+export const NAME = {
+    ANDROID: 'android',
+    IOS: 'ios',
+    STRING: 'string',
+    FUNCTION: 'function',
+    BOOLEAN: 'boolean',
+    NUMBER: 'number',
+    LOG_PREFIX: '【UniApp-JS】',
+};
+export const errorCodeUrl = 'https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/ErrorCode.html';

+ 989 - 0
TrtcCloud/lib/index.js

@@ -0,0 +1,989 @@
+import TrtcCloudImpl from './TrtcCloudImpl';
+import { TRTCVideoStreamType } from './TrtcDefines';
+const version = '1.3.3';
+export * from './TrtcDefines';
+/**
+ * TrtcCloud
+ *
+ * @class TrtcCloud
+ */
+export default class TrtcCloud {
+    /**
+     * 创建 TrtcCloud 单例
+     *
+     * @static
+     * @memberof TrtcCloud
+     * @example
+     * TrtcCloud.createInstance();
+     */
+    static createInstance() {
+        console.log('----------------------------------------------------------------');
+        console.log(`                        SDK ${version}                    `);
+        console.log('----------------------------------------------------------------');
+        return TrtcCloudImpl._createInstance();
+    }
+    /**
+     * 销毁 TrtcCloud 单例
+     *
+     * @static
+     * @memberof TrtcCloud
+     * @example
+     * TrtcCloud.destroyInstance();
+     */
+    static destroyInstance() {
+        return TrtcCloudImpl._destroyInstance();
+    }
+    /**
+     * 设置 TrtcCloud 事件监听
+     *
+     * @param {String} event 事件名称
+     * @param {Function} callback 事件回调
+     * @memberof TrtcCloud
+     *
+     * @example
+     * this.trtcCloud = TrtcCloud.createInstance(); // 创建 trtcCloud 实例
+     * this.trtcCloud.on('onEnterRoom', (res) => {});
+     */
+    on(event, callback) {
+        return TrtcCloudImpl._getInstance().on(event, callback);
+    }
+    /**
+     * 取消事件绑定<br>
+     *
+     * @param {String} event 事件名称,传入通配符 '*' 会解除所有事件绑定。
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.off('onEnterRoom');
+     *
+     * this.trtcCloud.off('*'); // 取消所有绑定的事件
+     */
+    off(event) {
+        return TrtcCloudImpl._getInstance().off(event);
+    }
+    /**
+     * 进房<br>
+     * 调用接口后,您会收到来自 TRTCCallback 中的 [onEnterRoom(result)]{@link TRTCCallback#onEnterRoom} 回调
+     * 如果加入成功,result 会是一个正数(result > 0),表示加入房间所消耗的时间,单位是毫秒(ms)。<br>
+     * 如果加入失败,result 会是一个负数(result < 0),表示进房失败的错误码。
+     *
+     * * 参数 scene 的枚举值如下:
+     * - {@link TRTCAppSceneVideoCall}:<br>
+     *          视频通话场景,支持720P、1080P高清画质,单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     *          适合:[1对1视频通话]、[300人视频会议]、[在线问诊]、[视频聊天]、[远程面试]等。<br>
+     * - {@link TRTCAppSceneAudioCall}:<br>
+     *          语音通话场景,支持 48kHz,支持双声道。单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     *          适合:[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。<br>
+     * - {@link TRTCAppSceneLIVE}:<br>
+     *          视频互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     *          适合:[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。<br>
+     * - {@link TRTCAppSceneVoiceChatRoom}:<br>
+     *          语音互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     *          适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。<br>
+     *
+     * **Note:**
+     * 1. 当 scene 选择为 TRTCAppSceneLIVE 或 TRTCAppSceneVoiceChatRoom 时,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。
+     * 2. 不管进房是否成功,enterRoom 都必须与 exitRoom 配对使用,在调用 `exitRoom` 前再次调用 `enterRoom` 函数会导致不可预期的错误问题。
+     *
+     * @param {TRTCParams} params - 进房参数
+     * @param {Number} params.sdkAppId      - 应用标识(必填)
+     * @param {String} params.userId        - 用户标识(必填)
+     * @param {String} params.userSig       - 用户签名(必填)
+     * @param {Number} params.roomId        - 房间号码, roomId 和 strRoomId 必须填一个, 若您选用 strRoomId,则 roomId 需要填写为0。
+     * @param {String} params.strRoomId     - 字符串房间号码 [选填],在同一个房间内的用户可以看到彼此并进行视频通话, roomId 和 strRoomId 必须填一个。若两者都填,则优先选择 roomId
+     * @param {TRTCRoleType} params.role    - 直播场景下的角色,默认值:主播
+     * - TRTCRoleAnchor: 主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。
+     * - TRTCRoleAudience: 观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。
+     * @param {String=} params.privateMapKey - 房间签名(非必填)
+     * @param {String=} params.businessInfo  - 业务数据(非必填)
+     * @param {String=} params.streamId      - 自定义 CDN 播放地址(非必填)
+     * @param {String=} params.userDefineRecordId - 设置云端录制完成后的回调消息中的 "userdefinerecordid" 字段内容,便于您更方便的识别录制回调(非必填)
+     * @param {TRTCAppScene} scene 应用场景,目前支持视频通话(TRTCAppSceneVideoCall)、语音通话(TRTCAppSceneAudioCall)、在线直播(TRTCAppSceneLIVE)、语音聊天室(VTRTCAppSceneVoiceChatRoom)四种场景,
+     * 详见 [TrtcDefines] 中 TRTCAppScene 参数定义
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCAppScene } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud = TrtcCloud.createInstance(); // 创建实例,只需创建一次
+     * const params = {
+     *   sdkAppId: 0,
+     *   userId: 'xxx',
+     *   roomId: 12345,
+     *   userSig: 'xxx'
+     * };
+     * this.trtcCloud.enterRoom(params, TRTCAppScene.TRTCAppSceneVideoCall);
+     */
+    enterRoom(params, scene) {
+        return TrtcCloudImpl._getInstance().enterRoom(params, scene);
+    }
+    /**
+     * 退房<br>
+     * 执行退出房间的相关逻辑释放资源后,SDK 会通过 `onExitRoom()` 回调通知到您
+     *
+     * **Note:**
+     * 1. 如果您要再次调用 `enterRoom()` 或者切换到其它的音视频 SDK,请等待 `onExitRoom()` 回调到来后再执行相关操作,否则可能会遇到如摄像头、麦克风设备被强占等各种异常问题。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.exitRoom();
+     */
+    exitRoom() {
+        return TrtcCloudImpl._getInstance().exitRoom();
+    }
+    /**
+     * 切换角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom)
+     *
+     * 在直播场景下,一个用户可能需要在“观众”和“主播”之间来回切换。
+     * 您可以在进房前通过 TRTCParams 中的 role 字段确定角色,也可以通过 switchRole 在进房后切换角色。
+     *
+     * @param {TRTCRoleType} role - 目标角色,默认为主播
+     * - TRTCRoleAnchor: 主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。
+     * - TRTCRoleAudience: 观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCRoleType } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.switchRole(TRTCRoleType.TRTCRoleAudience);
+     */
+    switchRole(role) {
+        return TrtcCloudImpl._getInstance().switchRole(role);
+    }
+    /**
+     * 请求跨房通话
+     *
+     * 默认情况下,只有同一个房间中的用户之间可以进行音视频通话,不同的房间之间的音视频流是相互隔离的。
+     * 使用该接口让身处两个不同房间中的主播进行跨房间的音视频流分享,从而让每个房间中的观众都能观看到这两个主播的音视频。
+     * 跨房通话的请求结果会通过监听 [onConnectOtherRoom](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TRTCCallback.html#event:onConnectOtherRoom) 事件通知给您。
+     *
+     * @param {Object} params - 跨房通话参数
+     * - 如果对端的房间号为数字,那么传入的参数为 roomId。
+     * - 如果对端的房间号为字符串,那么传入的参数为 strRoomId。
+     * - 针对对端的房间号类型传递对应参数,不需要两个同时传递。具体请看 example 的使用。
+     * @param {Number} params.roomId 跨房通话时对端的数字房间号 roomId(与 strRoomId 选填其中一个,不可同时传递)
+     * @param {String} params.strRoomId 跨房通话时对端的字符串房间号 strRoomId(与 roomId 选填其中一个,不可同时传递)
+     * @param {String} params.userId 跨房通话时对端的 userId(必填)
+     *
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.connectOtherRoom({"roomId": 1233, "userId": "user_11"});
+     * this.trtcCloud.connectOtherRoom({"strRoomId": "1233", "userId": "user_22"});
+     */
+    connectOtherRoom(params) {
+        return TrtcCloudImpl._getInstance().connectOtherRoom(params);
+    }
+    /**
+     * 退出跨房通话
+     *
+     * 退出跨房通话的请求结果会通过监听 [onDisconnectOtherRoom](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TRTCCallback.html#event:onDisconnectOtherRoom) 事件通知给您。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.disconnectOtherRoom();
+     */
+    disconnectOtherRoom() {
+        return TrtcCloudImpl._getInstance().disconnectOtherRoom();
+    }
+    /**
+     * 开启本地视频的预览画面<br>
+     * 当开始渲染首帧摄像头画面时,您会收到 `onFirstVideoFrame(null)` 回调
+     *
+     * @param {Boolean} isFrontCamera 前置、后置摄像头,true:前置摄像头;false:后置摄像头,**默认为 true**
+     * @param {String=} viewId 用于承载视频画面的渲染控件,使用原生插件中的 TRTCCloudUniPlugin-TXLocalViewComponent component,需要提供 viewId 属性值,例如 viewId=userId
+     * @memberof TrtcCloud
+     * @example
+     * // 预览本地画面
+     * const viewId = this.userId;
+     * this.trtcCloud.startLocalPreview(true, viewId);
+     */
+    startLocalPreview(isFrontCamera = true, viewId) {
+        return TrtcCloudImpl._getInstance().startLocalPreview(isFrontCamera, viewId);
+    }
+    /**
+     * 设置视频编码器的编码参数
+     * - 该设置能够决定远端用户看到的画面质量,同时也能决定云端录制出的视频文件的画面质量。
+     * @param {TRTCVideoEncParam} param 用于设置视频编码器的相关参数
+     * @memberof TrtcCloud
+     * @example
+     *
+     * import { TRTCVideoResolution, TRTCVideoResolutionMode, TRTCVideoEncParam } from '@/TrtcCloud/lib/TrtcDefines';
+     * const videoResolution = TRTCVideoResolution.TRTCVideoResolution_480_360;
+     * const videoResolutionMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape; // 横屏采集
+     * const videoFps = 15;
+     * const videoBitrate = 900;
+     * const minVideoBitrate = 200;
+     * const enableAdjustRes = false;
+     * // const param = new TRTCVideoEncParam(videoResolution, videoResolutionMode, videoFps, videoBitrate, minVideoBitrate, enableAdjustRes); // v1.1.0 方式
+     *
+     * const param = { // v1.2.0 以上版本支持的方式
+     *  videoResolution,
+     *  videoResolutionMode,
+     *  videoFps,
+     *  videoBitrate,
+     *  minVideoBitrate,
+     *  enableAdjustRes,
+     * };
+     *
+     * this.trtcCloud.setVideoEncoderParam(param);
+     */
+    setVideoEncoderParam(param) {
+        return TrtcCloudImpl._getInstance().setVideoEncoderParam(param);
+    }
+    /**
+     * 切换前置或后置摄像头
+     *
+     * @param {Boolean} isFrontCamera 前置、后置摄像头,true:前置摄像头;false:后置摄像头
+     * @memberof TrtcCloud
+     * @example
+     * // 切换前置或后置摄像头
+     * const isFrontCamera = true;
+     * this.trtcCloud.switchCamera(isFrontCamera);
+     */
+    switchCamera(isFrontCamera) {
+        return TrtcCloudImpl._getInstance().switchCamera(isFrontCamera);
+    }
+    /**
+     * 停止本地视频采集及预览
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.stopLocalPreview();
+     */
+    stopLocalPreview() {
+        return TrtcCloudImpl._getInstance().stopLocalPreview();
+    }
+    /**
+     * 设置本地画面的渲染参数,可设置的参数包括有:画面的旋转角度、填充模式以及左右镜像等。
+     * @param {TRTCRenderParams} params - 本地图像的参数
+     * @param {TRTCVideoRotation} params.rotation - 图像的顺时针旋转角度,支持90、180以及270旋转角度,默认值:TRTCVideoRotation.TRTCVideoRotation_0
+     * @param {TRTCVideoFillMode} params.fillMode - 视频画面填充模式,填充(画面可能会被拉伸裁剪)或适应(画面可能会有黑边),默认值:TRTCVideoFillMode.TRTCVideoFillMode_Fill
+     * @param {TRTCVideoMirrorType} params.mirrorType - 画面镜像模式,默认值:TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType } from '@/TrtcCloud/lib/TrtcDefines';
+     * const renderParams = {
+     *  rotation: TRTCVideoRotation.TRTCVideoRotation_0,
+     *  fillMode: TRTCVideoFillMode.TRTCVideoFillMode_Fill,
+     *  mirrorType: TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     * };
+     * this.trtcCloud.setLocalRenderParams(renderParams);
+     */
+    setLocalRenderParams(params) {
+        return TrtcCloudImpl._getInstance().setLocalRenderParams(params);
+    }
+    /**
+     * 暂停/恢复发布本地的视频流
+     *
+     * 该接口可以暂停(或恢复)发布本地的视频画面,暂停之后,同一房间中的其他用户将无法继续看到自己画面。 该接口在指定 TRTCVideoStreamTypeBig 时等效于 start/stopLocalPreview 这两个接口,但具有更好的响应速度。 因为 start/stopLocalPreview 需要打开和关闭摄像头,而打开和关闭摄像头都是硬件设备相关的操作,非常耗时。 相比之下,muteLocalVideo 只需要在软件层面对数据流进行暂停或者放行即可,因此效率更高,也更适合需要频繁打开关闭的场景。 当暂停/恢复发布指定 TRTCVideoStreamTypeBig 后,同一房间中的其他用户将会收到 onUserVideoAvailable 回调通知。 当暂停/恢复发布指定 TRTCVideoStreamTypeSub 后,同一房间中的其他用户将会收到 onUserSubStreamAvailable 回调通知。
+     * @param {Number} streamType 要暂停/恢复的视频流类型(仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub)
+     * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteLocalVideo(TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
+     */
+    muteLocalVideo(streamType, mute) {
+        return TrtcCloudImpl._getInstance().muteLocalVideo(streamType, mute);
+    }
+    /**
+     * 显示远端视频或辅流<br>
+     *
+     * @param {String} userId 指定远端用户的 userId
+     * @param {Number} streamType 指定要观看 userId 的视频流类型
+     * - 高清大画面:TRTCVideoStreamType.TRTCVideoStreamTypeBig
+     * - 低清小画面:TRTCVideoStreamType.TRTCVideoStreamTypeSmall
+     * - 辅流(屏幕分享):TRTCVideoStreamType.TRTCVideoStreamTypeSub
+     * @param {String} viewId 用于承载视频画面的渲染控件,使用原生插件中的 TRTCCloudUniPlugin-TXRemoteViewComponent component,需要提供 viewId 属性值,例如 viewId=userId
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines';
+     * const viewId = this.remoteUserId;
+     * this.trtcCloud.startRemoteView(userId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, viewId);
+     */
+    startRemoteView(userId, streamType, viewId) {
+        return TrtcCloudImpl._getInstance().startRemoteView(userId, streamType, viewId);
+    }
+    /**
+     * 停止显示远端视频画面,同时不再拉取该远端用户的视频数据流<br>
+     * 指定要停止观看的 userId 的视频流类型
+     *
+     * @param {String} userId 指定的远端用户 ID
+     * @param {Number} streamType
+     * - 高清大画面:TRTCVideoStreamType.TRTCVideoStreamTypeBig
+     * - 低清小画面:TRTCVideoStreamType.TRTCVideoStreamTypeSmall
+     * - 辅流(屏幕分享):TRTCVideoStreamType.TRTCVideoStreamTypeSub
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.stopRemoteView(remoteUserId, TRTCVideoStreamType.TRTCVideoStreamTypeBig);
+     */
+    stopRemoteView(userId, streamType) {
+        return TrtcCloudImpl._getInstance().stopRemoteView(userId, streamType);
+    }
+    /**
+     * 设置远端画面的渲染参数,可设置的参数包括有:画面的旋转角度、填充模式以及左右镜像等。
+     * @param {String} userId 远端用户 ID
+     * @param {Number} streamType 可以设置为主路画面(TRTCVideoStreamTypeBig)或辅路画面(TRTCVideoStreamTypeSub)
+     * @param {TRTCRenderParams} params - 图像的参数
+     * @param {TRTCVideoRotation} params.rotation - 图像的顺时针旋转角度,支持90、180以及270旋转角度,默认值:TRTCVideoRotation.TRTCVideoRotation_0
+     * @param {TRTCVideoFillMode} params.fillMode - 视频画面填充模式,填充(画面可能会被拉伸裁剪)或适应(画面可能会有黑边),默认值:TRTCVideoFillMode.TRTCVideoFillMode_Fill
+     * @param {TRTCVideoMirrorType} params.mirrorType - 画面镜像模式,默认值:TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType } from '@/TrtcCloud/lib/TrtcDefines';
+     * const renderParams = {
+     *  rotation: TRTCVideoRotation.TRTCVideoRotation_0,
+     *  fillMode: TRTCVideoFillMode.TRTCVideoFillMode_Fill,
+     *  mirrorType: TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     * };
+     * this.trtcCloud.setRemoteRenderParams(userId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, renderParams);
+     */
+    setRemoteRenderParams(userId, streamType, params) { }
+    /**
+     * 设置视频编码器输出的画面方向<br>
+     * 该设置不影响本地画面的预览方向,但会影响房间中其他用户所观看到(以及云端录制文件)的画面方向。
+     * 当用户将手机或 Pad 上下颠倒时,由于摄像头的采集方向没有变,所以房间中其他用户所看到的画面会变成上下颠倒的,
+     * 在这种情况下,您可以通过调用该接口将 SDK 编码出的画面方向旋转180度,如此一来,房间中其他用户所看到的画面可保持正常的方向。
+     * 如果您希望实现上述这种友好的交互体验,我们更推荐您直接调用 setGSensorMode 实现更加智能的方向适配,无需您手动调用本接口。
+     * @param {Number} rotation 目前支持 0、90、180、270 两个旋转角度,默认值:TRTCVideoRotation_0,即不旋转。
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoRotation } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.setVideoEncoderRotation(TRTCVideoRotation.TRTCVideoRotation_90);
+     */
+    setVideoEncoderRotation(rotation) {
+        return TrtcCloudImpl._getInstance().setVideoEncoderRotation(rotation);
+    }
+    /**
+     * 设置编码器输出的画面镜像模式
+     * @param {Boolean} mirror 是否开启远端镜像,true:开启远端画面镜像;false:关闭远端画面镜像,默认值:false。
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.setVideoEncoderMirror(true);
+     */
+    setVideoEncoderMirror(mirror) {
+        return TrtcCloudImpl._getInstance().setVideoEncoderMirror(mirror);
+    }
+    /**
+     * 设置重力感应的适配模式<br>
+     * 您可以通过本接口实现如下这种友好的交互体验:
+     * 当用户将手机或 Pad 上下颠倒时,由于摄像头的采集方向没有变,所以房间中其他用户所看到的画面会变成上下颠倒的,
+     * 在这种情况下,您可以通过调用该接口让 SDK 根据设备陀螺仪的朝向自动调整本地画面和编码器输出画面的旋转方向,以使远端观众可以看到正常朝向的画面。
+     * @param {Number} mode 重力感应模式,详情请参见 TRTCGSensorMode,默认值:TRTCGSensorMode_UIAutoLayout。。
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCGSensorMode } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.setGSensorMode(TRTCGSensorMode.TRTC_GSENSOR_MODE_DISABLE);
+     */
+    setGSensorMode(mode) {
+        return TrtcCloudImpl._getInstance().setGSensorMode(mode);
+    }
+    /**
+     * 视频画面截图
+     *
+     * 您可以通过本接口截取本地的视频画面,远端用户的主路画面以及远端用户的辅路(屏幕分享)画面。
+     *
+     * @param {String | null} userId 用户 ID,如指定 null 表示截取本地的视频画面
+     * @param {Number} streamType 视频流类型,可选择截取主路画面(TRTCVideoStreamTypeBig,常用于摄像头)或辅路画面(TRTCVideoStreamTypeSub,常用于屏幕分享)
+     * @param {TRTCSnapshotSourceType} sourceType 画面来源,可选择截取视频流画面(TRTCSnapshotSourceTypeStream)或视频渲染画面(TRTCSnapshotSourceTypeView),前者一般更清晰
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.snapshotVideo(null, TRTCVideoStreamType.TRTCVideoStreamTypeBig, TRTCSnapshotSourceType.TRTCSnapshotSourceTypeStream); // 截取本地视频流画面
+     * this.trtcCloud.snapshotVideo(this.remoteUserId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, TRTCSnapshotSourceType.TRTCSnapshotSourceTypeView); // 截取远端指定用户视频渲染画面
+     */
+    snapshotVideo(userId, streamType, sourceType) {
+        return TrtcCloudImpl._getInstance().snapshotVideo(userId, streamType, sourceType);
+    }
+    /**
+     * 开启本地音频的采集和上行, 并设置音频质量<br>
+     * 该函数会启动麦克风采集,并将音频数据传输给房间里的其他用户。 SDK 不会默认开启本地音频采集和上行,您需要调用该函数开启,否则房间里的其他用户将无法听到您的声音<br>
+     * 主播端的音质越高,观众端的听感越好,但传输所依赖的带宽也就越高,在带宽有限的场景下也更容易出现卡顿
+     *
+     * @param {TRTCAudioQuality} quality 声音音质
+     * - TRTCAudioQualitySpeech,流畅:采样率:16k;单声道;音频裸码率:16kbps;适合语音通话为主的场景,比如在线会议,语音通话。
+     * - TRTCAudioQualityDefault,默认:采样率:48k;单声道;音频裸码率:50kbps;SDK 默认的音频质量,如无特殊需求推荐选择之。
+     * - TRTCAudioQualityMusic,高音质:采样率:48k;双声道 + 全频带;音频裸码率:128kbps;适合需要高保真传输音乐的场景,比如在线K歌、音乐直播等
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCAudioQuality } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityDefault);
+     */
+    startLocalAudio(quality) {
+        return TrtcCloudImpl._getInstance().startLocalAudio(quality);
+    }
+    /**
+     * 关闭本地音频的采集和上行<br>
+     * 当关闭本地音频的采集和上行,房间里的其它成员会收到 `onUserAudioAvailable(false)` 回调通知
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.stopLocalAudio();
+     */
+    stopLocalAudio() {
+        return TrtcCloudImpl._getInstance().stopLocalAudio();
+    }
+    /**
+     * 静音本地的音频
+     *
+     * 当静音本地音频后,房间里的其它成员会收到 onUserAudioAvailable(false) 回调通知。
+     * 与 stopLocalAudio 不同之处在于,muteLocalAudio 并不会停止发送音视频数据,而是会继续发送码率极低的静音包。
+     * 在对录制质量要求很高的场景中,选择 muteLocalAudio 是更好的选择,能录制出兼容性更好的 MP4 文件。
+     * 这是由于 MP4 等视频文件格式,对于音频的连续性是要求很高的,简单粗暴地 stopLocalAudio 会导致录制出的 MP4 不易播放。
+     *
+     * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteLocalAudio(true);
+     */
+    muteLocalAudio(mute) {
+        return TrtcCloudImpl._getInstance().muteLocalAudio(mute);
+    }
+    /**
+     * 静音掉某一个用户的声音,同时不再拉取该远端用户的音频数据流
+     *
+     * @param {String}  userId - 用户 ID
+     * @param {Boolean} mute   - true:静音;false:非静音
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteRemoteAudio('denny', true);
+     */
+    muteRemoteAudio(userId, mute) {
+        return TrtcCloudImpl._getInstance().muteRemoteAudio(userId, mute);
+    }
+    /**
+     * 静音掉所有用户的声音,同时不再拉取该远端用户的音频数据流
+     *
+     * @param {Boolean} mute - true:静音;false:非静音
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteAllRemoteAudio(true);
+     */
+    muteAllRemoteAudio(mute) {
+        return TrtcCloudImpl._getInstance().muteAllRemoteAudio(mute);
+    }
+    /**
+     * 设置音频路由
+     *
+     * 设置“音频路由”,即设置声音是从手机的扬声器还是从听筒中播放出来,因此该接口仅适用于手机等移动端设备。 手机有两个扬声器:一个是位于手机顶部的听筒,一个是位于手机底部的立体声扬声器。
+     * 设置音频路由为听筒时,声音比较小,只有将耳朵凑近才能听清楚,隐私性较好,适合用于接听电话。 设置音频路由为扬声器时,声音比较大,不用将手机贴脸也能听清,因此可以实现“免提”的功能。
+     *
+     * @param {TRTCAudioRoute} route 音频路由,即声音由哪里输出(扬声器、听筒), 默认值:TRTCAudioRoute.TRTCAudioRouteSpeaker(扬声器),
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCAudioRoute } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.setAudioRoute(TRTCAudioRoute.TRTCAudioRouteSpeaker); // TRTCAudioRoute.TRTCAudioRouteEarpiece (听筒)
+     */
+    setAudioRoute(route) {
+        return TrtcCloudImpl._getInstance().setAudioRoute(route);
+    }
+    /**
+     * 启用或关闭音量大小提示
+     *
+     * 开启此功能后,SDK 会在 onUserVoiceVolume() 中反馈对每一路声音音量大小值的评估。
+     *
+     * **Note:**
+     * - 如需打开此功能,请在 startLocalAudio 之前调用才可以生效。
+     *
+     * @param {Number} interval - 设置 onUserVoiceVolume 回调的触发间隔,单位为ms,最小间隔为100ms,如果小于等于0则会关闭回调,建议设置为300ms
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.enableAudioVolumeEvaluation(300);
+     */
+    enableAudioVolumeEvaluation(interval) {
+        return TrtcCloudImpl._getInstance().enableAudioVolumeEvaluation(interval);
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      屏幕分享
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 设置屏幕分享(即辅路)的视频编码参数
+     *
+     * 该接口可以设定远端用户所看到的屏幕分享(即辅路)的画面质量,同时也能决定云端录制出的视频文件中屏幕分享的画面质量。 请注意如下两个接口的差异:
+     *  - setVideoEncoderParam 用于设置主路画面(TRTCVideoStreamTypeBig,一般用于摄像头)的视频编码参数。
+     *  - setSubStreamEncoderParam 用于设置辅路画面(TRTCVideoStreamTypeSub,一般用于屏幕分享)的视频编码参数。
+     *
+     * **Note:**
+     *  - 即使您使用主路传输屏幕分享(在调用 startScreenCapture 时设置 type=TRTCVideoStreamTypeBig),依然要使用 setSubStreamEncoderParam 设定屏幕分享的编码参数,而不要使用 setVideoEncoderParam
+     * @param {TRTCVideoEncParam} param	辅流编码参数,详情请参考 TRTCVideoEncParam。
+     * @memberof TrtcCloud
+     * @example
+     * const params = {
+     *   videoResolution: TRTCVideoResolution.TRTCVideoResolution_640_360,
+     *   videoResolutionMode: TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait,
+     *   videoFps: 15,
+     *   videoBitrate: 900,
+     *   minVideoBitrate: 200,
+     *   enableAdjustRes: false,
+     * };
+     * this.trtcCloud.setSubStreamEncoderParam(params);
+     */
+    setSubStreamEncoderParam(param) {
+        return TrtcCloudImpl._getInstance().setSubStreamEncoderParam(param);
+    }
+    /**
+     * 启动屏幕分享
+     *
+     * **Note:**
+     *  - 一个用户同时最多只能上传一条主路(TRTCVideoStreamTypeBig)画面和一条辅路(TRTCVideoStreamTypeSub)画面,
+     * 默认情况下,屏幕分享使用辅路画面,如果使用主路画面,建议您提前停止摄像头采集(stopLocalPreview)避免相互冲突。
+     *  - **仅支持 iOS 13.0 及以上系统,进行应用内的屏幕分享**
+     *  - **Android: UniApp 使用 SDK 内置的前台服务时,只需要将接口参数 enableForegroundService 设置为 true。**
+     *  - **Android: UniApp 自己启动前台,需要在 mediaProject 类型的前台服务成功后再启动屏幕分享。**
+     *
+     * @param {Number} streamType 屏幕分享使用的线路,可以设置为主路(TRTCVideoStreamTypeBig)或者辅路(TRTCVideoStreamTypeSub),推荐使用
+     * @param {TRTCVideoEncParam} encParams 屏幕分享的画面编码参数,可以设置为 null,表示让 SDK 选择最佳的编码参数(分辨率、码率等)。即使在调用 startScreenCapture 时设置 type=TRTCVideoStreamTypeBig,依然可以使用此接口更新屏幕分享的编码参数。
+     * @param {TRTCScreenShareParams} shareParams 您可以通过其中的 enableForegroundService 参数启用 SDK 内置的前台服务
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoResolution, TRTCVideoResolutionMode, TRTCVideoStreamType} from '@/TrtcCloud/lib/TrtcDefines';
+     * const encParams = {
+     *   videoResolution: TRTCVideoResolution.TRTCVideoResolution_640_360,
+     *   videoResolutionMode: TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait,
+     *   videoFps: 15,
+     *   videoBitrate: 900,
+     *   minVideoBitrate: 200,
+     *   enableAdjustRes: false,
+     * };
+     * const shareParams = {
+     *   enableForegroundService: true,
+     * };
+     * this.trtcCloud.startScreenCapture(TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams, shareParams);
+     */
+    startScreenCapture(streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams = null, shareParams = {}) {
+        return TrtcCloudImpl._getInstance().startScreenCapture(streamType, encParams, shareParams);
+    }
+    /**
+     * 停止屏幕分享
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.stopScreenCapture();
+     */
+    stopScreenCapture() {
+        return TrtcCloudImpl._getInstance().stopScreenCapture();
+    }
+    /**
+     * 暂停屏幕分享
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.pauseScreenCapture();
+     */
+    pauseScreenCapture() {
+        return TrtcCloudImpl._getInstance().pauseScreenCapture();
+    }
+    /**
+     * 恢复屏幕分享
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.resumeScreenCapture();
+     */
+    resumeScreenCapture() {
+        return TrtcCloudImpl._getInstance().resumeScreenCapture();
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      美颜 + 水印
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 设置美颜(磨皮)算法
+     * TRTC 内置多种不同的磨皮算法,您可以选择最适合您产品定位的方案
+     *
+     * **Note:**
+     * - 设置美颜前,先调用 `setBeautyLevel` 设置美颜级别。否则美颜级别为 0 表示关闭美颜
+     *
+     * @param {TRTCBeautyStyle} beautyStyle 美颜风格,TRTCBeautyStyleSmooth:光滑;TRTCBeautyStyleNature:自然;TRTCBeautyStylePitu:优图
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCBeautyStyle } from '@/TrtcCloud/lib/TrtcDefines';
+     * const beautyLevel = 5; // 美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。
+     * this.trtcCloud.setBeautyLevel(beautyLevel);
+     * this.trtcCloud.setBeautyStyle(TRTCBeautyStyle.TRTCBeautyStyleSmooth);
+     */
+    setBeautyStyle(beautyStyle) {
+        return TrtcCloudImpl._getInstance().setBeautyStyle(beautyStyle);
+    }
+    /**
+     * 设置美颜级别
+     * @param {Number} beautyLevel	美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * const beautyLevel = 5; // 美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。
+     * this.trtcCloud.setBeautyLevel(beautyLevel);
+     */
+    setBeautyLevel(beautyLevel) {
+        return TrtcCloudImpl._getInstance().setBeautyLevel(beautyLevel);
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      背景音效
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 开始播放背景音乐
+     * 每个音乐都需要您指定具体的 ID,您可以通过该 ID 对音乐的开始、停止、音量等进行设置。<br>
+     * **Note:**
+     * - 如果要多次播放同一首背景音乐,请不要每次播放都分配一个新的 ID,我们推荐使用相同的 ID。
+     * - 若您希望同时播放多首不同的音乐,请为不同的音乐分配不同的 ID 进行播放。
+     * - 如果使用同一个 ID 播放不同音乐,SDK 会先停止播放旧的音乐,再播放新的音乐。
+     *
+     * **Note:**<br>
+     * 在 uni-app 中 path 如何获取。
+     * - 使用 cdn 地址,例如:`path = https://web.sdk.qcloud.com/component/TUIKit/assets/uni-app/calling-bell-1.mp3;`
+     * - 使用本地绝对路径。
+     *     1. 通过 [uni.saveFile](https://zh.uniapp.dcloud.io/api/file/file.html#savefile) 获取保存后的相对路径(建议这种路径)。
+     *     2. 将上一步的相对路径转成绝对路径,[plus.io.convertLocalFileSystemURL](https://www.html5plus.org/doc/zh_cn/io.html#plus.io.convertLocalFileSystemURL)。
+     *
+     * @param {AudioMusicParam} musicParam 音乐参数
+     * @param {Number} musicParam.id 音乐 ID
+     * @param {String} musicParam.path 音效文件的完整路径或 URL 地址。支持的音频格式包括 MP3、AAC、M4A、WAV
+     * @param {Number} musicParam.loopCount 音乐循环播放的次数。取值范围为0 - 任意正整数,默认值:0。0表示播放音乐一次;1表示播放音乐两次;以此类推
+     * @param {Boolean} musicParam.publish 是否将音乐传到远端。true:音乐在本地播放的同时,远端用户也能听到该音乐;false:主播只能在本地听到该音乐,远端观众听不到。默认值:false。
+     * @param {Boolean} musicParam.isShortFile 播放的是否为短音乐文件。true:需要重复播放的短音乐文件;false:正常的音乐文件。默认值:false
+     * @param {Number} musicParam.startTimeMS 音乐开始播放时间点,单位: 毫秒。
+     * @param {Number} musicParam.endTimeMS 音乐结束播放时间点,单位: 毫秒,0 表示播放至文件结尾。
+     * @memberof TrtcCloud
+     * @example
+     * import { AudioMusicParam } from '@/TrtcCloud/lib/TrtcDefines';
+     * const musicParam = {
+     *  id: 1,
+     *  path: '',
+     *  loopCount: 1,
+     *  publish: true,
+     *  isShortFile: false,
+     *  startTimeMS: 0,
+     *  endTimeMS: 0,
+     * };
+     * this.trtcCloud.startPlayMusic(musicParam);
+     */
+    startPlayMusic(musicParam) {
+        return TrtcCloudImpl._getInstance().startPlayMusic(musicParam);
+    }
+    /**
+     * 停止播放背景音乐
+     * @param {Number} id	音乐 ID
+     *
+     * @memberof TrtcCloud
+     * @example
+     * const musicId = 5;
+     * this.trtcCloud.stopPlayMusic(musicId);
+     */
+    stopPlayMusic(id) {
+        return TrtcCloudImpl._getInstance().stopPlayMusic(id);
+    }
+    /**
+     * 暂停播放背景音乐
+     * @param {Number} id	音乐 ID
+     * @memberof TrtcCloud
+     * @example
+     * const musicId = 5;
+     * this.trtcCloud.pausePlayMusic(musicId);
+     */
+    pausePlayMusic(id) {
+        return TrtcCloudImpl._getInstance().pausePlayMusic(id);
+    }
+    /**
+     * 恢复播放背景音乐
+     * @param {Number} id	音乐 ID
+     * @memberof TrtcCloud
+     * @example
+     * const musicId = 5;
+     * this.trtcCloud.resumePlayMusic(musicId);
+     */
+    resumePlayMusic(id) {
+        return TrtcCloudImpl._getInstance().resumePlayMusic(id);
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                       设置 TRTCCallback 回调
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 设置 TrtcCloud 回调
+     *
+     * @example
+     * // 创建/使用/销毁 TrtcCloud 对象的示例代码:
+     * import TrtcCloud from '@/TrtcCloud/lib/index';
+     * this.trtcCloud = new TrtcCloud();
+     *
+     * // 添加事件监听的方法,事件关键字详见下方”通用事件回调“
+     * this.trtcCloud.on('onEnterRoom', (result) => {
+     *   if (result > 0) {
+     *     console.log(`enter room success, spend ${result}ms`);
+     *   } else {
+     *     console.log(`enter room failed, error code = ${result}`);
+     *   }
+     * });
+     *
+     * @namespace TRTCCallback
+     */
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      (一)事件回调
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 错误回调,表示 SDK 不可恢复的错误,一定要监听并分情况给用户适当的界面提示<br>
+     * @event TRTCCallback#onError
+     * @param {Number} code 错误码,[详见](https://cloud.tencent.com/document/product/647/38308#.E9.94.99.E8.AF.AF.E7.A0.81.E8.A1.A8)
+     * @param {String} message 错误信息
+     * @param {Object} extraInfo 扩展信息字段,个别错误码可能会带额外的信息帮助定位问题
+     */
+    onError(code, message, extraInfo) { }
+    /**
+     * 警告回调,用于告知您一些非严重性问题,例如出现卡顿或者可恢复的解码失败<br>
+     * @event TRTCCallback#onWarning
+     * @param {Number} code 警告码,[详见](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8)
+     * @param {String} message 警告信息
+     * @param {Object} extraInfo 扩展信息字段,个别警告码可能会带额外的信息帮助定位问题
+     */
+    onWarning(code, message, extraInfo) { }
+    /**
+     * 进房后的回调<br>
+     * 调用 `enterRoom()` 接口执行进房操作后,会收到 `onEnterRoom(result)` 回调<br>
+     * 如果加入成功,result 会是一个正数(result > 0),代表加入房间的时间消耗,单位是毫秒(ms)。<br>
+     * 如果加入失败,result 会是一个负数(result < 0),代表进房失败的错误码。
+     *
+     * @event TRTCCallback#onEnterRoom
+     * @param {Number} result 进房耗时
+     */
+    onEnterRoom(result) { }
+    /**
+     * 离开房间的事件回调<br>
+     * 调用 `exitRoom()` 接口会执行退出房间的相关逻辑,例如释放音视频设备资源和编解码器资源等。待资源释放完毕,会通过 `onExitRoom()` 回调通知到您<br>
+     *
+     * **Note:**
+     * - 如果您要再次调用 `enterRoom()` 或者切换到其他的音视频 SDK,请等待 `onExitRoom()` 回调到来之后再执行相关操作。 否则可能会遇到音频设备被占用等各种异常问题
+     *
+     * @event TRTCCallback#onExitRoom
+     * @param {Number} reason 离开房间原因,0:主动调用 exitRoom 退房;1:被服务器踢出当前房间;2:当前房间整个被解散
+     */
+    onExitRoom(reason) { }
+    /**
+     * 跨房通话事件回调<br>
+     * 调用 TRTCCloud 中的 [connectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#connectOtherRoom) 接口会将两个不同房间中的主播拉通视频通话,也就是所谓的“主播PK”功能。
+     * 调用者会收到 onConnectOtherRoom() 事件回调来获知跨房通话是否成功, 如果成功,两个房间中的所有用户都会收到来自另一个房间中的 PK 主播的 [onUserVideoAvailable()](http://127.0.0.1:5500/UniApp-TRTC-SDK/packages/TrtcCloud/docs/zh-cn/api/TRTCCallback.html#event:onUserVideoAvailable) 回调。
+     *
+     * @event TRTCCallback#onConnectOtherRoom
+     * @param {Object} params 调用 [connectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#connectOtherRoom) 接口返回值数据。
+     * - userId:跨房通话时对端 userId
+     * - errCode: [错误状态码](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8),返回0表示跨房通话成功。
+     * - errMsg: 状态信息,跨房通话成功返回 OK。
+     */
+    onConnectOtherRoom(params) { }
+    /**
+     * 结束跨房通话的结果回调<br>
+     * 调用 TRTCCloud 中的 [disconnectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#disconnectOtherRoom) 接口会将两个不同房间中的主播拉通视频通话,也就是所谓的“主播PK”功能。
+     * 调用者会收到 onDisconnectOtherRoom() 事件回调来获知结束跨房通话是否成功。
+     *
+     * @event TRTCCallback#onDisconnectOtherRoom
+     * @param {Object} params 调用 [disconnectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#disconnectOtherRoom) 失败时返回的错误数据。
+     * - errCode: [错误状态码](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8)。
+     * - errMsg: 错误信息。
+     */
+    onDisconnectOtherRoom(params) { }
+    /**
+     * 切换角色的事件回调<br>
+     * 调用 TRTCCloud 中的 switchRole() 接口会切换主播和观众的角色,该操作会伴随一个线路切换的过程, 待 SDK 切换完成后,会抛出 onSwitchRole() 事件回调
+     *
+     * @event TRTCCallback#onSwitchRole
+     * @param {Number} code 错误码,[详见](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8)
+     * @param {String} message 错误信息
+     */
+    onSwitchRole(code, message) { }
+    /**
+     * 开始渲染本地或远程用户的首帧画面<br>
+     * 如果 userId 为 null,代表开始渲染本地采集的摄像头画面,需要您先调用 `startLocalPreview` 触发。 如果 userId 不为 null,代表开始渲染远程用户的首帧画面,需要您先调用 `startRemoteView` 触发<br>
+     * 只有当您调用 `startLocalPreview()、startRemoteView() 或 startRemoteSubStreamView()` 之后,才会触发该回调
+     *
+     * @event TRTCCallback#onFirstVideoFrame
+     * @param {String} userId 本地或远程用户 ID,如果 userId === null 代表本地,userId !== null 代表远程
+     * @param {Number} streamType 视频流类型:摄像头或屏幕分享
+     * @param {Number} width 画面宽度
+     * @param {Number} height 画面高度
+     */
+    onFirstVideoFrame(userId, streamType, width, height) { }
+    /**
+     * 开始播放远程用户的首帧音频(本地声音暂不通知)<br>
+     * 如果 userId 为 null,代表开始渲染本地采集的摄像头画面,需要您先调用 `startLocalPreview` 触发。 如果 userId 不为 null,代表开始渲染远程用户的首帧画面,需要您先调用 `startRemoteView` 触发<br>
+     * 只有当您调用 `startLocalPreview()、startRemoteView() 或 startRemoteSubStreamView()` 之后,才会触发该回调
+     *
+     * @event TRTCCallback#onFirstAudioFrame
+     * @param {String} userId 远程用户 ID
+     */
+    onFirstAudioFrame(userId) { }
+    /**
+     * 截图完成时回调<br>
+     * @event TRTCCallback#onSnapshotComplete
+     * @param {String} base64Data 截图对应的 base64 数据
+     * @param {String} message 错误信息
+     */
+    onSnapshotComplete(base64Data, message) { }
+    /**
+     * 麦克风准备就绪
+     */
+    onMicDidReady() { }
+    /**
+     * 摄像头准备就绪
+     */
+    onCameraDidReady() { }
+    /**
+     * 网络质量:该回调每2秒触发一次,统计当前网络的上行和下行质量<br>
+     * userId 为本地用户 ID 代表自己当前的视频质量
+     *
+     * @param {String} localQuality 上行网络质量
+     * @param {String} remoteQuality 下行网络质量
+     */
+    onNetworkQuality(localQuality, remoteList) { }
+    /**
+     * 有用户加入当前房间<br>
+     * 出于性能方面的考虑,在两种不同的应用场景下,该通知的行为会有差别:<br>
+     * 通话场景(TRTCAppScene.TRTCAppSceneVideoCall 和 TRTCAppScene.TRTCAppSceneAudioCall):该场景下用户没有角色的区别,任何用户进入房间都会触发该通知。<br>
+     * 直播场景(TRTCAppScene.TRTCAppSceneLIVE 和 TRTCAppScene.TRTCAppSceneVoiceChatRoom ):该场景不限制观众的数量,如果任何用户进出都抛出回调会引起很大的性能损耗,所以该场景下只有主播进入房间时才会触发该通知,观众进入房间不会触发该通知
+     *
+     * @event TRTCCallback#onRemoteUserEnterRoom
+     * @param {String} userId 用户标识 ID
+     */
+    onRemoteUserEnterRoom(userId) { }
+    /**
+     * 有用户离开当前房间<br>
+     * 与 onRemoteUserEnterRoom 相对应,在两种不同的应用场景下,该通知的行为会有差别:<br>
+     * 通话场景(TRTCAppScene.TRTCAppSceneVideoCall 和 TRTCAppScene.TRTCAppSceneAudioCall):该场景下用户没有角色的区别,任何用户进入房间都会触发该通知。<br>
+     * 直播场景(TRTCAppScene.TRTCAppSceneLIVE 和 TRTCAppScene.TRTCAppSceneVoiceChatRoom ):该场景不限制观众的数量,如果任何用户进出都抛出回调会引起很大的性能损耗,所以该场景下只有主播进入房间时才会触发该通知,观众进入房间不会触发该通知
+     *
+     * @event TRTCCallback#onRemoteUserLeaveRoom
+     * @param {String} userId 用户标识 ID
+     * @param {Number} reason 离开原因,0 表示用户主动退出房间,1 表示用户超时退出,2 表示被踢出房间
+     */
+    onRemoteUserLeaveRoom(userId, reason) { }
+    /**
+     * 首帧本地音频数据已经被送出<br>
+     * 在 `enterRoom()` 并 `startLocalAudio()` 成功后开始麦克风采集,并将采集到的声音进行编码。 当 SDK 成功向云端送出第一帧音频数据后,会抛出这个回调事件
+     *
+     * @event TRTCCallback#onSendFirstLocalAudioFrame
+     */
+    onSendFirstLocalAudioFrame() { }
+    /**
+     * 首帧本地视频数据已经被送出<br>
+     * SDK 会在 `enterRoom()` 并 `startLocalPreview()` 成功后开始摄像头采集,并将采集到的画面进行编码。 当 SDK 成功向云端送出第一帧视频数据后,会抛出这个回调事件
+     *
+     * @event TRTCCallback#onSendFirstLocalVideoFrame
+     * @param {Number} streamType 视频流类型,大画面、小画面或辅流画面(屏幕分享)
+     */
+    onSendFirstLocalVideoFrame(streamType) { }
+    /**
+     * 技术指标统计回调<br>
+     * 如果您是熟悉音视频领域相关术语,可以通过这个回调获取 SDK 的所有技术指标。 如果您是首次开发音视频相关项目,可以只关注 `onNetworkQuality` 回调
+     *
+     * **Note:**
+     * - 每 2 秒回调一次
+     *
+     * @param {Object} statics 状态数据
+     */
+    onStatistics(statics) { }
+    /**
+     * 远端用户是否存在可播放的音频数据<br>
+     * @event TRTCCallback#onUserAudioAvailable
+     * @param {String} userId 用户标识 ID
+     * @param {Boolean} available 声音是否开启
+     */
+    onUserAudioAvailable(userId, available) { }
+    /**
+     * 远端用户是否存在可播放的主路画面(一般用于摄像头)<br>
+     * 当您收到 `onUserVideoAvailable(userId, true)` 通知时,表示该路画面已经有可用的视频数据帧到达。 此时,您需要调用 `startRemoteView(userId)` 接口加载该用户的远程画面。 然后,您会收到名为 onFirstVideoFrame(userid) 的首帧画面渲染回调。<br>
+     * 当您收到 `onUserVideoAvailable(userId, false)` 通知时,表示该路远程画面已经被关闭,可能由于该用户调用了 `muteLocalVideo()` 或 `stopLocalPreview()`。
+     *
+     * @event TRTCCallback#onUserVideoAvailable
+     * @param {String} userId 用户标识 ID
+     * @param {Boolean} available 画面是否开启
+     */
+    onUserVideoAvailable(userId, available) { }
+    /**
+     * 用于提示音量大小的回调,包括每个 userId 的音量和远端总音量<br>
+     * SDK 可以评估每一路音频的音量大小,并每隔一段时间抛出该事件回调,您可以根据音量大小在 UI 上做出相应的提示,比如“波形图”或“音量槽”。 要完成这个功能, 您需要先调用 enableAudioVolumeEvaluation 开启这个能力并设定事件抛出的时间间隔。 需要补充说明的是,无论当前房间中是否有人说话,SDK 都会按照您设定的时间间隔定时抛出此事件回调,只不过当没有人说话时,userVolumes 为空,totalVolume 为 0。
+     *
+     * **Note:**
+     * - userVolumes 为一个数组,对于数组中的每一个元素,当 userId 为空时表示本地麦克风采集的音量大小,当 userId 不为空时代表远端用户的音量大小
+     *
+     * @event TRTCCallback#onUserVoiceVolume
+     * @param {Array} userVolumes 是一个数组,用于承载所有正在说话的用户的音量大小,取值范围 0 - 100
+     * @param {Number} totalVolume 所有远端用户的总音量大小, 取值范围 0 - 100
+     */
+    onUserVoiceVolume(userVolumes, totalVolume) { }
+    /**
+     * 屏幕分享开启的事件回调<br>
+     * 当您通过 startScreenCapture 等相关接口启动屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCaptureStarted
+     */
+    onScreenCaptureStarted() { }
+    /**
+     * 屏幕分享停止的事件回调<br>
+     * 当您通过 stopScreenCapture 停止屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCaptureStopped
+     * @param {Number} reason 停止原因,0:用户主动停止;1:屏幕窗口关闭导致停止;2:表示屏幕分享的显示屏状态变更(如接口被拔出、投影模式变更等)
+     */
+    onScreenCaptureStopped(reason) { }
+    /**
+     * 屏幕分享停止的事件回调<br>
+     * 当您通过 pauseScreenCapture 停止屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCapturePaused
+     * @param {Number} reason 停止原因,0:用户主动停止;1:屏幕窗口关闭导致停止;2:表示屏幕分享的显示屏状态变更(如接口被拔出、投影模式变更等)
+     */
+    onScreenCapturePaused(reason) { }
+    /**
+     * 屏幕分享恢复的事件回调<br>
+     * 当您通过 resumeScreenCapture 恢复屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCaptureResumed
+     */
+    onScreenCaptureResumed() { }
+    /**
+     * 某远端用户发布/取消了辅路视频画面<br>
+     * “辅路画面”一般被用于承载屏幕分享的画面。当您收到 onUserSubStreamAvailable(userId, true) 通知时,表示该路画面已经有可播放的视频帧到达。 此时,您需要调用 startRemoteView 接口订阅该用户的远程画面,订阅成功后,您会继续收到该用户的首帧画面渲染回调 onFirstVideoFrame(userId)
+     *
+     * **Note:**
+     * - 拉取 Web 端(用 [WebRTC](https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/index.html) 实现屏幕分享)的屏幕分享,收不到 onUserSubStreamAvailable 事件。因为 [WebRTC](https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/index.html) 推的屏幕分享也是主流
+     * @param {String} userId 用户 ID
+     * @param {Boolean} available 是否可用,true 表示辅流可用
+     * @event TRTCCallback#onUserSubStreamAvailable
+     */
+    onUserSubStreamAvailable(userId, available) { }
+    /**
+     * 用户视频大小发生改变回调。<br>
+     * 当您收到 onUserVideoSizeChanged(userId, streamtype, newWidth, newHeight) 通知时,表示该路画面大小发生了调整,调整的原因可能是该用户调用了 setVideoEncoderParam 或者 setSubStreamEncoderParam 重新设置了画面尺寸。
+     * @param {String} userId 用户 ID
+     * @param {Number} streamType 视频流类型,仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub
+     * @param {Number} newWidth 视频流的宽度(像素)
+     * @param {Number} newHeight 视频流的高度(像素)
+     * @event TRTCCallback#onUserVideoSizeChanged
+     */
+    onUserVideoSizeChanged(userId, streamType, newWidth, newHeight) { }
+    /**
+     * 背景音乐开始播放
+     * @param {Number} id 播放的 id
+     * @param {Number} errCode 播放的状态码
+     * @event TRTCCallback#onStart
+     */
+    onStart(id, errCode) { }
+    /**
+     * 背景音乐的播放进度
+     * @param {Number} id 播放的 id
+     * @param {Number} curPtsMS 当前播放的位置
+     * @param {Number} durationMS 当前音频总时长
+     * @event TRTCCallback#onPlayProgress
+     */
+    onPlayProgress(id, curPtsMS, durationMS) { }
+    /**
+     * 背景音乐已经播放完毕
+     * @param {Number} id 播放的 id
+     * @param {Number} errCode 播放结束的状态码
+     * @event TRTCCallback#onComplete
+     */
+    onComplete(id, errCode) { }
+}

+ 279 - 0
TrtcCloud/permission.js

@@ -0,0 +1,279 @@
+/**
+ * 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
+ */
+ var isIos
+ // #ifdef APP-PLUS
+ isIos = (plus.os.name == "iOS");
+ // #endif
+ 
+ // 判断推送权限是否开启
+ function judgeIosPermissionPush() {
+   var result = false;
+   var UIApplication = plus.ios.import("UIApplication");
+   var app = UIApplication.sharedApplication();
+   var enabledTypes = 0;
+   if (app.currentUserNotificationSettings) {
+     var settings = app.currentUserNotificationSettings();
+     enabledTypes = settings.plusGetAttribute("types");
+     console.log("enabledTypes1:" + enabledTypes);
+     if (enabledTypes == 0) {
+       console.log("推送权限没有开启");
+     } else {
+       result = true;
+       console.log("已经开启推送功能!")
+     }
+     plus.ios.deleteObject(settings);
+   } else {
+     enabledTypes = app.enabledRemoteNotificationTypes();
+     if (enabledTypes == 0) {
+       console.log("推送权限没有开启!");
+     } else {
+       result = true;
+       console.log("已经开启推送功能!")
+     }
+     console.log("enabledTypes2:" + enabledTypes);
+   }
+   plus.ios.deleteObject(app);
+   plus.ios.deleteObject(UIApplication);
+   return result;
+ }
+ 
+ // 判断定位权限是否开启
+ function judgeIosPermissionLocation() {
+   var result = false;
+   var cllocationManger = plus.ios.import("CLLocationManager");
+   var status = cllocationManger.authorizationStatus();
+   result = (status != 2)
+   console.log("定位权限开启:" + result);
+   // 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
+   /* var enable = cllocationManger.locationServicesEnabled();
+   var status = cllocationManger.authorizationStatus();
+   console.log("enable:" + enable);
+   console.log("status:" + status);
+   if (enable && status != 2) {
+     result = true;
+     console.log("手机定位服务已开启且已授予定位权限");
+   } else {
+     console.log("手机系统的定位没有打开或未给予定位权限");
+   } */
+   plus.ios.deleteObject(cllocationManger);
+   return result;
+ }
+ // 判断麦克风权限是否开启
+ function judgeIosPermissionRecord() {
+   var result = false;
+   var avaudiosession = plus.ios.import("AVAudioSession");
+   var avaudio = avaudiosession.sharedInstance();
+   var permissionStatus = avaudio.recordPermission();
+   console.log("permissionStatus:" + permissionStatus);
+   if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
+     console.log("麦克风权限没有开启");
+   } else {
+     result = true;
+     console.log("麦克风权限已经开启");
+   }
+   plus.ios.deleteObject(avaudiosession);
+   return result;
+ }
+ 
+ // 判断相机权限是否开启
+ function judgeIosPermissionCamera() {
+   var result = false;
+   var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
+   var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
+   console.log("authStatus:" + authStatus);
+   if (authStatus == 3) {
+     result = true;
+     console.log("相机权限已经开启");
+   } else {
+     console.log("相机权限没有开启");
+   }
+   plus.ios.deleteObject(AVCaptureDevice);
+   return result;
+ }
+ 
+ // 判断相册权限是否开启
+ function judgeIosPermissionPhotoLibrary() {
+   var result = false;
+   var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
+   var authStatus = PHPhotoLibrary.authorizationStatus();
+   console.log("authStatus:" + authStatus);
+   if (authStatus == 3) {
+     result = true;
+     console.log("相册权限已经开启");
+   } else {
+     console.log("相册权限没有开启");
+   }
+   plus.ios.deleteObject(PHPhotoLibrary);
+   return result;
+ }
+ 
+ // 判断通讯录权限是否开启
+ function judgeIosPermissionContact() {
+   var result = false;
+   var CNContactStore = plus.ios.import("CNContactStore");
+   var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
+   if (cnAuthStatus == 3) {
+     result = true;
+     console.log("通讯录权限已经开启");
+   } else {
+     console.log("通讯录权限没有开启");
+   }
+   plus.ios.deleteObject(CNContactStore);
+   return result;
+ }
+ 
+ // 判断日历权限是否开启
+ function judgeIosPermissionCalendar() {
+   var result = false;
+   var EKEventStore = plus.ios.import("EKEventStore");
+   var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
+   if (ekAuthStatus == 3) {
+     result = true;
+     console.log("日历权限已经开启");
+   } else {
+     console.log("日历权限没有开启");
+   }
+   plus.ios.deleteObject(EKEventStore);
+   return result;
+ }
+ 
+ // 判断备忘录权限是否开启
+ function judgeIosPermissionMemo() {
+   var result = false;
+   var EKEventStore = plus.ios.import("EKEventStore");
+   var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
+   if (ekAuthStatus == 3) {
+     result = true;
+     console.log("备忘录权限已经开启");
+   } else {
+     console.log("备忘录权限没有开启");
+   }
+   plus.ios.deleteObject(EKEventStore);
+   return result;
+ }
+ 
+ // Android权限查询
+ function requestAndroidPermission(permissionID) {
+   return new Promise((resolve, reject) => {
+     plus.android.requestPermissions(
+       [permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
+       function(resultObj) {
+         var result = 0;
+         for (var i = 0; i < resultObj.granted.length; i++) {
+           var grantedPermission = resultObj.granted[i];
+           console.log('已获取的权限:' + grantedPermission);
+           result = 1
+         }
+         for (var i = 0; i < resultObj.deniedPresent.length; i++) {
+           var deniedPresentPermission = resultObj.deniedPresent[i];
+           console.log('拒绝本次申请的权限:' + deniedPresentPermission);
+           result = 0
+         }
+         for (var i = 0; i < resultObj.deniedAlways.length; i++) {
+           var deniedAlwaysPermission = resultObj.deniedAlways[i];
+           console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
+           result = -1
+         }
+         resolve(result);
+         // 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
+         // if (result != 1) {
+         // gotoAppPermissionSetting()
+         // }
+       },
+       function(error) {
+         console.log('申请权限错误:' + error.code + " = " + error.message);
+         resolve({
+           code: error.code,
+           message: error.message
+         });
+       }
+     );
+   });
+ }
+ 
+ // 使用一个方法,根据参数判断权限
+ function judgeIosPermission(permissionID) {
+   if (permissionID == "location") {
+     return judgeIosPermissionLocation()
+   } else if (permissionID == "camera") {
+     return judgeIosPermissionCamera()
+   } else if (permissionID == "photoLibrary") {
+     return judgeIosPermissionPhotoLibrary()
+   } else if (permissionID == "record") {
+     return judgeIosPermissionRecord()
+   } else if (permissionID == "push") {
+     return judgeIosPermissionPush()
+   } else if (permissionID == "contact") {
+     return judgeIosPermissionContact()
+   } else if (permissionID == "calendar") {
+     return judgeIosPermissionCalendar()
+   } else if (permissionID == "memo") {
+     return judgeIosPermissionMemo()
+   }
+   return false;
+ }
+ 
+ // 跳转到**应用**的权限页面
+ function gotoAppPermissionSetting() {
+   if (isIos) {
+     var UIApplication = plus.ios.import("UIApplication");
+     var application2 = UIApplication.sharedApplication();
+     var NSURL2 = plus.ios.import("NSURL");
+     // var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");		
+     var setting2 = NSURL2.URLWithString("app-settings:");
+     application2.openURL(setting2);
+ 
+     plus.ios.deleteObject(setting2);
+     plus.ios.deleteObject(NSURL2);
+     plus.ios.deleteObject(application2);
+   } else {
+     // console.log(plus.device.vendor);
+     var Intent = plus.android.importClass("android.content.Intent");
+     var Settings = plus.android.importClass("android.provider.Settings");
+     var Uri = plus.android.importClass("android.net.Uri");
+     var mainActivity = plus.android.runtimeMainActivity();
+     var intent = new Intent();
+     intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+     var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
+     intent.setData(uri);
+     mainActivity.startActivity(intent);
+   }
+ }
+ 
+ // 检查系统的设备服务是否开启
+ // var checkSystemEnableLocation = async function () {
+ function checkSystemEnableLocation() {
+   if (isIos) {
+     var result = false;
+     var cllocationManger = plus.ios.import("CLLocationManager");
+     var result = cllocationManger.locationServicesEnabled();
+     console.log("系统定位开启:" + result);
+     plus.ios.deleteObject(cllocationManger);
+     return result;
+   } else {
+     var context = plus.android.importClass("android.content.Context");
+     var locationManager = plus.android.importClass("android.location.LocationManager");
+     var main = plus.android.runtimeMainActivity();
+     var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
+     var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
+     console.log("系统定位开启:" + result);
+     return result
+   }
+ }
+ 
+//  module.exports = {
+//    judgeIosPermission: judgeIosPermission,
+//    requestAndroidPermission: requestAndroidPermission,
+//    checkSystemEnableLocation: checkSystemEnableLocation,
+//    gotoAppPermissionSetting: gotoAppPermissionSetting
+//  }
+
+// HBuilder 选择 vue3 时, 上面的打包无法通过 import 进行引入
+export default {
+  judgeIosPermission: judgeIosPermission,
+  requestAndroidPermission: requestAndroidPermission,
+  checkSystemEnableLocation: checkSystemEnableLocation,
+  gotoAppPermissionSetting: gotoAppPermissionSetting
+};
+ 

+ 19 - 0
TrtcCloud/view/TrtcLocalView.nvue

@@ -0,0 +1,19 @@
+<template>
+	<TRTCCloudUniPlugin-TXLocalViewComponent :viewId="viewId"></TRTCCloudUniPlugin-TXLocalViewComponent>
+</template>
+
+<script>
+	export default {
+		name: 'TrtcLocalView',
+		props: {
+			viewId: {
+				type: String,
+				default: ''
+			}
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 23 - 0
TrtcCloud/view/TrtcRemoteView.nvue

@@ -0,0 +1,23 @@
+<template>
+	<TRTCCloudUniPlugin-TXRemoteViewComponent :userId="userId" :viewId="viewId"></TRTCCloudUniPlugin-TXRemoteViewComponent>
+</template>
+
+<script>
+	export default {
+		name: 'TrtcRemoteView',
+		props: {
+			userId: {
+				type: String,
+				default: ''
+			},
+			viewId: {
+				type: String,
+				default: ''
+			}
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 36 - 0
androidPrivacy.json

@@ -0,0 +1,36 @@
+{
+    "version" : "1",
+    "prompt" : "none",
+    "title" : "%yinsi.title%",
+    "message" : "%yinsi.message%",
+    "buttonAccept" : "%yinsi.tongyijs%",
+    "buttonRefuse" : "%yinsi.butongyi%",
+    "second" : {
+        "title" : "%comp.queren%",
+        "message" : "%yinsi.Smessage%",
+        "buttonAccept" : "%yinsi.tongyijs%",
+        "buttonRefuse" : "%yinsi.tuichuyingy%"
+    },
+    "disagreeMode" : {
+        "support" : false,
+        "loadNativePlugins" : false,
+        "visitorEntry" : false,
+        "showAlways" : false
+    },
+    "styles" : {
+        "backgroundColor" : "#FFFFFF",
+        "borderRadius" : "5px",
+        "title" : {
+            "color" : "#ff00ff"
+        },
+        "buttonAccept" : {
+            "color" : "#E86E48"
+        },
+        "buttonRefuse" : {
+            "color" : "#727679"
+        },
+        "buttonVisitor" : {
+            "color" : "#727679"
+        }
+    }
+}

+ 8 - 0
changelog.md

@@ -0,0 +1,8 @@
+## 1.0.2(2022-06-30)
+- 新增 支持 ios 安全区
+## 1.0.1(2021-11-26)
+- 新增 schema 国际化 (HBuilderX 3.3+)
+- 修复 非 Android 平台切换语音无法实时变化的问题
+- 修复 设置某些语言下无法生效的问题 (HBuilderX 3.3+)
+## 1.0.0(2021-10-20)
+- 初始化

+ 30 - 0
common/jsencrypt.js

@@ -0,0 +1,30 @@
+import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
+
+// 密钥对生成 http://web.chacuo.net/netrsakeypair
+
+const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+  'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
+
+const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+  '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+  'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+  'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+  'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+  'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+  'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+  'UP8iWi1Qw0Y='
+
+// 加密
+export function encrypt(txt) {
+  const encryptor = new JSEncrypt()
+  encryptor.setPublicKey(publicKey) // 设置公钥
+  return encryptor.encrypt(txt) // 对数据进行加密
+}
+
+// 解密
+export function decrypt(txt) {
+  const encryptor = new JSEncrypt()
+  encryptor.setPrivateKey(privateKey) // 设置私钥
+  return encryptor.decrypt(txt) // 对数据进行解密
+}
+

+ 120 - 0
common/uni-ui.scss

@@ -0,0 +1,120 @@
+
+.uni-flex {
+	display: flex;
+}
+
+.uni-flex-row {
+	@extend .uni-flex;
+	flex-direction: row;
+	box-sizing: border-box;
+}
+
+.uni-flex-column {
+	@extend .uni-flex;
+	flex-direction: column;
+}
+
+.uni-color-gary {
+	color: #3b4144;
+}
+
+/* 标题 */
+.uni-title {
+	display: flex;
+	margin-bottom: $uni-spacing-col-base;
+	font-size: $uni-font-size-lg;
+	font-weight: bold;
+	color: #3b4144;
+}
+
+.uni-title-sub {
+	display: flex;
+	// margin-bottom: $uni-spacing-col-base;
+	font-size: $uni-font-size-base;
+	font-weight: 500;
+	color: #3b4144;
+}
+
+/* 描述 额外文本 */
+.uni-note {
+	margin-top: 10px;
+	color: #999;
+	font-size: $uni-font-size-sm;
+}
+
+/* 列表内容 */
+.uni-list-box {
+	@extend .uni-flex-row;
+	flex: 1;
+	margin-top: 10px;
+}
+
+/* 略缩图 */
+.uni-thumb {
+	flex-shrink: 0;
+	margin-right: $uni-spacing-row-base;
+	width: 125px;
+	height: 75px;
+	border-radius: $uni-border-radius-lg;
+	overflow: hidden;
+	border: 1px #f5f5f5 solid;
+	image {
+		width: 100%;
+		height: 100%;
+	}
+}
+
+.uni-media-box {
+	@extend .uni-flex-row;
+	// margin-bottom: $uni-spacing-col-base;
+	border-radius: $uni-border-radius-lg;
+	overflow: hidden;
+	.uni-thumb {
+		margin: 0;
+		margin-left: 4px;
+		flex-shrink: 1;
+		width: 33%;
+		border-radius:0;
+		&:first-child {
+			margin: 0;
+		}
+	}
+}
+
+/* 内容 */
+.uni-content {
+	@extend .uni-flex-column;
+	justify-content: space-between;
+}
+
+/* 列表footer */
+.uni-footer {
+	@extend .uni-flex-row;
+	justify-content: space-between;
+	margin-top: $uni-spacing-col-lg;
+}
+.uni-footer-text {
+	font-size: $uni-font-size-sm;
+	color: $uni-text-color-grey;
+	margin-left: 5px;
+}
+
+/* 标签 */
+
+.uni-tag {
+	flex-shrink: 0;
+	padding: 0 5px;
+	border: 1px $uni-border-color solid;
+	margin-right: $uni-spacing-row-sm;
+	border-radius: $uni-border-radius-base;
+	background: $uni-bg-color-grey;
+	color: $uni-text-color;
+	font-size: $uni-font-size-sm;
+}
+
+/* 链接 */
+.uni-link {
+	margin-left: 10px;
+	color: $uni-text-color;
+	text-decoration: underline;
+}

+ 403 - 0
components/XQGeneratePoster.vue

@@ -0,0 +1,403 @@
+<template>
+	<view class="content">
+		<u-mask :show="share_qrcode_flag" :zoom="false" :custom-style="{ background: 'rgba(0,0,0,.8)' }" :duration="0">
+			<view class="sq_box">
+				<view class="tz_box qrcode_box">
+					<view class="close_box" @click="share_qrcode_flag = false"><u-icon name="close" color="#ffffff"></u-icon></view>
+					<view class="share_qrcode">
+						<canvas canvas-id="myCanvas" style="width: 690px;height:1040px; position: fixed;top: -10000px;"></canvas>
+						<image @longpress="showSaveImgWin = true" style="width: 100%; height: 100%;" :src="canvasToTempFilePath"></image>
+					</view>
+				</view>
+			</view>
+		</u-mask>
+
+		<u-modal
+			v-model="showSaveImgWin"
+			content="确定要保存图片吗"
+			@confirm="saveShareImg(canvasToTempFilePath)"
+			@cancel="showSaveImgWin = false"
+			:show-cancel-button="true"
+		></u-modal>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'XQGeneratePoster',
+	data() {
+		return {
+			ratio: 1,
+			ctx: null, // 创建canvas对象
+			canvasToTempFilePath: null, // 保存最终生成的导出的图片地址
+			openStatus: true, // 声明一个全局变量判断是否授权保存到相册
+			share_qrcode_flag: false,
+			showSaveImgWin: false //保存图片到相册
+		};
+	},
+
+	methods: {
+		share_qrcode(option) {
+			if (option) {
+				if (!this.canvasToTempFilePath) {
+					this.createCanvasImage(option);
+				}
+				this.share_qrcode_flag = true;
+			}
+		},
+
+		//获取图片信息
+		downloadFileImg(url) {
+			return new Promise(resolve => {
+				uni.getImageInfo({
+					src: url,
+					success: res => {
+						resolve(res.path);
+					},
+					fail: err => {
+						console.log(err);
+						uni.showToast({
+							title: 'Lỗi mạng Vui lòng thử lại',
+							icon: 'loading'
+						});
+					}
+				});
+			});
+		},
+		// 生成海报
+		async createCanvasImage(option) {
+			// 点击生成海报数据埋点
+			if (!this.ctx) {
+				uni.showLoading({
+					title: '生成中...'
+				});
+				let code = this.downloadFileImg(option.codeUrl);
+				let cover = this.downloadFileImg(option.coverUrl);
+				let headImg = this.downloadFileImg(option.headUrl);
+				let bgUrl = '';
+				if (option.bgUrl) {
+					bgUrl = new Promise(resolve => {
+						uni.downloadFile({
+							//生成临时地址
+							url: option.bgUrl,
+							success: res => {
+								resolve(res.tempFilePath);
+							},
+							fail: erros => {
+								uni.showToast({
+									title: 'Lỗi mạng Vui lòng thử lại',
+									icon: 'loading'
+								});
+							}
+						});
+					});
+				}
+				Promise.all([headImg, code, cover, bgUrl]).then(result => {
+					const ctx = uni.createCanvasContext('myCanvas', this);
+					let canvasWidthPx = 640 * this.ratio,
+						canvasHeightPx = 1040 * this.ratio,
+						avatarurl_width = 120, //绘制的头像宽度
+						avatarurl_heigth = 120, //绘制的头像高度
+						avatarurl_x = 40, //绘制的头像在画布上的位置
+						avatarurl_y = 28, //绘制的头像在画布上的位置
+						codeurl_width = 180, //绘制的二维码宽度
+						codeurl_heigth = 180, //绘制的二维码高度
+						codeurl_x = 70, //绘制的二维码在画布上的位置
+						codeurl_y = 800, //绘制的二维码在画布上的位置
+						coverurl_width = 610, //绘制的封面宽度
+						coverurl_heigth = 350, //绘制的封面高度
+						coverurl_x = 40, //绘制的封面在画布上的位置
+						coverurl_y = 190; //绘制的封面在画布上的位置
+
+					if (option.bgUrl) {
+						ctx.drawImage(result[3], 0, 0, 690, 1040); // 背景图片需要本地
+					} else {
+						//绘制圆角矩形
+						ctx.save();
+						ctx.translate(0, 0);
+						//绘制圆角矩形的各个边
+						this.drawRoundRectPath(ctx, 690, 1040, 14);
+						ctx.fillStyle = option.fillStyle || '#0688ff'; //若是给定了值就用给定的值否则给予默认值
+						ctx.fill();
+						ctx.restore();
+					}
+
+					// 白底
+					ctx.setFillStyle('#ffffff');
+					ctx.fillRect(25, 175, 640, 840);
+
+					ctx.save(); // 先保存状态 已便于画完圆再用
+					ctx.beginPath(); //开始绘制
+					//先画个圆   前两个参数确定了圆心 (x,y) 坐标  第三个参数是圆的半径  四参数是绘图方向  默认是false,即顺时针
+					ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
+					ctx.clip(); //画了圆 再剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
+					ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推进去图片
+
+					ctx.restore(); //恢复之前保存的绘图上下文状态 可以继续绘制
+
+					ctx.font = 'normal bold 45px sans-serif';
+					ctx.setFillStyle('#ffffff'); // 文字颜色
+					if (option.nickName) {
+						this.dealWords({
+							ctx: ctx, //画布上下文
+							fontSize: 45, //字体大小
+							word: option.nickName, //需要处理的文字
+							maxWidth: 480, //一行文字最大宽度
+							x: 190, //文字在x轴要显示的位置
+							y: 40, //文字在y轴要显示的位置
+							maxLine: 1 //文字最多显示的行数
+						});
+					}
+					ctx.setFillStyle('#ffffff'); // 文字颜色
+					ctx.setFontSize(30); // 文字字号
+					ctx.fillText(option.miniName, 190, 130); // 绘制文字
+
+					ctx.setFillStyle('#222222');
+					if (option.tkName) {
+						this.dealWords({
+							ctx: ctx, //画布上下文
+							fontSize: 32, //字体大小
+							word: option.tkName, //需要处理的文字
+							maxWidth: 610, //一行文字最大宽度
+							x: 40, //文字在x轴要显示的位置
+							y: 550, //文字在y轴要显示的位置
+							maxLine: 2 //文字最多显示的行数
+						});
+					}
+
+					ctx.font = 'normal normal 26px sans-serif';
+					ctx.setFillStyle('#555555'); // 文字颜色
+					ctx.fillText('题库作者:', 40, 670); // 绘制文字
+
+					ctx.font = 'normal normal 26px sans-serif';
+					ctx.setFillStyle('#555555'); // 文字颜色
+					if (option.tkAuthor) {
+						this.dealWords({
+							ctx: ctx, //画布上下文
+							fontSize: 26, //字体大小
+							word: option.tkAuthor, //需要处理的文字
+							maxWidth: 490, //一行文字最大宽度
+							x: 170, //文字在x轴要显示的位置
+							y: 630, //文字在y轴要显示的位置
+							maxLine: 1 //文字最多显示的行数
+						});
+					}
+
+					// 白底
+					ctx.setFillStyle('#CBE6FE');
+					ctx.fillRect(40, 690, 125, 40);
+
+					ctx.font = 'normal normal 24px sans-serif';
+					ctx.setFillStyle('#1F8DFE'); // 文字颜色
+					ctx.fillText(option.tkType, 78, 720); // 绘制文字
+
+					// 白底
+					ctx.setFillStyle('#FDE5D2');
+					ctx.fillRect(180, 690, 125, 40);
+
+					ctx.setFillStyle('#F37F26'); // 文字颜色
+					ctx.fillText(option.cost, 218, 720); // 绘制文字
+
+					// 白底
+					ctx.setFillStyle('#D2F1EF');
+					ctx.fillRect(320, 690, 125, 40);
+
+					ctx.setFillStyle('#2EBBB4'); // 文字颜色
+					ctx.fillText(option.isPub, 360, 720); // 绘制文字
+
+					ctx.beginPath();
+					// 设置线宽
+					ctx.lineWidth = 1;
+					// 设置间距(参数为无限数组,虚线的样式会随数组循环)
+					ctx.setLineDash([10, 10]);
+					// 移动画笔至坐标 x20 y20 的位置
+					ctx.moveTo(30, 760);
+					// 绘制到坐标 x20 y100 的位置
+					ctx.lineTo(660, 760);
+					// 填充颜色
+					ctx.strokeStyle = '#aaaaaa';
+					// 开始填充
+					ctx.stroke();
+					ctx.closePath();
+
+					ctx.font = 'normal normal 36px sans-serif';
+					ctx.setFillStyle('#E65449'); // 文字颜色
+					ctx.fillText('长按识别', 300, 870); // 绘制孩子百分比
+
+					ctx.font = 'normal normal 36px sans-serif';
+					ctx.setFillStyle('#222222'); // 文字颜色
+					ctx.fillText('小程序码', 444, 870); // 绘制孩子百分比
+
+					ctx.font = 'normal normal 36px sans-serif';
+					ctx.setFillStyle('#222222'); // 文字颜色
+					ctx.fillText('查看题库详细信息', 300, 920); // 绘制孩子百分比
+
+					ctx.drawImage(result[2], coverurl_x, coverurl_y, coverurl_width, coverurl_heigth); // 绘制封面
+					ctx.drawImage(result[1], codeurl_x, codeurl_y, codeurl_width, codeurl_heigth); // 绘制头像
+					ctx.draw(false, () => {
+						// canvas画布转成图片并返回图片地址
+						uni.canvasToTempFilePath(
+							{
+								canvasId: 'myCanvas',
+								width: 690,
+								height: 1040,
+								destWidth: 690,
+								destHeight: 1040,
+								success: res => {
+									this.canvasToTempFilePath = res.tempFilePath;
+									this.showShareImg = true;
+									uni.showToast({
+										title: 'Vẽ thành công'
+									});
+								},
+								fail: err => {
+									uni.showToast({
+										title: 'Vẽ thất bại'
+									});
+								},
+								complete: () => {
+									uni.hideLoading();
+									uni.hideToast();
+								}
+							},
+							this
+						);
+					});
+				});
+			}
+		},
+
+		drawRoundRectPath(cxt, width, height, radius) {
+			cxt.beginPath(0);
+			//从右下角顺时针绘制,弧度从0到1/2PI
+			cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
+
+			//矩形下边线
+			cxt.lineTo(radius, height);
+
+			//左下角圆弧,弧度从1/2PI到PI
+			cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
+
+			//矩形左边线
+			cxt.lineTo(0, radius);
+
+			//左上角圆弧,弧度从PI到3/2PI
+			cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2);
+
+			//上边线
+			cxt.lineTo(width - radius, 0);
+
+			//右上角圆弧
+			cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2);
+
+			//右边线
+			cxt.lineTo(width, height - radius);
+			cxt.closePath();
+		},
+		//处理文字多出省略号显示
+		dealWords(options) {
+			options.ctx.setFontSize(options.fontSize); //设置字体大小
+			let allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth); //实际总共能分多少行
+			let count = allRow >= options.maxLine ? options.maxLine : allRow; //实际能分多少行与设置的最大显示行数比,谁小就用谁做循环次数
+			let endPos = 0; //当前字符串的截断点
+			for (let j = 0; j < count; j++) {
+				let nowStr = options.word.slice(endPos); //当前剩余的字符串
+				let rowWid = 0; //每一行当前宽度
+				if (options.ctx.measureText(nowStr).width > options.maxWidth) {
+					//如果当前的字符串宽度大于最大宽度,然后开始截取
+					for (let m = 0; m < nowStr.length; m++) {
+						rowWid += options.ctx.measureText(nowStr[m]).width; //当前字符串总宽度
+						if (rowWid > options.maxWidth) {
+							if (j === options.maxLine - 1) {
+								//如果是最后一行
+								options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 40); //(j+1)*18这是每一行的高度
+							} else {
+								options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 40);
+							}
+							endPos += m; //下次截断点
+							break;
+						}
+					}
+				} else {
+					//如果当前的字符串宽度小于最大宽度就直接输出
+					options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 40);
+				}
+			}
+		},
+
+		// 保存到系统相册
+		saveShareImg(canvasToTempFilePath) {
+			uni.saveImageToPhotosAlbum({
+				filePath: canvasToTempFilePath,
+				success: () => {
+					this.$u.toast('保存成功,快去分享到朋友圈吧~');
+				},
+				fail: () => {
+					this.$u.toast('保存失败~');
+				}
+			});
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.sq_box {
+	display: flex;
+	height: 100%;
+	justify-content: center;
+	color: #333333;
+	padding: 60rpx;
+	.tz_box {
+		background-color: #ffffff;
+		border-radius: 14rpx;
+		padding: 40rpx;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		position: relative;
+		width: 100%;
+		text-align: center;
+		line-height: 50rpx;
+		height: 80vh;
+		.close_box {
+			position: absolute;
+			left: 50%;
+			bottom: -100rpx;
+			border: 4rpx solid #ffffff;
+			width: 60rpx;
+			height: 60rpx;
+			margin-left: -30rpx;
+			border-radius: 50%;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+		}
+		.share_qrcode {
+			width: 100%;
+			height: 100%;
+		}
+		.tz_title {
+			font-size: 34rpx;
+			font-weight: 600;
+		}
+
+		.content_box {
+			margin: 50rpx 0;
+			text-align: left;
+			.inf {
+				font-weight: bold;
+				font-size: 36rpx;
+				.copy {
+					font-weight: 0;
+					color: rgb(85, 104, 147);
+					font-size: 30rpx;
+				}
+			}
+		}
+	}
+	.qrcode_box {
+		padding: 0;
+	}
+}
+</style>

+ 167 - 0
components/customNav/customNav.vue

@@ -0,0 +1,167 @@
+<template>
+	<view>
+		<!-- 自定义导航栏 -->
+			<view class="contentView">
+			<!-- 状态栏占位 -->
+			<view class="navBarBox" :style="{marginTop:statusBarHeight+'rpx'}">
+				<!-- 直正的导航栏内容 -->
+				<view v-if="shownav" class="navBar" >
+					<view class="leftconten">
+						<image class="logo" src="/static/images/fanhuiz@3x.png" mode="aspectFit" @click="leftbuttonsel(1)"></image>
+						<view v-if="titledetl==''" class="textlableR">
+							<view class="lableTR">
+								<text class="titleT" style="color: white;">{{title}}</text>
+							</view>
+						</view>
+						<view v-if="titledetl!=''" class="textlable">
+							<view class="lableT">{{title}}</view>
+							<view  class="lableB">{{titledetl}}</view>
+						</view>
+					</view>
+					<view class="rightconten">
+						<!-- <image  v-if="shareBT==1" class="mycart" src="/static/images/fenxiang@3x.png" mode="aspectFit" @click="leftbuttonsel(2)"></image> -->
+						<image  v-if="faverBT==1" class="mycart" :src="isfaver==0?'/static/images/faver@3x.png':'/static/images/faverr@3x.png'" mode="aspectFit" @click="leftbuttonsel(3)"></image>
+						<!-- <image  v-if="addBT==1" class="mycart" src="/static/images/plus-circle-fill@3x.png" mode="aspectFit" @click="leftbuttonsel(4)"></image> -->
+						<text v-if="xinzeng==1" class="xinzengTxt" @click="leftbuttonsel(5)">{{$t('schema.add')}}</text>
+						<uni-icons v-if="addBT==1"  custom-prefix="custom-icon" color="white" type="plus" size="26"  @click="leftbuttonsel(4)"></uni-icons>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view v-if="shownav" :style="{height:navBarHeight+'rpx'}">
+		</view>
+		<view v-if="!shownav" :style="{height:yincbtHeight+'rpx'}">
+		</view>
+	</view>
+		
+</template>
+
+<script>
+
+export default
+{
+	props:{
+		shownav:true,
+		title:'',
+		titledetl:'',
+		faverBT:0,
+		shareBT:0,
+		isfaver:0,
+		addBT:0,
+		xinzeng:0
+	},
+	data() {
+		return{ 
+			// 状态栏高度
+			statusBarHeight:0,
+			// 导航栏高度
+			navBarHeight: 50,
+			yincbtHeight:0,
+			};
+	},
+		//第一次加载时调用
+	created() {
+			//获取手机状态栏高度
+			var systemInfo = uni.getSystemInfoSync();
+			this.statusBarHeight=systemInfo.statusBarHeight*2+30;
+			this.navBarHeight = 50+this.statusBarHeight;
+			this.yincbtHeight=this.statusBarHeight;
+	},
+	methods:{
+		leftbuttonsel(item){
+			//触发一个更新事件
+			if(item==1){
+				uni.navigateBack();
+			}
+			this.$emit('Enavbarsel',item);
+		}
+		
+	},
+}
+
+</script>
+
+<style>
+	.contentView{
+		position: fixed;
+		left: 0;
+		right: 0;
+		top: 0;
+		z-index: 9999;
+		background-color: #00A6FF;
+	}
+	.navBarBox{
+		display: flex;
+		width: 750upx;
+		background-color: #00A6FF;
+	}
+	
+	.navBar {
+		display: flex;
+		width: 690upx;
+		margin-left: 30upx;
+		margin-bottom: 20rpx;
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center
+	}
+	.logo {
+		width: 50rpx;
+		height: 50rpx;
+		margin-left: 6rpx;
+	}
+	.textlable{
+		flex-direction:column;
+		margin-left: 20rpx;
+	}
+	.textlableR{
+		flex-direction:column;
+		margin-left: 20rpx;
+	}
+	.lableTR{
+		font-size: 32rpx;
+		color: rgb(255, 255, 255);
+	}
+	.lableT{
+		font-size: 30rpx;
+		color: rgb(255, 255, 255);
+	}
+	.lableB{
+		font-size: 22rpx;
+		color: rgb(255, 255, 255);
+	}
+	.leftconten{
+		display: flex;
+		flex-direction: row;
+		justify-content:flex-start;
+		margin-left: 20rpx;
+	}
+	.rightconten{
+		display: flex;
+		flex-direction: row;
+		justify-content:flex-end;
+	}
+
+	.mycart {
+		margin-right: 10rpx;
+		width: 50rpx;
+		height: 50rpx;
+	}
+	.xinzengTxt{
+		margin-right: 10rpx;
+		color: white;
+		font-size: 28rpx;
+	}
+	
+	.titleT{
+		/* width: 580upx; */
+		overflow: hidden;
+		text-overflow: ellipsis;
+		/* #ifndef APP-PLUS-NVUE */
+		display: -webkit-box;
+		-webkit-line-clamp: 1;
+		-webkit-box-orient: vertical;
+		/* #endif */
+	}
+</style>

+ 67 - 0
components/dachedengdai/dachedengdai.vue

@@ -0,0 +1,67 @@
+<template>
+	<view>
+		<view class="contentColumnC">
+			<view class="contentColumnC timectV">
+				<text class="textfontB4" style="color: white;">{{timeChange(timeInde)}}</text>
+				<text class="textfontB4" style="color: white;">呼叫中</text>
+			</view>
+			
+		</view>
+		<view class="contentColumnC">
+			<text class="quxiaohj" @click="actSelect(1)">取消呼叫</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"dachedengdai",
+		props: {
+			timeInde:0
+		},
+		data() {
+			return {
+				
+			};
+		},
+		methods:{
+			timeChange(timeInde){
+				var shi='00';
+				var fen='00';
+				var miao='00';
+				
+				shi = parseInt(timeInde/3600);
+				fen=timeInde%3600;
+				fen=parseInt(fen/60);
+				miao=timeInde%60;
+				return shi+':'+fen+':'+miao;
+			},
+			actSelect(index){
+				this.$emit('EddSelect',index);
+				
+			},
+		},
+	}
+</script>
+
+<style>
+
+.timectV{
+	width: 280rpx;
+	height: 280rpx;
+	border-radius: 140rpx;
+	background-color: rgba(80, 80, 80, 0.7);
+}
+.quxiaohj{
+	margin-top: 50rpx;
+	padding-left: 50rpx;
+	padding-right: 50rpx;
+	line-height: 60rpx;
+	text-align: center;
+	background-color: #1A1A1A;
+	color: white;
+	font-size: 34rpx;
+	border-radius: 30rpx;
+}
+
+</style>

+ 207 - 0
components/dachejiesuan/dachejiesuan.vue

@@ -0,0 +1,207 @@
+<template>
+	<view class="contentColumnC">
+		<view class="contentColumnC" style="width:700rpx;background-color: white;">
+			<view class="contentInRowL sizeSpace">
+				<text class="ztextfontB2">费用明细</text>
+			</view>
+			<view class="contentInRowS sizeSpace">
+				<view class="contentInRowL" style="align-items:center;">
+					<text class="textfontB3">总费用:</text>
+					<text style="font-size: 50rpx;font-weight: bold;">{{XChengObj.amount}}</text>
+					<text class="textfontB3">元</text>
+				</view>
+				<!-- <view class="contentInRowR">
+					<text class="textfontB3">支付宝支付</text>
+					<uni-icons></uni-icons>
+				</view> -->
+			</view>
+			<!-- <view class="contentInRowL sizeSpace">
+				<text class="textfontB3" style="color:darkgray;width: 660rpx;">预估价不含附加费,本次行程产生高速费12元,与预估相比正常,且无其他附加费用</text>
+			</view> -->
+			<view class="contentInRowS sizeSpace">
+				<text class="textfontB3">起步费</text>
+				<text class="textfontB3">{{qibuf}}元</text>
+			</view>
+			<view class="contentInRowS sizeSpace">
+				<text class="textfontB3">里程费</text>
+				<text class="textfontB3">{{XChengObj.fare}}元</text>
+			</view>
+			<view class="contentInRowS sizeSpace">
+				<text class="textfontB3">其他费用</text>
+				<text class="textfontB3">{{getqitafy()}}元</text>
+			</view>
+			<!-- <view class="contentInRowS sizeSpace">
+				<text class="textfontB3">优惠券</text>
+				<text class="textfontB3">0元</text>
+			</view> -->
+			<view class="contentColumnC bottomViewBt">
+				<text class="quxiaoBt" @click="quzhifu">去支付</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import api from "@/pages/api/api.js"
+	export default {
+		name:"dachejiesuan",
+		props: {
+			XChengObj:'',
+			qibuf:0
+		},
+		data() {
+			return {
+				
+			};
+		},
+		methods:{
+			getqitafy(){
+				var qt =  this.XChengObj.amount*1-this.XChengObj.fare*1-this.qibuf*1;
+				if(qt<=0){
+					qt=0;
+				}
+				return qt.toFixed(2);
+			},
+			quzhifu(){
+				uni.showToast({
+					title:'模拟支付完成',//that.i18n('api.wangluoshibai'),
+					icon: 'none',
+					duration: 2500
+				})
+				var data = {
+					id:this.XChengObj.id,
+					state:4
+				}
+				this.SetTxorder(data,0);
+			},
+			
+			SetTxorder(data,index){
+				api('SetTxorder',data,res=>{
+					console.log('SetTxorder------',res)
+					if(res.data.code==200){
+						this.pushMsg(this.XChengObj.driver.cid,this.XChengObj.user.phone,'乘客支付了');
+						uni.showToast({
+							title:'修改成功',//that.i18n('api.wangluoshibai'),
+							icon: 'none',
+							duration: 2500
+						})
+						this.$emit('EZfSelect',1);
+					}
+					else{
+						uni.showToast({
+							title:'修改失败',//that.i18n('api.wangluoshibai'),
+							icon: 'none',
+							duration: 2500
+						})
+					}
+				},failc=>{
+					//console.log('getTaxiPrices----',failc)
+					uni.showToast({
+						title:'网络错误',//that.i18n('api.wangluoshibai'),
+						icon: 'none',
+						duration: 2500
+					})
+				})
+			},
+			pushMsg(cid,phone,msg){//消息推送
+				var time=new Date();
+				var n,y,r,h,m,s;
+				n=time.getFullYear();
+				y=time.getMonth()+1;
+				r=time.getDate();
+				h=time.getHours();
+				m=time.getMinutes();
+				s=time.getSeconds();
+				
+				var timsStr = n+'-'+y+'-'+r+' '+h+':'+m+':'+s;
+				var payloadData={
+					rcuser:'尾号:'+phone.slice(-4),
+					time:timsStr,
+					msg:msg,
+					type:1
+				}
+				api('pushMsgQS',{
+					cid:cid,
+					title:'您有新消息了',
+					content:msg,
+					payload:payloadData
+				},res=>{
+					
+				},failc=>{
+					//console.log('getadvertis----',failc)
+				})
+			},
+			getVNPay(){
+				var language = uni.getStorageSync('language');
+				var lg;
+				if(language=='yuenan'){
+					lg='vi';
+				}
+				else{
+					lg='en';
+				}
+				
+				api('VNPay',{
+					orderid:this.XChengObj.ddId,
+					amount:this.XChengObj.amount,
+					language:lg
+				},res=>{
+					if(res.data.code!=200){
+						uni.showToast({
+						    title: res.data.msg,
+						    icon: 'none',
+						    duration: 3500
+						})
+						return;
+					}
+					uni.navigateTo({
+						url:'/pages/OrderList/buy/Zhifuyemian?url='+ encodeURIComponent(JSON.stringify(res.data.data))+'&ddid='+this.XChengObj.ddId
+					})
+				},failc=>{
+					//console.log('getadvertis----',failc)
+				})
+			},
+		},
+	}
+</script>
+
+<style>
+.sizeSpace{
+	width:660rpx;
+	margin-top: 20rpx;
+	align-items: center;
+}
+.bottomViewBt{
+	margin-top: 40rpx;
+	width:580rpx;
+}
+
+.quxiaoBt{
+	margin-top: 30rpx;
+	margin-bottom: 30rpx;
+	padding-left: 50rpx;
+	padding-right: 50rpx;
+	font-size: 32rpx;
+	font-weight: bold;
+	line-height: 60rpx;
+	border-radius: 30rpx;
+	text-align: center;
+	background-color: #E86E48;
+	color: white;
+}
+
+.querenBt{
+	margin-top: 30rpx;
+	margin-bottom: 30rpx;
+	padding-left: 50rpx;
+	padding-right: 50rpx;
+	font-size: 32rpx;
+	font-weight: bold;
+	border: 1rpx solid darkgray;
+	line-height: 60rpx;
+	border-radius: 30rpx;
+	text-align: center;
+	background-color: white;
+	color: #1A1A1A;
+}
+</style>

+ 123 - 0
components/dachesijijied/dachesijijied.vue

@@ -0,0 +1,123 @@
+<template>
+	<view>
+		<view style="width:700rpx;background-color: white;">
+			<view class="contentInRowS sizeSpace">
+				<view class="contentInRowL">
+					<image class="iconViewI" src="/static/images/dache/sijitx.png" mode="scaleToFill"></image>
+					<view v-if="XChengObj.state==1" class="contentColumn" style="margin-left: 16rpx;">
+						<text class="ztextfontB4">司机正在赶来</text>
+						<text class="textfontS2" style="color: darkgray;">请耐心等待!</text>
+					</view>
+					<view v-if="XChengObj.state==2" class="contentColumn" style="margin-left: 16rpx;">
+						<text class="ztextfontB4">为保证行车安全,请不要跟司机聊天!</text>
+						<text class="textfontS2" style="color: darkgray;">请保管好个人物品,下车请拿好!</text>
+					</view>
+				</view>
+				<text class="textfontS2"> </text>
+				<!-- <text class="textfontS2" style="color: darkgray;"  @click="actSelect(0)">取消订单</text> -->
+			</view>
+			<view class="contentColumnC">
+				<view class="contentColumnC boxViewct">
+					<view class="contentInRowS boxsizeSpace">
+						<view class="contentColumn">
+							<view class="chepaiV">
+							</view>
+							<view style="margin-top: -30rpx;">
+								<text class="chepaiText">京A23456</text>
+							</view>
+							<text class="ztextfontB4" style="margin-top: 40rpx;">黑色·丰田 凯美瑞</text>
+							<view class="contentInRowL" style="align-items: center;">
+								<text class="textfontB5" style="color: darkgray;">{{XChengObj.driver.nickName}}</text>
+								<text class="textfontB5"  style="color: darkgray;padding-left: 16rpx;">接单累计:1095</text>
+								<image style="width: 26rpx;height: 26rpx;" src="/static/images/dache/huangsexx.png" mode="scaleToFill"></image>
+							</view>
+						</view>
+						<view class="contentInRowR">
+							<image style="width: 70rpx;height: 70rpx;margin-right: 20rpx;" src="/static/images/dache/dianhualianxi.png" mode="scaleToFill"  @click="actSelect(1)"></image>
+							<image style="width: 70rpx;height: 70rpx;" src="/static/images/dache/xinxlt.png" mode="scaleToFill"  @click="actSelect(2)"></image>
+						</view>
+					</view>
+					<view style="height: 2rpx;background-color: lightgray;margin-top: 20rpx;margin-bottom: 20rpx;"></view>
+					<view class="contentInRowS boxsizeSpace">
+						<view class="contentColumnC"  @click="actSelect(3)">
+							<image class="actIconV" src="/static/images/dache/baojing.png" mode="scaleToFill"></image>
+							<text class="textfontB5" style="color: darkgray;">一键报警</text>
+						</view>
+						<view class="contentColumnC" @click="actSelect(4)">
+							<image class="actIconV" src="/static/images/dache/kefu.png" mode="scaleToFill"></image>
+							<text class="textfontB5" style="color: darkgray;">客服中心</text>
+						</view>
+						<view class="contentColumnC"  @click="actSelect(5)">
+							<image class="actIconV" src="/static/images/dache/xiugai.png" mode="scaleToFill"></image>
+							<text class="textfontB5" style="color: darkgray;">修改目的地</text>
+						</view>
+						<view class="contentColumnC"  @click="actSelect(6)">
+							<image class="actIconV" src="/static/images/dache/liuyan.png" mode="scaleToFill"></image>
+							<text class="textfontB5" style="color: darkgray;">语音留言</text>
+						</view>
+					</view>
+				</view>
+				<view style="height: 40rpx;"></view>
+			</view>
+			
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"dachesijijied",
+		props: {
+			XChengObj:''
+		},
+		data() {
+			return {
+
+			};
+		},
+		methods:{
+			actSelect(index){
+				this.$emit('EJDactSelect',index);
+			},
+		},
+	}
+</script>
+
+<style>
+.iconViewI{
+	width: 100rpx;
+	height: 100rpx;
+}
+.sizeSpace{
+	width: 660rpx;
+}
+
+.boxViewct{
+	margin-top: 20rpx;
+	width: 660rpx;
+	border-radius: 20rpx;
+	border: 1rpx solid lightgray;
+	/* box-shadow: 0rpx 0rpx 20rpx 0rpx lightgray; */
+}
+
+.boxsizeSpace{
+	width: 620rpx;
+}
+
+.chepaiV{
+	margin-top: 40rpx;
+	height: 30rpx;
+	background: linear-gradient(to right, #E86E48, #FFFFFF);
+}
+.chepaiText{
+	font-size: 50rpx;
+	line-height: 60rpx;
+	font-weight: bold;
+}
+
+.actIconV{
+	width: 60rpx;
+	height: 60rpx;
+}
+
+</style>

+ 114 - 0
components/dachexingcheng/dachexingcheng.vue

@@ -0,0 +1,114 @@
+<template>
+	<view >
+		<view class="contentColumnC" style="width: 700rpx;background-color: white;">
+			<view style="height: 20rpx;"></view>
+			<view v-if="weizhifu!=0" class="contentInRowS noteCtView" @click="actIndex(0)">
+				<text style="color: white;font-size: 32rpx;margin-left: 10rpx;">您有订单未完成支付!</text>
+				<uni-icons custom-prefix="custom-icon" color="white" type="right" size="24"></uni-icons>
+			</view>
+			<view class="contentInRowS" style="width:660rpx;align-items: center;">
+				<view class="contentInRowL" style="align-items: center;">
+					<text style="width: 20rpx;height: 20rpx;border-radius: 10rpx;background-color:#65AB91;"></text>
+					<view class="contentColumn" style="width: 580rpx;">
+						<text class="staddrtext">{{XChengObj.boardingAddress}}</text>
+						<text style="color: #65AB91;font-size: 24rpx;margin-left: 10rpx;">当前位置</text>
+					</view>
+				</view>
+				<uni-icons v-if="xiugai==0" custom-prefix="custom-icon" color="slateblue" type="refresh" size="32"  @click="actIndex(1)"></uni-icons>
+			</view>
+			<view class="contentInRowL mudidiViewct">
+				<view class="contentInRowL" style="align-items: center;">
+					<text style="width: 20rpx;height: 20rpx;border-radius: 10rpx;background-color:#E86E48;"></text>
+					<view class="contentColumn" style="width: 580rpx;">
+						<text class="staddrtext" style="color: #E86E48;">{{XChengObj.downAddress}}</text>
+						<text style="color: #E86E48;font-size: 24rpx;margin-left: 10rpx;">目的地</text>
+					</view>
+				</view>
+			</view>
+			<view v-if="XChengObj.distance!=''" class="contentInRowS" style="width:660rpx;align-items: center;">
+				<text class="staddrtext">里程:{{XChengObj.distance}}Km</text>
+				<text class="staddrtext" style="color: #E86E48;">预计用时:{{XChengObj.estimatedDuration}}</text>
+				<text class="staddrtext" style="color:darkmagenta;">车费:{{XChengObj.amount}}元</text>
+			</view>
+			<view style="height: 20rpx;"></view>
+		</view>
+		<view class="contentColumnC" style="margin-top: 40rpx;">
+			<text v-if="xiugai==0" class="actBTzhifu" @click="actIndex(2)">{{i18n('dache.woyaojiaoche')}}</text>
+			<text v-if="xiugai==1" class="actBTzhifu" @click="actIndex(3)">{{i18n('dache.xiugaimudd')}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"dachexingcheng",
+		props:{
+			XChengObj:'',
+			xiugai:0,
+			weizhifu:0
+		},
+		data() {
+			return {
+				mudidi:'',
+				mdaddr:'',
+			};
+		},
+		methods:{
+			i18n(str){
+				return getApp().globalData.$t(str);
+			},
+			actIndex(index){
+				this.$emit('EXCactSelect',index,'');
+			},
+			mdaddrinput(event){
+				this.mdaddr = event.target.value;
+				this.$emit('EXCactSelect',4,this.mdaddr);
+			},
+		},
+	}
+</script>
+
+<style>
+.noteCtView{
+	width: 660rpx;
+	align-items: center;
+	background-color: #E86E48;
+	border-radius: 10rpx;
+	margin-bottom: 20rpx;
+	height: 60rpx;
+}
+.staddrtext{
+	margin-left: 10rpx;
+	font-size: 28rpx;
+	color: #65AB91;
+}
+
+.mudidiViewct{
+	width: 660rpx;
+	align-items: center;
+	margin-top: 20rpx;
+	margin-bottom: 20rpx;
+	
+}
+.noinputV{
+	margin-left: 10rpx;
+	margin-top: 10rpx;
+	margin-bottom: 10rpx;
+	width: 580rpx;
+	height: 60rpx;
+	background-color: #F2F4FF;
+	border-radius: 8rpx;
+}
+.actBTzhifu{
+	font-size: 30rpx;
+	font-weight: bold;
+	line-height: 60rpx;
+	padding-left: 50rpx;
+	padding-right: 50rpx;
+	border-radius: 30rpx;
+	color: white;
+	background-color: #E86E48;
+	margin-bottom: 16rpx;
+
+}
+</style>

+ 192 - 0
components/dachexuancx/dachexuancx.vue

@@ -0,0 +1,192 @@
+<template>
+	<view class="contentColumnC">
+		<view class="contentColumnC popViewctv">
+			<view class="contentInRowS sizeSpace">
+				<view class="contentColumnC" @click="luxianSelect(0)">
+					<text class="xianluti" :style="xianluIndex==0?'background-color:#E86E48;':''">推荐线路</text>
+					<text class="timeText">{{XChengObj.estimatedDuration}}</text>
+					<text class="luchengText">{{XChengObj.distance}}Km</text>
+				</view>
+				<!-- <view class="contentColumnC" @click="luxianSelect(1)">
+					<text class="xianluti" :style="xianluIndex==1?'background-color:#E86E48;':''">线路2</text>
+					<text class="timeText">16分钟</text>
+					<text class="luchengText">6.5Km</text>
+				</view>
+				<view class="contentColumnC" @click="luxianSelect(2)">
+					<text class="xianluti" :style="xianluIndex==2?'background-color:#E86E48;':''">线路3</text>
+					<text class="timeText">16分钟</text>
+					<text class="luchengText">6.5Km</text>
+				</view> -->
+			</view>
+			<view class="sizeSpace" style="margin-top: 26rpx;">
+				<text class="textfontB5" >选择车型</text>
+			</view>
+			<view class="contentColumn">
+				<view class="lineBackColor" @click="chexingSle(0)">
+					<view class="contentInRowS sizeSpace" style="align-items: center;padding-top: 8rpx;padding-bottom: 16rpx;">
+						<view class="contentInRowL" style="align-items: center;">
+							<image style="width: 100rpx;height: 50rpx;" src="/static/images/dache/dachetb.png" mode="scaleToFill"></image>
+							<text class="ztextfontB3" style="margin-left: 10rpx;">特惠快车</text>
+						</view>
+						<view class="contentInRowR" style="align-items: center;width: 300rpx;">
+							<view class="contentInRowR" style="align-items:center;margin-right: 20rpx;">
+								<text class="textfontS3">预估</text>
+								<text class="ztextfontB1">{{XChengObj.amount}}</text>
+								<text class="textfontS3">元</text>
+							</view>
+							<uni-icons v-if="selchexList[0]==1" custom-prefix="custom-icon" color="#FFFFFF" type="checkbox" size="30"></uni-icons>
+						</view>
+					</view>
+				</view>
+				<view class="lineBackColor" @click="chexingSle(1)">
+					<view class="contentInRowS sizeSpace" style="align-items: center;padding-top: 16rpx;padding-bottom: 16rpx;">
+						<view class="contentInRowL" style="align-items: center;">
+							<image style="width: 100rpx;height: 50rpx;" src="/static/images/dache/dachetb.png" mode="scaleToFill"></image>
+							<text class="ztextfontB3" style="margin-left: 10rpx;">特惠快车</text>
+						</view>
+						<view class="contentInRowR" style="align-items: center;width: 300rpx;">
+							<view class="contentInRowR" style="align-items:center;margin-right: 20rpx;">
+								<text class="textfontS3">预估</text>
+								<text class="ztextfontB1">{{XChengObj.amount}}</text>
+								<text class="textfontS3">元</text>
+							</view>
+							<uni-icons v-if="selchexList[1]==1" custom-prefix="custom-icon" color="#FFFFFF" type="checkbox" size="30"></uni-icons>
+						</view>
+					</view>
+				</view>
+				<view class="lineBackColor" @click="chexingSle(2)">
+					<view class="contentInRowS sizeSpace" style="align-items: center;padding-top: 16rpx;padding-bottom: 16rpx;">
+						<view class="contentInRowL" style="align-items: center;">
+							<image style="width: 100rpx;height: 50rpx;" src="/static/images/dache/dachetb.png" mode="scaleToFill"></image>
+							<text class="ztextfontB3" style="margin-left: 10rpx;">特惠快车</text>
+						</view>
+						<view class="contentInRowR" style="align-items: center;width: 300rpx;">
+							<view class="contentInRowR" style="align-items:center;margin-right: 20rpx;">
+								<text class="textfontS3">预估</text>
+								<text class="ztextfontB1">{{XChengObj.amount}}</text>
+								<text class="textfontS3">元</text>
+							</view>
+							<uni-icons v-if="selchexList[2]==1" custom-prefix="custom-icon" color="#FFFFFF" type="checkbox" size="30"></uni-icons>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="contentInRowS sizeSpace bottomView">
+				<view v-if="selSum==0" class="contentInRowL" style="align-items: center;color: white;width: 400rpx;">
+					<text class="textfontS3" style="padding-left: 20rpx;color: white;">至少选择一种车型</text>
+				</view>
+				<view v-if="selSum>0" class="contentInRowL" style="align-items: center;color: white;width: 400rpx;">
+					<text class="textfontS3" style="padding-left: 20rpx;color: white;">已选{{selSum}}种车型 | 预估</text>
+					<text class="textfontS3" style="color: white;">{{XChengObj.amount}}</text>
+					<text class="textfontS3" style="color: white;">元</text>
+				</view>
+				<text class="hujiaoBt ztextfontB4" @click="querenhj">确认呼叫</text>
+			</view>
+		</view>
+	</view>
+	
+</template>
+
+<script>
+	export default {
+		name:"dachexuancx",
+		props: {
+			XChengObj:''
+		},
+		data() {
+			return {
+				xianluIndex:0,
+				chexIndex:0,
+				selchexList:[1,0,0],
+				selSum:1,
+				obj:'',
+			};
+		},
+		methods:{
+			setxcObj(obj){
+				console.log('setxcObj------',obj)
+			},
+			luxianSelect(index){
+				this.xianluIndex=index;
+			},
+			chexingSle(index){
+				if(this.selchexList[index]==1){
+					this.selchexList[index]=0;
+				}
+				else{
+					this.selchexList[index]=1;
+				}
+				this.obj=this.XChengObj;
+				this.obj.taxiType='0';
+				this.getShuliang();
+			},
+			getShuliang(){
+				var index = 0;
+				for(var i=0;i<this.selchexList.length;i++){
+					if(this.selchexList[i]!=0){
+						index=index+1;
+					}
+				}
+				this.selSum=index;
+			},
+			querenhj(){
+				if(this.obj==''){
+					this.obj=this.XChengObj;
+				}
+				this.$emit('EQuerenhj',this.obj);
+			},
+		}
+	}
+</script>
+
+<style>
+.popViewctv{
+	width: 700rpx;
+	border-radius: 20rpx 20rpx 0rpx 0rpx;
+	background-color:white
+}
+.sizeSpace{
+	width: 660rpx;
+}
+.xianluti{
+	font-size: 34rpx;
+	padding-left: 20rpx;
+	padding-right: 20rpx;
+	line-height: 50rpx;
+	background-color: darkgray;
+	color: black;
+	border-radius: 0 0 20rpx 20rpx;
+}
+
+.timeText{
+	font-size: 36rpx;
+	color: black;
+}
+
+.luchengText{
+	font-size: 28rpx;
+	color: darkgray;
+}
+.lineBackColor{
+	margin-top: 20rpx;
+	align-items: center;
+	background: linear-gradient(to right, #FFFFFF, #E86E48);
+}
+
+.bottomView{
+	margin-top: 30rpx;
+	background-color: #1a1a1a;
+	height: 80rpx;
+	border-radius: 40rpx;
+}
+
+.hujiaoBt{
+	background-color: #E86E48;
+	line-height: 80rpx;
+	border-radius: 40rpx;
+	padding-left: 60rpx;
+	padding-right: 60rpx;
+	text-align: center;
+	color: white;
+}
+</style>

+ 250 - 0
components/danxuanlist/danxuanlist.vue

@@ -0,0 +1,250 @@
+<template>
+<view>
+	<view class="contentV">
+		<view class="viewinbetween">
+			<view v-if="isedit" class="viewInrow">
+				<image style="width: 50rpx;height: 50rpx; margin-left: auto;" src="/static/images/jian@3x.png" mode="scaleToFill" @click="sanchuzhyg"></image>
+				<image style="width: 50rpx;height: 50rpx;padding-left: 20rpx;" src="/static/images/plus-circle-fill@3x.png" mode="scaleToFill" @click="zengjiaxz"></image>
+			</view>
+		</view>
+		<view>
+			<view v-for="(fenlei,i) in listData">
+				<view class="fenleiContent">
+					<view class="viewinbetween" >
+						<view class="viewIncolumn">
+							<view class="">
+								<text style="font-size: 28rpx;font-weight: bold;">{{fenlei.title}}</text>
+							</view>
+							<text style="font-size: 24rpx;color:#E02F73;">{{fenlei.type==1?$t('comp.danxuan'):$t('comp.duoxuan')}}</text>
+						</view>
+						<view v-if="!isedit" class="">
+							<text style="font-size: 28rpx;">{{fenlei.state!=1?$t('comp.kexuan'):$t('comp.bixuan')}}</text>
+						</view>
+						<view v-if="isedit" class="viewInrow">
+							<image style="width: 50rpx;height: 50rpx; margin-left: auto;" src="/static/images/jian@3x.png" mode="scaleToFill" @click="sanchuxx(i)"></image>
+							<image style="width: 50rpx;height: 50rpx;padding-left: 20rpx;" src="/static/images/plus-circle-fill@3x.png" mode="scaleToFill" @click="zengjiaxx(i)"></image>
+						</view>
+					</view>
+					<view v-for="(obj,j) in fenlei.objects">
+						<view class="viewinbetween" >
+							<view class="viewInrow" @click="objSelect(i,j)">
+								<image v-if="obj.state==0" style="width: 36rpx;" src="/static/images/tuoyuank@3x.png" mode="widthFix"></image>
+								<image v-if="obj.state==1" style="width: 36rpx;" src="/static/images/tuoyuan@3x.png" mode="widthFix"></image>
+								<text style="font-size: 28rpx;">{{obj.name}}</text>
+							</view>
+							<view class="">
+								<text v-if="obj.price==0" style="font-size: 28rpx;">{{$t('comp.mianfei')}}</text>
+								<text v-if="obj.price>0" style="font-size: 28rpx;">{{'+'+$formPr(obj.price)+$t('locale.huobidw')}}</text>
+							</view>
+						</view>
+					</view>
+					
+				</view>
+			</view>
+		</view>
+	</view>
+	<view>
+	<!-- 输入框示例 -->
+		<uni-popup ref="inputDialog" type="dialog">
+			<my-popup-dialog ref="inputClose"  mode="input" :popmode="popmode" :title="$t('comp.tianjiaguige')" value=""
+				:placeholder="$t('comp.qianshurggmc')" :placeholder2="$t('comp.qianshurzjje')" @confirm="dialogInputConfirm"></my-popup-dialog>
+		</uni-popup>
+	</view>
+	<view>
+		<!-- 提示窗示例 -->
+		<uni-popup ref="alertDialog" type="dialog">
+			<uni-popup-dialog type="warn" :cancelText="$t('comp.guanbi')" :confirmText="$t('comp.queren')" :title="$t('comp.tongzhi')" :content="$t('comp.qrscgg')" @confirm="dialogConfirm"
+				></uni-popup-dialog>
+		</uni-popup>
+	</view>
+</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			infolistD:'',
+			isedit:'',
+		},
+		data() {
+			return {
+				listData:[],
+				fenleilist:{
+					title:'',
+					type:1,//1单选,2多选
+					state:1,//2可选,1必选
+					objects:[]
+				},
+				object:{
+					name:'',
+					price:'',
+					note:'',
+					state:0
+				},
+				popmode:1,
+				editindex:-1
+			}
+		},
+		watch: {
+			infolistD(val){
+				if(''==val||null==val||undefined==val){
+					this.listData=[];
+				}
+				else{
+					this.listData = val;
+					this.infolistData();
+				}
+				
+			}
+		},
+		methods: {
+			sanchuzhyg(){
+				console.log('sanchuzhyg');
+				this.editindex = -1;
+				this.$refs.alertDialog.open();
+			},
+			zengjiaxz(){
+				console.log('zengjiaxz');
+				this.popmode=2;
+				this.$refs.inputDialog.open();
+			},
+			sanchuxx(index){
+				console.log('sanchuxx');
+				this.editindex = index;
+				this.$refs.alertDialog.open();
+			},
+			zengjiaxx(index){
+				console.log('zengjiaxx');
+				this.editindex = index;
+				this.popmode=1;
+				this.$refs.inputDialog.open();
+			},
+			dialogInputConfirm(val,val2,radioV,radioV2){
+				console.log('11点击确认',val,val2,radioV)
+				if(this.popmode==2){
+					var fenlei = {
+						title:val,
+						type:radioV,
+						state:radioV2,
+						objects:[]
+					};
+					this.listData.push(fenlei);
+				}
+				else{
+					var object={
+						name:val,
+						price:parseInt(val2),
+						note:'',
+						state:0
+					};
+					this.listData[this.editindex].objects.push(object);
+				}
+				this.infolistData();
+			},
+			objSelect(i,j){
+				var obj = this.listData[i].objects[j];
+				if(obj.state==0){
+					this.listData[i].objects[j].state=1;
+				}
+				else{
+					this.listData[i].objects[j].state=0;
+				}
+				
+				if(this.listData[i].type==1){//单选
+					for(var k=0;k<this.listData[i].objects.length;k++){
+						if(k!=j){
+							this.listData[i].objects[k].state=0;
+						}
+					}
+				}
+				if(this.listData[i].state==1){//必选
+					var mark = -1;
+					for(var k=0;k<this.listData[i].objects.length;k++){
+						if(this.listData[i].objects[k].state==1){
+							mark=k;
+							break;
+						}
+					}
+					if(mark<0){
+						this.listData[i].objects[0].state=1;
+					}
+				}
+				this.upDatalistData();
+			},
+			dialogConfirm(val){
+				console.log('点击确认删除',val)
+				if(this.editindex<0){
+					if(this.listData.length>0){
+						this.listData.pop();
+					}
+				}
+				else{
+					if(this.listData[this.editindex].objects.length>0){
+						this.listData[this.editindex].objects.pop();
+					}
+				}
+				this.upDatalistData();
+			},
+			infolistData(){
+				for(var i=0;i<this.listData.length;i++){
+					if(this.listData[i].state==1){
+						if(this.listData[i].objects.length>0){
+							var mark = -1;
+							for(var j=0;j<this.listData[i].objects.length;j++){
+								if(this.listData[i].objects[j].state==1){
+									mark = j;
+									break;
+								}
+							}
+							if(mark<0){
+								this.listData[i].objects[0].state=1;
+							}
+						}
+					}
+				}
+				this.upDatalistData();
+			},
+			upDatalistData(){
+				this.$emit('ElistDatachange',this.listData);
+			},
+		}
+	}
+</script>
+
+<style>
+	.contentV{
+		display: flex;
+		flex-direction: column;
+		width: 90%;
+		margin-left: 5%;
+		margin-top: 10rpx;
+	}
+	.fenleiContent{
+		display: flex;
+		flex-direction: column;
+		border-radius: 16rpx;
+		border: 2rpx solid #DCD7DB;
+		background-color: #FDF2F8;
+		margin-top: 10rpx;
+		margin-bottom: 10rpx;
+	}
+	.viewInrow{
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: flex-start;
+	}
+	.viewIncolumn{
+		display: flex;
+		flex-direction: column;
+		justify-content: flex-start;
+	}
+	.viewinbetween{
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		padding: 16rpx;
+	}
+
+</style>

+ 241 - 0
components/fenleiList/fenleiList - 副本.vue

@@ -0,0 +1,241 @@
+<template>
+	<view v-if="objList.length==6" class="item_list6">
+		<view class="item_content">
+			<view class="contentV" style="height: 360rpx;" @click="fenleixuanz(objList[0].id)">
+				<view class="">
+					<view class="title ztextfontB3">
+						<text>{{objList[0].title}}</text>
+					</view>
+					<view class="detail towrow textfontB5" style="width: 260rpx;">
+						<text>{{objList[0].detail}}</text>
+					</view>
+				</view>
+				<view class="viewInRow">
+					<netImage class="imagIconB" backgrS="1" width="190" height="190" :mysrc="objList[0].imageUrl" mymode="scaleToFill"></netImage>
+				</view>
+			</view>
+			<view class="contentV" style="height: 220rpx;" @click="fenleixuanz(objList[1].id)">
+				<view class="title textfontB5">
+					<text>{{objList[1].title}}</text>
+				</view>
+				<view class="viewInRow">
+					<text class="detail textfontB4">{{objList[1].detail}}</text>
+					<netImage class="imagIconM" backgrS="1" width="136" height="136" :mysrc="objList[1].imageUrl" mymode="scaleToFill"></netImage>
+				</view>
+			</view>
+			<view class="contentV" style="height: 150rpx;" @click="fenleixuanz(objList[2].id)">
+				<view class="viewInRow">
+					<view>
+						<view class="title ztextfontB3">
+							<text>{{objList[2].title}}</text>
+						</view>
+						<view class="detail textfontB5">
+							<text >{{objList[2].detail}}</text>
+						</view>
+					</view>
+					<netImage class="imagIconS" backgrS="1" width="120" height="120" :mysrc="objList[2].imageUrl" mymode="scaleToFill"></netImage>
+				</view>
+			</view>
+		</view>
+		
+		<view class="item_content">
+			<view class="contentV" style="height: 220rpx;" @click="fenleixuanz(objList[3].id)">
+				<view class="title ztextfontB3">
+					<text>{{objList[3].title}}</text>
+				</view>
+				<view class="viewInRow">
+					<view class="detail textfontB5">
+						<text>{{objList[3].detail}}</text>
+					</view>
+					<netImage class="imagIconM" backgrS="1" width="126" height="126" :mysrc="objList[3].imageUrl" mymode="scaleToFill"></netImage>
+				</view>
+			</view>
+			<view class="contentV" style="height: 270rpx;" @click="fenleixuanz(objList[4].id)">
+				<view class="">
+					<view class="title ztextfontB3">
+						<text>{{objList[4].title}}</text>
+					</view>
+					<text class="detail onerow textfontB5">{{objList[4].detail}}</text>
+				</view>
+				<view class="viewInRow">
+					<netImage class="imagIconBL" backgrS="1" width="130" height="130" :mysrc="objList[4].imageUrl" mymode="scaleToFill"></netImage>
+				</view>
+			</view>
+			<view class="contentV" style="height: 240rpx;" @click="fenleixuanz(objList[5].id)">
+				<view class="title ztextfontB3">
+					<text>{{objList[5].title}}</text>
+				</view>
+				<view class="viewInRow">
+					<text class="detail textfontB5">{{objList[5].detail}}</text>
+					<netImage class="imagIconM" backgrS="1" width="140" height="140" :mysrc="objList[5].imageUrl" mymode="scaleToFill"></netImage>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import api from "@/pages/api/api.js"
+	export default {
+		data() {
+			return {
+				listsize:0,
+				objList:[],
+				fenleiList:[],
+				
+			};
+		},
+		
+		methods:{
+			getfenleiList(){
+				api('fwlxlist',{
+					pageNum:1,
+					pageSize:20
+				},res=>{
+					if(res.data.code!=200){
+						return;
+					}
+					this.initListObj(res.data.rows)
+					//console.log('1111333333',res);
+				},failc=>{
+					//console.log('getadvertis----',failc)
+				})
+			},
+			
+			initListObj(list){
+				this.listsize=list.length;
+				this.objList=[];
+				var tmpList=[];
+				var language = uni.getStorageSync('language');
+				if(language=='yuenan'){
+					for(var i=0;i<this.listsize;i++){
+						var obj={
+							id:list[i].id,
+							imageUrl:list[i].image,
+							title:list[i].nameVi,
+							detail:list[i].illustrateVi
+						};
+						tmpList.push(obj);
+					}
+				}
+				else if(language=='zh-Hans'){
+					for(var i=0;i<this.listsize;i++){
+						var obj={
+							id:list[i].id,
+							imageUrl:list[i].image,
+							title:list[i].nameCn,
+							detail:list[i].illustrateCn
+						};
+						tmpList.push(obj);
+					}
+				}
+				else if(language=='zh-Hant'){
+					for(var i=0;i<this.listsize;i++){
+						var obj={
+							id:list[i].id,
+							imageUrl:list[i].image,
+							title:list[i].nameTw,
+							detail:list[i].illustrateTw
+						};
+						tmpList.push(obj);
+					}
+				}
+				this.objList=tmpList;
+				
+			},
+			fenleixuanz(e){
+				this.$emit('Efwflxuanze',e);
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+@font-face {
+	font-family: zrht;
+	src: url('/uni_modules/font/zrht.otf');
+}
+	.item_list6{
+		padding: 0 40rpx;
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-between;
+		
+		background-color: #F2F3F7;
+	}
+	.item_content{
+		width: 48%;
+		margin: 20rpx 0;
+		box-sizing: border-box;
+	}
+	.contentV{
+		margin-top: 20rpx;
+		background: white;
+		align-items: center;
+		border-radius: 12rpx;
+		border: 1rpx solid lightgrey;
+		box-shadow: 0rpx 0rpx 10rpx 0rpx lightgrey;
+	}
+	
+	.viewInRow{
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+	}
+	
+	.title{
+		margin: 14rpx;
+		color:black;
+		font-weight:bold;
+	}
+	.detail{
+		margin-left: 14rpx;
+		color:black;
+	}
+	.imagIconB{
+		margin-left: auto;
+		margin-top: 0rpx;
+		margin-right: 6rpx;
+		margin-bottom: 0rpx;
+		width: 230rpx;
+		height: 230rpx;
+	}
+	.imagIconBL{
+		margin-left: auto;
+		margin-top: 0rpx;
+		margin-right: 6rpx;
+		margin-bottom: 0rpx;
+		width: 130rpx;
+		height: 130rpx;
+	}
+	.imagIconM{
+		margin-left: auto;
+		margin-top: 0rpx;
+		margin-right: 6rpx;
+		margin-bottom: 0rpx;
+		width: 136rpx;
+		height: 136rpx;
+	}
+	.imagIconS{
+		margin-left: auto;
+		margin-right: 6rpx;
+		margin-top: 10rpx;
+		width: 120rpx;
+		height: 120rpx;
+	}
+	.towrow{
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+	}
+	.onerow{
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 1;
+		-webkit-box-orient: vertical;
+	}
+		
+</style>

+ 137 - 0
components/fenleiList/fenleiList.vue

@@ -0,0 +1,137 @@
+<template>
+	<view style="background-color: white;">
+		<scroll-view scroll-view  scroll-x="true" >
+			<view class="">
+				<view class="item_list">
+					<view v-for="(item, index) in objList">
+						<view class="item_content"  @click="fenleixuanz(item.id)">
+							<netImage width="140" height="140" :mysrc="item.imageUrl" mymode="scaleToFill"></netImage>
+							<view class="title">
+								<text >{{item.title}}</text>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>	  
+	import api from "@/pages/api/api.js"
+	export default {
+		data() {
+			return {
+				listsize:0,
+				objList:[],
+				fenleiList:[],
+			};
+		},
+		methods:{
+			getfenleiList(){
+					api('fwlxlist',{
+						pageNum:1,
+						pageSize:20
+					},res=>{
+						if(res.data.code!=200){
+							return;
+						}
+						this.initListObj(res.data.rows)
+						//console.log('1111333333',res);
+					},failc=>{
+						//console.log('getadvertis----',failc)
+					})
+				},
+				
+				initListObj(list){
+					this.listsize=list.length;
+					this.objList=[];
+					var tmpList=[];
+					var language = uni.getStorageSync('language');
+					if(language=='yuenan'){
+						for(var i=0;i<this.listsize;i++){
+							var obj={
+								id:list[i].id,
+								imageUrl:list[i].image,
+								title:list[i].nameVi,
+								detail:list[i].illustrateVi
+							};
+							tmpList.push(obj);
+						}
+					}
+					else if(language=='zh-Hans'){
+						for(var i=0;i<this.listsize;i++){
+							var obj={
+								id:list[i].id,
+								imageUrl:list[i].image,
+								title:list[i].nameCn,
+								detail:list[i].illustrateCn
+							};
+							tmpList.push(obj);
+						}
+					}
+					else if(language=='zh-Hant'){
+						for(var i=0;i<this.listsize;i++){
+							var obj={
+								id:list[i].id,
+								imageUrl:list[i].image,
+								title:list[i].nameTw,
+								detail:list[i].illustrateTw
+							};
+							tmpList.push(obj);
+						}
+					}
+					this.objList=tmpList;
+					
+				},
+				fenleixuanz(e){
+					this.$emit('Efwflxuanze',e);
+				},
+			},
+	}
+</script>
+
+<style lang="scss">
+
+@font-face {
+	font-family: zrht;
+	src: url('/uni_modules/font/zrht.otf');
+}
+
+	.item_list{
+		padding-left: 40rpx;
+		display: flex;
+		flex-direction: row;
+		justify-content: flex-start;
+	}
+	
+	.item_content{
+		width: 160rpx;
+		height: 230rpx;
+		margin: 16rpx 0;
+		padding: 14rpx;
+		box-sizing: border-box;
+		image{
+			width: 140rpx;
+			height:140rpx;
+			background-color:whitesmoke;
+			display: block;
+		}
+		
+		.title{
+			width: 100%;
+			text-align: center;
+			font-size: 24rpx;
+			line-height: 30rpx;
+			padding-top: 4rpx;
+		}
+	}	
+	.titleview{
+		padding-left: 40rpx;
+		padding-top: 22rpx;
+		font-size: 30rpx;
+		line-height: 46rpx;
+		// font-family: zrht;
+	}
+		
+</style>

+ 148 - 0
components/foodItem/foodItem.vue

@@ -0,0 +1,148 @@
+<template>
+	<view>
+		<view class="thumb-boxR">
+		<myImage class="goodimage" :mysrc="foodImag" mymode="scaleToFill"></myImage>
+		<view class="msText">
+			<text class="dianpuming" >{{name}}</text>
+			<view class="buyBT" style="background-color: #FEFCED;">
+				<!-- <image class="xingxing" src="/static/images/dianzan@3x.png" mode="heightFix"></image> -->
+				<text class="peisongsuoming detailtextV" style="color: #988233;">{{introduce}}</text>
+			</view>
+			<!-- <text class="peisongsuoming">{{$t('comp.yuexiao')}}300+</text> -->
+			<view class="buyBTSB">
+				<text class="peisongsuoming">{{$formPr(price+otherPrice)}}{{$t('locale.huobidw')}}</text>
+				<view class="rconten">
+					<image v-if="shuliang>0" class="imageRJ" src="/static/images/jian@3x.png" mode="aspectFit" @click="jiajian(-1)"></image>
+					<text v-if="shuliang>0" class="textR">{{shuliang}}</text>
+					<image class="imageR" src="/static/images/plus-circle-fill@3x.png" mode="aspectFit" @click="jiajian(1)"></image>
+				</view>
+			</view>
+		</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	
+	// var tempsp={
+	// 	"shangpin":shangpinlist[j],
+	// 	"sku":tempSKU,
+	// 	"otherPrice":otherPrice,
+	// 	"shuliang":shuliang
+	// }
+	
+	export default {
+		name:"foodItem",
+		props: {
+			food:'',
+			shuliang:0,
+			otherPrice:0,
+		},
+		data() {
+			return {
+				foodImag:'',
+				name:'',
+				price:0,
+				introduce:''
+			};
+		},
+		watch: {
+			food(val){
+				this.foodImag = this.food.shangpin.image;
+				this.name = this.food.shangpin.name;
+				this.price = this.food.shangpin.price;
+				this.introduce = this.food.shangpin.introduce;
+			}
+		},
+		methods:{
+			jiajian(e){
+				this.$emit('Ejiajian',e);
+			},
+		},
+	}
+</script>
+
+
+<style>
+
+	.thumb-boxR {
+	    width: 90%;
+		margin-left: 5%;
+	    display: flex;
+	    align-items: center;
+	    justify-content: flex-start;
+	    flex-direction: row;
+	    margin-top:12rpx;
+		background-color: white;
+		border-radius: 8rpx;
+	}
+	.goodimage{
+		border-radius: 8rpx;
+		width: 180rpx;
+		height:140rpx;
+	}
+	.msText{
+		width: 500rpx;
+		padding-left: 10rpx;
+		font-size: 22rpx;
+		line-height: 32rpx;
+	}
+	.dianpuming{
+		font-size: 30rpx;
+		line-height: 32rpx;
+		height: 32rpx;
+		font-weight: bold;
+	}
+	.buyBTSB{
+		display: flex;
+		flex-direction: row;
+		justify-content:space-between;
+		align-items: center;
+	}
+	
+	.buyBT{
+		display: flex;
+		flex-direction: row;
+		justify-content:flex-start;
+		align-items: center;
+	}
+	.xingxing{
+		width: 34rpx;
+		height: 34rpx;
+	}
+	.peisongsuoming{
+		font-size: 26rpx;
+		line-height: 38rpx;
+		height: 38rpx;
+		color: dimgray;
+	}
+	.detailtextV{
+		width: 90%;
+		height: 80rpx;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+	}
+	.rconten{
+		margin-left: auto;
+		display:flex;
+		flex-direction: row;
+		align-items: center;
+	}
+	.imageRJ{
+		width: 56rpx;
+		height: 56rpx;
+		margin-right: 8rpx;
+	}
+	.imageR{
+		width: 50rpx;
+		height: 50rpx;
+		margin-right: 30rpx;
+	}
+	.textR{
+		margin-left: 6rpx;
+		margin-right: 6rpx;
+	}
+</style>

+ 253 - 0
components/foodxuangou/foodxuangou.vue

@@ -0,0 +1,253 @@
+<template>
+	<view>
+		<foodItem style="width:100%;" :food="spindexSP" :shuliang="shuliang" :otherPrice="otherPrice" v-on:Ejiajian="jiajian"></foodItem>
+		<danxuanlist style="width:100%;" :infolistD="skuGuige" :isedit="false" v-on:ElistDatachange="listDatachange"></danxuanlist>
+		<view class="contentInRowL" style="margin-top: 10rpx;margin-left:6%;align-items: center;">
+			<text>{{$t('order.beizhu')}}</text>
+			<textarea class="textinput" auto-height="true"
+				:always-embed='false' 
+				:adjust-position='true'
+				cursor-spacing='30'
+				confirm-hold='true'
+				confirm-type='done'
+				:focus='false'
+				maxlength='100'
+				v-model='beizhu'
+				@confirm='mineSendBT' 
+			></textarea>
+			
+		</view>
+		<view style="display: flex;width:88%;margin-left:6%; margin-bottom: 20rpx;">
+			<label class="querenBt" @click="jiagouwuche()">{{$t('gouwu.jiarugouwc')}}</label>
+		</view>
+		<uni-popup ref="bzPop":maskClick="false">
+			<view class="contentColumnC" style="width:700rpx;background-color: white;margin-left: 25rpx;border-radius: 10rpx;">
+				<view class="contentInRowS" style="width: 90%;margin-top: 16rpx;">
+					<text style="color: chocolate;">{{$t('order.quxiao')}}</text>
+					<text style="font-weight: bold;">{{$t('order.beizhu')}}</text>
+					<text style="color: #00A6FF;" @click="querenBZ">{{$t('comp.queren')}}</text>
+				</view>
+				<textarea class="textinput" auto-height="true"
+					:always-embed='false' 
+					:adjust-position='true'
+					cursor-spacing='30'
+					confirm-hold='true'
+					confirm-type='done'
+					:focus='false'
+					maxlength='100'
+					v-model='beizhu'
+					@confirm='mineSendBT' 
+				></textarea>
+				<view style="height: 40rpx;"></view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"foodxuangou",
+		props: {
+			food:''
+		},
+		data() {
+			return {
+				spindexSP:'',
+				skuGuige:'',
+				shuliang:1,
+				otherPrice:0,
+				tempsku:'',
+				beizhu:'',
+				gouwuche:{
+					foodlist:[],
+					mendid:'',
+					userid:'',
+					mendname:''
+				}
+			};
+		},
+		watch: {
+			food(val){
+				//console.log(this.food);
+				this.spindexSP = this.food;
+				this.skuGuige = this.food.shangpin.foodSku;
+				this.otherPrice = this.getotherPrice(this.skuGuige);
+				this.tempsku = this.gettempSKU(this.skuGuige);
+				this.beizhu='';
+				this.$refs.bzPop.close();
+			}
+		},
+		methods: {
+			jiagouwuche(){
+				this.gengxingouwuche();
+				this.$emit('Ejiagouwuche');
+			},
+			
+			gengxingouwuche(){
+				if(this.shuliang<1){
+					uni.showToast({
+					    title: this.$t('comp.qingxzsp'),
+					    icon: 'none',
+					    duration: 2500
+					})
+					return;
+				}
+				
+				var gwc = uni.getStorageSync('gouwuche');
+				if(''==gwc||null==gwc||undefined==gwc){
+					this.gouwuche={
+						foodlist:[],
+						mendid:'',
+						userid:'',
+						mendname:''
+					};
+				}
+				else{
+					this.gouwuche = JSON.parse(gwc);
+				}
+				
+				var sp = this.food.shangpin;
+				if(this.gouwuche.mendid!=sp.store.id){
+					this.gouwuche={
+						foodlist:[],
+						mendid:sp.store.id,
+						userid:sp.store.userId,
+						mendname:sp.store.posName,
+					};
+				}
+				for(var i=0;i<this.gouwuche.foodlist.length;i++){
+					var gwf = this.gouwuche.foodlist[i];
+					var ask = JSON.stringify(gwf.ask);
+					var tempsku = JSON.stringify(this.tempsku);
+					if(gwf.id == sp.id &&ask === tempsku){
+						this.gouwuche.foodlist[i].number = this.shuliang;
+						let sgwc = JSON.stringify(this.gouwuche);
+						uni.setStorageSync('gouwuche',sgwc);
+						return;
+					}
+				}
+				
+				var f={
+					"id": sp.id,
+					"name": sp.name, 
+					"image": sp.image, 
+					"price": sp.price, 
+					"otherPrice":this.otherPrice,
+					"number": this.shuliang, 
+					"ask": this.tempsku,
+					"beizhu":this.beizhu
+				}
+				this.gouwuche.foodlist.push(f);
+				let tgwc = JSON.stringify(this.gouwuche);
+				uni.setStorageSync('gouwuche',tgwc);
+			},
+			
+			jiajian(e){
+				this.shuliang = this.shuliang+e; 
+			},
+			listDatachange(listData){
+				this.tempsku = this.gettempSKU(listData);
+				this.otherPrice = this.getotherPrice(listData);
+				//console.log(this.tempsku,this.otherPrice)
+			},
+			gettempSKU(foodSku){
+				var selectsku=[];
+				if(''==foodSku||null==foodSku||undefined==foodSku){
+					return selectsku;
+				}
+				for(var i=0;i<foodSku.length;i++){
+					if(foodSku[i].objects.length>0){
+						for(var j=0;j<foodSku[i].objects.length;j++){
+							if(foodSku[i].objects[j].state==1){
+								selectsku.push(foodSku[i].objects[j].name);
+							}
+						}
+					}
+				}
+				return selectsku;
+			},
+			getotherPrice(foodSku){
+				console.log('getotherPrice',foodSku);
+				var jiner=0;
+				if(''==foodSku||null==foodSku||undefined==foodSku){
+					return 0;
+				}
+				for(var i=0;i<foodSku.length;i++){
+					if(foodSku[i].objects.length>0){
+						for(var j=0;j<foodSku[i].objects.length;j++){
+							if(foodSku[i].objects[j].state==1){
+								if(foodSku[i].objects[j].price==0||!foodSku[i].objects[j].price){
+									jiner=jiner+0;
+								}
+								else{
+									jiner=jiner+parseFloat(foodSku[i].objects[j].price);
+								}
+							}
+						}
+					}
+				}
+				if(parseFloat(jiner)){
+					console.log('111',jiner);
+					return parseFloat(jiner);
+				}
+				else{
+					console.log('222',jiner);
+					return 0;
+				}
+			},
+			editBeizhu(){
+				console.log('11111111')
+				this.$refs.bzPop.open('top');
+			},
+			mineSendBT(){
+				console.log(this.beizhu)
+				this.$refs.bzPop.close();
+			},
+			querenBZ(){
+				console.log(this.beizhu)
+				this.$refs.bzPop.close();
+			},
+		},
+	}
+</script>
+
+<style>
+.querenBt{
+	margin-top: 30rpx;
+	width: 100%;
+	height: 60rpx;
+	line-height: 60rpx;
+	padding: 10rpx;
+	border-radius: 20rpx;
+	border: solid #00A6FF;
+	border-width: 0px 0px 6rpx 0px;
+	text-align: center;
+	justify-content: center;
+	background-color: #00A6FF;
+	color: white;
+	box-shadow: 0rpx 0rpx 10rpx 0rpx #00A6FF;
+}
+.beizhuBt{
+	padding: 10rpx 16rpx 10rpx 16rpx;
+	color: white;
+	border-radius: 8rpx;
+	background-color:chocolate;
+}
+.beizhutext{
+	color:darkgray;
+	font-size: 30rpx;
+	margin-left: 30rpx;
+	width: 500rpx;
+}
+.textinput{
+	margin-left: 8rpx;
+	padding-top: 10rpx;
+	padding-bottom: 10rpx;
+	width: 80%;
+	border-radius: 6rpx;
+	border: 1rpx solid darkgray;
+	font-size: 32upx;
+	background-color: white;
+}
+
+</style>

+ 78 - 0
components/imageconver/imageconver.vue

@@ -0,0 +1,78 @@
+<template>
+	<view >
+		<image class="imagesize" :src="defimagSrc=='/static/defimages/ddd.png'?defimagSrc:baseUrl+imagSrc" mode="scaleToFill" @error="imageError(imagSrc)"></image>
+		<view v-if="isyouhui" class="manjianB">
+			<text>{{youhuinote}}</text>
+			<image style="width: 30rpx;height: 30rpx;top: 4rpx;" src="/static/images/huorer@3x.png" mode="scaleToFill"></image>
+		</view>
+		<view class="remenfile" :style="isyouhui?'margin-top: -190rpx;':'margin-top: -80rpx;'">
+			<uni-icons v-if="isremen" custom-prefix="custom-icon" color="#E02F73" type="fire-filled" size="26" ></uni-icons>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:{
+			imagSrc:'',
+			isremen:false,
+			isyouhui:false,
+			youhuinote:''
+		},
+		data() {
+			return {
+				baseUrl:this.$baseImagurl,
+				defimagSrc:''
+			}
+		},
+		methods: {
+			imageError(index){
+				this.defimagSrc = '/static/defimages/ddd.png';//默认图片 
+			},
+		}
+	}
+</script>
+
+<style>
+	.imagesize{
+		width: 100%;
+		height: 100%;
+		border-radius: 16rpx;
+	}
+	.manjianB{
+		width: 200rpx;
+		height: 40rpx;
+		margin-left: 10rpx;
+		background-color: #CE366F;
+		line-height: 40rpx;
+		font-size: 24rpx;
+		color: white;
+		padding-left: 8rpx;
+		border-radius:0px 10px 10px 0px;
+		margin-top: -80rpx;
+	}
+	.tuijianB{
+		position: absolute;
+		width: 120rpx;
+		height: 40rpx;
+		margin-left: 10rpx;
+		background-color: #CE366F;
+		line-height: 40rpx;
+		font-size: 24rpx;
+		color: white;
+		padding-left: 8rpx;
+		border-radius:0px 10px 10px 0px;
+	}
+	.textsty{
+		font-size: 24rpx;
+		color: white;
+		padding-left: 8rpx;
+		padding-right: 12rpx;
+		background-color: aqua;
+	}
+.remenfile{
+		position: absolute;
+		margin-left: 10rpx;
+		z-index: 999;
+	}
+</style>

+ 548 - 0
components/liupishui-pickerpolygons/liupishui-pickerpolygons.vue

@@ -0,0 +1,548 @@
+<template>
+	<view class="box-picker_position">
+		<view class="map_wp">
+			<map id="map_20221212" class="picker-map" scale="12" min-scale="12" @regionchange="handleRegionchange" :latitude="position.latitude" :longitude="position.longitude" show-location='true' :polygons="polygons"></map>
+			<view :class="['picker_map_location', animateLocation?'animated':'']"></view>
+		</view>
+		<view class="list-picker_position">
+			<view class="hd">
+				<input type="text" v-model="searchKey" class="input_text" placeholder="请输入搜索地点">
+				<button class="btn-search" type="default" @click="searchPosition"><view class="picker-search"></view>搜索</button>
+			</view>
+			<view class="bd">
+				<view v-for="(item,index) in searchlist" @click="changeSelectItem(index)" :class="['item',item.useable?'':'disabled']" :key="index">
+					<view class="item-l">
+						<view class="picker-address"></view>
+					</view>
+					<view class="item-c">
+						<view class="title">{{item.title}}</view>
+						<view class="address">{{item.address}}</view>
+					</view>
+					<view class="item-r">
+						<view v-if="item.select" class="picker-checked"></view>
+					</view>
+				</view>
+			</view>
+			<view class="ft">
+				<button @click="confirmSelect" :class="['btn-selected', canConfirm?'':'disabled']">确定选点</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	var QQMapWX = require('./qqmap-wx-jssdk.js');
+	var qqmapsdk,handleRegionchangeTimmer;
+	export default {
+		props:{
+			polygons:{
+				type:Array,
+				default:[
+					{
+						points:[
+							{
+								latitude:'36.829066',
+								longitude:'118.025761',
+							},
+							{
+								latitude:'36.825012',
+								longitude:'118.066702',
+							},
+							{
+								latitude:'36.81161',
+								longitude:'118.042681'
+							},
+							{
+								latitude:'36.801964',
+								longitude:'118.034875',
+							},
+						],
+						strokeWidth:1,
+						strokeColor:'#ff000066',
+						fillColor:'#ff000016'
+					},
+					{
+						points:[
+							{
+								latitude:'36.817369',
+								longitude:'118.001311',
+							},
+							{
+								latitude:'36.808682',
+								longitude:'118.010281',
+							},{
+								latitude:'36.805555',
+								longitude:'117.996537',
+							},
+						],
+						strokeWidth:1,
+						strokeColor:'#ff000066',
+						fillColor:'#ff000016'
+					},
+				]
+			},
+			qqmapsdkKey:{
+				type:String,
+				default:''
+			},
+			base_url:{
+				type:String,
+				default:''
+			},
+			sig:{
+				type:String,
+				default:''
+			}
+		},
+		data() {
+			return {
+				canConfirm: false,
+				animateLocation:false,
+				isChangeSelectItem:false,
+				searchKey:'',
+				position:{
+					latitude:'36.811995',
+					longitude:'118.05539'
+				},
+				searchlist:[]
+			};
+		},
+		mounted(){
+			if(this.qqmapsdkKey==''){
+				console.error('需要腾讯地图开发Key,申请地址:https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/jsSdkOverview')
+				return;
+			}
+			qqmapsdk = new QQMapWX({
+				key:this.qqmapsdkKey,
+				BASE_URL:this.base_url
+			});
+			let that = this;
+			let needRegetLocation = true;
+			
+			if(uni.getStorageSync('mapPickerPosition')){
+				let data = JSON.parse(uni.getStorageSync('mapPickerPosition'));
+				if(new Date().getTime() < data.expireTime){
+					needRegetLocation = false;
+					that.position.latitude = data.position.latitude;
+					that.position.longitude = data.position.longitude;
+					that.init();
+				}
+			}
+			if(needRegetLocation){
+				uni.getLocation({
+					cacheTimeout:1,
+					accuracy:'best',
+					type:'gcj02',
+					isHighAccuracy:true,
+					success:function(e){
+						console.log(e);
+						that.position.latitude = e.latitude;
+						that.position.longitude = e.longitude;
+						uni.setStorageSync('mapPickerPosition',JSON.stringify({
+							expireTime: new Date().getTime() - 0 + 60*1000,
+							position:{
+								latitude: e.latitude,
+								longitude: e.longitude
+							}
+						}))
+						that.init();
+					},
+					fail:function(e){
+						console.log(e);
+					}
+				})
+			}
+			// uni.onLocationChange(function(e){
+			// 		console.log(11111,e);
+			// 		that.position.latitude = e.latitude;
+			// 		that.position.longitude = e.longitude;
+			// 	})
+		},
+		methods:{
+			init(){
+				this.animateLocation = true;
+				handleRegionchangeTimmer = setTimeout(()=>{
+					this.renderList();
+				},400)
+			},
+			renderList(){
+				let that = this;
+				let mapContext = uni.createMapContext("map_20221212", that);
+				mapContext.getCenterLocation({
+						success:function(rst){
+							let options = {
+									location:rst.latitude+','+rst.longitude,
+									get_poi:1,
+									poi_options: 'radius=1000',
+									sig:that.sig,
+									success:function(res){
+										//console.log('xxxxx',res.result.pois)
+										let isSelect = false;
+										if(res.message == "query ok"){
+											//that.$data.searchlist = [];
+											that.$data.searchlist = [...res.result.pois];
+											for(let i = 0;i<that.$data.searchlist.length;i++){
+												that.$data.searchlist.useable = false;
+												that.$data.searchlist.select = false;
+												for(let j = 0;j < that.polygons.length;j++){
+													if(that.isPointInPolygon(that.$data.searchlist[i].location.lat,that.$data.searchlist[i].location.lng,that.polygons[j].points)){
+														that.$data.searchlist[i].useable = true;
+														if(!isSelect){
+															that.$data.searchlist[i].select = true;
+															isSelect = true;
+														}
+													}
+												}
+												
+											}
+											setTimeout(()=>{
+												that.animateLocation = false;
+											},200)
+										}
+										if(isSelect){
+											that.canConfirm = true;
+										}else{
+											that.canConfirm = false;
+										}
+									},
+									fail:function(error){
+										console.log(error);
+									}
+								};
+							if(typeof(window)==='undefined'){
+								delete options.sig;
+							}
+							if(options.sig===''){
+								delete options.sig;
+							}
+							qqmapsdk.reverseGeocoder(options);
+							
+						}
+				});
+			},
+			searchPosition(){
+				if(this.searchKey.replace(/\s+/,'')==''){
+					return;
+				}
+				let that = this;
+				let searchOptions = {
+					keyword:this.searchKey,
+					location:{
+						latitude:this.position.latitude,
+						longitude:this.position.longitude
+					},
+					sig:that.sig,
+					success:function(rst){
+						let isSelect = false;
+						if(rst.message == "query ok"){
+							//that.$data.searchlist = [];
+							that.$data.searchlist = [...rst.data];
+							for(let i = 0;i<that.$data.searchlist.length;i++){
+								that.$data.searchlist.useable = false;
+								that.$data.searchlist.select = false;
+								for(let j = 0;j < that.polygons.length;j++){
+									if(that.isPointInPolygon(that.$data.searchlist[i].location.lat,that.$data.searchlist[i].location.lng,that.polygons[j].points)){
+										that.$data.searchlist[i].useable = true;
+										if(!isSelect){
+											that.$data.searchlist[i].select = true;
+											that.position.latitude = that.$data.searchlist[i].location.lat;
+											that.position.longitude = that.$data.searchlist[i].location.lng;
+											isSelect = true;
+										}
+									}
+								}
+								
+							}
+						}
+						if(isSelect){
+							that.canConfirm = true;
+						}else{
+							that.canConfirm = false;
+						}
+					}
+				};
+				if(typeof(window)==='undefined'){
+					delete searchOptions.sig;
+				}
+				if(searchOptions.sig===''){
+					delete searchOptions.sig;
+				}
+				
+				qqmapsdk.search(searchOptions);
+			},
+			changeSelectItem(index){
+				if(this.$data.searchlist[index].useable){
+					for(let i = 0;i<this.$data.searchlist.length;i++){
+						let temp = {};
+						for(var key in this.$data.searchlist[i]){
+							temp[key] = this.$data.searchlist[i][key];
+						}
+						if(i===index){
+							temp.select = true;
+							this.isChangeSelectItem = true;
+							this.position.latitude = temp.location.lat;
+							this.position.longitude = temp.location.lng;						
+						}else{
+							temp.select = false;
+						}
+						this.$set(this.$data.searchlist,i,temp);
+					}
+				}
+			},
+			handleRegionchange(e){
+				console.log(e);
+				this.animateLocation = false;
+				if(e.type=='end'){
+					if(this.isChangeSelectItem){
+						setTimeout(()=>{
+							this.isChangeSelectItem = false;
+						},100)
+						return;
+					}else{
+							this.animateLocation = true;
+							if(handleRegionchangeTimmer){
+								clearTimeout(handleRegionchangeTimmer);
+							}
+							handleRegionchangeTimmer = setTimeout(()=>{
+								this.renderList();
+							},400)
+						
+					}
+				}
+			},
+
+			isPointInPolygon(aLat, aLon, pointList){
+						/* 
+			            :param aLon: double 经度 
+			            :param aLat: double 纬度 
+			            :param pointList: list [{latitude: 22.22, longitude: 113.113}...] 多边形点的顺序需根据顺时针或逆时针,不能乱 
+			            */
+			            var iSum = 0  
+			            var iCount = pointList.length
+			              
+			            if(iCount < 3) {
+			                return false 
+			            }
+			            //  待判断的点(x, y) 为已知值
+			            var y = aLat
+			            var x = aLon
+			            for(var i = 0; i < iCount; i++) {
+			                var y1 = pointList[i].latitude
+			                var x1 = pointList[i].longitude
+			                if(i == iCount - 1) {
+			                    var y2 = pointList[0].latitude
+			                    var x2 = pointList[0].longitude
+			                } else {
+			                    var y2 = pointList[i + 1].latitude  
+			                    var x2 = pointList[i + 1].longitude
+			                }
+			                // 当前边的 2 个端点分别为 已知值(x1, y1), (x2, y2)
+							if (((y >= y1) && (y < y2)) || ((y >= y2) && (y < y1))) {
+			                    //  y 界于 y1 和 y2 之间
+			                    //  假设过待判断点(x, y)的水平直线和当前边的交点为(x_intersect, y_intersect),有y_intersect = y
+			                    // 则有(2个相似三角形,公用顶角,宽/宽 = 高/高):|x1 - x2| / |x1 - x_intersect| = |y1 - y2| / |y1 - y|
+			                    if (Math.abs(y1 - y2) > 0) {
+			                        var x_intersect = x1 - ((x1 - x2) * (y1 - y)) / (y1 - y2);  
+			                        if(x_intersect < x) {
+			                            iSum += 1 
+			                        }
+			                    }
+			                } 
+			            }
+			            if(iSum % 2 != 0) { //true就是在
+			                return true  
+			            }else { //false就是不在
+			                return false 
+			            }  
+				},
+				confirmSelect(){
+					if(this.canConfirm){
+						this.searchlist.forEach(val=>{
+							if(val.select){
+								val.polygonIndex = [];
+								this.polygons.forEach((polygon,index)=>{
+									if(this.isPointInPolygon(val.location.lat,val.location.lng,polygon.points)){
+										val.polygonIndex.push(index);
+									}
+								})
+								uni.setStorageSync('polygonLocationPicker',JSON.stringify(val));
+								this.$emit('selected',JSON.stringify(val));
+							}
+						})
+					}
+				}
+		}
+
+	}
+</script>
+
+<style scoped lang="scss">
+	@keyframes bounceInDown {
+		   from,
+		    20%,
+		    53%,
+		    to {
+		      animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+		      transform: translate3d(0, 0, 0);
+		    }
+		  
+		    40%,
+		    43% {
+		      animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+		      transform: translate3d(0, -30rpx, 0) scaleY(1.1);
+		    }
+		  
+		    70% {
+		      animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+		      transform: translate3d(0, -15rpx, 0) scaleY(1.05);
+		    }
+		  
+		    80% {
+		      transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+		      transform: translate3d(0, 0, 0) scaleY(0.95);
+		    }
+		  
+		    90% {
+		      transform: translate3d(0, -4rpx, 0) scaleY(1.02);
+		    }
+	  }
+	
+	.box-picker_position{
+		height: 100%;
+		width: 100%;
+		background: #fff;
+		display: flex;
+		flex-flow: column;
+		position: relative;
+		overflow: hidden;
+		box-sizing: border-box;
+	}
+	.map_wp{
+		position: relative;
+		width: 750rpx;
+		height: 400rpx;
+	}
+	.picker_map_location{
+		width: 60rpx;
+		height: 60rpx;
+		background-image: url("data:image/svg+xml,%3Csvg t='1670988557938' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='3498' width='200' height='200'%3E%3Cpath d='M511.968 0c-207.84 0-376.96 169.12-376.96 376.992 0 54.208 11.104 105.984 32.96 153.888 94.24 206.24 274.976 424 328.128 485.824 3.968 4.608 9.792 7.296 15.904 7.296s11.904-2.656 15.904-7.296c53.12-61.824 233.856-279.552 328.128-485.824 21.888-47.904 32.96-99.648 32.96-153.888-0.032-207.872-169.152-376.992-376.992-376.992zM511.968 572.8c-107.968 0-195.808-87.84-195.808-195.808s87.84-195.84 195.808-195.84 195.808 87.84 195.808 195.84c0 107.968-87.84 195.808-195.808 195.808z' fill='%23fa3c23' p-id='3499'%3E%3C/path%3E%3C/svg%3E");
+		background-size: cover;
+		background-position: center bottom;
+		position: absolute;
+		left: 50%;
+		top: 50%;
+		margin-left: -30rpx;
+		margin-top: -60rpx;
+		z-index: 999;
+		transform-origin: center bottom;
+	}
+	.picker_map_location.animated{
+		animation: bounceInDown .6s linear infinite;
+	}
+	.picker-map{
+		width: 750rpx;
+		height: 400rpx;
+	}
+	.list-picker_position{
+		position: relative;
+		flex: 1;
+		display: flex;
+		flex-flow: column;
+		overflow: hidden;
+		.hd{
+			padding: 20rpx 20rpx 10rpx;
+			display: flex;
+			.input_text{
+				flex: 1;
+				box-sizing: border-box;
+				background: #f2f2f2;
+				border-radius: 6rpx;
+				height: 60rpx;
+				font-size: 28rpx;
+				padding-left: 1em;
+			}
+		}
+		.bd{
+			padding: 20rpx;
+			box-sizing: border-box;
+			flex: 1;
+			overflow-y: scroll;
+			.item{
+				display: flex;
+				padding: 15rpx 10rpx;
+				border-bottom: 1px solid #ccc;
+				line-height: 1.92;
+				align-items: stretch;
+				.title{
+					font-size: 32rpx;
+				}
+				.address{
+					font-size: 24rpx;
+					color: #999;
+					line-height: 1.5;
+				}
+			}
+			.item-l{
+				padding: 10rpx 6rpx 0 0;
+			}
+			.item-c{
+				flex: 1;
+			}
+			.item-r{
+				width: 60rpx;
+				display: flex;
+				align-items: center;
+				align-content: center;
+			}
+			.item.disabled{
+				opacity: .5;
+			}
+		}
+	}
+	.btn-search{
+		background: #007AFF;
+		font-size: 24rpx;
+		color: #fff;
+		display: flex;
+		padding: 0;
+		align-items: center;
+		justify-content: center;
+		width: 120rpx;
+	}
+	.picker-search{
+		background-image: url("data:image/svg+xml,%3Csvg t='1670900132396' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='2679' width='200' height='200'%3E%3Cpath d='M685.6 660.336l155.152 155.168a16 16 0 0 1 0 22.624l-11.312 11.328a16 16 0 0 1-22.624 0l-158.528-158.544a289.792 289.792 0 0 1-165.152 51.36C322.336 742.256 192 611.904 192 451.12 192 290.336 322.336 160 483.136 160c160.784 0 291.12 130.336 291.12 291.136 0 82.112-33.984 156.272-88.672 209.2z m-202.464 33.92c134.272 0 243.12-108.848 243.12-243.12C726.256 316.848 617.408 208 483.136 208 348.848 208 240 316.848 240 451.136c0 134.272 108.848 243.12 243.136 243.12z' p-id='2680' fill='%23dbdbdb'%3E%3C/path%3E%3C/svg%3E");			background-size: cover;
+		background-size: cover;
+		width:36rpx;
+		height: 36rpx;
+		width: 36rpx;
+		display: block;
+		margin-right: 5rpx;
+	}
+	.picker-checked{
+		background-image: url("data:image/svg+xml,%3Csvg t='1670909673260' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='3763' width='200' height='200'%3E%3Cpath d='M417.185185 768c-9.481481 0-18.962963-3.792593-26.548148-11.377778l-246.518518-246.518518c-15.17037-15.17037-15.17037-37.925926 0-53.096297 15.17037-15.17037 37.925926-15.17037 53.096296 0L417.185185 676.977778l409.6-409.6c15.17037-15.17037 37.925926-15.17037 53.096296 0 15.17037 15.17037 15.17037 37.925926 0 53.096296l-436.148148 436.148148c-7.585185 7.585185-17.066667 11.377778-26.548148 11.377778z' p-id='3764' fill='%231e63ed'%3E%3C/path%3E%3C/svg%3E");
+		background-size: cover;
+		width: 46rpx;
+		height: 46rpx;
+		display: block;
+	}
+	.picker-address{
+		background-image: url("data:image/svg+xml,%3Csvg t='1670910118471' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='4833' width='200' height='200'%3E%3Cpath d='M508.313 1018.666c0 0-379.51-422.921-379.51-632.516 0-209.606 169.914-379.51 379.51-379.51s379.511 169.903 379.51 379.51c0 209.596-379.51 632.516-379.51 632.516zM508.313 55.295c-182.719 0-330.854 150.305-330.854 335.72s330.854 559.534 330.854 559.534 330.854-374.117 330.854-559.534c0-185.415-148.135-335.72-330.854-335.72zM508.312 512.654c-87.336 0-158.129-70.793-158.129-158.129s70.793-158.129 158.129-158.129 158.129 70.793 158.129 158.129c0 87.328-70.793 158.129-158.129 158.129zM508.313 240.185c-64.488 0-116.772 52.285-116.772 116.772s52.285 116.772 116.772 116.772c64.498 0 116.772-52.285 116.772-116.772 0-64.488-52.275-116.772-116.772-116.772z' fill='%23666666' p-id='4834'%3E%3C/path%3E%3C/svg%3E");
+		background-size: cover;
+		width: 36rpx;
+		height: 36rpx;
+		display: block;
+	}
+	.btn-selected{
+		background: #007AFF;
+		height: 80rpx;
+		line-height: 80rpx;
+		font-size: 32rpx;
+		color: #fff;
+		border: none;
+		border-radius: 0;
+	}
+	.btn-selected.disabled{
+		background: #f2f2f2;
+		color: #ccc;
+	}
+</style>

+ 1125 - 0
components/liupishui-pickerpolygons/qqmap-wx-jssdk.js

@@ -0,0 +1,1125 @@
+/**
+ * 微信小程序JavaScriptSDK
+ * 
+ * @version 1.2
+ * @date 2019-03-06
+ */
+
+var ERROR_CONF = {
+    KEY_ERR: 311,
+    KEY_ERR_MSG: 'key格式错误',
+    PARAM_ERR: 310,
+    PARAM_ERR_MSG: '请求参数信息有误',
+    SYSTEM_ERR: 600,
+    SYSTEM_ERR_MSG: '系统错误',
+    WX_ERR_CODE: 1000,
+    WX_OK_CODE: 200
+};
+var MODE = {
+  driving: 'driving',
+  transit: 'transit'
+};
+var EARTH_RADIUS = 6378136.49;
+var Utils = {
+  /**
+  * md5加密方法
+  * 版权所有©2011 Sebastian Tschan,https://blueimp.net
+  */
+  safeAdd(x, y) {
+    var lsw = (x & 0xffff) + (y & 0xffff);
+    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+    return (msw << 16) | (lsw & 0xffff);
+  },
+  bitRotateLeft(num, cnt) {
+    return (num << cnt) | (num >>> (32 - cnt));
+  },
+  md5cmn(q, a, b, x, s, t) {
+    return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b);
+  },
+  md5ff(a, b, c, d, x, s, t) {
+    return this.md5cmn((b & c) | (~b & d), a, b, x, s, t);
+  },
+  md5gg(a, b, c, d, x, s, t) {
+    return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t);
+  },
+  md5hh(a, b, c, d, x, s, t) {
+    return this.md5cmn(b ^ c ^ d, a, b, x, s, t);
+  },
+  md5ii(a, b, c, d, x, s, t) {
+    return this.md5cmn(c ^ (b | ~d), a, b, x, s, t);
+  },
+  binlMD5(x, len) {
+    /* append padding */
+    x[len >> 5] |= 0x80 << (len % 32);
+    x[((len + 64) >>> 9 << 4) + 14] = len;
+
+    var i;
+    var olda;
+    var oldb;
+    var oldc;
+    var oldd;
+    var a = 1732584193;
+    var b = -271733879;
+    var c = -1732584194;
+    var d = 271733878;
+
+    for (i = 0; i < x.length; i += 16) {
+      olda = a;
+      oldb = b;
+      oldc = c;
+      oldd = d;
+
+      a = this.md5ff(a, b, c, d, x[i], 7, -680876936);
+      d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586);
+      c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819);
+      b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
+      a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897);
+      d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
+      c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
+      b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983);
+      a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
+      d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
+      c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063);
+      b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
+      a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
+      d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101);
+      c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
+      b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+      a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510);
+      d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
+      c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713);
+      b = this.md5gg(b, c, d, a, x[i], 20, -373897302);
+      a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691);
+      d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083);
+      c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335);
+      b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848);
+      a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438);
+      d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
+      c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961);
+      b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
+      a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
+      d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784);
+      c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
+      b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+      a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558);
+      d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
+      c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
+      b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556);
+      a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
+      d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
+      c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632);
+      b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
+      a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174);
+      d = this.md5hh(d, a, b, c, x[i], 11, -358537222);
+      c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979);
+      b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189);
+      a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487);
+      d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835);
+      c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520);
+      b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+      a = this.md5ii(a, b, c, d, x[i], 6, -198630844);
+      d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
+      c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
+      b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055);
+      a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
+      d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
+      c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523);
+      b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
+      a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
+      d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744);
+      c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
+      b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
+      a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070);
+      d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
+      c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259);
+      b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+      a = this.safeAdd(a, olda);
+      b = this.safeAdd(b, oldb);
+      c = this.safeAdd(c, oldc);
+      d = this.safeAdd(d, oldd);
+    }
+    return [a, b, c, d];
+  },
+  binl2rstr(input) {
+    var i;
+    var output = '';
+    var length32 = input.length * 32;
+    for (i = 0; i < length32; i += 8) {
+      output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff);
+    }
+    return output;
+  },
+  rstr2binl(input) {
+    var i;
+    var output = [];
+    output[(input.length >> 2) - 1] = undefined;
+    for (i = 0; i < output.length; i += 1) {
+      output[i] = 0;
+    }
+    var length8 = input.length * 8;
+    for (i = 0; i < length8; i += 8) {
+      output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32);
+    }
+    return output;
+  },
+  rstrMD5(s) {
+    return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8));
+  },
+  rstrHMACMD5(key, data) {
+    var i;
+    var bkey = this.rstr2binl(key);
+    var ipad = [];
+    var opad = [];
+    var hash;
+    ipad[15] = opad[15] = undefined;
+    if (bkey.length > 16) {
+      bkey = this.binlMD5(bkey, key.length * 8);
+    }
+    for (i = 0; i < 16; i += 1) {
+      ipad[i] = bkey[i] ^ 0x36363636;
+      opad[i] = bkey[i] ^ 0x5c5c5c5c;
+    }
+    hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
+    return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128));
+  },
+  rstr2hex(input) {
+    var hexTab = '0123456789abcdef';
+    var output = '';
+    var x;
+    var i;
+    for (i = 0; i < input.length; i += 1) {
+      x = input.charCodeAt(i);
+      output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);
+    }
+    return output;
+  },
+  str2rstrUTF8(input) {
+    return unescape(encodeURIComponent(input));
+  },
+  rawMD5(s) {
+    return this.rstrMD5(this.str2rstrUTF8(s));
+  },
+  hexMD5(s) {
+    return this.rstr2hex(this.rawMD5(s));
+  },
+  rawHMACMD5(k, d) {
+    return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d));
+  },
+  hexHMACMD5(k, d) {
+    return this.rstr2hex(this.rawHMACMD5(k, d));
+  },
+
+  md5(string, key, raw) {
+    if (!key) {
+      if (!raw) {
+        return this.hexMD5(string);
+      }
+      return this.rawMD5(string);
+    }
+    if (!raw) {
+      return this.hexHMACMD5(key, string);
+    }
+    return this.rawHMACMD5(key, string);
+  },
+  /**
+   * 得到md5加密后的sig参数
+   * @param {Object} requestParam 接口参数
+   * @param {String} sk签名字符串
+   * @param {String} featrue 方法名
+   * @return 返回加密后的sig参数
+   */
+  getSig(requestParam, sk, feature, mode) {
+    var sig = null;
+    var requestArr = [];
+    Object.keys(requestParam).sort().forEach(function(key){
+      requestArr.push(key + '=' + requestParam[key]);
+    });
+    if (feature == 'search') {
+      sig = '/ws/place/v1/search?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'suggest') {
+      sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'reverseGeocoder') {
+      sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'geocoder') {
+      sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'getCityList') {
+      sig = '/ws/district/v1/list?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'getDistrictByCityId') {
+      sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'calculateDistance') {
+      sig = '/ws/distance/v1/?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'direction') {
+      sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk;
+    }
+    sig = this.md5(sig);
+    return sig;
+  },
+    /**
+     * 得到终点query字符串
+     * @param {Array|String} 检索数据
+     */
+    location2query(data) {
+        if (typeof data == 'string') {
+            return data;
+        }
+        var query = '';
+        for (var i = 0; i < data.length; i++) {
+            var d = data[i];
+            if (!!query) {
+                query += ';';
+            }
+            if (d.location) {
+                query = query + d.location.lat + ',' + d.location.lng;
+            }
+            if (d.latitude && d.longitude) {
+                query = query + d.latitude + ',' + d.longitude;
+            }
+        }
+        return query;
+    },
+
+    /**
+     * 计算角度
+     */
+    rad(d) {
+      return d * Math.PI / 180.0;
+    },  
+    /**
+     * 处理终点location数组
+     * @return 返回终点数组
+     */
+    getEndLocation(location){
+      var to = location.split(';');
+      var endLocation = [];
+      for (var i = 0; i < to.length; i++) {
+        endLocation.push({
+          lat: parseFloat(to[i].split(',')[0]),
+          lng: parseFloat(to[i].split(',')[1])
+        })
+      }
+      return endLocation;
+    },
+
+    /**
+     * 计算两点间直线距离
+     * @param a 表示纬度差
+     * @param b 表示经度差
+     * @return 返回的是距离,单位m
+     */
+    getDistance(latFrom, lngFrom, latTo, lngTo) {
+      var radLatFrom = this.rad(latFrom);
+      var radLatTo = this.rad(latTo);
+      var a = radLatFrom - radLatTo;
+      var b = this.rad(lngFrom) - this.rad(lngTo);
+      var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
+      distance = distance * EARTH_RADIUS;
+      distance = Math.round(distance * 10000) / 10000;
+      return parseFloat(distance.toFixed(0));
+    },
+    /**
+     * 使用微信接口进行定位
+     */
+    getWXLocation(success, fail, complete) {
+        wx.getLocation({
+            type: 'gcj02',
+            success: success,
+            fail: fail,
+            complete: complete
+        });
+    },
+
+    /**
+     * 获取location参数
+     */
+    getLocationParam(location) {
+        if (typeof location == 'string') {
+            var locationArr = location.split(',');
+            if (locationArr.length === 2) {
+                location = {
+                    latitude: location.split(',')[0],
+                    longitude: location.split(',')[1]
+                };
+            } else {
+                location = {};
+            }
+        }
+        return location;
+    },
+
+    /**
+     * 回调函数默认处理
+     */
+    polyfillParam(param) {
+        param.success = param.success || function () { };
+        param.fail = param.fail || function () { };
+        param.complete = param.complete || function () { };
+    },
+
+    /**
+     * 验证param对应的key值是否为空
+     * 
+     * @param {Object} param 接口参数
+     * @param {String} key 对应参数的key
+     */
+    checkParamKeyEmpty(param, key) {
+        if (!param[key]) {
+            var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
+            param.fail(errconf);
+            param.complete(errconf);
+            return true;
+        }
+        return false;
+    },
+
+    /**
+     * 验证参数中是否存在检索词keyword
+     * 
+     * @param {Object} param 接口参数
+     */
+    checkKeyword(param){
+        return !this.checkParamKeyEmpty(param, 'keyword');
+    },
+
+    /**
+     * 验证location值
+     * 
+     * @param {Object} param 接口参数
+     */
+    checkLocation(param) {
+        var location = this.getLocationParam(param.location);
+        if (!location || !location.latitude || !location.longitude) {
+            var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误');
+            param.fail(errconf);
+            param.complete(errconf);
+            return false;
+        }
+        return true;
+    },
+
+    /**
+     * 构造错误数据结构
+     * @param {Number} errCode 错误码
+     * @param {Number} errMsg 错误描述
+     */
+    buildErrorConfig(errCode, errMsg) {
+        return {
+            status: errCode,
+            message: errMsg
+        };
+    },
+
+    /**
+     * 
+     * 数据处理函数
+     * 根据传入参数不同处理不同数据
+     * @param {String} feature 功能名称
+     * search 地点搜索
+     * suggest关键词提示
+     * reverseGeocoder逆地址解析
+     * geocoder地址解析
+     * getCityList获取城市列表:父集
+     * getDistrictByCityId获取区县列表:子集
+     * calculateDistance距离计算
+     * @param {Object} param 接口参数
+     * @param {Object} data 数据
+     */
+    handleData(param,data,feature){
+      if (feature == 'search') {
+        var searchResult = data.data;
+        var searchSimplify = [];
+        for (var i = 0; i < searchResult.length; i++) {
+          searchSimplify.push({
+            id: searchResult[i].id || null,
+            title: searchResult[i].title || null,
+            latitude: searchResult[i].location && searchResult[i].location.lat || null,
+            longitude: searchResult[i].location && searchResult[i].location.lng || null,
+            address: searchResult[i].address || null,
+            category: searchResult[i].category || null,
+            tel: searchResult[i].tel || null,
+            adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
+            city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
+            district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
+            province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
+          })
+        }
+        param.success(data, {
+          searchResult: searchResult,
+          searchSimplify: searchSimplify
+        })
+      } else if (feature == 'suggest') {
+        var suggestResult = data.data;
+        var suggestSimplify = [];
+        for (var i = 0; i < suggestResult.length; i++) {
+          suggestSimplify.push({
+            adcode: suggestResult[i].adcode || null,
+            address: suggestResult[i].address || null,
+            category: suggestResult[i].category || null,
+            city: suggestResult[i].city || null,
+            district: suggestResult[i].district || null,
+            id: suggestResult[i].id || null,
+            latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
+            longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
+            province: suggestResult[i].province || null,
+            title: suggestResult[i].title || null,
+            type: suggestResult[i].type || null
+          })
+        }
+        param.success(data, {
+          suggestResult: suggestResult,
+          suggestSimplify: suggestSimplify
+          })
+      } else if (feature == 'reverseGeocoder') {
+        var reverseGeocoderResult = data.result;
+        var reverseGeocoderSimplify = {
+          address: reverseGeocoderResult.address || null,
+          latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
+          longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
+          adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
+          city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null,
+          district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null,
+          nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null,
+          province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null,
+          street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null,
+          street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null,
+          recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null,
+          rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null
+        };
+        if (reverseGeocoderResult.pois) {//判断是否返回周边poi
+          var pois = reverseGeocoderResult.pois;
+          var poisSimplify = [];
+          for (var i = 0;i < pois.length;i++) {
+            poisSimplify.push({
+              id: pois[i].id || null,
+              title: pois[i].title || null,
+              latitude: pois[i].location && pois[i].location.lat || null,
+              longitude: pois[i].location && pois[i].location.lng || null,
+              address: pois[i].address || null,
+              category: pois[i].category || null,
+              adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
+              city: pois[i].ad_info && pois[i].ad_info.city || null,
+              district: pois[i].ad_info && pois[i].ad_info.district || null,
+              province: pois[i].ad_info && pois[i].ad_info.province || null
+            })
+          }
+          param.success(data,{
+            reverseGeocoderResult: reverseGeocoderResult,
+            reverseGeocoderSimplify: reverseGeocoderSimplify,
+            pois: pois,
+            poisSimplify: poisSimplify
+          })
+        } else {
+          param.success(data, {
+            reverseGeocoderResult: reverseGeocoderResult,
+            reverseGeocoderSimplify: reverseGeocoderSimplify
+          })
+        }
+      } else if (feature == 'geocoder') {
+        var geocoderResult = data.result;
+        var geocoderSimplify = {
+          title: geocoderResult.title || null,
+          latitude: geocoderResult.location && geocoderResult.location.lat || null,
+          longitude: geocoderResult.location && geocoderResult.location.lng || null,
+          adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
+          province: geocoderResult.address_components && geocoderResult.address_components.province || null,
+          city: geocoderResult.address_components && geocoderResult.address_components.city || null,
+          district: geocoderResult.address_components && geocoderResult.address_components.district || null,
+          street: geocoderResult.address_components && geocoderResult.address_components.street || null,
+          street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null,
+          level: geocoderResult.level || null
+        };
+        param.success(data,{
+          geocoderResult: geocoderResult,
+          geocoderSimplify: geocoderSimplify
+        });
+      } else if (feature == 'getCityList') {
+        var provinceResult = data.result[0];
+        var cityResult = data.result[1];
+        var districtResult = data.result[2];
+        param.success(data,{
+          provinceResult: provinceResult,
+          cityResult: cityResult,
+          districtResult: districtResult
+        });
+      } else if (feature == 'getDistrictByCityId') {
+        var districtByCity = data.result[0];
+        param.success(data, districtByCity);
+      } else if (feature == 'calculateDistance') {
+        var calculateDistanceResult = data.result.elements;  
+        var distance = [];
+        for (var i = 0; i < calculateDistanceResult.length; i++){
+          distance.push(calculateDistanceResult[i].distance);
+        }   
+        param.success(data, {
+          calculateDistanceResult: calculateDistanceResult,
+          distance: distance
+          });
+      } else if (feature == 'direction') {
+        var direction = data.result.routes;
+        param.success(data,direction);
+      } else {
+        param.success(data);
+      }
+    },
+
+    /**
+     * 构造微信请求参数,公共属性处理
+     * 
+     * @param {Object} param 接口参数
+     * @param {Object} param 配置项
+     * @param {String} feature 方法名
+     */
+    buildWxRequestConfig(param, options, feature) {
+        var that = this;
+        options.header = { "content-type": "application/json" };
+        options.method = 'GET';
+        options.success = function (res) {
+            var data = res.data;
+            if (data.status === 0) {
+              that.handleData(param, data, feature);
+            } else {
+                param.fail(data);
+            }
+        };
+        options.fail = function (res) {
+            res.statusCode = ERROR_CONF.WX_ERR_CODE;
+            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+        };
+        options.complete = function (res) {
+            var statusCode = +res.statusCode;
+            switch(statusCode) {
+                case ERROR_CONF.WX_ERR_CODE: {
+                    param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+                    break;
+                }
+                case ERROR_CONF.WX_OK_CODE: {
+                    var data = res.data;
+                    if (data.status === 0) {
+                        param.complete(data);
+                    } else {
+                        param.complete(that.buildErrorConfig(data.status, data.message));
+                    }
+                    break;
+                }
+                default:{
+                    param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
+                }
+
+            }
+        };
+        return options;
+    },
+
+    /**
+     * 处理用户参数是否传入坐标进行不同的处理
+     */
+    locationProcess(param, locationsuccess, locationfail, locationcomplete) {
+        var that = this;
+        locationfail = locationfail || function (res) {
+            res.statusCode = ERROR_CONF.WX_ERR_CODE;
+            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+        };
+        locationcomplete = locationcomplete || function (res) {
+            if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
+                param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+            }
+        };
+        if (!param.location) {
+            that.getWXLocation(locationsuccess, locationfail, locationcomplete);
+        } else if (that.checkLocation(param)) {
+            var location = Utils.getLocationParam(param.location);
+            locationsuccess(location);
+        }
+    }
+};
+
+
+class QQMapWX {
+
+    /**
+     * 构造函数
+     * 
+     * @param {Object} options 接口参数,key 为必选参数
+     */
+    constructor(options) {
+        if (!options.key) {
+            throw Error('key值不能为空');
+        }
+        this.key = options.key;
+		this.BASE_URL = 'https://apis.map.qq.com/ws/';
+		if(options.BASE_URL!==''){
+			this.BASE_URL = options.BASE_URL;
+		}	
+		this.URL_SEARCH = this.BASE_URL + 'place/v1/search';
+		this.URL_SUGGESTION = this.BASE_URL + 'place/v1/suggestion';
+		this.URL_GET_GEOCODER = this.BASE_URL + 'geocoder/v1/';
+		this.URL_CITY_LIST = this.BASE_URL + 'district/v1/list';
+		this.URL_AREA_LIST = this.BASE_URL + 'district/v1/getchildren';
+		this.URL_DISTANCE = this.BASE_URL + 'distance/v1/';
+		this.URL_DIRECTION = this.BASE_URL + 'direction/v1/';
+    };
+
+    /**
+     * POI周边检索
+     *
+     * @param {Object} options 接口参数对象
+     * 
+     * 参数对象结构可以参考
+     * @see http://lbs.qq.com/webservice_v1/guide-search.html
+     */
+    search(options) {
+        var that = this;
+        options = options || {};
+
+        Utils.polyfillParam(options);
+
+        if (!Utils.checkKeyword(options)) {
+            return;
+        }
+
+        var requestParam = {
+            keyword: options.keyword,
+            orderby: options.orderby || '_distance',
+            page_size: options.page_size || 10,
+            page_index: options.page_index || 1,
+            output: 'json',
+            key: that.key
+        };
+
+        if (options.address_format) {
+            requestParam.address_format = options.address_format;
+        }
+
+        if (options.filter) {
+            requestParam.filter = options.filter;
+        }
+
+        var distance = options.distance || "1000";
+        var auto_extend = options.auto_extend || 1;
+        var region = null;
+        var rectangle = null;
+
+        //判断城市限定参数
+        if (options.region) {
+          region = options.region;
+        }
+
+        //矩形限定坐标(暂时只支持字符串格式)
+        if (options.rectangle) {
+          rectangle = options.rectangle;
+        }
+
+        var locationsuccess = function (result) {        
+          if (region && !rectangle) {
+            //城市限定参数拼接
+            requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")";
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+            }
+          } else if (rectangle && !region) {
+            //矩形搜索
+            requestParam.boundary = "rectangle(" + rectangle + ")";
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+            }
+            } else {
+              requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")";
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+            }
+            }            
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: that.URL_SEARCH,
+                data: requestParam
+            }, 'search'));
+        };
+        Utils.locationProcess(options, locationsuccess);
+    };
+
+    /**
+     * sug模糊检索
+     *
+     * @param {Object} options 接口参数对象
+     * 
+     * 参数对象结构可以参考
+     * http://lbs.qq.com/webservice_v1/guide-suggestion.html
+     */
+    getSuggestion(options) {
+        var that = this;
+        options = options || {};
+        Utils.polyfillParam(options);
+
+        if (!Utils.checkKeyword(options)) {
+            return;
+        }
+
+        var requestParam = {
+            keyword: options.keyword,
+            region: options.region || '全国',
+            region_fix: options.region_fix || 0,
+            policy: options.policy || 0,
+            page_size: options.page_size || 10,//控制显示条数
+            page_index: options.page_index || 1,//控制页数
+            get_subpois : options.get_subpois || 0,//返回子地点
+            output: 'json',
+            key: that.key
+        };
+        //长地址
+        if (options.address_format) {
+          requestParam.address_format = options.address_format;
+        }
+        //过滤
+        if (options.filter) {
+          requestParam.filter = options.filter;
+        }
+        //排序
+        if (options.location) {
+          var locationsuccess = function (result) {
+            requestParam.location = result.latitude + ',' + result.longitude;
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+              url: that.URL_SUGGESTION,
+              data: requestParam
+            }, "suggest"));      
+          };
+          Utils.locationProcess(options, locationsuccess);
+        } else {
+          if (options.sig) {
+            requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+          }
+          wx.request(Utils.buildWxRequestConfig(options, {
+            url: that.URL_SUGGESTION,
+            data: requestParam
+          }, "suggest"));      
+        }        
+    };
+
+    /**
+     * 逆地址解析
+     *
+     * @param {Object} options 接口参数对象
+     * 
+     * 请求参数结构可以参考
+     * http://lbs.qq.com/webservice_v1/guide-gcoder.html
+     */
+    reverseGeocoder(options) {
+        var that = this;
+        options = options || {};
+        Utils.polyfillParam(options);
+        var requestParam = {
+            coord_type: options.coord_type || 5,
+            get_poi: options.get_poi || 0,
+            output: 'json',
+            key: that.key
+        };
+        if (options.poi_options) {
+            requestParam.poi_options = options.poi_options
+        }
+
+        var locationsuccess = function (result) {
+            requestParam.location = result.latitude + ',' + result.longitude;
+          if (options.sig) {
+            requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder');
+          }
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: that.URL_GET_GEOCODER,
+                data: requestParam
+            }, 'reverseGeocoder'));
+        };
+        Utils.locationProcess(options, locationsuccess);
+    };
+
+    /**
+     * 地址解析
+     *
+     * @param {Object} options 接口参数对象
+     * 
+     * 请求参数结构可以参考
+     * http://lbs.qq.com/webservice_v1/guide-geocoder.html
+     */
+    geocoder(options) {
+        var that = this;
+        options = options || {};
+        Utils.polyfillParam(options);
+
+        if (Utils.checkParamKeyEmpty(options, 'address')) {
+            return;
+        }
+
+        var requestParam = {
+            address: options.address,
+            output: 'json',
+            key: that.key
+        };
+
+        //城市限定
+        if (options.region) {
+          requestParam.region = options.region;
+        }
+
+        if (options.sig) {
+          requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: that.URL_GET_GEOCODER,
+            data: requestParam
+        },'geocoder'));
+    };
+
+
+    /**
+     * 获取城市列表
+     *
+     * @param {Object} options 接口参数对象
+     * 
+     * 请求参数结构可以参考
+     * http://lbs.qq.com/webservice_v1/guide-region.html
+     */
+    getCityList(options) {
+        var that = this;
+        options = options || {};
+        Utils.polyfillParam(options);
+        var requestParam = {
+            output: 'json',
+            key: that.key
+        };
+
+        if (options.sig) {
+          requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: that.URL_CITY_LIST,
+            data: requestParam
+        },'getCityList'));
+    };
+
+    /**
+     * 获取对应城市ID的区县列表
+     *
+     * @param {Object} options 接口参数对象
+     * 
+     * 请求参数结构可以参考
+     * http://lbs.qq.com/webservice_v1/guide-region.html
+     */
+    getDistrictByCityId(options) {
+        var that = this;
+        options = options || {};
+        Utils.polyfillParam(options);
+
+        if (Utils.checkParamKeyEmpty(options, 'id')) {
+            return;
+        }
+
+        var requestParam = {
+            id: options.id || '',
+            output: 'json',
+            key: that.key
+        };
+
+        if (options.sig) {
+          requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: that.URL_AREA_LIST,
+            data: requestParam
+        },'getDistrictByCityId'));
+    };
+
+    /**
+     * 用于单起点到多终点的路线距离(非直线距离)计算:
+     * 支持两种距离计算方式:步行和驾车。
+     * 起点到终点最大限制直线距离10公里。
+     *
+     * 新增直线距离计算。
+     * 
+     * @param {Object} options 接口参数对象
+     * 
+     * 请求参数结构可以参考
+     * http://lbs.qq.com/webservice_v1/guide-distance.html
+     */
+    calculateDistance(options) {
+        var that = this;
+        options = options || {};
+        Utils.polyfillParam(options);
+
+        if (Utils.checkParamKeyEmpty(options, 'to')) {
+            return;
+        }
+
+        var requestParam = {
+            mode: options.mode || 'walking',
+            to: Utils.location2query(options.to),
+            output: 'json',
+            key: that.key
+        };
+
+        if (options.from) {
+          options.location = options.from;
+        }
+
+        //计算直线距离
+        if(requestParam.mode == 'straight'){        
+          var locationsuccess = function (result) {
+            var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标
+            var data = {
+              message:"query ok",
+              result:{
+                elements:[]
+              },
+              status:0
+            };
+            for (var i = 0; i < locationTo.length; i++) {
+              data.result.elements.push({//将坐标存入
+                distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng),
+                duration:0,
+                from:{
+                  lat: result.latitude,
+                  lng:result.longitude
+                },
+                to:{
+                  lat: locationTo[i].lat,
+                  lng: locationTo[i].lng
+                }
+              });            
+            }
+            var calculateResult = data.result.elements;
+            var distanceResult = [];
+            for (var i = 0; i < calculateResult.length; i++) {
+              distanceResult.push(calculateResult[i].distance);
+            }  
+            return options.success(data,{
+              calculateResult: calculateResult,
+              distanceResult: distanceResult
+            });
+          };
+          
+          Utils.locationProcess(options, locationsuccess);
+        } else {
+          var locationsuccess = function (result) {
+            requestParam.from = result.latitude + ',' + result.longitude;
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance');
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+              url: that.URL_DISTANCE,
+              data: requestParam
+            },'calculateDistance'));
+          };
+
+          Utils.locationProcess(options, locationsuccess);
+        }      
+    };
+
+  /**
+   * 路线规划:
+   * 
+   * @param {Object} options 接口参数对象
+   * 
+   * 请求参数结构可以参考
+   * https://lbs.qq.com/webservice_v1/guide-road.html
+   */
+  direction(options) {
+    var that = this;
+    options = options || {};
+    Utils.polyfillParam(options);
+
+    if (Utils.checkParamKeyEmpty(options, 'to')) {
+      return;
+    }
+
+    var requestParam = {
+      output: 'json',
+      key: that.key
+    };
+
+    //to格式处理
+    if (typeof options.to == 'string') {
+      requestParam.to = options.to;
+    } else {
+      requestParam.to = options.to.latitude + ',' + options.to.longitude;
+    }
+    //初始化局部请求域名
+    var SET_URL_DIRECTION = null;
+    //设置默认mode属性
+    options.mode = options.mode || MODE.driving;
+
+    //设置请求域名
+    SET_URL_DIRECTION = that.URL_DIRECTION + options.mode;
+
+    if (options.from) {
+      options.location = options.from;
+    }
+
+    if (options.mode == MODE.driving) {
+      if (options.from_poi) {
+        requestParam.from_poi = options.from_poi;
+      }
+      if (options.heading) {
+        requestParam.heading = options.heading;
+      }
+      if (options.speed) {
+        requestParam.speed = options.speed;
+      }
+      if (options.accuracy) {
+        requestParam.accuracy = options.accuracy;
+      }
+      if (options.road_type) {
+        requestParam.road_type = options.road_type;
+      }
+      if (options.to_poi) {
+        requestParam.to_poi = options.to_poi;
+      }
+      if (options.from_track) {
+        requestParam.from_track = options.from_track;
+      }
+      if (options.waypoints) {
+        requestParam.waypoints = options.waypoints;
+      }
+      if (options.policy) {
+        requestParam.policy = options.policy;
+      }
+      if (options.plate_number) {
+        requestParam.plate_number = options.plate_number;
+      }
+    }
+
+    if (options.mode == MODE.transit) {
+      if (options.departure_time) {
+        requestParam.departure_time = options.departure_time;
+      }
+      if (options.policy) {
+        requestParam.policy = options.policy;
+      }
+    } 
+
+    var locationsuccess = function (result) {
+      requestParam.from = result.latitude + ',' + result.longitude;
+      if (options.sig) {
+        requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode);
+      }
+      wx.request(Utils.buildWxRequestConfig(options, {
+        url: SET_URL_DIRECTION,
+        data: requestParam
+      }, 'direction'));
+    };
+
+    Utils.locationProcess(options, locationsuccess);
+  }
+};
+
+module.exports = QQMapWX;

+ 77 - 0
components/mapView/mapView.vue

@@ -0,0 +1,77 @@
+<template>
+	<view>
+		<view class="">
+			<view class="">
+				 <map id="map" class="mapbody" :style="'height:'+mapHeight+'rpx;'" :latitude="latitude" :longitude="longitude"  :markers="covers" @regionchange="regionChange">
+				</map>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"mapView",
+		props: {
+			pcovers:'',
+			
+		},
+		data() {
+			return {
+				mapHeight:0,
+				mapready:false,
+				covers:[],
+				includePoints:[],
+				latitude:0,
+				longitude:0
+			};
+		},
+		created() {
+			var info = uni.getSystemInfoSync();
+			console.log(info);
+			this.mapHeight=info.windowHeight/2;
+			this.mapContext = uni.createMapContext("map",this); 
+		},
+		
+		watch: {
+			pcovers(val){
+				this.covers = this.pcovers;
+				let include = [];
+				for(var i=0;i<this.covers.length;i++){
+					let  poi = {
+						longitude: this.covers[i].longitude,
+						latitude: this.covers[i].latitude
+					}
+					include.push(poi);
+				}
+				this.latitude=this.pcovers[2].latitude;
+				this.longitude=this.pcovers[2].longitude;
+			}
+		},
+		methods: {
+			regionChange(){
+				var that = this;
+				if(!this.mapready){
+					return;
+				}
+				
+				this.mapContext.getCenterLocation({
+					success: res => {
+						console.log('getCenterLocation');
+					},
+					fail: res => {
+						console.log("getCenterLocation11")
+					}
+				})
+			},
+		},
+	}
+</script>
+
+<style>
+	
+	.mapbody{
+		width: 100%;
+	}
+
+</style>

+ 56 - 0
components/myImage/myImage.vue

@@ -0,0 +1,56 @@
+<template>
+	<view>
+		<image v-if="isIcon" style="border-radius: 60rpx;" :class="[mymode=='widthFix'?'imageW':'imagev']"  :src="showdefault==1?'/static/logo.png':baseUrl+comUrl" :mode="mymode" @error="imageError" @click="myimageclick"></image>
+		<image v-if="!isIcon" :class="[mymode=='widthFix'?'imageW':'imagev']"  :src="showdefault==1?'/static/logo.png':baseUrl+comUrl" :mode="mymode" @error="imageError" @click="myimageclick"></image>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"myImage",
+		props:{
+			mysrc: '',
+			mymode:'',
+			isIcon:false
+		},
+		data() {
+			return {
+				defaultImage:'/static/logo.png',
+				baseUrl:'https://backend.cityexpress168.com.vn/prod-api',
+				showdefault:0,
+				comUrl:this.mysrc
+			};
+		},
+		watch: {
+			mysrc(val){
+				this.showdefault=0;
+				this.comUrl = this.mysrc
+				//console.log(this.comUrl);
+			}
+		},
+		methods:{
+			imageError(){
+				//this.comUrl = this.defaultImage;//morentup
+				this.showdefault=1;
+			},
+			myimageclick(comUrl){
+				this.$emit('Emyimageclick',comUrl);
+			},
+		},
+	}
+</script>
+
+<style>
+	.imageW{
+		margin: 0rpx;
+		width:100%;
+	}
+	.imageH{
+		margin: 0rpx;
+		height:100%;
+	}
+	.imagev{
+		width:100%;
+		height:100%;
+	}
+</style>

+ 77 - 0
components/netImage/netImage.vue

@@ -0,0 +1,77 @@
+<template>
+	<view :class="backgrS==1?'':'imageBGV'" :style="{width:width+'rpx',height:height+'rpx',borderRadius:bradius+'rpx'}">
+		<image :style="{width:width+'rpx',height:height+'rpx',borderRadius:bradius+'rpx'}"  :src="compleurl(comUrl)" :mode="mymode" @error="imageError" @click="myimageclick"></image>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"netImage",
+		props:{
+			mysrc: '',
+			mymode:'',
+			width:0,
+			height:0,
+			bradius:0,
+			backgrS:0,
+		},
+		data() {
+			return {
+				defaultImage:'/static/logo.png',
+				baseUrl:'https://backend.cityexpress168.com.vn/prod-api',
+				showdefault:0,
+				comUrl:this.mysrc
+			};
+		},
+		watch: {
+			mysrc(val){
+				this.showdefault=0;
+				this.comUrl = this.mysrc
+				//console.log('watch-------------')
+				//console.log(this.comUrl);
+			}
+		},
+		methods:{
+			imageError(){
+				this.comUrl ='';// this.defaultImage;//morentup
+				//console.log('imageError---------------')
+				//console.log(this.baseUrl+this.comUrl)
+				this.showdefault=1;
+			},
+			myimageclick(){
+				this.$emit('Emyimageclick',this.comUrl);
+			},
+			compleurl(url){
+				//console.log('------compleurl',url)
+				if(!url){
+					return '';
+				}
+				if(url.length<8){
+					return '';
+				}
+				var https= url.substring(0,8);
+				if(https==='https://'){
+					return url;
+				}
+				var http= url.substring(0,7);
+				if(http==='http://'){
+					return url;
+				}
+				else if(http==='/static/'){
+					return url;
+				}
+				else{
+					//console.log(this.baseUrl+url);
+					return (this.baseUrl+url);
+				}
+			}
+		},
+	}
+</script>
+
+<style>
+	.imageBGV{
+		background-color:floralwhite;
+		border: 1rpx solid lightgray;
+	}
+</style>

+ 238 - 0
components/popViewGG/popViewGG.vue

@@ -0,0 +1,238 @@
+<template>
+	<view>
+		<view class="tui-actionsheet-mask" :class="[show?'tui-mask-show':'']" @tap="handleClickMask"></view>
+		<view class="tui-actionsheet-class tui-actionsheet" :class="[show?'tui-actionsheet-show':'']">
+			<view class="tui-tips" :style="{fontSize:size+'rpx',color:color}" v-if="tips">
+				{{tips}}
+			</view>
+			<view :class="[isCancel?'tui-operate-box':'tui-operate-boxN']">
+				<slot></slot>
+			</view>
+			<view v-if="showbotom">
+				<view class="tui-actionsheet-btn tui-actionsheet-cancel" hover-class="tui-actionsheet-hover"
+					:hover-stay-time="150" v-if="isCancel" @tap="handleClickCancel(1)">{{$t("order.wancheng")}}</view>
+			</view>
+			
+		</view>
+	</view>
+</template>
+ 
+<script>
+	export default {
+		name: "tuiActionsheet",
+		props: {
+			//点击遮罩 是否可关闭
+			maskClosable: {
+				type: Boolean,
+				default: true
+			},
+			//显示操作菜单
+			show: {
+				type: Boolean,
+				default: false
+			},
+			//菜单按钮数组,自定义文本颜色,红色参考色:#e53a37
+			itemList:{},
+			//提示文字
+			tips: {
+				type: String,
+				default: ""
+			},
+			//提示文字
+			acttips: {
+				type: String,
+				default:''
+			},
+			//提示文字颜色
+			color: {
+				type: String,
+				default: "#9a9a9a"
+			},
+			//提示文字大小 rpx
+			size: {
+				type: Number,
+				default: 26
+			},
+			//是否需要取消按钮
+			isCancel: {
+				type: Boolean,
+				default: true
+			},
+			//是否需要底部按钮
+			showbotom: {
+				type: Boolean,
+				default: true
+			},
+			
+		},
+		watch: {
+			show(val){
+				if(val){
+					// 背景不可滚动
+					//document.body.style.overflow='hidden';
+				}
+				else{
+					// 背景可滚动
+					//document.body.style.overflow='';
+				}
+			}
+		},
+		methods: {
+			handleClickMask() {
+				if (!this.maskClosable) return;
+				this.handleClickCancel(0);
+			},
+			handleClickItem(e) {
+				if (!this.show) return;
+				const dataset = e.currentTarget.dataset;
+				this.$emit('click', {
+					index: dataset.index
+				});
+			},
+			
+			selectGuige(index,name){
+				this.$emit('EselectGuige',index,name);
+			},
+			
+			handleClickCancel(type) {
+				if(type==1){
+					this.$emit('ClickCancel');
+				}
+				this.$emit('chooseCancel');
+			}
+		}
+	}
+</script>
+ 
+<style>
+	.tui-actionsheet {
+		width:750upx;
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 9999;
+		visibility: hidden;
+		transform: translate3d(0, 100%, 0);
+		transform-origin: center;
+		transition: all 0.3s ease-in-out;
+		background: #eaeaec;
+		min-height: 100rpx;
+	}
+ 
+	.tui-actionsheet-show {
+		transform: translate3d(0, 0, 0);
+		visibility: visible;
+	}
+ 
+	.tui-tips {
+		width:750upx;
+		padding: 30rpx 60rpx;
+		box-sizing: border-box;
+		text-align: center;
+		background: #fff;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+ 
+	.tui-operate-box {
+		padding-bottom: 12rpx;
+		max-height: 80vh;
+		overflow: scroll;
+	}
+	.tui-operate-boxN {
+		max-height: 80vh;
+		overflow: scroll;
+	}
+ 
+	.tui-actionsheet-btn {
+		width:750upx;
+		height: 100rpx;
+		background: #fff;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		text-align: center;
+		font-size: 36rpx;
+		position: relative;
+	}
+ 
+	.tui-btn-last {
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+ 
+	.tui-actionsheet-divider::before {
+		content: '';
+		width:750upx;
+		border-top: 1rpx solid #d9d9d9;
+		position: absolute;
+		top: 0;
+		left: 0;
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+	}
+ 
+	.tui-actionsheet-cancel {
+		color: #1a1a1a;
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+ 
+	.tui-actionsheet-hover {
+		background: #f7f7f9;
+	}
+ 
+	.tui-actionsheet-mask {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: rgba(0, 0, 0, 0.6);
+		z-index: 9996;
+		transition: all 0.3s ease-in-out;
+		opacity: 0;
+		visibility: hidden;
+	}
+ 
+	.tui-mask-show {
+		opacity: 1;
+		visibility: visible;
+	}
+	
+	.skuViewCt{
+		display: flex;
+		flex-direction: column;
+		justify-content:center;
+		width: 100%;
+		margin-top: 10rpx;
+	}
+	
+	.contensbgg{
+		display: flex;
+		flex-wrap: wrap;
+		justify-content:flex-start;
+		align-items:center;
+	}
+	
+	.guigeleixing{
+		font-size: 26rpx;
+		line-height: 40rpx;
+		height: 40rpx;
+		color: black;
+		font-weight: bold;
+	}
+	.youhuixinxi{
+		margin: 8rpx;
+		padding: 4rpx;
+		font-size: 26rpx;
+		line-height: 54rpx;
+		height: 54rpx;
+		border: 2rpx solid lightgray;
+		border-radius: 8rpx;
+	}
+	.xz{
+		background-color: #ff0000;
+	}
+	
+</style>

+ 46 - 0
components/swiperImgs/swiperImgs.vue

@@ -0,0 +1,46 @@
+<template>
+	<view :style="{width:width+'rpx',height:height+'rpx'}">
+		<swiper :style="{width:width+'rpx',height:height+'rpx'}" :indicator-dots="true" 
+				:autoplay="true"       
+				:interval="2000"  
+				indicator-color="rgba(0, 0, 0, 0.3)"
+				indicator-active-color="#000000"
+				:duration="1000"
+				circular>      
+			<swiper-item v-for="(item,index) in imageList" :key="index">
+				<view class="contentColumnC">
+					<netImage :width="(width-56)" :height="Imgmargin(height)" bradius="0" :mysrc="item" mymode="scaleToFill"></netImage>
+				</view>
+			</swiper-item>
+		</swiper>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"swiperImgs",
+		props:{
+			imageList:'',
+			width:0,
+			height:0,
+		},
+		data() {
+			return {
+				
+			};
+		},
+		methods:{
+			Imgmargin(size){
+				return (size-30);
+			},
+		},
+		
+	}
+</script>
+
+<style>
+.swiper-item{
+	width: 100%;
+	height: 100%;
+}
+</style>

+ 78 - 0
components/weizhimap/weizhimap - 副本.nvue

@@ -0,0 +1,78 @@
+<template>
+	<view>
+		<map id="map" class="mapbody" :style="'height:'+height+'rpx;'" scale="18" show-location="true" :latitude="latitude" :longitude="longitude" :markers="marker">
+		</map>
+	</view>
+</template>
+
+<script>
+	import api from "@/pages/api/api.js"
+	export default {
+		name:"weizhimap",
+		props:{
+			covers:'',
+			height:0
+		},
+		data() {
+			return {
+				latitude:0,
+				longitude:0,
+				marker:'',
+				markImage:'/static/images/dizhil@3x.png',
+			};
+		},
+		onReady() {
+			
+		},
+		watch:{
+			covers(val){
+				console.log('-----',val);
+				this.markImage = val[0].iconPath;
+				setTimeout(()=>{
+					this.setLocat(val[0].latitude,val[0].longitude,1,3);
+				},500)
+				
+			}
+		},
+		methods:{
+			
+			setLocat(latitude,longitude,f,t){
+				this.latitude=latitude;
+				this.longitude = longitude;
+				this.marker=[{
+					id:1,//控件id
+					latitude: this.latitude,
+					longitude: this.longitude,
+					iconPath: this.markImage
+				}];
+				console.log(this.marker);
+				return;
+				var latlng = longitude+','+latitude;
+				
+				api('setLocat',{
+					latlng:latlng,
+					from:f,
+					to:t
+				},res=>{
+					this.latitude=res.data.data.result[0].y;
+					this.longitude = res.data.data.result[0].x;
+					this.marker=[{
+						latitude: this.latitude,
+						longitude: this.longitude,
+						iconPath: this.markImage
+					}];
+				},failc=>{
+					//console.log('getadvertis----',failc)
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+	.mapbody{
+		width: 750upx;
+		height: 400rpx;
+	}
+
+</style>

+ 83 - 0
components/weizhimap/weizhimap.nvue

@@ -0,0 +1,83 @@
+<template>
+	<view>
+		<web-view class="mapbody" :src="webUrl"></web-view>
+	</view>
+</template>
+
+<script>
+	import api from "@/pages/api/api.js"
+	export default {
+		name:"weizhimap",
+		props:{
+			covers:'',
+			height:0
+		},
+		data() {
+			return {
+				webUrl: '',
+				latitude:0,
+				longitude:0,
+				marker:'',
+				markImage:'/static/images/dizhil@3x.png',
+			};
+		},
+		onReady() {
+			
+		},
+		watch:{
+			covers(val){
+				console.log('-----',val);
+				this.markImage = val[0].iconPath;
+				if(val[1]){
+					this.webUrl = '/hybrid/html/maps/mapindex.html?sstate=0&&lat=' + val[0].latitude + '&lng=' + val[0].longitude+'&nlng='+val[1].longitude+'&nlat='+val[1].latitude;
+				}
+				else{
+					this.webUrl = '/hybrid/html/maps/mapindex.html?sstate=0&&lat=' + val[0].latitude + '&lng=' + val[0].longitude+'&nlng=0&nlat=0';
+				}
+				console.log(this.webUrl)
+				
+			}
+		},
+		methods:{
+			
+			setLocat(latitude,longitude,f,t){
+				this.latitude=latitude;
+				this.longitude = longitude;
+				this.marker=[{
+					id:1,//控件id
+					latitude: this.latitude,
+					longitude: this.longitude,
+					iconPath: this.markImage
+				}];
+				console.log(this.marker);
+				return;
+				var latlng = longitude+','+latitude;
+				
+				api('setLocat',{
+					latlng:latlng,
+					from:f,
+					to:t
+				},res=>{
+					this.latitude=res.data.data.result[0].y;
+					this.longitude = res.data.data.result[0].x;
+					this.marker=[{
+						latitude: this.latitude,
+						longitude: this.longitude,
+						iconPath: this.markImage
+					}];
+				},failc=>{
+					//console.log('getadvertis----',failc)
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+	.mapbody{
+		width: 750upx;
+		height: 500rpx;
+		background-color: aquamarine;
+	}
+
+</style>

+ 974 - 0
components/yhdsl-cropper/yhdsl-cropper.vue

@@ -0,0 +1,974 @@
+<template>
+	<view class="yhdsl" v-show="isShow">
+		<view>
+			<view class="cropper-content">
+				<view v-if="isShowImg" class="uni-corpper"
+					:style="'width:' + cropperInitW + 'px;height:' + cropperInitH + 'px;background:#000'">
+					<view class="uni-corpper-content" :style="
+							'width:' +
+								cropperW +
+								'px;height:' +
+								cropperH +
+								'px;left:' +
+								cropperL +
+								'px;top:' +
+								cropperT +
+								'px'
+						">
+						<image :src="imageSrc" :style="'width:' + cropperW + 'px;height:' + cropperH + 'px'"></image>
+						<view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove"
+							@touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd" :style="
+								'left:' + cutL + 'px;top:' + cutT + 'px;right:' + cutR + 'px;bottom:' + cutB + 'px'
+							">
+							<view class="uni-cropper-view-box">
+								<view class="uni-cropper-dashed-h"></view>
+								<view class="uni-cropper-dashed-v"></view>
+ 
+								<!-- 截图区域顶部 -->
+								<view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 截图区域右侧 -->
+								<view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 截图区域底部 -->
+								<view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 截图区域左侧 -->
+								<view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 右下角截图滑块 -->
+								<view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-tr" data-drag="topTight"></view>
+								<view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-rb" data-drag="rightBottom"
+									@touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove" @touchend.stop="dragEnd"></view>
+								<view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
+								<view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="cropper-config">
+				<view class="button-box">
+					<button type="warn" @click="chooseImage">{{$t('order.quxiao')}}</button>
+					<!-- <button type="warn" @click="previewImg">预览</button> -->
+					<button type="warn" @click="finish">{{$t('order.queding')}}</button>
+				</view>
+			</view>
+			<canvas canvas-id="myCanvas" :style="
+					'position:absolute;border: 2px solid red; width:' +
+						imageW +
+						'px;height:' +
+						imageH +
+						'px;top:-9999px;left:-9999px;'
+				"></canvas>
+		</view>
+	</view>
+</template>
+ 
+<script>
+	let sysInfo = uni.getSystemInfoSync();
+	let SCREEN_WIDTH = sysInfo.screenWidth;
+	let SCREEN_HEIGHT = sysInfo.windowHeight + 40;
+	let PAGE_X, // 手按下的x位置
+		PAGE_Y, // 手按下y的位置
+		PR = sysInfo.pixelRatio, // dpi
+		T_PAGE_X, // 手移动的时候x的位置
+		T_PAGE_Y, // 手移动的时候Y的位置
+		CUT_L, // 初始化拖拽元素的left值
+		CUT_T, // 初始化拖拽元素的top值
+		CUT_R, // 初始化拖拽元素的
+		CUT_B, // 初始化拖拽元素的
+		CUT_W, // 初始化拖拽元素的宽度
+		CUT_H, //  初始化拖拽元素的高度
+		IMG_RATIO, // 图片比例
+		IMG_REAL_W, // 图片实际的宽度
+		IMG_REAL_H, // 图片实际的高度
+		DRAFG_MOVE_RATIO = 1, //移动时候的比例,
+		INIT_DRAG_POSITION = 100, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
+		DRAW_IMAGE_W = sysInfo.screenWidth; // 设置生成的图片宽度
+	export default {
+		/**
+		 * 页面的初始数据
+		 */
+		data() {
+			return {
+				imageSrc: "",
+				isShow: false,
+				isShowImg: false,
+				// 初始化的宽高
+				cropperInitW: SCREEN_WIDTH,
+				cropperInitH: SCREEN_HEIGHT,
+				// 动态的宽高
+				cropperW: SCREEN_WIDTH,
+				cropperH: SCREEN_HEIGHT - 100,
+				// 动态的left top值
+				cropperL: 0,
+				cropperT: 0,
+				transL: 0,
+				transT: 0,
+				// 图片缩放值
+				scaleP: 0,
+				imageW: 0,
+				imageH: 0,
+				// 裁剪框 宽高
+				cutL: 0,
+				cutT: 0,
+				cutB: SCREEN_WIDTH,
+				cutR: "100%",
+				qualityWidth: DRAW_IMAGE_W,
+				innerAspectRadio: DRAFG_MOVE_RATIO,
+			};
+		},
+		props: {
+			/* 截图质量,压缩比  */
+			quality: {
+				type: Number | String,
+				default: 1,
+			},
+ 
+
+			src: String,
+ 
+			fileType: {
+				type: String,
+				default: "png",
+				validator: function(t) {
+					// 这个值必须匹配下列字符串中的一个
+					return t === "png" || t === "jpg";
+				},
+			},
+ 
+			/* 截取类型,自由截取free;固定比例截取(正方形)fixed  */
+			mode: {
+				type: String,
+				default: "free",
+				validator: function(t) {
+					// 这个值必须匹配下列字符串中的一个
+					return t === "free" || t === "fixed" || t === "scale";
+				},
+			},
+			scale: {
+				type: Number,
+				default: 1,
+			},
+		},
+		created() {
+			if (this.src) {
+				this.imageSrc = this.src;
+				this.loadImage();
+				this.isShow = true;
+				this.isShowImg = true;
+			}
+		},
+		methods: {
+			setData: function(obj) {
+				let that = this;
+				Object.keys(obj).forEach(function(key) {
+					that.$set(that.$data, key, obj[key]);
+				});
+			},
+ 
+			/* 选择图片  */
+			chooseImage: function() {
+				var _this = this;
+				uni.chooseImage({
+					sourceType:["album"],
+					sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
+					count: 1,
+					success: function(res) {
+						if(res.tempFiles[0].size / 1024 < 1024) {
+							_this.setData({
+								imageSrc: res.tempFilePaths[0],
+							});
+							_this.loadImage();
+							_this.isShow = true;
+						} else {
+							uni.showToast({
+								title: 'Kích thước ảnh không được vượt quá 1024KB, kích thước hiện tại' + (res.tempFiles[0].size / 1024).toFixed(2) + 'KB',
+								icon: 'none'
+							})
+						}
+					},
+				});
+			},
+			/* 将图片加载到画布  */
+			loadImage: function() {
+				var _this = this;
+				uni.showLoading({
+					title: "图片加载中...",
+				});
+ 
+				/* 获取图片信息  */
+				uni.getImageInfo({
+					src: _this.imageSrc,
+					success: function success(res) {
+						let imgH = res.height;
+						let imgW = res.width;
+ 
+						// let IMG_SCR_H_R = SCREEN_HEIGHT / imgH;
+						// let IMG_SCR_W_R = SCREEN_WIDTH / imgW;
+ 
+						/* 图片的宽高比  */
+						IMG_RATIO = imgW / imgH;
+ 
+						/**
+						 * 如果图片更高一些,为确保图片能够完整在视窗内显示需如下处理
+						 * 1. 缩放图片的高为 视窗高度减去底部菜单按钮高度(120)
+						 * 2. 根据图片缩放后的高度,根据图片宽高比计算图片的宽度
+						 * 3. 如果步骤2计算的图片宽度大于屏幕宽度,则需要再次调整图片宽度为视窗宽度-margin(10)
+						 * 4. 根据步骤3的宽度,结合图片宽高比重新计算图片的高度
+						 */
+						if (IMG_RATIO < 1 && (SCREEN_HEIGHT - 120) * IMG_RATIO < SCREEN_WIDTH - 10) {
+							IMG_REAL_W = (SCREEN_HEIGHT - 120) * IMG_RATIO;
+							IMG_REAL_H = SCREEN_HEIGHT - 120;
+						} else {
+							IMG_REAL_W = SCREEN_WIDTH - 10;
+							IMG_REAL_H = IMG_REAL_W / IMG_RATIO;
+						}
+ 
+						/* 初始化裁剪区域的位置和形状  */
+						let [cutT, cutB, cutL, cutR] = _this.initCutArea(IMG_RATIO, IMG_REAL_H,
+						IMG_REAL_W);
+ 
+						_this.setData({
+							/* 裁剪区域的宽高同图片尺寸  */
+							cropperW: IMG_REAL_W,
+							cropperH: IMG_REAL_H,
+ 
+							/* 上下左右各留一定的margin已便更好的拖动裁剪区域  */
+							cropperL: Math.ceil((SCREEN_WIDTH - IMG_REAL_W) / 2),
+ 
+							/* 留出底部操作按钮位置 70  */
+							cropperT: Math.ceil((SCREEN_HEIGHT - IMG_REAL_H - 90) / 2),
+							cutL: cutL,
+							cutT: cutT,
+							cutR: cutR,
+							cutB: cutB,
+							// 图片缩放值
+							imageW: IMG_REAL_W,
+							imageH: IMG_REAL_H,
+							scaleP: IMG_REAL_W / SCREEN_WIDTH,
+							qualityWidth: DRAW_IMAGE_W,
+							innerAspectRadio: IMG_RATIO,
+						});
+						_this.setData({
+							isShowImg: true,
+						});
+						uni.hideLoading();
+					},
+				});
+			},
+ 
+			initCutArea(IMG_RATIO, IMG_REAL_H, IMG_REAL_W) {
+				let _this = this;
+				/* 自由裁剪裁剪区域默认覆盖整个图片  */
+				let cutT = 0;
+				let cutB = 0;
+				let cutL = 0;
+				let cutR = 0;
+ 
+				/* 正方形裁剪,初始化裁剪区域为正方形并居中  */
+				if (_this.mode == "fixed") {
+					if (IMG_RATIO < 1) {
+						/* 图片比较高  */
+						cutT = (IMG_REAL_H - IMG_REAL_W) / 2;
+						cutB = (IMG_REAL_H - IMG_REAL_W) / 2;
+					} else {
+						/* 图片比较宽  */
+						cutL = (IMG_REAL_W - IMG_REAL_H) / 2;
+						cutR = (IMG_REAL_W - IMG_REAL_H) / 2;
+					}
+				}
+ 
+				/* 固定比例裁剪,初始化裁剪区域比例和设定值相同  */
+				if (_this.mode == "scale") {
+					let scale = +_this.scale;
+					if (IMG_RATIO < 1) {
+						/* 图片比较高  */
+						if (IMG_REAL_W / scale > IMG_REAL_H) {
+							cutT = cutB = 0;
+							cutL = cutR = (IMG_REAL_W - IMG_REAL_H * scale) / 2;
+						} else {
+							cutR = cutL = 0;
+							cutT = cutB = (IMG_REAL_H - IMG_REAL_W / scale) / 2;
+						}
+					} else {
+						/* 图片比较宽  */
+						if (IMG_REAL_H * scale > IMG_REAL_W) {
+							cutL = cutR = 0;
+							cutB = cutT = (IMG_REAL_H - IMG_REAL_W / scale) / 2;
+						} else {
+							cutT = cutB = 0;
+							cutL = cutR = (IMG_REAL_W - IMG_REAL_H * scale) / 2;
+						}
+					}
+				}
+ 
+				return [cutT, cutB, cutL, cutR];
+			},
+			// 拖动时候触发的touchStart事件
+			contentStartMove(e) {
+				PAGE_X = e.touches[0].pageX;
+				PAGE_Y = e.touches[0].pageY;
+			},
+			// 拖动时候触发的touchMove事件
+			contentMoveing(e) {
+				var _this = this;
+				var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+				var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+				// 左移
+				if (dragLengthX > 0) {
+					if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL;
+				} else {
+					if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR;
+				}
+				if (dragLengthY > 0) {
+					if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT;
+				} else {
+					if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB;
+				}
+				this.setData({
+					cutL: this.cutL - dragLengthX,
+					cutT: this.cutT - dragLengthY,
+					cutR: this.cutR + dragLengthX,
+					cutB: this.cutB + dragLengthY,
+				});
+				PAGE_X = e.touches[0].pageX;
+				PAGE_Y = e.touches[0].pageY;
+			},
+			contentTouchEnd() {},
+ 
+			// 获取图片尺寸信息
+			previewImg() {
+				try {
+					var _this = this;
+					uni.showLoading({
+						title: "图片生成中...",
+					});
+					// 将图片写入画布
+					const ctx = uni.createCanvasContext("myCanvas", _this);
+					ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
+					ctx.draw(true, () => {
+						// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
+						var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W;
+						var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H;
+						var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W;
+						var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H;
+						uni.canvasToTempFilePath({
+								x: canvasL,
+								y: canvasT,
+								width: canvasW,
+								height: canvasH,
+								// destWidth: canvasW,
+								// destHeight: canvasH,
+								quality: +this.quality,
+								fileType: this.fileType,
+								canvasId: "myCanvas",
+								success: function(res) {
+									uni.hideLoading();
+									// 成功获得地址的地方
+									uni.previewImage({
+										current: "", // 当前显示图片的http链接
+										urls: [res.tempFilePath], // 需要预览的图片http链接列表
+									});
+								},
+								fail: function(err) {
+									uni.hideLoading();
+									uni.showToast({
+										title: "Chụp ảnh thất bại!",
+										icon: "none",
+									});
+								},
+							},
+							_this
+						);
+					});
+				} catch (e) {}
+			},
+ 
+			/* 完成裁剪,输出裁剪后的图片路径  */
+			finish: function() {
+				var _this = this;
+				uni.showLoading({
+					title: "图片生成中...",
+				});
+				// 将图片写入画布
+				const ctx = uni.createCanvasContext("myCanvas", _this);
+				ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
+				ctx.draw(true, () => {
+					// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
+					var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W;
+					var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H;
+					var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W;
+					var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H;
+					uni.canvasToTempFilePath({
+							x: canvasL,
+							y: canvasT,
+							width: canvasW,
+							height: canvasH,
+							// destWidth: canvasW,
+							// destHeight: canvasH,
+							quality: +this.quality,
+							fileType: this.fileType,
+							canvasId: "myCanvas",
+							success: function(res) {
+								uni.hideLoading();
+								// 成功获得地址的地方
+								_this.$emit("uploadImg", res.tempFilePath);
+								_this.isShow = false;
+							},
+							fail: function(err) {
+								uni.hideLoading();
+								uni.showToast({
+									title: "Chụp ảnh thất bại!",
+									icon: "none",
+								});
+							},
+						},
+						_this
+					);
+				});
+			},
+ 
+			// 设置大小的时候触发的touchStart事件
+			dragStart(e) {
+				T_PAGE_X = e.touches[0].pageX;
+				T_PAGE_Y = e.touches[0].pageY;
+				CUT_L = this.cutL;
+				CUT_R = this.cutR;
+				CUT_B = this.cutB;
+				CUT_T = this.cutT;
+			},
+ 
+			// 设置大小的时候触发的touchMove事件
+			dragMove(e) {
+				// this.mode == "fixed" ? this.fixedScaleDrag(e) : this.freeDrag(e);
+				this[this.mode + "Drag"](e);
+			},
+ 
+			/* 固定比例(正方形)截取 ,只有右下角裁剪滑动拖动有效*/
+			fixedDrag(e) {
+				var _this = this;
+				var dragType = e.target.dataset.drag;
+				switch (dragType) {
+					case "rightBottom":
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						// var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						// if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B;
+ 
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R;
+ 
+						/* 右侧和底部同比变化 */
+						let cutB = CUT_B + dragLengthX;
+						let cutR = CUT_R + dragLengthX;
+ 
+						/* 越界判断  */
+						if (_this.cutB == 0 && cutB < 0) return;
+						if (_this.cutR == 0 && cutR < 0) return;
+ 
+						(_this.cutB > 0 || CUT_B == 0) &&
+						this.setData({
+							cutB: cutB < 0 ? 0 : cutB,
+							cutR: cutR,
+						});
+						break;
+					default:
+						break;
+				}
+			},
+ 
+			/* 等比例截图,只能通过右下角的滑块改变截图区域  */
+			scaleDrag(e) {
+				var _this = this;
+				var dragType = e.target.dataset.drag;
+				switch (dragType) {
+					case "rightBottom":
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						// var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						// if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B;
+ 
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R;
+ 
+						/* 右侧和底部同比变化 */
+						let cutB = CUT_B + dragLengthX / _this.scale;
+						let cutR = CUT_R + dragLengthX;
+ 
+						/* 越界判断  */
+						if (_this.cutB == 0 && cutB < 0) return;
+						if (_this.cutR == 0 && cutR < 0) return;
+ 
+						(_this.cutB > 0 || CUT_B == 0) &&
+						this.setData({
+							cutB: cutB < 0 ? 0 : cutB,
+							cutR: cutR,
+						});
+						break;
+					default:
+						break;
+				}
+			},
+ 
+			/* 自由截取,整个裁剪边框均能拖动  */
+			freeDrag(e) {
+				var _this = this;
+				var dragType = e.target.dataset.drag;
+				switch (dragType) {
+					case "right":
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						if (CUT_R + dragLength < 0) dragLength = -CUT_R;
+						this.setData({
+							cutR: CUT_R + dragLength,
+						});
+						break;
+					case "left":
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						if (CUT_L - dragLength < 0) dragLength = CUT_L;
+						if (CUT_L - dragLength > this.cropperW - this.cutR)
+							dragLength = CUT_L - (this.cropperW - this.cutR);
+						this.setData({
+							cutL: CUT_L - dragLength,
+						});
+						break;
+					case "top":
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						if (CUT_T - dragLength < 0) dragLength = CUT_T;
+						if (CUT_T - dragLength > this.cropperH - this.cutB)
+							dragLength = CUT_T - (this.cropperH - this.cutB);
+						this.setData({
+							cutT: CUT_T - dragLength,
+						});
+						break;
+					case "bottom":
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						if (CUT_B + dragLength < 0) dragLength = -CUT_B;
+						this.setData({
+							cutB: CUT_B + dragLength,
+						});
+						break;
+					case "rightBottom":
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B;
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R;
+						let cutB = CUT_B + dragLengthY;
+						let cutR = CUT_R + dragLengthX;
+						this.setData({
+							cutB: cutB,
+							cutR: cutR,
+						});
+						break;
+					default:
+						break;
+				}
+			},
+		},
+	};
+</script>
+ 
+<style>
+	/* pages/uni-cropper/index.wxss */
+	.yhdsl {
+		background-color: #fff;
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 50px;
+		display: block;
+		align-items: center;
+		flex-direction: column;
+		z-index: 998;
+		height: 100vh;
+	}
+ 
+	.cropper-config {
+		position: fixed;
+		z-index: 999;
+		bottom: 10px;
+		left: 0;
+		right: 0;
+ 
+		width: 90%;
+		margin: 0 auto;
+		/* padding: 20upx 40upx; */
+	}
+ 
+	.button-box {
+		position: absolute;
+		bottom: 0;
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+ 
+		width: 100%;
+	}
+ 
+	.button-box button {
+		width: 25%;
+		line-height: 35px;
+		height: 35px;
+		background-color: #509cff;
+	}
+ 
+	.cropper-content {
+		width: 100%;
+		min-height: 750upx;
+	}
+ 
+	.uni-corpper {
+		position: relative;
+ 
+		overflow: hidden;
+ 
+		box-sizing: border-box;
+		margin: 0 auto;
+ 
+		-webkit-user-select: none;
+		-moz-user-select: none;
+		-ms-user-select: none;
+		user-select: none;
+ 
+		-webkit-tap-highlight-color: transparent;
+		-webkit-touch-callout: none;
+	}
+ 
+	.uni-corpper-content {
+		position: relative;
+	}
+ 
+	.uni-corpper-content image {
+		display: block;
+ 
+		width: 100%;
+		min-width: 0 !important;
+		max-width: none !important;
+		/* height: 100%; */
+		min-height: 0 !important;
+		/* max-height: none !important; */
+ 
+		max-height: calc(100vh - 100upx);
+		margin: 0 auto;
+ 
+		image-orientation: 0deg !important;
+	}
+ 
+	/* 移动图片效果 */
+	.uni-cropper-drag-box {
+		position: absolute;
+		z-index: 1;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+ 
+		cursor: move;
+ 
+		background: rgba(0, 0, 0, 0.479);
+	}
+ 
+	/* 内部的信息 */
+	.uni-corpper-crop-box {
+		position: absolute;
+		z-index: 2;
+		max-height: calc(100vh - 100upx);
+		background: rgba(56, 50, 50, 0.479);
+	}
+ 
+	.uni-corpper-crop-box .uni-cropper-view-box {
+		position: relative;
+ 
+		display: block;
+		overflow: visible;
+ 
+		width: 100%;
+		height: 100%;
+ 
+		max-height: calc(100vh - 100upx);
+		outline: 5upx solid rgb(43, 89, 255);
+		outline-color: rgba(255, 255 255, 1);
+	}
+ 
+	/* 横向虚线 */
+	.uni-cropper-dashed-h {
+		position: absolute;
+		top: 33.33333333%;
+		left: 0;
+ 
+		width: 100%;
+		height: 33.33333333%;
+ 
+		border-top: 1upx dashed rgba(255, 255, 255, 0.5);
+		border-bottom: 1upx dashed rgba(255, 255, 255, 0.5);
+	}
+ 
+	/* 纵向虚线 */
+	.uni-cropper-dashed-v {
+		position: absolute;
+		top: 0;
+		left: 33.33333333%;
+ 
+		width: 33.33333333%;
+		height: 100%;
+ 
+		border-right: 1upx dashed rgba(255, 255, 255, 0.5);
+		border-left: 1upx dashed rgba(255, 255, 255, 0.5);
+	}
+ 
+	/* 四个方向的线  为了之后的拖动事件*/
+	.uni-cropper-line-t {
+		position: absolute;
+		top: 0;
+		left: 0;
+ 
+		display: block;
+ 
+		width: 100%;
+		height: 3upx;
+ 
+		cursor: n-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-t::before {
+		position: absolute;
+		z-index: 11;
+		top: 50%;
+		right: 0upx;
+		bottom: 0;
+ 
+		width: 100%;
+		height: 41upx;
+ 
+		content: "";
+		-webkit-transform: translate3d(0, -50%, 0);
+		transform: translate3d(0, -50%, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-line-r {
+		position: absolute;
+		top: 0;
+		right: 0upx;
+ 
+		display: block;
+ 
+		width: 3upx;
+		height: 100%;
+ 
+		cursor: e-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-r::before {
+		position: absolute;
+		z-index: 11;
+		top: 0;
+		bottom: 0;
+		left: 50%;
+ 
+		width: 41upx;
+		height: 100%;
+ 
+		content: "";
+		-webkit-transform: translate3d(-50%, 0, 0);
+		transform: translate3d(-50%, 0, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-line-b {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+ 
+		display: block;
+ 
+		width: 100%;
+		height: 3upx;
+ 
+		cursor: s-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-b::before {
+		position: absolute;
+		z-index: 11;
+		top: 50%;
+		right: 0upx;
+		bottom: 0;
+ 
+		width: 100%;
+		height: 41upx;
+ 
+		content: "";
+		-webkit-transform: translate3d(0, -50%, 0);
+		transform: translate3d(0, -50%, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-line-l {
+		position: absolute;
+		top: 0;
+		left: 0;
+ 
+		display: block;
+ 
+		width: 3upx;
+		height: 100%;
+ 
+		cursor: w-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-l::before {
+		position: absolute;
+		z-index: 11;
+		top: 0;
+		bottom: 0;
+		left: 50%;
+ 
+		width: 41upx;
+		height: 100%;
+ 
+		content: "";
+		-webkit-transform: translate3d(-50%, 0, 0);
+		transform: translate3d(-50%, 0, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-point {
+		position: absolute;
+		z-index: 3;
+ 
+		width: 5upx;
+		height: 5upx;
+ 
+		opacity: 0.75;
+		background-color: rgb(145, 132, 132);
+	}
+ 
+	.point-t {
+		top: -3upx;
+		left: 50%;
+ 
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-tr {
+		top: -3upx;
+		left: 100%;
+ 
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-r {
+		top: 50%;
+		left: 100%;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-rb {
+		position: absolute;
+		z-index: 1112;
+		top: 100%;
+		left: 100%;
+ 
+		width: 30upx;
+		height: 30upx;
+		border-radius: 50%;
+ 
+		cursor: n-resize;
+		-webkit-transform: translate3d(-50%, -50%, 0);
+		transform: translate3d(-50%, -50%, 0);
+ 
+		opacity: 1;
+		background-color: rgb(231, 222, 222);
+		background-color: #509cff;
+	}
+ 
+	.point-b {
+		top: 100%;
+		left: 50%;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-bl {
+		top: 100%;
+		left: 0;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-l {
+		top: 50%;
+		left: 0;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-lt {
+		top: 0;
+		left: 0;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	/* 裁剪框预览内容 */
+	.uni-cropper-viewer {
+		position: relative;
+ 
+		overflow: hidden;
+ 
+		width: 100%;
+		height: 100%;
+	}
+ 
+	.uni-cropper-viewer image {
+		position: absolute;
+		z-index: 2;
+	}
+</style>

+ 110 - 0
components/ysxyView/ysxyView.vue

@@ -0,0 +1,110 @@
+<template>
+	<view class="ysviewContent">
+		<view v-if="yuyan==0">
+			<view class="contentColumnC" style="padding-top: 20rpx;">
+				<text class="textfontB2" style="text-align: center;">用户协议及隐私政策</text>
+			</view>
+			<view style="margin-top: 20rpx;padding: 16rpx;">
+				<text>您在使用我们的服务时,我们可能会收集和使用您的相关信息。我们希望通过本</text>
+				<text class="ynszcdi" @click="btSelect(2)">《隐私政策》</text>
+				<text>向您说明,在使用我们的服务时,我们如何收集、使用、储存和分享这些信息,以及我们为您提供的访问、更新、控制和保护这些信息的方式。本</text>
+				<text class="ynszcdi" @click="btSelect(2)">《隐私政策》</text>
+				<text>,希望您仔细阅读,充分理解协议中的内容后再点击同意。</text>
+			</view>
+			<view class="contentInRowS" style="width: 90%;margin-left: 5%;margin-top: 20rpx;padding-bottom:20rpx;">
+				<text class="disagrBt" style="font-size: 24rpx;" @click="qiehuanyuy(1)">Ngôn ngữ/语言</text>
+				<text class="disagrBt" @click="btSelect(0)">不同意</text>
+				<text class="agrBt" @click="btSelect(1)">同意</text>
+			</view>
+		</view>
+		<view v-if="yuyan==1">
+			<view class="contentColumnC" style="padding-top: 20rpx;">
+				<text class="textfontB2" style="text-align: center;">Thỏa thuận người dùng và Chính sách bảo mật</text>
+			</view>
+			<view style="margin-top: 20rpx;padding: 16rpx;">
+				<text>Chúng tôi có thể thu thập và sử dụng thông tin về bạn khi bạn sử dụng Dịch vụ của chúng tôi. Chúng tôi hy vọng thông qua Ben</text>
+				<text class="ynszcdi" @click="btSelect(2)">"Chính sách bảo mật"</text>
+				<text>Giải thích cho bạn cách chúng tôi thu thập, sử dụng, lưu trữ và chia sẻ thông tin này khi sử dụng Dịch vụ của chúng tôi và cách chúng tôi cung cấp cho bạn quyền truy cập, cập nhật, kiểm soát và bảo vệ thông tin này. Ben</text>
+				<text class="ynszcdi" @click="btSelect(2)">"Chính sách bảo mật"</text>
+				<text>,Hy vọng bạn đọc kỹ, hiểu đầy đủ nội dung trong thỏa thuận trước khi nhấp vào đồng ý.</text>
+			</view>
+			<view class="contentInRowS" style="width: 90%;margin-left: 5%;margin-top: 20rpx;padding-bottom:20rpx;">
+				<text class="disagrBt" style="font-size: 24rpx;" @click="qiehuanyuy(0)">Ngôn ngữ/语言</text>
+				<text class="disagrBt" @click="btSelect(0)">Không đồng ý</text>
+				<text class="agrBt" @click="btSelect(1)">Đồng ý</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"ysxyView",
+		data() {
+			return {
+				yuyan:1
+			};
+		},
+		methods:{
+			btSelect(state){
+				this.$emit('EagrResult',state);
+			},
+			qiehuanyuy(s){
+				this.yuyan=s;
+				var code='';
+				if(this.yuyan==1){
+					code='yuenan';
+				}
+				else{
+					code='zh-Hans';
+				}
+				if (plus.os.name.toLowerCase() === 'android') {
+					uni.setStorageSync('language',code);
+					uni.setLocale(code);
+				}
+				else{
+					uni.setStorageSync('language',code);
+					uni.setLocale(code);
+					this.$i18n.locale = code;
+				}
+				
+			}
+			
+		},
+	}
+</script>
+
+<style>
+	.ysviewContent{
+		width: 84%;
+		margin-left: 8%;
+		background-color: white;
+		border-radius: 10rpx;
+	}
+	
+	.ynszcdi{
+		color: blue;
+		text-decoration:underline;
+	}
+	
+	.disagrBt{
+		background-color: white;
+		border: 2rpx solid lightgray;
+		padding-left: 12rpx;
+		padding-right: 12rpx;
+		line-height: 60rpx;
+		font-size: 26rpx;
+		border-radius: 8rpx;
+	}
+	.agrBt{
+		background-color: #00A6FF;
+		border: 2rpx solid #00A6FF;
+		padding-left: 12rpx;
+		padding-right: 12rpx;
+		line-height: 60rpx;
+		font-size: 26rpx;
+		border-radius: 8rpx;
+		color: white;
+	}
+
+</style>

+ 28 - 0
config/index.config.js

@@ -0,0 +1,28 @@
+const CONFIG = {
+	// 开发环境配置
+	development: {
+		assetsPath: '/static', // 静态资源路径
+		qqMapKey: '',
+		// baseUrl: 'https://api.amazeway.com.cn',
+		// hostUrl: 'https://api.amazeway.com.cn', // H5地址(前端运行地址)
+		baseUrl: 'https://api.cityexpress168.com.vn', // 后台接口请求地址https://backend.cityexpress168.com.vn
+		hostUrl: 'https://api.cityexpress168.com.vn', // H5地址(前端运行地址)https://backend.cityexpress168.com.vn
+		websocketUrl: '', // websocket服务端地址
+		weixinAppId: '', // 微信公众号appid
+		storeId: 0 //
+	},
+	// 生产环境配置
+	production: {
+		qqMapKey: '',
+		assetsPath: '/static', // 静态资源路径
+		// baseUrl: ' http://192.168.1.7:8080',
+		// hostUrl: ' http://192.168.1.7:8080', // H5地址(前端运行地址)
+		// baseUrl: 'https://api.cityexpress168.com.vn', // 后台接口请求地址
+		// hostUrl: 'https://api.cityexpress168.com.vn', // H5地址(前端运行地址)
+		websocketUrl: '', // websocket服务端地址
+		weixinAppId: '', // 微信公众号appid
+		storeId: 0 //
+	}
+
+};
+export default CONFIG[process.env.NODE_ENV];

BIN
cteuser.keystore


+ 5 - 0
cteuser.txt

@@ -0,0 +1,5 @@
+证书指纹:
+         MD5:  04:E0:4F:A4:14:FA:2B:FB:15:6D:9B:C7:21:50:F5:D4
+         SHA1: 4A:3B:F5:BB:36:ED:94:EE:B9:82:C9:6B:DB:CB:46:F3:F5:F6:73:BC
+         SHA256: 0E:E5:E8:AD:F5:DA:FB:52:EB:85:F6:E0:EA:B1:B1:77:9A:52:EF:7C:D1:01:12:D1:3D:CB:BD:DD:64:60:72:9E
+签名算法名称: SHA256withRSA

+ 59 - 0
debug/GenerateTestUserSig.js

@@ -0,0 +1,59 @@
+import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js';
+/**
+ * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
+ *
+ * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId,
+ * 它是腾讯云用于区分客户的唯一标识。
+ */
+
+const SDKAPPID = 20008901 ;
+/**
+ * 签名过期时间,建议不要设置的过短
+ * <p>
+ * 时间单位:秒
+ * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
+ */
+
+const EXPIRETIME = 604800;
+/**
+ * 计算签名用的加密密钥,获取步骤如下:
+ *
+ * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个,
+ * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
+ * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
+ *
+ * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
+ * 文档:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+
+const SECRETKEY = 'cc6b11f3614638fc6592e5bb9c39b1aaa642fc74964a1fa5278550d3d0adb9c5';
+/*
+ * Module:   GenerateTestUserSig
+ *
+ * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
+ *           其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
+ *
+ * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
+ *
+ *            本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
+ *            这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
+ *            一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
+ *
+ *            正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
+ *            由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
+ *
+ * Reference:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+
+function genTestUserSig(userID) {
+  const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME);
+  const userSig = generator.genTestUserSig(userID);
+  return {
+    sdkAppId: SDKAPPID,
+    userSig,
+  };
+}
+
+module.exports = {
+  genTestUserSig,
+};

File diff suppressed because it is too large
+ 1217 - 0
debug/lib-generate-test-usersig-es.min.js


+ 254 - 0
hybrid/html/maps/css/index.css

@@ -0,0 +1,254 @@
+* {
+	padding: 0;
+	margin: 0;
+}
+
+html,
+body {
+	width: 100%;
+	height: 100%;
+	overflow: hidden;
+	position: relative;
+}
+
+#map {
+	position: relative;
+	width: 100%;
+	height: 100%;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
+
+.loadinggif {
+	width: 50px;
+	height: 50px;
+	position: fixed;
+	left: 50%;
+	bottom: 50%;
+	margin-left: -25px;
+	margin-top: -25px;
+	z-index: 99;
+}
+
+.gm-style-mtc {
+	display: none;
+}
+
+.gmnoprint {
+	display: none !important;
+}
+
+.gmnoprint.gm-bundled-control.gm-bundled-control-on-bottom {
+	display: none;
+}
+
+.gm-control-active.gm-fullscreen-control {
+	display: none;
+}
+
+[class^="https://maps.google.com/maps"] {
+	display: none !important;
+}
+
+.tabs {
+	width: 60%;
+	height: 40px;
+	margin-left: 20%;
+	position: fixed;
+	left: 0;
+	top: 20px;
+	display: flex;
+	align-items: center;
+	justify-content: space-around;
+	z-index: 100;
+
+}
+
+.tabs div {
+	width: 100px;
+	height: 40px;
+	font-size: 18px;
+	font-weight: 700;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border-radius: 20px;
+	position: relative;
+	color: #666;
+}
+
+.tabs .active span {
+	position: relative;
+	font-size: 20px;
+	font-weight: bold;
+	color: #333;
+}
+
+.tabs .active span ::after {
+	content: '';
+	width: 20px;
+	height: 5px;
+	background-color: saddlebrown;
+	position: absolute;
+	left: 20px;
+	bottom: 10px;
+
+}
+
+.tabs-left {}
+
+.tabs-right {}
+
+
+
+/* 动画 */
+.loader {
+	position: fixed;
+	z-index: 99;
+	border: 8px solid #f3f3f3;
+	border-top: 8px solid #ea4335;
+	border-radius: 50%;
+	width: 45px;
+	height: 45px;
+	animation: spin 2s linear infinite;
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	margin-left: -30px;
+	margin-top: -30px;
+	transform: translate(-50%, -50%);
+
+}
+
+@keyframes spin {
+	0% {
+		transform: rotate(0deg);
+	}
+
+	100% {
+		transform: rotate(360deg);
+	}
+}
+
+/* end */
+/* 地图信息窗口样式 */
+.textoverflow {
+	width: 100%;
+
+	line-height: 23px;
+}
+
+.imgs {
+	width: 100%;
+	height: auto;
+	max-height: 150px;
+}
+
+.infoWindow-title {
+	width: 100%;
+
+	font-size: 16px;
+	font-weight: 600;
+	line-height: 22px;
+
+}
+
+/* end */
+#slider {
+	width: 96%;
+	margin-left: 2%;
+
+	background-color: #fff;
+	position: fixed;
+	left: 0;
+	bottom: 10px;
+	z-index: 100;
+	border-radius: 6px;
+	padding: 20px 15px;
+	box-sizing: border-box;
+
+}
+
+.slider-title {
+	width: 100%;
+	font-size: 15px;
+	font-weight: 500;
+
+
+}
+
+.slider-box {
+	width: 100%;
+	padding: 0 10p x 0 0;
+	box-sizing: border-box;
+	margin-top: 20px;
+	display: flex;
+	align-items: center;
+
+}
+
+.slider-btn {
+	width: 100%;
+	height: 40px;
+	color: #fff;
+	background-color: darkcyan;
+	font-size: 15px;
+	font-weight: 500;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border-radius: 5px;
+	margin-top: 30px;
+}
+
+.custom-button {
+	width: 26px;
+	color: #fff;
+	font-size: 12px;
+	font-weight: 500;
+	line-height: 25px;
+	text-align: center;
+	background-color: darkcyan;
+	border-radius: 100px;
+}
+
+#search-box {
+	height: 30px;
+	width: 93%;
+	position: fixed;
+	padding: 5px;
+	font-size: 16px;
+	border-radius: 4px;
+	border: 1px solid #ccc;
+	box-shadow: 0px 1px 3px #ddd;
+	left: 2%;
+	top: 80px;
+	font-size: 12px;
+}
+
+/* 定位图标 */
+.pos {
+	width: 36px;
+	height: 36px;
+	position: fixed;
+	right: 10px;
+	bottom: 250px;
+	z-index: 100;
+	padding: 6px;
+	box-sizing: border-box;
+	border-radius: 5px;
+	background-color: #fff;
+}
+.citys {
+	width: 96%;
+	position: fixed;
+	font-size: 16px;
+	left: 2%;
+	top: 130px;
+	font-size: 12px;
+	background-color: #fff;
+	padding: 5px 10px;
+	box-sizing: border-box;
+	border-radius: 5px;
+}

+ 1 - 0
hybrid/html/maps/css/modules/code.css

@@ -0,0 +1 @@
+html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:13px}.layui-code-title{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-title>.layui-code-about{position:absolute;right:10px;top:0;color:#b7b7b7}.layui-code-about>a{padding-left:10px}.layui-code-view>.layui-code-ol,.layui-code-view>.layui-code-ul{position:relative;overflow:auto}.layui-code-view>.layui-code-ol>li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view>.layui-code-ol>li:first-child,.layui-code-view>.layui-code-ul>li:first-child{padding-top:10px}.layui-code-view>.layui-code-ol>li:last-child,.layui-code-view>.layui-code-ul>li:last-child{padding-bottom:10px}.layui-code-view>.layui-code-ul>li{position:relative;line-height:20px;padding:0 10px;list-style-type:none;*list-style-type:none;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-dark{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-dark>.layui-code-title{border-bottom:none}.layui-code-dark>.layui-code-ol>li,.layui-code-dark>.layui-code-ul>li{background-color:#3f3f3f;border-left:none}.layui-code-dark>.layui-code-ul>li{margin-left:6px}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}

File diff suppressed because it is too large
+ 0 - 0
hybrid/html/maps/css/modules/laydate/default/laydate.css


BIN
hybrid/html/maps/css/modules/layer/default/icon-ext.png


BIN
hybrid/html/maps/css/modules/layer/default/icon.png


File diff suppressed because it is too large
+ 0 - 0
hybrid/html/maps/css/modules/layer/default/layer.css


BIN
hybrid/html/maps/css/modules/layer/default/loading-0.gif


BIN
hybrid/html/maps/css/modules/layer/default/loading-1.gif


BIN
hybrid/html/maps/css/modules/layer/default/loading-2.gif


+ 0 - 0
hybrid/html/maps/css/slider.css


File diff suppressed because it is too large
+ 0 - 0
hybrid/html/maps/css/vant.css


BIN
hybrid/html/maps/img/1.png


BIN
hybrid/html/maps/img/loading2.gif


BIN
hybrid/html/maps/img/positioning.png


File diff suppressed because it is too large
+ 5 - 0
hybrid/html/maps/js/lib/VConsole.js


+ 1104 - 0
hybrid/html/maps/js/lib/city.js

@@ -0,0 +1,1104 @@
+var cityArr = [
+	[
+		[113.631683, 34.766461],
+		[113.631493, 34.766214],
+		[113.631206, 34.765443],
+		[113.631135, 34.764565],
+		[113.629877, 34.760791],
+		[113.629858, 34.760548],
+		[113.628865, 34.757271],
+		[113.628885, 34.757173],
+		[113.628207, 34.75494],
+		[113.628336, 34.75464],
+		[113.628877, 34.754559],
+		[113.632646, 34.754195],
+		[113.632646, 34.748388],
+		[113.629856, 34.748396],
+		[113.629648, 34.748177],
+		[113.628111, 34.748233],
+		[113.628168, 34.747357],
+		[113.628111, 34.747295],
+		[113.628128, 34.744636],
+		[113.628075, 34.742891],
+		[113.628092, 34.739063],
+		[113.627832, 34.738785],
+		[113.626073, 34.737594],
+		[113.625458, 34.737044],
+		[113.625288, 34.736645],
+		[113.62499, 34.735003],
+		[113.624114, 34.732545],
+		[113.623589, 34.730981],
+		[113.622339, 34.728215],
+		[113.622179, 34.727586],
+		[113.621745, 34.722947],
+		[113.621609, 34.720152],
+		[113.62152, 34.719806],
+		[113.621315, 34.719665],
+		[113.620744, 34.719637],
+		[113.620682, 34.719439],
+		[113.62069, 34.716988],
+		[113.620828, 34.711984],
+		[113.62074, 34.712305],
+		[113.616795, 34.712387],
+		[113.61575, 34.710532],
+		[113.616838, 34.710591],
+		[113.617074, 34.710099],
+		[113.615588, 34.710021],
+		[113.61537, 34.709961],
+		[113.614199, 34.709926],
+		[113.613063, 34.709775],
+		[113.612829, 34.708557],
+		[113.613671, 34.707152],
+		[113.610734, 34.706881],
+		[113.609829, 34.706658],
+		[113.608224, 34.706452],
+		[113.607389, 34.704688],
+		[113.606157, 34.704815],
+		[113.60162, 34.704915],
+		[113.601132, 34.704976],
+		[113.600857, 34.705118],
+		[113.600664, 34.705563],
+		[113.600552, 34.706605],
+		[113.600404, 34.706974],
+		[113.600084, 34.707259],
+		[113.599676, 34.70741],
+		[113.59912, 34.707459],
+		[113.594411, 34.707332],
+		[113.592235, 34.707334],
+		[113.589581, 34.707502],
+		[113.589114, 34.707553],
+		[113.588264, 34.707763],
+		[113.587734, 34.708214],
+		[113.587553, 34.708811],
+		[113.587353, 34.71019],
+		[113.587024, 34.710641],
+		[113.586436, 34.711197],
+		[113.586262, 34.711515],
+		[113.586209, 34.711917],
+		[113.5862, 34.713282],
+		[113.585854, 34.713561],
+		[113.58509, 34.713438],
+		[113.584312, 34.713446],
+		[113.583921, 34.713533],
+		[113.580514, 34.714686],
+		[113.579866, 34.714859],
+		[113.5716, 34.716309],
+		[113.570214, 34.716446],
+		[113.568863, 34.716334],
+		[113.565763, 34.715707],
+		[113.565208, 34.715922],
+		[113.564091, 34.717555],
+		[113.563633, 34.717657],
+		[113.563563, 34.717442],
+		[113.563614, 34.716769],
+		[113.562583, 34.712566],
+		[113.562272, 34.712034],
+		[113.561831, 34.711711],
+		[113.5606, 34.711307],
+		[113.557571, 34.707848],
+		[113.557216, 34.707142],
+		[113.556843, 34.705519],
+		[113.556445, 34.704692],
+		[113.556082, 34.704351],
+		[113.554056, 34.702875],
+		[113.553667, 34.702537],
+		[113.553373, 34.702123],
+		[113.552627, 34.70072],
+		[113.552385, 34.70043],
+		[113.551798, 34.700271],
+		[113.551502, 34.70037],
+		[113.550033, 34.701585],
+		[113.549522, 34.70173],
+		[113.549279, 34.701605],
+		[113.549166, 34.701327],
+		[113.549305, 34.699319],
+		[113.549131, 34.699034],
+		[113.546587, 34.698547],
+		[113.542313, 34.70158],
+		[113.541934, 34.703698],
+		[113.54227, 34.705968],
+		[113.542349, 34.708364],
+		[113.541094, 34.708989],
+		[113.537366, 34.709618],
+		[113.534529, 34.714445],
+		[113.533889, 34.717165],
+		[113.531987, 34.717765],
+		[113.526763, 34.717931],
+		[113.525389, 34.718905],
+		[113.52538, 34.719773],
+		[113.524212, 34.720329],
+		[113.522793, 34.720019],
+		[113.519776, 34.718507],
+		[113.517597, 34.717975],
+		[113.515106, 34.715288],
+		[113.512894, 34.712832],
+		[113.511164, 34.710214],
+		[113.50978, 34.707642],
+		[113.508949, 34.704785],
+		[113.507911, 34.700316],
+		[113.507563, 34.696483],
+		[113.506942, 34.692996],
+		[113.50638, 34.689333],
+		[113.507131, 34.687209],
+		[113.507892, 34.685382],
+		[113.508723, 34.682396],
+		[113.508651, 34.68085],
+		[113.507761, 34.678853],
+		[113.506647, 34.676453],
+		[113.506162, 34.674679],
+		[113.505814, 34.672964],
+		[113.506646, 34.671122],
+		[113.507613, 34.669575],
+		[113.507683, 34.667804],
+		[113.506151, 34.665342],
+		[113.506635, 34.665234],
+		[113.509541, 34.663727],
+		[113.511746, 34.661948],
+		[113.513605, 34.660168],
+		[113.514226, 34.658847],
+		[113.514226, 34.65736],
+		[113.51388, 34.65421],
+		[113.514572, 34.652147],
+		[113.514285, 34.650206],
+		[113.512851, 34.649294],
+		[113.511112, 34.649127],
+		[113.507871, 34.649022],
+		[113.504688, 34.64806],
+		[113.504422, 34.64737],
+		[113.506072, 34.646448],
+		[113.510083, 34.645579],
+		[113.513326, 34.644763],
+		[113.516015, 34.644302],
+		[113.517053, 34.643952],
+		[113.516913, 34.64298],
+		[113.516015, 34.641378],
+		[113.515185, 34.64058],
+		[113.514562, 34.639097],
+		[113.514908, 34.637778],
+		[113.515867, 34.636512],
+		[113.517042, 34.635538],
+		[113.518626, 34.634792],
+		[113.520908, 34.634547],
+		[113.523261, 34.634542],
+		[113.526642, 34.634239],
+		[113.528847, 34.634401],
+		[113.527603, 34.632296],
+		[113.526219, 34.630694],
+		[113.525733, 34.629092],
+		[113.525396, 34.628179],
+		[113.526771, 34.627198],
+		[113.527947, 34.626855],
+		[113.530221, 34.626677],
+		[113.53208, 34.626325],
+		[113.534572, 34.626026],
+		[113.536777, 34.624991],
+		[113.538647, 34.622806],
+		[113.53933, 34.621772],
+		[113.539397, 34.620969],
+		[113.539122, 34.619777],
+		[113.538836, 34.618339],
+		[113.538359, 34.617089],
+		[113.538419, 34.61548],
+		[113.539251, 34.614848],
+		[113.541327, 34.613807],
+		[113.542917, 34.613809],
+		[113.544086, 34.614254],
+		[113.545195, 34.61517],
+		[113.546639, 34.61677],
+		[113.547885, 34.618198],
+		[113.549002, 34.621576],
+		[113.549279, 34.623632],
+		[113.549627, 34.625523],
+		[113.550319, 34.627749],
+		[113.551703, 34.629866],
+		[113.55302, 34.632036],
+		[113.554333, 34.633979],
+		[113.556273, 34.635283],
+		[113.557996, 34.635571],
+		[113.559865, 34.635841],
+		[113.561182, 34.635668],
+		[113.563114, 34.633833],
+		[113.564014, 34.632404],
+		[113.564835, 34.630969],
+		[113.567112, 34.628725],
+		[113.568837, 34.627406],
+		[113.570629, 34.625688],
+		[113.571391, 34.624255],
+		[113.572292, 34.622015],
+		[113.572707, 34.619617],
+		[113.572629, 34.617723],
+		[113.572006, 34.616241],
+		[113.570619, 34.614638],
+		[113.570064, 34.612921],
+		[113.570125, 34.610916],
+		[113.57172, 34.609311],
+		[113.573442, 34.607189],
+		[113.574333, 34.60627],
+		[113.575235, 34.605582],
+		[113.576969, 34.60512],
+		[113.57911, 34.604997],
+		[113.579941, 34.604536],
+		[113.582012, 34.603506],
+		[113.584021, 34.602761],
+		[113.586224, 34.603441],
+		[113.588513, 34.603834],
+		[113.590039, 34.603313],
+		[113.592942, 34.60251],
+		[113.595017, 34.602395],
+		[113.596196, 34.602791],
+		[113.597645, 34.603759],
+		[113.59917, 34.604047],
+		[113.601036, 34.604042],
+		[113.601799, 34.603121],
+		[113.601938, 34.60192],
+		[113.601792, 34.600659],
+		[113.602007, 34.600034],
+		[113.603179, 34.600547],
+		[113.604289, 34.601519],
+		[113.60547, 34.602663],
+		[113.606443, 34.603233],
+		[113.607822, 34.604376],
+		[113.608247, 34.606036],
+		[113.607553, 34.607186],
+		[113.605895, 34.607869],
+		[113.600499, 34.608625],
+		[113.599258, 34.609718],
+		[113.598981, 34.611082],
+		[113.599535, 34.612581],
+		[113.600647, 34.613771],
+		[113.601966, 34.615546],
+		[113.602382, 34.617089],
+		[113.602105, 34.618588],
+		[113.601143, 34.619783],
+		[113.600516, 34.623046],
+		[113.601637, 34.625391],
+		[113.603432, 34.627631],
+		[113.606142, 34.629395],
+		[113.607875, 34.629443],
+		[113.609405, 34.629043],
+		[113.611338, 34.627275],
+		[113.611956, 34.626186],
+		[113.61501, 34.625493],
+		[113.617015, 34.625771],
+		[113.618883, 34.626059],
+		[113.62062, 34.626915],
+		[113.621663, 34.627831],
+		[113.622706, 34.629496],
+		[113.622914, 34.631666],
+		[113.622854, 34.634985],
+		[113.622792, 34.636764],
+		[113.622862, 34.638194],
+		[113.623696, 34.638481],
+		[113.625085, 34.638762],
+		[113.626259, 34.638595],
+		[113.627927, 34.638299],
+		[113.632356, 34.637784],
+		[113.634094, 34.637839],
+		[113.636526, 34.638822],
+		[113.638404, 34.639788],
+		[113.640759, 34.641106],
+		[113.642358, 34.641218],
+		[113.644305, 34.641213],
+		[113.646383, 34.641096],
+		[113.648947, 34.640758],
+		[113.650894, 34.640189],
+		[113.652285, 34.639386],
+		[113.653666, 34.639042],
+		[113.655189, 34.639093],
+		[113.657206, 34.639321],
+		[113.658945, 34.639836],
+		[113.660544, 34.640699],
+		[113.662832, 34.642475],
+		[113.664057, 34.643516],
+		[113.663214, 34.645447],
+		[113.660484, 34.6463],
+		[113.662363, 34.648941],
+		[113.667145, 34.653972],
+		[113.66625, 34.656271],
+		[113.661589, 34.657275],
+		[113.655451, 34.659506],
+		[113.653044, 34.661863],
+		[113.653156, 34.665337],
+		[113.65539, 34.667172],
+		[113.65953, 34.668144],
+		[113.661007, 34.671446],
+		[113.664608, 34.678014],
+		[113.668392, 34.68207],
+		[113.670922, 34.686777],
+		[113.67507, 34.687892],
+		[113.675802, 34.69671],
+		[113.675229, 34.699284],
+		[113.673349, 34.699778],
+		[113.670541, 34.70049],
+		[113.669586, 34.702019],
+		[113.669672, 34.704723],
+		[113.673908, 34.708573],
+		[113.676411, 34.710117],
+		[113.676552, 34.714616],
+		[113.674005, 34.720109],
+		[113.670283, 34.726879],
+		[113.665971, 34.734431],
+		[113.665257, 34.736635],
+		[113.665119, 34.736848],
+		[113.667734, 34.73874],
+		[113.66771, 34.739233],
+		[113.668032, 34.739326],
+		[113.667949, 34.740447],
+		[113.667388, 34.740392],
+		[113.666617, 34.742058],
+		[113.666391, 34.742141],
+		[113.665493, 34.741709],
+		[113.66452, 34.741461],
+		[113.664093, 34.74255],
+		[113.663963, 34.743643],
+		[113.664694, 34.743821],
+		[113.66552, 34.744307],
+		[113.666452, 34.744554],
+		[113.666512, 34.744653],
+		[113.666529, 34.74674],
+		[113.66672, 34.747736],
+		[113.666903, 34.748032],
+		[113.668094, 34.748502],
+		[113.669445, 34.748692],
+		[113.669526, 34.751476],
+		[113.669481, 34.751576],
+		[113.668111, 34.751802],
+		[113.667025, 34.752287],
+		[113.66673, 34.752497],
+		[113.666617, 34.752799],
+		[113.666693, 34.753586],
+		[113.666904, 34.754427],
+		[113.666827, 34.755312],
+		[113.667001, 34.75608],
+		[113.665627, 34.756373],
+		[113.665321, 34.756797],
+		[113.662272, 34.757863],
+		[113.66026, 34.758383],
+		[113.660217, 34.759303],
+		[113.661169, 34.759344],
+		[113.661062, 34.760425],
+		[113.661029, 34.761295],
+		[113.661429, 34.761127],
+		[113.66205, 34.760999],
+		[113.662684, 34.758756],
+		[113.664283, 34.758315],
+		[113.664436, 34.759231],
+		[113.665233, 34.760768],
+		[113.665271, 34.763483],
+		[113.664553, 34.763546],
+		[113.662971, 34.763814],
+		[113.662954, 34.764218],
+		[113.659651, 34.764176],
+		[113.658165, 34.764174],
+		[113.657409, 34.764023],
+		[113.656687, 34.763579],
+		[113.655938, 34.76333],
+		[113.655081, 34.762911],
+		[113.654213, 34.762128],
+		[113.652755, 34.760014],
+		[113.652531, 34.75986],
+		[113.651638, 34.758318],
+		[113.645064, 34.759777],
+		[113.644274, 34.759999],
+		[113.643692, 34.760265],
+		[113.643301, 34.76061],
+		[113.63926, 34.766352],
+		[113.637755, 34.765835],
+		[113.637115, 34.765796],
+		[113.63249, 34.766386],
+		[113.631683, 34.766461]
+	],
+	[
+		[113.845063, 34.746141],
+		[113.842337, 34.746668],
+		[113.838943, 34.748032],
+		[113.835423, 34.751599],
+		[113.833044, 34.756248],
+		[113.830603, 34.757305],
+		[113.8222, 34.758942],
+		[113.818954, 34.759705],
+		[113.816583, 34.761645],
+		[113.817145, 34.765164],
+		[113.817034, 34.768043],
+		[113.813795, 34.768866],
+		[113.807788, 34.768331],
+		[113.800817, 34.766566],
+		[113.793379, 34.765379],
+		[113.790485, 34.763199],
+		[113.7889, 34.756143],
+		[113.786447, 34.751614],
+		[113.78189, 34.751265],
+		[113.779413, 34.753264],
+		[113.779239, 34.756374],
+		[113.774569, 34.758819],
+		[113.765151, 34.760605],
+		[113.761701, 34.760314],
+		[113.758829, 34.756933],
+		[113.75844, 34.756157],
+		[113.757469, 34.755301],
+		[113.757053, 34.755041],
+		[113.756635, 34.754963],
+		[113.755057, 34.754956],
+		[113.753417, 34.754812],
+		[113.752081, 34.754531],
+		[113.751613, 34.754326],
+		[113.749608, 34.753042],
+		[113.745545, 34.750775],
+		[113.744703, 34.750233],
+		[113.743871, 34.749621],
+		[113.737316, 34.744604],
+		[113.736526, 34.743906],
+		[113.736204, 34.743438],
+		[113.736003, 34.742902],
+		[113.735527, 34.741364],
+		[113.735265, 34.740858],
+		[113.734249, 34.739082],
+		[113.734014, 34.73854],
+		[113.733598, 34.737067],
+		[113.733354, 34.736777],
+		[113.732538, 34.736244],
+		[113.730437, 34.735149],
+		[113.729655, 34.734874],
+		[113.728761, 34.734842],
+		[113.727901, 34.735001],
+		[113.727093, 34.735363],
+		[113.726311, 34.735342],
+		[113.726348, 34.737886],
+		[113.723068, 34.737882],
+		[113.720638, 34.737832],
+		[113.720708, 34.739321],
+		[113.712267, 34.738883],
+		[113.712307, 34.735548],
+		[113.710463, 34.735163],
+		[113.710441, 34.737173],
+		[113.71036, 34.737542],
+		[113.710302, 34.738782],
+		[113.705473, 34.738531],
+		[113.705351, 34.737729],
+		[113.704123, 34.737682],
+		[113.703936, 34.739238],
+		[113.703925, 34.740128],
+		[113.703995, 34.742198],
+		[113.705752, 34.742455],
+		[113.706429, 34.742871],
+		[113.709098, 34.742766],
+		[113.710421, 34.746894],
+		[113.706056, 34.746933],
+		[113.703623, 34.746917],
+		[113.70298, 34.755799],
+		[113.70285, 34.756537],
+		[113.702545, 34.756967],
+		[113.702094, 34.757109],
+		[113.700041, 34.756983],
+		[113.69973, 34.756782],
+		[113.697573, 34.757123],
+		[113.697381, 34.755422],
+		[113.69437, 34.755397],
+		[113.694277, 34.755329],
+		[113.693282, 34.755377],
+		[113.691451, 34.755296],
+		[113.69146, 34.754044],
+		[113.690269, 34.753971],
+		[113.683531, 34.75567],
+		[113.681748, 34.756064],
+		[113.680052, 34.756388],
+		[113.677296, 34.756878],
+		[113.674209, 34.757375],
+		[113.67393, 34.757401],
+		[113.67339, 34.757211],
+		[113.671131, 34.755444],
+		[113.670887, 34.755305],
+		[113.67053, 34.755417],
+		[113.670373, 34.755836],
+		[113.670504, 34.756124],
+		[113.671296, 34.75707],
+		[113.671427, 34.757386],
+		[113.671366, 34.757688],
+		[113.671131, 34.757923],
+		[113.670695, 34.757805],
+		[113.669633, 34.75699],
+		[113.669095, 34.756881],
+		[113.668695, 34.75702],
+		[113.667591, 34.757672],
+		[113.66721, 34.757738],
+		[113.667234, 34.757409],
+		[113.667852, 34.756796],
+		[113.667939, 34.756543],
+		[113.667678, 34.756282],
+		[113.667001, 34.756081],
+		[113.666827, 34.755313],
+		[113.666905, 34.754427],
+		[113.666692, 34.753586],
+		[113.666618, 34.7528],
+		[113.666731, 34.752496],
+		[113.667025, 34.752287],
+		[113.668111, 34.751803],
+		[113.669481, 34.751575],
+		[113.669526, 34.751476],
+		[113.669444, 34.748691],
+		[113.668094, 34.748503],
+		[113.666903, 34.748032],
+		[113.66672, 34.747735],
+		[113.666529, 34.74674],
+		[113.666511, 34.744652],
+		[113.66645, 34.744554],
+		[113.665521, 34.744307],
+		[113.664693, 34.743821],
+		[113.663964, 34.743643],
+		[113.664092, 34.74255],
+		[113.664519, 34.741461],
+		[113.665494, 34.74171],
+		[113.666391, 34.742142],
+		[113.666616, 34.742059],
+		[113.667388, 34.740392],
+		[113.66795, 34.740447],
+		[113.668033, 34.739325],
+		[113.667711, 34.739234],
+		[113.667735, 34.73874],
+		[113.66512, 34.736849],
+		[113.665257, 34.736634],
+		[113.665971, 34.734431],
+		[113.670284, 34.726879],
+		[113.674004, 34.72011],
+		[113.676551, 34.714616],
+		[113.676412, 34.710118],
+		[113.673909, 34.708572],
+		[113.669672, 34.704725],
+		[113.669585, 34.702019],
+		[113.670541, 34.700491],
+		[113.673349, 34.699778],
+		[113.675228, 34.699284],
+		[113.675803, 34.69671],
+		[113.675071, 34.687892],
+		[113.670922, 34.686777],
+		[113.668392, 34.68207],
+		[113.664608, 34.678014],
+		[113.661008, 34.671447],
+		[113.659529, 34.668143],
+		[113.655391, 34.667172],
+		[113.653157, 34.665337],
+		[113.653044, 34.661864],
+		[113.655452, 34.659506],
+		[113.661589, 34.657275],
+		[113.66625, 34.656271],
+		[113.667147, 34.653973],
+		[113.662364, 34.648941],
+		[113.660485, 34.646299],
+		[113.663213, 34.645446],
+		[113.664058, 34.643516],
+		[113.664371, 34.643785],
+		[113.666241, 34.644473],
+		[113.667284, 34.644016],
+		[113.668457, 34.642759],
+		[113.669154, 34.641618],
+		[113.670266, 34.640521],
+		[113.672822, 34.638984],
+		[113.673996, 34.638124],
+		[113.675874, 34.635947],
+		[113.678787, 34.634057],
+		[113.681003, 34.633372],
+		[113.682665, 34.633427],
+		[113.684613, 34.634113],
+		[113.685658, 34.634857],
+		[113.687029, 34.636931],
+		[113.689735, 34.635289],
+		[113.692317, 34.637618],
+		[113.692779, 34.638422],
+		[113.692613, 34.641265],
+		[113.691338, 34.642137],
+		[113.691597, 34.643185],
+		[113.69257, 34.644066],
+		[113.692901, 34.644472],
+		[113.692596, 34.644779],
+		[113.691814, 34.645301],
+		[113.692222, 34.646028],
+		[113.693188, 34.645958],
+		[113.693952, 34.646012],
+		[113.694379, 34.646299],
+		[113.694466, 34.646798],
+		[113.694074, 34.647031],
+		[113.69358, 34.64719],
+		[113.693545, 34.647562],
+		[113.694022, 34.648117],
+		[113.695126, 34.648209],
+		[113.695938, 34.647784],
+		[113.696482, 34.64764],
+		[113.69697, 34.648086],
+		[113.696275, 34.649299],
+		[113.695944, 34.652111],
+		[113.698056, 34.651403],
+		[113.702569, 34.649678],
+		[113.704924, 34.649044],
+		[113.70888, 34.647896],
+		[113.711643, 34.646011],
+		[113.713093, 34.644348],
+		[113.714347, 34.644007],
+		[113.716284, 34.643774],
+		[113.717882, 34.643137],
+		[113.719264, 34.642224],
+		[113.720575, 34.641131],
+		[113.721063, 34.639358],
+		[113.722018, 34.637415],
+		[113.722774, 34.633806],
+		[113.723599, 34.630716],
+		[113.724076, 34.62911],
+		[113.724831, 34.627903],
+		[113.725804, 34.626934],
+		[113.730095, 34.625664],
+		[113.731693, 34.625549],
+		[113.735159, 34.625427],
+		[113.737303, 34.625371],
+		[113.740072, 34.625248],
+		[113.742295, 34.624666],
+		[113.743329, 34.624158],
+		[113.744084, 34.623297],
+		[113.745887, 34.622262],
+		[113.74969, 34.619849],
+		[113.751761, 34.61789],
+		[113.753759, 34.616169],
+		[113.754998, 34.614745],
+		[113.756655, 34.613482],
+		[113.757756, 34.613012],
+		[113.758945, 34.613528],
+		[113.7595, 34.614497],
+		[113.760332, 34.616332],
+		[113.760898, 34.618218],
+		[113.76139, 34.619534],
+		[113.761947, 34.620901],
+		[113.762918, 34.621988],
+		[113.764862, 34.622727],
+		[113.766109, 34.622896],
+		[113.768114, 34.622769],
+		[113.768876, 34.622311],
+		[113.770322, 34.621565],
+		[113.772039, 34.62064],
+		[113.773426, 34.620236],
+		[113.775845, 34.619827],
+		[113.777994, 34.6193],
+		[113.779927, 34.619012],
+		[113.781305, 34.618542],
+		[113.782483, 34.618378],
+		[113.7838, 34.618715],
+		[113.785315, 34.619334],
+		[113.786632, 34.619671],
+		[113.788088, 34.619558],
+		[113.789196, 34.619152],
+		[113.791543, 34.619877],
+		[113.792566, 34.621648],
+		[113.790723, 34.622975],
+		[113.790115, 34.625376],
+		[113.789995, 34.630702],
+		[113.78912, 34.635921],
+		[113.789623, 34.640326],
+		[113.790672, 34.643639],
+		[113.791728, 34.647066],
+		[113.793185, 34.649636],
+		[113.794648, 34.652036],
+		[113.796148, 34.653994],
+		[113.79841, 34.657669],
+		[113.802696, 34.65867],
+		[113.80636, 34.661676],
+		[113.809083, 34.662051],
+		[113.810303, 34.661425],
+		[113.81032, 34.649516],
+		[113.812379, 34.649309],
+		[113.813168, 34.649265],
+		[113.816207, 34.649019],
+		[113.816908, 34.650506],
+		[113.816986, 34.652507],
+		[113.816995, 34.655533],
+		[113.816945, 34.659896],
+		[113.816625, 34.663898],
+		[113.815456, 34.667334],
+		[113.815889, 34.671455],
+		[113.816453, 34.674317],
+		[113.817855, 34.677341],
+		[113.82181, 34.680471],
+		[113.825202, 34.682803],
+		[113.827843, 34.685764],
+		[113.829419, 34.687273],
+		[113.835819, 34.699649],
+		[113.835993, 34.701664],
+		[113.851294, 34.701122],
+		[113.859732, 34.701296],
+		[113.8623, 34.706665],
+		[113.863522, 34.714437],
+		[113.866104, 34.714406],
+		[113.866903, 34.72262],
+		[113.870743, 34.731437],
+		[113.867462, 34.731984],
+		[113.854431, 34.734131],
+		[113.85061, 34.736086],
+		[113.847, 34.740478],
+		[113.845496, 34.744942],
+		[113.845063, 34.746141]
+	],
+	[
+		[113.667, 34.756081],
+		[113.667677, 34.756281],
+		[113.66794, 34.756544],
+		[113.667853, 34.756796],
+		[113.667234, 34.75741],
+		[113.66721, 34.757738],
+		[113.66759, 34.757673],
+		[113.668695, 34.757021],
+		[113.669097, 34.75688],
+		[113.669633, 34.756991],
+		[113.670696, 34.757804],
+		[113.671131, 34.757923],
+		[113.671365, 34.757688],
+		[113.671428, 34.757386],
+		[113.671297, 34.757071],
+		[113.670504, 34.756124],
+		[113.670373, 34.755836],
+		[113.67053, 34.755418],
+		[113.670887, 34.755305],
+		[113.671131, 34.755444],
+		[113.673391, 34.757211],
+		[113.673929, 34.757401],
+		[113.67421, 34.757375],
+		[113.677297, 34.756877],
+		[113.680053, 34.756387],
+		[113.681748, 34.756064],
+		[113.68353, 34.75567],
+		[113.690268, 34.753971],
+		[113.69146, 34.754045],
+		[113.691452, 34.755296],
+		[113.693281, 34.755377],
+		[113.694276, 34.755329],
+		[113.69437, 34.755397],
+		[113.697381, 34.755423],
+		[113.697573, 34.757123],
+		[113.69973, 34.756781],
+		[113.700042, 34.756982],
+		[113.702092, 34.757108],
+		[113.702546, 34.756967],
+		[113.702851, 34.756536],
+		[113.70298, 34.755798],
+		[113.703623, 34.746918],
+		[113.706056, 34.746933],
+		[113.710421, 34.746894],
+		[113.709098, 34.742766],
+		[113.706428, 34.742871],
+		[113.705751, 34.742455],
+		[113.703995, 34.742198],
+		[113.703924, 34.740129],
+		[113.703938, 34.739238],
+		[113.704124, 34.737683],
+		[113.705352, 34.737729],
+		[113.705473, 34.738532],
+		[113.710302, 34.738782],
+		[113.71036, 34.737541],
+		[113.710442, 34.737173],
+		[113.710463, 34.735164],
+		[113.712308, 34.735547],
+		[113.712268, 34.738883],
+		[113.720707, 34.739321],
+		[113.720636, 34.737831],
+		[113.723066, 34.737883],
+		[113.72635, 34.737887],
+		[113.726311, 34.735343],
+		[113.727093, 34.735363],
+		[113.727901, 34.735001],
+		[113.728759, 34.734842],
+		[113.729655, 34.734874],
+		[113.730437, 34.735149],
+		[113.732539, 34.736245],
+		[113.733355, 34.736776],
+		[113.733597, 34.737067],
+		[113.734014, 34.738541],
+		[113.73425, 34.739083],
+		[113.735266, 34.740858],
+		[113.735526, 34.741365],
+		[113.736004, 34.742901],
+		[113.736206, 34.743437],
+		[113.736526, 34.743905],
+		[113.737316, 34.744604],
+		[113.74387, 34.749621],
+		[113.744702, 34.750234],
+		[113.745545, 34.750774],
+		[113.749608, 34.753043],
+		[113.751613, 34.754325],
+		[113.75208, 34.754532],
+		[113.753416, 34.754811],
+		[113.755056, 34.754956],
+		[113.756634, 34.754962],
+		[113.757051, 34.755041],
+		[113.757469, 34.7553],
+		[113.75844, 34.756158],
+		[113.758831, 34.756932],
+		[113.7617, 34.760314],
+		[113.765151, 34.760605],
+		[113.774569, 34.758818],
+		[113.779241, 34.756373],
+		[113.779411, 34.753263],
+		[113.781889, 34.751266],
+		[113.786445, 34.751613],
+		[113.7889, 34.756143],
+		[113.790485, 34.763199],
+		[113.793377, 34.76538],
+		[113.800816, 34.766566],
+		[113.807787, 34.768331],
+		[113.813795, 34.768865],
+		[113.817034, 34.768043],
+		[113.817144, 34.765165],
+		[113.816582, 34.761645],
+		[113.818953, 34.759704],
+		[113.822199, 34.75894],
+		[113.830601, 34.757305],
+		[113.833042, 34.756247],
+		[113.835423, 34.751598],
+		[113.838945, 34.748033],
+		[113.842336, 34.746667],
+		[113.845063, 34.746142],
+		[113.844457, 34.747956],
+		[113.84405, 34.750078],
+		[113.844761, 34.752649],
+		[113.845601, 34.756425],
+		[113.846596, 34.760143],
+		[113.848344, 34.764195],
+		[113.849541, 34.768194],
+		[113.849628, 34.77346],
+		[113.848822, 34.777819],
+		[113.846, 34.781724],
+		[113.843517, 34.784139],
+		[113.841596, 34.786615],
+		[113.839667, 34.788393],
+		[113.838578, 34.791263],
+		[113.838593, 34.794818],
+		[113.838751, 34.799227],
+		[113.838155, 34.804383],
+		[113.838795, 34.807009],
+		[113.839627, 34.80912],
+		[113.840536, 34.810719],
+		[113.841236, 34.812153],
+		[113.84, 34.8145],
+		[113.839601, 34.816964],
+		[113.839748, 34.819422],
+		[113.840588, 34.820562],
+		[113.843079, 34.822213],
+		[113.845591, 34.824486],
+		[113.845806, 34.825917],
+		[113.845192, 34.827354],
+		[113.842509, 34.830347],
+		[113.841402, 34.831665],
+		[113.840509, 34.833791],
+		[113.840727, 34.835502],
+		[113.841638, 34.838079],
+		[113.843334, 34.842764],
+		[113.844874, 34.846991],
+		[113.845575, 34.849958],
+		[113.846769, 34.852364],
+		[113.848231, 34.853608],
+		[113.849688, 34.854292],
+		[113.852179, 34.854511],
+		[113.853575, 34.855135],
+		[113.854958, 34.855983],
+		[113.85573, 34.857182],
+		[113.856145, 34.859061],
+		[113.8572, 34.859978],
+		[113.858932, 34.860654],
+		[113.861158, 34.861562],
+		[113.862819, 34.862638],
+		[113.864499, 34.864172],
+		[113.865746, 34.865488],
+		[113.866239, 34.867373],
+		[113.866389, 34.870062],
+		[113.86683, 34.873091],
+		[113.868024, 34.877383],
+		[113.870156, 34.885652],
+		[113.86484, 34.88483],
+		[113.841536, 34.879669],
+		[113.83799, 34.879079],
+		[113.826045, 34.877701],
+		[113.811262, 34.879],
+		[113.800467, 34.879942],
+		[113.795635, 34.882333],
+		[113.795469, 34.877478],
+		[113.801488, 34.871976],
+		[113.801322, 34.86708],
+		[113.797684, 34.865685],
+		[113.789102, 34.860424],
+		[113.783254, 34.858513],
+		[113.77892, 34.86101],
+		[113.767834, 34.867651],
+		[113.74297, 34.867303],
+		[113.71482, 34.868817],
+		[113.709988, 34.8647],
+		[113.705365, 34.858755],
+		[113.697245, 34.855843],
+		[113.685911, 34.854704],
+		[113.680192, 34.854945],
+		[113.680165, 34.852286],
+		[113.679116, 34.852459],
+		[113.678963, 34.853486],
+		[113.67642, 34.853588],
+		[113.676045, 34.851381],
+		[113.666979, 34.851166],
+		[113.66122, 34.850988],
+		[113.661089, 34.85172],
+		[113.654632, 34.851748],
+		[113.654921, 34.856858],
+		[113.646204, 34.857396],
+		[113.645884, 34.855973],
+		[113.644842, 34.856087],
+		[113.644278, 34.853951],
+		[113.641472, 34.852153],
+		[113.639742, 34.851191],
+		[113.639041, 34.846667],
+		[113.638459, 34.844046],
+		[113.638181, 34.843173],
+		[113.637971, 34.842188],
+		[113.634763, 34.841614],
+		[113.634721, 34.840336],
+		[113.634041, 34.8404],
+		[113.633243, 34.836785],
+		[113.633986, 34.836719],
+		[113.633425, 34.834685],
+		[113.63853, 34.834149],
+		[113.638524, 34.832954],
+		[113.637976, 34.831075],
+		[113.63837, 34.830983],
+		[113.637283, 34.827204],
+		[113.632582, 34.827696],
+		[113.632086, 34.825811],
+		[113.631225, 34.825983],
+		[113.631125, 34.824786],
+		[113.631138, 34.824341],
+		[113.630989, 34.823436],
+		[113.630865, 34.821566],
+		[113.630792, 34.821271],
+		[113.630732, 34.81992],
+		[113.630464, 34.816614],
+		[113.630188, 34.813452],
+		[113.63149, 34.81328],
+		[113.631154, 34.810978],
+		[113.63281, 34.810425],
+		[113.633007, 34.810146],
+		[113.632537, 34.806328],
+		[113.632566, 34.805981],
+		[113.633246, 34.805113],
+		[113.633981, 34.804325],
+		[113.634842, 34.803073],
+		[113.635784, 34.801441],
+		[113.637417, 34.799447],
+		[113.637574, 34.799002],
+		[113.638805, 34.797229],
+		[113.64006, 34.79537],
+		[113.638406, 34.794631],
+		[113.636842, 34.794737],
+		[113.636223, 34.794869],
+		[113.635543, 34.795875],
+		[113.633705, 34.798864],
+		[113.633608, 34.799286],
+		[113.63312, 34.799158],
+		[113.631928, 34.798577],
+		[113.631262, 34.798475],
+		[113.6308, 34.798665],
+		[113.629653, 34.799666],
+		[113.629212, 34.799823],
+		[113.628697, 34.799855],
+		[113.628047, 34.799776],
+		[113.624493, 34.798613],
+		[113.623598, 34.798434],
+		[113.622871, 34.798446],
+		[113.622435, 34.798579],
+		[113.622149, 34.798829],
+		[113.618997, 34.803537],
+		[113.618451, 34.80407],
+		[113.618067, 34.804304],
+		[113.617322, 34.804339],
+		[113.607988, 34.801055],
+		[113.607781, 34.800831],
+		[113.607687, 34.800328],
+		[113.607781, 34.799828],
+		[113.608128, 34.799156],
+		[113.610306, 34.795978],
+		[113.610784, 34.795577],
+		[113.611453, 34.795342],
+		[113.612345, 34.795385],
+		[113.615818, 34.795863],
+		[113.616157, 34.79564],
+		[113.620393, 34.7882],
+		[113.620584, 34.787726],
+		[113.620645, 34.787281],
+		[113.620479, 34.784954],
+		[113.620532, 34.784468],
+		[113.620671, 34.784335],
+		[113.621773, 34.783689],
+		[113.622175, 34.783333],
+		[113.622409, 34.782965],
+		[113.622514, 34.782484],
+		[113.622514, 34.781939],
+		[113.622165, 34.781078],
+		[113.621815, 34.780664],
+		[113.620802, 34.779912],
+		[113.621207, 34.779047],
+		[113.621283, 34.778671],
+		[113.622411, 34.778579],
+		[113.623451, 34.778546],
+		[113.624417, 34.776894],
+		[113.625952, 34.777371],
+		[113.627081, 34.777419],
+		[113.627435, 34.777129],
+		[113.628755, 34.774949],
+		[113.629243, 34.773824],
+		[113.629789, 34.772413],
+		[113.630789, 34.77064],
+		[113.631293, 34.769244],
+		[113.631474, 34.768529],
+		[113.631692, 34.766978],
+		[113.631682, 34.76646],
+		[113.63249, 34.766386],
+		[113.637115, 34.765796],
+		[113.637755, 34.765835],
+		[113.639259, 34.766353],
+		[113.643301, 34.760611],
+		[113.643692, 34.760265],
+		[113.644275, 34.759998],
+		[113.645065, 34.759778],
+		[113.651637, 34.758319],
+		[113.652532, 34.75986],
+		[113.652756, 34.760015],
+		[113.654212, 34.762128],
+		[113.655081, 34.762911],
+		[113.655514, 34.763158],
+		[113.656687, 34.763578],
+		[113.657409, 34.764023],
+		[113.658165, 34.764174],
+		[113.659651, 34.764175],
+		[113.662953, 34.764218],
+		[113.662971, 34.763813],
+		[113.664554, 34.763546],
+		[113.66527, 34.763483],
+		[113.665233, 34.760768],
+		[113.664436, 34.759232],
+		[113.664283, 34.758314],
+		[113.662685, 34.758756],
+		[113.66205, 34.760999],
+		[113.661428, 34.761126],
+		[113.661029, 34.761295],
+		[113.661063, 34.760425],
+		[113.661168, 34.759345],
+		[113.660215, 34.759303],
+		[113.66026, 34.758382],
+		[113.662273, 34.757863],
+		[113.66532, 34.756797],
+		[113.665627, 34.756373],
+		[113.667, 34.756081]
+	]
+
+]
+var cityObjArr = [];
+for (var i = 0; i < cityArr.length; i++) {
+	var arr = [];
+	for (var k = 0; k < cityArr[i].length; k++) {
+		var obj = {
+			lat: cityArr[i][k][1],
+			lng: cityArr[i][k][0]
+		}
+		arr.push(obj)
+	}
+	cityObjArr.push(arr)
+
+}

+ 747 - 0
hybrid/html/maps/js/lib/city.json

@@ -0,0 +1,747 @@
+{
+	"type": "FeatureCollection",
+	"features": [{
+		"type": "Feature",
+		"properties": {
+			"adcode": 410182,
+			"name": "荥阳市",
+			"center": [113.391523, 34.789077],
+			"centroid": [113.351681, 34.799765],
+			"childrenNum": 0,
+			"level": "district",
+			"acroutes": [100000, 410000, 410100],
+			"parent": {
+				"adcode": 410100
+			}
+		},
+		"geometry": {
+			"type": "MultiPolygon",
+			"coordinates": [
+				[
+					[
+						[113.272065, 34.723098],
+						[113.272632, 34.721607],
+						[113.271449, 34.720573],
+						[113.270334, 34.719883],
+						[113.26958, 34.71868],
+						[113.26958, 34.717254],
+						[113.270216, 34.715304],
+						[113.269518, 34.713583],
+						[113.267784, 34.7121],
+						[113.266818, 34.710602],
+						[113.265099, 34.705508],
+						[113.263567, 34.702868],
+						[113.261851, 34.700633],
+						[113.260319, 34.698966],
+						[113.259285, 34.696789],
+						[113.259009, 34.694045],
+						[113.260683, 34.691066],
+						[113.262222, 34.68872],
+						[113.263471, 34.686037],
+						[113.263888, 34.684657],
+						[113.26354, 34.682767],
+						[113.262437, 34.681456],
+						[113.26071, 34.680356],
+						[113.256263, 34.679175],
+						[113.255509, 34.678772],
+						[113.255229, 34.678228],
+						[113.254995, 34.677074],
+						[113.254881, 34.675145],
+						[113.255325, 34.673002],
+						[113.256064, 34.671829],
+						[113.256818, 34.671196],
+						[113.258224, 34.67061],
+						[113.259273, 34.669789],
+						[113.260212, 34.668305],
+						[113.261395, 34.666684],
+						[113.261116, 34.6662],
+						[113.261273, 34.665694],
+						[113.262686, 34.664973],
+						[113.263555, 34.66474],
+						[113.263348, 34.663934],
+						[113.262479, 34.663252],
+						[113.262272, 34.662788],
+						[113.263356, 34.661983],
+						[113.260897, 34.658033],
+						[113.25917, 34.654996],
+						[113.256478, 34.650635],
+						[113.253636, 34.648169],
+						[113.251694, 34.646566],
+						[113.250522, 34.64662],
+						[113.249274, 34.648971],
+						[113.24809, 34.648219],
+						[113.246018, 34.646616],
+						[113.244291, 34.64512],
+						[113.242912, 34.643122],
+						[113.242008, 34.641116],
+						[113.242227, 34.639571],
+						[113.241947, 34.638251],
+						[113.239871, 34.638428],
+						[113.236957, 34.639045],
+						[113.235225, 34.639739],
+						[113.233222, 34.640134],
+						[113.231901, 34.639793],
+						[113.230595, 34.638873],
+						[113.229691, 34.637894],
+						[113.228458, 34.635892],
+						[113.226646, 34.635888],
+						[113.223732, 34.637035],
+						[113.222357, 34.637319],
+						[113.220342, 34.637204],
+						[113.216953, 34.636744],
+						[113.213981, 34.635144],
+						[113.212464, 34.635255],
+						[113.209136, 34.636682],
+						[113.207474, 34.637085],
+						[113.205678, 34.637031],
+						[113.204364, 34.636448],
+						[113.203192, 34.634906],
+						[113.201407, 34.630729],
+						[113.199829, 34.628209],
+						[113.198792, 34.62672],
+						[113.199891, 34.626375],
+						[113.202047, 34.624718],
+						[113.202403, 34.622942],
+						[113.202192, 34.620935],
+						[113.201457, 34.615438],
+						[113.20215, 34.612464],
+						[113.203675, 34.610519],
+						[113.204992, 34.609368],
+						[113.206934, 34.609207],
+						[113.209707, 34.610116],
+						[113.212254, 34.610688],
+						[113.214126, 34.609725],
+						[113.21613, 34.609602],
+						[113.217861, 34.610231],
+						[113.220002, 34.611213],
+						[113.222223, 34.6119],
+						[113.222778, 34.610465],
+						[113.220775, 34.608865],
+						[113.220021, 34.607089],
+						[113.221886, 34.607146],
+						[113.225272, 34.608125],
+						[113.229906, 34.60893],
+						[113.232184, 34.609444],
+						[113.232939, 34.611796],
+						[113.233219, 34.613738],
+						[113.233835, 34.615457],
+						[113.236531, 34.616608],
+						[113.238534, 34.616719],
+						[113.240687, 34.617187],
+						[113.242204, 34.619408],
+						[113.243448, 34.62148],
+						[113.245034, 34.622282],
+						[113.248159, 34.6228],
+						[113.251135, 34.622804],
+						[113.253904, 34.623268],
+						[113.257994, 34.62316],
+						[113.262016, 34.623682],
+						[113.265409, 34.62443],
+						[113.269224, 34.624894],
+						[113.273038, 34.625761],
+						[113.276435, 34.626226],
+						[113.279066, 34.626287],
+						[113.281429, 34.626064],
+						[113.284133, 34.625332],
+						[113.286359, 34.624354],
+						[113.288028, 34.623387],
+						[113.290671, 34.621737],
+						[113.292889, 34.621227],
+						[113.299411, 34.621411],
+						[113.303654, 34.621365],
+						[113.3083, 34.621607],
+						[113.313019, 34.621511],
+						[113.316151, 34.620997],
+						[113.318718, 34.621012],
+						[113.322402, 34.622623],
+						[113.324688, 34.624917],
+						[113.328917, 34.628362],
+						[113.332739, 34.630096],
+						[113.334478, 34.629126],
+						[113.33614, 34.627633],
+						[113.337113, 34.626264],
+						[113.339966, 34.624902],
+						[113.343926, 34.625082],
+						[113.347116, 34.624407],
+						[113.349625, 34.623264],
+						[113.35324, 34.62064],
+						[113.35185, 34.618411],
+						[113.351023, 34.6168],
+						[113.354424, 34.614916],
+						[113.357545, 34.613439],
+						[113.36054, 34.612476],
+						[113.363941, 34.611213],
+						[113.366503, 34.610995],
+						[113.36887, 34.611344],
+						[113.370532, 34.612322],
+						[113.371923, 34.613749],
+						[113.373374, 34.615476],
+						[113.373792, 34.617425],
+						[113.374064, 34.620686],
+						[113.375385, 34.623153],
+						[113.376974, 34.62504],
+						[113.378981, 34.626985],
+						[113.382528, 34.629114],
+						[113.385232, 34.628316],
+						[113.387307, 34.627457],
+						[113.391677, 34.623513],
+						[113.393562, 34.622316],
+						[113.394665, 34.619969],
+						[113.395082, 34.61848],
+						[113.395362, 34.616305],
+						[113.394745, 34.6135],
+						[113.394603, 34.610753],
+						[113.394266, 34.609091],
+						[113.395438, 34.607952],
+						[113.398069, 34.607426],
+						[113.403619, 34.606689],
+						[113.407361, 34.606759],
+						[113.416844, 34.609272],
+						[113.421137, 34.60984],
+						[113.427502, 34.610979],
+						[113.434074, 34.611839],
+						[113.438433, 34.612115],
+						[113.44196, 34.612111],
+						[113.444725, 34.612568],
+						[113.446112, 34.61434],
+						[113.447912, 34.617951],
+						[113.449842, 34.620797],
+						[113.451298, 34.619305],
+						[113.452952, 34.618672],
+						[113.454752, 34.618618],
+						[113.456901, 34.618668],
+						[113.4589, 34.619754],
+						[113.460076, 34.620951],
+						[113.461799, 34.623978],
+						[113.462079, 34.628213],
+						[113.462841, 34.630215],
+						[113.463599, 34.632509],
+						[113.461592, 34.635773],
+						[113.45993, 34.637787],
+						[113.45993, 34.640077],
+						[113.460692, 34.641615],
+						[113.463186, 34.64229],
+						[113.464503, 34.643437],
+						[113.466989, 34.645032],
+						[113.468915, 34.644522],
+						[113.470727, 34.644622],
+						[113.471822, 34.646681],
+						[113.472102, 34.648568],
+						[113.472933, 34.651146],
+						[113.473545, 34.653776],
+						[113.475491, 34.655832],
+						[113.48129, 34.657818],
+						[113.484196, 34.659352],
+						[113.487368, 34.660491],
+						[113.491787, 34.662309],
+						[113.496146, 34.662803],
+						[113.499321, 34.662907],
+						[113.501741, 34.663298],
+						[113.503878, 34.664095],
+						[113.506153, 34.665342],
+						[113.507681, 34.667803],
+						[113.507613, 34.669575],
+						[113.506644, 34.671124],
+						[113.505816, 34.672964],
+						[113.506161, 34.674678],
+						[113.506647, 34.676453],
+						[113.50865, 34.68085],
+						[113.508723, 34.682395],
+						[113.507892, 34.685381],
+						[113.50713, 34.68721],
+						[113.506379, 34.689334],
+						[113.506942, 34.692994],
+						[113.507563, 34.696482],
+						[113.507911, 34.700315],
+						[113.508949, 34.704784],
+						[113.50978, 34.707643],
+						[113.511163, 34.710215],
+						[113.512894, 34.712832],
+						[113.517597, 34.717975],
+						[113.518359, 34.721006],
+						[113.517873, 34.722956],
+						[113.516153, 34.723707],
+						[113.514284, 34.724404],
+						[113.511864, 34.724347],
+						[113.508899, 34.725052],
+						[113.503848, 34.725469],
+						[113.499294, 34.725711],
+						[113.49528, 34.724523],
+						[113.494036, 34.723159],
+						[113.491554, 34.722136],
+						[113.488785, 34.723577],
+						[113.487402, 34.725071],
+						[113.485051, 34.725477],
+						[113.4825, 34.725546],
+						[113.479386, 34.725435],
+						[113.476625, 34.724761],
+						[113.473503, 34.724259],
+						[113.472197, 34.725684],
+						[113.471979, 34.727864],
+						[113.472197, 34.729753],
+						[113.473718, 34.731925],
+						[113.476269, 34.732086],
+						[113.478279, 34.731508],
+						[113.480075, 34.731278],
+						[113.482362, 34.732757],
+						[113.484162, 34.735439],
+						[113.485889, 34.736986],
+						[113.490803, 34.738224],
+						[113.488727, 34.739377],
+						[113.48672, 34.740239],
+						[113.485338, 34.741335],
+						[113.48327, 34.74397],
+						[113.481887, 34.746839],
+						[113.481194, 34.749023],
+						[113.481404, 34.75165],
+						[113.480573, 34.754347],
+						[113.476567, 34.756251],
+						[113.474553, 34.756484],
+						[113.470478, 34.756607],
+						[113.467571, 34.75725],
+						[113.464522, 34.75897],
+						[113.464315, 34.761662],
+						[113.465978, 34.763953],
+						[113.467502, 34.765668],
+						[113.468402, 34.768238],
+						[113.467916, 34.769778],
+						[113.467847, 34.771957],
+						[113.468402, 34.774426],
+						[113.470619, 34.774698],
+						[113.474633, 34.774292],
+						[113.476223, 34.773373],
+						[113.477253, 34.770953],
+						[113.479535, 34.768487],
+						[113.482718, 34.768541],
+						[113.485556, 34.768475],
+						[113.488808, 34.768805],
+						[113.493511, 34.769479],
+						[113.495518, 34.771011],
+						[113.494066, 34.772795],
+						[113.493653, 34.775139],
+						[113.494905, 34.777203],
+						[113.492622, 34.777896],
+						[113.489715, 34.778363],
+						[113.487364, 34.778428],
+						[113.485912, 34.779466],
+						[113.485981, 34.7813],
+						[113.487088, 34.782609],
+						[113.487712, 34.784037],
+						[113.487712, 34.786101],
+						[113.488482, 34.793946],
+						[113.487437, 34.796752],
+						[113.484331, 34.797793],
+						[113.482592, 34.798203],
+						[113.478448, 34.798207],
+						[113.477134, 34.797066],
+						[113.476502, 34.794095],
+						[113.474641, 34.791075],
+						[113.472358, 34.791419],
+						[113.470007, 34.792112],
+						[113.463358, 34.793211],
+						[113.460106, 34.793337],
+						[113.457682, 34.794091],
+						[113.455602, 34.795933],
+						[113.455744, 34.798046],
+						[113.456575, 34.799639],
+						[113.45782, 34.801641],
+						[113.458858, 34.802847],
+						[113.460106, 34.804102],
+						[113.460738, 34.805871],
+						[113.4608, 34.807765],
+						[113.460313, 34.809886],
+						[113.459482, 34.811945],
+						[113.457824, 34.813614],
+						[113.454844, 34.815976],
+						[113.453814, 34.81735],
+						[113.45319, 34.819003],
+						[113.453461, 34.82164],
+						[113.455744, 34.824617],
+						[113.457276, 34.830162],
+						[113.457762, 34.83268],
+						[113.458942, 34.834456],
+						[113.462335, 34.835585],
+						[113.464204, 34.835814],
+						[113.466142, 34.835696],
+						[113.468498, 34.835914],
+						[113.472305, 34.837563],
+						[113.474311, 34.837904],
+						[113.476525, 34.837609],
+						[113.478394, 34.83772],
+						[113.479995, 34.83909],
+						[113.483522, 34.840333],
+						[113.486085, 34.839468],
+						[113.489263, 34.83808],
+						[113.493147, 34.837268],
+						[113.495905, 34.837429],
+						[113.498888, 34.837816],
+						[113.50137, 34.838271],
+						[113.504629, 34.838256],
+						[113.507961, 34.840704],
+						[113.508444, 34.842992],
+						[113.508091, 34.844599],
+						[113.507061, 34.847522],
+						[113.507061, 34.849982],
+						[113.509007, 34.854038],
+						[113.509562, 34.856276],
+						[113.5097, 34.858452],
+						[113.509148, 34.860916],
+						[113.50811, 34.862867],
+						[113.506862, 34.86424],
+						[113.505414, 34.865445],
+						[113.504166, 34.866776],
+						[113.502232, 34.867698],
+						[113.499742, 34.869362],
+						[113.497735, 34.872295],
+						[113.497322, 34.875221],
+						[113.498291, 34.878591],
+						[113.498643, 34.88162],
+						[113.497954, 34.885517],
+						[113.498505, 34.886947],
+						[113.49975, 34.888258],
+						[113.501144, 34.88923],
+						[113.504395, 34.891964],
+						[113.508417, 34.89739],
+						[113.509393, 34.899852],
+						[113.509669, 34.901618],
+						[113.508907, 34.903633],
+						[113.508493, 34.905121],
+						[113.506904, 34.907873],
+						[113.505391, 34.909716],
+						[113.504828, 34.911379],
+						[113.503583, 34.914529],
+						[113.50227, 34.916704],
+						[113.501856, 34.918367],
+						[113.501657, 34.922323],
+						[113.502488, 34.926562],
+						[113.503258, 34.933136],
+						[113.503243, 34.933331],
+						[113.505966, 34.954257],
+						[113.510454, 34.961842],
+						[113.516318, 34.963698],
+						[113.522128, 34.966411],
+						[113.522787, 34.967034],
+						[113.515096, 34.965995],
+						[113.495843, 34.959924],
+						[113.477368, 34.957299],
+						[113.474859, 34.957463],
+						[113.465629, 34.958162],
+						[113.45931, 34.959928],
+						[113.452535, 34.960493],
+						[113.449674, 34.960226],
+						[113.429433, 34.964761],
+						[113.428755, 34.969876],
+						[113.429659, 34.977317],
+						[113.427188, 34.983563],
+						[113.419904, 34.987764],
+						[113.407824, 34.989506],
+						[113.394531, 34.986798],
+						[113.388816, 34.985064],
+						[113.381218, 34.982046],
+						[113.37558, 34.98001],
+						[113.371222, 34.977673],
+						[113.362578, 34.970331],
+						[113.358794, 34.965265],
+						[113.352114, 34.958258],
+						[113.349338, 34.95608],
+						[113.343455, 34.950517],
+						[113.333034, 34.944865],
+						[113.328227, 34.943302],
+						[113.320809, 34.942052],
+						[113.315294, 34.942209],
+						[113.304436, 34.945878],
+						[113.30228, 34.946539],
+						[113.28989, 34.952576],
+						[113.279978, 34.953696],
+						[113.27408, 34.954292],
+						[113.266114, 34.954135],
+						[113.260556, 34.953608],
+						[113.252985, 34.951529],
+						[113.243904, 34.946187],
+						[113.239327, 34.9395],
+						[113.23698, 34.92519],
+						[113.231472, 34.91628],
+						[113.228964, 34.911368],
+						[113.227677, 34.908412],
+						[113.222958, 34.90743],
+						[113.220323, 34.906604],
+						[113.214326, 34.905036],
+						[113.207761, 34.903041],
+						[113.197654, 34.900296],
+						[113.189596, 34.897493],
+						[113.185754, 34.896327],
+						[113.184203, 34.89578],
+						[113.179539, 34.893684],
+						[113.176693, 34.89305],
+						[113.170496, 34.891421],
+						[113.168727, 34.891111],
+						[113.16276, 34.889624],
+						[113.1579, 34.887727],
+						[113.156934, 34.887482],
+						[113.153158, 34.887245],
+						[113.140048, 34.884801],
+						[113.139799, 34.884633],
+						[113.142025, 34.877321],
+						[113.147965, 34.85628],
+						[113.147915, 34.856119],
+						[113.144468, 34.855847],
+						[113.14518, 34.853403],
+						[113.147314, 34.847633],
+						[113.147494, 34.846822],
+						[113.147325, 34.845361],
+						[113.146594, 34.843857],
+						[113.146804, 34.842767],
+						[113.147681, 34.841714],
+						[113.149202, 34.840203],
+						[113.15073, 34.837567],
+						[113.152235, 34.835642],
+						[113.15356, 34.833645],
+						[113.154663, 34.83234],
+						[113.156168, 34.831632],
+						[113.156716, 34.83102],
+						[113.157842, 34.828567],
+						[113.158363, 34.826933],
+						[113.158861, 34.82619],
+						[113.161825, 34.823152],
+						[113.163342, 34.821759],
+						[113.164399, 34.821005],
+						[113.166249, 34.820331],
+						[113.166957, 34.819757],
+						[113.167436, 34.818479],
+						[113.167516, 34.817667],
+						[113.167865, 34.817051],
+						[113.166827, 34.81653],
+						[113.164954, 34.815899],
+						[113.163637, 34.815845],
+						[113.162392, 34.816818],
+						[113.160718, 34.818708],
+						[113.159956, 34.818769],
+						[113.159964, 34.817162],
+						[113.159688, 34.815669],
+						[113.158447, 34.81441],
+						[113.156992, 34.81361],
+						[113.15631, 34.812462],
+						[113.155755, 34.810514],
+						[113.1559, 34.808688],
+						[113.15916, 34.806797],
+						[113.161316, 34.806456],
+						[113.164514, 34.80411],
+						[113.163411, 34.802678],
+						[113.161117, 34.802445],
+						[113.156751, 34.804163],
+						[113.155632, 34.804221],
+						[113.154533, 34.803593],
+						[113.153074, 34.802092],
+						[113.152806, 34.800722],
+						[113.152875, 34.799635],
+						[113.154748, 34.799007],
+						[113.156283, 34.798318],
+						[113.157042, 34.797464],
+						[113.154487, 34.795799],
+						[113.152415, 34.793452],
+						[113.152484, 34.792824],
+						[113.153039, 34.79202],
+						[113.156785, 34.792361],
+						[113.159765, 34.793739],
+						[113.161634, 34.793456],
+						[113.161921, 34.790646],
+						[113.160603, 34.789275],
+						[113.157915, 34.785374],
+						[113.154537, 34.781484],
+						[113.152607, 34.779427],
+						[113.151427, 34.777528],
+						[113.151159, 34.775698],
+						[113.152553, 34.774323],
+						[113.154771, 34.773978],
+						[113.157961, 34.773634],
+						[113.160247, 34.77381],
+						[113.16302, 34.773243],
+						[113.164414, 34.772324],
+						[113.165663, 34.77044],
+						[113.167325, 34.768376],
+						[113.168857, 34.76774],
+						[113.169968, 34.765971],
+						[113.170814, 34.762704],
+						[113.17076, 34.757438],
+						[113.169523, 34.754286],
+						[113.167876, 34.750857],
+						[113.166708, 34.748161],
+						[113.166785, 34.745131],
+						[113.167417, 34.743124],
+						[113.169497, 34.742036],
+						[113.171921, 34.741986],
+						[113.173924, 34.743411],
+						[113.175647, 34.745008],
+						[113.176758, 34.746387],
+						[113.177581, 34.747651],
+						[113.178202, 34.749823],
+						[113.177976, 34.752516],
+						[113.177424, 34.753952],
+						[113.177631, 34.755779],
+						[113.179772, 34.757491],
+						[113.182733, 34.759215],
+						[113.186754, 34.759732],
+						[113.190147, 34.75979],
+						[113.194582, 34.758821],
+						[113.198604, 34.758702],
+						[113.201863, 34.757844],
+						[113.208033, 34.75612],
+						[113.2131, 34.754527],
+						[113.215743, 34.752976],
+						[113.220312, 34.751555],
+						[113.224551, 34.750463],
+						[113.22919, 34.750356],
+						[113.231897, 34.750474],
+						[113.234601, 34.751045],
+						[113.23737, 34.752022],
+						[113.240285, 34.753347],
+						[113.24313, 34.754083],
+						[113.246524, 34.753922],
+						[113.24909, 34.754374],
+						[113.251035, 34.753581],
+						[113.253743, 34.75427],
+						[113.25575, 34.755822],
+						[113.25706, 34.758112],
+						[113.258243, 34.761034],
+						[113.258094, 34.762754],
+						[113.258929, 34.764642],
+						[113.258128, 34.766944],
+						[113.257688, 34.770026],
+						[113.257029, 34.772451],
+						[113.256367, 34.776747],
+						[113.255267, 34.781537],
+						[113.253881, 34.785845],
+						[113.25256, 34.787721],
+						[113.252008, 34.790581],
+						[113.253329, 34.796584],
+						[113.253, 34.798456],
+						[113.251284, 34.80091],
+						[113.251009, 34.80246],
+						[113.251085, 34.803922],
+						[113.251954, 34.806609],
+						[113.251683, 34.80881],
+						[113.250143, 34.812447],
+						[113.249756, 34.815585],
+						[113.25058, 34.819868],
+						[113.249538, 34.821249],
+						[113.248071, 34.822604],
+						[113.247481, 34.824353],
+						[113.248155, 34.825819],
+						[113.251058, 34.827537],
+						[113.252184, 34.828835],
+						[113.251935, 34.830503],
+						[113.252728, 34.831735],
+						[113.254314, 34.831957],
+						[113.255631, 34.831471],
+						[113.256757, 34.831463],
+						[113.257125, 34.832168],
+						[113.259867, 34.838363],
+						[113.260966, 34.83974],
+						[113.263272, 34.84147],
+						[113.266374, 34.842813],
+						[113.269825, 34.843589],
+						[113.274229, 34.843907],
+						[113.281315, 34.843597],
+						[113.284876, 34.84367],
+						[113.287094, 34.843321],
+						[113.288791, 34.841313],
+						[113.289105, 34.83899],
+						[113.288978, 34.835673],
+						[113.289472, 34.832921],
+						[113.291675, 34.830614],
+						[113.293494, 34.829757],
+						[113.294976, 34.828911],
+						[113.298005, 34.827885],
+						[113.30079, 34.828291],
+						[113.302839, 34.828111],
+						[113.308377, 34.827874],
+						[113.310319, 34.826783],
+						[113.311908, 34.825589],
+						[113.313635, 34.824005],
+						[113.315661, 34.821406],
+						[113.317653, 34.819627],
+						[113.318836, 34.817055],
+						[113.320445, 34.814823],
+						[113.320406, 34.81309],
+						[113.323405, 34.811983],
+						[113.324639, 34.811436],
+						[113.32434, 34.810464],
+						[113.325673, 34.809905],
+						[113.32545, 34.807674],
+						[113.32619, 34.807528],
+						[113.326071, 34.806962],
+						[113.32519, 34.806456],
+						[113.325198, 34.805729],
+						[113.325883, 34.805561],
+						[113.325791, 34.805028],
+						[113.323547, 34.804986],
+						[113.322946, 34.805323],
+						[113.32257, 34.805147],
+						[113.321682, 34.805652],
+						[113.320207, 34.80566],
+						[113.319951, 34.804133],
+						[113.320181, 34.802705],
+						[113.319958, 34.802517],
+						[113.318775, 34.802425],
+						[113.318243, 34.802062],
+						[113.318147, 34.798781],
+						[113.318534, 34.795573],
+						[113.3173, 34.792047],
+						[113.316171, 34.789153],
+						[113.314336, 34.785837],
+						[113.312195, 34.78184],
+						[113.311261, 34.778202],
+						[113.309108, 34.775062],
+						[113.306021, 34.771807],
+						[113.305412, 34.769766],
+						[113.304754, 34.766848],
+						[113.304424, 34.764041],
+						[113.302712, 34.762991],
+						[113.300839, 34.762271],
+						[113.298358, 34.761992],
+						[113.293838, 34.762482],
+						[113.291812, 34.762608],
+						[113.288281, 34.760889],
+						[113.287841, 34.758637],
+						[113.290388, 34.755894],
+						[113.29408, 34.754232],
+						[113.295975, 34.75265],
+						[113.298136, 34.751156],
+						[113.299285, 34.749835],
+						[113.299461, 34.748073],
+						[113.299369, 34.746441],
+						[113.298002, 34.743533],
+						[113.29717, 34.741043],
+						[113.297488, 34.739507],
+						[113.298365, 34.738902],
+						[113.300376, 34.738094],
+						[113.305229, 34.736408],
+						[113.306852, 34.735577],
+						[113.308254, 34.735013],
+						[113.308794, 34.734159],
+						[113.309315, 34.732761],
+						[113.309139, 34.730734],
+						[113.307687, 34.727385],
+						[113.305125, 34.725837],
+						[113.302789, 34.724734],
+						[113.300939, 34.722615],
+						[113.299878, 34.720458],
+						[113.299085, 34.718296],
+						[113.296749, 34.71653],
+						[113.294501, 34.715426],
+						[113.292823, 34.714897],
+						[113.29084, 34.714143],
+						[113.289032, 34.714143],
+						[113.287534, 34.715154],
+						[113.284892, 34.718013],
+						[113.282157, 34.719952],
+						[113.278327, 34.722105],
+						[113.27652, 34.722676],
+						[113.273877, 34.723205],
+						[113.272065, 34.723098]
+					]
+				]
+			]
+		}
+	}]
+}

+ 92 - 0
hybrid/html/maps/js/lib/common.js

@@ -0,0 +1,92 @@
+/**
+ * MapID
+ * 
+ * 
+ * */
+var MAPID = 'c0248134c43b27bf'
+
+/**
+ * 
+ * 获取url地址参数
+ * 
+ * */
+
+function getQueryVariable(variable) {
+	var query = decodeURI(window.location.search.substring(1));
+	var vars = query.split("&");
+	for (var i = 0; i < vars.length; i++) {
+		var pair = vars[i].split("=");
+		if (pair[0] == variable) {
+			return pair[1];
+		}
+	}
+	return (false);
+}
+
+
+
+/**
+ * 随机生成颜色rgb值
+ * 
+ * */
+
+function getRandomColor() {
+	const letters = '0123456789ABCDEF'; // 16进制颜色表示中可能出现的字符
+	let color = '#';
+	for (let i = 0; i < 6; i++) { // 随机生成6位十六进制数
+		color += letters[Math.floor(Math.random() * 16)]; // 根据随机数选取相应的字符
+	}
+	return color;
+}
+
+
+/**
+ * 随机生成中文文字
+ * 辅助方法 实际中可废弃
+ * */
+function randomChinese(num) {
+
+	let str = "";
+	const words = ["Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "sed", "do",
+		"eiusmod", "tempor",
+		"incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua", "Ut", "enim", "ad", "minim", "veniam",
+		"quis",
+		"nostrud", "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo",
+		"consequat",
+		"Duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", "voluptate", "velit", "esse", "cillum",
+		"dolore",
+		"eu", "fugiat", "nulla", "pariatur", "Excepteur", "sint", "occaecat", "cupidatat", "non", "proident",
+		"sunt",
+		"in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum"
+	];
+	for (let i = 0; i < num; i++) {
+		const randomWord = words[Math.floor(Math.random() * words.length)];
+		str += randomWord + " ";
+	}
+	return str.trim();
+}
+
+
+/**
+ * 加载动画
+ * 
+ */
+function LoadAnimation(isFalse) {
+	if (isFalse) {
+		document.getElementById("loader").style.display = "inline";
+	} else {
+		document.getElementById("loader").style.display = "none";
+	}
+
+}
+
+
+
+// export default {
+// 	LoadAnimation,
+// 	randomChinese,
+// 	getRandomColor,
+// 	getQueryVariable,
+// 	getMapID
+
+// }

File diff suppressed because it is too large
+ 1 - 0
hybrid/html/maps/js/lib/jquery-3.2.1.min.js


+ 26 - 0
hybrid/html/maps/js/lib/rem.js

@@ -0,0 +1,26 @@
+!(function(window) {
+  /* 设计图文档宽度 */
+  var docWidth = 750;
+  var doc = window.document,
+    docEl = doc.documentElement,
+    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
+  var recalc = (function refreshRem() {
+    var clientWidth = docEl.getBoundingClientRect().width;
+    /* 8.55:小于320px不再缩小,11.2:大于420px不再放大 */
+    docEl.style.fontSize = Math.max(Math.min(20 * (clientWidth / docWidth), 11.2), 8.55) * 5 + 'px';
+    return refreshRem;
+  })();
+  /* 添加倍屏标识,安卓为1 */
+  docEl.setAttribute('data-dpr', window.navigator.appVersion.match(/iphone/gi) ? window.devicePixelRatio : 1);
+  if (/iP(hone|od|ad)/.test(window.navigator.userAgent)) {
+    /* 添加IOS标识 */
+    doc.documentElement.classList.add('ios');
+    /* IOS8以上给html添加hairline样式,以便特殊处理 */
+    if (parseInt(window.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/)[1], 10) >= 8)
+      doc.documentElement.classList.add('hairline');
+  }
+  if (!doc.addEventListener)
+    return;
+  window.addEventListener(resizeEvt, recalc, false);
+  doc.addEventListener('DOMContentLoaded', recalc, false);
+})(window);

+ 0 - 0
hybrid/html/maps/js/lib/slider.js


+ 17 - 0
hybrid/html/maps/js/lib/toast.js

@@ -0,0 +1,17 @@
+function Toast(msg, duration) {
+	duration = isNaN(duration) ? 3000 : duration;
+	var m = document.createElement('div');
+
+	m.innerHTML = msg;
+	m.style.cssText =
+		"max-width:60%;min-width: 150px;padding:0 14px;height:auto;color: rgb(255, 255, 255);line-height: 40px;text-align: center;border-radius: 4px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.7);font-size: 16px;";
+	document.body.appendChild(m);
+	setTimeout(function() {
+		var d = 0.5;
+		m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
+		m.style.opacity = '0';
+		setTimeout(function() {
+			document.body.removeChild(m)
+		}, d * 1000);
+	}, duration);
+}

File diff suppressed because it is too large
+ 0 - 0
hybrid/html/maps/js/lib/uniwebviewsdk.js


+ 16810 - 0
hybrid/html/maps/js/lib/vant.js

@@ -0,0 +1,16810 @@
+(function(global, factory) {
+  typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue")) : typeof define === "function" && define.amd ? define(["exports", "vue"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.vant = {}, global.Vue));
+})(this, function(exports2, vue) {
+  "use strict";
+  const isDef = (val) => val !== void 0 && val !== null;
+  const isFunction = (val) => typeof val === "function";
+  const isObject = (val) => val !== null && typeof val === "object";
+  const isPromise = (val) => isObject(val) && isFunction(val.then) && isFunction(val.catch);
+  const isDate = (val) => Object.prototype.toString.call(val) === "[object Date]" && !Number.isNaN(val.getTime());
+  function isMobile(value) {
+    value = value.replace(/[^-|\d]/g, "");
+    return /^((\+86)|(86))?(1)\d{10}$/.test(value) || /^0[0-9-]{10,13}$/.test(value);
+  }
+  const isNumeric = (val) => typeof val === "number" || /^\d+(\.\d+)?$/.test(val);
+  const isIOS$1 = () => inBrowser$1 ? /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase()) : false;
+  function noop() {
+  }
+  const extend = Object.assign;
+  const inBrowser$1 = typeof window !== "undefined";
+  function get(object, path) {
+    const keys = path.split(".");
+    let result = object;
+    keys.forEach((key) => {
+      var _a;
+      result = isObject(result) ? (_a = result[key]) != null ? _a : "" : "";
+    });
+    return result;
+  }
+  function pick(obj, keys, ignoreUndefined) {
+    return keys.reduce((ret, key) => {
+      if (!ignoreUndefined || obj[key] !== void 0) {
+        ret[key] = obj[key];
+      }
+      return ret;
+    }, {});
+  }
+  const isSameValue = (newValue, oldValue) => JSON.stringify(newValue) === JSON.stringify(oldValue);
+  const toArray = (item) => Array.isArray(item) ? item : [item];
+  const unknownProp = null;
+  const numericProp = [Number, String];
+  const truthProp = {
+    type: Boolean,
+    default: true
+  };
+  const makeRequiredProp = (type) => ({
+    type,
+    required: true
+  });
+  const makeArrayProp = () => ({
+    type: Array,
+    default: () => []
+  });
+  const makeNumberProp = (defaultVal) => ({
+    type: Number,
+    default: defaultVal
+  });
+  const makeNumericProp = (defaultVal) => ({
+    type: numericProp,
+    default: defaultVal
+  });
+  const makeStringProp = (defaultVal) => ({
+    type: String,
+    default: defaultVal
+  });
+  var inBrowser = typeof window !== "undefined";
+  function raf(fn) {
+    return inBrowser ? requestAnimationFrame(fn) : -1;
+  }
+  function cancelRaf(id) {
+    if (inBrowser) {
+      cancelAnimationFrame(id);
+    }
+  }
+  function doubleRaf(fn) {
+    raf(() => raf(fn));
+  }
+  var isWindow = (val) => val === window;
+  var makeDOMRect = (width2, height2) => ({
+    top: 0,
+    left: 0,
+    right: width2,
+    bottom: height2,
+    width: width2,
+    height: height2
+  });
+  var useRect = (elementOrRef) => {
+    const element = vue.unref(elementOrRef);
+    if (isWindow(element)) {
+      const width2 = element.innerWidth;
+      const height2 = element.innerHeight;
+      return makeDOMRect(width2, height2);
+    }
+    if (element == null ? void 0 : element.getBoundingClientRect) {
+      return element.getBoundingClientRect();
+    }
+    return makeDOMRect(0, 0);
+  };
+  function useToggle(defaultValue = false) {
+    const state = vue.ref(defaultValue);
+    const toggle = (value = !state.value) => {
+      state.value = value;
+    };
+    return [state, toggle];
+  }
+  function useParent(key) {
+    const parent = vue.inject(key, null);
+    if (parent) {
+      const instance2 = vue.getCurrentInstance();
+      const { link, unlink, internalChildren } = parent;
+      link(instance2);
+      vue.onUnmounted(() => unlink(instance2));
+      const index = vue.computed(() => internalChildren.indexOf(instance2));
+      return {
+        parent,
+        index
+      };
+    }
+    return {
+      parent: null,
+      index: vue.ref(-1)
+    };
+  }
+  function flattenVNodes(children) {
+    const result = [];
+    const traverse = (children2) => {
+      if (Array.isArray(children2)) {
+        children2.forEach((child) => {
+          var _a;
+          if (vue.isVNode(child)) {
+            result.push(child);
+            if ((_a = child.component) == null ? void 0 : _a.subTree) {
+              result.push(child.component.subTree);
+              traverse(child.component.subTree.children);
+            }
+            if (child.children) {
+              traverse(child.children);
+            }
+          }
+        });
+      }
+    };
+    traverse(children);
+    return result;
+  }
+  var findVNodeIndex = (vnodes, vnode) => {
+    const index = vnodes.indexOf(vnode);
+    if (index === -1) {
+      return vnodes.findIndex(
+        (item) => vnode.key !== void 0 && vnode.key !== null && item.type === vnode.type && item.key === vnode.key
+      );
+    }
+    return index;
+  };
+  function sortChildren(parent, publicChildren, internalChildren) {
+    const vnodes = flattenVNodes(parent.subTree.children);
+    internalChildren.sort(
+      (a, b) => findVNodeIndex(vnodes, a.vnode) - findVNodeIndex(vnodes, b.vnode)
+    );
+    const orderedPublicChildren = internalChildren.map((item) => item.proxy);
+    publicChildren.sort((a, b) => {
+      const indexA = orderedPublicChildren.indexOf(a);
+      const indexB = orderedPublicChildren.indexOf(b);
+      return indexA - indexB;
+    });
+  }
+  function useChildren(key) {
+    const publicChildren = vue.reactive([]);
+    const internalChildren = vue.reactive([]);
+    const parent = vue.getCurrentInstance();
+    const linkChildren = (value) => {
+      const link = (child) => {
+        if (child.proxy) {
+          internalChildren.push(child);
+          publicChildren.push(child.proxy);
+          sortChildren(parent, publicChildren, internalChildren);
+        }
+      };
+      const unlink = (child) => {
+        const index = internalChildren.indexOf(child);
+        publicChildren.splice(index, 1);
+        internalChildren.splice(index, 1);
+      };
+      vue.provide(
+        key,
+        Object.assign(
+          {
+            link,
+            unlink,
+            children: publicChildren,
+            internalChildren
+          },
+          value
+        )
+      );
+    };
+    return {
+      children: publicChildren,
+      linkChildren
+    };
+  }
+  var SECOND = 1e3;
+  var MINUTE = 60 * SECOND;
+  var HOUR = 60 * MINUTE;
+  var DAY = 24 * HOUR;
+  function parseTime(time) {
+    const days = Math.floor(time / DAY);
+    const hours = Math.floor(time % DAY / HOUR);
+    const minutes = Math.floor(time % HOUR / MINUTE);
+    const seconds = Math.floor(time % MINUTE / SECOND);
+    const milliseconds = Math.floor(time % SECOND);
+    return {
+      total: time,
+      days,
+      hours,
+      minutes,
+      seconds,
+      milliseconds
+    };
+  }
+  function isSameSecond(time1, time2) {
+    return Math.floor(time1 / 1e3) === Math.floor(time2 / 1e3);
+  }
+  function useCountDown(options) {
+    let rafId;
+    let endTime;
+    let counting;
+    let deactivated;
+    const remain = vue.ref(options.time);
+    const current2 = vue.computed(() => parseTime(remain.value));
+    const pause = () => {
+      counting = false;
+      cancelRaf(rafId);
+    };
+    const getCurrentRemain = () => Math.max(endTime - Date.now(), 0);
+    const setRemain = (value) => {
+      var _a, _b;
+      remain.value = value;
+      (_a = options.onChange) == null ? void 0 : _a.call(options, current2.value);
+      if (value === 0) {
+        pause();
+        (_b = options.onFinish) == null ? void 0 : _b.call(options);
+      }
+    };
+    const microTick = () => {
+      rafId = raf(() => {
+        if (counting) {
+          setRemain(getCurrentRemain());
+          if (remain.value > 0) {
+            microTick();
+          }
+        }
+      });
+    };
+    const macroTick = () => {
+      rafId = raf(() => {
+        if (counting) {
+          const remainRemain = getCurrentRemain();
+          if (!isSameSecond(remainRemain, remain.value) || remainRemain === 0) {
+            setRemain(remainRemain);
+          }
+          if (remain.value > 0) {
+            macroTick();
+          }
+        }
+      });
+    };
+    const tick = () => {
+      if (!inBrowser) {
+        return;
+      }
+      if (options.millisecond) {
+        microTick();
+      } else {
+        macroTick();
+      }
+    };
+    const start2 = () => {
+      if (!counting) {
+        endTime = Date.now() + remain.value;
+        counting = true;
+        tick();
+      }
+    };
+    const reset = (totalTime = options.time) => {
+      pause();
+      remain.value = totalTime;
+    };
+    vue.onBeforeUnmount(pause);
+    vue.onActivated(() => {
+      if (deactivated) {
+        counting = true;
+        deactivated = false;
+        tick();
+      }
+    });
+    vue.onDeactivated(() => {
+      if (counting) {
+        pause();
+        deactivated = true;
+      }
+    });
+    return {
+      start: start2,
+      pause,
+      reset,
+      current: current2
+    };
+  }
+  function onMountedOrActivated(hook) {
+    let mounted;
+    vue.onMounted(() => {
+      hook();
+      vue.nextTick(() => {
+        mounted = true;
+      });
+    });
+    vue.onActivated(() => {
+      if (mounted) {
+        hook();
+      }
+    });
+  }
+  function useEventListener(type, listener, options = {}) {
+    if (!inBrowser) {
+      return;
+    }
+    const { target = window, passive: passive2 = false, capture = false } = options;
+    let cleaned = false;
+    let attached;
+    const add = (target2) => {
+      if (cleaned) {
+        return;
+      }
+      const element = vue.unref(target2);
+      if (element && !attached) {
+        element.addEventListener(type, listener, {
+          capture,
+          passive: passive2
+        });
+        attached = true;
+      }
+    };
+    const remove2 = (target2) => {
+      if (cleaned) {
+        return;
+      }
+      const element = vue.unref(target2);
+      if (element && attached) {
+        element.removeEventListener(type, listener, capture);
+        attached = false;
+      }
+    };
+    vue.onUnmounted(() => remove2(target));
+    vue.onDeactivated(() => remove2(target));
+    onMountedOrActivated(() => add(target));
+    let stopWatch;
+    if (vue.isRef(target)) {
+      stopWatch = vue.watch(target, (val, oldVal) => {
+        remove2(oldVal);
+        add(val);
+      });
+    }
+    return () => {
+      stopWatch == null ? void 0 : stopWatch();
+      remove2(target);
+      cleaned = true;
+    };
+  }
+  function useClickAway(target, listener, options = {}) {
+    if (!inBrowser) {
+      return;
+    }
+    const { eventName = "click" } = options;
+    const onClick = (event) => {
+      const targets = Array.isArray(target) ? target : [target];
+      const isClickAway = targets.every((item) => {
+        const element = vue.unref(item);
+        return element && !element.contains(event.target);
+      });
+      if (isClickAway) {
+        listener(event);
+      }
+    };
+    useEventListener(eventName, onClick, { target: document });
+  }
+  var width;
+  var height;
+  function useWindowSize() {
+    if (!width) {
+      width = vue.ref(0);
+      height = vue.ref(0);
+      if (inBrowser) {
+        const update = () => {
+          width.value = window.innerWidth;
+          height.value = window.innerHeight;
+        };
+        update();
+        window.addEventListener("resize", update, { passive: true });
+        window.addEventListener("orientationchange", update, { passive: true });
+      }
+    }
+    return { width, height };
+  }
+  var overflowScrollReg = /scroll|auto|overlay/i;
+  var defaultRoot = inBrowser ? window : void 0;
+  function isElement$1(node) {
+    const ELEMENT_NODE_TYPE = 1;
+    return node.tagName !== "HTML" && node.tagName !== "BODY" && node.nodeType === ELEMENT_NODE_TYPE;
+  }
+  function getScrollParent$1(el, root = defaultRoot) {
+    let node = el;
+    while (node && node !== root && isElement$1(node)) {
+      const { overflowY } = window.getComputedStyle(node);
+      if (overflowScrollReg.test(overflowY)) {
+        return node;
+      }
+      node = node.parentNode;
+    }
+    return root;
+  }
+  function useScrollParent(el, root = defaultRoot) {
+    const scrollParent = vue.ref();
+    vue.onMounted(() => {
+      if (el.value) {
+        scrollParent.value = getScrollParent$1(el.value, root);
+      }
+    });
+    return scrollParent;
+  }
+  var visibility;
+  function usePageVisibility() {
+    if (!visibility) {
+      visibility = vue.ref("visible");
+      if (inBrowser) {
+        const update = () => {
+          visibility.value = document.hidden ? "hidden" : "visible";
+        };
+        update();
+        window.addEventListener("visibilitychange", update);
+      }
+    }
+    return visibility;
+  }
+  var CUSTOM_FIELD_INJECTION_KEY = Symbol("van-field");
+  function useCustomFieldValue(customValue) {
+    const field = vue.inject(CUSTOM_FIELD_INJECTION_KEY, null);
+    if (field && !field.customValue.value) {
+      field.customValue.value = customValue;
+      vue.watch(customValue, () => {
+        field.resetValidation();
+        field.validateWithTrigger("onChange");
+      });
+    }
+  }
+  function getScrollTop(el) {
+    const top2 = "scrollTop" in el ? el.scrollTop : el.pageYOffset;
+    return Math.max(top2, 0);
+  }
+  function setScrollTop(el, value) {
+    if ("scrollTop" in el) {
+      el.scrollTop = value;
+    } else {
+      el.scrollTo(el.scrollX, value);
+    }
+  }
+  function getRootScrollTop() {
+    return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
+  }
+  function setRootScrollTop(value) {
+    setScrollTop(window, value);
+    setScrollTop(document.body, value);
+  }
+  function getElementTop(el, scroller) {
+    if (el === window) {
+      return 0;
+    }
+    const scrollTop = scroller ? getScrollTop(scroller) : getRootScrollTop();
+    return useRect(el).top + scrollTop;
+  }
+  const isIOS = isIOS$1();
+  function resetScroll() {
+    if (isIOS) {
+      setRootScrollTop(getRootScrollTop());
+    }
+  }
+  const stopPropagation = (event) => event.stopPropagation();
+  function preventDefault(event, isStopPropagation) {
+    if (typeof event.cancelable !== "boolean" || event.cancelable) {
+      event.preventDefault();
+    }
+    if (isStopPropagation) {
+      stopPropagation(event);
+    }
+  }
+  function isHidden(elementRef) {
+    const el = vue.unref(elementRef);
+    if (!el) {
+      return false;
+    }
+    const style = window.getComputedStyle(el);
+    const hidden = style.display === "none";
+    const parentHidden = el.offsetParent === null && style.position !== "fixed";
+    return hidden || parentHidden;
+  }
+  const { width: windowWidth, height: windowHeight } = useWindowSize();
+  function addUnit(value) {
+    if (isDef(value)) {
+      return isNumeric(value) ? `${value}px` : String(value);
+    }
+    return void 0;
+  }
+  function getSizeStyle(originSize) {
+    if (isDef(originSize)) {
+      if (Array.isArray(originSize)) {
+        return {
+          width: addUnit(originSize[0]),
+          height: addUnit(originSize[1])
+        };
+      }
+      const size = addUnit(originSize);
+      return {
+        width: size,
+        height: size
+      };
+    }
+  }
+  function getZIndexStyle(zIndex) {
+    const style = {};
+    if (zIndex !== void 0) {
+      style.zIndex = +zIndex;
+    }
+    return style;
+  }
+  let rootFontSize;
+  function getRootFontSize() {
+    if (!rootFontSize) {
+      const doc = document.documentElement;
+      const fontSize = doc.style.fontSize || window.getComputedStyle(doc).fontSize;
+      rootFontSize = parseFloat(fontSize);
+    }
+    return rootFontSize;
+  }
+  function convertRem(value) {
+    value = value.replace(/rem/g, "");
+    return +value * getRootFontSize();
+  }
+  function convertVw(value) {
+    value = value.replace(/vw/g, "");
+    return +value * windowWidth.value / 100;
+  }
+  function convertVh(value) {
+    value = value.replace(/vh/g, "");
+    return +value * windowHeight.value / 100;
+  }
+  function unitToPx(value) {
+    if (typeof value === "number") {
+      return value;
+    }
+    if (inBrowser$1) {
+      if (value.includes("rem")) {
+        return convertRem(value);
+      }
+      if (value.includes("vw")) {
+        return convertVw(value);
+      }
+      if (value.includes("vh")) {
+        return convertVh(value);
+      }
+    }
+    return parseFloat(value);
+  }
+  const camelizeRE = /-(\w)/g;
+  const camelize = (str) => str.replace(camelizeRE, (_, c) => c.toUpperCase());
+  const kebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
+  function padZero(num, targetLength = 2) {
+    let str = num + "";
+    while (str.length < targetLength) {
+      str = "0" + str;
+    }
+    return str;
+  }
+  const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
+  function trimExtraChar(value, char, regExp) {
+    const index = value.indexOf(char);
+    if (index === -1) {
+      return value;
+    }
+    if (char === "-" && index !== 0) {
+      return value.slice(0, index);
+    }
+    return value.slice(0, index + 1) + value.slice(index).replace(regExp, "");
+  }
+  function formatNumber(value, allowDot = true, allowMinus = true) {
+    if (allowDot) {
+      value = trimExtraChar(value, ".", /\./g);
+    } else {
+      value = value.split(".")[0];
+    }
+    if (allowMinus) {
+      value = trimExtraChar(value, "-", /-/g);
+    } else {
+      value = value.replace(/-/, "");
+    }
+    const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g;
+    return value.replace(regExp, "");
+  }
+  function addNumber(num1, num2) {
+    const cardinal = 10 ** 10;
+    return Math.round((num1 + num2) * cardinal) / cardinal;
+  }
+  const { hasOwnProperty } = Object.prototype;
+  function assignKey(to, from, key) {
+    const val = from[key];
+    if (!isDef(val)) {
+      return;
+    }
+    if (!hasOwnProperty.call(to, key) || !isObject(val)) {
+      to[key] = val;
+    } else {
+      to[key] = deepAssign(Object(to[key]), val);
+    }
+  }
+  function deepAssign(to, from) {
+    Object.keys(from).forEach((key) => {
+      assignKey(to, from, key);
+    });
+    return to;
+  }
+  var stdin_default$1O = {
+    name: "姓名",
+    tel: "电话",
+    save: "保存",
+    confirm: "确认",
+    cancel: "取消",
+    delete: "删除",
+    loading: "加载中...",
+    noCoupon: "暂无优惠券",
+    nameEmpty: "请填写姓名",
+    addContact: "添加联系人",
+    telInvalid: "请填写正确的电话",
+    vanCalendar: {
+      end: "结束",
+      start: "开始",
+      title: "日期选择",
+      weekdays: ["日", "一", "二", "三", "四", "五", "六"],
+      monthTitle: (year, month) => `${year}年${month}月`,
+      rangePrompt: (maxRange) => `最多选择 ${maxRange} 天`
+    },
+    vanCascader: {
+      select: "请选择"
+    },
+    vanPagination: {
+      prev: "上一页",
+      next: "下一页"
+    },
+    vanPullRefresh: {
+      pulling: "下拉即可刷新...",
+      loosing: "释放即可刷新..."
+    },
+    vanSubmitBar: {
+      label: "合计:"
+    },
+    vanCoupon: {
+      unlimited: "无门槛",
+      discount: (discount) => `${discount}折`,
+      condition: (condition) => `满${condition}元可用`
+    },
+    vanCouponCell: {
+      title: "优惠券",
+      count: (count) => `${count}张可用`
+    },
+    vanCouponList: {
+      exchange: "兑换",
+      close: "不使用",
+      enable: "可用",
+      disabled: "不可用",
+      placeholder: "输入优惠码"
+    },
+    vanAddressEdit: {
+      area: "地区",
+      areaEmpty: "请选择地区",
+      addressEmpty: "请填写详细地址",
+      addressDetail: "详细地址",
+      defaultAddress: "设为默认收货地址"
+    },
+    vanAddressList: {
+      add: "新增地址"
+    }
+  };
+  const lang = vue.ref("zh-CN");
+  const messages = vue.reactive({
+    "zh-CN": stdin_default$1O
+  });
+  const Locale = {
+    messages() {
+      return messages[lang.value];
+    },
+    use(newLang, newMessages) {
+      lang.value = newLang;
+      this.add({ [newLang]: newMessages });
+    },
+    add(newMessages = {}) {
+      deepAssign(messages, newMessages);
+    }
+  };
+  const useCurrentLang = () => lang;
+  var stdin_default$1N = Locale;
+  function createTranslate(name2) {
+    const prefix = camelize(name2) + ".";
+    return (path, ...args) => {
+      const messages2 = stdin_default$1N.messages();
+      const message = get(messages2, prefix + path) || get(messages2, path);
+      return isFunction(message) ? message(...args) : message;
+    };
+  }
+  function genBem(name2, mods) {
+    if (!mods) {
+      return "";
+    }
+    if (typeof mods === "string") {
+      return ` ${name2}--${mods}`;
+    }
+    if (Array.isArray(mods)) {
+      return mods.reduce(
+        (ret, item) => ret + genBem(name2, item),
+        ""
+      );
+    }
+    return Object.keys(mods).reduce(
+      (ret, key) => ret + (mods[key] ? genBem(name2, key) : ""),
+      ""
+    );
+  }
+  function createBEM(name2) {
+    return (el, mods) => {
+      if (el && typeof el !== "string") {
+        mods = el;
+        el = "";
+      }
+      el = el ? `${name2}__${el}` : name2;
+      return `${el}${genBem(el, mods)}`;
+    };
+  }
+  function createNamespace(name2) {
+    const prefixedName = `van-${name2}`;
+    return [
+      prefixedName,
+      createBEM(prefixedName),
+      createTranslate(prefixedName)
+    ];
+  }
+  const BORDER = "van-hairline";
+  const BORDER_TOP = `${BORDER}--top`;
+  const BORDER_LEFT = `${BORDER}--left`;
+  const BORDER_BOTTOM = `${BORDER}--bottom`;
+  const BORDER_SURROUND = `${BORDER}--surround`;
+  const BORDER_TOP_BOTTOM = `${BORDER}--top-bottom`;
+  const BORDER_UNSET_TOP_BOTTOM = `${BORDER}-unset--top-bottom`;
+  const HAPTICS_FEEDBACK = "van-haptics-feedback";
+  const FORM_KEY = Symbol("van-form");
+  const LONG_PRESS_START_TIME = 500;
+  function callInterceptor(interceptor, {
+    args = [],
+    done,
+    canceled
+  }) {
+    if (interceptor) {
+      const returnVal = interceptor.apply(null, args);
+      if (isPromise(returnVal)) {
+        returnVal.then((value) => {
+          if (value) {
+            done();
+          } else if (canceled) {
+            canceled();
+          }
+        }).catch(noop);
+      } else if (returnVal) {
+        done();
+      } else if (canceled) {
+        canceled();
+      }
+    } else {
+      done();
+    }
+  }
+  function withInstall(options) {
+    options.install = (app) => {
+      const { name: name2 } = options;
+      if (name2) {
+        app.component(name2, options);
+        app.component(camelize(`-${name2}`), options);
+      }
+    };
+    return options;
+  }
+  const POPUP_TOGGLE_KEY = Symbol();
+  function onPopupReopen(callback) {
+    const popupToggleStatus = vue.inject(POPUP_TOGGLE_KEY, null);
+    if (popupToggleStatus) {
+      vue.watch(popupToggleStatus, (show) => {
+        if (show) {
+          callback();
+        }
+      });
+    }
+  }
+  const useHeight = (element, withSafeArea) => {
+    const height2 = vue.ref();
+    const setHeight = () => {
+      height2.value = useRect(element).height;
+    };
+    vue.onMounted(() => {
+      vue.nextTick(setHeight);
+      if (withSafeArea) {
+        for (let i = 1; i <= 3; i++) {
+          setTimeout(setHeight, 100 * i);
+        }
+      }
+    });
+    onPopupReopen(() => vue.nextTick(setHeight));
+    vue.watch([windowWidth, windowHeight], setHeight);
+    return height2;
+  };
+  function usePlaceholder(contentRef, bem2) {
+    const height2 = useHeight(contentRef, true);
+    return (renderContent) => vue.createVNode("div", {
+      "class": bem2("placeholder"),
+      "style": {
+        height: height2.value ? `${height2.value}px` : void 0
+      }
+    }, [renderContent()]);
+  }
+  const [name$1C, bem$1x] = createNamespace("action-bar");
+  const ACTION_BAR_KEY = Symbol(name$1C);
+  const actionBarProps = {
+    placeholder: Boolean,
+    safeAreaInsetBottom: truthProp
+  };
+  var stdin_default$1M = vue.defineComponent({
+    name: name$1C,
+    props: actionBarProps,
+    setup(props, {
+      slots
+    }) {
+      const root = vue.ref();
+      const renderPlaceholder = usePlaceholder(root, bem$1x);
+      const {
+        linkChildren
+      } = useChildren(ACTION_BAR_KEY);
+      linkChildren();
+      const renderActionBar = () => {
+        var _a;
+        return vue.createVNode("div", {
+          "ref": root,
+          "class": [bem$1x(), {
+            "van-safe-area-bottom": props.safeAreaInsetBottom
+          }]
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+      return () => {
+        if (props.placeholder) {
+          return renderPlaceholder(renderActionBar);
+        }
+        return renderActionBar();
+      };
+    }
+  });
+  const ActionBar = withInstall(stdin_default$1M);
+  function useExpose(apis) {
+    const instance2 = vue.getCurrentInstance();
+    if (instance2) {
+      extend(instance2.proxy, apis);
+    }
+  }
+  const routeProps = {
+    to: [String, Object],
+    url: String,
+    replace: Boolean
+  };
+  function route({
+    to,
+    url,
+    replace,
+    $router: router
+  }) {
+    if (to && router) {
+      router[replace ? "replace" : "push"](to);
+    } else if (url) {
+      replace ? location.replace(url) : location.href = url;
+    }
+  }
+  function useRoute() {
+    const vm = vue.getCurrentInstance().proxy;
+    return () => route(vm);
+  }
+  const [name$1B, bem$1w] = createNamespace("badge");
+  const badgeProps = {
+    dot: Boolean,
+    max: numericProp,
+    tag: makeStringProp("div"),
+    color: String,
+    offset: Array,
+    content: numericProp,
+    showZero: truthProp,
+    position: makeStringProp("top-right")
+  };
+  var stdin_default$1L = vue.defineComponent({
+    name: name$1B,
+    props: badgeProps,
+    setup(props, {
+      slots
+    }) {
+      const hasContent = () => {
+        if (slots.content) {
+          return true;
+        }
+        const {
+          content,
+          showZero
+        } = props;
+        return isDef(content) && content !== "" && (showZero || content !== 0 && content !== "0");
+      };
+      const renderContent = () => {
+        const {
+          dot,
+          max,
+          content
+        } = props;
+        if (!dot && hasContent()) {
+          if (slots.content) {
+            return slots.content();
+          }
+          if (isDef(max) && isNumeric(content) && +content > +max) {
+            return `${max}+`;
+          }
+          return content;
+        }
+      };
+      const getOffsetWithMinusString = (val) => val.startsWith("-") ? val.replace("-", "") : `-${val}`;
+      const style = vue.computed(() => {
+        const style2 = {
+          background: props.color
+        };
+        if (props.offset) {
+          const [x, y] = props.offset;
+          const {
+            position
+          } = props;
+          const [offsetY, offsetX] = position.split("-");
+          if (slots.default) {
+            if (typeof y === "number") {
+              style2[offsetY] = addUnit(offsetY === "top" ? y : -y);
+            } else {
+              style2[offsetY] = offsetY === "top" ? addUnit(y) : getOffsetWithMinusString(y);
+            }
+            if (typeof x === "number") {
+              style2[offsetX] = addUnit(offsetX === "left" ? x : -x);
+            } else {
+              style2[offsetX] = offsetX === "left" ? addUnit(x) : getOffsetWithMinusString(x);
+            }
+          } else {
+            style2.marginTop = addUnit(y);
+            style2.marginLeft = addUnit(x);
+          }
+        }
+        return style2;
+      });
+      const renderBadge = () => {
+        if (hasContent() || props.dot) {
+          return vue.createVNode("div", {
+            "class": bem$1w([props.position, {
+              dot: props.dot,
+              fixed: !!slots.default
+            }]),
+            "style": style.value
+          }, [renderContent()]);
+        }
+      };
+      return () => {
+        if (slots.default) {
+          const {
+            tag
+          } = props;
+          return vue.createVNode(tag, {
+            "class": bem$1w("wrapper")
+          }, {
+            default: () => [slots.default(), renderBadge()]
+          });
+        }
+        return renderBadge();
+      };
+    }
+  });
+  const Badge = withInstall(stdin_default$1L);
+  let globalZIndex = 2e3;
+  const useGlobalZIndex = () => ++globalZIndex;
+  const setGlobalZIndex = (val) => {
+    globalZIndex = val;
+  };
+  const [name$1A, bem$1v] = createNamespace("config-provider");
+  const CONFIG_PROVIDER_KEY = Symbol(name$1A);
+  const configProviderProps = {
+    tag: makeStringProp("div"),
+    theme: makeStringProp("light"),
+    zIndex: Number,
+    themeVars: Object,
+    themeVarsDark: Object,
+    themeVarsLight: Object,
+    iconPrefix: String
+  };
+  function mapThemeVarsToCSSVars(themeVars) {
+    const cssVars = {};
+    Object.keys(themeVars).forEach((key) => {
+      cssVars[`--van-${kebabCase(key)}`] = themeVars[key];
+    });
+    return cssVars;
+  }
+  var stdin_default$1K = vue.defineComponent({
+    name: name$1A,
+    props: configProviderProps,
+    setup(props, {
+      slots
+    }) {
+      const style = vue.computed(() => mapThemeVarsToCSSVars(extend({}, props.themeVars, props.theme === "dark" ? props.themeVarsDark : props.themeVarsLight)));
+      if (inBrowser$1) {
+        const addTheme = () => {
+          document.documentElement.classList.add(`van-theme-${props.theme}`);
+        };
+        const removeTheme = (theme = props.theme) => {
+          document.documentElement.classList.remove(`van-theme-${theme}`);
+        };
+        vue.watch(() => props.theme, (newVal, oldVal) => {
+          if (oldVal) {
+            removeTheme(oldVal);
+          }
+          addTheme();
+        }, {
+          immediate: true
+        });
+        vue.onActivated(addTheme);
+        vue.onDeactivated(removeTheme);
+        vue.onBeforeUnmount(removeTheme);
+      }
+      vue.provide(CONFIG_PROVIDER_KEY, props);
+      vue.watchEffect(() => {
+        if (props.zIndex !== void 0) {
+          setGlobalZIndex(props.zIndex);
+        }
+      });
+      return () => vue.createVNode(props.tag, {
+        "class": bem$1v(),
+        "style": style.value
+      }, {
+        default: () => {
+          var _a;
+          return [(_a = slots.default) == null ? void 0 : _a.call(slots)];
+        }
+      });
+    }
+  });
+  const [name$1z, bem$1u] = createNamespace("icon");
+  const isImage = (name2) => name2 == null ? void 0 : name2.includes("/");
+  const iconProps = {
+    dot: Boolean,
+    tag: makeStringProp("i"),
+    name: String,
+    size: numericProp,
+    badge: numericProp,
+    color: String,
+    badgeProps: Object,
+    classPrefix: String
+  };
+  var stdin_default$1J = vue.defineComponent({
+    name: name$1z,
+    props: iconProps,
+    setup(props, {
+      slots
+    }) {
+      const config = vue.inject(CONFIG_PROVIDER_KEY, null);
+      const classPrefix = vue.computed(() => props.classPrefix || (config == null ? void 0 : config.iconPrefix) || bem$1u());
+      return () => {
+        const {
+          tag,
+          dot,
+          name: name2,
+          size,
+          badge,
+          color
+        } = props;
+        const isImageIcon = isImage(name2);
+        return vue.createVNode(Badge, vue.mergeProps({
+          "dot": dot,
+          "tag": tag,
+          "class": [classPrefix.value, isImageIcon ? "" : `${classPrefix.value}-${name2}`],
+          "style": {
+            color,
+            fontSize: addUnit(size)
+          },
+          "content": badge
+        }, props.badgeProps), {
+          default: () => {
+            var _a;
+            return [(_a = slots.default) == null ? void 0 : _a.call(slots), isImageIcon && vue.createVNode("img", {
+              "class": bem$1u("image"),
+              "src": name2
+            }, null)];
+          }
+        });
+      };
+    }
+  });
+  const Icon = withInstall(stdin_default$1J);
+  const [name$1y, bem$1t] = createNamespace("loading");
+  const SpinIcon = Array(12).fill(null).map((_, index) => vue.createVNode("i", {
+    "class": bem$1t("line", String(index + 1))
+  }, null));
+  const CircularIcon = vue.createVNode("svg", {
+    "class": bem$1t("circular"),
+    "viewBox": "25 25 50 50"
+  }, [vue.createVNode("circle", {
+    "cx": "50",
+    "cy": "50",
+    "r": "20",
+    "fill": "none"
+  }, null)]);
+  const loadingProps = {
+    size: numericProp,
+    type: makeStringProp("circular"),
+    color: String,
+    vertical: Boolean,
+    textSize: numericProp,
+    textColor: String
+  };
+  var stdin_default$1I = vue.defineComponent({
+    name: name$1y,
+    props: loadingProps,
+    setup(props, {
+      slots
+    }) {
+      const spinnerStyle = vue.computed(() => extend({
+        color: props.color
+      }, getSizeStyle(props.size)));
+      const renderIcon = () => {
+        const DefaultIcon = props.type === "spinner" ? SpinIcon : CircularIcon;
+        return vue.createVNode("span", {
+          "class": bem$1t("spinner", props.type),
+          "style": spinnerStyle.value
+        }, [slots.icon ? slots.icon() : DefaultIcon]);
+      };
+      const renderText = () => {
+        var _a;
+        if (slots.default) {
+          return vue.createVNode("span", {
+            "class": bem$1t("text"),
+            "style": {
+              fontSize: addUnit(props.textSize),
+              color: (_a = props.textColor) != null ? _a : props.color
+            }
+          }, [slots.default()]);
+        }
+      };
+      return () => {
+        const {
+          type,
+          vertical
+        } = props;
+        return vue.createVNode("div", {
+          "class": bem$1t([type, {
+            vertical
+          }]),
+          "aria-live": "polite",
+          "aria-busy": true
+        }, [renderIcon(), renderText()]);
+      };
+    }
+  });
+  const Loading = withInstall(stdin_default$1I);
+  const [name$1x, bem$1s] = createNamespace("button");
+  const buttonProps = extend({}, routeProps, {
+    tag: makeStringProp("button"),
+    text: String,
+    icon: String,
+    type: makeStringProp("default"),
+    size: makeStringProp("normal"),
+    color: String,
+    block: Boolean,
+    plain: Boolean,
+    round: Boolean,
+    square: Boolean,
+    loading: Boolean,
+    hairline: Boolean,
+    disabled: Boolean,
+    iconPrefix: String,
+    nativeType: makeStringProp("button"),
+    loadingSize: numericProp,
+    loadingText: String,
+    loadingType: String,
+    iconPosition: makeStringProp("left")
+  });
+  var stdin_default$1H = vue.defineComponent({
+    name: name$1x,
+    props: buttonProps,
+    emits: ["click"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const route2 = useRoute();
+      const renderLoadingIcon = () => {
+        if (slots.loading) {
+          return slots.loading();
+        }
+        return vue.createVNode(Loading, {
+          "size": props.loadingSize,
+          "type": props.loadingType,
+          "class": bem$1s("loading")
+        }, null);
+      };
+      const renderIcon = () => {
+        if (props.loading) {
+          return renderLoadingIcon();
+        }
+        if (slots.icon) {
+          return vue.createVNode("div", {
+            "class": bem$1s("icon")
+          }, [slots.icon()]);
+        }
+        if (props.icon) {
+          return vue.createVNode(Icon, {
+            "name": props.icon,
+            "class": bem$1s("icon"),
+            "classPrefix": props.iconPrefix
+          }, null);
+        }
+      };
+      const renderText = () => {
+        let text;
+        if (props.loading) {
+          text = props.loadingText;
+        } else {
+          text = slots.default ? slots.default() : props.text;
+        }
+        if (text) {
+          return vue.createVNode("span", {
+            "class": bem$1s("text")
+          }, [text]);
+        }
+      };
+      const getStyle = () => {
+        const {
+          color,
+          plain
+        } = props;
+        if (color) {
+          const style = {
+            color: plain ? color : "white"
+          };
+          if (!plain) {
+            style.background = color;
+          }
+          if (color.includes("gradient")) {
+            style.border = 0;
+          } else {
+            style.borderColor = color;
+          }
+          return style;
+        }
+      };
+      const onClick = (event) => {
+        if (props.loading) {
+          preventDefault(event);
+        } else if (!props.disabled) {
+          emit("click", event);
+          route2();
+        }
+      };
+      return () => {
+        const {
+          tag,
+          type,
+          size,
+          block,
+          round: round2,
+          plain,
+          square,
+          loading,
+          disabled,
+          hairline,
+          nativeType,
+          iconPosition
+        } = props;
+        const classes = [bem$1s([type, size, {
+          plain,
+          block,
+          round: round2,
+          square,
+          loading,
+          disabled,
+          hairline
+        }]), {
+          [BORDER_SURROUND]: hairline
+        }];
+        return vue.createVNode(tag, {
+          "type": nativeType,
+          "class": classes,
+          "style": getStyle(),
+          "disabled": disabled,
+          "onClick": onClick
+        }, {
+          default: () => [vue.createVNode("div", {
+            "class": bem$1s("content")
+          }, [iconPosition === "left" && renderIcon(), renderText(), iconPosition === "right" && renderIcon()])]
+        });
+      };
+    }
+  });
+  const Button = withInstall(stdin_default$1H);
+  const [name$1w, bem$1r] = createNamespace("action-bar-button");
+  const actionBarButtonProps = extend({}, routeProps, {
+    type: String,
+    text: String,
+    icon: String,
+    color: String,
+    loading: Boolean,
+    disabled: Boolean
+  });
+  var stdin_default$1G = vue.defineComponent({
+    name: name$1w,
+    props: actionBarButtonProps,
+    setup(props, {
+      slots
+    }) {
+      const route2 = useRoute();
+      const {
+        parent,
+        index
+      } = useParent(ACTION_BAR_KEY);
+      const isFirst = vue.computed(() => {
+        if (parent) {
+          const prev = parent.children[index.value - 1];
+          return !(prev && "isButton" in prev);
+        }
+      });
+      const isLast = vue.computed(() => {
+        if (parent) {
+          const next = parent.children[index.value + 1];
+          return !(next && "isButton" in next);
+        }
+      });
+      useExpose({
+        isButton: true
+      });
+      return () => {
+        const {
+          type,
+          icon,
+          text,
+          color,
+          loading,
+          disabled
+        } = props;
+        return vue.createVNode(Button, {
+          "class": bem$1r([type, {
+            last: isLast.value,
+            first: isFirst.value
+          }]),
+          "size": "large",
+          "type": type,
+          "icon": icon,
+          "color": color,
+          "loading": loading,
+          "disabled": disabled,
+          "onClick": route2
+        }, {
+          default: () => [slots.default ? slots.default() : text]
+        });
+      };
+    }
+  });
+  const ActionBarButton = withInstall(stdin_default$1G);
+  const [name$1v, bem$1q] = createNamespace("action-bar-icon");
+  const actionBarIconProps = extend({}, routeProps, {
+    dot: Boolean,
+    text: String,
+    icon: String,
+    color: String,
+    badge: numericProp,
+    iconClass: unknownProp,
+    badgeProps: Object,
+    iconPrefix: String
+  });
+  var stdin_default$1F = vue.defineComponent({
+    name: name$1v,
+    props: actionBarIconProps,
+    setup(props, {
+      slots
+    }) {
+      const route2 = useRoute();
+      useParent(ACTION_BAR_KEY);
+      const renderIcon = () => {
+        const {
+          dot,
+          badge,
+          icon,
+          color,
+          iconClass,
+          badgeProps: badgeProps2,
+          iconPrefix
+        } = props;
+        if (slots.icon) {
+          return vue.createVNode(Badge, vue.mergeProps({
+            "dot": dot,
+            "class": bem$1q("icon"),
+            "content": badge
+          }, badgeProps2), {
+            default: slots.icon
+          });
+        }
+        return vue.createVNode(Icon, {
+          "tag": "div",
+          "dot": dot,
+          "name": icon,
+          "badge": badge,
+          "color": color,
+          "class": [bem$1q("icon"), iconClass],
+          "badgeProps": badgeProps2,
+          "classPrefix": iconPrefix
+        }, null);
+      };
+      return () => vue.createVNode("div", {
+        "role": "button",
+        "class": bem$1q(),
+        "tabindex": 0,
+        "onClick": route2
+      }, [renderIcon(), slots.default ? slots.default() : props.text]);
+    }
+  });
+  const ActionBarIcon = withInstall(stdin_default$1F);
+  const popupSharedProps = {
+    // whether to show popup
+    show: Boolean,
+    // z-index
+    zIndex: numericProp,
+    // whether to show overlay
+    overlay: truthProp,
+    // transition duration
+    duration: numericProp,
+    // teleport
+    teleport: [String, Object],
+    // prevent body scroll
+    lockScroll: truthProp,
+    // whether to lazy render
+    lazyRender: truthProp,
+    // callback function before close
+    beforeClose: Function,
+    // overlay custom style
+    overlayStyle: Object,
+    // overlay custom class name
+    overlayClass: unknownProp,
+    // Initial rendering animation
+    transitionAppear: Boolean,
+    // whether to close popup when overlay is clicked
+    closeOnClickOverlay: truthProp
+  };
+  const popupSharedPropKeys = Object.keys(
+    popupSharedProps
+  );
+  function getDirection(x, y) {
+    if (x > y) {
+      return "horizontal";
+    }
+    if (y > x) {
+      return "vertical";
+    }
+    return "";
+  }
+  function useTouch() {
+    const startX = vue.ref(0);
+    const startY = vue.ref(0);
+    const deltaX = vue.ref(0);
+    const deltaY = vue.ref(0);
+    const offsetX = vue.ref(0);
+    const offsetY = vue.ref(0);
+    const direction = vue.ref("");
+    const isVertical = () => direction.value === "vertical";
+    const isHorizontal = () => direction.value === "horizontal";
+    const reset = () => {
+      deltaX.value = 0;
+      deltaY.value = 0;
+      offsetX.value = 0;
+      offsetY.value = 0;
+      direction.value = "";
+    };
+    const start2 = (event) => {
+      reset();
+      startX.value = event.touches[0].clientX;
+      startY.value = event.touches[0].clientY;
+    };
+    const move = (event) => {
+      const touch = event.touches[0];
+      deltaX.value = (touch.clientX < 0 ? 0 : touch.clientX) - startX.value;
+      deltaY.value = touch.clientY - startY.value;
+      offsetX.value = Math.abs(deltaX.value);
+      offsetY.value = Math.abs(deltaY.value);
+      const LOCK_DIRECTION_DISTANCE = 10;
+      if (!direction.value || offsetX.value < LOCK_DIRECTION_DISTANCE && offsetY.value < LOCK_DIRECTION_DISTANCE) {
+        direction.value = getDirection(offsetX.value, offsetY.value);
+      }
+    };
+    return {
+      move,
+      start: start2,
+      reset,
+      startX,
+      startY,
+      deltaX,
+      deltaY,
+      offsetX,
+      offsetY,
+      direction,
+      isVertical,
+      isHorizontal
+    };
+  }
+  let totalLockCount = 0;
+  const BODY_LOCK_CLASS = "van-overflow-hidden";
+  function useLockScroll(rootRef, shouldLock) {
+    const touch = useTouch();
+    const DIRECTION_UP = "01";
+    const DIRECTION_DOWN = "10";
+    const onTouchMove = (event) => {
+      touch.move(event);
+      const direction = touch.deltaY.value > 0 ? DIRECTION_DOWN : DIRECTION_UP;
+      const el = getScrollParent$1(
+        event.target,
+        rootRef.value
+      );
+      const { scrollHeight, offsetHeight, scrollTop } = el;
+      let status = "11";
+      if (scrollTop === 0) {
+        status = offsetHeight >= scrollHeight ? "00" : "01";
+      } else if (scrollTop + offsetHeight >= scrollHeight) {
+        status = "10";
+      }
+      if (status !== "11" && touch.isVertical() && !(parseInt(status, 2) & parseInt(direction, 2))) {
+        preventDefault(event, true);
+      }
+    };
+    const lock = () => {
+      document.addEventListener("touchstart", touch.start);
+      document.addEventListener("touchmove", onTouchMove, { passive: false });
+      if (!totalLockCount) {
+        document.body.classList.add(BODY_LOCK_CLASS);
+      }
+      totalLockCount++;
+    };
+    const unlock = () => {
+      if (totalLockCount) {
+        document.removeEventListener("touchstart", touch.start);
+        document.removeEventListener("touchmove", onTouchMove);
+        totalLockCount--;
+        if (!totalLockCount) {
+          document.body.classList.remove(BODY_LOCK_CLASS);
+        }
+      }
+    };
+    const init = () => shouldLock() && lock();
+    const destroy = () => shouldLock() && unlock();
+    onMountedOrActivated(init);
+    vue.onDeactivated(destroy);
+    vue.onBeforeUnmount(destroy);
+    vue.watch(shouldLock, (value) => {
+      value ? lock() : unlock();
+    });
+  }
+  function useLazyRender(show) {
+    const inited = vue.ref(false);
+    vue.watch(
+      show,
+      (value) => {
+        if (value) {
+          inited.value = value;
+        }
+      },
+      { immediate: true }
+    );
+    return (render) => () => inited.value ? render() : null;
+  }
+  const [name$1u, bem$1p] = createNamespace("overlay");
+  const overlayProps = {
+    show: Boolean,
+    zIndex: numericProp,
+    duration: numericProp,
+    className: unknownProp,
+    lockScroll: truthProp,
+    lazyRender: truthProp,
+    customStyle: Object
+  };
+  var stdin_default$1E = vue.defineComponent({
+    name: name$1u,
+    props: overlayProps,
+    setup(props, {
+      slots
+    }) {
+      const root = vue.ref();
+      const lazyRender = useLazyRender(() => props.show || !props.lazyRender);
+      const onTouchMove = (event) => {
+        if (props.lockScroll) {
+          preventDefault(event, true);
+        }
+      };
+      const renderOverlay = lazyRender(() => {
+        var _a;
+        const style = extend(getZIndexStyle(props.zIndex), props.customStyle);
+        if (isDef(props.duration)) {
+          style.animationDuration = `${props.duration}s`;
+        }
+        return vue.withDirectives(vue.createVNode("div", {
+          "ref": root,
+          "style": style,
+          "class": [bem$1p(), props.className]
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), [[vue.vShow, props.show]]);
+      });
+      useEventListener("touchmove", onTouchMove, {
+        target: root
+      });
+      return () => vue.createVNode(vue.Transition, {
+        "name": "van-fade",
+        "appear": true
+      }, {
+        default: renderOverlay
+      });
+    }
+  });
+  const Overlay = withInstall(stdin_default$1E);
+  const popupProps$2 = extend({}, popupSharedProps, {
+    round: Boolean,
+    position: makeStringProp("center"),
+    closeIcon: makeStringProp("cross"),
+    closeable: Boolean,
+    transition: String,
+    iconPrefix: String,
+    closeOnPopstate: Boolean,
+    closeIconPosition: makeStringProp("top-right"),
+    safeAreaInsetTop: Boolean,
+    safeAreaInsetBottom: Boolean
+  });
+  const [name$1t, bem$1o] = createNamespace("popup");
+  var stdin_default$1D = vue.defineComponent({
+    name: name$1t,
+    inheritAttrs: false,
+    props: popupProps$2,
+    emits: ["open", "close", "opened", "closed", "keydown", "update:show", "clickOverlay", "clickCloseIcon"],
+    setup(props, {
+      emit,
+      attrs,
+      slots
+    }) {
+      let opened;
+      let shouldReopen;
+      const zIndex = vue.ref();
+      const popupRef = vue.ref();
+      const lazyRender = useLazyRender(() => props.show || !props.lazyRender);
+      const style = vue.computed(() => {
+        const style2 = {
+          zIndex: zIndex.value
+        };
+        if (isDef(props.duration)) {
+          const key = props.position === "center" ? "animationDuration" : "transitionDuration";
+          style2[key] = `${props.duration}s`;
+        }
+        return style2;
+      });
+      const open = () => {
+        if (!opened) {
+          opened = true;
+          zIndex.value = props.zIndex !== void 0 ? +props.zIndex : useGlobalZIndex();
+          emit("open");
+        }
+      };
+      const close = () => {
+        if (opened) {
+          callInterceptor(props.beforeClose, {
+            done() {
+              opened = false;
+              emit("close");
+              emit("update:show", false);
+            }
+          });
+        }
+      };
+      const onClickOverlay = (event) => {
+        emit("clickOverlay", event);
+        if (props.closeOnClickOverlay) {
+          close();
+        }
+      };
+      const renderOverlay = () => {
+        if (props.overlay) {
+          return vue.createVNode(Overlay, {
+            "show": props.show,
+            "class": props.overlayClass,
+            "zIndex": zIndex.value,
+            "duration": props.duration,
+            "customStyle": props.overlayStyle,
+            "role": props.closeOnClickOverlay ? "button" : void 0,
+            "tabindex": props.closeOnClickOverlay ? 0 : void 0,
+            "onClick": onClickOverlay
+          }, {
+            default: slots["overlay-content"]
+          });
+        }
+      };
+      const onClickCloseIcon = (event) => {
+        emit("clickCloseIcon", event);
+        close();
+      };
+      const renderCloseIcon = () => {
+        if (props.closeable) {
+          return vue.createVNode(Icon, {
+            "role": "button",
+            "tabindex": 0,
+            "name": props.closeIcon,
+            "class": [bem$1o("close-icon", props.closeIconPosition), HAPTICS_FEEDBACK],
+            "classPrefix": props.iconPrefix,
+            "onClick": onClickCloseIcon
+          }, null);
+        }
+      };
+      const onOpened = () => emit("opened");
+      const onClosed = () => emit("closed");
+      const onKeydown = (event) => emit("keydown", event);
+      const renderPopup = lazyRender(() => {
+        var _a;
+        const {
+          round: round2,
+          position,
+          safeAreaInsetTop,
+          safeAreaInsetBottom
+        } = props;
+        return vue.withDirectives(vue.createVNode("div", vue.mergeProps({
+          "ref": popupRef,
+          "style": style.value,
+          "role": "dialog",
+          "tabindex": 0,
+          "class": [bem$1o({
+            round: round2,
+            [position]: position
+          }), {
+            "van-safe-area-top": safeAreaInsetTop,
+            "van-safe-area-bottom": safeAreaInsetBottom
+          }],
+          "onKeydown": onKeydown
+        }, attrs), [(_a = slots.default) == null ? void 0 : _a.call(slots), renderCloseIcon()]), [[vue.vShow, props.show]]);
+      });
+      const renderTransition = () => {
+        const {
+          position,
+          transition,
+          transitionAppear
+        } = props;
+        const name2 = position === "center" ? "van-fade" : `van-popup-slide-${position}`;
+        return vue.createVNode(vue.Transition, {
+          "name": transition || name2,
+          "appear": transitionAppear,
+          "onAfterEnter": onOpened,
+          "onAfterLeave": onClosed
+        }, {
+          default: renderPopup
+        });
+      };
+      vue.watch(() => props.show, (show) => {
+        if (show && !opened) {
+          open();
+          if (attrs.tabindex === 0) {
+            vue.nextTick(() => {
+              var _a;
+              (_a = popupRef.value) == null ? void 0 : _a.focus();
+            });
+          }
+        }
+        if (!show && opened) {
+          opened = false;
+          emit("close");
+        }
+      });
+      useExpose({
+        popupRef
+      });
+      useLockScroll(popupRef, () => props.show && props.lockScroll);
+      useEventListener("popstate", () => {
+        if (props.closeOnPopstate) {
+          close();
+          shouldReopen = false;
+        }
+      });
+      vue.onMounted(() => {
+        if (props.show) {
+          open();
+        }
+      });
+      vue.onActivated(() => {
+        if (shouldReopen) {
+          emit("update:show", true);
+          shouldReopen = false;
+        }
+      });
+      vue.onDeactivated(() => {
+        if (props.show && props.teleport) {
+          close();
+          shouldReopen = true;
+        }
+      });
+      vue.provide(POPUP_TOGGLE_KEY, () => props.show);
+      return () => {
+        if (props.teleport) {
+          return vue.createVNode(vue.Teleport, {
+            "to": props.teleport
+          }, {
+            default: () => [renderOverlay(), renderTransition()]
+          });
+        }
+        return vue.createVNode(vue.Fragment, null, [renderOverlay(), renderTransition()]);
+      };
+    }
+  });
+  const Popup = withInstall(stdin_default$1D);
+  const [name$1s, bem$1n] = createNamespace("action-sheet");
+  const actionSheetProps = extend({}, popupSharedProps, {
+    title: String,
+    round: truthProp,
+    actions: makeArrayProp(),
+    closeIcon: makeStringProp("cross"),
+    closeable: truthProp,
+    cancelText: String,
+    description: String,
+    closeOnPopstate: truthProp,
+    closeOnClickAction: Boolean,
+    safeAreaInsetBottom: truthProp
+  });
+  const popupInheritKeys$2 = [...popupSharedPropKeys, "round", "closeOnPopstate", "safeAreaInsetBottom"];
+  var stdin_default$1C = vue.defineComponent({
+    name: name$1s,
+    props: actionSheetProps,
+    emits: ["select", "cancel", "update:show"],
+    setup(props, {
+      slots,
+      emit
+    }) {
+      const updateShow = (show) => emit("update:show", show);
+      const onCancel = () => {
+        updateShow(false);
+        emit("cancel");
+      };
+      const renderHeader = () => {
+        if (props.title) {
+          return vue.createVNode("div", {
+            "class": bem$1n("header")
+          }, [props.title, props.closeable && vue.createVNode(Icon, {
+            "name": props.closeIcon,
+            "class": [bem$1n("close"), HAPTICS_FEEDBACK],
+            "onClick": onCancel
+          }, null)]);
+        }
+      };
+      const renderCancel = () => {
+        if (slots.cancel || props.cancelText) {
+          return [vue.createVNode("div", {
+            "class": bem$1n("gap")
+          }, null), vue.createVNode("button", {
+            "type": "button",
+            "class": bem$1n("cancel"),
+            "onClick": onCancel
+          }, [slots.cancel ? slots.cancel() : props.cancelText])];
+        }
+      };
+      const renderActionContent = (action, index) => {
+        if (action.loading) {
+          return vue.createVNode(Loading, {
+            "class": bem$1n("loading-icon")
+          }, null);
+        }
+        if (slots.action) {
+          return slots.action({
+            action,
+            index
+          });
+        }
+        return [vue.createVNode("span", {
+          "class": bem$1n("name")
+        }, [action.name]), action.subname && vue.createVNode("div", {
+          "class": bem$1n("subname")
+        }, [action.subname])];
+      };
+      const renderAction = (action, index) => {
+        const {
+          color,
+          loading,
+          callback,
+          disabled,
+          className
+        } = action;
+        const onClick = () => {
+          if (disabled || loading) {
+            return;
+          }
+          if (callback) {
+            callback(action);
+          }
+          if (props.closeOnClickAction) {
+            updateShow(false);
+          }
+          vue.nextTick(() => emit("select", action, index));
+        };
+        return vue.createVNode("button", {
+          "type": "button",
+          "style": {
+            color
+          },
+          "class": [bem$1n("item", {
+            loading,
+            disabled
+          }), className],
+          "onClick": onClick
+        }, [renderActionContent(action, index)]);
+      };
+      const renderDescription = () => {
+        if (props.description || slots.description) {
+          const content = slots.description ? slots.description() : props.description;
+          return vue.createVNode("div", {
+            "class": bem$1n("description")
+          }, [content]);
+        }
+      };
+      return () => vue.createVNode(Popup, vue.mergeProps({
+        "class": bem$1n(),
+        "position": "bottom",
+        "onUpdate:show": updateShow
+      }, pick(props, popupInheritKeys$2)), {
+        default: () => {
+          var _a;
+          return [renderHeader(), renderDescription(), vue.createVNode("div", {
+            "class": bem$1n("content")
+          }, [props.actions.map(renderAction), (_a = slots.default) == null ? void 0 : _a.call(slots)]), renderCancel()];
+        }
+      });
+    }
+  });
+  const ActionSheet = withInstall(stdin_default$1C);
+  const [name$1r, bem$1m, t$j] = createNamespace("picker");
+  const getFirstEnabledOption = (options) => options.find((option) => !option.disabled) || options[0];
+  function getColumnsType(columns, fields) {
+    const firstColumn = columns[0];
+    if (firstColumn) {
+      if (Array.isArray(firstColumn)) {
+        return "multiple";
+      }
+      if (fields.children in firstColumn) {
+        return "cascade";
+      }
+    }
+    return "default";
+  }
+  function findIndexOfEnabledOption(options, index) {
+    index = clamp(index, 0, options.length);
+    for (let i = index; i < options.length; i++) {
+      if (!options[i].disabled)
+        return i;
+    }
+    for (let i = index - 1; i >= 0; i--) {
+      if (!options[i].disabled)
+        return i;
+    }
+    return 0;
+  }
+  const isOptionExist = (options, value, fields) => value !== void 0 && !!options.find((option) => option[fields.value] === value);
+  function findOptionByValue(options, value, fields) {
+    const index = options.findIndex((option) => option[fields.value] === value);
+    const enabledIndex = findIndexOfEnabledOption(options, index);
+    return options[enabledIndex];
+  }
+  function formatCascadeColumns(columns, fields, selectedValues) {
+    const formatted = [];
+    let cursor = {
+      [fields.children]: columns
+    };
+    let columnIndex = 0;
+    while (cursor && cursor[fields.children]) {
+      const options = cursor[fields.children];
+      const value = selectedValues.value[columnIndex];
+      cursor = isDef(value) ? findOptionByValue(options, value, fields) : void 0;
+      if (!cursor && options.length) {
+        const firstValue = getFirstEnabledOption(options)[fields.value];
+        cursor = findOptionByValue(options, firstValue, fields);
+      }
+      columnIndex++;
+      formatted.push(options);
+    }
+    return formatted;
+  }
+  function getElementTranslateY(element) {
+    const { transform } = window.getComputedStyle(element);
+    const translateY = transform.slice(7, transform.length - 1).split(", ")[5];
+    return Number(translateY);
+  }
+  function assignDefaultFields(fields) {
+    return extend(
+      {
+        text: "text",
+        value: "value",
+        children: "children"
+      },
+      fields
+    );
+  }
+  const DEFAULT_DURATION = 200;
+  const MOMENTUM_TIME = 300;
+  const MOMENTUM_DISTANCE = 15;
+  const [name$1q, bem$1l] = createNamespace("picker-column");
+  const PICKER_KEY = Symbol(name$1q);
+  var stdin_default$1B = vue.defineComponent({
+    name: name$1q,
+    props: {
+      value: numericProp,
+      fields: makeRequiredProp(Object),
+      options: makeArrayProp(),
+      readonly: Boolean,
+      allowHtml: Boolean,
+      optionHeight: makeRequiredProp(Number),
+      swipeDuration: makeRequiredProp(numericProp),
+      visibleOptionNum: makeRequiredProp(numericProp)
+    },
+    emits: ["change", "clickOption"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      let moving;
+      let startOffset;
+      let touchStartTime;
+      let momentumOffset;
+      let transitionEndTrigger;
+      const root = vue.ref();
+      const wrapper = vue.ref();
+      const currentOffset = vue.ref(0);
+      const currentDuration = vue.ref(0);
+      const touch = useTouch();
+      const count = () => props.options.length;
+      const baseOffset = () => props.optionHeight * (+props.visibleOptionNum - 1) / 2;
+      const updateValueByIndex = (index) => {
+        const enabledIndex = findIndexOfEnabledOption(props.options, index);
+        const offset2 = -enabledIndex * props.optionHeight;
+        const trigger = () => {
+          const value = props.options[enabledIndex][props.fields.value];
+          if (value !== props.value) {
+            emit("change", value);
+          }
+        };
+        if (moving && offset2 !== currentOffset.value) {
+          transitionEndTrigger = trigger;
+        } else {
+          trigger();
+        }
+        currentOffset.value = offset2;
+      };
+      const isReadonly = () => props.readonly || !props.options.length;
+      const onClickOption = (index) => {
+        if (moving || isReadonly()) {
+          return;
+        }
+        transitionEndTrigger = null;
+        currentDuration.value = DEFAULT_DURATION;
+        updateValueByIndex(index);
+        emit("clickOption", props.options[index]);
+      };
+      const getIndexByOffset = (offset2) => clamp(Math.round(-offset2 / props.optionHeight), 0, count() - 1);
+      const momentum = (distance, duration) => {
+        const speed = Math.abs(distance / duration);
+        distance = currentOffset.value + speed / 3e-3 * (distance < 0 ? -1 : 1);
+        const index = getIndexByOffset(distance);
+        currentDuration.value = +props.swipeDuration;
+        updateValueByIndex(index);
+      };
+      const stopMomentum = () => {
+        moving = false;
+        currentDuration.value = 0;
+        if (transitionEndTrigger) {
+          transitionEndTrigger();
+          transitionEndTrigger = null;
+        }
+      };
+      const onTouchStart = (event) => {
+        if (isReadonly()) {
+          return;
+        }
+        touch.start(event);
+        if (moving) {
+          const translateY = getElementTranslateY(wrapper.value);
+          currentOffset.value = Math.min(0, translateY - baseOffset());
+        }
+        currentDuration.value = 0;
+        startOffset = currentOffset.value;
+        touchStartTime = Date.now();
+        momentumOffset = startOffset;
+        transitionEndTrigger = null;
+      };
+      const onTouchMove = (event) => {
+        if (isReadonly()) {
+          return;
+        }
+        touch.move(event);
+        if (touch.isVertical()) {
+          moving = true;
+          preventDefault(event, true);
+        }
+        currentOffset.value = clamp(startOffset + touch.deltaY.value, -(count() * props.optionHeight), props.optionHeight);
+        const now = Date.now();
+        if (now - touchStartTime > MOMENTUM_TIME) {
+          touchStartTime = now;
+          momentumOffset = currentOffset.value;
+        }
+      };
+      const onTouchEnd = () => {
+        if (isReadonly()) {
+          return;
+        }
+        const distance = currentOffset.value - momentumOffset;
+        const duration = Date.now() - touchStartTime;
+        const startMomentum = duration < MOMENTUM_TIME && Math.abs(distance) > MOMENTUM_DISTANCE;
+        if (startMomentum) {
+          momentum(distance, duration);
+          return;
+        }
+        const index = getIndexByOffset(currentOffset.value);
+        currentDuration.value = DEFAULT_DURATION;
+        updateValueByIndex(index);
+        setTimeout(() => {
+          moving = false;
+        }, 0);
+      };
+      const renderOptions = () => {
+        const optionStyle = {
+          height: `${props.optionHeight}px`
+        };
+        return props.options.map((option, index) => {
+          const text = option[props.fields.text];
+          const {
+            disabled
+          } = option;
+          const value = option[props.fields.value];
+          const data = {
+            role: "button",
+            style: optionStyle,
+            tabindex: disabled ? -1 : 0,
+            class: [bem$1l("item", {
+              disabled,
+              selected: value === props.value
+            }), option.className],
+            onClick: () => onClickOption(index)
+          };
+          const childData = {
+            class: "van-ellipsis",
+            [props.allowHtml ? "innerHTML" : "textContent"]: text
+          };
+          return vue.createVNode("li", data, [slots.option ? slots.option(option, index) : vue.createVNode("div", childData, null)]);
+        });
+      };
+      useParent(PICKER_KEY);
+      useExpose({
+        stopMomentum
+      });
+      vue.watchEffect(() => {
+        const index = props.options.findIndex((option) => option[props.fields.value] === props.value);
+        const enabledIndex = findIndexOfEnabledOption(props.options, index);
+        const offset2 = -enabledIndex * props.optionHeight;
+        currentOffset.value = offset2;
+      });
+      useEventListener("touchmove", onTouchMove, {
+        target: root
+      });
+      return () => vue.createVNode("div", {
+        "ref": root,
+        "class": bem$1l(),
+        "onTouchstartPassive": onTouchStart,
+        "onTouchend": onTouchEnd,
+        "onTouchcancel": onTouchEnd
+      }, [vue.createVNode("ul", {
+        "ref": wrapper,
+        "style": {
+          transform: `translate3d(0, ${currentOffset.value + baseOffset()}px, 0)`,
+          transitionDuration: `${currentDuration.value}ms`,
+          transitionProperty: currentDuration.value ? "all" : "none"
+        },
+        "class": bem$1l("wrapper"),
+        "onTransitionend": stopMomentum
+      }, [renderOptions()])]);
+    }
+  });
+  const [name$1p] = createNamespace("picker-toolbar");
+  const pickerToolbarProps = {
+    title: String,
+    cancelButtonText: String,
+    confirmButtonText: String
+  };
+  const pickerToolbarSlots = ["cancel", "confirm", "title", "toolbar"];
+  const pickerToolbarPropKeys = Object.keys(pickerToolbarProps);
+  var stdin_default$1A = vue.defineComponent({
+    name: name$1p,
+    props: pickerToolbarProps,
+    emits: ["confirm", "cancel"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const renderTitle = () => {
+        if (slots.title) {
+          return slots.title();
+        }
+        if (props.title) {
+          return vue.createVNode("div", {
+            "class": [bem$1m("title"), "van-ellipsis"]
+          }, [props.title]);
+        }
+      };
+      const onCancel = () => emit("cancel");
+      const onConfirm = () => emit("confirm");
+      const renderCancel = () => {
+        const text = props.cancelButtonText || t$j("cancel");
+        return vue.createVNode("button", {
+          "type": "button",
+          "class": [bem$1m("cancel"), HAPTICS_FEEDBACK],
+          "onClick": onCancel
+        }, [slots.cancel ? slots.cancel() : text]);
+      };
+      const renderConfirm = () => {
+        const text = props.confirmButtonText || t$j("confirm");
+        return vue.createVNode("button", {
+          "type": "button",
+          "class": [bem$1m("confirm"), HAPTICS_FEEDBACK],
+          "onClick": onConfirm
+        }, [slots.confirm ? slots.confirm() : text]);
+      };
+      return () => vue.createVNode("div", {
+        "class": bem$1m("toolbar")
+      }, [slots.toolbar ? slots.toolbar() : [renderCancel(), renderTitle(), renderConfirm()]]);
+    }
+  });
+  function scrollLeftTo(scroller, to, duration) {
+    let count = 0;
+    const from = scroller.scrollLeft;
+    const frames = duration === 0 ? 1 : Math.round(duration * 1e3 / 16);
+    function animate() {
+      scroller.scrollLeft += (to - from) / frames;
+      if (++count < frames) {
+        raf(animate);
+      }
+    }
+    animate();
+  }
+  function scrollTopTo(scroller, to, duration, callback) {
+    let current2 = getScrollTop(scroller);
+    const isDown = current2 < to;
+    const frames = duration === 0 ? 1 : Math.round(duration * 1e3 / 16);
+    const step = (to - current2) / frames;
+    function animate() {
+      current2 += step;
+      if (isDown && current2 > to || !isDown && current2 < to) {
+        current2 = to;
+      }
+      setScrollTop(scroller, current2);
+      if (isDown && current2 < to || !isDown && current2 > to) {
+        raf(animate);
+      } else if (callback) {
+        raf(callback);
+      }
+    }
+    animate();
+  }
+  let current = 0;
+  function useId() {
+    const vm = vue.getCurrentInstance();
+    const { name: name2 = "unknown" } = (vm == null ? void 0 : vm.type) || {};
+    return `${name2}-${++current}`;
+  }
+  function useRefs() {
+    const refs = vue.ref([]);
+    const cache = [];
+    vue.onBeforeUpdate(() => {
+      refs.value = [];
+    });
+    const setRefs = (index) => {
+      if (!cache[index]) {
+        cache[index] = (el) => {
+          refs.value[index] = el;
+        };
+      }
+      return cache[index];
+    };
+    return [refs, setRefs];
+  }
+  function useVisibilityChange(target, onChange) {
+    if (!inBrowser$1 || !window.IntersectionObserver) {
+      return;
+    }
+    const observer = new IntersectionObserver(
+      (entries) => {
+        onChange(entries[0].intersectionRatio > 0);
+      },
+      { root: document.body }
+    );
+    const observe = () => {
+      if (target.value) {
+        observer.observe(target.value);
+      }
+    };
+    const unobserve = () => {
+      if (target.value) {
+        observer.unobserve(target.value);
+      }
+    };
+    vue.onDeactivated(unobserve);
+    vue.onBeforeUnmount(unobserve);
+    onMountedOrActivated(observe);
+  }
+  const [name$1o, bem$1k] = createNamespace("sticky");
+  const stickyProps = {
+    zIndex: numericProp,
+    position: makeStringProp("top"),
+    container: Object,
+    offsetTop: makeNumericProp(0),
+    offsetBottom: makeNumericProp(0)
+  };
+  var stdin_default$1z = vue.defineComponent({
+    name: name$1o,
+    props: stickyProps,
+    emits: ["scroll", "change"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const root = vue.ref();
+      const scrollParent = useScrollParent(root);
+      const state = vue.reactive({
+        fixed: false,
+        width: 0,
+        // root width
+        height: 0,
+        // root height
+        transform: 0
+      });
+      const offset2 = vue.computed(() => unitToPx(props.position === "top" ? props.offsetTop : props.offsetBottom));
+      const rootStyle = vue.computed(() => {
+        const {
+          fixed,
+          height: height2,
+          width: width2
+        } = state;
+        if (fixed) {
+          return {
+            width: `${width2}px`,
+            height: `${height2}px`
+          };
+        }
+      });
+      const stickyStyle = vue.computed(() => {
+        if (!state.fixed) {
+          return;
+        }
+        const style = extend(getZIndexStyle(props.zIndex), {
+          width: `${state.width}px`,
+          height: `${state.height}px`,
+          [props.position]: `${offset2.value}px`
+        });
+        if (state.transform) {
+          style.transform = `translate3d(0, ${state.transform}px, 0)`;
+        }
+        return style;
+      });
+      const emitScroll = (scrollTop) => emit("scroll", {
+        scrollTop,
+        isFixed: state.fixed
+      });
+      const onScroll = () => {
+        if (!root.value || isHidden(root)) {
+          return;
+        }
+        const {
+          container,
+          position
+        } = props;
+        const rootRect = useRect(root);
+        const scrollTop = getScrollTop(window);
+        state.width = rootRect.width;
+        state.height = rootRect.height;
+        if (position === "top") {
+          if (container) {
+            const containerRect = useRect(container);
+            const difference = containerRect.bottom - offset2.value - state.height;
+            state.fixed = offset2.value > rootRect.top && containerRect.bottom > 0;
+            state.transform = difference < 0 ? difference : 0;
+          } else {
+            state.fixed = offset2.value > rootRect.top;
+          }
+        } else {
+          const {
+            clientHeight
+          } = document.documentElement;
+          if (container) {
+            const containerRect = useRect(container);
+            const difference = clientHeight - containerRect.top - offset2.value - state.height;
+            state.fixed = clientHeight - offset2.value < rootRect.bottom && clientHeight > containerRect.top;
+            state.transform = difference < 0 ? -difference : 0;
+          } else {
+            state.fixed = clientHeight - offset2.value < rootRect.bottom;
+          }
+        }
+        emitScroll(scrollTop);
+      };
+      vue.watch(() => state.fixed, (value) => emit("change", value));
+      useEventListener("scroll", onScroll, {
+        target: scrollParent,
+        passive: true
+      });
+      useVisibilityChange(root, onScroll);
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "ref": root,
+          "style": rootStyle.value
+        }, [vue.createVNode("div", {
+          "class": bem$1k({
+            fixed: state.fixed
+          }),
+          "style": stickyStyle.value
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)])]);
+      };
+    }
+  });
+  const Sticky = withInstall(stdin_default$1z);
+  const [name$1n, bem$1j] = createNamespace("tab");
+  var stdin_default$1y = vue.defineComponent({
+    name: name$1n,
+    props: {
+      id: String,
+      dot: Boolean,
+      type: String,
+      color: String,
+      title: String,
+      badge: numericProp,
+      shrink: Boolean,
+      isActive: Boolean,
+      disabled: Boolean,
+      controls: String,
+      scrollable: Boolean,
+      activeColor: String,
+      inactiveColor: String,
+      showZeroBadge: truthProp
+    },
+    setup(props, {
+      slots
+    }) {
+      const style = vue.computed(() => {
+        const style2 = {};
+        const {
+          type,
+          color,
+          disabled,
+          isActive,
+          activeColor,
+          inactiveColor
+        } = props;
+        const isCard = type === "card";
+        if (color && isCard) {
+          style2.borderColor = color;
+          if (!disabled) {
+            if (isActive) {
+              style2.backgroundColor = color;
+            } else {
+              style2.color = color;
+            }
+          }
+        }
+        const titleColor = isActive ? activeColor : inactiveColor;
+        if (titleColor) {
+          style2.color = titleColor;
+        }
+        return style2;
+      });
+      const renderText = () => {
+        const Text = vue.createVNode("span", {
+          "class": bem$1j("text", {
+            ellipsis: !props.scrollable
+          })
+        }, [slots.title ? slots.title() : props.title]);
+        if (props.dot || isDef(props.badge) && props.badge !== "") {
+          return vue.createVNode(Badge, {
+            "dot": props.dot,
+            "content": props.badge,
+            "showZero": props.showZeroBadge
+          }, {
+            default: () => [Text]
+          });
+        }
+        return Text;
+      };
+      return () => vue.createVNode("div", {
+        "id": props.id,
+        "role": "tab",
+        "class": [bem$1j([props.type, {
+          grow: props.scrollable && !props.shrink,
+          shrink: props.shrink,
+          active: props.isActive,
+          disabled: props.disabled
+        }])],
+        "style": style.value,
+        "tabindex": props.disabled ? void 0 : props.isActive ? 0 : -1,
+        "aria-selected": props.isActive,
+        "aria-disabled": props.disabled || void 0,
+        "aria-controls": props.controls
+      }, [renderText()]);
+    }
+  });
+  const [name$1m, bem$1i] = createNamespace("swipe");
+  const swipeProps = {
+    loop: truthProp,
+    width: numericProp,
+    height: numericProp,
+    vertical: Boolean,
+    autoplay: makeNumericProp(0),
+    duration: makeNumericProp(500),
+    touchable: truthProp,
+    lazyRender: Boolean,
+    initialSwipe: makeNumericProp(0),
+    indicatorColor: String,
+    showIndicators: truthProp,
+    stopPropagation: truthProp
+  };
+  const SWIPE_KEY = Symbol(name$1m);
+  var stdin_default$1x = vue.defineComponent({
+    name: name$1m,
+    props: swipeProps,
+    emits: ["change", "dragStart", "dragEnd"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const root = vue.ref();
+      const track = vue.ref();
+      const state = vue.reactive({
+        rect: null,
+        width: 0,
+        height: 0,
+        offset: 0,
+        active: 0,
+        swiping: false
+      });
+      let dragging = false;
+      const touch = useTouch();
+      const {
+        children,
+        linkChildren
+      } = useChildren(SWIPE_KEY);
+      const count = vue.computed(() => children.length);
+      const size = vue.computed(() => state[props.vertical ? "height" : "width"]);
+      const delta = vue.computed(() => props.vertical ? touch.deltaY.value : touch.deltaX.value);
+      const minOffset = vue.computed(() => {
+        if (state.rect) {
+          const base = props.vertical ? state.rect.height : state.rect.width;
+          return base - size.value * count.value;
+        }
+        return 0;
+      });
+      const maxCount = vue.computed(() => size.value ? Math.ceil(Math.abs(minOffset.value) / size.value) : count.value);
+      const trackSize = vue.computed(() => count.value * size.value);
+      const activeIndicator = vue.computed(() => (state.active + count.value) % count.value);
+      const isCorrectDirection = vue.computed(() => {
+        const expect = props.vertical ? "vertical" : "horizontal";
+        return touch.direction.value === expect;
+      });
+      const trackStyle = vue.computed(() => {
+        const style = {
+          transitionDuration: `${state.swiping ? 0 : props.duration}ms`,
+          transform: `translate${props.vertical ? "Y" : "X"}(${state.offset}px)`
+        };
+        if (size.value) {
+          const mainAxis = props.vertical ? "height" : "width";
+          const crossAxis = props.vertical ? "width" : "height";
+          style[mainAxis] = `${trackSize.value}px`;
+          style[crossAxis] = props[crossAxis] ? `${props[crossAxis]}px` : "";
+        }
+        return style;
+      });
+      const getTargetActive = (pace) => {
+        const {
+          active
+        } = state;
+        if (pace) {
+          if (props.loop) {
+            return clamp(active + pace, -1, count.value);
+          }
+          return clamp(active + pace, 0, maxCount.value);
+        }
+        return active;
+      };
+      const getTargetOffset = (targetActive, offset2 = 0) => {
+        let currentPosition = targetActive * size.value;
+        if (!props.loop) {
+          currentPosition = Math.min(currentPosition, -minOffset.value);
+        }
+        let targetOffset = offset2 - currentPosition;
+        if (!props.loop) {
+          targetOffset = clamp(targetOffset, minOffset.value, 0);
+        }
+        return targetOffset;
+      };
+      const move = ({
+        pace = 0,
+        offset: offset2 = 0,
+        emitChange
+      }) => {
+        if (count.value <= 1) {
+          return;
+        }
+        const {
+          active
+        } = state;
+        const targetActive = getTargetActive(pace);
+        const targetOffset = getTargetOffset(targetActive, offset2);
+        if (props.loop) {
+          if (children[0] && targetOffset !== minOffset.value) {
+            const outRightBound = targetOffset < minOffset.value;
+            children[0].setOffset(outRightBound ? trackSize.value : 0);
+          }
+          if (children[count.value - 1] && targetOffset !== 0) {
+            const outLeftBound = targetOffset > 0;
+            children[count.value - 1].setOffset(outLeftBound ? -trackSize.value : 0);
+          }
+        }
+        state.active = targetActive;
+        state.offset = targetOffset;
+        if (emitChange && targetActive !== active) {
+          emit("change", activeIndicator.value);
+        }
+      };
+      const correctPosition = () => {
+        state.swiping = true;
+        if (state.active <= -1) {
+          move({
+            pace: count.value
+          });
+        } else if (state.active >= count.value) {
+          move({
+            pace: -count.value
+          });
+        }
+      };
+      const prev = () => {
+        correctPosition();
+        touch.reset();
+        doubleRaf(() => {
+          state.swiping = false;
+          move({
+            pace: -1,
+            emitChange: true
+          });
+        });
+      };
+      const next = () => {
+        correctPosition();
+        touch.reset();
+        doubleRaf(() => {
+          state.swiping = false;
+          move({
+            pace: 1,
+            emitChange: true
+          });
+        });
+      };
+      let autoplayTimer;
+      const stopAutoplay = () => clearTimeout(autoplayTimer);
+      const autoplay = () => {
+        stopAutoplay();
+        if (+props.autoplay > 0 && count.value > 1) {
+          autoplayTimer = setTimeout(() => {
+            next();
+            autoplay();
+          }, +props.autoplay);
+        }
+      };
+      const initialize = (active = +props.initialSwipe) => {
+        if (!root.value) {
+          return;
+        }
+        const cb = () => {
+          var _a, _b;
+          if (!isHidden(root)) {
+            const rect = {
+              width: root.value.offsetWidth,
+              height: root.value.offsetHeight
+            };
+            state.rect = rect;
+            state.width = +((_a = props.width) != null ? _a : rect.width);
+            state.height = +((_b = props.height) != null ? _b : rect.height);
+          }
+          if (count.value) {
+            active = Math.min(count.value - 1, active);
+            if (active === -1) {
+              active = count.value - 1;
+            }
+          }
+          state.active = active;
+          state.swiping = true;
+          state.offset = getTargetOffset(active);
+          children.forEach((swipe) => {
+            swipe.setOffset(0);
+          });
+          autoplay();
+        };
+        if (isHidden(root)) {
+          vue.nextTick().then(cb);
+        } else {
+          cb();
+        }
+      };
+      const resize = () => initialize(state.active);
+      let touchStartTime;
+      const onTouchStart = (event) => {
+        if (!props.touchable || // avoid resetting position on multi-finger touch
+        event.touches.length > 1)
+          return;
+        touch.start(event);
+        dragging = false;
+        touchStartTime = Date.now();
+        stopAutoplay();
+        correctPosition();
+      };
+      const onTouchMove = (event) => {
+        if (props.touchable && state.swiping) {
+          touch.move(event);
+          if (isCorrectDirection.value) {
+            const isEdgeTouch = !props.loop && (state.active === 0 && delta.value > 0 || state.active === count.value - 1 && delta.value < 0);
+            if (!isEdgeTouch) {
+              preventDefault(event, props.stopPropagation);
+              move({
+                offset: delta.value
+              });
+              if (!dragging) {
+                emit("dragStart", {
+                  index: activeIndicator.value
+                });
+                dragging = true;
+              }
+            }
+          }
+        }
+      };
+      const onTouchEnd = () => {
+        if (!props.touchable || !state.swiping) {
+          return;
+        }
+        const duration = Date.now() - touchStartTime;
+        const speed = delta.value / duration;
+        const shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(delta.value) > size.value / 2;
+        if (shouldSwipe && isCorrectDirection.value) {
+          const offset2 = props.vertical ? touch.offsetY.value : touch.offsetX.value;
+          let pace = 0;
+          if (props.loop) {
+            pace = offset2 > 0 ? delta.value > 0 ? -1 : 1 : 0;
+          } else {
+            pace = -Math[delta.value > 0 ? "ceil" : "floor"](delta.value / size.value);
+          }
+          move({
+            pace,
+            emitChange: true
+          });
+        } else if (delta.value) {
+          move({
+            pace: 0
+          });
+        }
+        dragging = false;
+        state.swiping = false;
+        emit("dragEnd", {
+          index: activeIndicator.value
+        });
+        autoplay();
+      };
+      const swipeTo = (index, options = {}) => {
+        correctPosition();
+        touch.reset();
+        doubleRaf(() => {
+          let targetIndex;
+          if (props.loop && index === count.value) {
+            targetIndex = state.active === 0 ? 0 : index;
+          } else {
+            targetIndex = index % count.value;
+          }
+          if (options.immediate) {
+            doubleRaf(() => {
+              state.swiping = false;
+            });
+          } else {
+            state.swiping = false;
+          }
+          move({
+            pace: targetIndex - state.active,
+            emitChange: true
+          });
+        });
+      };
+      const renderDot = (_, index) => {
+        const active = index === activeIndicator.value;
+        const style = active ? {
+          backgroundColor: props.indicatorColor
+        } : void 0;
+        return vue.createVNode("i", {
+          "style": style,
+          "class": bem$1i("indicator", {
+            active
+          })
+        }, null);
+      };
+      const renderIndicator = () => {
+        if (slots.indicator) {
+          return slots.indicator({
+            active: activeIndicator.value,
+            total: count.value
+          });
+        }
+        if (props.showIndicators && count.value > 1) {
+          return vue.createVNode("div", {
+            "class": bem$1i("indicators", {
+              vertical: props.vertical
+            })
+          }, [Array(count.value).fill("").map(renderDot)]);
+        }
+      };
+      useExpose({
+        prev,
+        next,
+        state,
+        resize,
+        swipeTo
+      });
+      linkChildren({
+        size,
+        props,
+        count,
+        activeIndicator
+      });
+      vue.watch(() => props.initialSwipe, (value) => initialize(+value));
+      vue.watch(count, () => initialize(state.active));
+      vue.watch(() => props.autoplay, autoplay);
+      vue.watch([windowWidth, windowHeight], resize);
+      vue.watch(usePageVisibility(), (visible) => {
+        if (visible === "visible") {
+          autoplay();
+        } else {
+          stopAutoplay();
+        }
+      });
+      vue.onMounted(initialize);
+      vue.onActivated(() => initialize(state.active));
+      onPopupReopen(() => initialize(state.active));
+      vue.onDeactivated(stopAutoplay);
+      vue.onBeforeUnmount(stopAutoplay);
+      useEventListener("touchmove", onTouchMove, {
+        target: track
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "ref": root,
+          "class": bem$1i()
+        }, [vue.createVNode("div", {
+          "ref": track,
+          "style": trackStyle.value,
+          "class": bem$1i("track", {
+            vertical: props.vertical
+          }),
+          "onTouchstartPassive": onTouchStart,
+          "onTouchend": onTouchEnd,
+          "onTouchcancel": onTouchEnd
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), renderIndicator()]);
+      };
+    }
+  });
+  const Swipe = withInstall(stdin_default$1x);
+  const [name$1l, bem$1h] = createNamespace("tabs");
+  var stdin_default$1w = vue.defineComponent({
+    name: name$1l,
+    props: {
+      count: makeRequiredProp(Number),
+      inited: Boolean,
+      animated: Boolean,
+      duration: makeRequiredProp(numericProp),
+      swipeable: Boolean,
+      lazyRender: Boolean,
+      currentIndex: makeRequiredProp(Number)
+    },
+    emits: ["change"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const swipeRef = vue.ref();
+      const onChange = (index) => emit("change", index);
+      const renderChildren = () => {
+        var _a;
+        const Content = (_a = slots.default) == null ? void 0 : _a.call(slots);
+        if (props.animated || props.swipeable) {
+          return vue.createVNode(Swipe, {
+            "ref": swipeRef,
+            "loop": false,
+            "class": bem$1h("track"),
+            "duration": +props.duration * 1e3,
+            "touchable": props.swipeable,
+            "lazyRender": props.lazyRender,
+            "showIndicators": false,
+            "onChange": onChange
+          }, {
+            default: () => [Content]
+          });
+        }
+        return Content;
+      };
+      const swipeToCurrentTab = (index) => {
+        const swipe = swipeRef.value;
+        if (swipe && swipe.state.active !== index) {
+          swipe.swipeTo(index, {
+            immediate: !props.inited
+          });
+        }
+      };
+      vue.watch(() => props.currentIndex, swipeToCurrentTab);
+      vue.onMounted(() => {
+        swipeToCurrentTab(props.currentIndex);
+      });
+      useExpose({
+        swipeRef
+      });
+      return () => vue.createVNode("div", {
+        "class": bem$1h("content", {
+          animated: props.animated || props.swipeable
+        })
+      }, [renderChildren()]);
+    }
+  });
+  const [name$1k, bem$1g] = createNamespace("tabs");
+  const tabsProps = {
+    type: makeStringProp("line"),
+    color: String,
+    border: Boolean,
+    sticky: Boolean,
+    shrink: Boolean,
+    active: makeNumericProp(0),
+    duration: makeNumericProp(0.3),
+    animated: Boolean,
+    ellipsis: truthProp,
+    swipeable: Boolean,
+    scrollspy: Boolean,
+    offsetTop: makeNumericProp(0),
+    background: String,
+    lazyRender: truthProp,
+    lineWidth: numericProp,
+    lineHeight: numericProp,
+    beforeChange: Function,
+    swipeThreshold: makeNumericProp(5),
+    titleActiveColor: String,
+    titleInactiveColor: String
+  };
+  const TABS_KEY = Symbol(name$1k);
+  var stdin_default$1v = vue.defineComponent({
+    name: name$1k,
+    props: tabsProps,
+    emits: ["change", "scroll", "rendered", "clickTab", "update:active"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      let tabHeight;
+      let lockScroll;
+      let stickyFixed;
+      const root = vue.ref();
+      const navRef = vue.ref();
+      const wrapRef = vue.ref();
+      const contentRef = vue.ref();
+      const id = useId();
+      const scroller = useScrollParent(root);
+      const [titleRefs, setTitleRefs] = useRefs();
+      const {
+        children,
+        linkChildren
+      } = useChildren(TABS_KEY);
+      const state = vue.reactive({
+        inited: false,
+        position: "",
+        lineStyle: {},
+        currentIndex: -1
+      });
+      const scrollable = vue.computed(() => children.length > +props.swipeThreshold || !props.ellipsis || props.shrink);
+      const navStyle = vue.computed(() => ({
+        borderColor: props.color,
+        background: props.background
+      }));
+      const getTabName = (tab, index) => {
+        var _a;
+        return (_a = tab.name) != null ? _a : index;
+      };
+      const currentName = vue.computed(() => {
+        const activeTab = children[state.currentIndex];
+        if (activeTab) {
+          return getTabName(activeTab, state.currentIndex);
+        }
+      });
+      const offsetTopPx = vue.computed(() => unitToPx(props.offsetTop));
+      const scrollOffset = vue.computed(() => {
+        if (props.sticky) {
+          return offsetTopPx.value + tabHeight;
+        }
+        return 0;
+      });
+      const scrollIntoView = (immediate) => {
+        const nav = navRef.value;
+        const titles = titleRefs.value;
+        if (!scrollable.value || !nav || !titles || !titles[state.currentIndex]) {
+          return;
+        }
+        const title = titles[state.currentIndex].$el;
+        const to = title.offsetLeft - (nav.offsetWidth - title.offsetWidth) / 2;
+        scrollLeftTo(nav, to, immediate ? 0 : +props.duration);
+      };
+      const setLine = () => {
+        const shouldAnimate = state.inited;
+        vue.nextTick(() => {
+          const titles = titleRefs.value;
+          if (!titles || !titles[state.currentIndex] || props.type !== "line" || isHidden(root.value)) {
+            return;
+          }
+          const title = titles[state.currentIndex].$el;
+          const {
+            lineWidth,
+            lineHeight
+          } = props;
+          const left2 = title.offsetLeft + title.offsetWidth / 2;
+          const lineStyle = {
+            width: addUnit(lineWidth),
+            backgroundColor: props.color,
+            transform: `translateX(${left2}px) translateX(-50%)`
+          };
+          if (shouldAnimate) {
+            lineStyle.transitionDuration = `${props.duration}s`;
+          }
+          if (isDef(lineHeight)) {
+            const height2 = addUnit(lineHeight);
+            lineStyle.height = height2;
+            lineStyle.borderRadius = height2;
+          }
+          state.lineStyle = lineStyle;
+        });
+      };
+      const findAvailableTab = (index) => {
+        const diff = index < state.currentIndex ? -1 : 1;
+        while (index >= 0 && index < children.length) {
+          if (!children[index].disabled) {
+            return index;
+          }
+          index += diff;
+        }
+      };
+      const setCurrentIndex = (currentIndex, skipScrollIntoView) => {
+        const newIndex = findAvailableTab(currentIndex);
+        if (!isDef(newIndex)) {
+          return;
+        }
+        const newTab = children[newIndex];
+        const newName = getTabName(newTab, newIndex);
+        const shouldEmitChange = state.currentIndex !== null;
+        if (state.currentIndex !== newIndex) {
+          state.currentIndex = newIndex;
+          if (!skipScrollIntoView) {
+            scrollIntoView();
+          }
+          setLine();
+        }
+        if (newName !== props.active) {
+          emit("update:active", newName);
+          if (shouldEmitChange) {
+            emit("change", newName, newTab.title);
+          }
+        }
+        if (stickyFixed && !props.scrollspy) {
+          setRootScrollTop(Math.ceil(getElementTop(root.value) - offsetTopPx.value));
+        }
+      };
+      const setCurrentIndexByName = (name2, skipScrollIntoView) => {
+        const matched = children.find((tab, index2) => getTabName(tab, index2) === name2);
+        const index = matched ? children.indexOf(matched) : 0;
+        setCurrentIndex(index, skipScrollIntoView);
+      };
+      const scrollToCurrentContent = (immediate = false) => {
+        if (props.scrollspy) {
+          const target = children[state.currentIndex].$el;
+          if (target && scroller.value) {
+            const to = getElementTop(target, scroller.value) - scrollOffset.value;
+            lockScroll = true;
+            scrollTopTo(scroller.value, to, immediate ? 0 : +props.duration, () => {
+              lockScroll = false;
+            });
+          }
+        }
+      };
+      const onClickTab = (item, index, event) => {
+        const {
+          title,
+          disabled
+        } = children[index];
+        const name2 = getTabName(children[index], index);
+        if (!disabled) {
+          callInterceptor(props.beforeChange, {
+            args: [name2],
+            done: () => {
+              setCurrentIndex(index);
+              scrollToCurrentContent();
+            }
+          });
+          route(item);
+        }
+        emit("clickTab", {
+          name: name2,
+          title,
+          event,
+          disabled
+        });
+      };
+      const onStickyScroll = (params) => {
+        stickyFixed = params.isFixed;
+        emit("scroll", params);
+      };
+      const scrollTo = (name2) => {
+        vue.nextTick(() => {
+          setCurrentIndexByName(name2);
+          scrollToCurrentContent(true);
+        });
+      };
+      const getCurrentIndexOnScroll = () => {
+        for (let index = 0; index < children.length; index++) {
+          const {
+            top: top2
+          } = useRect(children[index].$el);
+          if (top2 > scrollOffset.value) {
+            return index === 0 ? 0 : index - 1;
+          }
+        }
+        return children.length - 1;
+      };
+      const onScroll = () => {
+        if (props.scrollspy && !lockScroll) {
+          const index = getCurrentIndexOnScroll();
+          setCurrentIndex(index);
+        }
+      };
+      const renderNav = () => children.map((item, index) => vue.createVNode(stdin_default$1y, vue.mergeProps({
+        "key": item.id,
+        "id": `${id}-${index}`,
+        "ref": setTitleRefs(index),
+        "type": props.type,
+        "color": props.color,
+        "style": item.titleStyle,
+        "class": item.titleClass,
+        "shrink": props.shrink,
+        "isActive": index === state.currentIndex,
+        "controls": item.id,
+        "scrollable": scrollable.value,
+        "activeColor": props.titleActiveColor,
+        "inactiveColor": props.titleInactiveColor,
+        "onClick": (event) => onClickTab(item, index, event)
+      }, pick(item, ["dot", "badge", "title", "disabled", "showZeroBadge"])), {
+        title: item.$slots.title
+      }));
+      const renderLine = () => {
+        if (props.type === "line" && children.length) {
+          return vue.createVNode("div", {
+            "class": bem$1g("line"),
+            "style": state.lineStyle
+          }, null);
+        }
+      };
+      const renderHeader = () => {
+        var _a, _b, _c;
+        const {
+          type,
+          border,
+          sticky
+        } = props;
+        const Header = [vue.createVNode("div", {
+          "ref": sticky ? void 0 : wrapRef,
+          "class": [bem$1g("wrap"), {
+            [BORDER_TOP_BOTTOM]: type === "line" && border
+          }]
+        }, [vue.createVNode("div", {
+          "ref": navRef,
+          "role": "tablist",
+          "class": bem$1g("nav", [type, {
+            shrink: props.shrink,
+            complete: scrollable.value
+          }]),
+          "style": navStyle.value,
+          "aria-orientation": "horizontal"
+        }, [(_a = slots["nav-left"]) == null ? void 0 : _a.call(slots), renderNav(), renderLine(), (_b = slots["nav-right"]) == null ? void 0 : _b.call(slots)])]), (_c = slots["nav-bottom"]) == null ? void 0 : _c.call(slots)];
+        if (sticky) {
+          return vue.createVNode("div", {
+            "ref": wrapRef
+          }, [Header]);
+        }
+        return Header;
+      };
+      vue.watch([() => props.color, windowWidth], setLine);
+      vue.watch(() => props.active, (value) => {
+        if (value !== currentName.value) {
+          setCurrentIndexByName(value);
+        }
+      });
+      vue.watch(() => children.length, () => {
+        if (state.inited) {
+          setCurrentIndexByName(props.active);
+          setLine();
+          vue.nextTick(() => {
+            scrollIntoView(true);
+          });
+        }
+      });
+      const init = () => {
+        setCurrentIndexByName(props.active, true);
+        vue.nextTick(() => {
+          state.inited = true;
+          if (wrapRef.value) {
+            tabHeight = useRect(wrapRef.value).height;
+          }
+          scrollIntoView(true);
+        });
+      };
+      const onRendered = (name2, title) => emit("rendered", name2, title);
+      const resize = () => {
+        setLine();
+        vue.nextTick(() => {
+          var _a, _b;
+          return (_b = (_a = contentRef.value) == null ? void 0 : _a.swipeRef.value) == null ? void 0 : _b.resize();
+        });
+      };
+      useExpose({
+        resize,
+        scrollTo
+      });
+      vue.onActivated(setLine);
+      onPopupReopen(setLine);
+      onMountedOrActivated(init);
+      useVisibilityChange(root, setLine);
+      useEventListener("scroll", onScroll, {
+        target: scroller,
+        passive: true
+      });
+      linkChildren({
+        id,
+        props,
+        setLine,
+        onRendered,
+        currentName,
+        scrollIntoView
+      });
+      return () => vue.createVNode("div", {
+        "ref": root,
+        "class": bem$1g([props.type])
+      }, [props.sticky ? vue.createVNode(Sticky, {
+        "container": root.value,
+        "offsetTop": offsetTopPx.value,
+        "onScroll": onStickyScroll
+      }, {
+        default: () => [renderHeader()]
+      }) : renderHeader(), vue.createVNode(stdin_default$1w, {
+        "ref": contentRef,
+        "count": children.length,
+        "inited": state.inited,
+        "animated": props.animated,
+        "duration": props.duration,
+        "swipeable": props.swipeable,
+        "lazyRender": props.lazyRender,
+        "currentIndex": state.currentIndex,
+        "onChange": setCurrentIndex
+      }, {
+        default: () => {
+          var _a;
+          return [(_a = slots.default) == null ? void 0 : _a.call(slots)];
+        }
+      })]);
+    }
+  });
+  const TAB_STATUS_KEY = Symbol();
+  const useTabStatus = () => vue.inject(TAB_STATUS_KEY, null);
+  const [name$1j, bem$1f] = createNamespace("swipe-item");
+  var stdin_default$1u = vue.defineComponent({
+    name: name$1j,
+    setup(props, {
+      slots
+    }) {
+      let rendered;
+      const state = vue.reactive({
+        offset: 0,
+        inited: false,
+        mounted: false
+      });
+      const {
+        parent,
+        index
+      } = useParent(SWIPE_KEY);
+      if (!parent) {
+        return;
+      }
+      const style = vue.computed(() => {
+        const style2 = {};
+        const {
+          vertical
+        } = parent.props;
+        if (parent.size.value) {
+          style2[vertical ? "height" : "width"] = `${parent.size.value}px`;
+        }
+        if (state.offset) {
+          style2.transform = `translate${vertical ? "Y" : "X"}(${state.offset}px)`;
+        }
+        return style2;
+      });
+      const shouldRender = vue.computed(() => {
+        const {
+          loop,
+          lazyRender
+        } = parent.props;
+        if (!lazyRender || rendered) {
+          return true;
+        }
+        if (!state.mounted) {
+          return false;
+        }
+        const active = parent.activeIndicator.value;
+        const maxActive = parent.count.value - 1;
+        const prevActive = active === 0 && loop ? maxActive : active - 1;
+        const nextActive = active === maxActive && loop ? 0 : active + 1;
+        rendered = index.value === active || index.value === prevActive || index.value === nextActive;
+        return rendered;
+      });
+      const setOffset = (offset2) => {
+        state.offset = offset2;
+      };
+      vue.onMounted(() => {
+        vue.nextTick(() => {
+          state.mounted = true;
+        });
+      });
+      useExpose({
+        setOffset
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "class": bem$1f(),
+          "style": style.value
+        }, [shouldRender.value ? (_a = slots.default) == null ? void 0 : _a.call(slots) : null]);
+      };
+    }
+  });
+  const SwipeItem = withInstall(stdin_default$1u);
+  const [name$1i, bem$1e] = createNamespace("tab");
+  const tabProps = extend({}, routeProps, {
+    dot: Boolean,
+    name: numericProp,
+    badge: numericProp,
+    title: String,
+    disabled: Boolean,
+    titleClass: unknownProp,
+    titleStyle: [String, Object],
+    showZeroBadge: truthProp
+  });
+  var stdin_default$1t = vue.defineComponent({
+    name: name$1i,
+    props: tabProps,
+    setup(props, {
+      slots
+    }) {
+      const id = useId();
+      const inited = vue.ref(false);
+      const {
+        parent,
+        index
+      } = useParent(TABS_KEY);
+      if (!parent) {
+        return;
+      }
+      const getName = () => {
+        var _a;
+        return (_a = props.name) != null ? _a : index.value;
+      };
+      const init = () => {
+        inited.value = true;
+        if (parent.props.lazyRender) {
+          vue.nextTick(() => {
+            parent.onRendered(getName(), props.title);
+          });
+        }
+      };
+      const active = vue.computed(() => {
+        const isActive = getName() === parent.currentName.value;
+        if (isActive && !inited.value) {
+          init();
+        }
+        return isActive;
+      });
+      const hasInactiveClass = vue.ref(!active.value);
+      vue.watch(active, (val) => {
+        if (val) {
+          hasInactiveClass.value = false;
+        } else {
+          doubleRaf(() => {
+            hasInactiveClass.value = true;
+          });
+        }
+      });
+      vue.watch(() => props.title, () => {
+        parent.setLine();
+        parent.scrollIntoView();
+      });
+      vue.provide(TAB_STATUS_KEY, active);
+      return () => {
+        var _a;
+        const label = `${parent.id}-${index.value}`;
+        const {
+          animated,
+          swipeable,
+          scrollspy,
+          lazyRender
+        } = parent.props;
+        if (!slots.default && !animated) {
+          return;
+        }
+        const show = scrollspy || active.value;
+        if (animated || swipeable) {
+          return vue.createVNode(SwipeItem, {
+            "id": id,
+            "role": "tabpanel",
+            "class": bem$1e("panel-wrapper", {
+              inactive: hasInactiveClass.value
+            }),
+            "tabindex": active.value ? 0 : -1,
+            "aria-hidden": !active.value,
+            "aria-labelledby": label
+          }, {
+            default: () => {
+              var _a2;
+              return [vue.createVNode("div", {
+                "class": bem$1e("panel")
+              }, [(_a2 = slots.default) == null ? void 0 : _a2.call(slots)])];
+            }
+          });
+        }
+        const shouldRender = inited.value || scrollspy || !lazyRender;
+        const Content = shouldRender ? (_a = slots.default) == null ? void 0 : _a.call(slots) : null;
+        useExpose({
+          id
+        });
+        return vue.withDirectives(vue.createVNode("div", {
+          "id": id,
+          "role": "tabpanel",
+          "class": bem$1e("panel"),
+          "tabindex": show ? 0 : -1,
+          "aria-labelledby": label
+        }, [Content]), [[vue.vShow, show]]);
+      };
+    }
+  });
+  const Tab = withInstall(stdin_default$1t);
+  const Tabs = withInstall(stdin_default$1v);
+  const [name$1h, bem$1d] = createNamespace("picker-group");
+  const PICKER_GROUP_KEY = Symbol(name$1h);
+  const pickerGroupProps = extend({
+    tabs: makeArrayProp(),
+    nextStepText: String
+  }, pickerToolbarProps);
+  var stdin_default$1s = vue.defineComponent({
+    name: name$1h,
+    props: pickerGroupProps,
+    emits: ["confirm", "cancel"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const activeTab = vue.ref(0);
+      const {
+        children,
+        linkChildren
+      } = useChildren(PICKER_GROUP_KEY);
+      linkChildren();
+      const showNextButton = () => activeTab.value < props.tabs.length - 1 && props.nextStepText;
+      const onConfirm = () => {
+        if (showNextButton()) {
+          activeTab.value++;
+        } else {
+          emit("confirm", children.map((item) => item.confirm()));
+        }
+      };
+      const onCancel = () => emit("cancel");
+      return () => {
+        var _a;
+        const childNodes = (_a = slots.default) == null ? void 0 : _a.call(slots);
+        const confirmButtonText = showNextButton() ? props.nextStepText : props.confirmButtonText;
+        return vue.createVNode("div", {
+          "class": bem$1d()
+        }, [vue.createVNode(stdin_default$1A, {
+          "title": props.title,
+          "cancelButtonText": props.cancelButtonText,
+          "confirmButtonText": confirmButtonText,
+          "onConfirm": onConfirm,
+          "onCancel": onCancel
+        }, pick(slots, pickerToolbarSlots)), vue.createVNode(Tabs, {
+          "active": activeTab.value,
+          "onUpdate:active": ($event) => activeTab.value = $event,
+          "class": bem$1d("tabs"),
+          "shrink": true,
+          "animated": true,
+          "lazyRender": false
+        }, {
+          default: () => [props.tabs.map((title, index) => vue.createVNode(Tab, {
+            "title": title,
+            "titleClass": bem$1d("tab-title")
+          }, {
+            default: () => [childNodes == null ? void 0 : childNodes[index]]
+          }))]
+        })]);
+      };
+    }
+  });
+  const pickerSharedProps = extend({
+    loading: Boolean,
+    readonly: Boolean,
+    allowHtml: Boolean,
+    optionHeight: makeNumericProp(44),
+    showToolbar: truthProp,
+    swipeDuration: makeNumericProp(1e3),
+    visibleOptionNum: makeNumericProp(6)
+  }, pickerToolbarProps);
+  const pickerProps = extend({}, pickerSharedProps, {
+    columns: makeArrayProp(),
+    modelValue: makeArrayProp(),
+    toolbarPosition: makeStringProp("top"),
+    columnsFieldNames: Object
+  });
+  var stdin_default$1r = vue.defineComponent({
+    name: name$1r,
+    props: pickerProps,
+    emits: ["confirm", "cancel", "change", "clickOption", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const columnsRef = vue.ref();
+      const selectedValues = vue.ref(props.modelValue.slice(0));
+      const {
+        parent
+      } = useParent(PICKER_GROUP_KEY);
+      const {
+        children,
+        linkChildren
+      } = useChildren(PICKER_KEY);
+      linkChildren();
+      const fields = vue.computed(() => assignDefaultFields(props.columnsFieldNames));
+      const optionHeight = vue.computed(() => unitToPx(props.optionHeight));
+      const columnsType = vue.computed(() => getColumnsType(props.columns, fields.value));
+      const currentColumns = vue.computed(() => {
+        const {
+          columns
+        } = props;
+        switch (columnsType.value) {
+          case "multiple":
+            return columns;
+          case "cascade":
+            return formatCascadeColumns(columns, fields.value, selectedValues);
+          default:
+            return [columns];
+        }
+      });
+      const hasOptions = vue.computed(() => currentColumns.value.some((options) => options.length));
+      const selectedOptions = vue.computed(() => currentColumns.value.map((options, index) => findOptionByValue(options, selectedValues.value[index], fields.value)));
+      const selectedIndexes = vue.computed(() => currentColumns.value.map((options, index) => options.findIndex((option) => option[fields.value.value] === selectedValues.value[index])));
+      const setValue = (index, value) => {
+        if (selectedValues.value[index] !== value) {
+          const newValues = selectedValues.value.slice(0);
+          newValues[index] = value;
+          selectedValues.value = newValues;
+        }
+      };
+      const getEventParams = () => ({
+        selectedValues: selectedValues.value.slice(0),
+        selectedOptions: selectedOptions.value,
+        selectedIndexes: selectedIndexes.value
+      });
+      const onChange = (value, columnIndex) => {
+        setValue(columnIndex, value);
+        if (columnsType.value === "cascade") {
+          selectedValues.value.forEach((value2, index) => {
+            const options = currentColumns.value[index];
+            if (!isOptionExist(options, value2, fields.value)) {
+              setValue(index, options.length ? options[0][fields.value.value] : void 0);
+            }
+          });
+        }
+        vue.nextTick(() => {
+          emit("change", extend({
+            columnIndex
+          }, getEventParams()));
+        });
+      };
+      const onClickOption = (currentOption, columnIndex) => emit("clickOption", extend({
+        columnIndex,
+        currentOption
+      }, getEventParams()));
+      const confirm = () => {
+        children.forEach((child) => child.stopMomentum());
+        const params = getEventParams();
+        vue.nextTick(() => {
+          emit("confirm", params);
+        });
+        return params;
+      };
+      const cancel = () => emit("cancel", getEventParams());
+      const renderColumnItems = () => currentColumns.value.map((options, columnIndex) => vue.createVNode(stdin_default$1B, {
+        "value": selectedValues.value[columnIndex],
+        "fields": fields.value,
+        "options": options,
+        "readonly": props.readonly,
+        "allowHtml": props.allowHtml,
+        "optionHeight": optionHeight.value,
+        "swipeDuration": props.swipeDuration,
+        "visibleOptionNum": props.visibleOptionNum,
+        "onChange": (value) => onChange(value, columnIndex),
+        "onClickOption": (option) => onClickOption(option, columnIndex)
+      }, {
+        option: slots.option
+      }));
+      const renderMask = (wrapHeight) => {
+        if (hasOptions.value) {
+          const frameStyle = {
+            height: `${optionHeight.value}px`
+          };
+          const maskStyle = {
+            backgroundSize: `100% ${(wrapHeight - optionHeight.value) / 2}px`
+          };
+          return [vue.createVNode("div", {
+            "class": bem$1m("mask"),
+            "style": maskStyle
+          }, null), vue.createVNode("div", {
+            "class": [BORDER_UNSET_TOP_BOTTOM, bem$1m("frame")],
+            "style": frameStyle
+          }, null)];
+        }
+      };
+      const renderColumns = () => {
+        const wrapHeight = optionHeight.value * +props.visibleOptionNum;
+        const columnsStyle = {
+          height: `${wrapHeight}px`
+        };
+        return vue.createVNode("div", {
+          "ref": columnsRef,
+          "class": bem$1m("columns"),
+          "style": columnsStyle
+        }, [renderColumnItems(), renderMask(wrapHeight)]);
+      };
+      const renderToolbar = () => {
+        if (props.showToolbar && !parent) {
+          return vue.createVNode(stdin_default$1A, vue.mergeProps(pick(props, pickerToolbarPropKeys), {
+            "onConfirm": confirm,
+            "onCancel": cancel
+          }), pick(slots, pickerToolbarSlots));
+        }
+      };
+      vue.watch(currentColumns, (columns) => {
+        columns.forEach((options, index) => {
+          if (options.length && !isOptionExist(options, selectedValues.value[index], fields.value)) {
+            setValue(index, getFirstEnabledOption(options)[fields.value.value]);
+          }
+        });
+      }, {
+        immediate: true
+      });
+      let lastEmittedModelValue;
+      vue.watch(() => props.modelValue, (newValues) => {
+        if (!isSameValue(newValues, selectedValues.value) && !isSameValue(newValues, lastEmittedModelValue)) {
+          selectedValues.value = newValues.slice(0);
+          lastEmittedModelValue = newValues.slice(0);
+        }
+      }, {
+        deep: true
+      });
+      vue.watch(selectedValues, (newValues) => {
+        if (!isSameValue(newValues, props.modelValue)) {
+          lastEmittedModelValue = newValues.slice(0);
+          emit("update:modelValue", lastEmittedModelValue);
+        }
+      }, {
+        immediate: true
+      });
+      useEventListener("touchmove", preventDefault, {
+        target: columnsRef
+      });
+      const getSelectedOptions = () => selectedOptions.value;
+      useExpose({
+        confirm,
+        getSelectedOptions
+      });
+      return () => {
+        var _a, _b;
+        return vue.createVNode("div", {
+          "class": bem$1m()
+        }, [props.toolbarPosition === "top" ? renderToolbar() : null, props.loading ? vue.createVNode(Loading, {
+          "class": bem$1m("loading")
+        }, null) : null, (_a = slots["columns-top"]) == null ? void 0 : _a.call(slots), renderColumns(), (_b = slots["columns-bottom"]) == null ? void 0 : _b.call(slots), props.toolbarPosition === "bottom" ? renderToolbar() : null]);
+      };
+    }
+  });
+  const AREA_EMPTY_CODE = "000000";
+  const INHERIT_SLOTS = [
+    "title",
+    "cancel",
+    "confirm",
+    "toolbar",
+    "columns-top",
+    "columns-bottom"
+  ];
+  const INHERIT_PROPS = [
+    "title",
+    "loading",
+    "readonly",
+    "optionHeight",
+    "swipeDuration",
+    "visibleOptionNum",
+    "cancelButtonText",
+    "confirmButtonText"
+  ];
+  const makeOption = (text = "", value = AREA_EMPTY_CODE, children = void 0) => ({
+    text,
+    value,
+    children
+  });
+  function formatDataForCascade({
+    areaList,
+    columnsNum,
+    columnsPlaceholder: placeholder
+  }) {
+    const {
+      city_list: city = {},
+      county_list: county = {},
+      province_list: province = {}
+    } = areaList;
+    const showCity = +columnsNum > 1;
+    const showCounty = +columnsNum > 2;
+    const getProvinceChildren = () => {
+      if (showCity) {
+        return placeholder.length ? [
+          makeOption(
+            placeholder[0],
+            AREA_EMPTY_CODE,
+            showCounty ? [] : void 0
+          )
+        ] : [];
+      }
+    };
+    const provinceMap = /* @__PURE__ */ new Map();
+    Object.keys(province).forEach((code) => {
+      provinceMap.set(
+        code.slice(0, 2),
+        makeOption(province[code], code, getProvinceChildren())
+      );
+    });
+    const cityMap = /* @__PURE__ */ new Map();
+    if (showCity) {
+      const getCityChildren = () => {
+        if (showCounty) {
+          return placeholder.length ? [makeOption(placeholder[1])] : [];
+        }
+      };
+      Object.keys(city).forEach((code) => {
+        const option = makeOption(city[code], code, getCityChildren());
+        cityMap.set(code.slice(0, 4), option);
+        const province2 = provinceMap.get(code.slice(0, 2));
+        if (province2) {
+          province2.children.push(option);
+        }
+      });
+    }
+    if (showCounty) {
+      Object.keys(county).forEach((code) => {
+        const city2 = cityMap.get(code.slice(0, 4));
+        if (city2) {
+          city2.children.push(makeOption(county[code], code));
+        }
+      });
+    }
+    const options = Array.from(provinceMap.values());
+    if (placeholder.length) {
+      const county2 = showCounty ? [makeOption(placeholder[2])] : void 0;
+      const city2 = showCity ? [makeOption(placeholder[1], AREA_EMPTY_CODE, county2)] : void 0;
+      options.unshift(makeOption(placeholder[0], AREA_EMPTY_CODE, city2));
+    }
+    return options;
+  }
+  const Picker = withInstall(stdin_default$1r);
+  const [name$1g, bem$1c] = createNamespace("area");
+  const areaProps = extend({}, pickerSharedProps, {
+    modelValue: String,
+    columnsNum: makeNumericProp(3),
+    columnsPlaceholder: makeArrayProp(),
+    areaList: {
+      type: Object,
+      default: () => ({})
+    }
+  });
+  var stdin_default$1q = vue.defineComponent({
+    name: name$1g,
+    props: areaProps,
+    emits: ["change", "confirm", "cancel", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const codes = vue.ref([]);
+      const picker = vue.ref();
+      const columns = vue.computed(() => formatDataForCascade(props));
+      const onChange = (...args) => emit("change", ...args);
+      const onCancel = (...args) => emit("cancel", ...args);
+      const onConfirm = (...args) => emit("confirm", ...args);
+      vue.watch(codes, (newCodes) => {
+        const lastCode = newCodes.length ? newCodes[newCodes.length - 1] : "";
+        if (lastCode && lastCode !== props.modelValue) {
+          emit("update:modelValue", lastCode);
+        }
+      }, {
+        deep: true
+      });
+      vue.watch(() => props.modelValue, (newCode) => {
+        if (newCode) {
+          const lastCode = codes.value.length ? codes.value[codes.value.length - 1] : "";
+          if (newCode !== lastCode) {
+            codes.value = [`${newCode.slice(0, 2)}0000`, `${newCode.slice(0, 4)}00`, newCode].slice(0, +props.columnsNum);
+          }
+        } else {
+          codes.value = [];
+        }
+      }, {
+        immediate: true
+      });
+      useExpose({
+        confirm: () => {
+          var _a;
+          return (_a = picker.value) == null ? void 0 : _a.confirm();
+        },
+        getSelectedOptions: () => {
+          var _a;
+          return ((_a = picker.value) == null ? void 0 : _a.getSelectedOptions()) || [];
+        }
+      });
+      return () => vue.createVNode(Picker, vue.mergeProps({
+        "ref": picker,
+        "modelValue": codes.value,
+        "onUpdate:modelValue": ($event) => codes.value = $event,
+        "class": bem$1c(),
+        "columns": columns.value,
+        "onChange": onChange,
+        "onCancel": onCancel,
+        "onConfirm": onConfirm
+      }, pick(props, INHERIT_PROPS)), pick(slots, INHERIT_SLOTS));
+    }
+  });
+  const Area = withInstall(stdin_default$1q);
+  const [name$1f, bem$1b] = createNamespace("cell");
+  const cellSharedProps = {
+    tag: makeStringProp("div"),
+    icon: String,
+    size: String,
+    title: numericProp,
+    value: numericProp,
+    label: numericProp,
+    center: Boolean,
+    isLink: Boolean,
+    border: truthProp,
+    required: Boolean,
+    iconPrefix: String,
+    valueClass: unknownProp,
+    labelClass: unknownProp,
+    titleClass: unknownProp,
+    titleStyle: null,
+    arrowDirection: String,
+    clickable: {
+      type: Boolean,
+      default: null
+    }
+  };
+  const cellProps = extend({}, cellSharedProps, routeProps);
+  var stdin_default$1p = vue.defineComponent({
+    name: name$1f,
+    props: cellProps,
+    setup(props, {
+      slots
+    }) {
+      const route2 = useRoute();
+      const renderLabel = () => {
+        const showLabel = slots.label || isDef(props.label);
+        if (showLabel) {
+          return vue.createVNode("div", {
+            "class": [bem$1b("label"), props.labelClass]
+          }, [slots.label ? slots.label() : props.label]);
+        }
+      };
+      const renderTitle = () => {
+        var _a;
+        if (slots.title || isDef(props.title)) {
+          const titleSlot = (_a = slots.title) == null ? void 0 : _a.call(slots);
+          if (Array.isArray(titleSlot) && titleSlot.length === 0) {
+            return;
+          }
+          return vue.createVNode("div", {
+            "class": [bem$1b("title"), props.titleClass],
+            "style": props.titleStyle
+          }, [titleSlot || vue.createVNode("span", null, [props.title]), renderLabel()]);
+        }
+      };
+      const renderValue = () => {
+        const slot = slots.value || slots.default;
+        const hasValue = slot || isDef(props.value);
+        if (hasValue) {
+          return vue.createVNode("div", {
+            "class": [bem$1b("value"), props.valueClass]
+          }, [slot ? slot() : vue.createVNode("span", null, [props.value])]);
+        }
+      };
+      const renderLeftIcon = () => {
+        if (slots.icon) {
+          return slots.icon();
+        }
+        if (props.icon) {
+          return vue.createVNode(Icon, {
+            "name": props.icon,
+            "class": bem$1b("left-icon"),
+            "classPrefix": props.iconPrefix
+          }, null);
+        }
+      };
+      const renderRightIcon = () => {
+        if (slots["right-icon"]) {
+          return slots["right-icon"]();
+        }
+        if (props.isLink) {
+          const name2 = props.arrowDirection && props.arrowDirection !== "right" ? `arrow-${props.arrowDirection}` : "arrow";
+          return vue.createVNode(Icon, {
+            "name": name2,
+            "class": bem$1b("right-icon")
+          }, null);
+        }
+      };
+      return () => {
+        var _a;
+        const {
+          tag,
+          size,
+          center,
+          border,
+          isLink,
+          required
+        } = props;
+        const clickable = (_a = props.clickable) != null ? _a : isLink;
+        const classes = {
+          center,
+          required,
+          clickable,
+          borderless: !border
+        };
+        if (size) {
+          classes[size] = !!size;
+        }
+        return vue.createVNode(tag, {
+          "class": bem$1b(classes),
+          "role": clickable ? "button" : void 0,
+          "tabindex": clickable ? 0 : void 0,
+          "onClick": route2
+        }, {
+          default: () => {
+            var _a2;
+            return [renderLeftIcon(), renderTitle(), renderValue(), renderRightIcon(), (_a2 = slots.extra) == null ? void 0 : _a2.call(slots)];
+          }
+        });
+      };
+    }
+  });
+  const Cell = withInstall(stdin_default$1p);
+  const [name$1e, bem$1a] = createNamespace("form");
+  const formProps = {
+    colon: Boolean,
+    disabled: Boolean,
+    readonly: Boolean,
+    showError: Boolean,
+    labelWidth: numericProp,
+    labelAlign: String,
+    inputAlign: String,
+    scrollToError: Boolean,
+    validateFirst: Boolean,
+    submitOnEnter: truthProp,
+    showErrorMessage: truthProp,
+    errorMessageAlign: String,
+    validateTrigger: {
+      type: [String, Array],
+      default: "onBlur"
+    }
+  };
+  var stdin_default$1o = vue.defineComponent({
+    name: name$1e,
+    props: formProps,
+    emits: ["submit", "failed"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        children,
+        linkChildren
+      } = useChildren(FORM_KEY);
+      const getFieldsByNames = (names) => {
+        if (names) {
+          return children.filter((field) => names.includes(field.name));
+        }
+        return children;
+      };
+      const validateSeq = (names) => new Promise((resolve, reject) => {
+        const errors = [];
+        const fields = getFieldsByNames(names);
+        fields.reduce((promise, field) => promise.then(() => {
+          if (!errors.length) {
+            return field.validate().then((error) => {
+              if (error) {
+                errors.push(error);
+              }
+            });
+          }
+        }), Promise.resolve()).then(() => {
+          if (errors.length) {
+            reject(errors);
+          } else {
+            resolve();
+          }
+        });
+      });
+      const validateAll = (names) => new Promise((resolve, reject) => {
+        const fields = getFieldsByNames(names);
+        Promise.all(fields.map((item) => item.validate())).then((errors) => {
+          errors = errors.filter(Boolean);
+          if (errors.length) {
+            reject(errors);
+          } else {
+            resolve();
+          }
+        });
+      });
+      const validateField = (name2) => {
+        const matched = children.find((item) => item.name === name2);
+        if (matched) {
+          return new Promise((resolve, reject) => {
+            matched.validate().then((error) => {
+              if (error) {
+                reject(error);
+              } else {
+                resolve();
+              }
+            });
+          });
+        }
+        return Promise.reject();
+      };
+      const validate = (name2) => {
+        if (typeof name2 === "string") {
+          return validateField(name2);
+        }
+        return props.validateFirst ? validateSeq(name2) : validateAll(name2);
+      };
+      const resetValidation = (name2) => {
+        if (typeof name2 === "string") {
+          name2 = [name2];
+        }
+        const fields = getFieldsByNames(name2);
+        fields.forEach((item) => {
+          item.resetValidation();
+        });
+      };
+      const getValidationStatus = () => children.reduce((form, field) => {
+        form[field.name] = field.getValidationStatus();
+        return form;
+      }, {});
+      const scrollToField = (name2, options) => {
+        children.some((item) => {
+          if (item.name === name2) {
+            item.$el.scrollIntoView(options);
+            return true;
+          }
+          return false;
+        });
+      };
+      const getValues = () => children.reduce((form, field) => {
+        if (field.name !== void 0) {
+          form[field.name] = field.formValue.value;
+        }
+        return form;
+      }, {});
+      const submit = () => {
+        const values = getValues();
+        validate().then(() => emit("submit", values)).catch((errors) => {
+          emit("failed", {
+            values,
+            errors
+          });
+          if (props.scrollToError && errors[0].name) {
+            scrollToField(errors[0].name);
+          }
+        });
+      };
+      const onSubmit = (event) => {
+        preventDefault(event);
+        submit();
+      };
+      linkChildren({
+        props
+      });
+      useExpose({
+        submit,
+        validate,
+        getValues,
+        scrollToField,
+        resetValidation,
+        getValidationStatus
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("form", {
+          "class": bem$1a(),
+          "onSubmit": onSubmit
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const Form = withInstall(stdin_default$1o);
+  function isEmptyValue(value) {
+    if (Array.isArray(value)) {
+      return !value.length;
+    }
+    if (value === 0) {
+      return false;
+    }
+    return !value;
+  }
+  function runSyncRule(value, rule) {
+    if (isEmptyValue(value)) {
+      if (rule.required) {
+        return false;
+      }
+      if (rule.validateEmpty === false) {
+        return true;
+      }
+    }
+    if (rule.pattern && !rule.pattern.test(String(value))) {
+      return false;
+    }
+    return true;
+  }
+  function runRuleValidator(value, rule) {
+    return new Promise((resolve) => {
+      const returnVal = rule.validator(value, rule);
+      if (isPromise(returnVal)) {
+        returnVal.then(resolve);
+        return;
+      }
+      resolve(returnVal);
+    });
+  }
+  function getRuleMessage(value, rule) {
+    const { message } = rule;
+    if (isFunction(message)) {
+      return message(value, rule);
+    }
+    return message || "";
+  }
+  function startComposing({ target }) {
+    target.composing = true;
+  }
+  function endComposing({ target }) {
+    if (target.composing) {
+      target.composing = false;
+      target.dispatchEvent(new Event("input"));
+    }
+  }
+  function resizeTextarea(input, autosize) {
+    const scrollTop = getRootScrollTop();
+    input.style.height = "auto";
+    let height2 = input.scrollHeight;
+    if (isObject(autosize)) {
+      const { maxHeight, minHeight } = autosize;
+      if (maxHeight !== void 0) {
+        height2 = Math.min(height2, maxHeight);
+      }
+      if (minHeight !== void 0) {
+        height2 = Math.max(height2, minHeight);
+      }
+    }
+    if (height2) {
+      input.style.height = `${height2}px`;
+      setRootScrollTop(scrollTop);
+    }
+  }
+  function mapInputType(type) {
+    if (type === "number") {
+      return {
+        type: "text",
+        inputmode: "decimal"
+      };
+    }
+    if (type === "digit") {
+      return {
+        type: "tel",
+        inputmode: "numeric"
+      };
+    }
+    return { type };
+  }
+  function getStringLength(str) {
+    return [...str].length;
+  }
+  function cutString(str, maxlength) {
+    return [...str].slice(0, maxlength).join("");
+  }
+  const [name$1d, bem$19] = createNamespace("field");
+  const fieldSharedProps = {
+    id: String,
+    name: String,
+    leftIcon: String,
+    rightIcon: String,
+    autofocus: Boolean,
+    clearable: Boolean,
+    maxlength: numericProp,
+    formatter: Function,
+    clearIcon: makeStringProp("clear"),
+    modelValue: makeNumericProp(""),
+    inputAlign: String,
+    placeholder: String,
+    autocomplete: String,
+    errorMessage: String,
+    enterkeyhint: String,
+    clearTrigger: makeStringProp("focus"),
+    formatTrigger: makeStringProp("onChange"),
+    error: {
+      type: Boolean,
+      default: null
+    },
+    disabled: {
+      type: Boolean,
+      default: null
+    },
+    readonly: {
+      type: Boolean,
+      default: null
+    }
+  };
+  const fieldProps = extend({}, cellSharedProps, fieldSharedProps, {
+    rows: numericProp,
+    type: makeStringProp("text"),
+    rules: Array,
+    autosize: [Boolean, Object],
+    labelWidth: numericProp,
+    labelClass: unknownProp,
+    labelAlign: String,
+    showWordLimit: Boolean,
+    errorMessageAlign: String,
+    colon: {
+      type: Boolean,
+      default: null
+    }
+  });
+  var stdin_default$1n = vue.defineComponent({
+    name: name$1d,
+    props: fieldProps,
+    emits: ["blur", "focus", "clear", "keypress", "clickInput", "endValidate", "startValidate", "clickLeftIcon", "clickRightIcon", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const id = useId();
+      const state = vue.reactive({
+        status: "unvalidated",
+        focused: false,
+        validateMessage: ""
+      });
+      const inputRef = vue.ref();
+      const clearIconRef = vue.ref();
+      const customValue = vue.ref();
+      const {
+        parent: form
+      } = useParent(FORM_KEY);
+      const getModelValue = () => {
+        var _a;
+        return String((_a = props.modelValue) != null ? _a : "");
+      };
+      const getProp = (key) => {
+        if (isDef(props[key])) {
+          return props[key];
+        }
+        if (form && isDef(form.props[key])) {
+          return form.props[key];
+        }
+      };
+      const showClear = vue.computed(() => {
+        const readonly = getProp("readonly");
+        if (props.clearable && !readonly) {
+          const hasValue = getModelValue() !== "";
+          const trigger = props.clearTrigger === "always" || props.clearTrigger === "focus" && state.focused;
+          return hasValue && trigger;
+        }
+        return false;
+      });
+      const formValue = vue.computed(() => {
+        if (customValue.value && slots.input) {
+          return customValue.value();
+        }
+        return props.modelValue;
+      });
+      const runRules = (rules) => rules.reduce((promise, rule) => promise.then(() => {
+        if (state.status === "failed") {
+          return;
+        }
+        let {
+          value
+        } = formValue;
+        if (rule.formatter) {
+          value = rule.formatter(value, rule);
+        }
+        if (!runSyncRule(value, rule)) {
+          state.status = "failed";
+          state.validateMessage = getRuleMessage(value, rule);
+          return;
+        }
+        if (rule.validator) {
+          if (isEmptyValue(value) && rule.validateEmpty === false) {
+            return;
+          }
+          return runRuleValidator(value, rule).then((result) => {
+            if (result && typeof result === "string") {
+              state.status = "failed";
+              state.validateMessage = result;
+            } else if (result === false) {
+              state.status = "failed";
+              state.validateMessage = getRuleMessage(value, rule);
+            }
+          });
+        }
+      }), Promise.resolve());
+      const resetValidation = () => {
+        state.status = "unvalidated";
+        state.validateMessage = "";
+      };
+      const endValidate = () => emit("endValidate", {
+        status: state.status,
+        message: state.validateMessage
+      });
+      const validate = (rules = props.rules) => new Promise((resolve) => {
+        resetValidation();
+        if (rules) {
+          emit("startValidate");
+          runRules(rules).then(() => {
+            if (state.status === "failed") {
+              resolve({
+                name: props.name,
+                message: state.validateMessage
+              });
+              endValidate();
+            } else {
+              state.status = "passed";
+              resolve();
+              endValidate();
+            }
+          });
+        } else {
+          resolve();
+        }
+      });
+      const validateWithTrigger = (trigger) => {
+        if (form && props.rules) {
+          const {
+            validateTrigger
+          } = form.props;
+          const defaultTrigger = toArray(validateTrigger).includes(trigger);
+          const rules = props.rules.filter((rule) => {
+            if (rule.trigger) {
+              return toArray(rule.trigger).includes(trigger);
+            }
+            return defaultTrigger;
+          });
+          if (rules.length) {
+            validate(rules);
+          }
+        }
+      };
+      const limitValueLength = (value) => {
+        var _a;
+        const {
+          maxlength
+        } = props;
+        if (isDef(maxlength) && getStringLength(value) > +maxlength) {
+          const modelValue = getModelValue();
+          if (modelValue && getStringLength(modelValue) === +maxlength) {
+            return modelValue;
+          }
+          const selectionEnd = (_a = inputRef.value) == null ? void 0 : _a.selectionEnd;
+          if (state.focused && selectionEnd) {
+            const valueArr = [...value];
+            const exceededLength = valueArr.length - +maxlength;
+            valueArr.splice(selectionEnd - exceededLength, exceededLength);
+            return valueArr.join("");
+          }
+          return cutString(value, +maxlength);
+        }
+        return value;
+      };
+      const updateValue = (value, trigger = "onChange") => {
+        const originalValue = value;
+        value = limitValueLength(value);
+        const limitDiffLen = getStringLength(originalValue) - getStringLength(value);
+        if (props.type === "number" || props.type === "digit") {
+          const isNumber = props.type === "number";
+          value = formatNumber(value, isNumber, isNumber);
+        }
+        let formatterDiffLen = 0;
+        if (props.formatter && trigger === props.formatTrigger) {
+          const {
+            formatter,
+            maxlength
+          } = props;
+          value = formatter(value);
+          if (isDef(maxlength) && getStringLength(value) > +maxlength) {
+            value = cutString(value, +maxlength);
+          }
+          if (inputRef.value && state.focused) {
+            const {
+              selectionEnd
+            } = inputRef.value;
+            const bcoVal = cutString(originalValue, selectionEnd);
+            formatterDiffLen = getStringLength(formatter(bcoVal)) - getStringLength(bcoVal);
+          }
+        }
+        if (inputRef.value && inputRef.value.value !== value) {
+          if (state.focused) {
+            let {
+              selectionStart,
+              selectionEnd
+            } = inputRef.value;
+            inputRef.value.value = value;
+            if (isDef(selectionStart) && isDef(selectionEnd)) {
+              const valueLen = getStringLength(value);
+              if (limitDiffLen) {
+                selectionStart -= limitDiffLen;
+                selectionEnd -= limitDiffLen;
+              } else if (formatterDiffLen) {
+                selectionStart += formatterDiffLen;
+                selectionEnd += formatterDiffLen;
+              }
+              inputRef.value.setSelectionRange(Math.min(selectionStart, valueLen), Math.min(selectionEnd, valueLen));
+            }
+          } else {
+            inputRef.value.value = value;
+          }
+        }
+        if (value !== props.modelValue) {
+          emit("update:modelValue", value);
+        }
+      };
+      const onInput = (event) => {
+        if (!event.target.composing) {
+          updateValue(event.target.value);
+        }
+      };
+      const blur = () => {
+        var _a;
+        return (_a = inputRef.value) == null ? void 0 : _a.blur();
+      };
+      const focus = () => {
+        var _a;
+        return (_a = inputRef.value) == null ? void 0 : _a.focus();
+      };
+      const adjustTextareaSize = () => {
+        const input = inputRef.value;
+        if (props.type === "textarea" && props.autosize && input) {
+          resizeTextarea(input, props.autosize);
+        }
+      };
+      const onFocus = (event) => {
+        state.focused = true;
+        emit("focus", event);
+        vue.nextTick(adjustTextareaSize);
+        if (getProp("readonly")) {
+          blur();
+        }
+      };
+      const onBlur = (event) => {
+        state.focused = false;
+        updateValue(getModelValue(), "onBlur");
+        emit("blur", event);
+        if (getProp("readonly")) {
+          return;
+        }
+        validateWithTrigger("onBlur");
+        vue.nextTick(adjustTextareaSize);
+        resetScroll();
+      };
+      const onClickInput = (event) => emit("clickInput", event);
+      const onClickLeftIcon = (event) => emit("clickLeftIcon", event);
+      const onClickRightIcon = (event) => emit("clickRightIcon", event);
+      const onClear = (event) => {
+        preventDefault(event);
+        emit("update:modelValue", "");
+        emit("clear", event);
+      };
+      const showError = vue.computed(() => {
+        if (typeof props.error === "boolean") {
+          return props.error;
+        }
+        if (form && form.props.showError && state.status === "failed") {
+          return true;
+        }
+      });
+      const labelStyle = vue.computed(() => {
+        const labelWidth = getProp("labelWidth");
+        const labelAlign = getProp("labelAlign");
+        if (labelWidth && labelAlign !== "top") {
+          return {
+            width: addUnit(labelWidth)
+          };
+        }
+      });
+      const onKeypress = (event) => {
+        const ENTER_CODE = 13;
+        if (event.keyCode === ENTER_CODE) {
+          const submitOnEnter = form && form.props.submitOnEnter;
+          if (!submitOnEnter && props.type !== "textarea") {
+            preventDefault(event);
+          }
+          if (props.type === "search") {
+            blur();
+          }
+        }
+        emit("keypress", event);
+      };
+      const getInputId = () => props.id || `${id}-input`;
+      const getValidationStatus = () => state.status;
+      const renderInput = () => {
+        const controlClass = bem$19("control", [getProp("inputAlign"), {
+          error: showError.value,
+          custom: !!slots.input,
+          "min-height": props.type === "textarea" && !props.autosize
+        }]);
+        if (slots.input) {
+          return vue.createVNode("div", {
+            "class": controlClass,
+            "onClick": onClickInput
+          }, [slots.input()]);
+        }
+        const inputAttrs = {
+          id: getInputId(),
+          ref: inputRef,
+          name: props.name,
+          rows: props.rows !== void 0 ? +props.rows : void 0,
+          class: controlClass,
+          disabled: getProp("disabled"),
+          readonly: getProp("readonly"),
+          autofocus: props.autofocus,
+          placeholder: props.placeholder,
+          autocomplete: props.autocomplete,
+          enterkeyhint: props.enterkeyhint,
+          "aria-labelledby": props.label ? `${id}-label` : void 0,
+          onBlur,
+          onFocus,
+          onInput,
+          onClick: onClickInput,
+          onChange: endComposing,
+          onKeypress,
+          onCompositionend: endComposing,
+          onCompositionstart: startComposing
+        };
+        if (props.type === "textarea") {
+          return vue.createVNode("textarea", inputAttrs, null);
+        }
+        return vue.createVNode("input", vue.mergeProps(mapInputType(props.type), inputAttrs), null);
+      };
+      const renderLeftIcon = () => {
+        const leftIconSlot = slots["left-icon"];
+        if (props.leftIcon || leftIconSlot) {
+          return vue.createVNode("div", {
+            "class": bem$19("left-icon"),
+            "onClick": onClickLeftIcon
+          }, [leftIconSlot ? leftIconSlot() : vue.createVNode(Icon, {
+            "name": props.leftIcon,
+            "classPrefix": props.iconPrefix
+          }, null)]);
+        }
+      };
+      const renderRightIcon = () => {
+        const rightIconSlot = slots["right-icon"];
+        if (props.rightIcon || rightIconSlot) {
+          return vue.createVNode("div", {
+            "class": bem$19("right-icon"),
+            "onClick": onClickRightIcon
+          }, [rightIconSlot ? rightIconSlot() : vue.createVNode(Icon, {
+            "name": props.rightIcon,
+            "classPrefix": props.iconPrefix
+          }, null)]);
+        }
+      };
+      const renderWordLimit = () => {
+        if (props.showWordLimit && props.maxlength) {
+          const count = getStringLength(getModelValue());
+          return vue.createVNode("div", {
+            "class": bem$19("word-limit")
+          }, [vue.createVNode("span", {
+            "class": bem$19("word-num")
+          }, [count]), vue.createTextVNode("/"), props.maxlength]);
+        }
+      };
+      const renderMessage = () => {
+        if (form && form.props.showErrorMessage === false) {
+          return;
+        }
+        const message = props.errorMessage || state.validateMessage;
+        if (message) {
+          const slot = slots["error-message"];
+          const errorMessageAlign = getProp("errorMessageAlign");
+          return vue.createVNode("div", {
+            "class": bem$19("error-message", errorMessageAlign)
+          }, [slot ? slot({
+            message
+          }) : message]);
+        }
+      };
+      const renderLabel = () => {
+        const labelWidth = getProp("labelWidth");
+        const labelAlign = getProp("labelAlign");
+        const colon = getProp("colon") ? ":" : "";
+        if (slots.label) {
+          return [slots.label(), colon];
+        }
+        if (props.label) {
+          return vue.createVNode("label", {
+            "id": `${id}-label`,
+            "for": getInputId(),
+            "style": labelAlign === "top" && labelWidth ? {
+              width: addUnit(labelWidth)
+            } : void 0
+          }, [props.label + colon]);
+        }
+      };
+      const renderFieldBody = () => [vue.createVNode("div", {
+        "class": bem$19("body")
+      }, [renderInput(), showClear.value && vue.createVNode(Icon, {
+        "ref": clearIconRef,
+        "name": props.clearIcon,
+        "class": bem$19("clear")
+      }, null), renderRightIcon(), slots.button && vue.createVNode("div", {
+        "class": bem$19("button")
+      }, [slots.button()])]), renderWordLimit(), renderMessage()];
+      useExpose({
+        blur,
+        focus,
+        validate,
+        formValue,
+        resetValidation,
+        getValidationStatus
+      });
+      vue.provide(CUSTOM_FIELD_INJECTION_KEY, {
+        customValue,
+        resetValidation,
+        validateWithTrigger
+      });
+      vue.watch(() => props.modelValue, () => {
+        updateValue(getModelValue());
+        resetValidation();
+        validateWithTrigger("onChange");
+        vue.nextTick(adjustTextareaSize);
+      });
+      vue.onMounted(() => {
+        updateValue(getModelValue(), props.formatTrigger);
+        vue.nextTick(adjustTextareaSize);
+      });
+      useEventListener("touchstart", onClear, {
+        target: vue.computed(() => {
+          var _a;
+          return (_a = clearIconRef.value) == null ? void 0 : _a.$el;
+        })
+      });
+      return () => {
+        const disabled = getProp("disabled");
+        const labelAlign = getProp("labelAlign");
+        const LeftIcon = renderLeftIcon();
+        const renderTitle = () => {
+          const Label = renderLabel();
+          if (labelAlign === "top") {
+            return [LeftIcon, Label].filter(Boolean);
+          }
+          return Label || [];
+        };
+        return vue.createVNode(Cell, {
+          "size": props.size,
+          "class": bem$19({
+            error: showError.value,
+            disabled,
+            [`label-${labelAlign}`]: labelAlign
+          }),
+          "center": props.center,
+          "border": props.border,
+          "isLink": props.isLink,
+          "clickable": props.clickable,
+          "titleStyle": labelStyle.value,
+          "valueClass": bem$19("value"),
+          "titleClass": [bem$19("label", [labelAlign, {
+            required: props.required
+          }]), props.labelClass],
+          "arrowDirection": props.arrowDirection
+        }, {
+          icon: LeftIcon && labelAlign !== "top" ? () => LeftIcon : null,
+          title: renderTitle,
+          value: renderFieldBody,
+          extra: slots.extra
+        });
+      };
+    }
+  });
+  const Field = withInstall(stdin_default$1n);
+  let lockCount = 0;
+  function lockClick(lock) {
+    if (lock) {
+      if (!lockCount) {
+        document.body.classList.add("van-toast--unclickable");
+      }
+      lockCount++;
+    } else if (lockCount) {
+      lockCount--;
+      if (!lockCount) {
+        document.body.classList.remove("van-toast--unclickable");
+      }
+    }
+  }
+  const [name$1c, bem$18] = createNamespace("toast");
+  const popupInheritProps = ["show", "overlay", "teleport", "transition", "overlayClass", "overlayStyle", "closeOnClickOverlay"];
+  const toastProps = {
+    icon: String,
+    show: Boolean,
+    type: makeStringProp("text"),
+    overlay: Boolean,
+    message: numericProp,
+    iconSize: numericProp,
+    duration: makeNumberProp(2e3),
+    position: makeStringProp("middle"),
+    teleport: [String, Object],
+    wordBreak: String,
+    className: unknownProp,
+    iconPrefix: String,
+    transition: makeStringProp("van-fade"),
+    loadingType: String,
+    forbidClick: Boolean,
+    overlayClass: unknownProp,
+    overlayStyle: Object,
+    closeOnClick: Boolean,
+    closeOnClickOverlay: Boolean
+  };
+  var stdin_default$1m = vue.defineComponent({
+    name: name$1c,
+    props: toastProps,
+    emits: ["update:show"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      let timer2;
+      let clickable = false;
+      const toggleClickable = () => {
+        const newValue = props.show && props.forbidClick;
+        if (clickable !== newValue) {
+          clickable = newValue;
+          lockClick(clickable);
+        }
+      };
+      const updateShow = (show) => emit("update:show", show);
+      const onClick = () => {
+        if (props.closeOnClick) {
+          updateShow(false);
+        }
+      };
+      const clearTimer = () => clearTimeout(timer2);
+      const renderIcon = () => {
+        const {
+          icon,
+          type,
+          iconSize,
+          iconPrefix,
+          loadingType
+        } = props;
+        const hasIcon = icon || type === "success" || type === "fail";
+        if (hasIcon) {
+          return vue.createVNode(Icon, {
+            "name": icon || type,
+            "size": iconSize,
+            "class": bem$18("icon"),
+            "classPrefix": iconPrefix
+          }, null);
+        }
+        if (type === "loading") {
+          return vue.createVNode(Loading, {
+            "class": bem$18("loading"),
+            "size": iconSize,
+            "type": loadingType
+          }, null);
+        }
+      };
+      const renderMessage = () => {
+        const {
+          type,
+          message
+        } = props;
+        if (slots.message) {
+          return vue.createVNode("div", {
+            "class": bem$18("text")
+          }, [slots.message()]);
+        }
+        if (isDef(message) && message !== "") {
+          return type === "html" ? vue.createVNode("div", {
+            "key": 0,
+            "class": bem$18("text"),
+            "innerHTML": String(message)
+          }, null) : vue.createVNode("div", {
+            "class": bem$18("text")
+          }, [message]);
+        }
+      };
+      vue.watch(() => [props.show, props.forbidClick], toggleClickable);
+      vue.watch(() => [props.show, props.type, props.message, props.duration], () => {
+        clearTimer();
+        if (props.show && props.duration > 0) {
+          timer2 = setTimeout(() => {
+            updateShow(false);
+          }, props.duration);
+        }
+      });
+      vue.onMounted(toggleClickable);
+      vue.onUnmounted(toggleClickable);
+      return () => vue.createVNode(Popup, vue.mergeProps({
+        "class": [bem$18([props.position, props.wordBreak === "normal" ? "break-normal" : props.wordBreak, {
+          [props.type]: !props.icon
+        }]), props.className],
+        "lockScroll": false,
+        "onClick": onClick,
+        "onClosed": clearTimer,
+        "onUpdate:show": updateShow
+      }, pick(props, popupInheritProps)), {
+        default: () => [renderIcon(), renderMessage()]
+      });
+    }
+  });
+  function usePopupState() {
+    const state = vue.reactive({
+      show: false
+    });
+    const toggle = (show) => {
+      state.show = show;
+    };
+    const open = (props) => {
+      extend(state, props, { transitionAppear: true });
+      toggle(true);
+    };
+    const close = () => toggle(false);
+    useExpose({ open, close, toggle });
+    return {
+      open,
+      close,
+      state,
+      toggle
+    };
+  }
+  function mountComponent(RootComponent) {
+    const app = vue.createApp(RootComponent);
+    const root = document.createElement("div");
+    document.body.appendChild(root);
+    return {
+      instance: app.mount(root),
+      unmount() {
+        app.unmount();
+        document.body.removeChild(root);
+      }
+    };
+  }
+  const defaultOptions$1 = {
+    icon: "",
+    type: "text",
+    message: "",
+    className: "",
+    overlay: false,
+    onClose: void 0,
+    onOpened: void 0,
+    duration: 2e3,
+    teleport: "body",
+    iconSize: void 0,
+    iconPrefix: void 0,
+    position: "middle",
+    transition: "van-fade",
+    forbidClick: false,
+    loadingType: void 0,
+    overlayClass: "",
+    overlayStyle: void 0,
+    closeOnClick: false,
+    closeOnClickOverlay: false
+  };
+  let queue = [];
+  let allowMultiple = false;
+  let currentOptions$2 = extend({}, defaultOptions$1);
+  const defaultOptionsMap = /* @__PURE__ */ new Map();
+  function parseOptions$1(message) {
+    if (isObject(message)) {
+      return message;
+    }
+    return {
+      message
+    };
+  }
+  function createInstance() {
+    const {
+      instance: instance2,
+      unmount
+    } = mountComponent({
+      setup() {
+        const message = vue.ref("");
+        const {
+          open,
+          state,
+          close,
+          toggle
+        } = usePopupState();
+        const onClosed = () => {
+          if (allowMultiple) {
+            queue = queue.filter((item) => item !== instance2);
+            unmount();
+          }
+        };
+        const render = () => {
+          const attrs = {
+            onClosed,
+            "onUpdate:show": toggle
+          };
+          return vue.createVNode(stdin_default$1m, vue.mergeProps(state, attrs), null);
+        };
+        vue.watch(message, (val) => {
+          state.message = val;
+        });
+        vue.getCurrentInstance().render = render;
+        return {
+          open,
+          close,
+          message
+        };
+      }
+    });
+    return instance2;
+  }
+  function getInstance() {
+    if (!queue.length || allowMultiple) {
+      const instance2 = createInstance();
+      queue.push(instance2);
+    }
+    return queue[queue.length - 1];
+  }
+  function showToast(options = {}) {
+    if (!inBrowser$1) {
+      return {};
+    }
+    const toast = getInstance();
+    const parsedOptions = parseOptions$1(options);
+    toast.open(extend({}, currentOptions$2, defaultOptionsMap.get(parsedOptions.type || currentOptions$2.type), parsedOptions));
+    return toast;
+  }
+  const createMethod = (type) => (options) => showToast(extend({
+    type
+  }, parseOptions$1(options)));
+  const showLoadingToast = createMethod("loading");
+  const showSuccessToast = createMethod("success");
+  const showFailToast = createMethod("fail");
+  const closeToast = (all) => {
+    var _a;
+    if (queue.length) {
+      if (all) {
+        queue.forEach((toast) => {
+          toast.close();
+        });
+        queue = [];
+      } else if (!allowMultiple) {
+        queue[0].close();
+      } else {
+        (_a = queue.shift()) == null ? void 0 : _a.close();
+      }
+    }
+  };
+  function setToastDefaultOptions(type, options) {
+    if (typeof type === "string") {
+      defaultOptionsMap.set(type, options);
+    } else {
+      extend(currentOptions$2, type);
+    }
+  }
+  const resetToastDefaultOptions = (type) => {
+    if (typeof type === "string") {
+      defaultOptionsMap.delete(type);
+    } else {
+      currentOptions$2 = extend({}, defaultOptions$1);
+      defaultOptionsMap.clear();
+    }
+  };
+  const allowMultipleToast = (value = true) => {
+    allowMultiple = value;
+  };
+  const Toast = withInstall(stdin_default$1m);
+  const [name$1b, bem$17] = createNamespace("switch");
+  const switchProps = {
+    size: numericProp,
+    loading: Boolean,
+    disabled: Boolean,
+    modelValue: unknownProp,
+    activeColor: String,
+    inactiveColor: String,
+    activeValue: {
+      type: unknownProp,
+      default: true
+    },
+    inactiveValue: {
+      type: unknownProp,
+      default: false
+    }
+  };
+  var stdin_default$1l = vue.defineComponent({
+    name: name$1b,
+    props: switchProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const isChecked = () => props.modelValue === props.activeValue;
+      const onClick = () => {
+        if (!props.disabled && !props.loading) {
+          const newValue = isChecked() ? props.inactiveValue : props.activeValue;
+          emit("update:modelValue", newValue);
+          emit("change", newValue);
+        }
+      };
+      const renderLoading = () => {
+        if (props.loading) {
+          const color = isChecked() ? props.activeColor : props.inactiveColor;
+          return vue.createVNode(Loading, {
+            "class": bem$17("loading"),
+            "color": color
+          }, null);
+        }
+        if (slots.node) {
+          return slots.node();
+        }
+      };
+      useCustomFieldValue(() => props.modelValue);
+      return () => {
+        var _a;
+        const {
+          size,
+          loading,
+          disabled,
+          activeColor,
+          inactiveColor
+        } = props;
+        const checked = isChecked();
+        const style = {
+          fontSize: addUnit(size),
+          backgroundColor: checked ? activeColor : inactiveColor
+        };
+        return vue.createVNode("div", {
+          "role": "switch",
+          "class": bem$17({
+            on: checked,
+            loading,
+            disabled
+          }),
+          "style": style,
+          "tabindex": disabled ? void 0 : 0,
+          "aria-checked": checked,
+          "onClick": onClick
+        }, [vue.createVNode("div", {
+          "class": bem$17("node")
+        }, [renderLoading()]), (_a = slots.background) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const Switch = withInstall(stdin_default$1l);
+  const [name$1a, bem$16] = createNamespace("address-edit-detail");
+  const t$i = createNamespace("address-edit")[2];
+  var stdin_default$1k = vue.defineComponent({
+    name: name$1a,
+    props: {
+      show: Boolean,
+      rows: numericProp,
+      value: String,
+      rules: Array,
+      focused: Boolean,
+      maxlength: numericProp,
+      searchResult: Array,
+      showSearchResult: Boolean
+    },
+    emits: ["blur", "focus", "input", "selectSearch"],
+    setup(props, {
+      emit
+    }) {
+      const field = vue.ref();
+      const showSearchResult = () => props.focused && props.searchResult && props.showSearchResult;
+      const onSelect = (express) => {
+        emit("selectSearch", express);
+        emit("input", `${express.address || ""} ${express.name || ""}`.trim());
+      };
+      const renderSearchResult = () => {
+        if (!showSearchResult()) {
+          return;
+        }
+        const {
+          searchResult
+        } = props;
+        return searchResult.map((express) => vue.createVNode(Cell, {
+          "clickable": true,
+          "key": (express.name || "") + (express.address || ""),
+          "icon": "location-o",
+          "title": express.name,
+          "label": express.address,
+          "class": bem$16("search-item"),
+          "border": false,
+          "onClick": () => onSelect(express)
+        }, null));
+      };
+      const onBlur = (event) => emit("blur", event);
+      const onFocus = (event) => emit("focus", event);
+      const onInput = (value) => emit("input", value);
+      return () => {
+        if (props.show) {
+          return vue.createVNode(vue.Fragment, null, [vue.createVNode(Field, {
+            "autosize": true,
+            "clearable": true,
+            "ref": field,
+            "class": bem$16(),
+            "rows": props.rows,
+            "type": "textarea",
+            "rules": props.rules,
+            "label": t$i("addressDetail"),
+            "border": !showSearchResult(),
+            "maxlength": props.maxlength,
+            "modelValue": props.value,
+            "placeholder": t$i("addressDetail"),
+            "onBlur": onBlur,
+            "onFocus": onFocus,
+            "onUpdate:modelValue": onInput
+          }, null), renderSearchResult()]);
+        }
+      };
+    }
+  });
+  const [name$19, bem$15, t$h] = createNamespace("address-edit");
+  const DEFAULT_DATA = {
+    name: "",
+    tel: "",
+    city: "",
+    county: "",
+    country: "",
+    province: "",
+    areaCode: "",
+    isDefault: false,
+    addressDetail: ""
+  };
+  const addressEditProps = {
+    areaList: Object,
+    isSaving: Boolean,
+    isDeleting: Boolean,
+    validator: Function,
+    showArea: truthProp,
+    showDetail: truthProp,
+    showDelete: Boolean,
+    disableArea: Boolean,
+    searchResult: Array,
+    telMaxlength: numericProp,
+    showSetDefault: Boolean,
+    saveButtonText: String,
+    areaPlaceholder: String,
+    deleteButtonText: String,
+    showSearchResult: Boolean,
+    detailRows: makeNumericProp(1),
+    detailMaxlength: makeNumericProp(200),
+    areaColumnsPlaceholder: makeArrayProp(),
+    addressInfo: {
+      type: Object,
+      default: () => extend({}, DEFAULT_DATA)
+    },
+    telValidator: {
+      type: Function,
+      default: isMobile
+    }
+  };
+  var stdin_default$1j = vue.defineComponent({
+    name: name$19,
+    props: addressEditProps,
+    emits: ["save", "focus", "delete", "clickArea", "changeArea", "changeDetail", "selectSearch", "changeDefault"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const areaRef = vue.ref();
+      const data = vue.reactive({});
+      const showAreaPopup = vue.ref(false);
+      const detailFocused = vue.ref(false);
+      const areaListLoaded = vue.computed(() => isObject(props.areaList) && Object.keys(props.areaList).length);
+      const areaText = vue.computed(() => {
+        const {
+          province,
+          city,
+          county,
+          areaCode
+        } = data;
+        if (areaCode) {
+          const arr = [province, city, county];
+          if (province && province === city) {
+            arr.splice(1, 1);
+          }
+          return arr.filter(Boolean).join("/");
+        }
+        return "";
+      });
+      const hideBottomFields = vue.computed(() => {
+        var _a;
+        return ((_a = props.searchResult) == null ? void 0 : _a.length) && detailFocused.value;
+      });
+      const onFocus = (key) => {
+        detailFocused.value = key === "addressDetail";
+        emit("focus", key);
+      };
+      const rules = vue.computed(() => {
+        const {
+          validator,
+          telValidator
+        } = props;
+        const makeRule = (name2, emptyMessage) => ({
+          validator: (value) => {
+            if (validator) {
+              const message = validator(name2, value);
+              if (message) {
+                return message;
+              }
+            }
+            if (!value) {
+              return emptyMessage;
+            }
+            return true;
+          }
+        });
+        return {
+          name: [makeRule("name", t$h("nameEmpty"))],
+          tel: [makeRule("tel", t$h("telInvalid")), {
+            validator: telValidator,
+            message: t$h("telInvalid")
+          }],
+          areaCode: [makeRule("areaCode", t$h("areaEmpty"))],
+          addressDetail: [makeRule("addressDetail", t$h("addressEmpty"))]
+        };
+      });
+      const onSave = () => emit("save", data);
+      const onChangeDetail = (val) => {
+        data.addressDetail = val;
+        emit("changeDetail", val);
+      };
+      const assignAreaText = (options) => {
+        data.province = options[0].text;
+        data.city = options[1].text;
+        data.county = options[2].text;
+      };
+      const onAreaConfirm = ({
+        selectedValues,
+        selectedOptions
+      }) => {
+        if (selectedValues.some((value) => value === AREA_EMPTY_CODE)) {
+          showToast(t$h("areaEmpty"));
+        } else {
+          showAreaPopup.value = false;
+          assignAreaText(selectedOptions);
+          emit("changeArea", selectedOptions);
+        }
+      };
+      const onDelete = () => emit("delete", data);
+      const setAreaCode = (code) => {
+        data.areaCode = code || "";
+      };
+      const onDetailBlur = () => {
+        setTimeout(() => {
+          detailFocused.value = false;
+        });
+      };
+      const setAddressDetail = (value) => {
+        data.addressDetail = value;
+      };
+      const renderSetDefaultCell = () => {
+        if (props.showSetDefault) {
+          const slots2 = {
+            "right-icon": () => vue.createVNode(Switch, {
+              "modelValue": data.isDefault,
+              "onUpdate:modelValue": ($event) => data.isDefault = $event,
+              "onChange": (event) => emit("changeDefault", event)
+            }, null)
+          };
+          return vue.withDirectives(vue.createVNode(Cell, {
+            "center": true,
+            "title": t$h("defaultAddress"),
+            "class": bem$15("default")
+          }, slots2), [[vue.vShow, !hideBottomFields.value]]);
+        }
+      };
+      useExpose({
+        setAreaCode,
+        setAddressDetail
+      });
+      vue.watch(() => props.addressInfo, (value) => {
+        extend(data, DEFAULT_DATA, value);
+        vue.nextTick(() => {
+          var _a;
+          const options = (_a = areaRef.value) == null ? void 0 : _a.getSelectedOptions();
+          if (options && options.every((option) => option && option.value !== AREA_EMPTY_CODE)) {
+            assignAreaText(options);
+          }
+        });
+      }, {
+        deep: true,
+        immediate: true
+      });
+      return () => {
+        const {
+          disableArea
+        } = props;
+        return vue.createVNode(Form, {
+          "class": bem$15(),
+          "onSubmit": onSave
+        }, {
+          default: () => {
+            var _a;
+            return [vue.createVNode("div", {
+              "class": bem$15("fields")
+            }, [vue.createVNode(Field, {
+              "modelValue": data.name,
+              "onUpdate:modelValue": ($event) => data.name = $event,
+              "clearable": true,
+              "label": t$h("name"),
+              "rules": rules.value.name,
+              "placeholder": t$h("name"),
+              "onFocus": () => onFocus("name")
+            }, null), vue.createVNode(Field, {
+              "modelValue": data.tel,
+              "onUpdate:modelValue": ($event) => data.tel = $event,
+              "clearable": true,
+              "type": "tel",
+              "label": t$h("tel"),
+              "rules": rules.value.tel,
+              "maxlength": props.telMaxlength,
+              "placeholder": t$h("tel"),
+              "onFocus": () => onFocus("tel")
+            }, null), vue.withDirectives(vue.createVNode(Field, {
+              "readonly": true,
+              "label": t$h("area"),
+              "is-link": !disableArea,
+              "modelValue": areaText.value,
+              "rules": rules.value.areaCode,
+              "placeholder": props.areaPlaceholder || t$h("area"),
+              "onFocus": () => onFocus("areaCode"),
+              "onClick": () => {
+                emit("clickArea");
+                showAreaPopup.value = !disableArea;
+              }
+            }, null), [[vue.vShow, props.showArea]]), vue.createVNode(stdin_default$1k, {
+              "show": props.showDetail,
+              "rows": props.detailRows,
+              "rules": rules.value.addressDetail,
+              "value": data.addressDetail,
+              "focused": detailFocused.value,
+              "maxlength": props.detailMaxlength,
+              "searchResult": props.searchResult,
+              "showSearchResult": props.showSearchResult,
+              "onBlur": onDetailBlur,
+              "onFocus": () => onFocus("addressDetail"),
+              "onInput": onChangeDetail,
+              "onSelectSearch": (event) => emit("selectSearch", event)
+            }, null), (_a = slots.default) == null ? void 0 : _a.call(slots)]), renderSetDefaultCell(), vue.withDirectives(vue.createVNode("div", {
+              "class": bem$15("buttons")
+            }, [vue.createVNode(Button, {
+              "block": true,
+              "round": true,
+              "type": "primary",
+              "text": props.saveButtonText || t$h("save"),
+              "class": bem$15("button"),
+              "loading": props.isSaving,
+              "nativeType": "submit"
+            }, null), props.showDelete && vue.createVNode(Button, {
+              "block": true,
+              "round": true,
+              "class": bem$15("button"),
+              "loading": props.isDeleting,
+              "text": props.deleteButtonText || t$h("delete"),
+              "onClick": onDelete
+            }, null)]), [[vue.vShow, !hideBottomFields.value]]), vue.createVNode(Popup, {
+              "show": showAreaPopup.value,
+              "onUpdate:show": ($event) => showAreaPopup.value = $event,
+              "round": true,
+              "teleport": "body",
+              "position": "bottom",
+              "lazyRender": false
+            }, {
+              default: () => [vue.createVNode(Area, {
+                "modelValue": data.areaCode,
+                "onUpdate:modelValue": ($event) => data.areaCode = $event,
+                "ref": areaRef,
+                "loading": !areaListLoaded.value,
+                "areaList": props.areaList,
+                "columnsPlaceholder": props.areaColumnsPlaceholder,
+                "onConfirm": onAreaConfirm,
+                "onCancel": () => {
+                  showAreaPopup.value = false;
+                }
+              }, null)]
+            })];
+          }
+        });
+      };
+    }
+  });
+  const AddressEdit = withInstall(stdin_default$1j);
+  const [name$18, bem$14] = createNamespace("radio-group");
+  const radioGroupProps = {
+    disabled: Boolean,
+    iconSize: numericProp,
+    direction: String,
+    modelValue: unknownProp,
+    checkedColor: String
+  };
+  const RADIO_KEY = Symbol(name$18);
+  var stdin_default$1i = vue.defineComponent({
+    name: name$18,
+    props: radioGroupProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        linkChildren
+      } = useChildren(RADIO_KEY);
+      const updateValue = (value) => emit("update:modelValue", value);
+      vue.watch(() => props.modelValue, (value) => emit("change", value));
+      linkChildren({
+        props,
+        updateValue
+      });
+      useCustomFieldValue(() => props.modelValue);
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "class": bem$14([props.direction]),
+          "role": "radiogroup"
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const RadioGroup = withInstall(stdin_default$1i);
+  const [name$17, bem$13] = createNamespace("tag");
+  const tagProps = {
+    size: String,
+    mark: Boolean,
+    show: truthProp,
+    type: makeStringProp("default"),
+    color: String,
+    plain: Boolean,
+    round: Boolean,
+    textColor: String,
+    closeable: Boolean
+  };
+  var stdin_default$1h = vue.defineComponent({
+    name: name$17,
+    props: tagProps,
+    emits: ["close"],
+    setup(props, {
+      slots,
+      emit
+    }) {
+      const onClose = (event) => {
+        event.stopPropagation();
+        emit("close", event);
+      };
+      const getStyle = () => {
+        if (props.plain) {
+          return {
+            color: props.textColor || props.color,
+            borderColor: props.color
+          };
+        }
+        return {
+          color: props.textColor,
+          background: props.color
+        };
+      };
+      const renderTag = () => {
+        var _a;
+        const {
+          type,
+          mark,
+          plain,
+          round: round2,
+          size,
+          closeable
+        } = props;
+        const classes = {
+          mark,
+          plain,
+          round: round2
+        };
+        if (size) {
+          classes[size] = size;
+        }
+        const CloseIcon = closeable && vue.createVNode(Icon, {
+          "name": "cross",
+          "class": [bem$13("close"), HAPTICS_FEEDBACK],
+          "onClick": onClose
+        }, null);
+        return vue.createVNode("span", {
+          "style": getStyle(),
+          "class": bem$13([classes, type])
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots), CloseIcon]);
+      };
+      return () => vue.createVNode(vue.Transition, {
+        "name": props.closeable ? "van-fade" : void 0
+      }, {
+        default: () => [props.show ? renderTag() : null]
+      });
+    }
+  });
+  const Tag = withInstall(stdin_default$1h);
+  const checkerProps = {
+    name: unknownProp,
+    shape: makeStringProp("round"),
+    disabled: Boolean,
+    iconSize: numericProp,
+    modelValue: unknownProp,
+    checkedColor: String,
+    labelPosition: String,
+    labelDisabled: Boolean
+  };
+  var stdin_default$1g = vue.defineComponent({
+    props: extend({}, checkerProps, {
+      bem: makeRequiredProp(Function),
+      role: String,
+      parent: Object,
+      checked: Boolean,
+      bindGroup: truthProp
+    }),
+    emits: ["click", "toggle"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const iconRef = vue.ref();
+      const getParentProp = (name2) => {
+        if (props.parent && props.bindGroup) {
+          return props.parent.props[name2];
+        }
+      };
+      const disabled = vue.computed(() => getParentProp("disabled") || props.disabled);
+      const direction = vue.computed(() => getParentProp("direction"));
+      const iconStyle = vue.computed(() => {
+        const checkedColor = props.checkedColor || getParentProp("checkedColor");
+        if (checkedColor && props.checked && !disabled.value) {
+          return {
+            borderColor: checkedColor,
+            backgroundColor: checkedColor
+          };
+        }
+      });
+      const onClick = (event) => {
+        const {
+          target
+        } = event;
+        const icon = iconRef.value;
+        const iconClicked = icon === target || (icon == null ? void 0 : icon.contains(target));
+        if (!disabled.value && (iconClicked || !props.labelDisabled)) {
+          emit("toggle");
+        }
+        emit("click", event);
+      };
+      const renderIcon = () => {
+        const {
+          bem: bem2,
+          shape,
+          checked
+        } = props;
+        const iconSize = props.iconSize || getParentProp("iconSize");
+        return vue.createVNode("div", {
+          "ref": iconRef,
+          "class": bem2("icon", [shape, {
+            disabled: disabled.value,
+            checked
+          }]),
+          "style": {
+            fontSize: addUnit(iconSize)
+          }
+        }, [slots.icon ? slots.icon({
+          checked,
+          disabled: disabled.value
+        }) : vue.createVNode(Icon, {
+          "name": "success",
+          "style": iconStyle.value
+        }, null)]);
+      };
+      const renderLabel = () => {
+        if (slots.default) {
+          return vue.createVNode("span", {
+            "class": props.bem("label", [props.labelPosition, {
+              disabled: disabled.value
+            }])
+          }, [slots.default()]);
+        }
+      };
+      return () => {
+        const nodes = props.labelPosition === "left" ? [renderLabel(), renderIcon()] : [renderIcon(), renderLabel()];
+        return vue.createVNode("div", {
+          "role": props.role,
+          "class": props.bem([{
+            disabled: disabled.value,
+            "label-disabled": props.labelDisabled
+          }, direction.value]),
+          "tabindex": disabled.value ? void 0 : 0,
+          "aria-checked": props.checked,
+          "onClick": onClick
+        }, [nodes]);
+      };
+    }
+  });
+  const radioProps = checkerProps;
+  const [name$16, bem$12] = createNamespace("radio");
+  var stdin_default$1f = vue.defineComponent({
+    name: name$16,
+    props: checkerProps,
+    emits: ["update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        parent
+      } = useParent(RADIO_KEY);
+      const checked = () => {
+        const value = parent ? parent.props.modelValue : props.modelValue;
+        return value === props.name;
+      };
+      const toggle = () => {
+        if (parent) {
+          parent.updateValue(props.name);
+        } else {
+          emit("update:modelValue", props.name);
+        }
+      };
+      return () => vue.createVNode(stdin_default$1g, vue.mergeProps({
+        "bem": bem$12,
+        "role": "radio",
+        "parent": parent,
+        "checked": checked(),
+        "onToggle": toggle
+      }, props), pick(slots, ["default", "icon"]));
+    }
+  });
+  const Radio = withInstall(stdin_default$1f);
+  const [name$15, bem$11] = createNamespace("address-item");
+  var stdin_default$1e = vue.defineComponent({
+    name: name$15,
+    props: {
+      address: makeRequiredProp(Object),
+      disabled: Boolean,
+      switchable: Boolean,
+      defaultTagText: String
+    },
+    emits: ["edit", "click", "select"],
+    setup(props, {
+      slots,
+      emit
+    }) {
+      const onClick = () => {
+        if (props.switchable) {
+          emit("select");
+        }
+        emit("click");
+      };
+      const renderRightIcon = () => vue.createVNode(Icon, {
+        "name": "edit",
+        "class": bem$11("edit"),
+        "onClick": (event) => {
+          event.stopPropagation();
+          emit("edit");
+          emit("click");
+        }
+      }, null);
+      const renderTag = () => {
+        if (slots.tag) {
+          return slots.tag(props.address);
+        }
+        if (props.address.isDefault && props.defaultTagText) {
+          return vue.createVNode(Tag, {
+            "type": "primary",
+            "round": true,
+            "class": bem$11("tag")
+          }, {
+            default: () => [props.defaultTagText]
+          });
+        }
+      };
+      const renderContent = () => {
+        const {
+          address,
+          disabled,
+          switchable
+        } = props;
+        const Info = [vue.createVNode("div", {
+          "class": bem$11("name")
+        }, [`${address.name} ${address.tel}`, renderTag()]), vue.createVNode("div", {
+          "class": bem$11("address")
+        }, [address.address])];
+        if (switchable && !disabled) {
+          return vue.createVNode(Radio, {
+            "name": address.id,
+            "iconSize": 18
+          }, {
+            default: () => [Info]
+          });
+        }
+        return Info;
+      };
+      return () => {
+        var _a;
+        const {
+          disabled
+        } = props;
+        return vue.createVNode("div", {
+          "class": bem$11({
+            disabled
+          }),
+          "onClick": onClick
+        }, [vue.createVNode(Cell, {
+          "border": false,
+          "titleClass": bem$11("title")
+        }, {
+          title: renderContent,
+          "right-icon": renderRightIcon
+        }), (_a = slots.bottom) == null ? void 0 : _a.call(slots, extend({}, props.address, {
+          disabled
+        }))]);
+      };
+    }
+  });
+  const [name$14, bem$10, t$g] = createNamespace("address-list");
+  const addressListProps = {
+    list: makeArrayProp(),
+    modelValue: numericProp,
+    switchable: truthProp,
+    disabledText: String,
+    disabledList: makeArrayProp(),
+    addButtonText: String,
+    defaultTagText: String
+  };
+  var stdin_default$1d = vue.defineComponent({
+    name: name$14,
+    props: addressListProps,
+    emits: ["add", "edit", "select", "clickItem", "editDisabled", "selectDisabled", "update:modelValue"],
+    setup(props, {
+      slots,
+      emit
+    }) {
+      const renderItem = (item, index, disabled) => {
+        const onEdit = () => emit(disabled ? "editDisabled" : "edit", item, index);
+        const onClick = () => emit("clickItem", item, index);
+        const onSelect = () => {
+          emit(disabled ? "selectDisabled" : "select", item, index);
+          if (!disabled) {
+            emit("update:modelValue", item.id);
+          }
+        };
+        return vue.createVNode(stdin_default$1e, {
+          "key": item.id,
+          "address": item,
+          "disabled": disabled,
+          "switchable": props.switchable,
+          "defaultTagText": props.defaultTagText,
+          "onEdit": onEdit,
+          "onClick": onClick,
+          "onSelect": onSelect
+        }, {
+          bottom: slots["item-bottom"],
+          tag: slots.tag
+        });
+      };
+      const renderList = (list, disabled) => {
+        if (list) {
+          return list.map((item, index) => renderItem(item, index, disabled));
+        }
+      };
+      const renderBottom = () => vue.createVNode("div", {
+        "class": [bem$10("bottom"), "van-safe-area-bottom"]
+      }, [vue.createVNode(Button, {
+        "round": true,
+        "block": true,
+        "type": "primary",
+        "text": props.addButtonText || t$g("add"),
+        "class": bem$10("add"),
+        "onClick": () => emit("add")
+      }, null)]);
+      return () => {
+        var _a, _b;
+        const List2 = renderList(props.list);
+        const DisabledList = renderList(props.disabledList, true);
+        const DisabledText = props.disabledText && vue.createVNode("div", {
+          "class": bem$10("disabled-text")
+        }, [props.disabledText]);
+        return vue.createVNode("div", {
+          "class": bem$10()
+        }, [(_a = slots.top) == null ? void 0 : _a.call(slots), vue.createVNode(RadioGroup, {
+          "modelValue": props.modelValue
+        }, {
+          default: () => [List2]
+        }), DisabledText, DisabledList, (_b = slots.default) == null ? void 0 : _b.call(slots), renderBottom()]);
+      };
+    }
+  });
+  const AddressList = withInstall(stdin_default$1d);
+  const hasIntersectionObserver = inBrowser && "IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype;
+  const modeType = {
+    event: "event",
+    observer: "observer"
+  };
+  function remove(arr, item) {
+    if (!arr.length)
+      return;
+    const index = arr.indexOf(item);
+    if (index > -1)
+      return arr.splice(index, 1);
+  }
+  function getBestSelectionFromSrcset(el, scale) {
+    if (el.tagName !== "IMG" || !el.getAttribute("data-srcset"))
+      return;
+    let options = el.getAttribute("data-srcset");
+    const container = el.parentNode;
+    const containerWidth = container.offsetWidth * scale;
+    let spaceIndex;
+    let tmpSrc;
+    let tmpWidth;
+    options = options.trim().split(",");
+    const result = options.map((item) => {
+      item = item.trim();
+      spaceIndex = item.lastIndexOf(" ");
+      if (spaceIndex === -1) {
+        tmpSrc = item;
+        tmpWidth = 999998;
+      } else {
+        tmpSrc = item.substr(0, spaceIndex);
+        tmpWidth = parseInt(
+          item.substr(spaceIndex + 1, item.length - spaceIndex - 2),
+          10
+        );
+      }
+      return [tmpWidth, tmpSrc];
+    });
+    result.sort((a, b) => {
+      if (a[0] < b[0]) {
+        return 1;
+      }
+      if (a[0] > b[0]) {
+        return -1;
+      }
+      if (a[0] === b[0]) {
+        if (b[1].indexOf(".webp", b[1].length - 5) !== -1) {
+          return 1;
+        }
+        if (a[1].indexOf(".webp", a[1].length - 5) !== -1) {
+          return -1;
+        }
+      }
+      return 0;
+    });
+    let bestSelectedSrc = "";
+    let tmpOption;
+    for (let i = 0; i < result.length; i++) {
+      tmpOption = result[i];
+      bestSelectedSrc = tmpOption[1];
+      const next = result[i + 1];
+      if (next && next[0] < containerWidth) {
+        bestSelectedSrc = tmpOption[1];
+        break;
+      } else if (!next) {
+        bestSelectedSrc = tmpOption[1];
+        break;
+      }
+    }
+    return bestSelectedSrc;
+  }
+  const getDPR = (scale = 1) => inBrowser ? window.devicePixelRatio || scale : scale;
+  function supportWebp() {
+    if (!inBrowser)
+      return false;
+    let support = true;
+    try {
+      const elem = document.createElement("canvas");
+      if (elem.getContext && elem.getContext("2d")) {
+        support = elem.toDataURL("image/webp").indexOf("data:image/webp") === 0;
+      }
+    } catch (err) {
+      support = false;
+    }
+    return support;
+  }
+  function throttle(action, delay) {
+    let timeout = null;
+    let lastRun = 0;
+    return function(...args) {
+      if (timeout) {
+        return;
+      }
+      const elapsed = Date.now() - lastRun;
+      const runCallback = () => {
+        lastRun = Date.now();
+        timeout = false;
+        action.apply(this, args);
+      };
+      if (elapsed >= delay) {
+        runCallback();
+      } else {
+        timeout = setTimeout(runCallback, delay);
+      }
+    };
+  }
+  function on(el, type, func) {
+    el.addEventListener(type, func, {
+      capture: false,
+      passive: true
+    });
+  }
+  function off(el, type, func) {
+    el.removeEventListener(type, func, false);
+  }
+  const loadImageAsync = (item, resolve, reject) => {
+    const image = new Image();
+    if (!item || !item.src) {
+      return reject(new Error("image src is required"));
+    }
+    image.src = item.src;
+    if (item.cors) {
+      image.crossOrigin = item.cors;
+    }
+    image.onload = () => resolve({
+      naturalHeight: image.naturalHeight,
+      naturalWidth: image.naturalWidth,
+      src: image.src
+    });
+    image.onerror = (e) => reject(e);
+  };
+  class ImageCache {
+    constructor({ max }) {
+      this.options = {
+        max: max || 100
+      };
+      this.caches = [];
+    }
+    has(key) {
+      return this.caches.indexOf(key) > -1;
+    }
+    add(key) {
+      if (this.has(key))
+        return;
+      this.caches.push(key);
+      if (this.caches.length > this.options.max) {
+        this.free();
+      }
+    }
+    free() {
+      this.caches.shift();
+    }
+  }
+  const [name$13, bem$$] = createNamespace("back-top");
+  const backTopProps = {
+    right: numericProp,
+    bottom: numericProp,
+    zIndex: numericProp,
+    target: [String, Object],
+    offset: makeNumericProp(200),
+    immediate: Boolean,
+    teleport: {
+      type: [String, Object],
+      default: "body"
+    }
+  };
+  var stdin_default$1c = vue.defineComponent({
+    name: name$13,
+    inheritAttrs: false,
+    props: backTopProps,
+    emits: ["click"],
+    setup(props, {
+      emit,
+      slots,
+      attrs
+    }) {
+      const show = vue.ref(false);
+      const root = vue.ref();
+      const scrollParent = vue.ref();
+      const style = vue.computed(() => extend(getZIndexStyle(props.zIndex), {
+        right: addUnit(props.right),
+        bottom: addUnit(props.bottom)
+      }));
+      const onClick = (event) => {
+        var _a;
+        emit("click", event);
+        (_a = scrollParent.value) == null ? void 0 : _a.scrollTo({
+          top: 0,
+          behavior: props.immediate ? "auto" : "smooth"
+        });
+      };
+      const scroll = () => {
+        show.value = scrollParent.value ? getScrollTop(scrollParent.value) >= +props.offset : false;
+      };
+      const getTarget = () => {
+        const {
+          target
+        } = props;
+        if (typeof target === "string") {
+          const el = document.querySelector(target);
+          if (el) {
+            return el;
+          }
+        } else {
+          return target;
+        }
+      };
+      const updateTarget = () => {
+        if (inBrowser$1) {
+          vue.nextTick(() => {
+            scrollParent.value = props.target ? getTarget() : getScrollParent$1(root.value);
+            scroll();
+          });
+        }
+      };
+      useEventListener("scroll", throttle(scroll, 100), {
+        target: scrollParent
+      });
+      vue.onMounted(updateTarget);
+      vue.watch(() => props.target, updateTarget);
+      return () => {
+        const Content = vue.createVNode("div", vue.mergeProps({
+          "ref": root,
+          "class": bem$$({
+            active: show.value
+          }),
+          "style": style.value,
+          "onClick": onClick
+        }, attrs), [slots.default ? slots.default() : vue.createVNode(Icon, {
+          "name": "back-top",
+          "class": bem$$("icon")
+        }, null)]);
+        if (props.teleport) {
+          return vue.createVNode(vue.Teleport, {
+            "to": props.teleport
+          }, {
+            default: () => [Content]
+          });
+        }
+        return Content;
+      };
+    }
+  });
+  const BackTop = withInstall(stdin_default$1c);
+  const [name$12, bem$_, t$f] = createNamespace("calendar");
+  const formatMonthTitle = (date) => t$f("monthTitle", date.getFullYear(), date.getMonth() + 1);
+  function compareMonth(date1, date2) {
+    const year1 = date1.getFullYear();
+    const year2 = date2.getFullYear();
+    if (year1 === year2) {
+      const month1 = date1.getMonth();
+      const month2 = date2.getMonth();
+      return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
+    }
+    return year1 > year2 ? 1 : -1;
+  }
+  function compareDay(day1, day2) {
+    const compareMonthResult = compareMonth(day1, day2);
+    if (compareMonthResult === 0) {
+      const date1 = day1.getDate();
+      const date2 = day2.getDate();
+      return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
+    }
+    return compareMonthResult;
+  }
+  const cloneDate = (date) => new Date(date);
+  const cloneDates = (dates) => Array.isArray(dates) ? dates.map(cloneDate) : cloneDate(dates);
+  function getDayByOffset(date, offset2) {
+    const cloned = cloneDate(date);
+    cloned.setDate(cloned.getDate() + offset2);
+    return cloned;
+  }
+  const getPrevDay = (date) => getDayByOffset(date, -1);
+  const getNextDay = (date) => getDayByOffset(date, 1);
+  const getToday = () => {
+    const today = /* @__PURE__ */ new Date();
+    today.setHours(0, 0, 0, 0);
+    return today;
+  };
+  function calcDateNum(date) {
+    const day1 = date[0].getTime();
+    const day2 = date[1].getTime();
+    return (day2 - day1) / (1e3 * 60 * 60 * 24) + 1;
+  }
+  const sharedProps = extend({}, pickerSharedProps, {
+    modelValue: makeArrayProp(),
+    filter: Function,
+    formatter: {
+      type: Function,
+      default: (type, option) => option
+    }
+  });
+  const pickerInheritKeys = Object.keys(pickerSharedProps);
+  function times(n, iteratee) {
+    if (n < 0) {
+      return [];
+    }
+    const result = Array(n);
+    let index = -1;
+    while (++index < n) {
+      result[index] = iteratee(index);
+    }
+    return result;
+  }
+  const getMonthEndDay = (year, month) => 32 - new Date(year, month - 1, 32).getDate();
+  const genOptions = (min, max, type, formatter, filter) => {
+    const options = times(max - min + 1, (index) => {
+      const value = padZero(min + index);
+      return formatter(type, {
+        text: value,
+        value
+      });
+    });
+    return filter ? filter(type, options) : options;
+  };
+  const formatValueRange = (values, columns) => values.map((value, index) => {
+    const column = columns[index];
+    if (column.length) {
+      const maxValue = +column[column.length - 1].value;
+      if (+value > maxValue) {
+        return String(maxValue);
+      }
+    }
+    return value;
+  });
+  const [name$11] = createNamespace("calendar-day");
+  var stdin_default$1b = vue.defineComponent({
+    name: name$11,
+    props: {
+      item: makeRequiredProp(Object),
+      color: String,
+      index: Number,
+      offset: makeNumberProp(0),
+      rowHeight: String
+    },
+    emits: ["click"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const style = vue.computed(() => {
+        var _a;
+        const {
+          item,
+          index,
+          color,
+          offset: offset2,
+          rowHeight
+        } = props;
+        const style2 = {
+          height: rowHeight
+        };
+        if (item.type === "placeholder") {
+          style2.width = "100%";
+          return style2;
+        }
+        if (index === 0) {
+          style2.marginLeft = `${100 * offset2 / 7}%`;
+        }
+        if (color) {
+          switch (item.type) {
+            case "end":
+            case "start":
+            case "start-end":
+            case "multiple-middle":
+            case "multiple-selected":
+              style2.background = color;
+              break;
+            case "middle":
+              style2.color = color;
+              break;
+          }
+        }
+        if (offset2 + (((_a = item.date) == null ? void 0 : _a.getDate()) || 1) > 28) {
+          style2.marginBottom = 0;
+        }
+        return style2;
+      });
+      const onClick = () => {
+        if (props.item.type !== "disabled") {
+          emit("click", props.item);
+        }
+      };
+      const renderTopInfo = () => {
+        const {
+          topInfo
+        } = props.item;
+        if (topInfo || slots["top-info"]) {
+          return vue.createVNode("div", {
+            "class": bem$_("top-info")
+          }, [slots["top-info"] ? slots["top-info"](props.item) : topInfo]);
+        }
+      };
+      const renderBottomInfo = () => {
+        const {
+          bottomInfo
+        } = props.item;
+        if (bottomInfo || slots["bottom-info"]) {
+          return vue.createVNode("div", {
+            "class": bem$_("bottom-info")
+          }, [slots["bottom-info"] ? slots["bottom-info"](props.item) : bottomInfo]);
+        }
+      };
+      const renderContent = () => {
+        const {
+          item,
+          color,
+          rowHeight
+        } = props;
+        const {
+          type,
+          text
+        } = item;
+        const Nodes = [renderTopInfo(), text, renderBottomInfo()];
+        if (type === "selected") {
+          return vue.createVNode("div", {
+            "class": bem$_("selected-day"),
+            "style": {
+              width: rowHeight,
+              height: rowHeight,
+              background: color
+            }
+          }, [Nodes]);
+        }
+        return Nodes;
+      };
+      return () => {
+        const {
+          type,
+          className
+        } = props.item;
+        if (type === "placeholder") {
+          return vue.createVNode("div", {
+            "class": bem$_("day"),
+            "style": style.value
+          }, null);
+        }
+        return vue.createVNode("div", {
+          "role": "gridcell",
+          "style": style.value,
+          "class": [bem$_("day", type), className],
+          "tabindex": type === "disabled" ? void 0 : -1,
+          "onClick": onClick
+        }, [renderContent()]);
+      };
+    }
+  });
+  const [name$10] = createNamespace("calendar-month");
+  const calendarMonthProps = {
+    date: makeRequiredProp(Date),
+    type: String,
+    color: String,
+    minDate: makeRequiredProp(Date),
+    maxDate: makeRequiredProp(Date),
+    showMark: Boolean,
+    rowHeight: numericProp,
+    formatter: Function,
+    lazyRender: Boolean,
+    currentDate: [Date, Array],
+    allowSameDay: Boolean,
+    showSubtitle: Boolean,
+    showMonthTitle: Boolean,
+    firstDayOfWeek: Number
+  };
+  var stdin_default$1a = vue.defineComponent({
+    name: name$10,
+    props: calendarMonthProps,
+    emits: ["click"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const [visible, setVisible] = useToggle();
+      const daysRef = vue.ref();
+      const monthRef = vue.ref();
+      const height2 = useHeight(monthRef);
+      const title = vue.computed(() => formatMonthTitle(props.date));
+      const rowHeight = vue.computed(() => addUnit(props.rowHeight));
+      const offset2 = vue.computed(() => {
+        const realDay = props.date.getDay();
+        if (props.firstDayOfWeek) {
+          return (realDay + 7 - props.firstDayOfWeek) % 7;
+        }
+        return realDay;
+      });
+      const totalDay = vue.computed(() => getMonthEndDay(props.date.getFullYear(), props.date.getMonth() + 1));
+      const shouldRender = vue.computed(() => visible.value || !props.lazyRender);
+      const getTitle = () => title.value;
+      const getMultipleDayType = (day) => {
+        const isSelected = (date) => props.currentDate.some((item) => compareDay(item, date) === 0);
+        if (isSelected(day)) {
+          const prevDay = getPrevDay(day);
+          const nextDay = getNextDay(day);
+          const prevSelected = isSelected(prevDay);
+          const nextSelected = isSelected(nextDay);
+          if (prevSelected && nextSelected) {
+            return "multiple-middle";
+          }
+          if (prevSelected) {
+            return "end";
+          }
+          if (nextSelected) {
+            return "start";
+          }
+          return "multiple-selected";
+        }
+        return "";
+      };
+      const getRangeDayType = (day) => {
+        const [startDay, endDay] = props.currentDate;
+        if (!startDay) {
+          return "";
+        }
+        const compareToStart = compareDay(day, startDay);
+        if (!endDay) {
+          return compareToStart === 0 ? "start" : "";
+        }
+        const compareToEnd = compareDay(day, endDay);
+        if (props.allowSameDay && compareToStart === 0 && compareToEnd === 0) {
+          return "start-end";
+        }
+        if (compareToStart === 0) {
+          return "start";
+        }
+        if (compareToEnd === 0) {
+          return "end";
+        }
+        if (compareToStart > 0 && compareToEnd < 0) {
+          return "middle";
+        }
+        return "";
+      };
+      const getDayType = (day) => {
+        const {
+          type,
+          minDate,
+          maxDate,
+          currentDate
+        } = props;
+        if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
+          return "disabled";
+        }
+        if (currentDate === null) {
+          return "";
+        }
+        if (Array.isArray(currentDate)) {
+          if (type === "multiple") {
+            return getMultipleDayType(day);
+          }
+          if (type === "range") {
+            return getRangeDayType(day);
+          }
+        } else if (type === "single") {
+          return compareDay(day, currentDate) === 0 ? "selected" : "";
+        }
+        return "";
+      };
+      const getBottomInfo = (dayType) => {
+        if (props.type === "range") {
+          if (dayType === "start" || dayType === "end") {
+            return t$f(dayType);
+          }
+          if (dayType === "start-end") {
+            return `${t$f("start")}/${t$f("end")}`;
+          }
+        }
+      };
+      const renderTitle = () => {
+        if (props.showMonthTitle) {
+          return vue.createVNode("div", {
+            "class": bem$_("month-title")
+          }, [slots["month-title"] ? slots["month-title"]({
+            date: props.date,
+            text: title.value
+          }) : title.value]);
+        }
+      };
+      const renderMark = () => {
+        if (props.showMark && shouldRender.value) {
+          return vue.createVNode("div", {
+            "class": bem$_("month-mark")
+          }, [props.date.getMonth() + 1]);
+        }
+      };
+      const placeholders = vue.computed(() => {
+        const count = Math.ceil((totalDay.value + offset2.value) / 7);
+        return Array(count).fill({
+          type: "placeholder"
+        });
+      });
+      const days = vue.computed(() => {
+        const days2 = [];
+        const year = props.date.getFullYear();
+        const month = props.date.getMonth();
+        for (let day = 1; day <= totalDay.value; day++) {
+          const date = new Date(year, month, day);
+          const type = getDayType(date);
+          let config = {
+            date,
+            type,
+            text: day,
+            bottomInfo: getBottomInfo(type)
+          };
+          if (props.formatter) {
+            config = props.formatter(config);
+          }
+          days2.push(config);
+        }
+        return days2;
+      });
+      const disabledDays = vue.computed(() => days.value.filter((day) => day.type === "disabled"));
+      const scrollToDate = (body, targetDate) => {
+        if (daysRef.value) {
+          const daysRect = useRect(daysRef.value);
+          const totalRows = placeholders.value.length;
+          const currentRow = Math.ceil((targetDate.getDate() + offset2.value) / 7);
+          const rowOffset = (currentRow - 1) * daysRect.height / totalRows;
+          setScrollTop(body, daysRect.top + rowOffset + body.scrollTop - useRect(body).top);
+        }
+      };
+      const renderDay = (item, index) => vue.createVNode(stdin_default$1b, {
+        "item": item,
+        "index": index,
+        "color": props.color,
+        "offset": offset2.value,
+        "rowHeight": rowHeight.value,
+        "onClick": (item2) => emit("click", item2)
+      }, pick(slots, ["top-info", "bottom-info"]));
+      const renderDays = () => vue.createVNode("div", {
+        "ref": daysRef,
+        "role": "grid",
+        "class": bem$_("days")
+      }, [renderMark(), (shouldRender.value ? days : placeholders).value.map(renderDay)]);
+      useExpose({
+        getTitle,
+        getHeight: () => height2.value,
+        setVisible,
+        scrollToDate,
+        disabledDays
+      });
+      return () => vue.createVNode("div", {
+        "class": bem$_("month"),
+        "ref": monthRef
+      }, [renderTitle(), renderDays()]);
+    }
+  });
+  const [name$$] = createNamespace("calendar-header");
+  var stdin_default$19 = vue.defineComponent({
+    name: name$$,
+    props: {
+      date: Date,
+      title: String,
+      subtitle: String,
+      showTitle: Boolean,
+      showSubtitle: Boolean,
+      firstDayOfWeek: Number
+    },
+    emits: ["clickSubtitle"],
+    setup(props, {
+      slots,
+      emit
+    }) {
+      const renderTitle = () => {
+        if (props.showTitle) {
+          const text = props.title || t$f("title");
+          const title = slots.title ? slots.title() : text;
+          return vue.createVNode("div", {
+            "class": bem$_("header-title")
+          }, [title]);
+        }
+      };
+      const onClickSubtitle = (event) => emit("clickSubtitle", event);
+      const renderSubtitle = () => {
+        if (props.showSubtitle) {
+          const title = slots.subtitle ? slots.subtitle({
+            date: props.date,
+            text: props.subtitle
+          }) : props.subtitle;
+          return vue.createVNode("div", {
+            "class": bem$_("header-subtitle"),
+            "onClick": onClickSubtitle
+          }, [title]);
+        }
+      };
+      const renderWeekDays = () => {
+        const {
+          firstDayOfWeek
+        } = props;
+        const weekdays = t$f("weekdays");
+        const renderWeekDays2 = [...weekdays.slice(firstDayOfWeek, 7), ...weekdays.slice(0, firstDayOfWeek)];
+        return vue.createVNode("div", {
+          "class": bem$_("weekdays")
+        }, [renderWeekDays2.map((text) => vue.createVNode("span", {
+          "class": bem$_("weekday")
+        }, [text]))]);
+      };
+      return () => vue.createVNode("div", {
+        "class": bem$_("header")
+      }, [renderTitle(), renderSubtitle(), renderWeekDays()]);
+    }
+  });
+  const calendarProps = {
+    show: Boolean,
+    type: makeStringProp("single"),
+    title: String,
+    color: String,
+    round: truthProp,
+    readonly: Boolean,
+    poppable: truthProp,
+    maxRange: makeNumericProp(null),
+    position: makeStringProp("bottom"),
+    teleport: [String, Object],
+    showMark: truthProp,
+    showTitle: truthProp,
+    formatter: Function,
+    rowHeight: numericProp,
+    confirmText: String,
+    rangePrompt: String,
+    lazyRender: truthProp,
+    showConfirm: truthProp,
+    defaultDate: [Date, Array],
+    allowSameDay: Boolean,
+    showSubtitle: truthProp,
+    closeOnPopstate: truthProp,
+    showRangePrompt: truthProp,
+    confirmDisabledText: String,
+    closeOnClickOverlay: truthProp,
+    safeAreaInsetTop: Boolean,
+    safeAreaInsetBottom: truthProp,
+    minDate: {
+      type: Date,
+      validator: isDate,
+      default: getToday
+    },
+    maxDate: {
+      type: Date,
+      validator: isDate,
+      default: () => {
+        const now = getToday();
+        return new Date(now.getFullYear(), now.getMonth() + 6, now.getDate());
+      }
+    },
+    firstDayOfWeek: {
+      type: numericProp,
+      default: 0,
+      validator: (val) => val >= 0 && val <= 6
+    }
+  };
+  var stdin_default$18 = vue.defineComponent({
+    name: name$12,
+    props: calendarProps,
+    emits: ["select", "confirm", "unselect", "monthShow", "overRange", "update:show", "clickSubtitle"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const limitDateRange = (date, minDate = props.minDate, maxDate = props.maxDate) => {
+        if (compareDay(date, minDate) === -1) {
+          return minDate;
+        }
+        if (compareDay(date, maxDate) === 1) {
+          return maxDate;
+        }
+        return date;
+      };
+      const getInitialDate = (defaultDate = props.defaultDate) => {
+        const {
+          type,
+          minDate,
+          maxDate,
+          allowSameDay
+        } = props;
+        if (defaultDate === null) {
+          return defaultDate;
+        }
+        const now = getToday();
+        if (type === "range") {
+          if (!Array.isArray(defaultDate)) {
+            defaultDate = [];
+          }
+          const start2 = limitDateRange(defaultDate[0] || now, minDate, allowSameDay ? maxDate : getPrevDay(maxDate));
+          const end2 = limitDateRange(defaultDate[1] || now, allowSameDay ? minDate : getNextDay(minDate));
+          return [start2, end2];
+        }
+        if (type === "multiple") {
+          if (Array.isArray(defaultDate)) {
+            return defaultDate.map((date) => limitDateRange(date));
+          }
+          return [limitDateRange(now)];
+        }
+        if (!defaultDate || Array.isArray(defaultDate)) {
+          defaultDate = now;
+        }
+        return limitDateRange(defaultDate);
+      };
+      let bodyHeight;
+      const bodyRef = vue.ref();
+      const subtitle = vue.ref({
+        text: "",
+        date: void 0
+      });
+      const currentDate = vue.ref(getInitialDate());
+      const [monthRefs, setMonthRefs] = useRefs();
+      const dayOffset = vue.computed(() => props.firstDayOfWeek ? +props.firstDayOfWeek % 7 : 0);
+      const months = vue.computed(() => {
+        const months2 = [];
+        const cursor = new Date(props.minDate);
+        cursor.setDate(1);
+        do {
+          months2.push(new Date(cursor));
+          cursor.setMonth(cursor.getMonth() + 1);
+        } while (compareMonth(cursor, props.maxDate) !== 1);
+        return months2;
+      });
+      const buttonDisabled = vue.computed(() => {
+        if (currentDate.value) {
+          if (props.type === "range") {
+            return !currentDate.value[0] || !currentDate.value[1];
+          }
+          if (props.type === "multiple") {
+            return !currentDate.value.length;
+          }
+        }
+        return !currentDate.value;
+      });
+      const getSelectedDate = () => currentDate.value;
+      const onScroll = () => {
+        const top2 = getScrollTop(bodyRef.value);
+        const bottom2 = top2 + bodyHeight;
+        const heights = months.value.map((item, index) => monthRefs.value[index].getHeight());
+        const heightSum = heights.reduce((a, b) => a + b, 0);
+        if (bottom2 > heightSum && top2 > 0) {
+          return;
+        }
+        let height2 = 0;
+        let currentMonth;
+        const visibleRange = [-1, -1];
+        for (let i = 0; i < months.value.length; i++) {
+          const month = monthRefs.value[i];
+          const visible = height2 <= bottom2 && height2 + heights[i] >= top2;
+          if (visible) {
+            visibleRange[1] = i;
+            if (!currentMonth) {
+              currentMonth = month;
+              visibleRange[0] = i;
+            }
+            if (!monthRefs.value[i].showed) {
+              monthRefs.value[i].showed = true;
+              emit("monthShow", {
+                date: month.date,
+                title: month.getTitle()
+              });
+            }
+          }
+          height2 += heights[i];
+        }
+        months.value.forEach((month, index) => {
+          const visible = index >= visibleRange[0] - 1 && index <= visibleRange[1] + 1;
+          monthRefs.value[index].setVisible(visible);
+        });
+        if (currentMonth) {
+          subtitle.value = {
+            text: currentMonth.getTitle(),
+            date: currentMonth.date
+          };
+        }
+      };
+      const scrollToDate = (targetDate) => {
+        raf(() => {
+          months.value.some((month, index) => {
+            if (compareMonth(month, targetDate) === 0) {
+              if (bodyRef.value) {
+                monthRefs.value[index].scrollToDate(bodyRef.value, targetDate);
+              }
+              return true;
+            }
+            return false;
+          });
+          onScroll();
+        });
+      };
+      const scrollToCurrentDate = () => {
+        if (props.poppable && !props.show) {
+          return;
+        }
+        if (currentDate.value) {
+          const targetDate = props.type === "single" ? currentDate.value : currentDate.value[0];
+          if (isDate(targetDate)) {
+            scrollToDate(targetDate);
+          }
+        } else {
+          raf(onScroll);
+        }
+      };
+      const init = () => {
+        if (props.poppable && !props.show) {
+          return;
+        }
+        raf(() => {
+          bodyHeight = Math.floor(useRect(bodyRef).height);
+        });
+        scrollToCurrentDate();
+      };
+      const reset = (date = getInitialDate()) => {
+        currentDate.value = date;
+        scrollToCurrentDate();
+      };
+      const checkRange = (date) => {
+        const {
+          maxRange,
+          rangePrompt,
+          showRangePrompt
+        } = props;
+        if (maxRange && calcDateNum(date) > +maxRange) {
+          if (showRangePrompt) {
+            showToast(rangePrompt || t$f("rangePrompt", maxRange));
+          }
+          emit("overRange");
+          return false;
+        }
+        return true;
+      };
+      const onConfirm = () => {
+        var _a;
+        return emit("confirm", (_a = currentDate.value) != null ? _a : cloneDates(currentDate.value));
+      };
+      const select = (date, complete) => {
+        const setCurrentDate = (date2) => {
+          currentDate.value = date2;
+          emit("select", cloneDates(date2));
+        };
+        if (complete && props.type === "range") {
+          const valid = checkRange(date);
+          if (!valid) {
+            setCurrentDate([date[0], getDayByOffset(date[0], +props.maxRange - 1)]);
+            return;
+          }
+        }
+        setCurrentDate(date);
+        if (complete && !props.showConfirm) {
+          onConfirm();
+        }
+      };
+      const getDisabledDate = (disabledDays2, startDay, date) => {
+        var _a;
+        return (_a = disabledDays2.find((day) => compareDay(startDay, day.date) === -1 && compareDay(day.date, date) === -1)) == null ? void 0 : _a.date;
+      };
+      const disabledDays = vue.computed(() => monthRefs.value.reduce((arr, ref2) => {
+        var _a, _b;
+        arr.push(...(_b = (_a = ref2.disabledDays) == null ? void 0 : _a.value) != null ? _b : []);
+        return arr;
+      }, []));
+      const onClickDay = (item) => {
+        if (props.readonly || !item.date) {
+          return;
+        }
+        const {
+          date
+        } = item;
+        const {
+          type
+        } = props;
+        if (type === "range") {
+          if (!currentDate.value) {
+            select([date]);
+            return;
+          }
+          const [startDay, endDay] = currentDate.value;
+          if (startDay && !endDay) {
+            const compareToStart = compareDay(date, startDay);
+            if (compareToStart === 1) {
+              const disabledDay = getDisabledDate(disabledDays.value, startDay, date);
+              if (disabledDay) {
+                const endDay2 = getPrevDay(disabledDay);
+                if (compareDay(startDay, endDay2) === -1) {
+                  select([startDay, endDay2]);
+                } else {
+                  select([date]);
+                }
+              } else {
+                select([startDay, date], true);
+              }
+            } else if (compareToStart === -1) {
+              select([date]);
+            } else if (props.allowSameDay) {
+              select([date, date], true);
+            }
+          } else {
+            select([date]);
+          }
+        } else if (type === "multiple") {
+          if (!currentDate.value) {
+            select([date]);
+            return;
+          }
+          const dates = currentDate.value;
+          const selectedIndex = dates.findIndex((dateItem) => compareDay(dateItem, date) === 0);
+          if (selectedIndex !== -1) {
+            const [unselectedDate] = dates.splice(selectedIndex, 1);
+            emit("unselect", cloneDate(unselectedDate));
+          } else if (props.maxRange && dates.length >= +props.maxRange) {
+            showToast(props.rangePrompt || t$f("rangePrompt", props.maxRange));
+          } else {
+            select([...dates, date]);
+          }
+        } else {
+          select(date, true);
+        }
+      };
+      const updateShow = (value) => emit("update:show", value);
+      const renderMonth = (date, index) => {
+        const showMonthTitle = index !== 0 || !props.showSubtitle;
+        return vue.createVNode(stdin_default$1a, vue.mergeProps({
+          "ref": setMonthRefs(index),
+          "date": date,
+          "currentDate": currentDate.value,
+          "showMonthTitle": showMonthTitle,
+          "firstDayOfWeek": dayOffset.value
+        }, pick(props, ["type", "color", "minDate", "maxDate", "showMark", "formatter", "rowHeight", "lazyRender", "showSubtitle", "allowSameDay"]), {
+          "onClick": onClickDay
+        }), pick(slots, ["top-info", "bottom-info", "month-title"]));
+      };
+      const renderFooterButton = () => {
+        if (slots.footer) {
+          return slots.footer();
+        }
+        if (props.showConfirm) {
+          const slot = slots["confirm-text"];
+          const disabled = buttonDisabled.value;
+          const text = disabled ? props.confirmDisabledText : props.confirmText;
+          return vue.createVNode(Button, {
+            "round": true,
+            "block": true,
+            "type": "primary",
+            "color": props.color,
+            "class": bem$_("confirm"),
+            "disabled": disabled,
+            "nativeType": "button",
+            "onClick": onConfirm
+          }, {
+            default: () => [slot ? slot({
+              disabled
+            }) : text || t$f("confirm")]
+          });
+        }
+      };
+      const renderFooter = () => vue.createVNode("div", {
+        "class": [bem$_("footer"), {
+          "van-safe-area-bottom": props.safeAreaInsetBottom
+        }]
+      }, [renderFooterButton()]);
+      const renderCalendar = () => vue.createVNode("div", {
+        "class": bem$_()
+      }, [vue.createVNode(stdin_default$19, {
+        "date": subtitle.value.date,
+        "title": props.title,
+        "subtitle": subtitle.value.text,
+        "showTitle": props.showTitle,
+        "showSubtitle": props.showSubtitle,
+        "firstDayOfWeek": dayOffset.value,
+        "onClickSubtitle": (event) => emit("clickSubtitle", event)
+      }, pick(slots, ["title", "subtitle"])), vue.createVNode("div", {
+        "ref": bodyRef,
+        "class": bem$_("body"),
+        "onScroll": onScroll
+      }, [months.value.map(renderMonth)]), renderFooter()]);
+      vue.watch(() => props.show, init);
+      vue.watch(() => [props.type, props.minDate, props.maxDate], () => reset(getInitialDate(currentDate.value)));
+      vue.watch(() => props.defaultDate, (value = null) => {
+        currentDate.value = value;
+        scrollToCurrentDate();
+      });
+      useExpose({
+        reset,
+        scrollToDate,
+        getSelectedDate
+      });
+      onMountedOrActivated(init);
+      return () => {
+        if (props.poppable) {
+          return vue.createVNode(Popup, {
+            "show": props.show,
+            "class": bem$_("popup"),
+            "round": props.round,
+            "position": props.position,
+            "closeable": props.showTitle || props.showSubtitle,
+            "teleport": props.teleport,
+            "closeOnPopstate": props.closeOnPopstate,
+            "safeAreaInsetTop": props.safeAreaInsetTop,
+            "closeOnClickOverlay": props.closeOnClickOverlay,
+            "onUpdate:show": updateShow
+          }, {
+            default: renderCalendar
+          });
+        }
+        return renderCalendar();
+      };
+    }
+  });
+  const Calendar = withInstall(stdin_default$18);
+  const [name$_, bem$Z] = createNamespace("image");
+  const imageProps = {
+    src: String,
+    alt: String,
+    fit: String,
+    position: String,
+    round: Boolean,
+    block: Boolean,
+    width: numericProp,
+    height: numericProp,
+    radius: numericProp,
+    lazyLoad: Boolean,
+    iconSize: numericProp,
+    showError: truthProp,
+    errorIcon: makeStringProp("photo-fail"),
+    iconPrefix: String,
+    showLoading: truthProp,
+    loadingIcon: makeStringProp("photo")
+  };
+  var stdin_default$17 = vue.defineComponent({
+    name: name$_,
+    props: imageProps,
+    emits: ["load", "error"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const error = vue.ref(false);
+      const loading = vue.ref(true);
+      const imageRef = vue.ref();
+      const {
+        $Lazyload
+      } = vue.getCurrentInstance().proxy;
+      const style = vue.computed(() => {
+        const style2 = {
+          width: addUnit(props.width),
+          height: addUnit(props.height)
+        };
+        if (isDef(props.radius)) {
+          style2.overflow = "hidden";
+          style2.borderRadius = addUnit(props.radius);
+        }
+        return style2;
+      });
+      vue.watch(() => props.src, () => {
+        error.value = false;
+        loading.value = true;
+      });
+      const onLoad = (event) => {
+        if (loading.value) {
+          loading.value = false;
+          emit("load", event);
+        }
+      };
+      const triggerLoad = () => {
+        const loadEvent = new Event("load");
+        Object.defineProperty(loadEvent, "target", {
+          value: imageRef.value,
+          enumerable: true
+        });
+        onLoad(loadEvent);
+      };
+      const onError = (event) => {
+        error.value = true;
+        loading.value = false;
+        emit("error", event);
+      };
+      const renderIcon = (name2, className, slot) => {
+        if (slot) {
+          return slot();
+        }
+        return vue.createVNode(Icon, {
+          "name": name2,
+          "size": props.iconSize,
+          "class": className,
+          "classPrefix": props.iconPrefix
+        }, null);
+      };
+      const renderPlaceholder = () => {
+        if (loading.value && props.showLoading) {
+          return vue.createVNode("div", {
+            "class": bem$Z("loading")
+          }, [renderIcon(props.loadingIcon, bem$Z("loading-icon"), slots.loading)]);
+        }
+        if (error.value && props.showError) {
+          return vue.createVNode("div", {
+            "class": bem$Z("error")
+          }, [renderIcon(props.errorIcon, bem$Z("error-icon"), slots.error)]);
+        }
+      };
+      const renderImage = () => {
+        if (error.value || !props.src) {
+          return;
+        }
+        const attrs = {
+          alt: props.alt,
+          class: bem$Z("img"),
+          style: {
+            objectFit: props.fit,
+            objectPosition: props.position
+          }
+        };
+        if (props.lazyLoad) {
+          return vue.withDirectives(vue.createVNode("img", vue.mergeProps({
+            "ref": imageRef
+          }, attrs), null), [[vue.resolveDirective("lazy"), props.src]]);
+        }
+        return vue.createVNode("img", vue.mergeProps({
+          "ref": imageRef,
+          "src": props.src,
+          "onLoad": onLoad,
+          "onError": onError
+        }, attrs), null);
+      };
+      const onLazyLoaded = ({
+        el
+      }) => {
+        const check = () => {
+          if (el === imageRef.value && loading.value) {
+            triggerLoad();
+          }
+        };
+        if (imageRef.value) {
+          check();
+        } else {
+          vue.nextTick(check);
+        }
+      };
+      const onLazyLoadError = ({
+        el
+      }) => {
+        if (el === imageRef.value && !error.value) {
+          onError();
+        }
+      };
+      if ($Lazyload && inBrowser$1) {
+        $Lazyload.$on("loaded", onLazyLoaded);
+        $Lazyload.$on("error", onLazyLoadError);
+        vue.onBeforeUnmount(() => {
+          $Lazyload.$off("loaded", onLazyLoaded);
+          $Lazyload.$off("error", onLazyLoadError);
+        });
+      }
+      vue.onMounted(() => {
+        vue.nextTick(() => {
+          var _a;
+          if ((_a = imageRef.value) == null ? void 0 : _a.complete) {
+            triggerLoad();
+          }
+        });
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "class": bem$Z({
+            round: props.round,
+            block: props.block
+          }),
+          "style": style.value
+        }, [renderImage(), renderPlaceholder(), (_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const Image$1 = withInstall(stdin_default$17);
+  const [name$Z, bem$Y] = createNamespace("card");
+  const cardProps = {
+    tag: String,
+    num: numericProp,
+    desc: String,
+    thumb: String,
+    title: String,
+    price: numericProp,
+    centered: Boolean,
+    lazyLoad: Boolean,
+    currency: makeStringProp("¥"),
+    thumbLink: String,
+    originPrice: numericProp
+  };
+  var stdin_default$16 = vue.defineComponent({
+    name: name$Z,
+    props: cardProps,
+    emits: ["clickThumb"],
+    setup(props, {
+      slots,
+      emit
+    }) {
+      const renderTitle = () => {
+        if (slots.title) {
+          return slots.title();
+        }
+        if (props.title) {
+          return vue.createVNode("div", {
+            "class": [bem$Y("title"), "van-multi-ellipsis--l2"]
+          }, [props.title]);
+        }
+      };
+      const renderThumbTag = () => {
+        if (slots.tag || props.tag) {
+          return vue.createVNode("div", {
+            "class": bem$Y("tag")
+          }, [slots.tag ? slots.tag() : vue.createVNode(Tag, {
+            "mark": true,
+            "type": "primary"
+          }, {
+            default: () => [props.tag]
+          })]);
+        }
+      };
+      const renderThumbImage = () => {
+        if (slots.thumb) {
+          return slots.thumb();
+        }
+        return vue.createVNode(Image$1, {
+          "src": props.thumb,
+          "fit": "cover",
+          "width": "100%",
+          "height": "100%",
+          "lazyLoad": props.lazyLoad
+        }, null);
+      };
+      const renderThumb = () => {
+        if (slots.thumb || props.thumb) {
+          return vue.createVNode("a", {
+            "href": props.thumbLink,
+            "class": bem$Y("thumb"),
+            "onClick": (event) => emit("clickThumb", event)
+          }, [renderThumbImage(), renderThumbTag()]);
+        }
+      };
+      const renderDesc = () => {
+        if (slots.desc) {
+          return slots.desc();
+        }
+        if (props.desc) {
+          return vue.createVNode("div", {
+            "class": [bem$Y("desc"), "van-ellipsis"]
+          }, [props.desc]);
+        }
+      };
+      const renderPriceText = () => {
+        const priceArr = props.price.toString().split(".");
+        return vue.createVNode("div", null, [vue.createVNode("span", {
+          "class": bem$Y("price-currency")
+        }, [props.currency]), vue.createVNode("span", {
+          "class": bem$Y("price-integer")
+        }, [priceArr[0]]), vue.createTextVNode("."), vue.createVNode("span", {
+          "class": bem$Y("price-decimal")
+        }, [priceArr[1]])]);
+      };
+      return () => {
+        var _a, _b, _c;
+        const showNum = slots.num || isDef(props.num);
+        const showPrice = slots.price || isDef(props.price);
+        const showOriginPrice = slots["origin-price"] || isDef(props.originPrice);
+        const showBottom = showNum || showPrice || showOriginPrice || slots.bottom;
+        const Price = showPrice && vue.createVNode("div", {
+          "class": bem$Y("price")
+        }, [slots.price ? slots.price() : renderPriceText()]);
+        const OriginPrice = showOriginPrice && vue.createVNode("div", {
+          "class": bem$Y("origin-price")
+        }, [slots["origin-price"] ? slots["origin-price"]() : `${props.currency} ${props.originPrice}`]);
+        const Num = showNum && vue.createVNode("div", {
+          "class": bem$Y("num")
+        }, [slots.num ? slots.num() : `x${props.num}`]);
+        const Footer = slots.footer && vue.createVNode("div", {
+          "class": bem$Y("footer")
+        }, [slots.footer()]);
+        const Bottom = showBottom && vue.createVNode("div", {
+          "class": bem$Y("bottom")
+        }, [(_a = slots["price-top"]) == null ? void 0 : _a.call(slots), Price, OriginPrice, Num, (_b = slots.bottom) == null ? void 0 : _b.call(slots)]);
+        return vue.createVNode("div", {
+          "class": bem$Y()
+        }, [vue.createVNode("div", {
+          "class": bem$Y("header")
+        }, [renderThumb(), vue.createVNode("div", {
+          "class": bem$Y("content", {
+            centered: props.centered
+          })
+        }, [vue.createVNode("div", null, [renderTitle(), renderDesc(), (_c = slots.tags) == null ? void 0 : _c.call(slots)]), Bottom])]), Footer]);
+      };
+    }
+  });
+  const Card = withInstall(stdin_default$16);
+  const [name$Y, bem$X, t$e] = createNamespace("cascader");
+  const cascaderProps = {
+    title: String,
+    options: makeArrayProp(),
+    closeable: truthProp,
+    swipeable: truthProp,
+    closeIcon: makeStringProp("cross"),
+    showHeader: truthProp,
+    modelValue: numericProp,
+    fieldNames: Object,
+    placeholder: String,
+    activeColor: String
+  };
+  var stdin_default$15 = vue.defineComponent({
+    name: name$Y,
+    props: cascaderProps,
+    emits: ["close", "change", "finish", "clickTab", "update:modelValue"],
+    setup(props, {
+      slots,
+      emit
+    }) {
+      const tabs = vue.ref([]);
+      const activeTab = vue.ref(0);
+      const {
+        text: textKey,
+        value: valueKey,
+        children: childrenKey
+      } = extend({
+        text: "text",
+        value: "value",
+        children: "children"
+      }, props.fieldNames);
+      const getSelectedOptionsByValue = (options, value) => {
+        for (const option of options) {
+          if (option[valueKey] === value) {
+            return [option];
+          }
+          if (option[childrenKey]) {
+            const selectedOptions = getSelectedOptionsByValue(option[childrenKey], value);
+            if (selectedOptions) {
+              return [option, ...selectedOptions];
+            }
+          }
+        }
+      };
+      const updateTabs = () => {
+        const {
+          options,
+          modelValue
+        } = props;
+        if (modelValue !== void 0) {
+          const selectedOptions = getSelectedOptionsByValue(options, modelValue);
+          if (selectedOptions) {
+            let optionsCursor = options;
+            tabs.value = selectedOptions.map((option) => {
+              const tab = {
+                options: optionsCursor,
+                selected: option
+              };
+              const next = optionsCursor.find((item) => item[valueKey] === option[valueKey]);
+              if (next) {
+                optionsCursor = next[childrenKey];
+              }
+              return tab;
+            });
+            if (optionsCursor) {
+              tabs.value.push({
+                options: optionsCursor,
+                selected: null
+              });
+            }
+            vue.nextTick(() => {
+              activeTab.value = tabs.value.length - 1;
+            });
+            return;
+          }
+        }
+        tabs.value = [{
+          options,
+          selected: null
+        }];
+      };
+      const onSelect = (option, tabIndex) => {
+        if (option.disabled) {
+          return;
+        }
+        tabs.value[tabIndex].selected = option;
+        if (tabs.value.length > tabIndex + 1) {
+          tabs.value = tabs.value.slice(0, tabIndex + 1);
+        }
+        if (option[childrenKey]) {
+          const nextTab = {
+            options: option[childrenKey],
+            selected: null
+          };
+          if (tabs.value[tabIndex + 1]) {
+            tabs.value[tabIndex + 1] = nextTab;
+          } else {
+            tabs.value.push(nextTab);
+          }
+          vue.nextTick(() => {
+            activeTab.value++;
+          });
+        }
+        const selectedOptions = tabs.value.map((tab) => tab.selected).filter(Boolean);
+        emit("update:modelValue", option[valueKey]);
+        const params = {
+          value: option[valueKey],
+          tabIndex,
+          selectedOptions
+        };
+        emit("change", params);
+        if (!option[childrenKey]) {
+          emit("finish", params);
+        }
+      };
+      const onClose = () => emit("close");
+      const onClickTab = ({
+        name: name2,
+        title
+      }) => emit("clickTab", name2, title);
+      const renderHeader = () => props.showHeader ? vue.createVNode("div", {
+        "class": bem$X("header")
+      }, [vue.createVNode("h2", {
+        "class": bem$X("title")
+      }, [slots.title ? slots.title() : props.title]), props.closeable ? vue.createVNode(Icon, {
+        "name": props.closeIcon,
+        "class": [bem$X("close-icon"), HAPTICS_FEEDBACK],
+        "onClick": onClose
+      }, null) : null]) : null;
+      const renderOption = (option, selectedOption, tabIndex) => {
+        const {
+          disabled
+        } = option;
+        const selected = !!(selectedOption && option[valueKey] === selectedOption[valueKey]);
+        const color = option.color || (selected ? props.activeColor : void 0);
+        const Text = slots.option ? slots.option({
+          option,
+          selected
+        }) : vue.createVNode("span", null, [option[textKey]]);
+        return vue.createVNode("li", {
+          "role": "menuitemradio",
+          "class": [bem$X("option", {
+            selected,
+            disabled
+          }), option.className],
+          "style": {
+            color
+          },
+          "tabindex": disabled ? void 0 : selected ? 0 : -1,
+          "aria-checked": selected,
+          "aria-disabled": disabled || void 0,
+          "onClick": () => onSelect(option, tabIndex)
+        }, [Text, selected ? vue.createVNode(Icon, {
+          "name": "success",
+          "class": bem$X("selected-icon")
+        }, null) : null]);
+      };
+      const renderOptions = (options, selectedOption, tabIndex) => vue.createVNode("ul", {
+        "role": "menu",
+        "class": bem$X("options")
+      }, [options.map((option) => renderOption(option, selectedOption, tabIndex))]);
+      const renderTab = (tab, tabIndex) => {
+        const {
+          options,
+          selected
+        } = tab;
+        const placeholder = props.placeholder || t$e("select");
+        const title = selected ? selected[textKey] : placeholder;
+        return vue.createVNode(Tab, {
+          "title": title,
+          "titleClass": bem$X("tab", {
+            unselected: !selected
+          })
+        }, {
+          default: () => {
+            var _a, _b;
+            return [(_a = slots["options-top"]) == null ? void 0 : _a.call(slots, {
+              tabIndex
+            }), renderOptions(options, selected, tabIndex), (_b = slots["options-bottom"]) == null ? void 0 : _b.call(slots, {
+              tabIndex
+            })];
+          }
+        });
+      };
+      const renderTabs = () => vue.createVNode(Tabs, {
+        "active": activeTab.value,
+        "onUpdate:active": ($event) => activeTab.value = $event,
+        "shrink": true,
+        "animated": true,
+        "class": bem$X("tabs"),
+        "color": props.activeColor,
+        "swipeable": props.swipeable,
+        "onClickTab": onClickTab
+      }, {
+        default: () => [tabs.value.map(renderTab)]
+      });
+      updateTabs();
+      vue.watch(() => props.options, updateTabs, {
+        deep: true
+      });
+      vue.watch(() => props.modelValue, (value) => {
+        if (value !== void 0) {
+          const values = tabs.value.map((tab) => {
+            var _a;
+            return (_a = tab.selected) == null ? void 0 : _a[valueKey];
+          });
+          if (values.includes(value)) {
+            return;
+          }
+        }
+        updateTabs();
+      });
+      return () => vue.createVNode("div", {
+        "class": bem$X()
+      }, [renderHeader(), renderTabs()]);
+    }
+  });
+  const Cascader = withInstall(stdin_default$15);
+  const [name$X, bem$W] = createNamespace("cell-group");
+  const cellGroupProps = {
+    title: String,
+    inset: Boolean,
+    border: truthProp
+  };
+  var stdin_default$14 = vue.defineComponent({
+    name: name$X,
+    inheritAttrs: false,
+    props: cellGroupProps,
+    setup(props, {
+      slots,
+      attrs
+    }) {
+      const renderGroup = () => {
+        var _a;
+        return vue.createVNode("div", vue.mergeProps({
+          "class": [bem$W({
+            inset: props.inset
+          }), {
+            [BORDER_TOP_BOTTOM]: props.border && !props.inset
+          }]
+        }, attrs), [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+      const renderTitle = () => vue.createVNode("div", {
+        "class": bem$W("title", {
+          inset: props.inset
+        })
+      }, [slots.title ? slots.title() : props.title]);
+      return () => {
+        if (props.title || slots.title) {
+          return vue.createVNode(vue.Fragment, null, [renderTitle(), renderGroup()]);
+        }
+        return renderGroup();
+      };
+    }
+  });
+  const CellGroup = withInstall(stdin_default$14);
+  const [name$W, bem$V] = createNamespace("checkbox-group");
+  const checkboxGroupProps = {
+    max: numericProp,
+    disabled: Boolean,
+    iconSize: numericProp,
+    direction: String,
+    modelValue: makeArrayProp(),
+    checkedColor: String
+  };
+  const CHECKBOX_GROUP_KEY = Symbol(name$W);
+  var stdin_default$13 = vue.defineComponent({
+    name: name$W,
+    props: checkboxGroupProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        children,
+        linkChildren
+      } = useChildren(CHECKBOX_GROUP_KEY);
+      const updateValue = (value) => emit("update:modelValue", value);
+      const toggleAll = (options = {}) => {
+        if (typeof options === "boolean") {
+          options = {
+            checked: options
+          };
+        }
+        const {
+          checked,
+          skipDisabled
+        } = options;
+        const checkedChildren = children.filter((item) => {
+          if (!item.props.bindGroup) {
+            return false;
+          }
+          if (item.props.disabled && skipDisabled) {
+            return item.checked.value;
+          }
+          return checked != null ? checked : !item.checked.value;
+        });
+        const names = checkedChildren.map((item) => item.name);
+        updateValue(names);
+      };
+      vue.watch(() => props.modelValue, (value) => emit("change", value));
+      useExpose({
+        toggleAll
+      });
+      useCustomFieldValue(() => props.modelValue);
+      linkChildren({
+        props,
+        updateValue
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "class": bem$V([props.direction])
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const [name$V, bem$U] = createNamespace("checkbox");
+  const checkboxProps = extend({}, checkerProps, {
+    bindGroup: truthProp
+  });
+  var stdin_default$12 = vue.defineComponent({
+    name: name$V,
+    props: checkboxProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        parent
+      } = useParent(CHECKBOX_GROUP_KEY);
+      const setParentValue = (checked2) => {
+        const {
+          name: name2
+        } = props;
+        const {
+          max,
+          modelValue
+        } = parent.props;
+        const value = modelValue.slice();
+        if (checked2) {
+          const overlimit = max && value.length >= +max;
+          if (!overlimit && !value.includes(name2)) {
+            value.push(name2);
+            if (props.bindGroup) {
+              parent.updateValue(value);
+            }
+          }
+        } else {
+          const index = value.indexOf(name2);
+          if (index !== -1) {
+            value.splice(index, 1);
+            if (props.bindGroup) {
+              parent.updateValue(value);
+            }
+          }
+        }
+      };
+      const checked = vue.computed(() => {
+        if (parent && props.bindGroup) {
+          return parent.props.modelValue.indexOf(props.name) !== -1;
+        }
+        return !!props.modelValue;
+      });
+      const toggle = (newValue = !checked.value) => {
+        if (parent && props.bindGroup) {
+          setParentValue(newValue);
+        } else {
+          emit("update:modelValue", newValue);
+        }
+      };
+      vue.watch(() => props.modelValue, (value) => emit("change", value));
+      useExpose({
+        toggle,
+        props,
+        checked
+      });
+      useCustomFieldValue(() => props.modelValue);
+      return () => vue.createVNode(stdin_default$1g, vue.mergeProps({
+        "bem": bem$U,
+        "role": "checkbox",
+        "parent": parent,
+        "checked": checked.value,
+        "onToggle": toggle
+      }, props), pick(slots, ["default", "icon"]));
+    }
+  });
+  const Checkbox = withInstall(stdin_default$12);
+  const CheckboxGroup = withInstall(stdin_default$13);
+  const [name$U, bem$T] = createNamespace("circle");
+  let uid = 0;
+  const format$1 = (rate) => Math.min(Math.max(+rate, 0), 100);
+  function getPath(clockwise, viewBoxSize) {
+    const sweepFlag = clockwise ? 1 : 0;
+    return `M ${viewBoxSize / 2} ${viewBoxSize / 2} m 0, -500 a 500, 500 0 1, ${sweepFlag} 0, 1000 a 500, 500 0 1, ${sweepFlag} 0, -1000`;
+  }
+  const circleProps = {
+    text: String,
+    size: numericProp,
+    fill: makeStringProp("none"),
+    rate: makeNumericProp(100),
+    speed: makeNumericProp(0),
+    color: [String, Object],
+    clockwise: truthProp,
+    layerColor: String,
+    currentRate: makeNumberProp(0),
+    strokeWidth: makeNumericProp(40),
+    strokeLinecap: String,
+    startPosition: makeStringProp("top")
+  };
+  var stdin_default$11 = vue.defineComponent({
+    name: name$U,
+    props: circleProps,
+    emits: ["update:currentRate"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const id = `van-circle-${uid++}`;
+      const viewBoxSize = vue.computed(() => +props.strokeWidth + 1e3);
+      const path = vue.computed(() => getPath(props.clockwise, viewBoxSize.value));
+      const svgStyle = vue.computed(() => {
+        const ROTATE_ANGLE_MAP = {
+          top: 0,
+          right: 90,
+          bottom: 180,
+          left: 270
+        };
+        const angleValue = ROTATE_ANGLE_MAP[props.startPosition];
+        if (angleValue) {
+          return {
+            transform: `rotate(${angleValue}deg)`
+          };
+        }
+      });
+      vue.watch(() => props.rate, (rate) => {
+        let rafId;
+        const startTime = Date.now();
+        const startRate = props.currentRate;
+        const endRate = format$1(rate);
+        const duration = Math.abs((startRate - endRate) * 1e3 / +props.speed);
+        const animate = () => {
+          const now = Date.now();
+          const progress = Math.min((now - startTime) / duration, 1);
+          const rate2 = progress * (endRate - startRate) + startRate;
+          emit("update:currentRate", format$1(parseFloat(rate2.toFixed(1))));
+          if (endRate > startRate ? rate2 < endRate : rate2 > endRate) {
+            rafId = raf(animate);
+          }
+        };
+        if (props.speed) {
+          if (rafId) {
+            cancelRaf(rafId);
+          }
+          rafId = raf(animate);
+        } else {
+          emit("update:currentRate", endRate);
+        }
+      }, {
+        immediate: true
+      });
+      const renderHover = () => {
+        const PERIMETER = 3140;
+        const {
+          strokeWidth,
+          currentRate,
+          strokeLinecap
+        } = props;
+        const offset2 = PERIMETER * currentRate / 100;
+        const color = isObject(props.color) ? `url(#${id})` : props.color;
+        const style = {
+          stroke: color,
+          strokeWidth: `${+strokeWidth + 1}px`,
+          strokeLinecap,
+          strokeDasharray: `${offset2}px ${PERIMETER}px`
+        };
+        return vue.createVNode("path", {
+          "d": path.value,
+          "style": style,
+          "class": bem$T("hover"),
+          "stroke": color
+        }, null);
+      };
+      const renderLayer = () => {
+        const style = {
+          fill: props.fill,
+          stroke: props.layerColor,
+          strokeWidth: `${props.strokeWidth}px`
+        };
+        return vue.createVNode("path", {
+          "class": bem$T("layer"),
+          "style": style,
+          "d": path.value
+        }, null);
+      };
+      const renderGradient = () => {
+        const {
+          color
+        } = props;
+        if (!isObject(color)) {
+          return;
+        }
+        const Stops = Object.keys(color).sort((a, b) => parseFloat(a) - parseFloat(b)).map((key, index) => vue.createVNode("stop", {
+          "key": index,
+          "offset": key,
+          "stop-color": color[key]
+        }, null));
+        return vue.createVNode("defs", null, [vue.createVNode("linearGradient", {
+          "id": id,
+          "x1": "100%",
+          "y1": "0%",
+          "x2": "0%",
+          "y2": "0%"
+        }, [Stops])]);
+      };
+      const renderText = () => {
+        if (slots.default) {
+          return slots.default();
+        }
+        if (props.text) {
+          return vue.createVNode("div", {
+            "class": bem$T("text")
+          }, [props.text]);
+        }
+      };
+      return () => vue.createVNode("div", {
+        "class": bem$T(),
+        "style": getSizeStyle(props.size)
+      }, [vue.createVNode("svg", {
+        "viewBox": `0 0 ${viewBoxSize.value} ${viewBoxSize.value}`,
+        "style": svgStyle.value
+      }, [renderGradient(), renderLayer(), renderHover()]), renderText()]);
+    }
+  });
+  const Circle = withInstall(stdin_default$11);
+  const [name$T, bem$S] = createNamespace("row");
+  const ROW_KEY = Symbol(name$T);
+  const rowProps = {
+    tag: makeStringProp("div"),
+    wrap: truthProp,
+    align: String,
+    gutter: makeNumericProp(0),
+    justify: String
+  };
+  var stdin_default$10 = vue.defineComponent({
+    name: name$T,
+    props: rowProps,
+    setup(props, {
+      slots
+    }) {
+      const {
+        children,
+        linkChildren
+      } = useChildren(ROW_KEY);
+      const groups = vue.computed(() => {
+        const groups2 = [[]];
+        let totalSpan = 0;
+        children.forEach((child, index) => {
+          totalSpan += Number(child.span);
+          if (totalSpan > 24) {
+            groups2.push([index]);
+            totalSpan -= 24;
+          } else {
+            groups2[groups2.length - 1].push(index);
+          }
+        });
+        return groups2;
+      });
+      const spaces = vue.computed(() => {
+        const gutter = Number(props.gutter);
+        const spaces2 = [];
+        if (!gutter) {
+          return spaces2;
+        }
+        groups.value.forEach((group) => {
+          const averagePadding = gutter * (group.length - 1) / group.length;
+          group.forEach((item, index) => {
+            if (index === 0) {
+              spaces2.push({
+                right: averagePadding
+              });
+            } else {
+              const left2 = gutter - spaces2[item - 1].right;
+              const right2 = averagePadding - left2;
+              spaces2.push({
+                left: left2,
+                right: right2
+              });
+            }
+          });
+        });
+        return spaces2;
+      });
+      linkChildren({
+        spaces
+      });
+      return () => {
+        const {
+          tag,
+          wrap,
+          align,
+          justify
+        } = props;
+        return vue.createVNode(tag, {
+          "class": bem$S({
+            [`align-${align}`]: align,
+            [`justify-${justify}`]: justify,
+            nowrap: !wrap
+          })
+        }, {
+          default: () => {
+            var _a;
+            return [(_a = slots.default) == null ? void 0 : _a.call(slots)];
+          }
+        });
+      };
+    }
+  });
+  const [name$S, bem$R] = createNamespace("col");
+  const colProps = {
+    tag: makeStringProp("div"),
+    span: makeNumericProp(0),
+    offset: numericProp
+  };
+  var stdin_default$$ = vue.defineComponent({
+    name: name$S,
+    props: colProps,
+    setup(props, {
+      slots
+    }) {
+      const {
+        parent,
+        index
+      } = useParent(ROW_KEY);
+      const style = vue.computed(() => {
+        if (!parent) {
+          return;
+        }
+        const {
+          spaces
+        } = parent;
+        if (spaces && spaces.value && spaces.value[index.value]) {
+          const {
+            left: left2,
+            right: right2
+          } = spaces.value[index.value];
+          return {
+            paddingLeft: left2 ? `${left2}px` : null,
+            paddingRight: right2 ? `${right2}px` : null
+          };
+        }
+      });
+      return () => {
+        const {
+          tag,
+          span,
+          offset: offset2
+        } = props;
+        return vue.createVNode(tag, {
+          "style": style.value,
+          "class": bem$R({
+            [span]: span,
+            [`offset-${offset2}`]: offset2
+          })
+        }, {
+          default: () => {
+            var _a;
+            return [(_a = slots.default) == null ? void 0 : _a.call(slots)];
+          }
+        });
+      };
+    }
+  });
+  const Col = withInstall(stdin_default$$);
+  const [name$R, bem$Q] = createNamespace("collapse");
+  const COLLAPSE_KEY = Symbol(name$R);
+  const collapseProps = {
+    border: truthProp,
+    accordion: Boolean,
+    modelValue: {
+      type: [String, Number, Array],
+      default: ""
+    }
+  };
+  var stdin_default$_ = vue.defineComponent({
+    name: name$R,
+    props: collapseProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        linkChildren,
+        children
+      } = useChildren(COLLAPSE_KEY);
+      const updateName = (name2) => {
+        emit("change", name2);
+        emit("update:modelValue", name2);
+      };
+      const toggle = (name2, expanded) => {
+        const {
+          accordion,
+          modelValue
+        } = props;
+        if (accordion) {
+          updateName(name2 === modelValue ? "" : name2);
+        } else if (expanded) {
+          updateName(modelValue.concat(name2));
+        } else {
+          updateName(modelValue.filter((activeName) => activeName !== name2));
+        }
+      };
+      const toggleAll = (options = {}) => {
+        if (props.accordion) {
+          return;
+        }
+        if (typeof options === "boolean") {
+          options = {
+            expanded: options
+          };
+        }
+        const {
+          expanded,
+          skipDisabled
+        } = options;
+        const expandedChildren = children.filter((item) => {
+          if (item.disabled && skipDisabled) {
+            return item.expanded.value;
+          }
+          return expanded != null ? expanded : !item.expanded.value;
+        });
+        const names = expandedChildren.map((item) => item.itemName.value);
+        updateName(names);
+      };
+      const isExpanded = (name2) => {
+        const {
+          accordion,
+          modelValue
+        } = props;
+        return accordion ? modelValue === name2 : modelValue.includes(name2);
+      };
+      useExpose({
+        toggleAll
+      });
+      linkChildren({
+        toggle,
+        isExpanded
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "class": [bem$Q(), {
+            [BORDER_TOP_BOTTOM]: props.border
+          }]
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const Collapse = withInstall(stdin_default$_);
+  const [name$Q, bem$P] = createNamespace("collapse-item");
+  const CELL_SLOTS = ["icon", "title", "value", "label", "right-icon"];
+  const collapseItemProps = extend({}, cellSharedProps, {
+    name: numericProp,
+    isLink: truthProp,
+    disabled: Boolean,
+    readonly: Boolean,
+    lazyRender: truthProp
+  });
+  var stdin_default$Z = vue.defineComponent({
+    name: name$Q,
+    props: collapseItemProps,
+    setup(props, {
+      slots
+    }) {
+      const wrapperRef = vue.ref();
+      const contentRef = vue.ref();
+      const {
+        parent,
+        index
+      } = useParent(COLLAPSE_KEY);
+      if (!parent) {
+        return;
+      }
+      const name2 = vue.computed(() => {
+        var _a;
+        return (_a = props.name) != null ? _a : index.value;
+      });
+      const expanded = vue.computed(() => parent.isExpanded(name2.value));
+      const show = vue.ref(expanded.value);
+      const lazyRender = useLazyRender(() => show.value || !props.lazyRender);
+      const onTransitionEnd = () => {
+        if (!expanded.value) {
+          show.value = false;
+        } else if (wrapperRef.value) {
+          wrapperRef.value.style.height = "";
+        }
+      };
+      vue.watch(expanded, (value, oldValue) => {
+        if (oldValue === null) {
+          return;
+        }
+        if (value) {
+          show.value = true;
+        }
+        const tick = value ? vue.nextTick : raf;
+        tick(() => {
+          if (!contentRef.value || !wrapperRef.value) {
+            return;
+          }
+          const {
+            offsetHeight
+          } = contentRef.value;
+          if (offsetHeight) {
+            const contentHeight = `${offsetHeight}px`;
+            wrapperRef.value.style.height = value ? "0" : contentHeight;
+            doubleRaf(() => {
+              if (wrapperRef.value) {
+                wrapperRef.value.style.height = value ? contentHeight : "0";
+              }
+            });
+          } else {
+            onTransitionEnd();
+          }
+        });
+      });
+      const toggle = (newValue = !expanded.value) => {
+        parent.toggle(name2.value, newValue);
+      };
+      const onClickTitle = () => {
+        if (!props.disabled && !props.readonly) {
+          toggle();
+        }
+      };
+      const renderTitle = () => {
+        const {
+          border,
+          disabled,
+          readonly
+        } = props;
+        const attrs = pick(props, Object.keys(cellSharedProps));
+        if (readonly) {
+          attrs.isLink = false;
+        }
+        if (disabled || readonly) {
+          attrs.clickable = false;
+        }
+        return vue.createVNode(Cell, vue.mergeProps({
+          "role": "button",
+          "class": bem$P("title", {
+            disabled,
+            expanded: expanded.value,
+            borderless: !border
+          }),
+          "aria-expanded": String(expanded.value),
+          "onClick": onClickTitle
+        }, attrs), pick(slots, CELL_SLOTS));
+      };
+      const renderContent = lazyRender(() => {
+        var _a;
+        return vue.withDirectives(vue.createVNode("div", {
+          "ref": wrapperRef,
+          "class": bem$P("wrapper"),
+          "onTransitionend": onTransitionEnd
+        }, [vue.createVNode("div", {
+          "ref": contentRef,
+          "class": bem$P("content")
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)])]), [[vue.vShow, show.value]]);
+      });
+      useExpose({
+        toggle,
+        expanded,
+        itemName: name2
+      });
+      return () => vue.createVNode("div", {
+        "class": [bem$P({
+          border: index.value && props.border
+        })]
+      }, [renderTitle(), renderContent()]);
+    }
+  });
+  const CollapseItem = withInstall(stdin_default$Z);
+  const ConfigProvider = withInstall(stdin_default$1K);
+  const [name$P, bem$O, t$d] = createNamespace("contact-card");
+  const contactCardProps = {
+    tel: String,
+    name: String,
+    type: makeStringProp("add"),
+    addText: String,
+    editable: truthProp
+  };
+  var stdin_default$Y = vue.defineComponent({
+    name: name$P,
+    props: contactCardProps,
+    emits: ["click"],
+    setup(props, {
+      emit
+    }) {
+      const onClick = (event) => {
+        if (props.editable) {
+          emit("click", event);
+        }
+      };
+      const renderContent = () => {
+        if (props.type === "add") {
+          return props.addText || t$d("addContact");
+        }
+        return [vue.createVNode("div", null, [`${t$d("name")}:${props.name}`]), vue.createVNode("div", null, [`${t$d("tel")}:${props.tel}`])];
+      };
+      return () => vue.createVNode(Cell, {
+        "center": true,
+        "icon": props.type === "edit" ? "contact" : "add-square",
+        "class": bem$O([props.type]),
+        "border": false,
+        "isLink": props.editable,
+        "titleClass": bem$O("title"),
+        "onClick": onClick
+      }, {
+        title: renderContent
+      });
+    }
+  });
+  const ContactCard = withInstall(stdin_default$Y);
+  const [name$O, bem$N, t$c] = createNamespace("contact-edit");
+  const DEFAULT_CONTACT = {
+    tel: "",
+    name: ""
+  };
+  const contactEditProps = {
+    isEdit: Boolean,
+    isSaving: Boolean,
+    isDeleting: Boolean,
+    showSetDefault: Boolean,
+    setDefaultLabel: String,
+    contactInfo: {
+      type: Object,
+      default: () => extend({}, DEFAULT_CONTACT)
+    },
+    telValidator: {
+      type: Function,
+      default: isMobile
+    }
+  };
+  var stdin_default$X = vue.defineComponent({
+    name: name$O,
+    props: contactEditProps,
+    emits: ["save", "delete", "changeDefault"],
+    setup(props, {
+      emit
+    }) {
+      const contact = vue.reactive(extend({}, DEFAULT_CONTACT, props.contactInfo));
+      const onSave = () => {
+        if (!props.isSaving) {
+          emit("save", contact);
+        }
+      };
+      const onDelete = () => emit("delete", contact);
+      const renderButtons = () => vue.createVNode("div", {
+        "class": bem$N("buttons")
+      }, [vue.createVNode(Button, {
+        "block": true,
+        "round": true,
+        "type": "primary",
+        "text": t$c("save"),
+        "class": bem$N("button"),
+        "loading": props.isSaving,
+        "nativeType": "submit"
+      }, null), props.isEdit && vue.createVNode(Button, {
+        "block": true,
+        "round": true,
+        "text": t$c("delete"),
+        "class": bem$N("button"),
+        "loading": props.isDeleting,
+        "onClick": onDelete
+      }, null)]);
+      const renderSwitch = () => vue.createVNode(Switch, {
+        "modelValue": contact.isDefault,
+        "onUpdate:modelValue": ($event) => contact.isDefault = $event,
+        "onChange": (checked) => emit("changeDefault", checked)
+      }, null);
+      const renderSetDefault = () => {
+        if (props.showSetDefault) {
+          return vue.createVNode(Cell, {
+            "title": props.setDefaultLabel,
+            "class": bem$N("switch-cell"),
+            "border": false
+          }, {
+            "right-icon": renderSwitch
+          });
+        }
+      };
+      vue.watch(() => props.contactInfo, (value) => extend(contact, DEFAULT_CONTACT, value));
+      return () => vue.createVNode(Form, {
+        "class": bem$N(),
+        "onSubmit": onSave
+      }, {
+        default: () => [vue.createVNode("div", {
+          "class": bem$N("fields")
+        }, [vue.createVNode(Field, {
+          "modelValue": contact.name,
+          "onUpdate:modelValue": ($event) => contact.name = $event,
+          "clearable": true,
+          "label": t$c("name"),
+          "rules": [{
+            required: true,
+            message: t$c("nameEmpty")
+          }],
+          "maxlength": "30",
+          "placeholder": t$c("name")
+        }, null), vue.createVNode(Field, {
+          "modelValue": contact.tel,
+          "onUpdate:modelValue": ($event) => contact.tel = $event,
+          "clearable": true,
+          "type": "tel",
+          "label": t$c("tel"),
+          "rules": [{
+            validator: props.telValidator,
+            message: t$c("telInvalid")
+          }],
+          "placeholder": t$c("tel")
+        }, null)]), renderSetDefault(), renderButtons()]
+      });
+    }
+  });
+  const ContactEdit = withInstall(stdin_default$X);
+  const [name$N, bem$M, t$b] = createNamespace("contact-list");
+  const contactListProps = {
+    list: Array,
+    addText: String,
+    modelValue: unknownProp,
+    defaultTagText: String
+  };
+  var stdin_default$W = vue.defineComponent({
+    name: name$N,
+    props: contactListProps,
+    emits: ["add", "edit", "select", "update:modelValue"],
+    setup(props, {
+      emit
+    }) {
+      const renderItem = (item, index) => {
+        const onClick = () => {
+          emit("update:modelValue", item.id);
+          emit("select", item, index);
+        };
+        const renderRightIcon = () => vue.createVNode(Radio, {
+          "class": bem$M("radio"),
+          "name": item.id,
+          "iconSize": 16
+        }, null);
+        const renderEditIcon = () => vue.createVNode(Icon, {
+          "name": "edit",
+          "class": bem$M("edit"),
+          "onClick": (event) => {
+            event.stopPropagation();
+            emit("edit", item, index);
+          }
+        }, null);
+        const renderContent = () => {
+          const nodes = [`${item.name},${item.tel}`];
+          if (item.isDefault && props.defaultTagText) {
+            nodes.push(vue.createVNode(Tag, {
+              "type": "primary",
+              "round": true,
+              "class": bem$M("item-tag")
+            }, {
+              default: () => [props.defaultTagText]
+            }));
+          }
+          return nodes;
+        };
+        return vue.createVNode(Cell, {
+          "key": item.id,
+          "isLink": true,
+          "center": true,
+          "class": bem$M("item"),
+          "titleClass": bem$M("item-title"),
+          "onClick": onClick
+        }, {
+          icon: renderEditIcon,
+          title: renderContent,
+          "right-icon": renderRightIcon
+        });
+      };
+      return () => vue.createVNode("div", {
+        "class": bem$M()
+      }, [vue.createVNode(RadioGroup, {
+        "modelValue": props.modelValue,
+        "class": bem$M("group")
+      }, {
+        default: () => [props.list && props.list.map(renderItem)]
+      }), vue.createVNode("div", {
+        "class": [bem$M("bottom"), "van-safe-area-bottom"]
+      }, [vue.createVNode(Button, {
+        "round": true,
+        "block": true,
+        "type": "primary",
+        "class": bem$M("add"),
+        "text": props.addText || t$b("addContact"),
+        "onClick": () => emit("add")
+      }, null)])]);
+    }
+  });
+  const ContactList = withInstall(stdin_default$W);
+  function parseFormat(format2, currentTime) {
+    const { days } = currentTime;
+    let { hours, minutes, seconds, milliseconds } = currentTime;
+    if (format2.includes("DD")) {
+      format2 = format2.replace("DD", padZero(days));
+    } else {
+      hours += days * 24;
+    }
+    if (format2.includes("HH")) {
+      format2 = format2.replace("HH", padZero(hours));
+    } else {
+      minutes += hours * 60;
+    }
+    if (format2.includes("mm")) {
+      format2 = format2.replace("mm", padZero(minutes));
+    } else {
+      seconds += minutes * 60;
+    }
+    if (format2.includes("ss")) {
+      format2 = format2.replace("ss", padZero(seconds));
+    } else {
+      milliseconds += seconds * 1e3;
+    }
+    if (format2.includes("S")) {
+      const ms = padZero(milliseconds, 3);
+      if (format2.includes("SSS")) {
+        format2 = format2.replace("SSS", ms);
+      } else if (format2.includes("SS")) {
+        format2 = format2.replace("SS", ms.slice(0, 2));
+      } else {
+        format2 = format2.replace("S", ms.charAt(0));
+      }
+    }
+    return format2;
+  }
+  const [name$M, bem$L] = createNamespace("count-down");
+  const countDownProps = {
+    time: makeNumericProp(0),
+    format: makeStringProp("HH:mm:ss"),
+    autoStart: truthProp,
+    millisecond: Boolean
+  };
+  var stdin_default$V = vue.defineComponent({
+    name: name$M,
+    props: countDownProps,
+    emits: ["change", "finish"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        start: start2,
+        pause,
+        reset,
+        current: current2
+      } = useCountDown({
+        time: +props.time,
+        millisecond: props.millisecond,
+        onChange: (current22) => emit("change", current22),
+        onFinish: () => emit("finish")
+      });
+      const timeText = vue.computed(() => parseFormat(props.format, current2.value));
+      const resetTime = () => {
+        reset(+props.time);
+        if (props.autoStart) {
+          start2();
+        }
+      };
+      vue.watch(() => props.time, resetTime, {
+        immediate: true
+      });
+      useExpose({
+        start: start2,
+        pause,
+        reset: resetTime
+      });
+      return () => vue.createVNode("div", {
+        "role": "timer",
+        "class": bem$L()
+      }, [slots.default ? slots.default(current2.value) : timeText.value]);
+    }
+  });
+  const CountDown = withInstall(stdin_default$V);
+  function getDate(timeStamp) {
+    const date = new Date(timeStamp * 1e3);
+    return `${date.getFullYear()}.${padZero(date.getMonth() + 1)}.${padZero(
+      date.getDate()
+    )}`;
+  }
+  const formatDiscount = (discount) => (discount / 10).toFixed(discount % 10 === 0 ? 0 : 1);
+  const formatAmount = (amount) => (amount / 100).toFixed(amount % 100 === 0 ? 0 : amount % 10 === 0 ? 1 : 2);
+  const [name$L, bem$K, t$a] = createNamespace("coupon");
+  var stdin_default$U = vue.defineComponent({
+    name: name$L,
+    props: {
+      chosen: Boolean,
+      coupon: makeRequiredProp(Object),
+      disabled: Boolean,
+      currency: makeStringProp("¥")
+    },
+    setup(props) {
+      const validPeriod = vue.computed(() => {
+        const {
+          startAt,
+          endAt
+        } = props.coupon;
+        return `${getDate(startAt)} - ${getDate(endAt)}`;
+      });
+      const faceAmount = vue.computed(() => {
+        const {
+          coupon,
+          currency
+        } = props;
+        if (coupon.valueDesc) {
+          return [coupon.valueDesc, vue.createVNode("span", null, [coupon.unitDesc || ""])];
+        }
+        if (coupon.denominations) {
+          const denominations = formatAmount(coupon.denominations);
+          return [vue.createVNode("span", null, [currency]), ` ${denominations}`];
+        }
+        if (coupon.discount) {
+          return t$a("discount", formatDiscount(coupon.discount));
+        }
+        return "";
+      });
+      const conditionMessage = vue.computed(() => {
+        const condition = formatAmount(props.coupon.originCondition || 0);
+        return condition === "0" ? t$a("unlimited") : t$a("condition", condition);
+      });
+      return () => {
+        const {
+          chosen,
+          coupon,
+          disabled
+        } = props;
+        const description = disabled && coupon.reason || coupon.description;
+        return vue.createVNode("div", {
+          "class": bem$K({
+            disabled
+          })
+        }, [vue.createVNode("div", {
+          "class": bem$K("content")
+        }, [vue.createVNode("div", {
+          "class": bem$K("head")
+        }, [vue.createVNode("h2", {
+          "class": bem$K("amount")
+        }, [faceAmount.value]), vue.createVNode("p", {
+          "class": bem$K("condition")
+        }, [coupon.condition || conditionMessage.value])]), vue.createVNode("div", {
+          "class": bem$K("body")
+        }, [vue.createVNode("p", {
+          "class": bem$K("name")
+        }, [coupon.name]), vue.createVNode("p", {
+          "class": bem$K("valid")
+        }, [validPeriod.value]), !disabled && vue.createVNode(Checkbox, {
+          "class": bem$K("corner"),
+          "modelValue": chosen
+        }, null)])]), description && vue.createVNode("p", {
+          "class": bem$K("description")
+        }, [description])]);
+      };
+    }
+  });
+  const Coupon = withInstall(stdin_default$U);
+  const [name$K, bem$J, t$9] = createNamespace("coupon-cell");
+  const couponCellProps = {
+    title: String,
+    border: truthProp,
+    editable: truthProp,
+    coupons: makeArrayProp(),
+    currency: makeStringProp("¥"),
+    chosenCoupon: makeNumericProp(-1)
+  };
+  function formatValue({
+    coupons,
+    chosenCoupon,
+    currency
+  }) {
+    const coupon = coupons[+chosenCoupon];
+    if (coupon) {
+      let value = 0;
+      if (isDef(coupon.value)) {
+        ({
+          value
+        } = coupon);
+      } else if (isDef(coupon.denominations)) {
+        value = coupon.denominations;
+      }
+      return `-${currency} ${(value / 100).toFixed(2)}`;
+    }
+    return coupons.length === 0 ? t$9("noCoupon") : t$9("count", coupons.length);
+  }
+  var stdin_default$T = vue.defineComponent({
+    name: name$K,
+    props: couponCellProps,
+    setup(props) {
+      return () => {
+        const selected = props.coupons[+props.chosenCoupon];
+        return vue.createVNode(Cell, {
+          "class": bem$J(),
+          "value": formatValue(props),
+          "title": props.title || t$9("title"),
+          "border": props.border,
+          "isLink": props.editable,
+          "valueClass": bem$J("value", {
+            selected
+          })
+        }, null);
+      };
+    }
+  });
+  const CouponCell = withInstall(stdin_default$T);
+  const [name$J, bem$I] = createNamespace("empty");
+  const emptyProps = {
+    image: makeStringProp("default"),
+    imageSize: [Number, String, Array],
+    description: String
+  };
+  var stdin_default$S = vue.defineComponent({
+    name: name$J,
+    props: emptyProps,
+    setup(props, {
+      slots
+    }) {
+      const renderDescription = () => {
+        const description = slots.description ? slots.description() : props.description;
+        if (description) {
+          return vue.createVNode("p", {
+            "class": bem$I("description")
+          }, [description]);
+        }
+      };
+      const renderBottom = () => {
+        if (slots.default) {
+          return vue.createVNode("div", {
+            "class": bem$I("bottom")
+          }, [slots.default()]);
+        }
+      };
+      const baseId = useId();
+      const getId = (num) => `${baseId}-${num}`;
+      const getUrlById = (num) => `url(#${getId(num)})`;
+      const renderStop = (color, offset2, opacity) => vue.createVNode("stop", {
+        "stop-color": color,
+        "offset": `${offset2}%`,
+        "stop-opacity": opacity
+      }, null);
+      const renderStops = (fromColor, toColor) => [renderStop(fromColor, 0), renderStop(toColor, 100)];
+      const renderShadow = (id) => [vue.createVNode("defs", null, [vue.createVNode("radialGradient", {
+        "id": getId(id),
+        "cx": "50%",
+        "cy": "54%",
+        "fx": "50%",
+        "fy": "54%",
+        "r": "297%",
+        "gradientTransform": "matrix(-.16 0 0 -.33 .58 .72)"
+      }, [renderStop("#EBEDF0", 0), renderStop("#F2F3F5", 100, 0.3)])]), vue.createVNode("ellipse", {
+        "fill": getUrlById(id),
+        "opacity": ".8",
+        "cx": "80",
+        "cy": "140",
+        "rx": "46",
+        "ry": "8"
+      }, null)];
+      const renderBuilding = () => [vue.createVNode("defs", null, [vue.createVNode("linearGradient", {
+        "id": getId("a"),
+        "x1": "64%",
+        "y1": "100%",
+        "x2": "64%"
+      }, [renderStop("#FFF", 0, 0.5), renderStop("#F2F3F5", 100)])]), vue.createVNode("g", {
+        "opacity": ".8"
+      }, [vue.createVNode("path", {
+        "d": "M36 131V53H16v20H2v58h34z",
+        "fill": getUrlById("a")
+      }, null), vue.createVNode("path", {
+        "d": "M123 15h22v14h9v77h-31V15z",
+        "fill": getUrlById("a")
+      }, null)])];
+      const renderCloud = () => [vue.createVNode("defs", null, [vue.createVNode("linearGradient", {
+        "id": getId("b"),
+        "x1": "64%",
+        "y1": "97%",
+        "x2": "64%",
+        "y2": "0%"
+      }, [renderStop("#F2F3F5", 0, 0.3), renderStop("#F2F3F5", 100)])]), vue.createVNode("g", {
+        "opacity": ".8"
+      }, [vue.createVNode("path", {
+        "d": "M87 6c3 0 7 3 8 6a8 8 0 1 1-1 16H80a7 7 0 0 1-8-6c0-4 3-7 6-7 0-5 4-9 9-9Z",
+        "fill": getUrlById("b")
+      }, null), vue.createVNode("path", {
+        "d": "M19 23c2 0 3 1 4 3 2 0 4 2 4 4a4 4 0 0 1-4 3v1h-7v-1l-1 1c-2 0-3-2-3-4 0-1 1-3 3-3 0-2 2-4 4-4Z",
+        "fill": getUrlById("b")
+      }, null)])];
+      const renderNetwork = () => vue.createVNode("svg", {
+        "viewBox": "0 0 160 160"
+      }, [vue.createVNode("defs", null, [vue.createVNode("linearGradient", {
+        "id": getId(1),
+        "x1": "64%",
+        "y1": "100%",
+        "x2": "64%"
+      }, [renderStop("#FFF", 0, 0.5), renderStop("#F2F3F5", 100)]), vue.createVNode("linearGradient", {
+        "id": getId(2),
+        "x1": "50%",
+        "x2": "50%",
+        "y2": "84%"
+      }, [renderStop("#EBEDF0", 0), renderStop("#DCDEE0", 100, 0)]), vue.createVNode("linearGradient", {
+        "id": getId(3),
+        "x1": "100%",
+        "x2": "100%",
+        "y2": "100%"
+      }, [renderStops("#EAEDF0", "#DCDEE0")]), vue.createVNode("radialGradient", {
+        "id": getId(4),
+        "cx": "50%",
+        "cy": "0%",
+        "fx": "50%",
+        "fy": "0%",
+        "r": "100%",
+        "gradientTransform": "matrix(0 1 -.54 0 .5 -.5)"
+      }, [renderStop("#EBEDF0", 0), renderStop("#FFF", 100, 0)])]), vue.createVNode("g", {
+        "fill": "none"
+      }, [renderBuilding(), vue.createVNode("path", {
+        "fill": getUrlById(4),
+        "d": "M0 139h160v21H0z"
+      }, null), vue.createVNode("path", {
+        "d": "M80 54a7 7 0 0 1 3 13v27l-2 2h-2a2 2 0 0 1-2-2V67a7 7 0 0 1 3-13z",
+        "fill": getUrlById(2)
+      }, null), vue.createVNode("g", {
+        "opacity": ".6",
+        "stroke-linecap": "round",
+        "stroke-width": "7"
+      }, [vue.createVNode("path", {
+        "d": "M64 47a19 19 0 0 0-5 13c0 5 2 10 5 13",
+        "stroke": getUrlById(3)
+      }, null), vue.createVNode("path", {
+        "d": "M53 36a34 34 0 0 0 0 48",
+        "stroke": getUrlById(3)
+      }, null), vue.createVNode("path", {
+        "d": "M95 73a19 19 0 0 0 6-13c0-5-2-9-6-13",
+        "stroke": getUrlById(3)
+      }, null), vue.createVNode("path", {
+        "d": "M106 84a34 34 0 0 0 0-48",
+        "stroke": getUrlById(3)
+      }, null)]), vue.createVNode("g", {
+        "transform": "translate(31 105)"
+      }, [vue.createVNode("rect", {
+        "fill": "#EBEDF0",
+        "width": "98",
+        "height": "34",
+        "rx": "2"
+      }, null), vue.createVNode("rect", {
+        "fill": "#FFF",
+        "x": "9",
+        "y": "8",
+        "width": "80",
+        "height": "18",
+        "rx": "1.1"
+      }, null), vue.createVNode("rect", {
+        "fill": "#EBEDF0",
+        "x": "15",
+        "y": "12",
+        "width": "18",
+        "height": "6",
+        "rx": "1.1"
+      }, null)])])]);
+      const renderMaterial = () => vue.createVNode("svg", {
+        "viewBox": "0 0 160 160"
+      }, [vue.createVNode("defs", null, [vue.createVNode("linearGradient", {
+        "x1": "50%",
+        "x2": "50%",
+        "y2": "100%",
+        "id": getId(5)
+      }, [renderStops("#F2F3F5", "#DCDEE0")]), vue.createVNode("linearGradient", {
+        "x1": "95%",
+        "y1": "48%",
+        "x2": "5.5%",
+        "y2": "51%",
+        "id": getId(6)
+      }, [renderStops("#EAEDF1", "#DCDEE0")]), vue.createVNode("linearGradient", {
+        "y1": "45%",
+        "x2": "100%",
+        "y2": "54%",
+        "id": getId(7)
+      }, [renderStops("#EAEDF1", "#DCDEE0")])]), renderBuilding(), renderCloud(), vue.createVNode("g", {
+        "transform": "translate(36 50)",
+        "fill": "none"
+      }, [vue.createVNode("g", {
+        "transform": "translate(8)"
+      }, [vue.createVNode("rect", {
+        "fill": "#EBEDF0",
+        "opacity": ".6",
+        "x": "38",
+        "y": "13",
+        "width": "36",
+        "height": "53",
+        "rx": "2"
+      }, null), vue.createVNode("rect", {
+        "fill": getUrlById(5),
+        "width": "64",
+        "height": "66",
+        "rx": "2"
+      }, null), vue.createVNode("rect", {
+        "fill": "#FFF",
+        "x": "6",
+        "y": "6",
+        "width": "52",
+        "height": "55",
+        "rx": "1"
+      }, null), vue.createVNode("g", {
+        "transform": "translate(15 17)",
+        "fill": getUrlById(6)
+      }, [vue.createVNode("rect", {
+        "width": "34",
+        "height": "6",
+        "rx": "1"
+      }, null), vue.createVNode("path", {
+        "d": "M0 14h34v6H0z"
+      }, null), vue.createVNode("rect", {
+        "y": "28",
+        "width": "34",
+        "height": "6",
+        "rx": "1"
+      }, null)])]), vue.createVNode("rect", {
+        "fill": getUrlById(7),
+        "y": "61",
+        "width": "88",
+        "height": "28",
+        "rx": "1"
+      }, null), vue.createVNode("rect", {
+        "fill": "#F7F8FA",
+        "x": "29",
+        "y": "72",
+        "width": "30",
+        "height": "6",
+        "rx": "1"
+      }, null)])]);
+      const renderError = () => vue.createVNode("svg", {
+        "viewBox": "0 0 160 160"
+      }, [vue.createVNode("defs", null, [vue.createVNode("linearGradient", {
+        "x1": "50%",
+        "x2": "50%",
+        "y2": "100%",
+        "id": getId(8)
+      }, [renderStops("#EAEDF1", "#DCDEE0")])]), renderBuilding(), renderCloud(), renderShadow("c"), vue.createVNode("path", {
+        "d": "m59 60 21 21 21-21h3l9 9v3L92 93l21 21v3l-9 9h-3l-21-21-21 21h-3l-9-9v-3l21-21-21-21v-3l9-9h3Z",
+        "fill": getUrlById(8)
+      }, null)]);
+      const renderSearch = () => vue.createVNode("svg", {
+        "viewBox": "0 0 160 160"
+      }, [vue.createVNode("defs", null, [vue.createVNode("linearGradient", {
+        "x1": "50%",
+        "y1": "100%",
+        "x2": "50%",
+        "id": getId(9)
+      }, [renderStops("#EEE", "#D8D8D8")]), vue.createVNode("linearGradient", {
+        "x1": "100%",
+        "y1": "50%",
+        "y2": "50%",
+        "id": getId(10)
+      }, [renderStops("#F2F3F5", "#DCDEE0")]), vue.createVNode("linearGradient", {
+        "x1": "50%",
+        "x2": "50%",
+        "y2": "100%",
+        "id": getId(11)
+      }, [renderStops("#F2F3F5", "#DCDEE0")]), vue.createVNode("linearGradient", {
+        "x1": "50%",
+        "x2": "50%",
+        "y2": "100%",
+        "id": getId(12)
+      }, [renderStops("#FFF", "#F7F8FA")])]), renderBuilding(), renderCloud(), renderShadow("d"), vue.createVNode("g", {
+        "transform": "rotate(-45 113 -4)",
+        "fill": "none"
+      }, [vue.createVNode("rect", {
+        "fill": getUrlById(9),
+        "x": "24",
+        "y": "52.8",
+        "width": "5.8",
+        "height": "19",
+        "rx": "1"
+      }, null), vue.createVNode("rect", {
+        "fill": getUrlById(10),
+        "x": "22.1",
+        "y": "67.3",
+        "width": "9.9",
+        "height": "28",
+        "rx": "1"
+      }, null), vue.createVNode("circle", {
+        "stroke": getUrlById(11),
+        "stroke-width": "8",
+        "cx": "27",
+        "cy": "27",
+        "r": "27"
+      }, null), vue.createVNode("circle", {
+        "fill": getUrlById(12),
+        "cx": "27",
+        "cy": "27",
+        "r": "16"
+      }, null), vue.createVNode("path", {
+        "d": "M37 7c-8 0-15 5-16 12",
+        "stroke": getUrlById(11),
+        "stroke-width": "3",
+        "opacity": ".5",
+        "stroke-linecap": "round",
+        "transform": "rotate(45 29 13)"
+      }, null)])]);
+      const renderImage = () => {
+        var _a;
+        if (slots.image) {
+          return slots.image();
+        }
+        const PRESET_IMAGES = {
+          error: renderError,
+          search: renderSearch,
+          network: renderNetwork,
+          default: renderMaterial
+        };
+        return ((_a = PRESET_IMAGES[props.image]) == null ? void 0 : _a.call(PRESET_IMAGES)) || vue.createVNode("img", {
+          "src": props.image
+        }, null);
+      };
+      return () => vue.createVNode("div", {
+        "class": bem$I()
+      }, [vue.createVNode("div", {
+        "class": bem$I("image"),
+        "style": getSizeStyle(props.imageSize)
+      }, [renderImage()]), renderDescription(), renderBottom()]);
+    }
+  });
+  const Empty = withInstall(stdin_default$S);
+  const [name$I, bem$H, t$8] = createNamespace("coupon-list");
+  const couponListProps = {
+    code: makeStringProp(""),
+    coupons: makeArrayProp(),
+    currency: makeStringProp("¥"),
+    showCount: truthProp,
+    emptyImage: String,
+    chosenCoupon: makeNumberProp(-1),
+    enabledTitle: String,
+    disabledTitle: String,
+    disabledCoupons: makeArrayProp(),
+    showExchangeBar: truthProp,
+    showCloseButton: truthProp,
+    closeButtonText: String,
+    inputPlaceholder: String,
+    exchangeMinLength: makeNumberProp(1),
+    exchangeButtonText: String,
+    displayedCouponIndex: makeNumberProp(-1),
+    exchangeButtonLoading: Boolean,
+    exchangeButtonDisabled: Boolean
+  };
+  var stdin_default$R = vue.defineComponent({
+    name: name$I,
+    props: couponListProps,
+    emits: ["change", "exchange", "update:code"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const [couponRefs, setCouponRefs] = useRefs();
+      const root = vue.ref();
+      const barRef = vue.ref();
+      const activeTab = vue.ref(0);
+      const listHeight = vue.ref(0);
+      const currentCode = vue.ref(props.code);
+      const buttonDisabled = vue.computed(() => !props.exchangeButtonLoading && (props.exchangeButtonDisabled || !currentCode.value || currentCode.value.length < props.exchangeMinLength));
+      const updateListHeight = () => {
+        const TABS_HEIGHT = 44;
+        const rootHeight = useRect(root).height;
+        const headerHeight = useRect(barRef).height + TABS_HEIGHT;
+        listHeight.value = (rootHeight > headerHeight ? rootHeight : windowHeight.value) - headerHeight;
+      };
+      const onExchange = () => {
+        emit("exchange", currentCode.value);
+        if (!props.code) {
+          currentCode.value = "";
+        }
+      };
+      const scrollToCoupon = (index) => {
+        vue.nextTick(() => {
+          var _a;
+          return (_a = couponRefs.value[index]) == null ? void 0 : _a.scrollIntoView();
+        });
+      };
+      const renderEmpty = () => vue.createVNode(Empty, {
+        "image": props.emptyImage
+      }, {
+        default: () => [vue.createVNode("p", {
+          "class": bem$H("empty-tip")
+        }, [t$8("noCoupon")])]
+      });
+      const renderExchangeBar = () => {
+        if (props.showExchangeBar) {
+          return vue.createVNode("div", {
+            "ref": barRef,
+            "class": bem$H("exchange-bar")
+          }, [vue.createVNode(Field, {
+            "modelValue": currentCode.value,
+            "onUpdate:modelValue": ($event) => currentCode.value = $event,
+            "clearable": true,
+            "border": false,
+            "class": bem$H("field"),
+            "placeholder": props.inputPlaceholder || t$8("placeholder"),
+            "maxlength": "20"
+          }, null), vue.createVNode(Button, {
+            "plain": true,
+            "type": "primary",
+            "class": bem$H("exchange"),
+            "text": props.exchangeButtonText || t$8("exchange"),
+            "loading": props.exchangeButtonLoading,
+            "disabled": buttonDisabled.value,
+            "onClick": onExchange
+          }, null)]);
+        }
+      };
+      const renderCouponTab = () => {
+        const {
+          coupons
+        } = props;
+        const count = props.showCount ? ` (${coupons.length})` : "";
+        const title = (props.enabledTitle || t$8("enable")) + count;
+        return vue.createVNode(Tab, {
+          "title": title
+        }, {
+          default: () => {
+            var _a;
+            return [vue.createVNode("div", {
+              "class": bem$H("list", {
+                "with-bottom": props.showCloseButton
+              }),
+              "style": {
+                height: `${listHeight.value}px`
+              }
+            }, [coupons.map((coupon, index) => vue.createVNode(Coupon, {
+              "key": coupon.id,
+              "ref": setCouponRefs(index),
+              "coupon": coupon,
+              "chosen": index === props.chosenCoupon,
+              "currency": props.currency,
+              "onClick": () => emit("change", index)
+            }, null)), !coupons.length && renderEmpty(), (_a = slots["list-footer"]) == null ? void 0 : _a.call(slots)])];
+          }
+        });
+      };
+      const renderDisabledTab = () => {
+        const {
+          disabledCoupons
+        } = props;
+        const count = props.showCount ? ` (${disabledCoupons.length})` : "";
+        const title = (props.disabledTitle || t$8("disabled")) + count;
+        return vue.createVNode(Tab, {
+          "title": title
+        }, {
+          default: () => {
+            var _a;
+            return [vue.createVNode("div", {
+              "class": bem$H("list", {
+                "with-bottom": props.showCloseButton
+              }),
+              "style": {
+                height: `${listHeight.value}px`
+              }
+            }, [disabledCoupons.map((coupon) => vue.createVNode(Coupon, {
+              "disabled": true,
+              "key": coupon.id,
+              "coupon": coupon,
+              "currency": props.currency
+            }, null)), !disabledCoupons.length && renderEmpty(), (_a = slots["disabled-list-footer"]) == null ? void 0 : _a.call(slots)])];
+          }
+        });
+      };
+      vue.watch(() => props.code, (value) => {
+        currentCode.value = value;
+      });
+      vue.watch(windowHeight, updateListHeight);
+      vue.watch(currentCode, (value) => emit("update:code", value));
+      vue.watch(() => props.displayedCouponIndex, scrollToCoupon);
+      vue.onMounted(() => {
+        updateListHeight();
+        scrollToCoupon(props.displayedCouponIndex);
+      });
+      return () => vue.createVNode("div", {
+        "ref": root,
+        "class": bem$H()
+      }, [renderExchangeBar(), vue.createVNode(Tabs, {
+        "active": activeTab.value,
+        "onUpdate:active": ($event) => activeTab.value = $event,
+        "class": bem$H("tab")
+      }, {
+        default: () => [renderCouponTab(), renderDisabledTab()]
+      }), vue.createVNode("div", {
+        "class": bem$H("bottom")
+      }, [vue.withDirectives(vue.createVNode(Button, {
+        "round": true,
+        "block": true,
+        "type": "primary",
+        "class": bem$H("close"),
+        "text": props.closeButtonText || t$8("close"),
+        "onClick": () => emit("change", -1)
+      }, null), [[vue.vShow, props.showCloseButton]])])]);
+    }
+  });
+  const CouponList = withInstall(stdin_default$R);
+  const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
+  const [name$H] = createNamespace("date-picker");
+  const datePickerProps = extend({}, sharedProps, {
+    columnsType: {
+      type: Array,
+      default: () => ["year", "month", "day"]
+    },
+    minDate: {
+      type: Date,
+      default: () => new Date(currentYear - 10, 0, 1),
+      validator: isDate
+    },
+    maxDate: {
+      type: Date,
+      default: () => new Date(currentYear + 10, 11, 31),
+      validator: isDate
+    }
+  });
+  var stdin_default$Q = vue.defineComponent({
+    name: name$H,
+    props: datePickerProps,
+    emits: ["confirm", "cancel", "change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const currentValues = vue.ref(props.modelValue);
+      const genYearOptions = () => {
+        const minYear = props.minDate.getFullYear();
+        const maxYear = props.maxDate.getFullYear();
+        return genOptions(minYear, maxYear, "year", props.formatter, props.filter);
+      };
+      const isMinYear = (year) => year === props.minDate.getFullYear();
+      const isMaxYear = (year) => year === props.maxDate.getFullYear();
+      const isMinMonth = (month) => month === props.minDate.getMonth() + 1;
+      const isMaxMonth = (month) => month === props.maxDate.getMonth() + 1;
+      const getValue = (type) => {
+        const {
+          minDate,
+          columnsType
+        } = props;
+        const index = columnsType.indexOf(type);
+        const value = currentValues.value[index];
+        if (value) {
+          return +value;
+        }
+        switch (type) {
+          case "year":
+            return minDate.getFullYear();
+          case "month":
+            return minDate.getMonth() + 1;
+          case "day":
+            return minDate.getDate();
+        }
+      };
+      const genMonthOptions = () => {
+        const year = getValue("year");
+        const minMonth = isMinYear(year) ? props.minDate.getMonth() + 1 : 1;
+        const maxMonth = isMaxYear(year) ? props.maxDate.getMonth() + 1 : 12;
+        return genOptions(minMonth, maxMonth, "month", props.formatter, props.filter);
+      };
+      const genDayOptions = () => {
+        const year = getValue("year");
+        const month = getValue("month");
+        const minDate = isMinYear(year) && isMinMonth(month) ? props.minDate.getDate() : 1;
+        const maxDate = isMaxYear(year) && isMaxMonth(month) ? props.maxDate.getDate() : getMonthEndDay(year, month);
+        return genOptions(minDate, maxDate, "day", props.formatter, props.filter);
+      };
+      const columns = vue.computed(() => props.columnsType.map((type) => {
+        switch (type) {
+          case "year":
+            return genYearOptions();
+          case "month":
+            return genMonthOptions();
+          case "day":
+            return genDayOptions();
+          default:
+            return [];
+        }
+      }));
+      vue.watch(currentValues, (newValues) => {
+        if (!isSameValue(newValues, props.modelValue)) {
+          emit("update:modelValue", newValues);
+        }
+      });
+      vue.watch(() => props.modelValue, (newValues) => {
+        newValues = formatValueRange(newValues, columns.value);
+        if (!isSameValue(newValues, currentValues.value)) {
+          currentValues.value = newValues;
+        }
+      }, {
+        immediate: true
+      });
+      const onChange = (...args) => emit("change", ...args);
+      const onCancel = (...args) => emit("cancel", ...args);
+      const onConfirm = (...args) => emit("confirm", ...args);
+      return () => vue.createVNode(Picker, vue.mergeProps({
+        "modelValue": currentValues.value,
+        "onUpdate:modelValue": ($event) => currentValues.value = $event,
+        "columns": columns.value,
+        "onChange": onChange,
+        "onCancel": onCancel,
+        "onConfirm": onConfirm
+      }, pick(props, pickerInheritKeys)), slots);
+    }
+  });
+  const DatePicker = withInstall(stdin_default$Q);
+  const [name$G, bem$G, t$7] = createNamespace("dialog");
+  const dialogProps = extend({}, popupSharedProps, {
+    title: String,
+    theme: String,
+    width: numericProp,
+    message: [String, Function],
+    callback: Function,
+    allowHtml: Boolean,
+    className: unknownProp,
+    transition: makeStringProp("van-dialog-bounce"),
+    messageAlign: String,
+    closeOnPopstate: truthProp,
+    showCancelButton: Boolean,
+    cancelButtonText: String,
+    cancelButtonColor: String,
+    cancelButtonDisabled: Boolean,
+    confirmButtonText: String,
+    confirmButtonColor: String,
+    confirmButtonDisabled: Boolean,
+    showConfirmButton: truthProp,
+    closeOnClickOverlay: Boolean
+  });
+  const popupInheritKeys$1 = [...popupSharedPropKeys, "transition", "closeOnPopstate"];
+  var stdin_default$P = vue.defineComponent({
+    name: name$G,
+    props: dialogProps,
+    emits: ["confirm", "cancel", "keydown", "update:show"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const root = vue.ref();
+      const loading = vue.reactive({
+        confirm: false,
+        cancel: false
+      });
+      const updateShow = (value) => emit("update:show", value);
+      const close = (action) => {
+        var _a;
+        updateShow(false);
+        (_a = props.callback) == null ? void 0 : _a.call(props, action);
+      };
+      const getActionHandler = (action) => () => {
+        if (!props.show) {
+          return;
+        }
+        emit(action);
+        if (props.beforeClose) {
+          loading[action] = true;
+          callInterceptor(props.beforeClose, {
+            args: [action],
+            done() {
+              close(action);
+              loading[action] = false;
+            },
+            canceled() {
+              loading[action] = false;
+            }
+          });
+        } else {
+          close(action);
+        }
+      };
+      const onCancel = getActionHandler("cancel");
+      const onConfirm = getActionHandler("confirm");
+      const onKeydown = vue.withKeys((event) => {
+        var _a, _b;
+        if (event.target !== ((_b = (_a = root.value) == null ? void 0 : _a.popupRef) == null ? void 0 : _b.value)) {
+          return;
+        }
+        const onEventType = {
+          Enter: props.showConfirmButton ? onConfirm : noop,
+          Escape: props.showCancelButton ? onCancel : noop
+        };
+        onEventType[event.key]();
+        emit("keydown", event);
+      }, ["enter", "esc"]);
+      const renderTitle = () => {
+        const title = slots.title ? slots.title() : props.title;
+        if (title) {
+          return vue.createVNode("div", {
+            "class": bem$G("header", {
+              isolated: !props.message && !slots.default
+            })
+          }, [title]);
+        }
+      };
+      const renderMessage = (hasTitle) => {
+        const {
+          message,
+          allowHtml,
+          messageAlign
+        } = props;
+        const classNames = bem$G("message", {
+          "has-title": hasTitle,
+          [messageAlign]: messageAlign
+        });
+        const content = isFunction(message) ? message() : message;
+        if (allowHtml && typeof content === "string") {
+          return vue.createVNode("div", {
+            "class": classNames,
+            "innerHTML": content
+          }, null);
+        }
+        return vue.createVNode("div", {
+          "class": classNames
+        }, [content]);
+      };
+      const renderContent = () => {
+        if (slots.default) {
+          return vue.createVNode("div", {
+            "class": bem$G("content")
+          }, [slots.default()]);
+        }
+        const {
+          title,
+          message,
+          allowHtml
+        } = props;
+        if (message) {
+          const hasTitle = !!(title || slots.title);
+          return vue.createVNode("div", {
+            "key": allowHtml ? 1 : 0,
+            "class": bem$G("content", {
+              isolated: !hasTitle
+            })
+          }, [renderMessage(hasTitle)]);
+        }
+      };
+      const renderButtons = () => vue.createVNode("div", {
+        "class": [BORDER_TOP, bem$G("footer")]
+      }, [props.showCancelButton && vue.createVNode(Button, {
+        "size": "large",
+        "text": props.cancelButtonText || t$7("cancel"),
+        "class": bem$G("cancel"),
+        "style": {
+          color: props.cancelButtonColor
+        },
+        "loading": loading.cancel,
+        "disabled": props.cancelButtonDisabled,
+        "onClick": onCancel
+      }, null), props.showConfirmButton && vue.createVNode(Button, {
+        "size": "large",
+        "text": props.confirmButtonText || t$7("confirm"),
+        "class": [bem$G("confirm"), {
+          [BORDER_LEFT]: props.showCancelButton
+        }],
+        "style": {
+          color: props.confirmButtonColor
+        },
+        "loading": loading.confirm,
+        "disabled": props.confirmButtonDisabled,
+        "onClick": onConfirm
+      }, null)]);
+      const renderRoundButtons = () => vue.createVNode(ActionBar, {
+        "class": bem$G("footer")
+      }, {
+        default: () => [props.showCancelButton && vue.createVNode(ActionBarButton, {
+          "type": "warning",
+          "text": props.cancelButtonText || t$7("cancel"),
+          "class": bem$G("cancel"),
+          "color": props.cancelButtonColor,
+          "loading": loading.cancel,
+          "disabled": props.cancelButtonDisabled,
+          "onClick": onCancel
+        }, null), props.showConfirmButton && vue.createVNode(ActionBarButton, {
+          "type": "danger",
+          "text": props.confirmButtonText || t$7("confirm"),
+          "class": bem$G("confirm"),
+          "color": props.confirmButtonColor,
+          "loading": loading.confirm,
+          "disabled": props.confirmButtonDisabled,
+          "onClick": onConfirm
+        }, null)]
+      });
+      const renderFooter = () => {
+        if (slots.footer) {
+          return slots.footer();
+        }
+        return props.theme === "round-button" ? renderRoundButtons() : renderButtons();
+      };
+      return () => {
+        const {
+          width: width2,
+          title,
+          theme,
+          message,
+          className
+        } = props;
+        return vue.createVNode(Popup, vue.mergeProps({
+          "ref": root,
+          "role": "dialog",
+          "class": [bem$G([theme]), className],
+          "style": {
+            width: addUnit(width2)
+          },
+          "tabindex": 0,
+          "aria-labelledby": title || message,
+          "onKeydown": onKeydown,
+          "onUpdate:show": updateShow
+        }, pick(props, popupInheritKeys$1)), {
+          default: () => [renderTitle(), renderContent(), renderFooter()]
+        });
+      };
+    }
+  });
+  let instance$2;
+  const DEFAULT_OPTIONS$1 = {
+    title: "",
+    width: "",
+    theme: null,
+    message: "",
+    overlay: true,
+    callback: null,
+    teleport: "body",
+    className: "",
+    allowHtml: false,
+    lockScroll: true,
+    transition: void 0,
+    beforeClose: null,
+    overlayClass: "",
+    overlayStyle: void 0,
+    messageAlign: "",
+    cancelButtonText: "",
+    cancelButtonColor: null,
+    cancelButtonDisabled: false,
+    confirmButtonText: "",
+    confirmButtonColor: null,
+    confirmButtonDisabled: false,
+    showConfirmButton: true,
+    showCancelButton: false,
+    closeOnPopstate: true,
+    closeOnClickOverlay: false
+  };
+  let currentOptions$1 = extend({}, DEFAULT_OPTIONS$1);
+  function initInstance$2() {
+    const Wrapper = {
+      setup() {
+        const {
+          state,
+          toggle
+        } = usePopupState();
+        return () => vue.createVNode(stdin_default$P, vue.mergeProps(state, {
+          "onUpdate:show": toggle
+        }), null);
+      }
+    };
+    ({
+      instance: instance$2
+    } = mountComponent(Wrapper));
+  }
+  function showDialog(options) {
+    if (!inBrowser$1) {
+      return Promise.resolve();
+    }
+    return new Promise((resolve, reject) => {
+      if (!instance$2) {
+        initInstance$2();
+      }
+      instance$2.open(extend({}, currentOptions$1, options, {
+        callback: (action) => {
+          (action === "confirm" ? resolve : reject)(action);
+        }
+      }));
+    });
+  }
+  const setDialogDefaultOptions = (options) => {
+    extend(currentOptions$1, options);
+  };
+  const resetDialogDefaultOptions = () => {
+    currentOptions$1 = extend({}, DEFAULT_OPTIONS$1);
+  };
+  const showConfirmDialog = (options) => showDialog(extend({
+    showCancelButton: true
+  }, options));
+  const closeDialog = () => {
+    if (instance$2) {
+      instance$2.toggle(false);
+    }
+  };
+  const Dialog = withInstall(stdin_default$P);
+  const [name$F, bem$F] = createNamespace("divider");
+  const dividerProps = {
+    dashed: Boolean,
+    hairline: truthProp,
+    contentPosition: makeStringProp("center")
+  };
+  var stdin_default$O = vue.defineComponent({
+    name: name$F,
+    props: dividerProps,
+    setup(props, {
+      slots
+    }) {
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "role": "separator",
+          "class": bem$F({
+            dashed: props.dashed,
+            hairline: props.hairline,
+            [`content-${props.contentPosition}`]: !!slots.default
+          })
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const Divider = withInstall(stdin_default$O);
+  const [name$E, bem$E] = createNamespace("dropdown-menu");
+  const dropdownMenuProps = {
+    overlay: truthProp,
+    zIndex: numericProp,
+    duration: makeNumericProp(0.2),
+    direction: makeStringProp("down"),
+    activeColor: String,
+    closeOnClickOutside: truthProp,
+    closeOnClickOverlay: truthProp
+  };
+  const DROPDOWN_KEY = Symbol(name$E);
+  var stdin_default$N = vue.defineComponent({
+    name: name$E,
+    props: dropdownMenuProps,
+    setup(props, {
+      slots
+    }) {
+      const id = useId();
+      const root = vue.ref();
+      const barRef = vue.ref();
+      const offset2 = vue.ref(0);
+      const {
+        children,
+        linkChildren
+      } = useChildren(DROPDOWN_KEY);
+      const scrollParent = useScrollParent(root);
+      const opened = vue.computed(() => children.some((item) => item.state.showWrapper));
+      const barStyle = vue.computed(() => {
+        if (opened.value && isDef(props.zIndex)) {
+          return {
+            zIndex: +props.zIndex + 1
+          };
+        }
+      });
+      const onClickAway = () => {
+        if (props.closeOnClickOutside) {
+          children.forEach((item) => {
+            item.toggle(false);
+          });
+        }
+      };
+      const updateOffset = () => {
+        if (barRef.value) {
+          const rect = useRect(barRef);
+          if (props.direction === "down") {
+            offset2.value = rect.bottom;
+          } else {
+            offset2.value = windowHeight.value - rect.top;
+          }
+        }
+      };
+      const onScroll = () => {
+        if (opened.value) {
+          updateOffset();
+        }
+      };
+      const toggleItem = (active) => {
+        children.forEach((item, index) => {
+          if (index === active) {
+            item.toggle();
+          } else if (item.state.showPopup) {
+            item.toggle(false, {
+              immediate: true
+            });
+          }
+        });
+      };
+      const renderTitle = (item, index) => {
+        const {
+          showPopup
+        } = item.state;
+        const {
+          disabled,
+          titleClass
+        } = item;
+        return vue.createVNode("div", {
+          "id": `${id}-${index}`,
+          "role": "button",
+          "tabindex": disabled ? void 0 : 0,
+          "class": [bem$E("item", {
+            disabled
+          }), {
+            [HAPTICS_FEEDBACK]: !disabled
+          }],
+          "onClick": () => {
+            if (!disabled) {
+              toggleItem(index);
+            }
+          }
+        }, [vue.createVNode("span", {
+          "class": [bem$E("title", {
+            down: showPopup === (props.direction === "down"),
+            active: showPopup
+          }), titleClass],
+          "style": {
+            color: showPopup ? props.activeColor : ""
+          }
+        }, [vue.createVNode("div", {
+          "class": "van-ellipsis"
+        }, [item.renderTitle()])])]);
+      };
+      linkChildren({
+        id,
+        props,
+        offset: offset2,
+        updateOffset
+      });
+      useClickAway(root, onClickAway);
+      useEventListener("scroll", onScroll, {
+        target: scrollParent,
+        passive: true
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "ref": root,
+          "class": bem$E()
+        }, [vue.createVNode("div", {
+          "ref": barRef,
+          "style": barStyle.value,
+          "class": bem$E("bar", {
+            opened: opened.value
+          })
+        }, [children.map(renderTitle)]), (_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const [name$D, bem$D] = createNamespace("dropdown-item");
+  const dropdownItemProps = {
+    title: String,
+    options: makeArrayProp(),
+    disabled: Boolean,
+    teleport: [String, Object],
+    lazyRender: truthProp,
+    modelValue: unknownProp,
+    titleClass: unknownProp
+  };
+  var stdin_default$M = vue.defineComponent({
+    name: name$D,
+    inheritAttrs: false,
+    props: dropdownItemProps,
+    emits: ["open", "opened", "close", "closed", "change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots,
+      attrs
+    }) {
+      const state = vue.reactive({
+        showPopup: false,
+        transition: true,
+        showWrapper: false
+      });
+      const {
+        parent,
+        index
+      } = useParent(DROPDOWN_KEY);
+      if (!parent) {
+        return;
+      }
+      const getEmitter = (name2) => () => emit(name2);
+      const onOpen = getEmitter("open");
+      const onClose = getEmitter("close");
+      const onOpened = getEmitter("opened");
+      const onClosed = () => {
+        state.showWrapper = false;
+        emit("closed");
+      };
+      const onClickWrapper = (event) => {
+        if (props.teleport) {
+          event.stopPropagation();
+        }
+      };
+      const toggle = (show = !state.showPopup, options = {}) => {
+        if (show === state.showPopup) {
+          return;
+        }
+        state.showPopup = show;
+        state.transition = !options.immediate;
+        if (show) {
+          parent.updateOffset();
+          state.showWrapper = true;
+        }
+      };
+      const renderTitle = () => {
+        if (slots.title) {
+          return slots.title();
+        }
+        if (props.title) {
+          return props.title;
+        }
+        const match = props.options.find((option) => option.value === props.modelValue);
+        return match ? match.text : "";
+      };
+      const renderOption = (option) => {
+        const {
+          activeColor
+        } = parent.props;
+        const active = option.value === props.modelValue;
+        const onClick = () => {
+          state.showPopup = false;
+          if (option.value !== props.modelValue) {
+            emit("update:modelValue", option.value);
+            emit("change", option.value);
+          }
+        };
+        const renderIcon = () => {
+          if (active) {
+            return vue.createVNode(Icon, {
+              "class": bem$D("icon"),
+              "color": activeColor,
+              "name": "success"
+            }, null);
+          }
+        };
+        return vue.createVNode(Cell, {
+          "role": "menuitem",
+          "key": option.value,
+          "icon": option.icon,
+          "title": option.text,
+          "class": bem$D("option", {
+            active
+          }),
+          "style": {
+            color: active ? activeColor : ""
+          },
+          "tabindex": active ? 0 : -1,
+          "clickable": true,
+          "onClick": onClick
+        }, {
+          value: renderIcon
+        });
+      };
+      const renderContent = () => {
+        const {
+          offset: offset2
+        } = parent;
+        const {
+          zIndex,
+          overlay,
+          duration,
+          direction,
+          closeOnClickOverlay
+        } = parent.props;
+        const style = getZIndexStyle(zIndex);
+        if (direction === "down") {
+          style.top = `${offset2.value}px`;
+        } else {
+          style.bottom = `${offset2.value}px`;
+        }
+        return vue.withDirectives(vue.createVNode("div", vue.mergeProps({
+          "style": style,
+          "class": bem$D([direction]),
+          "onClick": onClickWrapper
+        }, attrs), [vue.createVNode(Popup, {
+          "show": state.showPopup,
+          "onUpdate:show": ($event) => state.showPopup = $event,
+          "role": "menu",
+          "class": bem$D("content"),
+          "overlay": overlay,
+          "position": direction === "down" ? "top" : "bottom",
+          "duration": state.transition ? duration : 0,
+          "lazyRender": props.lazyRender,
+          "overlayStyle": {
+            position: "absolute"
+          },
+          "aria-labelledby": `${parent.id}-${index.value}`,
+          "closeOnClickOverlay": closeOnClickOverlay,
+          "onOpen": onOpen,
+          "onClose": onClose,
+          "onOpened": onOpened,
+          "onClosed": onClosed
+        }, {
+          default: () => {
+            var _a;
+            return [props.options.map(renderOption), (_a = slots.default) == null ? void 0 : _a.call(slots)];
+          }
+        })]), [[vue.vShow, state.showWrapper]]);
+      };
+      useExpose({
+        state,
+        toggle,
+        renderTitle
+      });
+      return () => {
+        if (props.teleport) {
+          return vue.createVNode(vue.Teleport, {
+            "to": props.teleport
+          }, {
+            default: () => [renderContent()]
+          });
+        }
+        return renderContent();
+      };
+    }
+  });
+  const DropdownItem = withInstall(stdin_default$M);
+  const DropdownMenu = withInstall(stdin_default$N);
+  const [name$C, bem$C] = createNamespace("grid");
+  const gridProps = {
+    square: Boolean,
+    center: truthProp,
+    border: truthProp,
+    gutter: numericProp,
+    reverse: Boolean,
+    iconSize: numericProp,
+    direction: String,
+    clickable: Boolean,
+    columnNum: makeNumericProp(4)
+  };
+  const GRID_KEY = Symbol(name$C);
+  var stdin_default$L = vue.defineComponent({
+    name: name$C,
+    props: gridProps,
+    setup(props, {
+      slots
+    }) {
+      const {
+        linkChildren
+      } = useChildren(GRID_KEY);
+      linkChildren({
+        props
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "style": {
+            paddingLeft: addUnit(props.gutter)
+          },
+          "class": [bem$C(), {
+            [BORDER_TOP]: props.border && !props.gutter
+          }]
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const Grid = withInstall(stdin_default$L);
+  const [name$B, bem$B] = createNamespace("grid-item");
+  const gridItemProps = extend({}, routeProps, {
+    dot: Boolean,
+    text: String,
+    icon: String,
+    badge: numericProp,
+    iconColor: String,
+    iconPrefix: String,
+    badgeProps: Object
+  });
+  var stdin_default$K = vue.defineComponent({
+    name: name$B,
+    props: gridItemProps,
+    setup(props, {
+      slots
+    }) {
+      const {
+        parent,
+        index
+      } = useParent(GRID_KEY);
+      const route2 = useRoute();
+      if (!parent) {
+        return;
+      }
+      const rootStyle = vue.computed(() => {
+        const {
+          square,
+          gutter,
+          columnNum
+        } = parent.props;
+        const percent = `${100 / +columnNum}%`;
+        const style = {
+          flexBasis: percent
+        };
+        if (square) {
+          style.paddingTop = percent;
+        } else if (gutter) {
+          const gutterValue = addUnit(gutter);
+          style.paddingRight = gutterValue;
+          if (index.value >= +columnNum) {
+            style.marginTop = gutterValue;
+          }
+        }
+        return style;
+      });
+      const contentStyle = vue.computed(() => {
+        const {
+          square,
+          gutter
+        } = parent.props;
+        if (square && gutter) {
+          const gutterValue = addUnit(gutter);
+          return {
+            right: gutterValue,
+            bottom: gutterValue,
+            height: "auto"
+          };
+        }
+      });
+      const renderIcon = () => {
+        if (slots.icon) {
+          return vue.createVNode(Badge, vue.mergeProps({
+            "dot": props.dot,
+            "content": props.badge
+          }, props.badgeProps), {
+            default: slots.icon
+          });
+        }
+        if (props.icon) {
+          return vue.createVNode(Icon, {
+            "dot": props.dot,
+            "name": props.icon,
+            "size": parent.props.iconSize,
+            "badge": props.badge,
+            "class": bem$B("icon"),
+            "color": props.iconColor,
+            "badgeProps": props.badgeProps,
+            "classPrefix": props.iconPrefix
+          }, null);
+        }
+      };
+      const renderText = () => {
+        if (slots.text) {
+          return slots.text();
+        }
+        if (props.text) {
+          return vue.createVNode("span", {
+            "class": bem$B("text")
+          }, [props.text]);
+        }
+      };
+      const renderContent = () => {
+        if (slots.default) {
+          return slots.default();
+        }
+        return [renderIcon(), renderText()];
+      };
+      return () => {
+        const {
+          center,
+          border,
+          square,
+          gutter,
+          reverse,
+          direction,
+          clickable
+        } = parent.props;
+        const classes = [bem$B("content", [direction, {
+          center,
+          square,
+          reverse,
+          clickable,
+          surround: border && gutter
+        }]), {
+          [BORDER]: border
+        }];
+        return vue.createVNode("div", {
+          "class": [bem$B({
+            square
+          })],
+          "style": rootStyle.value
+        }, [vue.createVNode("div", {
+          "role": clickable ? "button" : void 0,
+          "class": classes,
+          "style": contentStyle.value,
+          "tabindex": clickable ? 0 : void 0,
+          "onClick": route2
+        }, [renderContent()])]);
+      };
+    }
+  });
+  const GridItem = withInstall(stdin_default$K);
+  const getDistance = (touches) => Math.sqrt((touches[0].clientX - touches[1].clientX) ** 2 + (touches[0].clientY - touches[1].clientY) ** 2);
+  const bem$A = createNamespace("image-preview")[1];
+  var stdin_default$J = vue.defineComponent({
+    props: {
+      src: String,
+      show: Boolean,
+      active: Number,
+      minZoom: makeRequiredProp(numericProp),
+      maxZoom: makeRequiredProp(numericProp),
+      rootWidth: makeRequiredProp(Number),
+      rootHeight: makeRequiredProp(Number),
+      disableZoom: Boolean
+    },
+    emits: ["scale", "close", "longPress"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const state = vue.reactive({
+        scale: 1,
+        moveX: 0,
+        moveY: 0,
+        moving: false,
+        zooming: false,
+        imageRatio: 0,
+        displayWidth: 0,
+        displayHeight: 0
+      });
+      const touch = useTouch();
+      const swipeItem = vue.ref();
+      const vertical = vue.computed(() => {
+        const {
+          rootWidth,
+          rootHeight
+        } = props;
+        const rootRatio = rootHeight / rootWidth;
+        return state.imageRatio > rootRatio;
+      });
+      const imageStyle = vue.computed(() => {
+        const {
+          scale,
+          moveX,
+          moveY,
+          moving,
+          zooming
+        } = state;
+        const style = {
+          transitionDuration: zooming || moving ? "0s" : ".3s"
+        };
+        if (scale !== 1) {
+          const offsetX = moveX / scale;
+          const offsetY = moveY / scale;
+          style.transform = `scale(${scale}, ${scale}) translate(${offsetX}px, ${offsetY}px)`;
+        }
+        return style;
+      });
+      const maxMoveX = vue.computed(() => {
+        if (state.imageRatio) {
+          const {
+            rootWidth,
+            rootHeight
+          } = props;
+          const displayWidth = vertical.value ? rootHeight / state.imageRatio : rootWidth;
+          return Math.max(0, (state.scale * displayWidth - rootWidth) / 2);
+        }
+        return 0;
+      });
+      const maxMoveY = vue.computed(() => {
+        if (state.imageRatio) {
+          const {
+            rootWidth,
+            rootHeight
+          } = props;
+          const displayHeight = vertical.value ? rootHeight : rootWidth * state.imageRatio;
+          return Math.max(0, (state.scale * displayHeight - rootHeight) / 2);
+        }
+        return 0;
+      });
+      const setScale = (scale) => {
+        scale = clamp(scale, +props.minZoom, +props.maxZoom + 1);
+        if (scale !== state.scale) {
+          state.scale = scale;
+          emit("scale", {
+            scale,
+            index: props.active
+          });
+        }
+      };
+      const resetScale = () => {
+        setScale(1);
+        state.moveX = 0;
+        state.moveY = 0;
+      };
+      const toggleScale = () => {
+        const scale = state.scale > 1 ? 1 : 2;
+        setScale(scale);
+        state.moveX = 0;
+        state.moveY = 0;
+      };
+      let fingerNum;
+      let startMoveX;
+      let startMoveY;
+      let startScale;
+      let startDistance;
+      let doubleTapTimer;
+      let touchStartTime;
+      let isImageMoved = false;
+      const onTouchStart = (event) => {
+        const {
+          touches
+        } = event;
+        fingerNum = touches.length;
+        if (fingerNum === 2 && props.disableZoom) {
+          return;
+        }
+        const {
+          offsetX
+        } = touch;
+        touch.start(event);
+        startMoveX = state.moveX;
+        startMoveY = state.moveY;
+        touchStartTime = Date.now();
+        isImageMoved = false;
+        state.moving = fingerNum === 1 && state.scale !== 1;
+        state.zooming = fingerNum === 2 && !offsetX.value;
+        if (state.zooming) {
+          startScale = state.scale;
+          startDistance = getDistance(event.touches);
+        }
+      };
+      const onTouchMove = (event) => {
+        const {
+          touches
+        } = event;
+        touch.move(event);
+        if (state.moving) {
+          const {
+            deltaX,
+            deltaY
+          } = touch;
+          const moveX = deltaX.value + startMoveX;
+          const moveY = deltaY.value + startMoveY;
+          if ((moveX > maxMoveX.value || moveX < -maxMoveX.value) && !isImageMoved && touch.isHorizontal()) {
+            state.moving = false;
+            return;
+          }
+          isImageMoved = true;
+          preventDefault(event, true);
+          state.moveX = clamp(moveX, -maxMoveX.value, maxMoveX.value);
+          state.moveY = clamp(moveY, -maxMoveY.value, maxMoveY.value);
+        }
+        if (state.zooming) {
+          preventDefault(event, true);
+          if (touches.length === 2) {
+            const distance = getDistance(touches);
+            const scale = startScale * distance / startDistance;
+            setScale(scale);
+          }
+        }
+      };
+      const checkTap = () => {
+        if (fingerNum > 1) {
+          return;
+        }
+        const {
+          offsetX,
+          offsetY
+        } = touch;
+        const deltaTime = Date.now() - touchStartTime;
+        const TAP_TIME = 250;
+        const TAP_OFFSET = 5;
+        if (offsetX.value < TAP_OFFSET && offsetY.value < TAP_OFFSET) {
+          if (deltaTime < TAP_TIME) {
+            if (doubleTapTimer) {
+              clearTimeout(doubleTapTimer);
+              doubleTapTimer = null;
+              toggleScale();
+            } else {
+              doubleTapTimer = setTimeout(() => {
+                emit("close");
+                doubleTapTimer = null;
+              }, TAP_TIME);
+            }
+          } else if (deltaTime > LONG_PRESS_START_TIME) {
+            emit("longPress");
+          }
+        }
+      };
+      const onTouchEnd = (event) => {
+        let stopPropagation2 = false;
+        if (state.moving || state.zooming) {
+          stopPropagation2 = true;
+          if (state.moving && startMoveX === state.moveX && startMoveY === state.moveY) {
+            stopPropagation2 = false;
+          }
+          if (!event.touches.length) {
+            if (state.zooming) {
+              state.moveX = clamp(state.moveX, -maxMoveX.value, maxMoveX.value);
+              state.moveY = clamp(state.moveY, -maxMoveY.value, maxMoveY.value);
+              state.zooming = false;
+            }
+            state.moving = false;
+            startMoveX = 0;
+            startMoveY = 0;
+            startScale = 1;
+            if (state.scale < 1) {
+              resetScale();
+            }
+            const maxZoom = +props.maxZoom;
+            if (state.scale > maxZoom) {
+              state.scale = maxZoom;
+            }
+          }
+        }
+        preventDefault(event, stopPropagation2);
+        checkTap();
+        touch.reset();
+      };
+      const onLoad = (event) => {
+        const {
+          naturalWidth,
+          naturalHeight
+        } = event.target;
+        state.imageRatio = naturalHeight / naturalWidth;
+      };
+      vue.watch(() => props.active, resetScale);
+      vue.watch(() => props.show, (value) => {
+        if (!value) {
+          resetScale();
+        }
+      });
+      useEventListener("touchmove", onTouchMove, {
+        target: vue.computed(() => {
+          var _a;
+          return (_a = swipeItem.value) == null ? void 0 : _a.$el;
+        })
+      });
+      return () => {
+        const imageSlots = {
+          loading: () => vue.createVNode(Loading, {
+            "type": "spinner"
+          }, null)
+        };
+        return vue.createVNode(SwipeItem, {
+          "ref": swipeItem,
+          "class": bem$A("swipe-item"),
+          "onTouchstartPassive": onTouchStart,
+          "onTouchend": onTouchEnd,
+          "onTouchcancel": onTouchEnd
+        }, {
+          default: () => [slots.image ? vue.createVNode("div", {
+            "class": bem$A("image-wrap")
+          }, [slots.image({
+            src: props.src
+          })]) : vue.createVNode(Image$1, {
+            "src": props.src,
+            "fit": "contain",
+            "class": bem$A("image", {
+              vertical: vertical.value
+            }),
+            "style": imageStyle.value,
+            "onLoad": onLoad
+          }, imageSlots)]
+        });
+      };
+    }
+  });
+  const [name$A, bem$z] = createNamespace("image-preview");
+  const popupProps$1 = ["show", "teleport", "transition", "overlayStyle", "closeOnPopstate"];
+  const imagePreviewProps = {
+    show: Boolean,
+    loop: truthProp,
+    images: makeArrayProp(),
+    minZoom: makeNumericProp(1 / 3),
+    maxZoom: makeNumericProp(3),
+    overlay: truthProp,
+    closeable: Boolean,
+    showIndex: truthProp,
+    className: unknownProp,
+    closeIcon: makeStringProp("clear"),
+    transition: String,
+    beforeClose: Function,
+    overlayClass: unknownProp,
+    overlayStyle: Object,
+    swipeDuration: makeNumericProp(300),
+    startPosition: makeNumericProp(0),
+    showIndicators: Boolean,
+    closeOnPopstate: truthProp,
+    closeIconPosition: makeStringProp("top-right"),
+    teleport: [String, Object]
+  };
+  var stdin_default$I = vue.defineComponent({
+    name: name$A,
+    props: imagePreviewProps,
+    emits: ["scale", "close", "closed", "change", "longPress", "update:show"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const swipeRef = vue.ref();
+      const state = vue.reactive({
+        active: 0,
+        rootWidth: 0,
+        rootHeight: 0,
+        disableZoom: false
+      });
+      const resize = () => {
+        if (swipeRef.value) {
+          const rect = useRect(swipeRef.value.$el);
+          state.rootWidth = rect.width;
+          state.rootHeight = rect.height;
+          swipeRef.value.resize();
+        }
+      };
+      const emitScale = (args) => emit("scale", args);
+      const updateShow = (show) => emit("update:show", show);
+      const emitClose = () => {
+        callInterceptor(props.beforeClose, {
+          args: [state.active],
+          done: () => updateShow(false)
+        });
+      };
+      const setActive = (active) => {
+        if (active !== state.active) {
+          state.active = active;
+          emit("change", active);
+        }
+      };
+      const renderIndex = () => {
+        if (props.showIndex) {
+          return vue.createVNode("div", {
+            "class": bem$z("index")
+          }, [slots.index ? slots.index({
+            index: state.active
+          }) : `${state.active + 1} / ${props.images.length}`]);
+        }
+      };
+      const renderCover = () => {
+        if (slots.cover) {
+          return vue.createVNode("div", {
+            "class": bem$z("cover")
+          }, [slots.cover()]);
+        }
+      };
+      const onDragStart = () => {
+        state.disableZoom = true;
+      };
+      const onDragEnd = () => {
+        state.disableZoom = false;
+      };
+      const renderImages = () => vue.createVNode(Swipe, {
+        "ref": swipeRef,
+        "lazyRender": true,
+        "loop": props.loop,
+        "class": bem$z("swipe"),
+        "duration": props.swipeDuration,
+        "initialSwipe": props.startPosition,
+        "showIndicators": props.showIndicators,
+        "indicatorColor": "white",
+        "onChange": setActive,
+        "onDragEnd": onDragEnd,
+        "onDragStart": onDragStart
+      }, {
+        default: () => [props.images.map((image, index) => vue.createVNode(stdin_default$J, {
+          "src": image,
+          "show": props.show,
+          "active": state.active,
+          "maxZoom": props.maxZoom,
+          "minZoom": props.minZoom,
+          "rootWidth": state.rootWidth,
+          "rootHeight": state.rootHeight,
+          "disableZoom": state.disableZoom,
+          "onScale": emitScale,
+          "onClose": emitClose,
+          "onLongPress": () => emit("longPress", {
+            index
+          })
+        }, {
+          image: slots.image
+        }))]
+      });
+      const renderClose = () => {
+        if (props.closeable) {
+          return vue.createVNode(Icon, {
+            "role": "button",
+            "name": props.closeIcon,
+            "class": [bem$z("close-icon", props.closeIconPosition), HAPTICS_FEEDBACK],
+            "onClick": emitClose
+          }, null);
+        }
+      };
+      const onClosed = () => emit("closed");
+      const swipeTo = (index, options) => {
+        var _a;
+        return (_a = swipeRef.value) == null ? void 0 : _a.swipeTo(index, options);
+      };
+      useExpose({
+        swipeTo
+      });
+      vue.onMounted(resize);
+      vue.watch([windowWidth, windowHeight], resize);
+      vue.watch(() => props.startPosition, (value) => setActive(+value));
+      vue.watch(() => props.show, (value) => {
+        const {
+          images,
+          startPosition
+        } = props;
+        if (value) {
+          setActive(+startPosition);
+          vue.nextTick(() => {
+            resize();
+            swipeTo(+startPosition, {
+              immediate: true
+            });
+          });
+        } else {
+          emit("close", {
+            index: state.active,
+            url: images[state.active]
+          });
+        }
+      });
+      return () => vue.createVNode(Popup, vue.mergeProps({
+        "class": [bem$z(), props.className],
+        "overlayClass": [bem$z("overlay"), props.overlayClass],
+        "onClosed": onClosed,
+        "onUpdate:show": updateShow
+      }, pick(props, popupProps$1)), {
+        default: () => [renderClose(), renderImages(), renderIndex(), renderCover()]
+      });
+    }
+  });
+  let instance$1;
+  const defaultConfig = {
+    loop: true,
+    images: [],
+    maxZoom: 3,
+    minZoom: 1 / 3,
+    onScale: void 0,
+    onClose: void 0,
+    onChange: void 0,
+    teleport: "body",
+    className: "",
+    showIndex: true,
+    closeable: false,
+    closeIcon: "clear",
+    transition: void 0,
+    beforeClose: void 0,
+    overlayStyle: void 0,
+    overlayClass: void 0,
+    startPosition: 0,
+    swipeDuration: 300,
+    showIndicators: false,
+    closeOnPopstate: true,
+    closeIconPosition: "top-right"
+  };
+  function initInstance$1() {
+    ({
+      instance: instance$1
+    } = mountComponent({
+      setup() {
+        const {
+          state,
+          toggle
+        } = usePopupState();
+        const onClosed = () => {
+          state.images = [];
+        };
+        return () => vue.createVNode(stdin_default$I, vue.mergeProps(state, {
+          "onClosed": onClosed,
+          "onUpdate:show": toggle
+        }), null);
+      }
+    }));
+  }
+  const showImagePreview = (options, startPosition = 0) => {
+    if (!inBrowser$1) {
+      return;
+    }
+    if (!instance$1) {
+      initInstance$1();
+    }
+    options = Array.isArray(options) ? {
+      images: options,
+      startPosition
+    } : options;
+    instance$1.open(extend({}, defaultConfig, options));
+    return instance$1;
+  };
+  const ImagePreview = withInstall(stdin_default$I);
+  function genAlphabet() {
+    const charCodeOfA = "A".charCodeAt(0);
+    const indexList = Array(26).fill("").map((_, i) => String.fromCharCode(charCodeOfA + i));
+    return indexList;
+  }
+  const [name$z, bem$y] = createNamespace("index-bar");
+  const indexBarProps = {
+    sticky: truthProp,
+    zIndex: numericProp,
+    teleport: [String, Object],
+    highlightColor: String,
+    stickyOffsetTop: makeNumberProp(0),
+    indexList: {
+      type: Array,
+      default: genAlphabet
+    }
+  };
+  const INDEX_BAR_KEY = Symbol(name$z);
+  var stdin_default$H = vue.defineComponent({
+    name: name$z,
+    props: indexBarProps,
+    emits: ["select", "change"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const root = vue.ref();
+      const sidebar = vue.ref();
+      const activeAnchor = vue.ref("");
+      const touch = useTouch();
+      const scrollParent = useScrollParent(root);
+      const {
+        children,
+        linkChildren
+      } = useChildren(INDEX_BAR_KEY);
+      let selectActiveIndex;
+      linkChildren({
+        props
+      });
+      const sidebarStyle = vue.computed(() => {
+        if (isDef(props.zIndex)) {
+          return {
+            zIndex: +props.zIndex + 1
+          };
+        }
+      });
+      const highlightStyle = vue.computed(() => {
+        if (props.highlightColor) {
+          return {
+            color: props.highlightColor
+          };
+        }
+      });
+      const getActiveAnchor = (scrollTop, rects) => {
+        for (let i = children.length - 1; i >= 0; i--) {
+          const prevHeight = i > 0 ? rects[i - 1].height : 0;
+          const reachTop = props.sticky ? prevHeight + props.stickyOffsetTop : 0;
+          if (scrollTop + reachTop >= rects[i].top) {
+            return i;
+          }
+        }
+        return -1;
+      };
+      const getMatchAnchor = (index) => children.find((item) => String(item.index) === index);
+      const onScroll = () => {
+        if (isHidden(root)) {
+          return;
+        }
+        const {
+          sticky,
+          indexList
+        } = props;
+        const scrollTop = getScrollTop(scrollParent.value);
+        const scrollParentRect = useRect(scrollParent);
+        const rects = children.map((item) => item.getRect(scrollParent.value, scrollParentRect));
+        let active = -1;
+        if (selectActiveIndex) {
+          const match = getMatchAnchor(selectActiveIndex);
+          if (match) {
+            const rect = match.getRect(scrollParent.value, scrollParentRect);
+            active = getActiveAnchor(rect.top, rects);
+          }
+        } else {
+          active = getActiveAnchor(scrollTop, rects);
+        }
+        activeAnchor.value = indexList[active];
+        if (sticky) {
+          children.forEach((item, index) => {
+            const {
+              state,
+              $el
+            } = item;
+            if (index === active || index === active - 1) {
+              const rect = $el.getBoundingClientRect();
+              state.left = rect.left;
+              state.width = rect.width;
+            } else {
+              state.left = null;
+              state.width = null;
+            }
+            if (index === active) {
+              state.active = true;
+              state.top = Math.max(props.stickyOffsetTop, rects[index].top - scrollTop) + scrollParentRect.top;
+            } else if (index === active - 1 && selectActiveIndex === "") {
+              const activeItemTop = rects[active].top - scrollTop;
+              state.active = activeItemTop > 0;
+              state.top = activeItemTop + scrollParentRect.top - rects[index].height;
+            } else {
+              state.active = false;
+            }
+          });
+        }
+        selectActiveIndex = "";
+      };
+      const init = () => {
+        vue.nextTick(onScroll);
+      };
+      useEventListener("scroll", onScroll, {
+        target: scrollParent,
+        passive: true
+      });
+      vue.onMounted(init);
+      vue.watch(() => props.indexList, init);
+      vue.watch(activeAnchor, (value) => {
+        if (value) {
+          emit("change", value);
+        }
+      });
+      const renderIndexes = () => props.indexList.map((index) => {
+        const active = index === activeAnchor.value;
+        return vue.createVNode("span", {
+          "class": bem$y("index", {
+            active
+          }),
+          "style": active ? highlightStyle.value : void 0,
+          "data-index": index
+        }, [index]);
+      });
+      const scrollTo = (index) => {
+        selectActiveIndex = String(index);
+        const match = getMatchAnchor(selectActiveIndex);
+        if (match) {
+          const scrollTop = getScrollTop(scrollParent.value);
+          const scrollParentRect = useRect(scrollParent);
+          const {
+            offsetHeight
+          } = document.documentElement;
+          match.$el.scrollIntoView();
+          if (scrollTop === offsetHeight - scrollParentRect.height) {
+            onScroll();
+            return;
+          }
+          if (props.sticky && props.stickyOffsetTop) {
+            setRootScrollTop(getRootScrollTop() - props.stickyOffsetTop);
+          }
+          emit("select", match.index);
+        }
+      };
+      const scrollToElement = (element) => {
+        const {
+          index
+        } = element.dataset;
+        if (index) {
+          scrollTo(index);
+        }
+      };
+      const onClickSidebar = (event) => {
+        scrollToElement(event.target);
+      };
+      let touchActiveIndex;
+      const onTouchMove = (event) => {
+        touch.move(event);
+        if (touch.isVertical()) {
+          preventDefault(event);
+          const {
+            clientX,
+            clientY
+          } = event.touches[0];
+          const target = document.elementFromPoint(clientX, clientY);
+          if (target) {
+            const {
+              index
+            } = target.dataset;
+            if (index && touchActiveIndex !== index) {
+              touchActiveIndex = index;
+              scrollToElement(target);
+            }
+          }
+        }
+      };
+      const renderSidebar = () => vue.createVNode("div", {
+        "ref": sidebar,
+        "class": bem$y("sidebar"),
+        "style": sidebarStyle.value,
+        "onClick": onClickSidebar,
+        "onTouchstartPassive": touch.start
+      }, [renderIndexes()]);
+      useExpose({
+        scrollTo
+      });
+      useEventListener("touchmove", onTouchMove, {
+        target: sidebar
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "ref": root,
+          "class": bem$y()
+        }, [props.teleport ? vue.createVNode(vue.Teleport, {
+          "to": props.teleport
+        }, {
+          default: () => [renderSidebar()]
+        }) : renderSidebar(), (_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const [name$y, bem$x] = createNamespace("index-anchor");
+  const indexAnchorProps = {
+    index: numericProp
+  };
+  var stdin_default$G = vue.defineComponent({
+    name: name$y,
+    props: indexAnchorProps,
+    setup(props, {
+      slots
+    }) {
+      const state = vue.reactive({
+        top: 0,
+        left: null,
+        rect: {
+          top: 0,
+          height: 0
+        },
+        width: null,
+        active: false
+      });
+      const root = vue.ref();
+      const {
+        parent
+      } = useParent(INDEX_BAR_KEY);
+      if (!parent) {
+        return;
+      }
+      const isSticky = () => state.active && parent.props.sticky;
+      const anchorStyle = vue.computed(() => {
+        const {
+          zIndex,
+          highlightColor
+        } = parent.props;
+        if (isSticky()) {
+          return extend(getZIndexStyle(zIndex), {
+            left: state.left ? `${state.left}px` : void 0,
+            width: state.width ? `${state.width}px` : void 0,
+            transform: state.top ? `translate3d(0, ${state.top}px, 0)` : void 0,
+            color: highlightColor
+          });
+        }
+      });
+      const getRect = (scrollParent, scrollParentRect) => {
+        const rootRect = useRect(root);
+        state.rect.height = rootRect.height;
+        if (scrollParent === window || scrollParent === document.body) {
+          state.rect.top = rootRect.top + getRootScrollTop();
+        } else {
+          state.rect.top = rootRect.top + getScrollTop(scrollParent) - scrollParentRect.top;
+        }
+        return state.rect;
+      };
+      useExpose({
+        state,
+        getRect
+      });
+      return () => {
+        const sticky = isSticky();
+        return vue.createVNode("div", {
+          "ref": root,
+          "style": {
+            height: sticky ? `${state.rect.height}px` : void 0
+          }
+        }, [vue.createVNode("div", {
+          "style": anchorStyle.value,
+          "class": [bem$x({
+            sticky
+          }), {
+            [BORDER_BOTTOM]: sticky
+          }]
+        }, [slots.default ? slots.default() : props.index])]);
+      };
+    }
+  });
+  const IndexAnchor = withInstall(stdin_default$G);
+  const IndexBar = withInstall(stdin_default$H);
+  const [name$x, bem$w, t$6] = createNamespace("list");
+  const listProps = {
+    error: Boolean,
+    offset: makeNumericProp(300),
+    loading: Boolean,
+    disabled: Boolean,
+    finished: Boolean,
+    errorText: String,
+    direction: makeStringProp("down"),
+    loadingText: String,
+    finishedText: String,
+    immediateCheck: truthProp
+  };
+  var stdin_default$F = vue.defineComponent({
+    name: name$x,
+    props: listProps,
+    emits: ["load", "update:error", "update:loading"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const loading = vue.ref(props.loading);
+      const root = vue.ref();
+      const placeholder = vue.ref();
+      const tabStatus = useTabStatus();
+      const scrollParent = useScrollParent(root);
+      const check = () => {
+        vue.nextTick(() => {
+          if (loading.value || props.finished || props.disabled || props.error || // skip check when inside an inactive tab
+          (tabStatus == null ? void 0 : tabStatus.value) === false) {
+            return;
+          }
+          const {
+            direction
+          } = props;
+          const offset2 = +props.offset;
+          const scrollParentRect = useRect(scrollParent);
+          if (!scrollParentRect.height || isHidden(root)) {
+            return;
+          }
+          let isReachEdge = false;
+          const placeholderRect = useRect(placeholder);
+          if (direction === "up") {
+            isReachEdge = scrollParentRect.top - placeholderRect.top <= offset2;
+          } else {
+            isReachEdge = placeholderRect.bottom - scrollParentRect.bottom <= offset2;
+          }
+          if (isReachEdge) {
+            loading.value = true;
+            emit("update:loading", true);
+            emit("load");
+          }
+        });
+      };
+      const renderFinishedText = () => {
+        if (props.finished) {
+          const text = slots.finished ? slots.finished() : props.finishedText;
+          if (text) {
+            return vue.createVNode("div", {
+              "class": bem$w("finished-text")
+            }, [text]);
+          }
+        }
+      };
+      const clickErrorText = () => {
+        emit("update:error", false);
+        check();
+      };
+      const renderErrorText = () => {
+        if (props.error) {
+          const text = slots.error ? slots.error() : props.errorText;
+          if (text) {
+            return vue.createVNode("div", {
+              "role": "button",
+              "class": bem$w("error-text"),
+              "tabindex": 0,
+              "onClick": clickErrorText
+            }, [text]);
+          }
+        }
+      };
+      const renderLoading = () => {
+        if (loading.value && !props.finished && !props.disabled) {
+          return vue.createVNode("div", {
+            "class": bem$w("loading")
+          }, [slots.loading ? slots.loading() : vue.createVNode(Loading, {
+            "class": bem$w("loading-icon")
+          }, {
+            default: () => [props.loadingText || t$6("loading")]
+          })]);
+        }
+      };
+      vue.watch(() => [props.loading, props.finished, props.error], check);
+      if (tabStatus) {
+        vue.watch(tabStatus, (tabActive) => {
+          if (tabActive) {
+            check();
+          }
+        });
+      }
+      vue.onUpdated(() => {
+        loading.value = props.loading;
+      });
+      vue.onMounted(() => {
+        if (props.immediateCheck) {
+          check();
+        }
+      });
+      useExpose({
+        check
+      });
+      useEventListener("scroll", check, {
+        target: scrollParent,
+        passive: true
+      });
+      return () => {
+        var _a;
+        const Content = (_a = slots.default) == null ? void 0 : _a.call(slots);
+        const Placeholder = vue.createVNode("div", {
+          "ref": placeholder,
+          "class": bem$w("placeholder")
+        }, null);
+        return vue.createVNode("div", {
+          "ref": root,
+          "role": "feed",
+          "class": bem$w(),
+          "aria-busy": loading.value
+        }, [props.direction === "down" ? Content : Placeholder, renderLoading(), renderFinishedText(), renderErrorText(), props.direction === "up" ? Content : Placeholder]);
+      };
+    }
+  });
+  const List = withInstall(stdin_default$F);
+  const [name$w, bem$v] = createNamespace("nav-bar");
+  const navBarProps = {
+    title: String,
+    fixed: Boolean,
+    zIndex: numericProp,
+    border: truthProp,
+    leftText: String,
+    rightText: String,
+    leftArrow: Boolean,
+    placeholder: Boolean,
+    safeAreaInsetTop: Boolean,
+    clickable: truthProp
+  };
+  var stdin_default$E = vue.defineComponent({
+    name: name$w,
+    props: navBarProps,
+    emits: ["clickLeft", "clickRight"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const navBarRef = vue.ref();
+      const renderPlaceholder = usePlaceholder(navBarRef, bem$v);
+      const onClickLeft = (event) => emit("clickLeft", event);
+      const onClickRight = (event) => emit("clickRight", event);
+      const renderLeft = () => {
+        if (slots.left) {
+          return slots.left();
+        }
+        return [props.leftArrow && vue.createVNode(Icon, {
+          "class": bem$v("arrow"),
+          "name": "arrow-left"
+        }, null), props.leftText && vue.createVNode("span", {
+          "class": bem$v("text")
+        }, [props.leftText])];
+      };
+      const renderRight = () => {
+        if (slots.right) {
+          return slots.right();
+        }
+        return vue.createVNode("span", {
+          "class": bem$v("text")
+        }, [props.rightText]);
+      };
+      const renderNavBar = () => {
+        const {
+          title,
+          fixed,
+          border,
+          zIndex
+        } = props;
+        const style = getZIndexStyle(zIndex);
+        const hasLeft = props.leftArrow || props.leftText || slots.left;
+        const hasRight = props.rightText || slots.right;
+        return vue.createVNode("div", {
+          "ref": navBarRef,
+          "style": style,
+          "class": [bem$v({
+            fixed
+          }), {
+            [BORDER_BOTTOM]: border,
+            "van-safe-area-top": props.safeAreaInsetTop
+          }]
+        }, [vue.createVNode("div", {
+          "class": bem$v("content")
+        }, [hasLeft && vue.createVNode("div", {
+          "class": [bem$v("left"), props.clickable ? HAPTICS_FEEDBACK : ""],
+          "onClick": onClickLeft
+        }, [renderLeft()]), vue.createVNode("div", {
+          "class": [bem$v("title"), "van-ellipsis"]
+        }, [slots.title ? slots.title() : title]), hasRight && vue.createVNode("div", {
+          "class": [bem$v("right"), props.clickable ? HAPTICS_FEEDBACK : ""],
+          "onClick": onClickRight
+        }, [renderRight()])])]);
+      };
+      return () => {
+        if (props.fixed && props.placeholder) {
+          return renderPlaceholder(renderNavBar);
+        }
+        return renderNavBar();
+      };
+    }
+  });
+  const NavBar = withInstall(stdin_default$E);
+  const [name$v, bem$u] = createNamespace("notice-bar");
+  const noticeBarProps = {
+    text: String,
+    mode: String,
+    color: String,
+    delay: makeNumericProp(1),
+    speed: makeNumericProp(60),
+    leftIcon: String,
+    wrapable: Boolean,
+    background: String,
+    scrollable: {
+      type: Boolean,
+      default: null
+    }
+  };
+  var stdin_default$D = vue.defineComponent({
+    name: name$v,
+    props: noticeBarProps,
+    emits: ["close", "replay"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      let wrapWidth = 0;
+      let contentWidth = 0;
+      let startTimer;
+      const wrapRef = vue.ref();
+      const contentRef = vue.ref();
+      const state = vue.reactive({
+        show: true,
+        offset: 0,
+        duration: 0
+      });
+      const renderLeftIcon = () => {
+        if (slots["left-icon"]) {
+          return slots["left-icon"]();
+        }
+        if (props.leftIcon) {
+          return vue.createVNode(Icon, {
+            "class": bem$u("left-icon"),
+            "name": props.leftIcon
+          }, null);
+        }
+      };
+      const getRightIconName = () => {
+        if (props.mode === "closeable") {
+          return "cross";
+        }
+        if (props.mode === "link") {
+          return "arrow";
+        }
+      };
+      const onClickRightIcon = (event) => {
+        if (props.mode === "closeable") {
+          state.show = false;
+          emit("close", event);
+        }
+      };
+      const renderRightIcon = () => {
+        if (slots["right-icon"]) {
+          return slots["right-icon"]();
+        }
+        const name2 = getRightIconName();
+        if (name2) {
+          return vue.createVNode(Icon, {
+            "name": name2,
+            "class": bem$u("right-icon"),
+            "onClick": onClickRightIcon
+          }, null);
+        }
+      };
+      const onTransitionEnd = () => {
+        state.offset = wrapWidth;
+        state.duration = 0;
+        raf(() => {
+          doubleRaf(() => {
+            state.offset = -contentWidth;
+            state.duration = (contentWidth + wrapWidth) / +props.speed;
+            emit("replay");
+          });
+        });
+      };
+      const renderMarquee = () => {
+        const ellipsis = props.scrollable === false && !props.wrapable;
+        const style = {
+          transform: state.offset ? `translateX(${state.offset}px)` : "",
+          transitionDuration: `${state.duration}s`
+        };
+        return vue.createVNode("div", {
+          "ref": wrapRef,
+          "role": "marquee",
+          "class": bem$u("wrap")
+        }, [vue.createVNode("div", {
+          "ref": contentRef,
+          "style": style,
+          "class": [bem$u("content"), {
+            "van-ellipsis": ellipsis
+          }],
+          "onTransitionend": onTransitionEnd
+        }, [slots.default ? slots.default() : props.text])]);
+      };
+      const reset = () => {
+        const {
+          delay,
+          speed,
+          scrollable
+        } = props;
+        const ms = isDef(delay) ? +delay * 1e3 : 0;
+        wrapWidth = 0;
+        contentWidth = 0;
+        state.offset = 0;
+        state.duration = 0;
+        clearTimeout(startTimer);
+        startTimer = setTimeout(() => {
+          if (!wrapRef.value || !contentRef.value || scrollable === false) {
+            return;
+          }
+          const wrapRefWidth = useRect(wrapRef).width;
+          const contentRefWidth = useRect(contentRef).width;
+          if (scrollable || contentRefWidth > wrapRefWidth) {
+            doubleRaf(() => {
+              wrapWidth = wrapRefWidth;
+              contentWidth = contentRefWidth;
+              state.offset = -contentWidth;
+              state.duration = contentWidth / +speed;
+            });
+          }
+        }, ms);
+      };
+      onPopupReopen(reset);
+      onMountedOrActivated(reset);
+      useEventListener("pageshow", reset);
+      useExpose({
+        reset
+      });
+      vue.watch(() => [props.text, props.scrollable], reset);
+      return () => {
+        const {
+          color,
+          wrapable,
+          background
+        } = props;
+        return vue.withDirectives(vue.createVNode("div", {
+          "role": "alert",
+          "class": bem$u({
+            wrapable
+          }),
+          "style": {
+            color,
+            background
+          }
+        }, [renderLeftIcon(), renderMarquee(), renderRightIcon()]), [[vue.vShow, state.show]]);
+      };
+    }
+  });
+  const NoticeBar = withInstall(stdin_default$D);
+  const [name$u, bem$t] = createNamespace("notify");
+  const notifyProps = extend({}, popupSharedProps, {
+    type: makeStringProp("danger"),
+    color: String,
+    message: numericProp,
+    position: makeStringProp("top"),
+    className: unknownProp,
+    background: String,
+    lockScroll: Boolean
+  });
+  var stdin_default$C = vue.defineComponent({
+    name: name$u,
+    props: notifyProps,
+    emits: ["update:show"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const updateShow = (show) => emit("update:show", show);
+      return () => vue.createVNode(Popup, {
+        "show": props.show,
+        "class": [bem$t([props.type]), props.className],
+        "style": {
+          color: props.color,
+          background: props.background
+        },
+        "overlay": false,
+        "zIndex": props.zIndex,
+        "position": props.position,
+        "duration": 0.2,
+        "lockScroll": props.lockScroll,
+        "onUpdate:show": updateShow
+      }, {
+        default: () => [slots.default ? slots.default() : props.message]
+      });
+    }
+  });
+  let timer;
+  let instance;
+  const parseOptions = (message) => isObject(message) ? message : {
+    message
+  };
+  function initInstance() {
+    ({
+      instance
+    } = mountComponent({
+      setup() {
+        const {
+          state,
+          toggle
+        } = usePopupState();
+        return () => vue.createVNode(stdin_default$C, vue.mergeProps(state, {
+          "onUpdate:show": toggle
+        }), null);
+      }
+    }));
+  }
+  const getDefaultOptions = () => ({
+    type: "danger",
+    color: void 0,
+    message: "",
+    onClose: void 0,
+    onClick: void 0,
+    onOpened: void 0,
+    duration: 3e3,
+    position: void 0,
+    className: "",
+    lockScroll: false,
+    background: void 0
+  });
+  let currentOptions = getDefaultOptions();
+  const closeNotify = () => {
+    if (instance) {
+      instance.toggle(false);
+    }
+  };
+  function showNotify(options) {
+    if (!inBrowser$1) {
+      return;
+    }
+    if (!instance) {
+      initInstance();
+    }
+    options = extend({}, currentOptions, parseOptions(options));
+    instance.open(options);
+    clearTimeout(timer);
+    if (options.duration > 0) {
+      timer = setTimeout(closeNotify, options.duration);
+    }
+    return instance;
+  }
+  const setNotifyDefaultOptions = (options) => extend(currentOptions, options);
+  const resetNotifyDefaultOptions = () => {
+    currentOptions = getDefaultOptions();
+  };
+  const Notify = withInstall(stdin_default$C);
+  const [name$t, bem$s] = createNamespace("key");
+  const CollapseIcon = vue.createVNode("svg", {
+    "class": bem$s("collapse-icon"),
+    "viewBox": "0 0 30 24"
+  }, [vue.createVNode("path", {
+    "d": "M26 13h-2v2h2v-2zm-8-3h2V8h-2v2zm2-4h2V4h-2v2zm2 4h4V4h-2v4h-2v2zm-7 14 3-3h-6l3 3zM6 13H4v2h2v-2zm16 0H8v2h14v-2zm-12-3h2V8h-2v2zM28 0l1 1 1 1v15l-1 2H1l-1-2V2l1-1 1-1zm0 2H2v15h26V2zM6 4v2H4V4zm10 2h2V4h-2v2zM8 9v1H4V8zm8 0v1h-2V8zm-6-5v2H8V4zm4 0v2h-2V4z",
+    "fill": "currentColor"
+  }, null)]);
+  const DeleteIcon = vue.createVNode("svg", {
+    "class": bem$s("delete-icon"),
+    "viewBox": "0 0 32 22"
+  }, [vue.createVNode("path", {
+    "d": "M28 0a4 4 0 0 1 4 4v14a4 4 0 0 1-4 4H10.4a2 2 0 0 1-1.4-.6L1 13.1c-.6-.5-.9-1.3-.9-2 0-1 .3-1.7.9-2.2L9 .6a2 2 0 0 1 1.4-.6zm0 2H10.4l-8.2 8.3a1 1 0 0 0-.3.7c0 .3.1.5.3.7l8.2 8.4H28a2 2 0 0 0 2-2V4c0-1.1-.9-2-2-2zm-5 4a1 1 0 0 1 .7.3 1 1 0 0 1 0 1.4L20.4 11l3.3 3.3c.2.2.3.5.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3L19 12.4l-3.4 3.3a1 1 0 0 1-.6.3 1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.2.1-.5.3-.7l3.3-3.3-3.3-3.3A1 1 0 0 1 14 7c0-.3.1-.5.3-.7A1 1 0 0 1 15 6a1 1 0 0 1 .6.3L19 9.6l3.3-3.3A1 1 0 0 1 23 6z",
+    "fill": "currentColor"
+  }, null)]);
+  var stdin_default$B = vue.defineComponent({
+    name: name$t,
+    props: {
+      type: String,
+      text: numericProp,
+      color: String,
+      wider: Boolean,
+      large: Boolean,
+      loading: Boolean
+    },
+    emits: ["press"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const active = vue.ref(false);
+      const touch = useTouch();
+      const onTouchStart = (event) => {
+        touch.start(event);
+        active.value = true;
+      };
+      const onTouchMove = (event) => {
+        touch.move(event);
+        if (touch.direction.value) {
+          active.value = false;
+        }
+      };
+      const onTouchEnd = (event) => {
+        if (active.value) {
+          if (!slots.default) {
+            preventDefault(event);
+          }
+          active.value = false;
+          emit("press", props.text, props.type);
+        }
+      };
+      const renderContent = () => {
+        if (props.loading) {
+          return vue.createVNode(Loading, {
+            "class": bem$s("loading-icon")
+          }, null);
+        }
+        const text = slots.default ? slots.default() : props.text;
+        switch (props.type) {
+          case "delete":
+            return text || DeleteIcon;
+          case "extra":
+            return text || CollapseIcon;
+          default:
+            return text;
+        }
+      };
+      return () => vue.createVNode("div", {
+        "class": bem$s("wrapper", {
+          wider: props.wider
+        }),
+        "onTouchstartPassive": onTouchStart,
+        "onTouchmovePassive": onTouchMove,
+        "onTouchend": onTouchEnd,
+        "onTouchcancel": onTouchEnd
+      }, [vue.createVNode("div", {
+        "role": "button",
+        "tabindex": 0,
+        "class": bem$s([props.color, {
+          large: props.large,
+          active: active.value,
+          delete: props.type === "delete"
+        }])
+      }, [renderContent()])]);
+    }
+  });
+  const [name$s, bem$r] = createNamespace("number-keyboard");
+  const numberKeyboardProps = {
+    show: Boolean,
+    title: String,
+    theme: makeStringProp("default"),
+    zIndex: numericProp,
+    teleport: [String, Object],
+    maxlength: makeNumericProp(Infinity),
+    modelValue: makeStringProp(""),
+    transition: truthProp,
+    blurOnClose: truthProp,
+    showDeleteKey: truthProp,
+    randomKeyOrder: Boolean,
+    closeButtonText: String,
+    deleteButtonText: String,
+    closeButtonLoading: Boolean,
+    hideOnClickOutside: truthProp,
+    safeAreaInsetBottom: truthProp,
+    extraKey: {
+      type: [String, Array],
+      default: ""
+    }
+  };
+  function shuffle(array) {
+    for (let i = array.length - 1; i > 0; i--) {
+      const j = Math.floor(Math.random() * (i + 1));
+      const temp = array[i];
+      array[i] = array[j];
+      array[j] = temp;
+    }
+    return array;
+  }
+  var stdin_default$A = vue.defineComponent({
+    name: name$s,
+    inheritAttrs: false,
+    props: numberKeyboardProps,
+    emits: ["show", "hide", "blur", "input", "close", "delete", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots,
+      attrs
+    }) {
+      const root = vue.ref();
+      const genBasicKeys = () => {
+        const keys2 = Array(9).fill("").map((_, i) => ({
+          text: i + 1
+        }));
+        if (props.randomKeyOrder) {
+          shuffle(keys2);
+        }
+        return keys2;
+      };
+      const genDefaultKeys = () => [...genBasicKeys(), {
+        text: props.extraKey,
+        type: "extra"
+      }, {
+        text: 0
+      }, {
+        text: props.showDeleteKey ? props.deleteButtonText : "",
+        type: props.showDeleteKey ? "delete" : ""
+      }];
+      const genCustomKeys = () => {
+        const keys2 = genBasicKeys();
+        const {
+          extraKey
+        } = props;
+        const extraKeys = Array.isArray(extraKey) ? extraKey : [extraKey];
+        if (extraKeys.length === 1) {
+          keys2.push({
+            text: 0,
+            wider: true
+          }, {
+            text: extraKeys[0],
+            type: "extra"
+          });
+        } else if (extraKeys.length === 2) {
+          keys2.push({
+            text: extraKeys[0],
+            type: "extra"
+          }, {
+            text: 0
+          }, {
+            text: extraKeys[1],
+            type: "extra"
+          });
+        }
+        return keys2;
+      };
+      const keys = vue.computed(() => props.theme === "custom" ? genCustomKeys() : genDefaultKeys());
+      const onBlur = () => {
+        if (props.show) {
+          emit("blur");
+        }
+      };
+      const onClose = () => {
+        emit("close");
+        if (props.blurOnClose) {
+          onBlur();
+        }
+      };
+      const onAnimationEnd = () => emit(props.show ? "show" : "hide");
+      const onPress = (text, type) => {
+        if (text === "") {
+          if (type === "extra") {
+            onBlur();
+          }
+          return;
+        }
+        const value = props.modelValue;
+        if (type === "delete") {
+          emit("delete");
+          emit("update:modelValue", value.slice(0, value.length - 1));
+        } else if (type === "close") {
+          onClose();
+        } else if (value.length < +props.maxlength) {
+          emit("input", text);
+          emit("update:modelValue", value + text);
+        }
+      };
+      const renderTitle = () => {
+        const {
+          title,
+          theme,
+          closeButtonText
+        } = props;
+        const leftSlot = slots["title-left"];
+        const showClose = closeButtonText && theme === "default";
+        const showTitle = title || showClose || leftSlot;
+        if (!showTitle) {
+          return;
+        }
+        return vue.createVNode("div", {
+          "class": bem$r("header")
+        }, [leftSlot && vue.createVNode("span", {
+          "class": bem$r("title-left")
+        }, [leftSlot()]), title && vue.createVNode("h2", {
+          "class": bem$r("title")
+        }, [title]), showClose && vue.createVNode("button", {
+          "type": "button",
+          "class": [bem$r("close"), HAPTICS_FEEDBACK],
+          "onClick": onClose
+        }, [closeButtonText])]);
+      };
+      const renderKeys = () => keys.value.map((key) => {
+        const keySlots = {};
+        if (key.type === "delete") {
+          keySlots.default = slots.delete;
+        }
+        if (key.type === "extra") {
+          keySlots.default = slots["extra-key"];
+        }
+        return vue.createVNode(stdin_default$B, {
+          "key": key.text,
+          "text": key.text,
+          "type": key.type,
+          "wider": key.wider,
+          "color": key.color,
+          "onPress": onPress
+        }, keySlots);
+      });
+      const renderSidebar = () => {
+        if (props.theme === "custom") {
+          return vue.createVNode("div", {
+            "class": bem$r("sidebar")
+          }, [props.showDeleteKey && vue.createVNode(stdin_default$B, {
+            "large": true,
+            "text": props.deleteButtonText,
+            "type": "delete",
+            "onPress": onPress
+          }, {
+            delete: slots.delete
+          }), vue.createVNode(stdin_default$B, {
+            "large": true,
+            "text": props.closeButtonText,
+            "type": "close",
+            "color": "blue",
+            "loading": props.closeButtonLoading,
+            "onPress": onPress
+          }, null)]);
+        }
+      };
+      vue.watch(() => props.show, (value) => {
+        if (!props.transition) {
+          emit(value ? "show" : "hide");
+        }
+      });
+      if (props.hideOnClickOutside) {
+        useClickAway(root, onBlur, {
+          eventName: "touchstart"
+        });
+      }
+      return () => {
+        const Title = renderTitle();
+        const Content = vue.createVNode(vue.Transition, {
+          "name": props.transition ? "van-slide-up" : ""
+        }, {
+          default: () => [vue.withDirectives(vue.createVNode("div", vue.mergeProps({
+            "ref": root,
+            "style": getZIndexStyle(props.zIndex),
+            "class": bem$r({
+              unfit: !props.safeAreaInsetBottom,
+              "with-title": !!Title
+            }),
+            "onAnimationend": onAnimationEnd,
+            "onTouchstartPassive": stopPropagation
+          }, attrs), [Title, vue.createVNode("div", {
+            "class": bem$r("body")
+          }, [vue.createVNode("div", {
+            "class": bem$r("keys")
+          }, [renderKeys()]), renderSidebar()])]), [[vue.vShow, props.show]])]
+        });
+        if (props.teleport) {
+          return vue.createVNode(vue.Teleport, {
+            "to": props.teleport
+          }, {
+            default: () => [Content]
+          });
+        }
+        return Content;
+      };
+    }
+  });
+  const NumberKeyboard = withInstall(stdin_default$A);
+  const [name$r, bem$q, t$5] = createNamespace("pagination");
+  const makePage = (number, text, active) => ({
+    number,
+    text,
+    active
+  });
+  const paginationProps = {
+    mode: makeStringProp("multi"),
+    prevText: String,
+    nextText: String,
+    pageCount: makeNumericProp(0),
+    modelValue: makeNumberProp(0),
+    totalItems: makeNumericProp(0),
+    showPageSize: makeNumericProp(5),
+    itemsPerPage: makeNumericProp(10),
+    forceEllipses: Boolean
+  };
+  var stdin_default$z = vue.defineComponent({
+    name: name$r,
+    props: paginationProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const count = vue.computed(() => {
+        const {
+          pageCount,
+          totalItems,
+          itemsPerPage
+        } = props;
+        const count2 = +pageCount || Math.ceil(+totalItems / +itemsPerPage);
+        return Math.max(1, count2);
+      });
+      const pages = vue.computed(() => {
+        const items = [];
+        const pageCount = count.value;
+        const showPageSize = +props.showPageSize;
+        const {
+          modelValue,
+          forceEllipses
+        } = props;
+        let startPage = 1;
+        let endPage = pageCount;
+        const isMaxSized = showPageSize < pageCount;
+        if (isMaxSized) {
+          startPage = Math.max(modelValue - Math.floor(showPageSize / 2), 1);
+          endPage = startPage + showPageSize - 1;
+          if (endPage > pageCount) {
+            endPage = pageCount;
+            startPage = endPage - showPageSize + 1;
+          }
+        }
+        for (let number = startPage; number <= endPage; number++) {
+          const page = makePage(number, number, number === modelValue);
+          items.push(page);
+        }
+        if (isMaxSized && showPageSize > 0 && forceEllipses) {
+          if (startPage > 1) {
+            const prevPages = makePage(startPage - 1, "...");
+            items.unshift(prevPages);
+          }
+          if (endPage < pageCount) {
+            const nextPages = makePage(endPage + 1, "...");
+            items.push(nextPages);
+          }
+        }
+        return items;
+      });
+      const updateModelValue = (value, emitChange) => {
+        value = clamp(value, 1, count.value);
+        if (props.modelValue !== value) {
+          emit("update:modelValue", value);
+          if (emitChange) {
+            emit("change", value);
+          }
+        }
+      };
+      vue.watchEffect(() => updateModelValue(props.modelValue));
+      const renderDesc = () => vue.createVNode("li", {
+        "class": bem$q("page-desc")
+      }, [slots.pageDesc ? slots.pageDesc() : `${props.modelValue}/${count.value}`]);
+      const renderPrevButton = () => {
+        const {
+          mode,
+          modelValue
+        } = props;
+        const slot = slots["prev-text"];
+        const disabled = modelValue === 1;
+        return vue.createVNode("li", {
+          "class": [bem$q("item", {
+            disabled,
+            border: mode === "simple",
+            prev: true
+          }), BORDER_SURROUND]
+        }, [vue.createVNode("button", {
+          "type": "button",
+          "disabled": disabled,
+          "onClick": () => updateModelValue(modelValue - 1, true)
+        }, [slot ? slot() : props.prevText || t$5("prev")])]);
+      };
+      const renderNextButton = () => {
+        const {
+          mode,
+          modelValue
+        } = props;
+        const slot = slots["next-text"];
+        const disabled = modelValue === count.value;
+        return vue.createVNode("li", {
+          "class": [bem$q("item", {
+            disabled,
+            border: mode === "simple",
+            next: true
+          }), BORDER_SURROUND]
+        }, [vue.createVNode("button", {
+          "type": "button",
+          "disabled": disabled,
+          "onClick": () => updateModelValue(modelValue + 1, true)
+        }, [slot ? slot() : props.nextText || t$5("next")])]);
+      };
+      const renderPages = () => pages.value.map((page) => vue.createVNode("li", {
+        "class": [bem$q("item", {
+          active: page.active,
+          page: true
+        }), BORDER_SURROUND]
+      }, [vue.createVNode("button", {
+        "type": "button",
+        "aria-current": page.active || void 0,
+        "onClick": () => updateModelValue(page.number, true)
+      }, [slots.page ? slots.page(page) : page.text])]));
+      return () => vue.createVNode("nav", {
+        "role": "navigation",
+        "class": bem$q()
+      }, [vue.createVNode("ul", {
+        "class": bem$q("items")
+      }, [renderPrevButton(), props.mode === "simple" ? renderDesc() : renderPages(), renderNextButton()])]);
+    }
+  });
+  const Pagination = withInstall(stdin_default$z);
+  const [name$q, bem$p] = createNamespace("password-input");
+  const passwordInputProps = {
+    info: String,
+    mask: truthProp,
+    value: makeStringProp(""),
+    gutter: numericProp,
+    length: makeNumericProp(6),
+    focused: Boolean,
+    errorInfo: String
+  };
+  var stdin_default$y = vue.defineComponent({
+    name: name$q,
+    props: passwordInputProps,
+    emits: ["focus"],
+    setup(props, {
+      emit
+    }) {
+      const onTouchStart = (event) => {
+        event.stopPropagation();
+        emit("focus", event);
+      };
+      const renderPoints = () => {
+        const Points = [];
+        const {
+          mask,
+          value,
+          gutter,
+          focused
+        } = props;
+        const length = +props.length;
+        for (let i = 0; i < length; i++) {
+          const char = value[i];
+          const showBorder = i !== 0 && !gutter;
+          const showCursor = focused && i === value.length;
+          let style;
+          if (i !== 0 && gutter) {
+            style = {
+              marginLeft: addUnit(gutter)
+            };
+          }
+          Points.push(vue.createVNode("li", {
+            "class": [{
+              [BORDER_LEFT]: showBorder
+            }, bem$p("item", {
+              focus: showCursor
+            })],
+            "style": style
+          }, [mask ? vue.createVNode("i", {
+            "style": {
+              visibility: char ? "visible" : "hidden"
+            }
+          }, null) : char, showCursor && vue.createVNode("div", {
+            "class": bem$p("cursor")
+          }, null)]));
+        }
+        return Points;
+      };
+      return () => {
+        const info = props.errorInfo || props.info;
+        return vue.createVNode("div", {
+          "class": bem$p()
+        }, [vue.createVNode("ul", {
+          "class": [bem$p("security"), {
+            [BORDER_SURROUND]: !props.gutter
+          }],
+          "onTouchstartPassive": onTouchStart
+        }, [renderPoints()]), info && vue.createVNode("div", {
+          "class": bem$p(props.errorInfo ? "error-info" : "info")
+        }, [info])]);
+      };
+    }
+  });
+  const PasswordInput = withInstall(stdin_default$y);
+  const PickerGroup = withInstall(stdin_default$1s);
+  function getWindow(node) {
+    if (node == null) {
+      return window;
+    }
+    if (node.toString() !== "[object Window]") {
+      var ownerDocument = node.ownerDocument;
+      return ownerDocument ? ownerDocument.defaultView || window : window;
+    }
+    return node;
+  }
+  function isElement(node) {
+    var OwnElement = getWindow(node).Element;
+    return node instanceof OwnElement || node instanceof Element;
+  }
+  function isHTMLElement(node) {
+    var OwnElement = getWindow(node).HTMLElement;
+    return node instanceof OwnElement || node instanceof HTMLElement;
+  }
+  function isShadowRoot(node) {
+    if (typeof ShadowRoot === "undefined") {
+      return false;
+    }
+    var OwnElement = getWindow(node).ShadowRoot;
+    return node instanceof OwnElement || node instanceof ShadowRoot;
+  }
+  var round = Math.round;
+  function getUAString() {
+    var uaData = navigator.userAgentData;
+    if (uaData != null && uaData.brands) {
+      return uaData.brands.map(function(item) {
+        return item.brand + "/" + item.version;
+      }).join(" ");
+    }
+    return navigator.userAgent;
+  }
+  function isLayoutViewport() {
+    return !/^((?!chrome|android).)*safari/i.test(getUAString());
+  }
+  function getBoundingClientRect(element, includeScale, isFixedStrategy) {
+    if (includeScale === void 0) {
+      includeScale = false;
+    }
+    if (isFixedStrategy === void 0) {
+      isFixedStrategy = false;
+    }
+    var clientRect = element.getBoundingClientRect();
+    var scaleX = 1;
+    var scaleY = 1;
+    if (includeScale && isHTMLElement(element)) {
+      scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
+      scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
+    }
+    var _ref = isElement(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport;
+    var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
+    var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
+    var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
+    var width2 = clientRect.width / scaleX;
+    var height2 = clientRect.height / scaleY;
+    return {
+      width: width2,
+      height: height2,
+      top: y,
+      right: x + width2,
+      bottom: y + height2,
+      left: x,
+      x,
+      y
+    };
+  }
+  function getWindowScroll(node) {
+    var win = getWindow(node);
+    var scrollLeft = win.pageXOffset;
+    var scrollTop = win.pageYOffset;
+    return {
+      scrollLeft,
+      scrollTop
+    };
+  }
+  function getHTMLElementScroll(element) {
+    return {
+      scrollLeft: element.scrollLeft,
+      scrollTop: element.scrollTop
+    };
+  }
+  function getNodeScroll(node) {
+    if (node === getWindow(node) || !isHTMLElement(node)) {
+      return getWindowScroll(node);
+    } else {
+      return getHTMLElementScroll(node);
+    }
+  }
+  function getNodeName(element) {
+    return element ? (element.nodeName || "").toLowerCase() : null;
+  }
+  function getDocumentElement(element) {
+    return ((isElement(element) ? element.ownerDocument : (
+      // $FlowFixMe[prop-missing]
+      element.document
+    )) || window.document).documentElement;
+  }
+  function getWindowScrollBarX(element) {
+    return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
+  }
+  function getComputedStyle(element) {
+    return getWindow(element).getComputedStyle(element);
+  }
+  function isScrollParent(element) {
+    var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY;
+    return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
+  }
+  function isElementScaled(element) {
+    var rect = element.getBoundingClientRect();
+    var scaleX = round(rect.width) / element.offsetWidth || 1;
+    var scaleY = round(rect.height) / element.offsetHeight || 1;
+    return scaleX !== 1 || scaleY !== 1;
+  }
+  function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
+    if (isFixed === void 0) {
+      isFixed = false;
+    }
+    var isOffsetParentAnElement = isHTMLElement(offsetParent);
+    var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
+    var documentElement = getDocumentElement(offsetParent);
+    var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
+    var scroll = {
+      scrollLeft: 0,
+      scrollTop: 0
+    };
+    var offsets = {
+      x: 0,
+      y: 0
+    };
+    if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
+      if (getNodeName(offsetParent) !== "body" || // https://github.com/popperjs/popper-core/issues/1078
+      isScrollParent(documentElement)) {
+        scroll = getNodeScroll(offsetParent);
+      }
+      if (isHTMLElement(offsetParent)) {
+        offsets = getBoundingClientRect(offsetParent, true);
+        offsets.x += offsetParent.clientLeft;
+        offsets.y += offsetParent.clientTop;
+      } else if (documentElement) {
+        offsets.x = getWindowScrollBarX(documentElement);
+      }
+    }
+    return {
+      x: rect.left + scroll.scrollLeft - offsets.x,
+      y: rect.top + scroll.scrollTop - offsets.y,
+      width: rect.width,
+      height: rect.height
+    };
+  }
+  function getLayoutRect(element) {
+    var clientRect = getBoundingClientRect(element);
+    var width2 = element.offsetWidth;
+    var height2 = element.offsetHeight;
+    if (Math.abs(clientRect.width - width2) <= 1) {
+      width2 = clientRect.width;
+    }
+    if (Math.abs(clientRect.height - height2) <= 1) {
+      height2 = clientRect.height;
+    }
+    return {
+      x: element.offsetLeft,
+      y: element.offsetTop,
+      width: width2,
+      height: height2
+    };
+  }
+  function getParentNode(element) {
+    if (getNodeName(element) === "html") {
+      return element;
+    }
+    return (
+      // this is a quicker (but less type safe) way to save quite some bytes from the bundle
+      // $FlowFixMe[incompatible-return]
+      // $FlowFixMe[prop-missing]
+      element.assignedSlot || // step into the shadow DOM of the parent of a slotted node
+      element.parentNode || // DOM Element detected
+      (isShadowRoot(element) ? element.host : null) || // ShadowRoot detected
+      // $FlowFixMe[incompatible-call]: HTMLElement is a Node
+      getDocumentElement(element)
+    );
+  }
+  function getScrollParent(node) {
+    if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) {
+      return node.ownerDocument.body;
+    }
+    if (isHTMLElement(node) && isScrollParent(node)) {
+      return node;
+    }
+    return getScrollParent(getParentNode(node));
+  }
+  function listScrollParents(element, list) {
+    var _element$ownerDocumen;
+    if (list === void 0) {
+      list = [];
+    }
+    var scrollParent = getScrollParent(element);
+    var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
+    var win = getWindow(scrollParent);
+    var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
+    var updatedList = list.concat(target);
+    return isBody ? updatedList : (
+      // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
+      updatedList.concat(listScrollParents(getParentNode(target)))
+    );
+  }
+  function isTableElement(element) {
+    return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0;
+  }
+  function getTrueOffsetParent(element) {
+    if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
+    getComputedStyle(element).position === "fixed") {
+      return null;
+    }
+    return element.offsetParent;
+  }
+  function getContainingBlock(element) {
+    var isFirefox = /firefox/i.test(getUAString());
+    var isIE = /Trident/i.test(getUAString());
+    if (isIE && isHTMLElement(element)) {
+      var elementCss = getComputedStyle(element);
+      if (elementCss.position === "fixed") {
+        return null;
+      }
+    }
+    var currentNode = getParentNode(element);
+    if (isShadowRoot(currentNode)) {
+      currentNode = currentNode.host;
+    }
+    while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) {
+      var css = getComputedStyle(currentNode);
+      if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") {
+        return currentNode;
+      } else {
+        currentNode = currentNode.parentNode;
+      }
+    }
+    return null;
+  }
+  function getOffsetParent(element) {
+    var window2 = getWindow(element);
+    var offsetParent = getTrueOffsetParent(element);
+    while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") {
+      offsetParent = getTrueOffsetParent(offsetParent);
+    }
+    if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) {
+      return window2;
+    }
+    return offsetParent || getContainingBlock(element) || window2;
+  }
+  var top = "top";
+  var bottom = "bottom";
+  var right = "right";
+  var left = "left";
+  var auto = "auto";
+  var basePlacements = [top, bottom, right, left];
+  var start = "start";
+  var end = "end";
+  var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) {
+    return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
+  }, []);
+  var beforeRead = "beforeRead";
+  var read = "read";
+  var afterRead = "afterRead";
+  var beforeMain = "beforeMain";
+  var main = "main";
+  var afterMain = "afterMain";
+  var beforeWrite = "beforeWrite";
+  var write = "write";
+  var afterWrite = "afterWrite";
+  var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
+  function order(modifiers) {
+    var map = /* @__PURE__ */ new Map();
+    var visited = /* @__PURE__ */ new Set();
+    var result = [];
+    modifiers.forEach(function(modifier) {
+      map.set(modifier.name, modifier);
+    });
+    function sort(modifier) {
+      visited.add(modifier.name);
+      var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
+      requires.forEach(function(dep) {
+        if (!visited.has(dep)) {
+          var depModifier = map.get(dep);
+          if (depModifier) {
+            sort(depModifier);
+          }
+        }
+      });
+      result.push(modifier);
+    }
+    modifiers.forEach(function(modifier) {
+      if (!visited.has(modifier.name)) {
+        sort(modifier);
+      }
+    });
+    return result;
+  }
+  function orderModifiers(modifiers) {
+    var orderedModifiers = order(modifiers);
+    return modifierPhases.reduce(function(acc, phase) {
+      return acc.concat(orderedModifiers.filter(function(modifier) {
+        return modifier.phase === phase;
+      }));
+    }, []);
+  }
+  function debounce(fn2) {
+    var pending;
+    return function() {
+      if (!pending) {
+        pending = new Promise(function(resolve) {
+          Promise.resolve().then(function() {
+            pending = void 0;
+            resolve(fn2());
+          });
+        });
+      }
+      return pending;
+    };
+  }
+  function format(str) {
+    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+      args[_key - 1] = arguments[_key];
+    }
+    return [].concat(args).reduce(function(p, c) {
+      return p.replace(/%s/, c);
+    }, str);
+  }
+  var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';
+  var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available';
+  var VALID_PROPERTIES = ["name", "enabled", "phase", "fn", "effect", "requires", "options"];
+  function validateModifiers(modifiers) {
+    modifiers.forEach(function(modifier) {
+      [].concat(Object.keys(modifier), VALID_PROPERTIES).filter(function(value, index, self2) {
+        return self2.indexOf(value) === index;
+      }).forEach(function(key) {
+        switch (key) {
+          case "name":
+            if (typeof modifier.name !== "string") {
+              console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', '"' + String(modifier.name) + '"'));
+            }
+            break;
+          case "enabled":
+            if (typeof modifier.enabled !== "boolean") {
+              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', '"' + String(modifier.enabled) + '"'));
+            }
+            break;
+          case "phase":
+            if (modifierPhases.indexOf(modifier.phase) < 0) {
+              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(", "), '"' + String(modifier.phase) + '"'));
+            }
+            break;
+          case "fn":
+            if (typeof modifier.fn !== "function") {
+              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', '"' + String(modifier.fn) + '"'));
+            }
+            break;
+          case "effect":
+            if (modifier.effect != null && typeof modifier.effect !== "function") {
+              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', '"' + String(modifier.fn) + '"'));
+            }
+            break;
+          case "requires":
+            if (modifier.requires != null && !Array.isArray(modifier.requires)) {
+              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', '"' + String(modifier.requires) + '"'));
+            }
+            break;
+          case "requiresIfExists":
+            if (!Array.isArray(modifier.requiresIfExists)) {
+              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', '"' + String(modifier.requiresIfExists) + '"'));
+            }
+            break;
+          case "options":
+          case "data":
+            break;
+          default:
+            console.error('PopperJS: an invalid property has been provided to the "' + modifier.name + '" modifier, valid properties are ' + VALID_PROPERTIES.map(function(s) {
+              return '"' + s + '"';
+            }).join(", ") + '; but "' + key + '" was provided.');
+        }
+        modifier.requires && modifier.requires.forEach(function(requirement) {
+          if (modifiers.find(function(mod) {
+            return mod.name === requirement;
+          }) == null) {
+            console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement));
+          }
+        });
+      });
+    });
+  }
+  function uniqueBy(arr, fn2) {
+    var identifiers = /* @__PURE__ */ new Set();
+    return arr.filter(function(item) {
+      var identifier = fn2(item);
+      if (!identifiers.has(identifier)) {
+        identifiers.add(identifier);
+        return true;
+      }
+    });
+  }
+  function getBasePlacement(placement) {
+    return placement.split("-")[0];
+  }
+  function mergeByName(modifiers) {
+    var merged = modifiers.reduce(function(merged2, current2) {
+      var existing = merged2[current2.name];
+      merged2[current2.name] = existing ? Object.assign({}, existing, current2, {
+        options: Object.assign({}, existing.options, current2.options),
+        data: Object.assign({}, existing.data, current2.data)
+      }) : current2;
+      return merged2;
+    }, {});
+    return Object.keys(merged).map(function(key) {
+      return merged[key];
+    });
+  }
+  function getVariation(placement) {
+    return placement.split("-")[1];
+  }
+  function getMainAxisFromPlacement(placement) {
+    return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y";
+  }
+  function computeOffsets(_ref) {
+    var reference = _ref.reference, element = _ref.element, placement = _ref.placement;
+    var basePlacement = placement ? getBasePlacement(placement) : null;
+    var variation = placement ? getVariation(placement) : null;
+    var commonX = reference.x + reference.width / 2 - element.width / 2;
+    var commonY = reference.y + reference.height / 2 - element.height / 2;
+    var offsets;
+    switch (basePlacement) {
+      case top:
+        offsets = {
+          x: commonX,
+          y: reference.y - element.height
+        };
+        break;
+      case bottom:
+        offsets = {
+          x: commonX,
+          y: reference.y + reference.height
+        };
+        break;
+      case right:
+        offsets = {
+          x: reference.x + reference.width,
+          y: commonY
+        };
+        break;
+      case left:
+        offsets = {
+          x: reference.x - element.width,
+          y: commonY
+        };
+        break;
+      default:
+        offsets = {
+          x: reference.x,
+          y: reference.y
+        };
+    }
+    var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
+    if (mainAxis != null) {
+      var len = mainAxis === "y" ? "height" : "width";
+      switch (variation) {
+        case start:
+          offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
+          break;
+        case end:
+          offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
+          break;
+      }
+    }
+    return offsets;
+  }
+  var INVALID_ELEMENT_ERROR = "Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.";
+  var INFINITE_LOOP_ERROR = "Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.";
+  var DEFAULT_OPTIONS = {
+    placement: "bottom",
+    modifiers: [],
+    strategy: "absolute"
+  };
+  function areValidElements() {
+    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+    return !args.some(function(element) {
+      return !(element && typeof element.getBoundingClientRect === "function");
+    });
+  }
+  function popperGenerator(generatorOptions) {
+    if (generatorOptions === void 0) {
+      generatorOptions = {};
+    }
+    var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions2 = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
+    return function createPopper2(reference, popper, options) {
+      if (options === void 0) {
+        options = defaultOptions2;
+      }
+      var state = {
+        placement: "bottom",
+        orderedModifiers: [],
+        options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions2),
+        modifiersData: {},
+        elements: {
+          reference,
+          popper
+        },
+        attributes: {},
+        styles: {}
+      };
+      var effectCleanupFns = [];
+      var isDestroyed = false;
+      var instance2 = {
+        state,
+        setOptions: function setOptions(setOptionsAction) {
+          var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction;
+          cleanupModifierEffects();
+          state.options = Object.assign({}, defaultOptions2, state.options, options2);
+          state.scrollParents = {
+            reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],
+            popper: listScrollParents(popper)
+          };
+          var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers)));
+          state.orderedModifiers = orderedModifiers.filter(function(m) {
+            return m.enabled;
+          });
+          {
+            var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function(_ref) {
+              var name2 = _ref.name;
+              return name2;
+            });
+            validateModifiers(modifiers);
+            if (getBasePlacement(state.options.placement) === auto) {
+              var flipModifier = state.orderedModifiers.find(function(_ref2) {
+                var name2 = _ref2.name;
+                return name2 === "flip";
+              });
+              if (!flipModifier) {
+                console.error(['Popper: "auto" placements require the "flip" modifier be', "present and enabled to work."].join(" "));
+              }
+            }
+            var _getComputedStyle = getComputedStyle(popper), marginTop = _getComputedStyle.marginTop, marginRight = _getComputedStyle.marginRight, marginBottom = _getComputedStyle.marginBottom, marginLeft = _getComputedStyle.marginLeft;
+            if ([marginTop, marginRight, marginBottom, marginLeft].some(function(margin) {
+              return parseFloat(margin);
+            })) {
+              console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', "between the popper and its reference element or boundary.", "To replicate margin, use the `offset` modifier, as well as", "the `padding` option in the `preventOverflow` and `flip`", "modifiers."].join(" "));
+            }
+          }
+          runModifierEffects();
+          return instance2.update();
+        },
+        // Sync update – it will always be executed, even if not necessary. This
+        // is useful for low frequency updates where sync behavior simplifies the
+        // logic.
+        // For high frequency updates (e.g. `resize` and `scroll` events), always
+        // prefer the async Popper#update method
+        forceUpdate: function forceUpdate() {
+          if (isDestroyed) {
+            return;
+          }
+          var _state$elements = state.elements, reference2 = _state$elements.reference, popper2 = _state$elements.popper;
+          if (!areValidElements(reference2, popper2)) {
+            {
+              console.error(INVALID_ELEMENT_ERROR);
+            }
+            return;
+          }
+          state.rects = {
+            reference: getCompositeRect(reference2, getOffsetParent(popper2), state.options.strategy === "fixed"),
+            popper: getLayoutRect(popper2)
+          };
+          state.reset = false;
+          state.placement = state.options.placement;
+          state.orderedModifiers.forEach(function(modifier) {
+            return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
+          });
+          var __debug_loops__ = 0;
+          for (var index = 0; index < state.orderedModifiers.length; index++) {
+            {
+              __debug_loops__ += 1;
+              if (__debug_loops__ > 100) {
+                console.error(INFINITE_LOOP_ERROR);
+                break;
+              }
+            }
+            if (state.reset === true) {
+              state.reset = false;
+              index = -1;
+              continue;
+            }
+            var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name2 = _state$orderedModifie.name;
+            if (typeof fn2 === "function") {
+              state = fn2({
+                state,
+                options: _options,
+                name: name2,
+                instance: instance2
+              }) || state;
+            }
+          }
+        },
+        // Async and optimistically optimized update – it will not be executed if
+        // not necessary (debounced to run at most once-per-tick)
+        update: debounce(function() {
+          return new Promise(function(resolve) {
+            instance2.forceUpdate();
+            resolve(state);
+          });
+        }),
+        destroy: function destroy() {
+          cleanupModifierEffects();
+          isDestroyed = true;
+        }
+      };
+      if (!areValidElements(reference, popper)) {
+        {
+          console.error(INVALID_ELEMENT_ERROR);
+        }
+        return instance2;
+      }
+      instance2.setOptions(options).then(function(state2) {
+        if (!isDestroyed && options.onFirstUpdate) {
+          options.onFirstUpdate(state2);
+        }
+      });
+      function runModifierEffects() {
+        state.orderedModifiers.forEach(function(_ref3) {
+          var name2 = _ref3.name, _ref3$options = _ref3.options, options2 = _ref3$options === void 0 ? {} : _ref3$options, effect3 = _ref3.effect;
+          if (typeof effect3 === "function") {
+            var cleanupFn = effect3({
+              state,
+              name: name2,
+              instance: instance2,
+              options: options2
+            });
+            var noopFn = function noopFn2() {
+            };
+            effectCleanupFns.push(cleanupFn || noopFn);
+          }
+        });
+      }
+      function cleanupModifierEffects() {
+        effectCleanupFns.forEach(function(fn2) {
+          return fn2();
+        });
+        effectCleanupFns = [];
+      }
+      return instance2;
+    };
+  }
+  var passive = {
+    passive: true
+  };
+  function effect(_ref) {
+    var state = _ref.state, instance2 = _ref.instance, options = _ref.options;
+    var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize;
+    var window2 = getWindow(state.elements.popper);
+    var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
+    if (scroll) {
+      scrollParents.forEach(function(scrollParent) {
+        scrollParent.addEventListener("scroll", instance2.update, passive);
+      });
+    }
+    if (resize) {
+      window2.addEventListener("resize", instance2.update, passive);
+    }
+    return function() {
+      if (scroll) {
+        scrollParents.forEach(function(scrollParent) {
+          scrollParent.removeEventListener("scroll", instance2.update, passive);
+        });
+      }
+      if (resize) {
+        window2.removeEventListener("resize", instance2.update, passive);
+      }
+    };
+  }
+  var eventListeners_default = {
+    name: "eventListeners",
+    enabled: true,
+    phase: "write",
+    fn: function fn() {
+    },
+    effect,
+    data: {}
+  };
+  function popperOffsets(_ref) {
+    var state = _ref.state, name2 = _ref.name;
+    state.modifiersData[name2] = computeOffsets({
+      reference: state.rects.reference,
+      element: state.rects.popper,
+      strategy: "absolute",
+      placement: state.placement
+    });
+  }
+  var popperOffsets_default = {
+    name: "popperOffsets",
+    enabled: true,
+    phase: "read",
+    fn: popperOffsets,
+    data: {}
+  };
+  var unsetSides = {
+    top: "auto",
+    right: "auto",
+    bottom: "auto",
+    left: "auto"
+  };
+  function roundOffsetsByDPR(_ref) {
+    var x = _ref.x, y = _ref.y;
+    var win = window;
+    var dpr = win.devicePixelRatio || 1;
+    return {
+      x: round(x * dpr) / dpr || 0,
+      y: round(y * dpr) / dpr || 0
+    };
+  }
+  function mapToStyles(_ref2) {
+    var _Object$assign2;
+    var popper = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed;
+    var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y;
+    var _ref3 = typeof roundOffsets === "function" ? roundOffsets({
+      x,
+      y
+    }) : {
+      x,
+      y
+    };
+    x = _ref3.x;
+    y = _ref3.y;
+    var hasX = offsets.hasOwnProperty("x");
+    var hasY = offsets.hasOwnProperty("y");
+    var sideX = left;
+    var sideY = top;
+    var win = window;
+    if (adaptive) {
+      var offsetParent = getOffsetParent(popper);
+      var heightProp = "clientHeight";
+      var widthProp = "clientWidth";
+      if (offsetParent === getWindow(popper)) {
+        offsetParent = getDocumentElement(popper);
+        if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") {
+          heightProp = "scrollHeight";
+          widthProp = "scrollWidth";
+        }
+      }
+      offsetParent = offsetParent;
+      if (placement === top || (placement === left || placement === right) && variation === end) {
+        sideY = bottom;
+        var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : (
+          // $FlowFixMe[prop-missing]
+          offsetParent[heightProp]
+        );
+        y -= offsetY - popperRect.height;
+        y *= gpuAcceleration ? 1 : -1;
+      }
+      if (placement === left || (placement === top || placement === bottom) && variation === end) {
+        sideX = right;
+        var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : (
+          // $FlowFixMe[prop-missing]
+          offsetParent[widthProp]
+        );
+        x -= offsetX - popperRect.width;
+        x *= gpuAcceleration ? 1 : -1;
+      }
+    }
+    var commonStyles = Object.assign({
+      position
+    }, adaptive && unsetSides);
+    var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
+      x,
+      y
+    }) : {
+      x,
+      y
+    };
+    x = _ref4.x;
+    y = _ref4.y;
+    if (gpuAcceleration) {
+      var _Object$assign;
+      return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
+    }
+    return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2));
+  }
+  function computeStyles(_ref5) {
+    var state = _ref5.state, options = _ref5.options;
+    var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
+    {
+      var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || "";
+      if (adaptive && ["transform", "top", "right", "bottom", "left"].some(function(property) {
+        return transitionProperty.indexOf(property) >= 0;
+      })) {
+        console.warn(["Popper: Detected CSS transitions on at least one of the following", 'CSS properties: "transform", "top", "right", "bottom", "left".', "\n\n", 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', "for smooth transitions, or remove these properties from the CSS", "transition declaration on the popper element if only transitioning", "opacity or background-color for example.", "\n\n", "We recommend using the popper element as a wrapper around an inner", "element that can have any CSS property transitioned for animations."].join(" "));
+      }
+    }
+    var commonStyles = {
+      placement: getBasePlacement(state.placement),
+      variation: getVariation(state.placement),
+      popper: state.elements.popper,
+      popperRect: state.rects.popper,
+      gpuAcceleration,
+      isFixed: state.options.strategy === "fixed"
+    };
+    if (state.modifiersData.popperOffsets != null) {
+      state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
+        offsets: state.modifiersData.popperOffsets,
+        position: state.options.strategy,
+        adaptive,
+        roundOffsets
+      })));
+    }
+    if (state.modifiersData.arrow != null) {
+      state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
+        offsets: state.modifiersData.arrow,
+        position: "absolute",
+        adaptive: false,
+        roundOffsets
+      })));
+    }
+    state.attributes.popper = Object.assign({}, state.attributes.popper, {
+      "data-popper-placement": state.placement
+    });
+  }
+  var computeStyles_default = {
+    name: "computeStyles",
+    enabled: true,
+    phase: "beforeWrite",
+    fn: computeStyles,
+    data: {}
+  };
+  function applyStyles(_ref) {
+    var state = _ref.state;
+    Object.keys(state.elements).forEach(function(name2) {
+      var style = state.styles[name2] || {};
+      var attributes = state.attributes[name2] || {};
+      var element = state.elements[name2];
+      if (!isHTMLElement(element) || !getNodeName(element)) {
+        return;
+      }
+      Object.assign(element.style, style);
+      Object.keys(attributes).forEach(function(name22) {
+        var value = attributes[name22];
+        if (value === false) {
+          element.removeAttribute(name22);
+        } else {
+          element.setAttribute(name22, value === true ? "" : value);
+        }
+      });
+    });
+  }
+  function effect2(_ref2) {
+    var state = _ref2.state;
+    var initialStyles = {
+      popper: {
+        position: state.options.strategy,
+        left: "0",
+        top: "0",
+        margin: "0"
+      },
+      arrow: {
+        position: "absolute"
+      },
+      reference: {}
+    };
+    Object.assign(state.elements.popper.style, initialStyles.popper);
+    state.styles = initialStyles;
+    if (state.elements.arrow) {
+      Object.assign(state.elements.arrow.style, initialStyles.arrow);
+    }
+    return function() {
+      Object.keys(state.elements).forEach(function(name2) {
+        var element = state.elements[name2];
+        var attributes = state.attributes[name2] || {};
+        var styleProperties = Object.keys(state.styles.hasOwnProperty(name2) ? state.styles[name2] : initialStyles[name2]);
+        var style = styleProperties.reduce(function(style2, property) {
+          style2[property] = "";
+          return style2;
+        }, {});
+        if (!isHTMLElement(element) || !getNodeName(element)) {
+          return;
+        }
+        Object.assign(element.style, style);
+        Object.keys(attributes).forEach(function(attribute) {
+          element.removeAttribute(attribute);
+        });
+      });
+    };
+  }
+  var applyStyles_default = {
+    name: "applyStyles",
+    enabled: true,
+    phase: "write",
+    fn: applyStyles,
+    effect: effect2,
+    requires: ["computeStyles"]
+  };
+  var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default];
+  var createPopper = /* @__PURE__ */ popperGenerator({
+    defaultModifiers
+  });
+  function distanceAndSkiddingToXY(placement, rects, offset2) {
+    var basePlacement = getBasePlacement(placement);
+    var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
+    var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, {
+      placement
+    })) : offset2, skidding = _ref[0], distance = _ref[1];
+    skidding = skidding || 0;
+    distance = (distance || 0) * invertDistance;
+    return [left, right].indexOf(basePlacement) >= 0 ? {
+      x: distance,
+      y: skidding
+    } : {
+      x: skidding,
+      y: distance
+    };
+  }
+  function offset(_ref2) {
+    var state = _ref2.state, options = _ref2.options, name2 = _ref2.name;
+    var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset;
+    var data = placements.reduce(function(acc, placement) {
+      acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2);
+      return acc;
+    }, {});
+    var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y;
+    if (state.modifiersData.popperOffsets != null) {
+      state.modifiersData.popperOffsets.x += x;
+      state.modifiersData.popperOffsets.y += y;
+    }
+    state.modifiersData[name2] = data;
+  }
+  var offset_default = {
+    name: "offset",
+    enabled: true,
+    phase: "main",
+    requires: ["popperOffsets"],
+    fn: offset
+  };
+  const useSyncPropRef = (getProp, setProp) => {
+    const propRef = vue.ref(getProp());
+    vue.watch(getProp, (value) => {
+      if (value !== propRef.value) {
+        propRef.value = value;
+      }
+    });
+    vue.watch(propRef, (value) => {
+      if (value !== getProp()) {
+        setProp(value);
+      }
+    });
+    return propRef;
+  };
+  const [name$p, bem$o] = createNamespace("popover");
+  const popupProps = ["overlay", "duration", "teleport", "overlayStyle", "overlayClass", "closeOnClickOverlay"];
+  const popoverProps = {
+    show: Boolean,
+    theme: makeStringProp("light"),
+    overlay: Boolean,
+    actions: makeArrayProp(),
+    trigger: makeStringProp("click"),
+    duration: numericProp,
+    showArrow: truthProp,
+    placement: makeStringProp("bottom"),
+    iconPrefix: String,
+    overlayClass: unknownProp,
+    overlayStyle: Object,
+    closeOnClickAction: truthProp,
+    closeOnClickOverlay: truthProp,
+    closeOnClickOutside: truthProp,
+    offset: {
+      type: Array,
+      default: () => [0, 8]
+    },
+    teleport: {
+      type: [String, Object],
+      default: "body"
+    }
+  };
+  var stdin_default$x = vue.defineComponent({
+    name: name$p,
+    props: popoverProps,
+    emits: ["select", "touchstart", "update:show"],
+    setup(props, {
+      emit,
+      slots,
+      attrs
+    }) {
+      let popper;
+      const popupRef = vue.ref();
+      const wrapperRef = vue.ref();
+      const popoverRef = vue.ref();
+      const show = useSyncPropRef(() => props.show, (value) => emit("update:show", value));
+      const getPopoverOptions = () => ({
+        placement: props.placement,
+        modifiers: [{
+          name: "computeStyles",
+          options: {
+            adaptive: false,
+            gpuAcceleration: false
+          }
+        }, extend({}, offset_default, {
+          options: {
+            offset: props.offset
+          }
+        })]
+      });
+      const createPopperInstance = () => {
+        if (wrapperRef.value && popoverRef.value) {
+          return createPopper(wrapperRef.value, popoverRef.value.popupRef.value, getPopoverOptions());
+        }
+        return null;
+      };
+      const updateLocation = () => {
+        vue.nextTick(() => {
+          if (!show.value) {
+            return;
+          }
+          if (!popper) {
+            popper = createPopperInstance();
+            if (inBrowser$1) {
+              window.addEventListener("animationend", updateLocation);
+              window.addEventListener("transitionend", updateLocation);
+            }
+          } else {
+            popper.setOptions(getPopoverOptions());
+          }
+        });
+      };
+      const updateShow = (value) => {
+        show.value = value;
+      };
+      const onClickWrapper = () => {
+        if (props.trigger === "click") {
+          show.value = !show.value;
+        }
+      };
+      const onClickAction = (action, index) => {
+        if (action.disabled) {
+          return;
+        }
+        emit("select", action, index);
+        if (props.closeOnClickAction) {
+          show.value = false;
+        }
+      };
+      const onClickAway = () => {
+        if (show.value && props.closeOnClickOutside && (!props.overlay || props.closeOnClickOverlay)) {
+          show.value = false;
+        }
+      };
+      const renderActionContent = (action, index) => {
+        if (slots.action) {
+          return slots.action({
+            action,
+            index
+          });
+        }
+        return [action.icon && vue.createVNode(Icon, {
+          "name": action.icon,
+          "classPrefix": props.iconPrefix,
+          "class": bem$o("action-icon")
+        }, null), vue.createVNode("div", {
+          "class": [bem$o("action-text"), BORDER_BOTTOM]
+        }, [action.text])];
+      };
+      const renderAction = (action, index) => {
+        const {
+          icon,
+          color,
+          disabled,
+          className
+        } = action;
+        return vue.createVNode("div", {
+          "role": "menuitem",
+          "class": [bem$o("action", {
+            disabled,
+            "with-icon": icon
+          }), className],
+          "style": {
+            color
+          },
+          "tabindex": disabled ? void 0 : 0,
+          "aria-disabled": disabled || void 0,
+          "onClick": () => onClickAction(action, index)
+        }, [renderActionContent(action, index)]);
+      };
+      vue.onMounted(() => {
+        updateLocation();
+        vue.watchEffect(() => {
+          var _a;
+          popupRef.value = (_a = popoverRef.value) == null ? void 0 : _a.popupRef.value;
+        });
+      });
+      vue.onBeforeUnmount(() => {
+        if (popper) {
+          if (inBrowser$1) {
+            window.removeEventListener("animationend", updateLocation);
+            window.removeEventListener("transitionend", updateLocation);
+          }
+          popper.destroy();
+          popper = null;
+        }
+      });
+      vue.watch(() => [show.value, props.offset, props.placement], updateLocation);
+      useClickAway([wrapperRef, popupRef], onClickAway, {
+        eventName: "touchstart"
+      });
+      return () => {
+        var _a;
+        return vue.createVNode(vue.Fragment, null, [vue.createVNode("span", {
+          "ref": wrapperRef,
+          "class": bem$o("wrapper"),
+          "onClick": onClickWrapper
+        }, [(_a = slots.reference) == null ? void 0 : _a.call(slots)]), vue.createVNode(Popup, vue.mergeProps({
+          "ref": popoverRef,
+          "show": show.value,
+          "class": bem$o([props.theme]),
+          "position": "",
+          "transition": "van-popover-zoom",
+          "lockScroll": false,
+          "onUpdate:show": updateShow
+        }, attrs, pick(props, popupProps)), {
+          default: () => [props.showArrow && vue.createVNode("div", {
+            "class": bem$o("arrow")
+          }, null), vue.createVNode("div", {
+            "role": "menu",
+            "class": bem$o("content")
+          }, [slots.default ? slots.default() : props.actions.map(renderAction)])]
+        })]);
+      };
+    }
+  });
+  const Popover = withInstall(stdin_default$x);
+  const [name$o, bem$n] = createNamespace("progress");
+  const progressProps = {
+    color: String,
+    inactive: Boolean,
+    pivotText: String,
+    textColor: String,
+    showPivot: truthProp,
+    pivotColor: String,
+    trackColor: String,
+    strokeWidth: numericProp,
+    percentage: {
+      type: numericProp,
+      default: 0,
+      validator: (value) => +value >= 0 && +value <= 100
+    }
+  };
+  var stdin_default$w = vue.defineComponent({
+    name: name$o,
+    props: progressProps,
+    setup(props) {
+      const background = vue.computed(() => props.inactive ? void 0 : props.color);
+      const renderPivot = () => {
+        const {
+          textColor,
+          pivotText,
+          pivotColor,
+          percentage
+        } = props;
+        const text = pivotText != null ? pivotText : `${percentage}%`;
+        if (props.showPivot && text) {
+          const style = {
+            color: textColor,
+            left: `${+percentage}%`,
+            transform: `translate(-${+percentage}%,-50%)`,
+            background: pivotColor || background.value
+          };
+          return vue.createVNode("span", {
+            "style": style,
+            "class": bem$n("pivot", {
+              inactive: props.inactive
+            })
+          }, [text]);
+        }
+      };
+      return () => {
+        const {
+          trackColor,
+          percentage,
+          strokeWidth
+        } = props;
+        const rootStyle = {
+          background: trackColor,
+          height: addUnit(strokeWidth)
+        };
+        const portionStyle = {
+          width: `${percentage}%`,
+          background: background.value
+        };
+        return vue.createVNode("div", {
+          "class": bem$n(),
+          "style": rootStyle
+        }, [vue.createVNode("span", {
+          "class": bem$n("portion", {
+            inactive: props.inactive
+          }),
+          "style": portionStyle
+        }, null), renderPivot()]);
+      };
+    }
+  });
+  const Progress = withInstall(stdin_default$w);
+  const [name$n, bem$m, t$4] = createNamespace("pull-refresh");
+  const DEFAULT_HEAD_HEIGHT = 50;
+  const TEXT_STATUS = ["pulling", "loosing", "success"];
+  const pullRefreshProps = {
+    disabled: Boolean,
+    modelValue: Boolean,
+    headHeight: makeNumericProp(DEFAULT_HEAD_HEIGHT),
+    successText: String,
+    pullingText: String,
+    loosingText: String,
+    loadingText: String,
+    pullDistance: numericProp,
+    successDuration: makeNumericProp(500),
+    animationDuration: makeNumericProp(300)
+  };
+  var stdin_default$v = vue.defineComponent({
+    name: name$n,
+    props: pullRefreshProps,
+    emits: ["change", "refresh", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      let reachTop;
+      const root = vue.ref();
+      const track = vue.ref();
+      const scrollParent = useScrollParent(root);
+      const state = vue.reactive({
+        status: "normal",
+        distance: 0,
+        duration: 0
+      });
+      const touch = useTouch();
+      const getHeadStyle = () => {
+        if (props.headHeight !== DEFAULT_HEAD_HEIGHT) {
+          return {
+            height: `${props.headHeight}px`
+          };
+        }
+      };
+      const isTouchable = () => state.status !== "loading" && state.status !== "success" && !props.disabled;
+      const ease = (distance) => {
+        const pullDistance = +(props.pullDistance || props.headHeight);
+        if (distance > pullDistance) {
+          if (distance < pullDistance * 2) {
+            distance = pullDistance + (distance - pullDistance) / 2;
+          } else {
+            distance = pullDistance * 1.5 + (distance - pullDistance * 2) / 4;
+          }
+        }
+        return Math.round(distance);
+      };
+      const setStatus = (distance, isLoading) => {
+        const pullDistance = +(props.pullDistance || props.headHeight);
+        state.distance = distance;
+        if (isLoading) {
+          state.status = "loading";
+        } else if (distance === 0) {
+          state.status = "normal";
+        } else if (distance < pullDistance) {
+          state.status = "pulling";
+        } else {
+          state.status = "loosing";
+        }
+        emit("change", {
+          status: state.status,
+          distance
+        });
+      };
+      const getStatusText = () => {
+        const {
+          status
+        } = state;
+        if (status === "normal") {
+          return "";
+        }
+        return props[`${status}Text`] || t$4(status);
+      };
+      const renderStatus = () => {
+        const {
+          status,
+          distance
+        } = state;
+        if (slots[status]) {
+          return slots[status]({
+            distance
+          });
+        }
+        const nodes = [];
+        if (TEXT_STATUS.includes(status)) {
+          nodes.push(vue.createVNode("div", {
+            "class": bem$m("text")
+          }, [getStatusText()]));
+        }
+        if (status === "loading") {
+          nodes.push(vue.createVNode(Loading, {
+            "class": bem$m("loading")
+          }, {
+            default: getStatusText
+          }));
+        }
+        return nodes;
+      };
+      const showSuccessTip = () => {
+        state.status = "success";
+        setTimeout(() => {
+          setStatus(0);
+        }, +props.successDuration);
+      };
+      const checkPosition = (event) => {
+        reachTop = getScrollTop(scrollParent.value) === 0;
+        if (reachTop) {
+          state.duration = 0;
+          touch.start(event);
+        }
+      };
+      const onTouchStart = (event) => {
+        if (isTouchable()) {
+          checkPosition(event);
+        }
+      };
+      const onTouchMove = (event) => {
+        if (isTouchable()) {
+          if (!reachTop) {
+            checkPosition(event);
+          }
+          const {
+            deltaY
+          } = touch;
+          touch.move(event);
+          if (reachTop && deltaY.value >= 0 && touch.isVertical()) {
+            preventDefault(event);
+            setStatus(ease(deltaY.value));
+          }
+        }
+      };
+      const onTouchEnd = () => {
+        if (reachTop && touch.deltaY.value && isTouchable()) {
+          state.duration = +props.animationDuration;
+          if (state.status === "loosing") {
+            setStatus(+props.headHeight, true);
+            emit("update:modelValue", true);
+            vue.nextTick(() => emit("refresh"));
+          } else {
+            setStatus(0);
+          }
+        }
+      };
+      vue.watch(() => props.modelValue, (value) => {
+        state.duration = +props.animationDuration;
+        if (value) {
+          setStatus(+props.headHeight, true);
+        } else if (slots.success || props.successText) {
+          showSuccessTip();
+        } else {
+          setStatus(0, false);
+        }
+      });
+      useEventListener("touchmove", onTouchMove, {
+        target: track
+      });
+      return () => {
+        var _a;
+        const trackStyle = {
+          transitionDuration: `${state.duration}ms`,
+          transform: state.distance ? `translate3d(0,${state.distance}px, 0)` : ""
+        };
+        return vue.createVNode("div", {
+          "ref": root,
+          "class": bem$m()
+        }, [vue.createVNode("div", {
+          "ref": track,
+          "class": bem$m("track"),
+          "style": trackStyle,
+          "onTouchstartPassive": onTouchStart,
+          "onTouchend": onTouchEnd,
+          "onTouchcancel": onTouchEnd
+        }, [vue.createVNode("div", {
+          "class": bem$m("head"),
+          "style": getHeadStyle()
+        }, [renderStatus()]), (_a = slots.default) == null ? void 0 : _a.call(slots)])]);
+      };
+    }
+  });
+  const PullRefresh = withInstall(stdin_default$v);
+  const [name$m, bem$l] = createNamespace("rate");
+  function getRateStatus(value, index, allowHalf, readonly) {
+    if (value >= index) {
+      return {
+        status: "full",
+        value: 1
+      };
+    }
+    if (value + 0.5 >= index && allowHalf && !readonly) {
+      return {
+        status: "half",
+        value: 0.5
+      };
+    }
+    if (value + 1 >= index && allowHalf && readonly) {
+      const cardinal = 10 ** 10;
+      return {
+        status: "half",
+        value: Math.round((value - index + 1) * cardinal) / cardinal
+      };
+    }
+    return {
+      status: "void",
+      value: 0
+    };
+  }
+  const rateProps = {
+    size: numericProp,
+    icon: makeStringProp("star"),
+    color: String,
+    count: makeNumericProp(5),
+    gutter: numericProp,
+    readonly: Boolean,
+    disabled: Boolean,
+    voidIcon: makeStringProp("star-o"),
+    allowHalf: Boolean,
+    voidColor: String,
+    touchable: truthProp,
+    iconPrefix: String,
+    modelValue: makeNumberProp(0),
+    disabledColor: String
+  };
+  var stdin_default$u = vue.defineComponent({
+    name: name$m,
+    props: rateProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit
+    }) {
+      const touch = useTouch();
+      const [itemRefs, setItemRefs] = useRefs();
+      const groupRef = vue.ref();
+      const untouchable = () => props.readonly || props.disabled || !props.touchable;
+      const list = vue.computed(() => Array(+props.count).fill("").map((_, i) => getRateStatus(props.modelValue, i + 1, props.allowHalf, props.readonly)));
+      let ranges;
+      let groupRefRect;
+      let minRectTop = Number.MAX_SAFE_INTEGER;
+      let maxRectTop = Number.MIN_SAFE_INTEGER;
+      const updateRanges = () => {
+        groupRefRect = useRect(groupRef);
+        const rects = itemRefs.value.map(useRect);
+        ranges = [];
+        rects.forEach((rect, index) => {
+          minRectTop = Math.min(rect.top, minRectTop);
+          maxRectTop = Math.max(rect.top, maxRectTop);
+          if (props.allowHalf) {
+            ranges.push({
+              score: index + 0.5,
+              left: rect.left,
+              top: rect.top,
+              height: rect.height
+            }, {
+              score: index + 1,
+              left: rect.left + rect.width / 2,
+              top: rect.top,
+              height: rect.height
+            });
+          } else {
+            ranges.push({
+              score: index + 1,
+              left: rect.left,
+              top: rect.top,
+              height: rect.height
+            });
+          }
+        });
+      };
+      const getScoreByPosition = (x, y) => {
+        for (let i = ranges.length - 1; i > 0; i--) {
+          if (y >= groupRefRect.top && y <= groupRefRect.bottom) {
+            if (x > ranges[i].left && y >= ranges[i].top && y <= ranges[i].top + ranges[i].height) {
+              return ranges[i].score;
+            }
+          } else {
+            const curTop = y < groupRefRect.top ? minRectTop : maxRectTop;
+            if (x > ranges[i].left && ranges[i].top === curTop) {
+              return ranges[i].score;
+            }
+          }
+        }
+        return props.allowHalf ? 0.5 : 1;
+      };
+      const select = (index) => {
+        if (!props.disabled && !props.readonly && index !== props.modelValue) {
+          emit("update:modelValue", index);
+          emit("change", index);
+        }
+      };
+      const onTouchStart = (event) => {
+        if (untouchable()) {
+          return;
+        }
+        touch.start(event);
+        updateRanges();
+      };
+      const onTouchMove = (event) => {
+        if (untouchable()) {
+          return;
+        }
+        touch.move(event);
+        if (touch.isHorizontal()) {
+          const {
+            clientX,
+            clientY
+          } = event.touches[0];
+          preventDefault(event);
+          select(getScoreByPosition(clientX, clientY));
+        }
+      };
+      const renderStar = (item, index) => {
+        const {
+          icon,
+          size,
+          color,
+          count,
+          gutter,
+          voidIcon,
+          disabled,
+          voidColor,
+          allowHalf,
+          iconPrefix,
+          disabledColor
+        } = props;
+        const score = index + 1;
+        const isFull = item.status === "full";
+        const isVoid = item.status === "void";
+        const renderHalf = allowHalf && item.value > 0 && item.value < 1;
+        let style;
+        if (gutter && score !== +count) {
+          style = {
+            paddingRight: addUnit(gutter)
+          };
+        }
+        const onClickItem = (event) => {
+          updateRanges();
+          select(allowHalf ? getScoreByPosition(event.clientX, event.clientY) : score);
+        };
+        return vue.createVNode("div", {
+          "key": index,
+          "ref": setItemRefs(index),
+          "role": "radio",
+          "style": style,
+          "class": bem$l("item"),
+          "tabindex": disabled ? void 0 : 0,
+          "aria-setsize": count,
+          "aria-posinset": score,
+          "aria-checked": !isVoid,
+          "onClick": onClickItem
+        }, [vue.createVNode(Icon, {
+          "size": size,
+          "name": isFull ? icon : voidIcon,
+          "class": bem$l("icon", {
+            disabled,
+            full: isFull
+          }),
+          "color": disabled ? disabledColor : isFull ? color : voidColor,
+          "classPrefix": iconPrefix
+        }, null), renderHalf && vue.createVNode(Icon, {
+          "size": size,
+          "style": {
+            width: item.value + "em"
+          },
+          "name": isVoid ? voidIcon : icon,
+          "class": bem$l("icon", ["half", {
+            disabled,
+            full: !isVoid
+          }]),
+          "color": disabled ? disabledColor : isVoid ? voidColor : color,
+          "classPrefix": iconPrefix
+        }, null)]);
+      };
+      useCustomFieldValue(() => props.modelValue);
+      useEventListener("touchmove", onTouchMove, {
+        target: groupRef
+      });
+      return () => vue.createVNode("div", {
+        "ref": groupRef,
+        "role": "radiogroup",
+        "class": bem$l({
+          readonly: props.readonly,
+          disabled: props.disabled
+        }),
+        "tabindex": props.disabled ? void 0 : 0,
+        "aria-disabled": props.disabled,
+        "aria-readonly": props.readonly,
+        "onTouchstartPassive": onTouchStart
+      }, [list.value.map(renderStar)]);
+    }
+  });
+  const Rate = withInstall(stdin_default$u);
+  const Row = withInstall(stdin_default$10);
+  const [name$l, bem$k, t$3] = createNamespace("search");
+  const searchProps = extend({}, fieldSharedProps, {
+    label: String,
+    shape: makeStringProp("square"),
+    leftIcon: makeStringProp("search"),
+    clearable: truthProp,
+    actionText: String,
+    background: String,
+    showAction: Boolean
+  });
+  var stdin_default$t = vue.defineComponent({
+    name: name$l,
+    props: searchProps,
+    emits: ["blur", "focus", "clear", "search", "cancel", "clickInput", "clickLeftIcon", "clickRightIcon", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots,
+      attrs
+    }) {
+      const id = useId();
+      const fieldRef = vue.ref();
+      const onCancel = () => {
+        if (!slots.action) {
+          emit("update:modelValue", "");
+          emit("cancel");
+        }
+      };
+      const onKeypress = (event) => {
+        const ENTER_CODE = 13;
+        if (event.keyCode === ENTER_CODE) {
+          preventDefault(event);
+          emit("search", props.modelValue);
+        }
+      };
+      const getInputId = () => props.id || `${id}-input`;
+      const renderLabel = () => {
+        if (slots.label || props.label) {
+          return vue.createVNode("label", {
+            "class": bem$k("label"),
+            "for": getInputId()
+          }, [slots.label ? slots.label() : props.label]);
+        }
+      };
+      const renderAction = () => {
+        if (props.showAction) {
+          const text = props.actionText || t$3("cancel");
+          return vue.createVNode("div", {
+            "class": bem$k("action"),
+            "role": "button",
+            "tabindex": 0,
+            "onClick": onCancel
+          }, [slots.action ? slots.action() : text]);
+        }
+      };
+      const blur = () => {
+        var _a;
+        return (_a = fieldRef.value) == null ? void 0 : _a.blur();
+      };
+      const focus = () => {
+        var _a;
+        return (_a = fieldRef.value) == null ? void 0 : _a.focus();
+      };
+      const onBlur = (event) => emit("blur", event);
+      const onFocus = (event) => emit("focus", event);
+      const onClear = (event) => emit("clear", event);
+      const onClickInput = (event) => emit("clickInput", event);
+      const onClickLeftIcon = (event) => emit("clickLeftIcon", event);
+      const onClickRightIcon = (event) => emit("clickRightIcon", event);
+      const fieldPropNames = Object.keys(fieldSharedProps);
+      const renderField = () => {
+        const fieldAttrs = extend({}, attrs, pick(props, fieldPropNames), {
+          id: getInputId()
+        });
+        const onInput = (value) => emit("update:modelValue", value);
+        return vue.createVNode(Field, vue.mergeProps({
+          "ref": fieldRef,
+          "type": "search",
+          "class": bem$k("field"),
+          "border": false,
+          "onBlur": onBlur,
+          "onFocus": onFocus,
+          "onClear": onClear,
+          "onKeypress": onKeypress,
+          "onClickInput": onClickInput,
+          "onClickLeftIcon": onClickLeftIcon,
+          "onClickRightIcon": onClickRightIcon,
+          "onUpdate:modelValue": onInput
+        }, fieldAttrs), pick(slots, ["left-icon", "right-icon"]));
+      };
+      useExpose({
+        focus,
+        blur
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "class": bem$k({
+            "show-action": props.showAction
+          }),
+          "style": {
+            background: props.background
+          }
+        }, [(_a = slots.left) == null ? void 0 : _a.call(slots), vue.createVNode("div", {
+          "class": bem$k("content", props.shape)
+        }, [renderLabel(), renderField()]), renderAction()]);
+      };
+    }
+  });
+  const Search = withInstall(stdin_default$t);
+  const popupInheritKeys = [...popupSharedPropKeys, "round", "closeOnPopstate", "safeAreaInsetBottom"];
+  const iconMap = {
+    qq: "qq",
+    link: "link-o",
+    weibo: "weibo",
+    qrcode: "qr",
+    poster: "photo-o",
+    wechat: "wechat",
+    "weapp-qrcode": "miniprogram-o",
+    "wechat-moments": "wechat-moments"
+  };
+  const [name$k, bem$j, t$2] = createNamespace("share-sheet");
+  const shareSheetProps = extend({}, popupSharedProps, {
+    title: String,
+    round: truthProp,
+    options: makeArrayProp(),
+    cancelText: String,
+    description: String,
+    closeOnPopstate: truthProp,
+    safeAreaInsetBottom: truthProp
+  });
+  var stdin_default$s = vue.defineComponent({
+    name: name$k,
+    props: shareSheetProps,
+    emits: ["cancel", "select", "update:show"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const updateShow = (value) => emit("update:show", value);
+      const onCancel = () => {
+        updateShow(false);
+        emit("cancel");
+      };
+      const onSelect = (option, index) => emit("select", option, index);
+      const renderHeader = () => {
+        const title = slots.title ? slots.title() : props.title;
+        const description = slots.description ? slots.description() : props.description;
+        if (title || description) {
+          return vue.createVNode("div", {
+            "class": bem$j("header")
+          }, [title && vue.createVNode("h2", {
+            "class": bem$j("title")
+          }, [title]), description && vue.createVNode("span", {
+            "class": bem$j("description")
+          }, [description])]);
+        }
+      };
+      const renderIcon = (icon) => {
+        if (iconMap[icon]) {
+          return vue.createVNode("div", {
+            "class": bem$j("icon", [icon])
+          }, [vue.createVNode(Icon, {
+            "name": iconMap[icon] || icon
+          }, null)]);
+        }
+        return vue.createVNode("img", {
+          "src": icon,
+          "class": bem$j("image-icon")
+        }, null);
+      };
+      const renderOption = (option, index) => {
+        const {
+          name: name2,
+          icon,
+          className,
+          description
+        } = option;
+        return vue.createVNode("div", {
+          "role": "button",
+          "tabindex": 0,
+          "class": [bem$j("option"), className, HAPTICS_FEEDBACK],
+          "onClick": () => onSelect(option, index)
+        }, [renderIcon(icon), name2 && vue.createVNode("span", {
+          "class": bem$j("name")
+        }, [name2]), description && vue.createVNode("span", {
+          "class": bem$j("option-description")
+        }, [description])]);
+      };
+      const renderOptions = (options, border) => vue.createVNode("div", {
+        "class": bem$j("options", {
+          border
+        })
+      }, [options.map(renderOption)]);
+      const renderRows = () => {
+        const {
+          options
+        } = props;
+        if (Array.isArray(options[0])) {
+          return options.map((item, index) => renderOptions(item, index !== 0));
+        }
+        return renderOptions(options);
+      };
+      const renderCancelButton = () => {
+        var _a;
+        const cancelText = (_a = props.cancelText) != null ? _a : t$2("cancel");
+        if (slots.cancel || cancelText) {
+          return vue.createVNode("button", {
+            "type": "button",
+            "class": bem$j("cancel"),
+            "onClick": onCancel
+          }, [slots.cancel ? slots.cancel() : cancelText]);
+        }
+      };
+      return () => vue.createVNode(Popup, vue.mergeProps({
+        "class": bem$j(),
+        "position": "bottom",
+        "onUpdate:show": updateShow
+      }, pick(props, popupInheritKeys)), {
+        default: () => [renderHeader(), renderRows(), renderCancelButton()]
+      });
+    }
+  });
+  const ShareSheet = withInstall(stdin_default$s);
+  const [name$j, bem$i] = createNamespace("sidebar");
+  const SIDEBAR_KEY = Symbol(name$j);
+  const sidebarProps = {
+    modelValue: makeNumericProp(0)
+  };
+  var stdin_default$r = vue.defineComponent({
+    name: name$j,
+    props: sidebarProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        linkChildren
+      } = useChildren(SIDEBAR_KEY);
+      const getActive = () => +props.modelValue;
+      const setActive = (value) => {
+        if (value !== getActive()) {
+          emit("update:modelValue", value);
+          emit("change", value);
+        }
+      };
+      linkChildren({
+        getActive,
+        setActive
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "role": "tablist",
+          "class": bem$i()
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+    }
+  });
+  const Sidebar = withInstall(stdin_default$r);
+  const [name$i, bem$h] = createNamespace("sidebar-item");
+  const sidebarItemProps = extend({}, routeProps, {
+    dot: Boolean,
+    title: String,
+    badge: numericProp,
+    disabled: Boolean,
+    badgeProps: Object
+  });
+  var stdin_default$q = vue.defineComponent({
+    name: name$i,
+    props: sidebarItemProps,
+    emits: ["click"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const route2 = useRoute();
+      const {
+        parent,
+        index
+      } = useParent(SIDEBAR_KEY);
+      if (!parent) {
+        return;
+      }
+      const onClick = () => {
+        if (props.disabled) {
+          return;
+        }
+        emit("click", index.value);
+        parent.setActive(index.value);
+        route2();
+      };
+      return () => {
+        const {
+          dot,
+          badge,
+          title,
+          disabled
+        } = props;
+        const selected = index.value === parent.getActive();
+        return vue.createVNode("div", {
+          "role": "tab",
+          "class": bem$h({
+            select: selected,
+            disabled
+          }),
+          "tabindex": disabled ? void 0 : 0,
+          "aria-selected": selected,
+          "onClick": onClick
+        }, [vue.createVNode(Badge, vue.mergeProps({
+          "dot": dot,
+          "class": bem$h("text"),
+          "content": badge
+        }, props.badgeProps), {
+          default: () => [slots.title ? slots.title() : title]
+        })]);
+      };
+    }
+  });
+  const SidebarItem = withInstall(stdin_default$q);
+  const [name$h, bem$g] = createNamespace("skeleton-title");
+  const skeletonTitleProps = {
+    round: Boolean,
+    titleWidth: numericProp
+  };
+  var stdin_default$p = vue.defineComponent({
+    name: name$h,
+    props: skeletonTitleProps,
+    setup(props) {
+      return () => vue.createVNode("h3", {
+        "class": bem$g([{
+          round: props.round
+        }]),
+        "style": {
+          width: addUnit(props.titleWidth)
+        }
+      }, null);
+    }
+  });
+  const SkeletonTitle = withInstall(stdin_default$p);
+  var stdin_default$o = SkeletonTitle;
+  const [name$g, bem$f] = createNamespace("skeleton-avatar");
+  const skeletonAvatarProps = {
+    avatarSize: numericProp,
+    avatarShape: makeStringProp("round")
+  };
+  var stdin_default$n = vue.defineComponent({
+    name: name$g,
+    props: skeletonAvatarProps,
+    setup(props) {
+      return () => vue.createVNode("div", {
+        "class": bem$f([props.avatarShape]),
+        "style": getSizeStyle(props.avatarSize)
+      }, null);
+    }
+  });
+  const SkeletonAvatar = withInstall(stdin_default$n);
+  var stdin_default$m = SkeletonAvatar;
+  const DEFAULT_ROW_WIDTH = "100%";
+  const skeletonParagraphProps = {
+    round: Boolean,
+    rowWidth: {
+      type: numericProp,
+      default: DEFAULT_ROW_WIDTH
+    }
+  };
+  const [name$f, bem$e] = createNamespace("skeleton-paragraph");
+  var stdin_default$l = vue.defineComponent({
+    name: name$f,
+    props: skeletonParagraphProps,
+    setup(props) {
+      return () => vue.createVNode("div", {
+        "class": bem$e([{
+          round: props.round
+        }]),
+        "style": {
+          width: props.rowWidth
+        }
+      }, null);
+    }
+  });
+  const SkeletonParagraph = withInstall(stdin_default$l);
+  var stdin_default$k = SkeletonParagraph;
+  const [name$e, bem$d] = createNamespace("skeleton");
+  const DEFAULT_LAST_ROW_WIDTH = "60%";
+  const skeletonProps = {
+    row: makeNumericProp(0),
+    round: Boolean,
+    title: Boolean,
+    titleWidth: numericProp,
+    avatar: Boolean,
+    avatarSize: numericProp,
+    avatarShape: makeStringProp("round"),
+    loading: truthProp,
+    animate: truthProp,
+    rowWidth: {
+      type: [Number, String, Array],
+      default: DEFAULT_ROW_WIDTH
+    }
+  };
+  var stdin_default$j = vue.defineComponent({
+    name: name$e,
+    inheritAttrs: false,
+    props: skeletonProps,
+    setup(props, {
+      slots,
+      attrs
+    }) {
+      const renderAvatar = () => {
+        if (props.avatar) {
+          return vue.createVNode(stdin_default$m, {
+            "avatarShape": props.avatarShape,
+            "avatarSize": props.avatarSize
+          }, null);
+        }
+      };
+      const renderTitle = () => {
+        if (props.title) {
+          return vue.createVNode(stdin_default$o, {
+            "round": props.round,
+            "titleWidth": props.titleWidth
+          }, null);
+        }
+      };
+      const getRowWidth = (index) => {
+        const {
+          rowWidth
+        } = props;
+        if (rowWidth === DEFAULT_ROW_WIDTH && index === +props.row - 1) {
+          return DEFAULT_LAST_ROW_WIDTH;
+        }
+        if (Array.isArray(rowWidth)) {
+          return rowWidth[index];
+        }
+        return rowWidth;
+      };
+      const renderRows = () => Array(+props.row).fill("").map((_, i) => vue.createVNode(stdin_default$k, {
+        "key": i,
+        "round": props.round,
+        "rowWidth": addUnit(getRowWidth(i))
+      }, null));
+      const renderContents = () => {
+        if (slots.template) {
+          return slots.template();
+        }
+        return vue.createVNode(vue.Fragment, null, [renderAvatar(), vue.createVNode("div", {
+          "class": bem$d("content")
+        }, [renderTitle(), renderRows()])]);
+      };
+      return () => {
+        var _a;
+        if (!props.loading) {
+          return (_a = slots.default) == null ? void 0 : _a.call(slots);
+        }
+        return vue.createVNode("div", vue.mergeProps({
+          "class": bem$d({
+            animate: props.animate,
+            round: props.round
+          })
+        }, attrs), [renderContents()]);
+      };
+    }
+  });
+  const Skeleton = withInstall(stdin_default$j);
+  const [name$d, bem$c] = createNamespace("skeleton-image");
+  const skeletonImageProps = {
+    imageSize: numericProp,
+    imageShape: makeStringProp("square")
+  };
+  var stdin_default$i = vue.defineComponent({
+    name: name$d,
+    props: skeletonImageProps,
+    setup(props) {
+      return () => vue.createVNode("div", {
+        "class": bem$c([props.imageShape]),
+        "style": getSizeStyle(props.imageSize)
+      }, [vue.createVNode(Icon, {
+        "name": "photo",
+        "class": bem$c("icon")
+      }, null)]);
+    }
+  });
+  const SkeletonImage = withInstall(stdin_default$i);
+  const [name$c, bem$b] = createNamespace("slider");
+  const sliderProps = {
+    min: makeNumericProp(0),
+    max: makeNumericProp(100),
+    step: makeNumericProp(1),
+    range: Boolean,
+    reverse: Boolean,
+    disabled: Boolean,
+    readonly: Boolean,
+    vertical: Boolean,
+    barHeight: numericProp,
+    buttonSize: numericProp,
+    activeColor: String,
+    inactiveColor: String,
+    modelValue: {
+      type: [Number, Array],
+      default: 0
+    }
+  };
+  var stdin_default$h = vue.defineComponent({
+    name: name$c,
+    props: sliderProps,
+    emits: ["change", "dragEnd", "dragStart", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      let buttonIndex;
+      let current2;
+      let startValue;
+      const root = vue.ref();
+      const slider = [vue.ref(), vue.ref()];
+      const dragStatus = vue.ref();
+      const touch = useTouch();
+      const scope = vue.computed(() => Number(props.max) - Number(props.min));
+      const wrapperStyle = vue.computed(() => {
+        const crossAxis = props.vertical ? "width" : "height";
+        return {
+          background: props.inactiveColor,
+          [crossAxis]: addUnit(props.barHeight)
+        };
+      });
+      const isRange = (val) => props.range && Array.isArray(val);
+      const calcMainAxis = () => {
+        const {
+          modelValue,
+          min
+        } = props;
+        if (isRange(modelValue)) {
+          return `${(modelValue[1] - modelValue[0]) * 100 / scope.value}%`;
+        }
+        return `${(modelValue - Number(min)) * 100 / scope.value}%`;
+      };
+      const calcOffset = () => {
+        const {
+          modelValue,
+          min
+        } = props;
+        if (isRange(modelValue)) {
+          return `${(modelValue[0] - Number(min)) * 100 / scope.value}%`;
+        }
+        return "0%";
+      };
+      const barStyle = vue.computed(() => {
+        const mainAxis = props.vertical ? "height" : "width";
+        const style = {
+          [mainAxis]: calcMainAxis(),
+          background: props.activeColor
+        };
+        if (dragStatus.value) {
+          style.transition = "none";
+        }
+        const getPositionKey = () => {
+          if (props.vertical) {
+            return props.reverse ? "bottom" : "top";
+          }
+          return props.reverse ? "right" : "left";
+        };
+        style[getPositionKey()] = calcOffset();
+        return style;
+      });
+      const format2 = (value) => {
+        const min = +props.min;
+        const max = +props.max;
+        const step = +props.step;
+        value = clamp(value, min, max);
+        const diff = Math.round((value - min) / step) * step;
+        return addNumber(min, diff);
+      };
+      const handleRangeValue = (value) => {
+        var _a, _b;
+        const left2 = (_a = value[0]) != null ? _a : Number(props.min);
+        const right2 = (_b = value[1]) != null ? _b : Number(props.max);
+        return left2 > right2 ? [right2, left2] : [left2, right2];
+      };
+      const updateValue = (value, end2) => {
+        if (isRange(value)) {
+          value = handleRangeValue(value).map(format2);
+        } else {
+          value = format2(value);
+        }
+        if (!isSameValue(value, props.modelValue)) {
+          emit("update:modelValue", value);
+        }
+        if (end2 && !isSameValue(value, startValue)) {
+          emit("change", value);
+        }
+      };
+      const onClick = (event) => {
+        event.stopPropagation();
+        if (props.disabled || props.readonly) {
+          return;
+        }
+        const {
+          min,
+          reverse,
+          vertical,
+          modelValue
+        } = props;
+        const rect = useRect(root);
+        const getDelta = () => {
+          if (vertical) {
+            if (reverse) {
+              return rect.bottom - event.clientY;
+            }
+            return event.clientY - rect.top;
+          }
+          if (reverse) {
+            return rect.right - event.clientX;
+          }
+          return event.clientX - rect.left;
+        };
+        const total = vertical ? rect.height : rect.width;
+        const value = Number(min) + getDelta() / total * scope.value;
+        if (isRange(modelValue)) {
+          const [left2, right2] = modelValue;
+          const middle = (left2 + right2) / 2;
+          if (value <= middle) {
+            updateValue([value, right2], true);
+          } else {
+            updateValue([left2, value], true);
+          }
+        } else {
+          updateValue(value, true);
+        }
+      };
+      const onTouchStart = (event) => {
+        if (props.disabled || props.readonly) {
+          return;
+        }
+        touch.start(event);
+        current2 = props.modelValue;
+        if (isRange(current2)) {
+          startValue = current2.map(format2);
+        } else {
+          startValue = format2(current2);
+        }
+        dragStatus.value = "start";
+      };
+      const onTouchMove = (event) => {
+        if (props.disabled || props.readonly) {
+          return;
+        }
+        if (dragStatus.value === "start") {
+          emit("dragStart", event);
+        }
+        preventDefault(event, true);
+        touch.move(event);
+        dragStatus.value = "dragging";
+        const rect = useRect(root);
+        const delta = props.vertical ? touch.deltaY.value : touch.deltaX.value;
+        const total = props.vertical ? rect.height : rect.width;
+        let diff = delta / total * scope.value;
+        if (props.reverse) {
+          diff = -diff;
+        }
+        if (isRange(startValue)) {
+          const index = props.reverse ? 1 - buttonIndex : buttonIndex;
+          current2[index] = startValue[index] + diff;
+        } else {
+          current2 = startValue + diff;
+        }
+        updateValue(current2);
+      };
+      const onTouchEnd = (event) => {
+        if (props.disabled || props.readonly) {
+          return;
+        }
+        if (dragStatus.value === "dragging") {
+          updateValue(current2, true);
+          emit("dragEnd", event);
+        }
+        dragStatus.value = "";
+      };
+      const getButtonClassName = (index) => {
+        if (typeof index === "number") {
+          const position = ["left", "right"];
+          return bem$b(`button-wrapper`, position[index]);
+        }
+        return bem$b("button-wrapper", props.reverse ? "left" : "right");
+      };
+      const renderButtonContent = (value, index) => {
+        if (typeof index === "number") {
+          const slot = slots[index === 0 ? "left-button" : "right-button"];
+          if (slot) {
+            return slot({
+              value
+            });
+          }
+        }
+        if (slots.button) {
+          return slots.button({
+            value
+          });
+        }
+        return vue.createVNode("div", {
+          "class": bem$b("button"),
+          "style": getSizeStyle(props.buttonSize)
+        }, null);
+      };
+      const renderButton = (index) => {
+        const current22 = typeof index === "number" ? props.modelValue[index] : props.modelValue;
+        return vue.createVNode("div", {
+          "ref": slider[index != null ? index : 0],
+          "role": "slider",
+          "class": getButtonClassName(index),
+          "tabindex": props.disabled ? void 0 : 0,
+          "aria-valuemin": props.min,
+          "aria-valuenow": current22,
+          "aria-valuemax": props.max,
+          "aria-disabled": props.disabled || void 0,
+          "aria-readonly": props.readonly || void 0,
+          "aria-orientation": props.vertical ? "vertical" : "horizontal",
+          "onTouchstartPassive": (event) => {
+            if (typeof index === "number") {
+              buttonIndex = index;
+            }
+            onTouchStart(event);
+          },
+          "onTouchend": onTouchEnd,
+          "onTouchcancel": onTouchEnd,
+          "onClick": stopPropagation
+        }, [renderButtonContent(current22, index)]);
+      };
+      updateValue(props.modelValue);
+      useCustomFieldValue(() => props.modelValue);
+      slider.forEach((item) => {
+        useEventListener("touchmove", onTouchMove, {
+          target: item
+        });
+      });
+      return () => vue.createVNode("div", {
+        "ref": root,
+        "style": wrapperStyle.value,
+        "class": bem$b({
+          vertical: props.vertical,
+          disabled: props.disabled
+        }),
+        "onClick": onClick
+      }, [vue.createVNode("div", {
+        "class": bem$b("bar"),
+        "style": barStyle.value
+      }, [props.range ? [renderButton(0), renderButton(1)] : renderButton()])]);
+    }
+  });
+  const Slider = withInstall(stdin_default$h);
+  const [name$b, bem$a] = createNamespace("space");
+  const spaceProps = {
+    align: String,
+    direction: {
+      type: String,
+      default: "horizontal"
+    },
+    size: {
+      type: [Number, String, Array],
+      default: 8
+    },
+    wrap: Boolean,
+    fill: Boolean
+  };
+  function filterEmpty(children = []) {
+    const nodes = [];
+    children.forEach((child) => {
+      if (Array.isArray(child)) {
+        nodes.push(...child);
+      } else if (child.type === vue.Fragment) {
+        nodes.push(...filterEmpty(child.children));
+      } else {
+        nodes.push(child);
+      }
+    });
+    return nodes.filter((c) => {
+      var _a;
+      return !(c && (c.type === vue.Comment || c.type === vue.Fragment && ((_a = c.children) == null ? void 0 : _a.length) === 0 || c.type === vue.Text && c.children.trim() === ""));
+    });
+  }
+  var stdin_default$g = vue.defineComponent({
+    name: name$b,
+    props: spaceProps,
+    setup(props, {
+      slots
+    }) {
+      const mergedAlign = vue.computed(() => {
+        var _a;
+        return (_a = props.align) != null ? _a : props.direction === "horizontal" ? "center" : "";
+      });
+      const getMargin = (size) => {
+        if (typeof size === "number") {
+          return size + "px";
+        }
+        return size;
+      };
+      const getMarginStyle = (isLast) => {
+        const style = {};
+        const marginRight = `${getMargin(Array.isArray(props.size) ? props.size[0] : props.size)}`;
+        const marginBottom = `${getMargin(Array.isArray(props.size) ? props.size[1] : props.size)}`;
+        if (isLast) {
+          return props.wrap ? {
+            marginBottom
+          } : {};
+        }
+        if (props.direction === "horizontal") {
+          style.marginRight = marginRight;
+        }
+        if (props.direction === "vertical" || props.wrap) {
+          style.marginBottom = marginBottom;
+        }
+        return style;
+      };
+      return () => {
+        var _a;
+        const children = filterEmpty((_a = slots.default) == null ? void 0 : _a.call(slots));
+        return vue.createVNode("div", {
+          "class": [bem$a({
+            [props.direction]: props.direction,
+            [`align-${mergedAlign.value}`]: mergedAlign.value,
+            wrap: props.wrap,
+            fill: props.fill
+          })]
+        }, [children.map((c, i) => vue.createVNode("div", {
+          "key": `item-${i}`,
+          "class": `${name$b}-item`,
+          "style": getMarginStyle(i === children.length - 1)
+        }, [c]))]);
+      };
+    }
+  });
+  const Space = withInstall(stdin_default$g);
+  const [name$a, bem$9] = createNamespace("steps");
+  const stepsProps = {
+    active: makeNumericProp(0),
+    direction: makeStringProp("horizontal"),
+    activeIcon: makeStringProp("checked"),
+    iconPrefix: String,
+    finishIcon: String,
+    activeColor: String,
+    inactiveIcon: String,
+    inactiveColor: String
+  };
+  const STEPS_KEY = Symbol(name$a);
+  var stdin_default$f = vue.defineComponent({
+    name: name$a,
+    props: stepsProps,
+    emits: ["clickStep"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const {
+        linkChildren
+      } = useChildren(STEPS_KEY);
+      const onClickStep = (index) => emit("clickStep", index);
+      linkChildren({
+        props,
+        onClickStep
+      });
+      return () => {
+        var _a;
+        return vue.createVNode("div", {
+          "class": bem$9([props.direction])
+        }, [vue.createVNode("div", {
+          "class": bem$9("items")
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)])]);
+      };
+    }
+  });
+  const [name$9, bem$8] = createNamespace("step");
+  var stdin_default$e = vue.defineComponent({
+    name: name$9,
+    setup(props, {
+      slots
+    }) {
+      const {
+        parent,
+        index
+      } = useParent(STEPS_KEY);
+      if (!parent) {
+        return;
+      }
+      const parentProps = parent.props;
+      const getStatus = () => {
+        const active = +parentProps.active;
+        if (index.value < active) {
+          return "finish";
+        }
+        return index.value === active ? "process" : "waiting";
+      };
+      const isActive = () => getStatus() === "process";
+      const lineStyle = vue.computed(() => ({
+        background: getStatus() === "finish" ? parentProps.activeColor : parentProps.inactiveColor
+      }));
+      const titleStyle = vue.computed(() => {
+        if (isActive()) {
+          return {
+            color: parentProps.activeColor
+          };
+        }
+        if (getStatus() === "waiting") {
+          return {
+            color: parentProps.inactiveColor
+          };
+        }
+      });
+      const onClickStep = () => parent.onClickStep(index.value);
+      const renderCircle = () => {
+        const {
+          iconPrefix,
+          finishIcon,
+          activeIcon,
+          activeColor,
+          inactiveIcon
+        } = parentProps;
+        if (isActive()) {
+          if (slots["active-icon"]) {
+            return slots["active-icon"]();
+          }
+          return vue.createVNode(Icon, {
+            "class": bem$8("icon", "active"),
+            "name": activeIcon,
+            "color": activeColor,
+            "classPrefix": iconPrefix
+          }, null);
+        }
+        if (getStatus() === "finish" && (finishIcon || slots["finish-icon"])) {
+          if (slots["finish-icon"]) {
+            return slots["finish-icon"]();
+          }
+          return vue.createVNode(Icon, {
+            "class": bem$8("icon", "finish"),
+            "name": finishIcon,
+            "color": activeColor,
+            "classPrefix": iconPrefix
+          }, null);
+        }
+        if (slots["inactive-icon"]) {
+          return slots["inactive-icon"]();
+        }
+        if (inactiveIcon) {
+          return vue.createVNode(Icon, {
+            "class": bem$8("icon"),
+            "name": inactiveIcon,
+            "classPrefix": iconPrefix
+          }, null);
+        }
+        return vue.createVNode("i", {
+          "class": bem$8("circle"),
+          "style": lineStyle.value
+        }, null);
+      };
+      return () => {
+        var _a;
+        const status = getStatus();
+        return vue.createVNode("div", {
+          "class": [BORDER, bem$8([parentProps.direction, {
+            [status]: status
+          }])]
+        }, [vue.createVNode("div", {
+          "class": bem$8("title", {
+            active: isActive()
+          }),
+          "style": titleStyle.value,
+          "onClick": onClickStep
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), vue.createVNode("div", {
+          "class": bem$8("circle-container"),
+          "onClick": onClickStep
+        }, [renderCircle()]), vue.createVNode("div", {
+          "class": bem$8("line"),
+          "style": lineStyle.value
+        }, null)]);
+      };
+    }
+  });
+  const Step = withInstall(stdin_default$e);
+  const [name$8, bem$7] = createNamespace("stepper");
+  const LONG_PRESS_INTERVAL = 200;
+  const isEqual = (value1, value2) => String(value1) === String(value2);
+  const stepperProps = {
+    min: makeNumericProp(1),
+    max: makeNumericProp(Infinity),
+    name: makeNumericProp(""),
+    step: makeNumericProp(1),
+    theme: String,
+    integer: Boolean,
+    disabled: Boolean,
+    showPlus: truthProp,
+    showMinus: truthProp,
+    showInput: truthProp,
+    longPress: truthProp,
+    autoFixed: truthProp,
+    allowEmpty: Boolean,
+    modelValue: numericProp,
+    inputWidth: numericProp,
+    buttonSize: numericProp,
+    placeholder: String,
+    disablePlus: Boolean,
+    disableMinus: Boolean,
+    disableInput: Boolean,
+    beforeChange: Function,
+    defaultValue: makeNumericProp(1),
+    decimalLength: numericProp
+  };
+  var stdin_default$d = vue.defineComponent({
+    name: name$8,
+    props: stepperProps,
+    emits: ["plus", "blur", "minus", "focus", "change", "overlimit", "update:modelValue"],
+    setup(props, {
+      emit
+    }) {
+      const format2 = (value, autoFixed = true) => {
+        const {
+          min,
+          max,
+          allowEmpty,
+          decimalLength
+        } = props;
+        if (allowEmpty && value === "") {
+          return value;
+        }
+        value = formatNumber(String(value), !props.integer);
+        value = value === "" ? 0 : +value;
+        value = Number.isNaN(value) ? +min : value;
+        value = autoFixed ? Math.max(Math.min(+max, value), +min) : value;
+        if (isDef(decimalLength)) {
+          value = value.toFixed(+decimalLength);
+        }
+        return value;
+      };
+      const getInitialValue = () => {
+        var _a;
+        const defaultValue = (_a = props.modelValue) != null ? _a : props.defaultValue;
+        const value = format2(defaultValue);
+        if (!isEqual(value, props.modelValue)) {
+          emit("update:modelValue", value);
+        }
+        return value;
+      };
+      let actionType;
+      const inputRef = vue.ref();
+      const current2 = vue.ref(getInitialValue());
+      const minusDisabled = vue.computed(() => props.disabled || props.disableMinus || +current2.value <= +props.min);
+      const plusDisabled = vue.computed(() => props.disabled || props.disablePlus || +current2.value >= +props.max);
+      const inputStyle = vue.computed(() => ({
+        width: addUnit(props.inputWidth),
+        height: addUnit(props.buttonSize)
+      }));
+      const buttonStyle = vue.computed(() => getSizeStyle(props.buttonSize));
+      const check = () => {
+        const value = format2(current2.value);
+        if (!isEqual(value, current2.value)) {
+          current2.value = value;
+        }
+      };
+      const setValue = (value) => {
+        if (props.beforeChange) {
+          callInterceptor(props.beforeChange, {
+            args: [value],
+            done() {
+              current2.value = value;
+            }
+          });
+        } else {
+          current2.value = value;
+        }
+      };
+      const onChange = () => {
+        if (actionType === "plus" && plusDisabled.value || actionType === "minus" && minusDisabled.value) {
+          emit("overlimit", actionType);
+          return;
+        }
+        const diff = actionType === "minus" ? -props.step : +props.step;
+        const value = format2(addNumber(+current2.value, diff));
+        setValue(value);
+        emit(actionType);
+      };
+      const onInput = (event) => {
+        const input = event.target;
+        const {
+          value
+        } = input;
+        const {
+          decimalLength
+        } = props;
+        let formatted = formatNumber(String(value), !props.integer);
+        if (isDef(decimalLength) && formatted.includes(".")) {
+          const pair = formatted.split(".");
+          formatted = `${pair[0]}.${pair[1].slice(0, +decimalLength)}`;
+        }
+        if (props.beforeChange) {
+          input.value = String(current2.value);
+        } else if (!isEqual(value, formatted)) {
+          input.value = formatted;
+        }
+        const isNumeric2 = formatted === String(+formatted);
+        setValue(isNumeric2 ? +formatted : formatted);
+      };
+      const onFocus = (event) => {
+        var _a;
+        if (props.disableInput) {
+          (_a = inputRef.value) == null ? void 0 : _a.blur();
+        } else {
+          emit("focus", event);
+        }
+      };
+      const onBlur = (event) => {
+        const input = event.target;
+        const value = format2(input.value, props.autoFixed);
+        input.value = String(value);
+        current2.value = value;
+        vue.nextTick(() => {
+          emit("blur", event);
+          resetScroll();
+        });
+      };
+      let isLongPress;
+      let longPressTimer;
+      const longPressStep = () => {
+        longPressTimer = setTimeout(() => {
+          onChange();
+          longPressStep();
+        }, LONG_PRESS_INTERVAL);
+      };
+      const onTouchStart = () => {
+        if (props.longPress) {
+          isLongPress = false;
+          clearTimeout(longPressTimer);
+          longPressTimer = setTimeout(() => {
+            isLongPress = true;
+            onChange();
+            longPressStep();
+          }, LONG_PRESS_START_TIME);
+        }
+      };
+      const onTouchEnd = (event) => {
+        if (props.longPress) {
+          clearTimeout(longPressTimer);
+          if (isLongPress) {
+            preventDefault(event);
+          }
+        }
+      };
+      const onMousedown = (event) => {
+        if (props.disableInput) {
+          preventDefault(event);
+        }
+      };
+      const createListeners = (type) => ({
+        onClick: (event) => {
+          preventDefault(event);
+          actionType = type;
+          onChange();
+        },
+        onTouchstartPassive: () => {
+          actionType = type;
+          onTouchStart();
+        },
+        onTouchend: onTouchEnd,
+        onTouchcancel: onTouchEnd
+      });
+      vue.watch(() => [props.max, props.min, props.integer, props.decimalLength], check);
+      vue.watch(() => props.modelValue, (value) => {
+        if (!isEqual(value, current2.value)) {
+          current2.value = format2(value);
+        }
+      });
+      vue.watch(current2, (value) => {
+        emit("update:modelValue", value);
+        emit("change", value, {
+          name: props.name
+        });
+      });
+      useCustomFieldValue(() => props.modelValue);
+      return () => vue.createVNode("div", {
+        "role": "group",
+        "class": bem$7([props.theme])
+      }, [vue.withDirectives(vue.createVNode("button", vue.mergeProps({
+        "type": "button",
+        "style": buttonStyle.value,
+        "class": [bem$7("minus", {
+          disabled: minusDisabled.value
+        }), {
+          [HAPTICS_FEEDBACK]: !minusDisabled.value
+        }],
+        "aria-disabled": minusDisabled.value || void 0
+      }, createListeners("minus")), null), [[vue.vShow, props.showMinus]]), vue.withDirectives(vue.createVNode("input", {
+        "ref": inputRef,
+        "type": props.integer ? "tel" : "text",
+        "role": "spinbutton",
+        "class": bem$7("input"),
+        "value": current2.value,
+        "style": inputStyle.value,
+        "disabled": props.disabled,
+        "readonly": props.disableInput,
+        "inputmode": props.integer ? "numeric" : "decimal",
+        "placeholder": props.placeholder,
+        "aria-valuemax": props.max,
+        "aria-valuemin": props.min,
+        "aria-valuenow": current2.value,
+        "onBlur": onBlur,
+        "onInput": onInput,
+        "onFocus": onFocus,
+        "onMousedown": onMousedown
+      }, null), [[vue.vShow, props.showInput]]), vue.withDirectives(vue.createVNode("button", vue.mergeProps({
+        "type": "button",
+        "style": buttonStyle.value,
+        "class": [bem$7("plus", {
+          disabled: plusDisabled.value
+        }), {
+          [HAPTICS_FEEDBACK]: !plusDisabled.value
+        }],
+        "aria-disabled": plusDisabled.value || void 0
+      }, createListeners("plus")), null), [[vue.vShow, props.showPlus]])]);
+    }
+  });
+  const Stepper = withInstall(stdin_default$d);
+  const Steps = withInstall(stdin_default$f);
+  const [name$7, bem$6, t$1] = createNamespace("submit-bar");
+  const submitBarProps = {
+    tip: String,
+    label: String,
+    price: Number,
+    tipIcon: String,
+    loading: Boolean,
+    currency: makeStringProp("¥"),
+    disabled: Boolean,
+    textAlign: String,
+    buttonText: String,
+    buttonType: makeStringProp("danger"),
+    buttonColor: String,
+    suffixLabel: String,
+    placeholder: Boolean,
+    decimalLength: makeNumericProp(2),
+    safeAreaInsetBottom: truthProp
+  };
+  var stdin_default$c = vue.defineComponent({
+    name: name$7,
+    props: submitBarProps,
+    emits: ["submit"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const root = vue.ref();
+      const renderPlaceholder = usePlaceholder(root, bem$6);
+      const renderText = () => {
+        const {
+          price,
+          label,
+          currency,
+          textAlign,
+          suffixLabel,
+          decimalLength
+        } = props;
+        if (typeof price === "number") {
+          const pricePair = (price / 100).toFixed(+decimalLength).split(".");
+          const decimal = decimalLength ? `.${pricePair[1]}` : "";
+          return vue.createVNode("div", {
+            "class": bem$6("text"),
+            "style": {
+              textAlign
+            }
+          }, [vue.createVNode("span", null, [label || t$1("label")]), vue.createVNode("span", {
+            "class": bem$6("price")
+          }, [currency, vue.createVNode("span", {
+            "class": bem$6("price-integer")
+          }, [pricePair[0]]), decimal]), suffixLabel && vue.createVNode("span", {
+            "class": bem$6("suffix-label")
+          }, [suffixLabel])]);
+        }
+      };
+      const renderTip = () => {
+        var _a;
+        const {
+          tip,
+          tipIcon
+        } = props;
+        if (slots.tip || tip) {
+          return vue.createVNode("div", {
+            "class": bem$6("tip")
+          }, [tipIcon && vue.createVNode(Icon, {
+            "class": bem$6("tip-icon"),
+            "name": tipIcon
+          }, null), tip && vue.createVNode("span", {
+            "class": bem$6("tip-text")
+          }, [tip]), (_a = slots.tip) == null ? void 0 : _a.call(slots)]);
+        }
+      };
+      const onClickButton = () => emit("submit");
+      const renderButton = () => {
+        if (slots.button) {
+          return slots.button();
+        }
+        return vue.createVNode(Button, {
+          "round": true,
+          "type": props.buttonType,
+          "text": props.buttonText,
+          "class": bem$6("button", props.buttonType),
+          "color": props.buttonColor,
+          "loading": props.loading,
+          "disabled": props.disabled,
+          "onClick": onClickButton
+        }, null);
+      };
+      const renderSubmitBar = () => {
+        var _a, _b;
+        return vue.createVNode("div", {
+          "ref": root,
+          "class": [bem$6(), {
+            "van-safe-area-bottom": props.safeAreaInsetBottom
+          }]
+        }, [(_a = slots.top) == null ? void 0 : _a.call(slots), renderTip(), vue.createVNode("div", {
+          "class": bem$6("bar")
+        }, [(_b = slots.default) == null ? void 0 : _b.call(slots), renderText(), renderButton()])]);
+      };
+      return () => {
+        if (props.placeholder) {
+          return renderPlaceholder(renderSubmitBar);
+        }
+        return renderSubmitBar();
+      };
+    }
+  });
+  const SubmitBar = withInstall(stdin_default$c);
+  const [name$6, bem$5] = createNamespace("swipe-cell");
+  const swipeCellProps = {
+    name: makeNumericProp(""),
+    disabled: Boolean,
+    leftWidth: numericProp,
+    rightWidth: numericProp,
+    beforeClose: Function,
+    stopPropagation: Boolean
+  };
+  var stdin_default$b = vue.defineComponent({
+    name: name$6,
+    props: swipeCellProps,
+    emits: ["open", "close", "click"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      let opened;
+      let lockClick2;
+      let startOffset;
+      const root = vue.ref();
+      const leftRef = vue.ref();
+      const rightRef = vue.ref();
+      const state = vue.reactive({
+        offset: 0,
+        dragging: false
+      });
+      const touch = useTouch();
+      const getWidthByRef = (ref2) => ref2.value ? useRect(ref2).width : 0;
+      const leftWidth = vue.computed(() => isDef(props.leftWidth) ? +props.leftWidth : getWidthByRef(leftRef));
+      const rightWidth = vue.computed(() => isDef(props.rightWidth) ? +props.rightWidth : getWidthByRef(rightRef));
+      const open = (side) => {
+        state.offset = side === "left" ? leftWidth.value : -rightWidth.value;
+        if (!opened) {
+          opened = true;
+          emit("open", {
+            name: props.name,
+            position: side
+          });
+        }
+      };
+      const close = (position) => {
+        state.offset = 0;
+        if (opened) {
+          opened = false;
+          emit("close", {
+            name: props.name,
+            position
+          });
+        }
+      };
+      const toggle = (side) => {
+        const offset2 = Math.abs(state.offset);
+        const THRESHOLD = 0.15;
+        const threshold = opened ? 1 - THRESHOLD : THRESHOLD;
+        const width2 = side === "left" ? leftWidth.value : rightWidth.value;
+        if (width2 && offset2 > width2 * threshold) {
+          open(side);
+        } else {
+          close(side);
+        }
+      };
+      const onTouchStart = (event) => {
+        if (!props.disabled) {
+          startOffset = state.offset;
+          touch.start(event);
+        }
+      };
+      const onTouchMove = (event) => {
+        if (props.disabled) {
+          return;
+        }
+        const {
+          deltaX
+        } = touch;
+        touch.move(event);
+        if (touch.isHorizontal()) {
+          lockClick2 = true;
+          state.dragging = true;
+          const isEdge = !opened || deltaX.value * startOffset < 0;
+          if (isEdge) {
+            preventDefault(event, props.stopPropagation);
+          }
+          state.offset = clamp(deltaX.value + startOffset, -rightWidth.value, leftWidth.value);
+        }
+      };
+      const onTouchEnd = () => {
+        if (state.dragging) {
+          state.dragging = false;
+          toggle(state.offset > 0 ? "left" : "right");
+          setTimeout(() => {
+            lockClick2 = false;
+          }, 0);
+        }
+      };
+      const onClick = (position = "outside") => {
+        emit("click", position);
+        if (opened && !lockClick2) {
+          callInterceptor(props.beforeClose, {
+            args: [{
+              name: props.name,
+              position
+            }],
+            done: () => close(position)
+          });
+        }
+      };
+      const getClickHandler = (position, stop) => (event) => {
+        if (stop) {
+          event.stopPropagation();
+        }
+        onClick(position);
+      };
+      const renderSideContent = (side, ref2) => {
+        const contentSlot = slots[side];
+        if (contentSlot) {
+          return vue.createVNode("div", {
+            "ref": ref2,
+            "class": bem$5(side),
+            "onClick": getClickHandler(side, true)
+          }, [contentSlot()]);
+        }
+      };
+      useExpose({
+        open,
+        close
+      });
+      useClickAway(root, () => onClick("outside"), {
+        eventName: "touchstart"
+      });
+      useEventListener("touchmove", onTouchMove, {
+        target: root
+      });
+      return () => {
+        var _a;
+        const wrapperStyle = {
+          transform: `translate3d(${state.offset}px, 0, 0)`,
+          transitionDuration: state.dragging ? "0s" : ".6s"
+        };
+        return vue.createVNode("div", {
+          "ref": root,
+          "class": bem$5(),
+          "onClick": getClickHandler("cell", lockClick2),
+          "onTouchstartPassive": onTouchStart,
+          "onTouchend": onTouchEnd,
+          "onTouchcancel": onTouchEnd
+        }, [vue.createVNode("div", {
+          "class": bem$5("wrapper"),
+          "style": wrapperStyle
+        }, [renderSideContent("left", leftRef), (_a = slots.default) == null ? void 0 : _a.call(slots), renderSideContent("right", rightRef)])]);
+      };
+    }
+  });
+  const SwipeCell = withInstall(stdin_default$b);
+  const [name$5, bem$4] = createNamespace("tabbar");
+  const tabbarProps = {
+    route: Boolean,
+    fixed: truthProp,
+    border: truthProp,
+    zIndex: numericProp,
+    placeholder: Boolean,
+    activeColor: String,
+    beforeChange: Function,
+    inactiveColor: String,
+    modelValue: makeNumericProp(0),
+    safeAreaInsetBottom: {
+      type: Boolean,
+      default: null
+    }
+  };
+  const TABBAR_KEY = Symbol(name$5);
+  var stdin_default$a = vue.defineComponent({
+    name: name$5,
+    props: tabbarProps,
+    emits: ["change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const root = vue.ref();
+      const {
+        linkChildren
+      } = useChildren(TABBAR_KEY);
+      const renderPlaceholder = usePlaceholder(root, bem$4);
+      const enableSafeArea = () => {
+        var _a;
+        return (_a = props.safeAreaInsetBottom) != null ? _a : props.fixed;
+      };
+      const renderTabbar = () => {
+        var _a;
+        const {
+          fixed,
+          zIndex,
+          border
+        } = props;
+        return vue.createVNode("div", {
+          "ref": root,
+          "role": "tablist",
+          "style": getZIndexStyle(zIndex),
+          "class": [bem$4({
+            fixed
+          }), {
+            [BORDER_TOP_BOTTOM]: border,
+            "van-safe-area-bottom": enableSafeArea()
+          }]
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
+      };
+      const setActive = (active, afterChange) => {
+        callInterceptor(props.beforeChange, {
+          args: [active],
+          done() {
+            emit("update:modelValue", active);
+            emit("change", active);
+            afterChange();
+          }
+        });
+      };
+      linkChildren({
+        props,
+        setActive
+      });
+      return () => {
+        if (props.fixed && props.placeholder) {
+          return renderPlaceholder(renderTabbar);
+        }
+        return renderTabbar();
+      };
+    }
+  });
+  const Tabbar = withInstall(stdin_default$a);
+  const [name$4, bem$3] = createNamespace("tabbar-item");
+  const tabbarItemProps = extend({}, routeProps, {
+    dot: Boolean,
+    icon: String,
+    name: numericProp,
+    badge: numericProp,
+    badgeProps: Object,
+    iconPrefix: String
+  });
+  var stdin_default$9 = vue.defineComponent({
+    name: name$4,
+    props: tabbarItemProps,
+    emits: ["click"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const route2 = useRoute();
+      const vm = vue.getCurrentInstance().proxy;
+      const {
+        parent,
+        index
+      } = useParent(TABBAR_KEY);
+      if (!parent) {
+        return;
+      }
+      const active = vue.computed(() => {
+        var _a;
+        const {
+          route: route22,
+          modelValue
+        } = parent.props;
+        if (route22 && "$route" in vm) {
+          const {
+            $route
+          } = vm;
+          const {
+            to
+          } = props;
+          const config = isObject(to) ? to : {
+            path: to
+          };
+          return !!$route.matched.find((val) => {
+            const pathMatched = "path" in config && config.path === val.path;
+            const nameMatched = "name" in config && config.name === val.name;
+            return pathMatched || nameMatched;
+          });
+        }
+        return ((_a = props.name) != null ? _a : index.value) === modelValue;
+      });
+      const onClick = (event) => {
+        var _a;
+        if (!active.value) {
+          parent.setActive((_a = props.name) != null ? _a : index.value, route2);
+        }
+        emit("click", event);
+      };
+      const renderIcon = () => {
+        if (slots.icon) {
+          return slots.icon({
+            active: active.value
+          });
+        }
+        if (props.icon) {
+          return vue.createVNode(Icon, {
+            "name": props.icon,
+            "classPrefix": props.iconPrefix
+          }, null);
+        }
+      };
+      return () => {
+        var _a;
+        const {
+          dot,
+          badge
+        } = props;
+        const {
+          activeColor,
+          inactiveColor
+        } = parent.props;
+        const color = active.value ? activeColor : inactiveColor;
+        return vue.createVNode("div", {
+          "role": "tab",
+          "class": bem$3({
+            active: active.value
+          }),
+          "style": {
+            color
+          },
+          "tabindex": 0,
+          "aria-selected": active.value,
+          "onClick": onClick
+        }, [vue.createVNode(Badge, vue.mergeProps({
+          "dot": dot,
+          "class": bem$3("icon"),
+          "content": badge
+        }, props.badgeProps), {
+          default: renderIcon
+        }), vue.createVNode("div", {
+          "class": bem$3("text")
+        }, [(_a = slots.default) == null ? void 0 : _a.call(slots, {
+          active: active.value
+        })])]);
+      };
+    }
+  });
+  const TabbarItem = withInstall(stdin_default$9);
+  const [name$3, bem$2] = createNamespace("text-ellipsis");
+  const textEllipsisProps = {
+    rows: makeNumericProp(1),
+    content: makeStringProp(""),
+    expandText: makeStringProp(""),
+    collapseText: makeStringProp("")
+  };
+  var stdin_default$8 = vue.defineComponent({
+    name: name$3,
+    props: textEllipsisProps,
+    emits: ["clickAction"],
+    setup(props, {
+      emit
+    }) {
+      const text = vue.ref("");
+      const expanded = vue.ref(false);
+      const hasAction = vue.ref(false);
+      const root = vue.ref();
+      const pxToNum = (value) => {
+        if (!value)
+          return 0;
+        const match = value.match(/^\d*(\.\d*)?/);
+        return match ? Number(match[0]) : 0;
+      };
+      const calcEllipsised = () => {
+        const cloneContainer = () => {
+          if (!root.value)
+            return;
+          const originStyle = window.getComputedStyle(root.value);
+          const container2 = document.createElement("div");
+          const styleNames = Array.prototype.slice.apply(originStyle);
+          styleNames.forEach((name2) => {
+            container2.style.setProperty(name2, originStyle.getPropertyValue(name2));
+          });
+          container2.style.position = "fixed";
+          container2.style.zIndex = "-9999";
+          container2.style.top = "-9999px";
+          container2.style.height = "auto";
+          container2.style.minHeight = "auto";
+          container2.style.maxHeight = "auto";
+          container2.innerText = props.content;
+          document.body.appendChild(container2);
+          return container2;
+        };
+        const calcEllipsisText = (container2, maxHeight2) => {
+          const {
+            content,
+            expandText
+          } = props;
+          const dot = "...";
+          let left2 = 0;
+          let right2 = content.length;
+          let res = -1;
+          while (left2 <= right2) {
+            const mid = Math.floor((left2 + right2) / 2);
+            container2.innerText = content.slice(0, mid) + dot + expandText;
+            if (container2.offsetHeight <= maxHeight2) {
+              left2 = mid + 1;
+              res = mid;
+            } else {
+              right2 = mid - 1;
+            }
+          }
+          return content.slice(0, res) + dot;
+        };
+        const container = cloneContainer();
+        if (!container)
+          return;
+        const {
+          paddingBottom,
+          paddingTop,
+          lineHeight
+        } = container.style;
+        const maxHeight = (Number(props.rows) + 0.5) * pxToNum(lineHeight) + pxToNum(paddingTop) + pxToNum(paddingBottom);
+        if (maxHeight < container.offsetHeight) {
+          hasAction.value = true;
+          text.value = calcEllipsisText(container, maxHeight);
+        } else {
+          hasAction.value = false;
+          text.value = props.content;
+        }
+        document.body.removeChild(container);
+      };
+      const onClickAction = (event) => {
+        expanded.value = !expanded.value;
+        emit("clickAction", event);
+      };
+      const renderAction = () => vue.createVNode("span", {
+        "class": bem$2("action"),
+        "onClick": onClickAction
+      }, [expanded.value ? props.collapseText : props.expandText]);
+      vue.onMounted(calcEllipsised);
+      vue.watch(() => [props.content, props.rows], calcEllipsised);
+      useEventListener("resize", calcEllipsised);
+      return () => vue.createVNode("div", {
+        "ref": root,
+        "class": bem$2()
+      }, [expanded.value ? props.content : text.value, hasAction.value ? renderAction() : null]);
+    }
+  });
+  const TextEllipsis = withInstall(stdin_default$8);
+  const [name$2] = createNamespace("time-picker");
+  const timePickerProps = extend({}, sharedProps, {
+    minHour: makeNumericProp(0),
+    maxHour: makeNumericProp(23),
+    minMinute: makeNumericProp(0),
+    maxMinute: makeNumericProp(59),
+    minSecond: makeNumericProp(0),
+    maxSecond: makeNumericProp(59),
+    columnsType: {
+      type: Array,
+      default: () => ["hour", "minute"]
+    }
+  });
+  var stdin_default$7 = vue.defineComponent({
+    name: name$2,
+    props: timePickerProps,
+    emits: ["confirm", "cancel", "change", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const currentValues = vue.ref(props.modelValue);
+      const columns = vue.computed(() => props.columnsType.map((type) => {
+        const {
+          filter,
+          formatter
+        } = props;
+        switch (type) {
+          case "hour":
+            return genOptions(+props.minHour, +props.maxHour, type, formatter, filter);
+          case "minute":
+            return genOptions(+props.minMinute, +props.maxMinute, type, formatter, filter);
+          case "second":
+            return genOptions(+props.minSecond, +props.maxSecond, type, formatter, filter);
+          default:
+            return [];
+        }
+      }));
+      vue.watch(currentValues, (newValues) => {
+        if (!isSameValue(newValues, props.modelValue)) {
+          emit("update:modelValue", newValues);
+        }
+      });
+      vue.watch(() => props.modelValue, (newValues) => {
+        newValues = formatValueRange(newValues, columns.value);
+        if (!isSameValue(newValues, currentValues.value)) {
+          currentValues.value = newValues;
+        }
+      }, {
+        immediate: true
+      });
+      const onChange = (...args) => emit("change", ...args);
+      const onCancel = (...args) => emit("cancel", ...args);
+      const onConfirm = (...args) => emit("confirm", ...args);
+      return () => vue.createVNode(Picker, vue.mergeProps({
+        "modelValue": currentValues.value,
+        "onUpdate:modelValue": ($event) => currentValues.value = $event,
+        "columns": columns.value,
+        "onChange": onChange,
+        "onCancel": onCancel,
+        "onConfirm": onConfirm
+      }, pick(props, pickerInheritKeys)), slots);
+    }
+  });
+  const TimePicker = withInstall(stdin_default$7);
+  const [name$1, bem$1] = createNamespace("tree-select");
+  const treeSelectProps = {
+    max: makeNumericProp(Infinity),
+    items: makeArrayProp(),
+    height: makeNumericProp(300),
+    selectedIcon: makeStringProp("success"),
+    mainActiveIndex: makeNumericProp(0),
+    activeId: {
+      type: [Number, String, Array],
+      default: 0
+    }
+  };
+  var stdin_default$6 = vue.defineComponent({
+    name: name$1,
+    props: treeSelectProps,
+    emits: ["clickNav", "clickItem", "update:activeId", "update:mainActiveIndex"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const isActiveItem = (id) => Array.isArray(props.activeId) ? props.activeId.includes(id) : props.activeId === id;
+      const renderSubItem = (item) => {
+        const onClick = () => {
+          if (item.disabled) {
+            return;
+          }
+          let activeId;
+          if (Array.isArray(props.activeId)) {
+            activeId = props.activeId.slice();
+            const index = activeId.indexOf(item.id);
+            if (index !== -1) {
+              activeId.splice(index, 1);
+            } else if (activeId.length < +props.max) {
+              activeId.push(item.id);
+            }
+          } else {
+            activeId = item.id;
+          }
+          emit("update:activeId", activeId);
+          emit("clickItem", item);
+        };
+        return vue.createVNode("div", {
+          "key": item.id,
+          "class": ["van-ellipsis", bem$1("item", {
+            active: isActiveItem(item.id),
+            disabled: item.disabled
+          })],
+          "onClick": onClick
+        }, [item.text, isActiveItem(item.id) && vue.createVNode(Icon, {
+          "name": props.selectedIcon,
+          "class": bem$1("selected")
+        }, null)]);
+      };
+      const onSidebarChange = (index) => {
+        emit("update:mainActiveIndex", index);
+      };
+      const onClickSidebarItem = (index) => emit("clickNav", index);
+      const renderSidebar = () => {
+        const Items = props.items.map((item) => vue.createVNode(SidebarItem, {
+          "dot": item.dot,
+          "badge": item.badge,
+          "class": [bem$1("nav-item"), item.className],
+          "disabled": item.disabled,
+          "onClick": onClickSidebarItem
+        }, {
+          title: () => slots["nav-text"] ? slots["nav-text"](item) : item.text
+        }));
+        return vue.createVNode(Sidebar, {
+          "class": bem$1("nav"),
+          "modelValue": props.mainActiveIndex,
+          "onChange": onSidebarChange
+        }, {
+          default: () => [Items]
+        });
+      };
+      const renderContent = () => {
+        if (slots.content) {
+          return slots.content();
+        }
+        const selected = props.items[+props.mainActiveIndex] || {};
+        if (selected.children) {
+          return selected.children.map(renderSubItem);
+        }
+      };
+      return () => vue.createVNode("div", {
+        "class": bem$1(),
+        "style": {
+          height: addUnit(props.height)
+        }
+      }, [renderSidebar(), vue.createVNode("div", {
+        "class": bem$1("content")
+      }, [renderContent()])]);
+    }
+  });
+  const TreeSelect = withInstall(stdin_default$6);
+  const [name, bem, t] = createNamespace("uploader");
+  function readFileContent(file, resultType) {
+    return new Promise((resolve) => {
+      if (resultType === "file") {
+        resolve();
+        return;
+      }
+      const reader = new FileReader();
+      reader.onload = (event) => {
+        resolve(event.target.result);
+      };
+      if (resultType === "dataUrl") {
+        reader.readAsDataURL(file);
+      } else if (resultType === "text") {
+        reader.readAsText(file);
+      }
+    });
+  }
+  function isOversize(items, maxSize) {
+    return toArray(items).some((item) => {
+      if (item.file) {
+        if (isFunction(maxSize)) {
+          return maxSize(item.file);
+        }
+        return item.file.size > +maxSize;
+      }
+      return false;
+    });
+  }
+  function filterFiles(items, maxSize) {
+    const valid = [];
+    const invalid = [];
+    items.forEach((item) => {
+      if (isOversize(item, maxSize)) {
+        invalid.push(item);
+      } else {
+        valid.push(item);
+      }
+    });
+    return { valid, invalid };
+  }
+  const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg|avif)/i;
+  const isImageUrl = (url) => IMAGE_REGEXP.test(url);
+  function isImageFile(item) {
+    if (item.isImage) {
+      return true;
+    }
+    if (item.file && item.file.type) {
+      return item.file.type.indexOf("image") === 0;
+    }
+    if (item.url) {
+      return isImageUrl(item.url);
+    }
+    if (typeof item.content === "string") {
+      return item.content.indexOf("data:image") === 0;
+    }
+    return false;
+  }
+  var stdin_default$5 = vue.defineComponent({
+    props: {
+      name: numericProp,
+      item: makeRequiredProp(Object),
+      index: Number,
+      imageFit: String,
+      lazyLoad: Boolean,
+      deletable: Boolean,
+      previewSize: [Number, String, Array],
+      beforeDelete: Function
+    },
+    emits: ["delete", "preview"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const renderMask = () => {
+        const {
+          status,
+          message
+        } = props.item;
+        if (status === "uploading" || status === "failed") {
+          const MaskIcon = status === "failed" ? vue.createVNode(Icon, {
+            "name": "close",
+            "class": bem("mask-icon")
+          }, null) : vue.createVNode(Loading, {
+            "class": bem("loading")
+          }, null);
+          const showMessage = isDef(message) && message !== "";
+          return vue.createVNode("div", {
+            "class": bem("mask")
+          }, [MaskIcon, showMessage && vue.createVNode("div", {
+            "class": bem("mask-message")
+          }, [message])]);
+        }
+      };
+      const onDelete = (event) => {
+        const {
+          name: name2,
+          item,
+          index,
+          beforeDelete
+        } = props;
+        event.stopPropagation();
+        callInterceptor(beforeDelete, {
+          args: [item, {
+            name: name2,
+            index
+          }],
+          done: () => emit("delete")
+        });
+      };
+      const onPreview = () => emit("preview");
+      const renderDeleteIcon = () => {
+        if (props.deletable && props.item.status !== "uploading") {
+          const slot = slots["preview-delete"];
+          return vue.createVNode("div", {
+            "role": "button",
+            "class": bem("preview-delete", {
+              shadow: !slot
+            }),
+            "tabindex": 0,
+            "aria-label": t("delete"),
+            "onClick": onDelete
+          }, [slot ? slot() : vue.createVNode(Icon, {
+            "name": "cross",
+            "class": bem("preview-delete-icon")
+          }, null)]);
+        }
+      };
+      const renderCover = () => {
+        if (slots["preview-cover"]) {
+          const {
+            index,
+            item
+          } = props;
+          return vue.createVNode("div", {
+            "class": bem("preview-cover")
+          }, [slots["preview-cover"](extend({
+            index
+          }, item))]);
+        }
+      };
+      const renderPreview = () => {
+        const {
+          item,
+          lazyLoad,
+          imageFit,
+          previewSize
+        } = props;
+        if (isImageFile(item)) {
+          return vue.createVNode(Image$1, {
+            "fit": imageFit,
+            "src": item.content || item.url,
+            "class": bem("preview-image"),
+            "width": Array.isArray(previewSize) ? previewSize[0] : previewSize,
+            "height": Array.isArray(previewSize) ? previewSize[1] : previewSize,
+            "lazyLoad": lazyLoad,
+            "onClick": onPreview
+          }, {
+            default: renderCover
+          });
+        }
+        return vue.createVNode("div", {
+          "class": bem("file"),
+          "style": getSizeStyle(props.previewSize)
+        }, [vue.createVNode(Icon, {
+          "class": bem("file-icon"),
+          "name": "description"
+        }, null), vue.createVNode("div", {
+          "class": [bem("file-name"), "van-ellipsis"]
+        }, [item.file ? item.file.name : item.url]), renderCover()]);
+      };
+      return () => vue.createVNode("div", {
+        "class": bem("preview")
+      }, [renderPreview(), renderMask(), renderDeleteIcon()]);
+    }
+  });
+  const uploaderProps = {
+    name: makeNumericProp(""),
+    accept: makeStringProp("image/*"),
+    capture: String,
+    multiple: Boolean,
+    disabled: Boolean,
+    readonly: Boolean,
+    lazyLoad: Boolean,
+    maxCount: makeNumericProp(Infinity),
+    imageFit: makeStringProp("cover"),
+    resultType: makeStringProp("dataUrl"),
+    uploadIcon: makeStringProp("photograph"),
+    uploadText: String,
+    deletable: truthProp,
+    afterRead: Function,
+    showUpload: truthProp,
+    modelValue: makeArrayProp(),
+    beforeRead: Function,
+    beforeDelete: Function,
+    previewSize: [Number, String, Array],
+    previewImage: truthProp,
+    previewOptions: Object,
+    previewFullImage: truthProp,
+    maxSize: {
+      type: [Number, String, Function],
+      default: Infinity
+    }
+  };
+  var stdin_default$4 = vue.defineComponent({
+    name,
+    props: uploaderProps,
+    emits: ["delete", "oversize", "clickUpload", "closePreview", "clickPreview", "update:modelValue"],
+    setup(props, {
+      emit,
+      slots
+    }) {
+      const inputRef = vue.ref();
+      const urls = [];
+      const getDetail = (index = props.modelValue.length) => ({
+        name: props.name,
+        index
+      });
+      const resetInput = () => {
+        if (inputRef.value) {
+          inputRef.value.value = "";
+        }
+      };
+      const onAfterRead = (items) => {
+        resetInput();
+        if (isOversize(items, props.maxSize)) {
+          if (Array.isArray(items)) {
+            const result = filterFiles(items, props.maxSize);
+            items = result.valid;
+            emit("oversize", result.invalid, getDetail());
+            if (!items.length) {
+              return;
+            }
+          } else {
+            emit("oversize", items, getDetail());
+            return;
+          }
+        }
+        items = vue.reactive(items);
+        emit("update:modelValue", [...props.modelValue, ...toArray(items)]);
+        if (props.afterRead) {
+          props.afterRead(items, getDetail());
+        }
+      };
+      const readFile = (files) => {
+        const {
+          maxCount,
+          modelValue,
+          resultType
+        } = props;
+        if (Array.isArray(files)) {
+          const remainCount = +maxCount - modelValue.length;
+          if (files.length > remainCount) {
+            files = files.slice(0, remainCount);
+          }
+          Promise.all(files.map((file) => readFileContent(file, resultType))).then((contents) => {
+            const fileList = files.map((file, index) => {
+              const result = {
+                file,
+                status: "",
+                message: ""
+              };
+              if (contents[index]) {
+                result.content = contents[index];
+              }
+              return result;
+            });
+            onAfterRead(fileList);
+          });
+        } else {
+          readFileContent(files, resultType).then((content) => {
+            const result = {
+              file: files,
+              status: "",
+              message: ""
+            };
+            if (content) {
+              result.content = content;
+            }
+            onAfterRead(result);
+          });
+        }
+      };
+      const onChange = (event) => {
+        const {
+          files
+        } = event.target;
+        if (props.disabled || !files || !files.length) {
+          return;
+        }
+        const file = files.length === 1 ? files[0] : [].slice.call(files);
+        if (props.beforeRead) {
+          const response = props.beforeRead(file, getDetail());
+          if (!response) {
+            resetInput();
+            return;
+          }
+          if (isPromise(response)) {
+            response.then((data) => {
+              if (data) {
+                readFile(data);
+              } else {
+                readFile(file);
+              }
+            }).catch(resetInput);
+            return;
+          }
+        }
+        readFile(file);
+      };
+      let imagePreview;
+      const onClosePreview = () => emit("closePreview");
+      const previewImage = (item) => {
+        if (props.previewFullImage) {
+          const imageFiles = props.modelValue.filter(isImageFile);
+          const images = imageFiles.map((item2) => {
+            if (item2.file && !item2.url && item2.status !== "failed") {
+              item2.url = URL.createObjectURL(item2.file);
+              urls.push(item2.url);
+            }
+            return item2.url;
+          }).filter(Boolean);
+          imagePreview = showImagePreview(extend({
+            images,
+            startPosition: imageFiles.indexOf(item),
+            onClose: onClosePreview
+          }, props.previewOptions));
+        }
+      };
+      const closeImagePreview = () => {
+        if (imagePreview) {
+          imagePreview.close();
+        }
+      };
+      const deleteFile = (item, index) => {
+        const fileList = props.modelValue.slice(0);
+        fileList.splice(index, 1);
+        emit("update:modelValue", fileList);
+        emit("delete", item, getDetail(index));
+      };
+      const renderPreviewItem = (item, index) => {
+        const needPickData = ["imageFit", "deletable", "previewSize", "beforeDelete"];
+        const previewData = extend(pick(props, needPickData), pick(item, needPickData, true));
+        return vue.createVNode(stdin_default$5, vue.mergeProps({
+          "item": item,
+          "index": index,
+          "onClick": () => emit("clickPreview", item, getDetail(index)),
+          "onDelete": () => deleteFile(item, index),
+          "onPreview": () => previewImage(item)
+        }, pick(props, ["name", "lazyLoad"]), previewData), pick(slots, ["preview-cover", "preview-delete"]));
+      };
+      const renderPreviewList = () => {
+        if (props.previewImage) {
+          return props.modelValue.map(renderPreviewItem);
+        }
+      };
+      const onClickUpload = (event) => emit("clickUpload", event);
+      const renderUpload = () => {
+        if (props.modelValue.length >= +props.maxCount) {
+          return;
+        }
+        const Input = props.readonly ? null : vue.createVNode("input", {
+          "ref": inputRef,
+          "type": "file",
+          "class": bem("input"),
+          "accept": props.accept,
+          "capture": props.capture,
+          "multiple": props.multiple,
+          "disabled": props.disabled,
+          "onChange": onChange
+        }, null);
+        if (slots.default) {
+          return vue.createVNode("div", {
+            "class": bem("input-wrapper"),
+            "onClick": onClickUpload
+          }, [slots.default(), Input]);
+        }
+        return vue.withDirectives(vue.createVNode("div", {
+          "class": bem("upload", {
+            readonly: props.readonly
+          }),
+          "style": getSizeStyle(props.previewSize),
+          "onClick": onClickUpload
+        }, [vue.createVNode(Icon, {
+          "name": props.uploadIcon,
+          "class": bem("upload-icon")
+        }, null), props.uploadText && vue.createVNode("span", {
+          "class": bem("upload-text")
+        }, [props.uploadText]), Input]), [[vue.vShow, props.showUpload]]);
+      };
+      const chooseFile = () => {
+        if (inputRef.value && !props.disabled) {
+          inputRef.value.click();
+        }
+      };
+      vue.onBeforeUnmount(() => {
+        urls.forEach((url) => URL.revokeObjectURL(url));
+      });
+      useExpose({
+        chooseFile,
+        closeImagePreview
+      });
+      useCustomFieldValue(() => props.modelValue);
+      return () => vue.createVNode("div", {
+        "class": bem()
+      }, [vue.createVNode("div", {
+        "class": bem("wrapper", {
+          disabled: props.disabled
+        })
+      }, [renderPreviewList(), renderUpload()])]);
+    }
+  });
+  const Uploader = withInstall(stdin_default$4);
+  class ReactiveListener {
+    constructor({
+      el,
+      src,
+      error,
+      loading,
+      bindType,
+      $parent,
+      options,
+      cors,
+      elRenderer,
+      imageCache
+    }) {
+      this.el = el;
+      this.src = src;
+      this.error = error;
+      this.loading = loading;
+      this.bindType = bindType;
+      this.attempt = 0;
+      this.cors = cors;
+      this.naturalHeight = 0;
+      this.naturalWidth = 0;
+      this.options = options;
+      this.$parent = $parent;
+      this.elRenderer = elRenderer;
+      this.imageCache = imageCache;
+      this.performanceData = {
+        loadStart: 0,
+        loadEnd: 0
+      };
+      this.filter();
+      this.initState();
+      this.render("loading", false);
+    }
+    /*
+     * init listener state
+     * @return
+     */
+    initState() {
+      if ("dataset" in this.el) {
+        this.el.dataset.src = this.src;
+      } else {
+        this.el.setAttribute("data-src", this.src);
+      }
+      this.state = {
+        loading: false,
+        error: false,
+        loaded: false,
+        rendered: false
+      };
+    }
+    /*
+     * record performance
+     * @return
+     */
+    record(event) {
+      this.performanceData[event] = Date.now();
+    }
+    /*
+     * update image listener data
+     * @param  {String} image uri
+     * @param  {String} loading image uri
+     * @param  {String} error image uri
+     * @return
+     */
+    update({ src, loading, error }) {
+      const oldSrc = this.src;
+      this.src = src;
+      this.loading = loading;
+      this.error = error;
+      this.filter();
+      if (oldSrc !== this.src) {
+        this.attempt = 0;
+        this.initState();
+      }
+    }
+    /*
+     *  check el is in view
+     * @return {Boolean} el is in view
+     */
+    checkInView() {
+      const rect = useRect(this.el);
+      return rect.top < window.innerHeight * this.options.preLoad && rect.bottom > this.options.preLoadTop && rect.left < window.innerWidth * this.options.preLoad && rect.right > 0;
+    }
+    /*
+     * listener filter
+     */
+    filter() {
+      Object.keys(this.options.filter).forEach((key) => {
+        this.options.filter[key](this, this.options);
+      });
+    }
+    /*
+     * render loading first
+     * @params cb:Function
+     * @return
+     */
+    renderLoading(cb) {
+      this.state.loading = true;
+      loadImageAsync(
+        {
+          src: this.loading,
+          cors: this.cors
+        },
+        () => {
+          this.render("loading", false);
+          this.state.loading = false;
+          cb();
+        },
+        () => {
+          cb();
+          this.state.loading = false;
+        }
+      );
+    }
+    /*
+     * try load image and  render it
+     * @return
+     */
+    load(onFinish = noop) {
+      if (this.attempt > this.options.attempt - 1 && this.state.error) {
+        onFinish();
+        return;
+      }
+      if (this.state.rendered && this.state.loaded)
+        return;
+      if (this.imageCache.has(this.src)) {
+        this.state.loaded = true;
+        this.render("loaded", true);
+        this.state.rendered = true;
+        return onFinish();
+      }
+      this.renderLoading(() => {
+        var _a, _b;
+        this.attempt++;
+        (_b = (_a = this.options.adapter).beforeLoad) == null ? void 0 : _b.call(_a, this, this.options);
+        this.record("loadStart");
+        loadImageAsync(
+          {
+            src: this.src,
+            cors: this.cors
+          },
+          (data) => {
+            this.naturalHeight = data.naturalHeight;
+            this.naturalWidth = data.naturalWidth;
+            this.state.loaded = true;
+            this.state.error = false;
+            this.record("loadEnd");
+            this.render("loaded", false);
+            this.state.rendered = true;
+            this.imageCache.add(this.src);
+            onFinish();
+          },
+          (err) => {
+            !this.options.silent && console.error(err);
+            this.state.error = true;
+            this.state.loaded = false;
+            this.render("error", false);
+          }
+        );
+      });
+    }
+    /*
+     * render image
+     * @param  {String} state to render // ['loading', 'src', 'error']
+     * @param  {String} is form cache
+     * @return
+     */
+    render(state, cache) {
+      this.elRenderer(this, state, cache);
+    }
+    /*
+     * output performance data
+     * @return {Object} performance data
+     */
+    performance() {
+      let state = "loading";
+      let time = 0;
+      if (this.state.loaded) {
+        state = "loaded";
+        time = (this.performanceData.loadEnd - this.performanceData.loadStart) / 1e3;
+      }
+      if (this.state.error)
+        state = "error";
+      return {
+        src: this.src,
+        state,
+        time
+      };
+    }
+    /*
+     * $destroy
+     * @return
+     */
+    $destroy() {
+      this.el = null;
+      this.src = null;
+      this.error = null;
+      this.loading = null;
+      this.bindType = null;
+      this.attempt = 0;
+    }
+  }
+  const DEFAULT_URL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
+  const DEFAULT_EVENTS = [
+    "scroll",
+    "wheel",
+    "mousewheel",
+    "resize",
+    "animationend",
+    "transitionend",
+    "touchmove"
+  ];
+  const DEFAULT_OBSERVER_OPTIONS = {
+    rootMargin: "0px",
+    threshold: 0
+  };
+  function stdin_default$3() {
+    return class Lazy {
+      constructor({
+        preLoad,
+        error,
+        throttleWait,
+        preLoadTop,
+        dispatchEvent,
+        loading,
+        attempt,
+        silent = true,
+        scale,
+        listenEvents,
+        filter,
+        adapter,
+        observer,
+        observerOptions
+      }) {
+        this.mode = modeType.event;
+        this.listeners = [];
+        this.targetIndex = 0;
+        this.targets = [];
+        this.options = {
+          silent,
+          dispatchEvent: !!dispatchEvent,
+          throttleWait: throttleWait || 200,
+          preLoad: preLoad || 1.3,
+          preLoadTop: preLoadTop || 0,
+          error: error || DEFAULT_URL,
+          loading: loading || DEFAULT_URL,
+          attempt: attempt || 3,
+          scale: scale || getDPR(scale),
+          ListenEvents: listenEvents || DEFAULT_EVENTS,
+          supportWebp: supportWebp(),
+          filter: filter || {},
+          adapter: adapter || {},
+          observer: !!observer,
+          observerOptions: observerOptions || DEFAULT_OBSERVER_OPTIONS
+        };
+        this.initEvent();
+        this.imageCache = new ImageCache({ max: 200 });
+        this.lazyLoadHandler = throttle(
+          this.lazyLoadHandler.bind(this),
+          this.options.throttleWait
+        );
+        this.setMode(this.options.observer ? modeType.observer : modeType.event);
+      }
+      /**
+       * update config
+       * @param  {Object} config params
+       * @return
+       */
+      config(options = {}) {
+        Object.assign(this.options, options);
+      }
+      /**
+       * output listener's load performance
+       * @return {Array}
+       */
+      performance() {
+        return this.listeners.map((item) => item.performance());
+      }
+      /*
+       * add lazy component to queue
+       * @param  {Vue} vm lazy component instance
+       * @return
+       */
+      addLazyBox(vm) {
+        this.listeners.push(vm);
+        if (inBrowser) {
+          this.addListenerTarget(window);
+          this.observer && this.observer.observe(vm.el);
+          if (vm.$el && vm.$el.parentNode) {
+            this.addListenerTarget(vm.$el.parentNode);
+          }
+        }
+      }
+      /*
+       * add image listener to queue
+       * @param  {DOM} el
+       * @param  {object} binding vue directive binding
+       * @param  {vnode} vnode vue directive vnode
+       * @return
+       */
+      add(el, binding, vnode) {
+        if (this.listeners.some((item) => item.el === el)) {
+          this.update(el, binding);
+          return vue.nextTick(this.lazyLoadHandler);
+        }
+        const value = this.valueFormatter(binding.value);
+        let { src } = value;
+        vue.nextTick(() => {
+          src = getBestSelectionFromSrcset(el, this.options.scale) || src;
+          this.observer && this.observer.observe(el);
+          const container = Object.keys(binding.modifiers)[0];
+          let $parent;
+          if (container) {
+            $parent = vnode.context.$refs[container];
+            $parent = $parent ? $parent.$el || $parent : document.getElementById(container);
+          }
+          if (!$parent) {
+            $parent = getScrollParent$1(el);
+          }
+          const newListener = new ReactiveListener({
+            bindType: binding.arg,
+            $parent,
+            el,
+            src,
+            loading: value.loading,
+            error: value.error,
+            cors: value.cors,
+            elRenderer: this.elRenderer.bind(this),
+            options: this.options,
+            imageCache: this.imageCache
+          });
+          this.listeners.push(newListener);
+          if (inBrowser) {
+            this.addListenerTarget(window);
+            this.addListenerTarget($parent);
+          }
+          this.lazyLoadHandler();
+          vue.nextTick(() => this.lazyLoadHandler());
+        });
+      }
+      /**
+       * update image src
+       * @param  {DOM} el
+       * @param  {object} vue directive binding
+       * @return
+       */
+      update(el, binding, vnode) {
+        const value = this.valueFormatter(binding.value);
+        let { src } = value;
+        src = getBestSelectionFromSrcset(el, this.options.scale) || src;
+        const exist = this.listeners.find((item) => item.el === el);
+        if (!exist) {
+          this.add(el, binding, vnode);
+        } else {
+          exist.update({
+            src,
+            error: value.error,
+            loading: value.loading
+          });
+        }
+        if (this.observer) {
+          this.observer.unobserve(el);
+          this.observer.observe(el);
+        }
+        this.lazyLoadHandler();
+        vue.nextTick(() => this.lazyLoadHandler());
+      }
+      /**
+       * remove listener form list
+       * @param  {DOM} el
+       * @return
+       */
+      remove(el) {
+        if (!el)
+          return;
+        this.observer && this.observer.unobserve(el);
+        const existItem = this.listeners.find((item) => item.el === el);
+        if (existItem) {
+          this.removeListenerTarget(existItem.$parent);
+          this.removeListenerTarget(window);
+          remove(this.listeners, existItem);
+          existItem.$destroy();
+        }
+      }
+      /*
+       * remove lazy components form list
+       * @param  {Vue} vm Vue instance
+       * @return
+       */
+      removeComponent(vm) {
+        if (!vm)
+          return;
+        remove(this.listeners, vm);
+        this.observer && this.observer.unobserve(vm.el);
+        if (vm.$parent && vm.$el.parentNode) {
+          this.removeListenerTarget(vm.$el.parentNode);
+        }
+        this.removeListenerTarget(window);
+      }
+      setMode(mode) {
+        if (!hasIntersectionObserver && mode === modeType.observer) {
+          mode = modeType.event;
+        }
+        this.mode = mode;
+        if (mode === modeType.event) {
+          if (this.observer) {
+            this.listeners.forEach((listener) => {
+              this.observer.unobserve(listener.el);
+            });
+            this.observer = null;
+          }
+          this.targets.forEach((target) => {
+            this.initListen(target.el, true);
+          });
+        } else {
+          this.targets.forEach((target) => {
+            this.initListen(target.el, false);
+          });
+          this.initIntersectionObserver();
+        }
+      }
+      /*
+       *** Private functions ***
+       */
+      /*
+       * add listener target
+       * @param  {DOM} el listener target
+       * @return
+       */
+      addListenerTarget(el) {
+        if (!el)
+          return;
+        let target = this.targets.find((target2) => target2.el === el);
+        if (!target) {
+          target = {
+            el,
+            id: ++this.targetIndex,
+            childrenCount: 1,
+            listened: true
+          };
+          this.mode === modeType.event && this.initListen(target.el, true);
+          this.targets.push(target);
+        } else {
+          target.childrenCount++;
+        }
+        return this.targetIndex;
+      }
+      /*
+       * remove listener target or reduce target childrenCount
+       * @param  {DOM} el or window
+       * @return
+       */
+      removeListenerTarget(el) {
+        this.targets.forEach((target, index) => {
+          if (target.el === el) {
+            target.childrenCount--;
+            if (!target.childrenCount) {
+              this.initListen(target.el, false);
+              this.targets.splice(index, 1);
+              target = null;
+            }
+          }
+        });
+      }
+      /*
+       * add or remove eventlistener
+       * @param  {DOM} el DOM or Window
+       * @param  {boolean} start flag
+       * @return
+       */
+      initListen(el, start2) {
+        this.options.ListenEvents.forEach(
+          (evt) => (start2 ? on : off)(el, evt, this.lazyLoadHandler)
+        );
+      }
+      initEvent() {
+        this.Event = {
+          listeners: {
+            loading: [],
+            loaded: [],
+            error: []
+          }
+        };
+        this.$on = (event, func) => {
+          if (!this.Event.listeners[event])
+            this.Event.listeners[event] = [];
+          this.Event.listeners[event].push(func);
+        };
+        this.$once = (event, func) => {
+          const on2 = (...args) => {
+            this.$off(event, on2);
+            func.apply(this, args);
+          };
+          this.$on(event, on2);
+        };
+        this.$off = (event, func) => {
+          if (!func) {
+            if (!this.Event.listeners[event])
+              return;
+            this.Event.listeners[event].length = 0;
+            return;
+          }
+          remove(this.Event.listeners[event], func);
+        };
+        this.$emit = (event, context, inCache) => {
+          if (!this.Event.listeners[event])
+            return;
+          this.Event.listeners[event].forEach((func) => func(context, inCache));
+        };
+      }
+      /**
+       * find nodes which in viewport and trigger load
+       * @return
+       */
+      lazyLoadHandler() {
+        const freeList = [];
+        this.listeners.forEach((listener) => {
+          if (!listener.el || !listener.el.parentNode) {
+            freeList.push(listener);
+          }
+          const catIn = listener.checkInView();
+          if (!catIn)
+            return;
+          listener.load();
+        });
+        freeList.forEach((item) => {
+          remove(this.listeners, item);
+          item.$destroy();
+        });
+      }
+      /**
+       * init IntersectionObserver
+       * set mode to observer
+       * @return
+       */
+      initIntersectionObserver() {
+        if (!hasIntersectionObserver) {
+          return;
+        }
+        this.observer = new IntersectionObserver(
+          this.observerHandler.bind(this),
+          this.options.observerOptions
+        );
+        if (this.listeners.length) {
+          this.listeners.forEach((listener) => {
+            this.observer.observe(listener.el);
+          });
+        }
+      }
+      /**
+       * init IntersectionObserver
+       * @return
+       */
+      observerHandler(entries) {
+        entries.forEach((entry) => {
+          if (entry.isIntersecting) {
+            this.listeners.forEach((listener) => {
+              if (listener.el === entry.target) {
+                if (listener.state.loaded)
+                  return this.observer.unobserve(listener.el);
+                listener.load();
+              }
+            });
+          }
+        });
+      }
+      /**
+       * set element attribute with image'url and state
+       * @param  {object} lazyload listener object
+       * @param  {string} state will be rendered
+       * @param  {bool} inCache  is rendered from cache
+       * @return
+       */
+      elRenderer(listener, state, cache) {
+        if (!listener.el)
+          return;
+        const { el, bindType } = listener;
+        let src;
+        switch (state) {
+          case "loading":
+            src = listener.loading;
+            break;
+          case "error":
+            src = listener.error;
+            break;
+          default:
+            ({ src } = listener);
+            break;
+        }
+        if (bindType) {
+          el.style[bindType] = 'url("' + src + '")';
+        } else if (el.getAttribute("src") !== src) {
+          el.setAttribute("src", src);
+        }
+        el.setAttribute("lazy", state);
+        this.$emit(state, listener, cache);
+        this.options.adapter[state] && this.options.adapter[state](listener, this.options);
+        if (this.options.dispatchEvent) {
+          const event = new CustomEvent(state, {
+            detail: listener
+          });
+          el.dispatchEvent(event);
+        }
+      }
+      /**
+       * generate loading loaded error image url
+       * @param {string} image's src
+       * @return {object} image's loading, loaded, error url
+       */
+      valueFormatter(value) {
+        let src = value;
+        let { loading, error } = this.options;
+        if (isObject(value)) {
+          ({ src } = value);
+          loading = value.loading || this.options.loading;
+          error = value.error || this.options.error;
+        }
+        return {
+          src,
+          loading,
+          error
+        };
+      }
+    };
+  }
+  var stdin_default$2 = (lazy) => ({
+    props: {
+      tag: {
+        type: String,
+        default: "div"
+      }
+    },
+    emits: ["show"],
+    render() {
+      return vue.h(
+        this.tag,
+        this.show && this.$slots.default ? this.$slots.default() : null
+      );
+    },
+    data() {
+      return {
+        el: null,
+        state: {
+          loaded: false
+        },
+        show: false
+      };
+    },
+    mounted() {
+      this.el = this.$el;
+      lazy.addLazyBox(this);
+      lazy.lazyLoadHandler();
+    },
+    beforeUnmount() {
+      lazy.removeComponent(this);
+    },
+    methods: {
+      checkInView() {
+        const rect = useRect(this.$el);
+        return inBrowser && rect.top < window.innerHeight * lazy.options.preLoad && rect.bottom > 0 && rect.left < window.innerWidth * lazy.options.preLoad && rect.right > 0;
+      },
+      load() {
+        this.show = true;
+        this.state.loaded = true;
+        this.$emit("show", this);
+      },
+      destroy() {
+        return this.$destroy;
+      }
+    }
+  });
+  const defaultOptions = {
+    selector: "img"
+  };
+  class LazyContainer {
+    constructor({ el, binding, vnode, lazy }) {
+      this.el = null;
+      this.vnode = vnode;
+      this.binding = binding;
+      this.options = {};
+      this.lazy = lazy;
+      this.queue = [];
+      this.update({ el, binding });
+    }
+    update({ el, binding }) {
+      this.el = el;
+      this.options = Object.assign({}, defaultOptions, binding.value);
+      const imgs = this.getImgs();
+      imgs.forEach((el2) => {
+        this.lazy.add(
+          el2,
+          Object.assign({}, this.binding, {
+            value: {
+              src: "dataset" in el2 ? el2.dataset.src : el2.getAttribute("data-src"),
+              error: ("dataset" in el2 ? el2.dataset.error : el2.getAttribute("data-error")) || this.options.error,
+              loading: ("dataset" in el2 ? el2.dataset.loading : el2.getAttribute("data-loading")) || this.options.loading
+            }
+          }),
+          this.vnode
+        );
+      });
+    }
+    getImgs() {
+      return Array.from(this.el.querySelectorAll(this.options.selector));
+    }
+    clear() {
+      const imgs = this.getImgs();
+      imgs.forEach((el) => this.lazy.remove(el));
+      this.vnode = null;
+      this.binding = null;
+      this.lazy = null;
+    }
+  }
+  class LazyContainerManager {
+    constructor({ lazy }) {
+      this.lazy = lazy;
+      this.queue = [];
+    }
+    bind(el, binding, vnode) {
+      const container = new LazyContainer({
+        el,
+        binding,
+        vnode,
+        lazy: this.lazy
+      });
+      this.queue.push(container);
+    }
+    update(el, binding, vnode) {
+      const container = this.queue.find((item) => item.el === el);
+      if (!container)
+        return;
+      container.update({ el, binding, vnode });
+    }
+    unbind(el) {
+      const container = this.queue.find((item) => item.el === el);
+      if (!container)
+        return;
+      container.clear();
+      remove(this.queue, container);
+    }
+  }
+  var stdin_default$1 = (lazyManager) => ({
+    props: {
+      src: [String, Object],
+      tag: {
+        type: String,
+        default: "img"
+      }
+    },
+    render() {
+      var _a, _b;
+      return vue.h(
+        this.tag,
+        {
+          src: this.renderSrc
+        },
+        (_b = (_a = this.$slots).default) == null ? void 0 : _b.call(_a)
+      );
+    },
+    data() {
+      return {
+        el: null,
+        options: {
+          src: "",
+          error: "",
+          loading: "",
+          attempt: lazyManager.options.attempt
+        },
+        state: {
+          loaded: false,
+          error: false,
+          attempt: 0
+        },
+        renderSrc: ""
+      };
+    },
+    watch: {
+      src() {
+        this.init();
+        lazyManager.addLazyBox(this);
+        lazyManager.lazyLoadHandler();
+      }
+    },
+    created() {
+      this.init();
+    },
+    mounted() {
+      this.el = this.$el;
+      lazyManager.addLazyBox(this);
+      lazyManager.lazyLoadHandler();
+    },
+    beforeUnmount() {
+      lazyManager.removeComponent(this);
+    },
+    methods: {
+      init() {
+        const { src, loading, error } = lazyManager.valueFormatter(this.src);
+        this.state.loaded = false;
+        this.options.src = src;
+        this.options.error = error;
+        this.options.loading = loading;
+        this.renderSrc = this.options.loading;
+      },
+      checkInView() {
+        const rect = useRect(this.$el);
+        return rect.top < window.innerHeight * lazyManager.options.preLoad && rect.bottom > 0 && rect.left < window.innerWidth * lazyManager.options.preLoad && rect.right > 0;
+      },
+      load(onFinish = noop) {
+        if (this.state.attempt > this.options.attempt - 1 && this.state.error) {
+          onFinish();
+          return;
+        }
+        const { src } = this.options;
+        loadImageAsync(
+          { src },
+          ({ src: src2 }) => {
+            this.renderSrc = src2;
+            this.state.loaded = true;
+          },
+          () => {
+            this.state.attempt++;
+            this.renderSrc = this.options.error;
+            this.state.error = true;
+          }
+        );
+      }
+    }
+  });
+  const Lazyload = {
+    /*
+     * install function
+     * @param  {App} app
+     * @param  {object} options lazyload options
+     */
+    install(app, options = {}) {
+      const LazyClass = stdin_default$3();
+      const lazy = new LazyClass(options);
+      const lazyContainer = new LazyContainerManager({ lazy });
+      app.config.globalProperties.$Lazyload = lazy;
+      if (options.lazyComponent) {
+        app.component("LazyComponent", stdin_default$2(lazy));
+      }
+      if (options.lazyImage) {
+        app.component("LazyImage", stdin_default$1(lazy));
+      }
+      app.directive("lazy", {
+        beforeMount: lazy.add.bind(lazy),
+        updated: lazy.update.bind(lazy),
+        unmounted: lazy.remove.bind(lazy)
+      });
+      app.directive("lazy-container", {
+        beforeMount: lazyContainer.bind.bind(lazyContainer),
+        updated: lazyContainer.update.bind(lazyContainer),
+        unmounted: lazyContainer.unbind.bind(lazyContainer)
+      });
+    }
+  };
+  const version = "4.1.2";
+  function install(app) {
+    const components = [
+      ActionBar,
+      ActionBarButton,
+      ActionBarIcon,
+      ActionSheet,
+      AddressEdit,
+      AddressList,
+      Area,
+      BackTop,
+      Badge,
+      Button,
+      Calendar,
+      Card,
+      Cascader,
+      Cell,
+      CellGroup,
+      Checkbox,
+      CheckboxGroup,
+      Circle,
+      Col,
+      Collapse,
+      CollapseItem,
+      ConfigProvider,
+      ContactCard,
+      ContactEdit,
+      ContactList,
+      CountDown,
+      Coupon,
+      CouponCell,
+      CouponList,
+      DatePicker,
+      Dialog,
+      Divider,
+      DropdownItem,
+      DropdownMenu,
+      Empty,
+      Field,
+      Form,
+      Grid,
+      GridItem,
+      Icon,
+      Image$1,
+      ImagePreview,
+      IndexAnchor,
+      IndexBar,
+      List,
+      Loading,
+      Locale,
+      NavBar,
+      NoticeBar,
+      Notify,
+      NumberKeyboard,
+      Overlay,
+      Pagination,
+      PasswordInput,
+      Picker,
+      PickerGroup,
+      Popover,
+      Popup,
+      Progress,
+      PullRefresh,
+      Radio,
+      RadioGroup,
+      Rate,
+      Row,
+      Search,
+      ShareSheet,
+      Sidebar,
+      SidebarItem,
+      Skeleton,
+      SkeletonAvatar,
+      SkeletonImage,
+      SkeletonParagraph,
+      SkeletonTitle,
+      Slider,
+      Space,
+      Step,
+      Stepper,
+      Steps,
+      Sticky,
+      SubmitBar,
+      Swipe,
+      SwipeCell,
+      SwipeItem,
+      Switch,
+      Tab,
+      Tabbar,
+      TabbarItem,
+      Tabs,
+      Tag,
+      TextEllipsis,
+      TimePicker,
+      Toast,
+      TreeSelect,
+      Uploader
+    ];
+    components.forEach((item) => {
+      if (item.install) {
+        app.use(item);
+      } else if (item.name) {
+        app.component(item.name, item);
+      }
+    });
+  }
+  var stdin_default = {
+    install,
+    version
+  };
+  exports2.ActionBar = ActionBar;
+  exports2.ActionBarButton = ActionBarButton;
+  exports2.ActionBarIcon = ActionBarIcon;
+  exports2.ActionSheet = ActionSheet;
+  exports2.AddressEdit = AddressEdit;
+  exports2.AddressList = AddressList;
+  exports2.Area = Area;
+  exports2.BackTop = BackTop;
+  exports2.Badge = Badge;
+  exports2.Button = Button;
+  exports2.Calendar = Calendar;
+  exports2.Card = Card;
+  exports2.Cascader = Cascader;
+  exports2.Cell = Cell;
+  exports2.CellGroup = CellGroup;
+  exports2.Checkbox = Checkbox;
+  exports2.CheckboxGroup = CheckboxGroup;
+  exports2.Circle = Circle;
+  exports2.Col = Col;
+  exports2.Collapse = Collapse;
+  exports2.CollapseItem = CollapseItem;
+  exports2.ConfigProvider = ConfigProvider;
+  exports2.ContactCard = ContactCard;
+  exports2.ContactEdit = ContactEdit;
+  exports2.ContactList = ContactList;
+  exports2.CountDown = CountDown;
+  exports2.Coupon = Coupon;
+  exports2.CouponCell = CouponCell;
+  exports2.CouponList = CouponList;
+  exports2.DEFAULT_ROW_WIDTH = DEFAULT_ROW_WIDTH;
+  exports2.DatePicker = DatePicker;
+  exports2.Dialog = Dialog;
+  exports2.Divider = Divider;
+  exports2.DropdownItem = DropdownItem;
+  exports2.DropdownMenu = DropdownMenu;
+  exports2.Empty = Empty;
+  exports2.Field = Field;
+  exports2.Form = Form;
+  exports2.Grid = Grid;
+  exports2.GridItem = GridItem;
+  exports2.Icon = Icon;
+  exports2.Image = Image$1;
+  exports2.ImagePreview = ImagePreview;
+  exports2.IndexAnchor = IndexAnchor;
+  exports2.IndexBar = IndexBar;
+  exports2.Lazyload = Lazyload;
+  exports2.List = List;
+  exports2.Loading = Loading;
+  exports2.Locale = Locale;
+  exports2.NavBar = NavBar;
+  exports2.NoticeBar = NoticeBar;
+  exports2.Notify = Notify;
+  exports2.NumberKeyboard = NumberKeyboard;
+  exports2.Overlay = Overlay;
+  exports2.Pagination = Pagination;
+  exports2.PasswordInput = PasswordInput;
+  exports2.Picker = Picker;
+  exports2.PickerGroup = PickerGroup;
+  exports2.Popover = Popover;
+  exports2.Popup = Popup;
+  exports2.Progress = Progress;
+  exports2.PullRefresh = PullRefresh;
+  exports2.Radio = Radio;
+  exports2.RadioGroup = RadioGroup;
+  exports2.Rate = Rate;
+  exports2.Row = Row;
+  exports2.Search = Search;
+  exports2.ShareSheet = ShareSheet;
+  exports2.Sidebar = Sidebar;
+  exports2.SidebarItem = SidebarItem;
+  exports2.Skeleton = Skeleton;
+  exports2.SkeletonAvatar = SkeletonAvatar;
+  exports2.SkeletonImage = SkeletonImage;
+  exports2.SkeletonParagraph = SkeletonParagraph;
+  exports2.SkeletonTitle = SkeletonTitle;
+  exports2.Slider = Slider;
+  exports2.Space = Space;
+  exports2.Step = Step;
+  exports2.Stepper = Stepper;
+  exports2.Steps = Steps;
+  exports2.Sticky = Sticky;
+  exports2.SubmitBar = SubmitBar;
+  exports2.Swipe = Swipe;
+  exports2.SwipeCell = SwipeCell;
+  exports2.SwipeItem = SwipeItem;
+  exports2.Switch = Switch;
+  exports2.Tab = Tab;
+  exports2.Tabbar = Tabbar;
+  exports2.TabbarItem = TabbarItem;
+  exports2.Tabs = Tabs;
+  exports2.Tag = Tag;
+  exports2.TextEllipsis = TextEllipsis;
+  exports2.TimePicker = TimePicker;
+  exports2.Toast = Toast;
+  exports2.TreeSelect = TreeSelect;
+  exports2.Uploader = Uploader;
+  exports2.actionBarButtonProps = actionBarButtonProps;
+  exports2.actionBarIconProps = actionBarIconProps;
+  exports2.actionBarProps = actionBarProps;
+  exports2.actionSheetProps = actionSheetProps;
+  exports2.addressEditProps = addressEditProps;
+  exports2.addressListProps = addressListProps;
+  exports2.allowMultipleToast = allowMultipleToast;
+  exports2.areaProps = areaProps;
+  exports2.backTopProps = backTopProps;
+  exports2.badgeProps = badgeProps;
+  exports2.buttonProps = buttonProps;
+  exports2.calendarProps = calendarProps;
+  exports2.cardProps = cardProps;
+  exports2.cascaderProps = cascaderProps;
+  exports2.cellGroupProps = cellGroupProps;
+  exports2.cellProps = cellProps;
+  exports2.checkboxGroupProps = checkboxGroupProps;
+  exports2.checkboxProps = checkboxProps;
+  exports2.circleProps = circleProps;
+  exports2.closeDialog = closeDialog;
+  exports2.closeNotify = closeNotify;
+  exports2.closeToast = closeToast;
+  exports2.colProps = colProps;
+  exports2.collapseItemProps = collapseItemProps;
+  exports2.collapseProps = collapseProps;
+  exports2.configProviderProps = configProviderProps;
+  exports2.contactCardProps = contactCardProps;
+  exports2.contactEditProps = contactEditProps;
+  exports2.contactListProps = contactListProps;
+  exports2.countDownProps = countDownProps;
+  exports2.couponCellProps = couponCellProps;
+  exports2.couponListProps = couponListProps;
+  exports2.datePickerProps = datePickerProps;
+  exports2.default = stdin_default;
+  exports2.dialogProps = dialogProps;
+  exports2.dividerProps = dividerProps;
+  exports2.dropdownItemProps = dropdownItemProps;
+  exports2.dropdownMenuProps = dropdownMenuProps;
+  exports2.emptyProps = emptyProps;
+  exports2.fieldProps = fieldProps;
+  exports2.formProps = formProps;
+  exports2.gridItemProps = gridItemProps;
+  exports2.gridProps = gridProps;
+  exports2.iconProps = iconProps;
+  exports2.imagePreviewProps = imagePreviewProps;
+  exports2.imageProps = imageProps;
+  exports2.indexAnchorProps = indexAnchorProps;
+  exports2.indexBarProps = indexBarProps;
+  exports2.install = install;
+  exports2.listProps = listProps;
+  exports2.loadingProps = loadingProps;
+  exports2.navBarProps = navBarProps;
+  exports2.noticeBarProps = noticeBarProps;
+  exports2.notifyProps = notifyProps;
+  exports2.numberKeyboardProps = numberKeyboardProps;
+  exports2.overlayProps = overlayProps;
+  exports2.paginationProps = paginationProps;
+  exports2.passwordInputProps = passwordInputProps;
+  exports2.pickerGroupProps = pickerGroupProps;
+  exports2.pickerProps = pickerProps;
+  exports2.popoverProps = popoverProps;
+  exports2.popupProps = popupProps$2;
+  exports2.progressProps = progressProps;
+  exports2.pullRefreshProps = pullRefreshProps;
+  exports2.radioGroupProps = radioGroupProps;
+  exports2.radioProps = radioProps;
+  exports2.rateProps = rateProps;
+  exports2.resetDialogDefaultOptions = resetDialogDefaultOptions;
+  exports2.resetNotifyDefaultOptions = resetNotifyDefaultOptions;
+  exports2.resetToastDefaultOptions = resetToastDefaultOptions;
+  exports2.rowProps = rowProps;
+  exports2.searchProps = searchProps;
+  exports2.setDialogDefaultOptions = setDialogDefaultOptions;
+  exports2.setNotifyDefaultOptions = setNotifyDefaultOptions;
+  exports2.setToastDefaultOptions = setToastDefaultOptions;
+  exports2.shareSheetProps = shareSheetProps;
+  exports2.showConfirmDialog = showConfirmDialog;
+  exports2.showDialog = showDialog;
+  exports2.showFailToast = showFailToast;
+  exports2.showImagePreview = showImagePreview;
+  exports2.showLoadingToast = showLoadingToast;
+  exports2.showNotify = showNotify;
+  exports2.showSuccessToast = showSuccessToast;
+  exports2.showToast = showToast;
+  exports2.sidebarItemProps = sidebarItemProps;
+  exports2.sidebarProps = sidebarProps;
+  exports2.skeletonAvatarProps = skeletonAvatarProps;
+  exports2.skeletonImageProps = skeletonImageProps;
+  exports2.skeletonParagraphProps = skeletonParagraphProps;
+  exports2.skeletonProps = skeletonProps;
+  exports2.skeletonTitleProps = skeletonTitleProps;
+  exports2.sliderProps = sliderProps;
+  exports2.spaceProps = spaceProps;
+  exports2.stepperProps = stepperProps;
+  exports2.stepsProps = stepsProps;
+  exports2.stickyProps = stickyProps;
+  exports2.submitBarProps = submitBarProps;
+  exports2.swipeCellProps = swipeCellProps;
+  exports2.swipeProps = swipeProps;
+  exports2.switchProps = switchProps;
+  exports2.tabProps = tabProps;
+  exports2.tabbarItemProps = tabbarItemProps;
+  exports2.tabbarProps = tabbarProps;
+  exports2.tabsProps = tabsProps;
+  exports2.tagProps = tagProps;
+  exports2.textEllipsisProps = textEllipsisProps;
+  exports2.timePickerProps = timePickerProps;
+  exports2.toastProps = toastProps;
+  exports2.treeSelectProps = treeSelectProps;
+  exports2.uploaderProps = uploaderProps;
+  exports2.useCurrentLang = useCurrentLang;
+  exports2.version = version;
+  Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
+});

File diff suppressed because it is too large
+ 6 - 0
hybrid/html/maps/js/lib/vue.js


+ 468 - 0
hybrid/html/maps/js/mapindex.js

@@ -0,0 +1,468 @@
+
+function showInputView(){
+	const box = document.getElementById("search-box");
+	box.style.display = "block"; //设置样式为不显示(隐藏)
+	// const citys = document.getElementById("citys");
+	// citys.style.display = "block"; //设置样式为不显示(隐藏)
+}
+
+function hidInputView(){
+	const box = document.getElementById("search-box");
+	box.style.display = "none"; //设置样式为不显示(隐藏)
+	// const citys = document.getElementById("citys");
+	// citys.style.display = "none"; //设置样式为不显示(隐藏)
+}
+
+
+document.addEventListener('UniAppJSBridgeReady', function() {
+var lats = getQueryVariable('lat') * 1;
+var lngs = getQueryVariable('lng') * 1;
+var latn = getQueryVariable('nlat') * 1;
+var lngn = getQueryVariable('nlng') * 1;
+var sstate = getQueryVariable('sstate') * 1;
+var lg = getQueryVariable('lg') * 1;
+var zoom = 15; //地图缩放比例
+var coords = "";
+var startAddr="";
+var endcoords = "";
+var endAddr="";
+var mpcenter = "";
+var searchmarker = "";
+
+
+
+var showinput=false;
+
+
+var map; //地图
+var drawRouteMarker = []; //路线marker
+var directionsRendererArr = []; //地图路线
+/**
+ * 初始化
+ * 
+ */
+function initMap() {
+	if (lats && lngs) {
+		coords = {
+			lat: lats,
+			lng: lngs
+		};
+		mpcenter = {
+			lat: lats,
+			lng: lngs
+		};
+	} else {
+		navigator.geolocation.getCurrentPosition(function(position) {
+			coords = {
+				lat: position.coords.latitude,
+				lng: position.coords.longitude
+			};
+			mpcenter = {
+				lat: position.coords.latitude-0.001,
+				lng: position.coords.longitude
+			};
+			lats = position.coords.latitude;
+			lngs = position.coords.longitude
+		});
+	}
+	map = new google.maps.Map(document.getElementById('map'), {
+		zoom: zoom,
+		center: mpcenter,
+		mapId: MAPID,
+		animation: 'BOUNCE'
+	});
+	if(latn!=0 && lngn!=0){
+		endcoords ={
+			lat: latn,
+			lng: lngn
+		};
+		drawRoute();
+	}
+	else{
+		searchmarker = new google.maps.Marker({
+			map: map,
+			position: coords,
+			title: '',
+		});
+		getAddress(coords,'',0);
+	}
+	
+	if(sstate==0){
+		const box = document.getElementById("search-box");
+		box.style.display = "none"; //设置样式为不显示(隐藏)
+		const posl = document.getElementById("pos");
+		posl.style.display = "none"; //设置样式为不显示(隐藏)
+	}
+	else if(sstate==1){
+		const box = document.getElementById("search-box");
+		if(lg==1){
+			box.placeholder='Vui lòng nhập điểm đến...';
+		}
+		if(lg==2){
+			box.placeholder='请输入目的地...';
+		}
+		if(lg==3){
+			box.placeholder='請輸入目的地...';
+		}
+		
+		Repositioning();
+		ListeningInputBox();
+	}
+	else if(sstate==2){
+		const box = document.getElementById("search-box");
+		box.style.display = "none"; //设置样式为不显示(隐藏)
+		const posl = document.getElementById("pos");
+		posl.style.display = "none"; //设置样式为不显示(隐藏)
+		
+	}
+	
+	setTimeout(() => {
+		LoadAnimation(false)
+	}, 500)
+	
+}
+
+/**
+ * 监听输入框 输入事件
+ * 
+ * */
+function ListeningInputBox() {
+	// 创建 Autocomplete 实例
+
+	const input = document.getElementById("search-box");
+	const autocomplete = new google.maps.places.Autocomplete(input);
+	// 设置 Autocomplete 参数
+	autocomplete.setFields(["geometry", "name"]);
+	// 添加事件监听器,当用户选择某个地点时,在地图上标记出所选位置
+	LoadAnimation(true)
+	autocomplete.addListener("place_changed", function() {
+		const place = autocomplete.getPlace();
+		var latlng = JSON.parse(JSON.stringify(place.geometry.location));
+		var placename = document.getElementById("search-box").value;
+		getAddress(latlng,placename,1);
+		if (!place.geometry) {
+			console.log("返回的地理信息无效!");
+			return;
+		}
+		
+		// 将地图中心点指向用户所选位置,并设置标记
+		map.setCenter(place.geometry.location);
+		if (searchmarker) { //去除marker标记点
+			searchmarker.setMap(null)
+			searchmarker = ""
+		}
+		searchmarker = new google.maps.Marker({
+			map: map,
+			position: place.geometry.location,
+			title: place.name,
+		});
+		
+		//以搜索地址为目的地规划路径
+		// endcoords = place.geometry.location;
+		// drawRoute();
+		setTimeout(() => {
+			LoadAnimation(false)
+		}, 1000)
+		
+	});
+}
+/**
+ * 根据经度纬度获取相对应的地址信息
+ *  提取 国家 省/州 市 区/县 路 门牌号  
+ * 
+ * */
+function getAddress(latlng,name,mark) {
+	
+	// 根据经纬度发起 Reverse Geocoding API 请求,获取地址信息
+	var geocoder = new google.maps.Geocoder();
+	var cityInfo = {
+		country: "", //国家
+		province: "", //省
+		city: "", //市
+		district: "", //区
+		street: "", //街道	
+		door: "", //门牌号
+		address: "", //详细地址
+		name:name//地址名称
+	}
+	geocoder.geocode({
+		location: latlng,
+	}, function(results, status) {
+		if (status === 'OK') {
+			if (results[0]) {
+				console.log(results[0])
+				for (var i = 0; i < results.length; i++) {
+					var components = results[i].address_components;
+					for (var j = 0; j < components.length; j++) {
+						var component = components[j];
+						if (component.types.includes("country")) {
+							console.log("国家:  ====>" + component.long_name);
+							cityInfo.country = component.long_name || '';
+						} else if (component.types.includes("administrative_area_level_1")) {
+							console.log("省/州:  ====>" + component.long_name);
+							cityInfo.province = component.long_name || '';
+						} else if (component.types.includes("locality")) {
+							console.log("城市: ====> " + component.long_name);
+							cityInfo.city = component.long_name || '';
+						} else if (component.types.includes("sublocality_level_1")) {
+							console.log("区/县: ====>" + component.long_name);
+							cityInfo.district = component.long_name || '';
+						} else if (component.types.includes("route")) {
+							console.log("路/街道名: ====> " + component.long_name);
+							cityInfo.street = component.long_name || '';
+						} else if (component.types.includes("street_number")) {
+							console.log("门牌号: ====> " + component.long_name);
+							cityInfo.door = component.long_name || '';
+						}
+					}
+				}
+				cityInfo.address = results[0].formatted_address;
+				returngeocode(latlng,cityInfo,mark);
+				// console.log("cityInfo==========", cityInfo)
+				// addInfo(cityInfo)
+				
+			} else {
+				//alert('找不到地址信息');
+				returngeocode(latlng,cityInfo,mark);
+			}
+		} else {
+			//alert('获取地址信息失败:' + status);
+			returngeocode(latlng,cityInfo,mark);
+		}
+	});
+}
+
+function returngeocode(location,cityInfo,type){
+	uni.postMessage({
+		data: {
+			position:location,
+			cityInfo:cityInfo,
+			type:type
+		}
+	});
+}
+
+function addInfo(cityInfo) {
+	// 获取子节点并设置新的文本内容
+	const child1 = document.getElementById('country');
+	child1.textContent = cityInfo.country;
+	const child2 = document.getElementById('province');
+	child2.textContent = cityInfo.province;
+	const child3 = document.getElementById('city');
+	child3.textContent = cityInfo.city;
+	const child4 = document.getElementById('district');
+	child4.textContent = cityInfo.district;
+	const child5 = document.getElementById('street');
+	child5.textContent = cityInfo.street;
+	const child6 = document.getElementById('door');
+	child6.textContent = cityInfo.door;
+	const child7 = document.getElementById('address');
+	child7.textContent = cityInfo.address;
+
+}
+
+/**
+ * 画路线图
+ *  经度纬度加了随机函数 故 起始点和终点 各不一致
+ *  需要用到此功能自行调整
+ * 
+ * */
+function drawRoute() {
+	LoadAnimation(true)
+	clearDrawRoute()
+	const directionsService = new google.maps.DirectionsService();
+	var TravelMode = [{
+			id: 1,
+			name: "DRIVING",
+			color: "#ea4335"
+		},
+		{
+			id: 2,
+			name: "WALKING",
+			color: "#7825fa"
+		},
+		{
+			id: 3,
+			name: "BICYCLING",
+			color: "#fa6200"
+		},
+		{
+			id: 4,
+			name: "TRANSIT",
+			color: "#ff00ff"
+		}
+	];
+	startDrawRoute(directionsService, TravelMode[0]);
+	
+}
+
+/**
+ * 清除路线
+ * 
+ * */
+function clearDrawRoute() {
+	if (directionsRendererArr) { //清空线
+		for (var i = 0; i < directionsRendererArr.length; i++) {
+			directionsRendererArr[i].setMap(null);
+		}
+		// 清空数组
+		directionsRendererArr = [];
+	}
+	if (drawRouteMarker) { //清空标记点
+		for (var i = 0; i < drawRouteMarker.length; i++) {
+			drawRouteMarker[i].setMap(null);
+		}
+		// 清空数组
+		drawRouteMarker = [];
+
+	}
+
+}
+
+/**
+ * 
+ * 开始绘制以下路线图
+ *	DRIVING:驾车模式。这是默认的出行方式,计算出行路线时考虑当时的实时交通情况。
+ *可用  WALKING:步行模式。计算步行路线时会考虑人行道、人行横道等规则,因此得到的路线可能与驾车路线不同。
+ *可用  BICYCLING:骑行模式。计算骑行路线时,避开了折返点和拥堵路段,提供了适合骑自行车的路线。
+ * TRANSIT:公共交通模式。在城市间导航中被广泛使用,提供了乘坐公共交通工具(如公交车、地铁、火车和轻轨)的路线方案。
+ * FLIGHTS:飞行模式。在 Google Maps 平台上无法使用,此模式只适用于各大航空公司网站等其他服务商范畴内。
+ * 
+ * */
+function startDrawRoute(directionsService, travelMode) {
+	// 随机数字而已  动态数字  方便查询效果
+	// let min = 5000;
+	// let max = 10000;
+	// let randomNum = (Math.floor(Math.random() * (max - min + 1)) + min) / 500000;
+	// 起点坐标
+
+	/**
+	 * lat 和lng数据为随机数据  运行时 调整为自己所在位置坐标
+	 * 
+	 * */
+	const origin = {
+		lat: coords.lat,
+		lng: coords.lng
+	};
+	// 终点坐标
+	const destination = {
+		lat: endcoords.lat,
+		lng: endcoords.lng
+	};
+    
+	var directionsRenderer = new google.maps.DirectionsRenderer({
+		map: map,
+		suppressMarkers: true, // 关闭默认图标
+		polylineOptions: {
+			strokeColor: travelMode.color, //设置路线颜色
+			strokeWeight: 5 //设置路线宽度
+		},
+		// draggable: true //允许用户拖动路线
+
+	});
+	const request = {
+		origin: origin,
+		destination: endcoords,
+		travelMode: travelMode.name, //绘制路线的模式
+	};
+	directionsService.route(request,
+		(result, status) => {
+			if (status === "OK") {
+				directionsRenderer.setDirections(result);
+				directionsRenderer.setMap(map);
+				// 获取起点和终点的信息并添加标记
+				var startMarker = new google.maps.Marker({
+					position: result.routes[0].legs[0].start_location,
+					map: map,
+					icon: {
+						url: "https://maps.gstatic.com/mapfiles/ms2/micons/pink.png",
+						scaledSize: new google.maps.Size(50, 50),
+					},
+				});
+				
+				drawRouteMarker.push(startMarker)
+				var endMarker = new google.maps.Marker({
+					position: result.routes[0].legs[0].end_location,
+					map: map,
+					icon: {
+						url: "https://maps.gstatic.com/mapfiles/ms2/micons/orange.png",
+						scaledSize: new google.maps.Size(50, 50),
+					},
+				});
+				drawRouteMarker.push(endMarker)
+				directionsRendererArr.push(directionsRenderer)
+				//显示路线的总距离
+				// console.log('距离===', directionsRenderer.directions.routes[0].legs[0].distance.text)
+				// console.log('时间===', directionsRenderer.directions.routes[0].legs[0].duration.text)
+				// for (var k = 0; k < directionsRenderer.directions.routes[0].legs[0].steps.length; k++) {
+				// 	console.log(directionsRenderer.directions.routes[0].legs[0].steps[k].instructions)
+				// }
+				if (searchmarker) { //去除marker标记点
+					searchmarker.setMap(null)
+					searchmarker = ""
+				}
+				uni.postMessage({
+					data: {
+						distance:directionsRenderer.directions.routes[0].legs[0].distance.text,
+						duration:directionsRenderer.directions.routes[0].legs[0].duration.text,
+						type:2
+					}
+				});
+			} else {
+				// console.log(travelMode, "绘制失败===", result)
+				uni.postMessage({
+					data: {
+						drawRoute:result
+					}
+				});
+			}
+		}
+	);
+
+	LoadAnimation(false)
+}
+
+/**
+ * 重新定位
+ * 
+ * 
+ * */
+function Repositioning() {
+	LoadAnimation(true)
+	var element = document.getElementById('pos');
+	element.addEventListener("click", function() {
+		if (navigator.geolocation) {
+			navigator.geolocation.getCurrentPosition(function(position) {
+				// lats = position.coords.latitude;
+				// lngs = position.coords.longitude;
+				var pos = {
+					lat: position.coords.latitude,
+					lng: position.coords.longitude
+				};
+				LoadAnimation(false)
+				map.setCenter(pos); // 将地图中心置于当前位置
+				// 将地图中心点指向用户所选位置,并设置标记
+				if (searchmarker) { //去除marker标记点
+					searchmarker.setMap(null)
+					searchmarker = ""
+				}
+				searchmarker = new google.maps.Marker({
+					map: map,
+					position: pos,
+					title:'location',
+				});
+				getAddress(pos,'',0);
+			}, function() {
+				console.log("无法获取地理位置信息");
+			});
+		} else {
+			console.log("浏览器不支持Geolocation API");
+		}
+
+
+	});
+}
+
+LoadAnimation(true)
+window.initMap = initMap;
+});

+ 39 - 0
hybrid/html/maps/mapindex.html

@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport"
+			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=0" />
+		<link href="http://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet" type="text/css">
+		<title></title>
+		<link rel="stylesheet" type="text/css" href="./css/index.css" />
+		<script src="./js/lib/common.js"></script>
+		<script src="./js/lib/toast.js"></script>
+	</head>
+	<body>
+		<!-- 地图 -->
+		<div id="map"></div>
+		<!-- 输入框事件 -->
+		<input id="search-box" type="text" placeholder="Vui lòng nhập điểm đến...">
+		<!-- css loading动画 -->
+		<!-- 定位 -->
+		<img class="pos" id="pos" src="./img/positioning.png" alt="">
+
+		<!-- <div class="citys" id="citys">
+			【国家 :<text id="country"></text>&nbsp;&nbsp;&nbsp;】
+			【省 : <text id="province"></text>&nbsp;&nbsp;&nbsp;】
+			【市 : <text id="city"></text>&nbsp;&nbsp;&nbsp;】
+			【区 : <text id="district"></text>&nbsp;&nbsp;&nbsp;】
+			【路 : <text id="street"></text>&nbsp;&nbsp;&nbsp;】
+			【 门牌号: <text id="door"></text>&nbsp;&nbsp;&nbsp;】
+			【详情地址 : <text id="address"></text>&nbsp;&nbsp;&nbsp;】</div> -->
+			<div class="loader" id="loader"></div>
+	</body>
+	<script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
+	 
+	<script
+		src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDHkkTK3p_uVk4oQ0MT9u0fr6Psglo5vH8&libraries=places&callback=initMap"
+		async defer></script>
+
+	<script type="text/javascript" src="./js/mapindex.js"></script>
+</html>

+ 404 - 0
hybrid/html/voices/audio.html

@@ -0,0 +1,404 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link rel="stylesheet" type="text/css" href="./css/index.css" />
+		<title id="title"></title>
+		<style>
+		html, body {
+		    height: 100%;
+		}
+		body {
+		    margin: 0;
+		}
+		video {
+		    width: 100%;
+		    height: 100%;
+		    position: absolute;
+		    left: 0;
+		    top: 0;
+		    z-index: -1;
+		}
+		
+		</style>
+	</head>
+	<body>
+		<!-- <video class="Bvideo" id="Big_video"  preload autoplay onclick="Bvideoselc()"></video> -->
+		<!-- <video class="Svideo" id="sm_video"  preload muted autoplay onclick="Svideoselc()"></video> -->
+		<audio id="my_audio" autoplay></audio>
+		<div class="contentColumnC" style="width: 100%;margin-top: 60px;"">
+			<div id="ICnote"></div>
+			<img class="iconImg" style="margin-top: 5px;" src="./img/logo.png" alt="" onclick="guaduan()"/>
+			<div class="contentInRowC" style="width: 100%;margin-top: 10px;">
+				<div id="markNote"></div>
+				<img class="calling" src="./img/loading2.gif" alt="" />
+			</div>
+		</div>
+		 <div style="width: 100%;margin-top: 100px;">
+			 <div class="contentColumnC">
+				 <img id='dianhua_Img' class="guadanImg" style="margin-top: 5px;" src="./img/jietong.png" alt="" onclick="guaduan()"/>
+			 </div>
+		 </div>
+		 <div>
+			 <div id="sdpkNote"></div>
+		 </div>
+	</body>
+	<script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
+	<script>
+		let language = getQueryVariable('language');
+		let title,state1,state2,state3,state4,state5,ICnote;
+		const title_div = document.getElementById('title');
+		const ICnote_div = document.getElementById('ICnote');
+	let localStream = null;
+	let localCall = 0;
+	let localCandidata=null;
+	let peer = null;
+	let video=null;
+	let jietong=false;
+	let payload=null;
+	
+	let markindex=0;
+	
+	// const Big_video = document.getElementById('Big_video');
+	// const sm_video = document.getElementById('sm_video');
+	// const my_audio = document.getElementById('my_audio');
+	const dianhua_Img = document.getElementById('dianhua_Img');
+	
+	const markNote = document.getElementById('markNote');
+	const sdpkNote = document.getElementById('sdpkNote');
+	
+	//====================================================
+	function getQueryVariable(variable) {
+		var query = decodeURI(window.location.search.substring(1));
+		var vars = query.split("&");
+		for (var i = 0; i < vars.length; i++) {
+			var pair = vars[i].split("=");
+			if (pair[0] == variable) {
+				return pair[1];
+			}
+		}
+		return (false);
+	}
+	function Bvideoselc(){
+		if(localStream!=null){
+			//Big_video.srcObject =localStream;
+			Big_video.setAttribute('autoplay', true); /* THIS */
+		}
+	}
+	function Svideoselc(){
+		if(localStream!=null){
+			//sm_video.srcObject =localStream;
+			sm_video.setAttribute('autoplay', true); /* THIS */
+		}
+		
+	}
+	function guaduan(){
+		if(jietong){
+			if(peer){
+				peer.close();
+			}
+			uni.postMessage({
+			    data: {
+			        data:'', // 回传
+					type:88
+			    },
+			});
+		}
+		else{
+			jietong=true;
+			markNote.innerHTML=state2;
+			if(payload!=null){
+				RCstartWebRct(payload);
+			}
+			dianhua_Img.src = "./img/guaduandd.png"
+		}
+	}
+	function duifangguaduan(){
+		if(jietong){
+			if(peer){
+				peer.close();
+			}
+			markNote.innerHTML=state4;
+		}
+	}
+	//====================================================
+	function appAct (obj) {
+		if(obj.type==1){//主动发起im通话
+			localCall=1;
+			//startWebRct(obj.type);
+			markNote.innerHTML=state1;
+			
+		}
+		else if(obj.type==2){//收到发起方sdp offer
+			if(localCall==1){//发起方收到接受方 sdp answer
+				markNote.innerHTML=state2;
+				RCremoteData(obj.payload);
+			}
+			else{//接受方 收到发起方sdp offer
+				//markNote.innerHTML=state1;
+				payload=obj.payload;
+				if(jietong){
+					//markNote.innerHTML=state2;
+					RCstartWebRct(obj.payload);//启动wbrtc
+				}
+			}
+		}
+		else if(obj.type==3){//收到candidate
+			//markNote.innerHTML=state2;
+			//sdpkNote.innerHTML=JSON.stringify(obj.payload);
+			for(var i=0;i<obj.payload.length;i++){//收到candidate 添加到Rct
+				peer.addIceCandidate(obj.payload[i]);
+			}
+			if(localCall!=1){//接收方收到candidate 回应自己的candidate给发起方
+				uni.postMessage({
+				    data: {
+				        data:localCandidata, //应答方回应candidate
+						type:3
+				    },
+				});
+			}
+		}
+	}
+	
+	async function startCapture(displayMediaOptions) {
+	    try {
+	        localStream = await navigator.mediaDevices.getUserMedia(displayMediaOptions);
+			// Big_video.srcObject =localStream;
+			// Big_video.setAttribute('autoplay', true); /* THIS */
+			// markindex=markindex+1;
+			// uni.postMessage({
+			//     data: {
+			//         data:markindex, // 回传
+			// 		type:99999
+			//     },
+			// });
+			uni.postMessage({
+			    data: {
+			        data:'', // 回传
+					type:99
+			    },
+			});
+	    } catch(err) {
+	        console.error(err);
+	    }
+	}
+	async function startWebRct(type){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				]
+			}
+		);
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		});
+		//创建本地offer
+		const offer = peer.createOffer({
+			offerToReceiveAudio:1,
+			offerToReceiveVideo:0
+		});
+		//记录本地offer
+		offer.then(value => {
+			peer.setLocalDescription(value);
+			uni.postMessage({
+			    data: {
+			        data:value, // 回传并推送offer
+					type:2
+			    },
+			});
+		}).catch(error => {
+		});
+		peer.onconnectionstatechange = function (ev) {
+			if(peer.connectionState=="closed"){
+				markNote.innerHTML=state5;
+			}
+			if(peer.connectionState=="connected"){
+				markNote.innerHTML=state3;
+			}
+			if(peer.connectionState=="connecting"){
+				markNote.innerHTML=state2;
+			}
+			if(peer.connectionState=="disconnected"){
+				markNote.innerHTML=state4;
+			}
+		};
+		localCandidata=[]
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			localCandidata.push(event.candidate);
+		  }
+		}
+		startCommunicate();
+	}
+	//发起方收到 远端SDP answer  保存并发送candidate
+	async function RCremoteData(rcData){//收到remoteAnswer
+		//记录远端offer
+		await peer.setRemoteDescription(rcData)
+		
+		uni.postMessage({
+		    data: {
+		        data:localCandidata, // 发起方先发candidate
+				type:3
+		    },
+		});
+	}
+	function startCommunicate(){
+		peer.ontrack = (e) => {
+			if(e.streams[0]){
+				var otherVideos = document.querySelector('#my_audio');
+				//var otherVideos = document.querySelector('#Big_video');
+				otherVideos.srcObject = e.streams[0];
+				//otherVideos.setAttribute('autoplay', true); /* THIS */
+				uni.postMessage({
+				    data: {
+				        data:JSON.stringify(e.streams[0]), // 回传并推送offer
+						type:'sss'
+				    },
+				});
+			}
+			// sm_video.srcObject =localStream;
+			// sm_video.setAttribute('autoplay', true); /* THIS */
+		}
+	}
+	async function RCstartWebRct(payload){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				],
+				offerExtmapAllowMixed:false
+			}
+		);
+		// uni.postMessage({
+		//     data: {
+		//         data:1, //应答方回应candidate
+		// 		type:33333
+		//     },
+		// });
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		})
+		localCandidata=[];
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			//let strcandidate=JSON.stringify(event.candidate);
+			localCandidata.push(event.candidate);
+		  }
+		}
+		
+		
+		startCommunicate();
+		// uni.postMessage({
+		//     data: {
+		//         data:2, //应答方回应candidate
+		// 		type:33333
+		//     },
+		// });
+		peer.onconnectionstatechange = function (ev) {
+			if(peer.connectionState=="closed"){
+				markNote.innerHTML=state5;
+			}
+			if(peer.connectionState=="connected"){
+				markNote.innerHTML=state3;
+			}
+			if(peer.connectionState=="connecting"){
+				markNote.innerHTML=state2;
+			}
+			if(peer.connectionState=="disconnected"){
+				markNote.innerHTML=state4;
+			}
+		};
+		
+		
+		//记录远端offer
+		//记录远端offer
+		const offer = new RTCSessionDescription(payload);
+		uni.postMessage({
+		    data: {
+		        data:offer, //应答方回应candidate
+				type:33333
+		    },
+		});
+		await peer.setRemoteDescription(offer);
+		//await peer.setRemoteDescription(payload)//iOS发起的通话 安卓音频适配异常----------------
+
+		// uni.postMessage({
+		//     data: {
+		//         data:4, //应答方回应candidate
+		// 		type:33333
+		//     },
+		// });
+		const remoteAnswer = await peer.createAnswer();
+		// uni.postMessage({
+		//     data: {
+		//         data:remoteAnswer, //应答方回应candidate
+		// 		type:33333
+		//     },
+		// });
+		//记录本地offer
+		await peer.setLocalDescription(remoteAnswer);
+		//推送remoteAnswer
+		uni.postMessage({
+		    data: {
+		        data:remoteAnswer, // 回传并推送offer
+				type:2
+		    },
+		});
+		
+	}
+	function initRtc() {
+		if(language=='yuenan'){//越南语
+			ICnote='CTE Rider yêu cầu IM Voice Call';
+			title='IM Cuộc gọi thoại';
+			state1='Đang gọi';
+			state2='Đang kết nối';
+			state3='Đã kết nối';
+			state4='Bị treo';
+			state5='Kết thúc cuộc gọi';
+		}
+		if(language=='zh-Hans'){//简体中文
+			ICnote='CTE骑手请求IM语音通话'
+			title='IM 语音通话';
+			state1='正在呼叫';
+			state2='正在接通';
+			state3='已接通';
+			state4='已挂断';
+			state5='结束通话';
+		}
+		if(language=='zh-Hant'){//繁体中文
+			ICnote='CTE騎手請求IM語音通話'
+			title='IM 語音通話';
+			state1='正在呼叫';
+			state2='正在接通';
+			state3='已接通';
+			state4='已掛斷';
+			state5='結束通話';
+		}
+		markNote.innerHTML=title;
+		ICnote_div.innerHTML=ICnote;
+		title_div.innerHTML=title;
+		setTimeout(() => {
+			startCapture({ video: true, audio: true});
+			//startCapture({audio: true});
+		}, 1000)
+		return;
+	}
+	function releaseTack(){
+		if(peer){
+			peer.close();
+		}
+	}
+	window.onload=initRtc;
+	window.onunload=releaseTack;
+	</script>
+	
+</html>

+ 74 - 0
hybrid/html/voices/css/index.css

@@ -0,0 +1,74 @@
+* {
+	padding: 0;
+	margin: 0;
+}
+
+.loadinggif {
+	width: 50px;
+	height: 50px;
+	position: fixed;
+	left: 50%;
+	bottom: 50%;
+	margin-left: -25px;
+	margin-top: -25px;
+	z-index: 99;
+}
+
+.Bvideo {
+	display: flex;
+	width: 100%;
+	height: auto;
+	left: 0;
+	top: 0;
+	z-index: 1;
+}
+.Svideo {
+	position: fixed;
+	flex-direction: row;
+	width: 30%;
+	height: auto;
+	left: auto;
+	right: 0;
+	bottom: 0;
+	z-index: 99;
+}
+
+.bottomView{
+	position: fixed;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
+	width: 100%;
+	height: 100px;
+	top: auto;
+	bottom: 0;
+	z-index: 999;
+	background-color: rgba(100, 100, 100, 0.5); /* 黑色,50% 透明度 */
+}
+
+.contentInRowC{
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+}
+.contentColumnC{
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+}
+.iconImg{
+	width: 120px;
+	height: 120px;
+	border-radius: 6px;
+}
+.guadanImg{
+	width: 54px;
+	height: 54px;
+}
+.calling{
+	width: 26px;
+	height: 26px;
+}
+

+ 1 - 0
hybrid/html/voices/css/modules/code.css

@@ -0,0 +1 @@
+html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:13px}.layui-code-title{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-title>.layui-code-about{position:absolute;right:10px;top:0;color:#b7b7b7}.layui-code-about>a{padding-left:10px}.layui-code-view>.layui-code-ol,.layui-code-view>.layui-code-ul{position:relative;overflow:auto}.layui-code-view>.layui-code-ol>li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view>.layui-code-ol>li:first-child,.layui-code-view>.layui-code-ul>li:first-child{padding-top:10px}.layui-code-view>.layui-code-ol>li:last-child,.layui-code-view>.layui-code-ul>li:last-child{padding-bottom:10px}.layui-code-view>.layui-code-ul>li{position:relative;line-height:20px;padding:0 10px;list-style-type:none;*list-style-type:none;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-dark{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-dark>.layui-code-title{border-bottom:none}.layui-code-dark>.layui-code-ol>li,.layui-code-dark>.layui-code-ul>li{background-color:#3f3f3f;border-left:none}.layui-code-dark>.layui-code-ul>li{margin-left:6px}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}

File diff suppressed because it is too large
+ 0 - 0
hybrid/html/voices/css/modules/laydate/default/laydate.css


BIN
hybrid/html/voices/css/modules/layer/default/icon-ext.png


BIN
hybrid/html/voices/css/modules/layer/default/icon.png


File diff suppressed because it is too large
+ 0 - 0
hybrid/html/voices/css/modules/layer/default/layer.css


BIN
hybrid/html/voices/css/modules/layer/default/loading-0.gif


BIN
hybrid/html/voices/css/modules/layer/default/loading-1.gif


BIN
hybrid/html/voices/css/modules/layer/default/loading-2.gif


+ 0 - 0
hybrid/html/voices/css/slider.css


File diff suppressed because it is too large
+ 0 - 0
hybrid/html/voices/css/vant.css


BIN
hybrid/html/voices/img/guaduandd.png


BIN
hybrid/html/voices/img/jietong.png


BIN
hybrid/html/voices/img/loading2.gif


BIN
hybrid/html/voices/img/logo.png


+ 254 - 0
hybrid/html/voices/index.html

@@ -0,0 +1,254 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link rel="stylesheet" type="text/css" href="./css/index.css" />
+		<title>IM通话</title>
+		<style>
+		html, body {
+		    height: 100%;
+		}
+		body {
+		    margin: 0;
+		}
+		video {
+		    width: 100%;
+		    height: 100%;
+		    position: absolute;
+		    left: 0;
+		    top: 0;
+		    z-index: -1;
+		}
+		
+		</style>
+	</head>
+	<body>
+		<video class="Bvideo" id="Big_video"  preload autoplay onclick="Bvideoselc()"></video>
+		<!-- <video class="Svideo" id="sm_video"  preload muted autoplay onclick="Svideoselc()"></video> -->
+		<!-- <audio id="my_audio" autoplay></audio> -->
+		 <div class="bottomView" style="width: 100%;">
+			 <div class="contentColumnC">
+				 <img class="guadanImg" style="margin-top: 5px;" src="./img/guaduandd.png" alt="" onclick="guaduan()"/>
+				 <div class="contentInRowC" style="width: 100%;margin-top: 10px;">
+					 <div id="markNote"></div>
+					 <img class="calling" src="./img/loading2.gif" alt="" />
+				 </div>
+			 </div>
+		 </div>
+	</body>
+	<script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
+	<script>
+	let localStream = null;
+	let localCall = 0;
+	let localCandidata=null;
+	let peer = null;
+	let video=null;
+	// const Big_video = document.getElementById('Big_video');
+	// const sm_video = document.getElementById('sm_video');
+	// const my_audio = document.getElementById('my_audio');
+	
+	const markNote = document.getElementById('markNote');
+	//====================================================
+	function Bvideoselc(){
+		if(localStream!=null){
+			//Big_video.srcObject =localStream;
+			Big_video.setAttribute('autoplay', true); /* THIS */
+		}
+	}
+	function Svideoselc(){
+		if(localStream!=null){
+			//sm_video.srcObject =localStream;
+			sm_video.setAttribute('autoplay', true); /* THIS */
+		}
+		
+	}
+	function guaduan(){
+		peer.close();
+		uni.postMessage({
+		    data: {
+		        data:'', // 回传
+				type:88
+		    },
+		});
+	}
+	//====================================================
+	function appAct (obj) {
+		if(obj.type==1){//主动发起im通话
+			localCall=1;
+			startWebRct(obj.type);
+			markNote.innerHTML='拨打中'
+		}
+		else if(obj.type==2){//收到推送消息
+			if(localCall==1){
+				markNote.innerHTML='接通中'
+				RCremoteData(obj.payload);
+			}
+			else{
+				RCstartWebRct(obj.payload);
+			}
+		}
+		else if(obj.type==3){//收到candidate
+			markNote.innerHTML='接通中'
+			for(var i=0;i<obj.payload.length;i++){
+				peer.addIceCandidate(obj.payload[i]);
+			}
+			if(localCall!=1){
+				uni.postMessage({
+				    data: {
+				        data:localCandidata, //应答方回应candidate
+						type:3
+				    },
+				});
+			}
+			
+		}
+	}
+	
+	async function startCapture(displayMediaOptions) {
+	    try {
+	        localStream = await navigator.mediaDevices.getUserMedia(displayMediaOptions);
+			// Big_video.srcObject =localStream;
+			// Big_video.setAttribute('autoplay', true); /* THIS */
+			
+			uni.postMessage({
+			    data: {
+			        data:'', // 回传
+					type:99
+			    },
+			});
+	    } catch(err) {
+	        console.error(err);
+	    }
+	}
+	async function startWebRct(type){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				]
+			}
+		);
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		});
+		//创建本地offer
+		const offer = peer.createOffer({
+			offerToReceiveAudio:1,
+			offerToReceiveVideo:1
+		});
+		//记录本地offer
+		offer.then(value => {
+			peer.setLocalDescription(value);
+			uni.postMessage({
+			    data: {
+			        data:value, // 回传并推送offer
+					type:2
+			    },
+			});
+		}).catch(error => {
+		});
+		peer.oniceconnectionstatechange = function (ev) {
+			if(peer.connectionState=="closed"){
+				markNote.innerHTML='结束通话'
+			}
+			if(peer.connectionState=="connected"){
+				markNote.innerHTML='已接通'
+			}
+			if(peer.connectionState=="connecting"){
+				markNote.innerHTML='连接中'
+			}
+			if(peer.connectionState=="disconnected"){
+				markNote.innerHTML='对方挂断'
+			}
+		};
+		localCandidata=[]
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			localCandidata.push(event.candidate);
+		  }
+		}
+		startCommunicate();
+	}
+	
+	async function RCremoteData(rcData){//收到remoteAnswer
+		//记录远端offer
+		await peer.setRemoteDescription(rcData)
+		
+		uni.postMessage({
+		    data: {
+		        data:localCandidata, // 发起方先发candidate
+				type:3
+		    },
+		});
+	}
+	function startCommunicate(){
+		peer.ontrack = (e) => {
+			if(e.streams[0]){
+				//var otherVideos = document.querySelector('#my_audio');
+				var otherVideos = document.querySelector('#Big_video');
+				otherVideos.srcObject = e.streams[0];
+			}
+			// sm_video.srcObject =localStream;
+			// sm_video.setAttribute('autoplay', true); /* THIS */
+		}
+	}
+	async function RCstartWebRct(payload){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				]
+			}
+		);
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		})
+		localCandidata=[];
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			//let strcandidate=JSON.stringify(event.candidate);
+			localCandidata.push(event.candidate);
+		  }
+		}
+		startCommunicate();
+		//记录远端offer
+		await peer.setRemoteDescription(payload)
+		
+		const remoteAnswer = await peer.createAnswer();
+		//记录本地offer
+		await peer.setLocalDescription(remoteAnswer);
+		//推送remoteAnswer
+		uni.postMessage({
+		    data: {
+		        data:remoteAnswer, // 回传并推送offer
+				type:2
+		    },
+		});
+		
+	}
+	function initRtc() {
+		markNote.innerHTML='IM通话'
+		setTimeout(() => {
+			startCapture({ video: true, audio: true});
+			//startCapture({audio: true});
+		}, 1000)
+		return;
+	}
+	function releaseTack(){
+		if(peer){
+			peer.close();
+		}
+	}
+	window.onload=initRtc;
+	window.onunload=releaseTack;
+	</script>
+	
+</html>

File diff suppressed because it is too large
+ 0 - 0
hybrid/html/voices/js/lib/uniwebviewsdk.js


+ 5649 - 0
hybrid/html/xuanfu/css/mui.css

@@ -0,0 +1,5649 @@
+/*!
+ * =====================================================
+ * Mui v3.7.3 (http://dev.dcloud.net.cn/mui)
+ * =====================================================
+ */
+
+/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
+html
+{
+    font-family: sans-serif;
+
+    -webkit-text-size-adjust: 100%;
+}
+
+body
+{
+    margin: 0;
+}
+
+body::after
+{
+    position: fixed;
+    top: -1000px;
+    left: -1000px;
+
+    content: '';
+    -webkit-animation: shadow-preload .1s;
+            animation: shadow-preload .1s;
+    -webkit-animation-delay: 3s;
+            animation-delay: 3s;
+}
+
+@-webkit-keyframes shadow-preload
+{
+    0%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+
+    100%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+}
+@keyframes shadow-preload
+{
+    0%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+
+    100%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+nav,
+section,
+summary
+{
+    display: block;
+}
+
+audio,
+canvas,
+progress,
+video
+{
+    display: inline-block;
+
+    vertical-align: baseline;
+}
+
+audio:not([controls])
+{
+    display: none;
+
+    height: 0;
+}
+
+[hidden],
+template
+{
+    display: none;
+}
+
+a
+{
+    background: transparent;
+}
+
+a:active,
+a:hover
+{
+    outline: 0;
+}
+
+abbr[title]
+{
+    border-bottom: 1px dotted;
+}
+
+b,
+strong
+{
+    font-weight: bold;
+}
+
+dfn
+{
+    font-style: italic;
+}
+
+h1
+{
+    font-size: 2em;
+
+    margin: .67em 0;
+}
+
+mark
+{
+    color: #000;
+    background: #ff0;
+}
+
+small
+{
+    font-size: 80%;
+}
+
+sub,
+sup
+{
+    font-size: 75%;
+    line-height: 0;
+
+    position: relative;
+
+    vertical-align: baseline;
+}
+
+sup
+{
+    top: -.5em;
+}
+
+sub
+{
+    bottom: -.25em;
+}
+
+img
+{
+    border: 0;
+}
+
+svg:not(:root)
+{
+    overflow: hidden;
+}
+
+figure
+{
+    margin: 1em 40px;
+}
+
+hr
+{
+    box-sizing: content-box;
+    height: 0;
+}
+
+pre
+{
+    overflow: auto;
+}
+
+code,
+kbd,
+pre,
+samp
+{
+    font-family: monospace, monospace;
+    font-size: 1em;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea
+{
+    font: inherit;
+
+    margin: 0;
+
+    color: inherit;
+}
+
+button
+{
+    overflow: visible;
+}
+
+button,
+select
+{
+    text-transform: none;
+}
+
+button,
+html input[type='button'],
+input[type='reset'],
+input[type='submit']
+{
+    cursor: pointer;
+
+    -webkit-appearance: button;
+}
+
+button[disabled],
+html input[disabled]
+{
+    cursor: default;
+}
+
+input
+{
+    line-height: normal;
+}
+
+input[type='checkbox'],
+input[type='radio']
+{
+    box-sizing: border-box;
+    padding: 0;
+}
+
+input[type='number']::-webkit-inner-spin-button,
+input[type='number']::-webkit-outer-spin-button
+{
+    height: auto;
+}
+
+input[type='search']
+{
+    -webkit-box-sizing: content-box;
+            box-sizing: content-box;
+
+    -webkit-appearance: textfield;
+}
+
+input[type='search']::-webkit-search-cancel-button,
+input[type='search']::-webkit-search-decoration
+{
+    -webkit-appearance: none;
+}
+
+fieldset
+{
+    margin: 0 2px;
+    padding: .35em .625em .75em;
+
+    border: 1px solid #c0c0c0;
+}
+
+legend
+{
+    padding: 0;
+
+    border: 0;
+}
+
+textarea
+{
+    overflow: auto;
+}
+
+optgroup
+{
+    font-weight: bold;
+}
+
+table
+{
+    border-spacing: 0;
+    border-collapse: collapse;
+}
+
+td,
+th
+{
+    padding: 0;
+}
+
+*
+{
+    -webkit-box-sizing: border-box;
+            box-sizing: border-box;
+
+    -webkit-user-select: none;
+
+    outline: none;
+
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+}
+
+body
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    font-size: 17px;
+    line-height: 21px;
+
+    color: #000;
+    background-color: #efeff4;
+
+    -webkit-overflow-scrolling: touch;
+}
+
+a
+{
+    text-decoration: none;
+
+    color: #007aff;
+}
+a:active
+{
+    color: #0062cc;
+}
+
+.mui-content
+{
+    background-color: #efeff4;
+
+    -webkit-overflow-scrolling: touch;
+}
+
+.mui-bar-nav ~ .mui-content
+{
+    padding-top: 44px;
+}
+.mui-bar-nav ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    top: 44px;
+}
+
+.mui-bar-header-secondary ~ .mui-content
+{
+    padding-top: 88px;
+}
+.mui-bar-header-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    top: 88px;
+}
+
+.mui-bar-footer ~ .mui-content
+{
+    padding-bottom: 44px;
+}
+.mui-bar-footer ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 44px;
+}
+
+.mui-bar-footer-secondary ~ .mui-content
+{
+    padding-bottom: 88px;
+}
+.mui-bar-footer-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 88px;
+}
+
+.mui-bar-tab ~ .mui-content
+{
+    padding-bottom: 50px;
+}
+.mui-bar-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 50px;
+}
+
+.mui-bar-footer-secondary-tab ~ .mui-content
+{
+    padding-bottom: 94px;
+}
+.mui-bar-footer-secondary-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 94px;
+}
+
+.mui-content-padded
+{
+    margin: 10px;
+}
+
+.mui-inline
+{
+    display: inline-block;
+
+    vertical-align: top;
+}
+
+.mui-block
+{
+    display: block !important;
+}
+
+.mui-visibility
+{
+    visibility: visible !important;
+}
+
+.mui-hidden
+{
+    display: none !important;
+}
+
+.mui-ellipsis
+{
+    overflow: hidden;
+
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.mui-ellipsis-2
+{
+    display: -webkit-box;
+    overflow: hidden;
+
+    white-space: normal !important;
+    text-overflow: ellipsis;
+    word-wrap: break-word;
+
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+}
+
+.mui-table
+{
+    display: table;
+
+    width: 100%;
+
+    table-layout: fixed;
+}
+
+.mui-table-cell
+{
+    position: relative;
+
+    display: table-cell;
+}
+
+.mui-text-left
+{
+    text-align: left !important;
+}
+
+.mui-text-center
+{
+    text-align: center !important;
+}
+
+.mui-text-justify
+{
+    text-align: justify !important;
+}
+
+.mui-text-right
+{
+    text-align: right !important;
+}
+
+.mui-pull-left
+{
+    float: left;
+}
+
+.mui-pull-right
+{
+    float: right;
+}
+
+.mui-list-unstyled
+{
+    padding-left: 0;
+
+    list-style: none;
+}
+
+.mui-list-inline
+{
+    margin-left: -5px;
+    padding-left: 0;
+
+    list-style: none;
+}
+
+.mui-list-inline > li
+{
+    display: inline-block;
+
+    padding-right: 5px;
+    padding-left: 5px;
+}
+
+.mui-clearfix:before, .mui-clearfix:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-clearfix:after
+{
+    clear: both;
+}
+
+.mui-bg-primary
+{
+    background-color: #007aff;
+}
+
+.mui-bg-positive
+{
+    background-color: #4cd964;
+}
+
+.mui-bg-negative
+{
+    background-color: #dd524d;
+}
+
+.mui-error
+{
+    margin: 88px 35px;
+    padding: 10px;
+
+    border-radius: 6px;
+    background-color: #bbb;
+}
+
+.mui-subtitle
+{
+    font-size: 15px;
+}
+
+h1, h2, h3, h4, h5, h6
+{
+    line-height: 1;
+
+    margin-top: 5px;
+    margin-bottom: 5px;
+}
+
+h1, .mui-h1
+{
+    font-size: 36px;
+}
+
+h2, .mui-h2
+{
+    font-size: 30px;
+}
+
+h3, .mui-h3
+{
+    font-size: 24px;
+}
+
+h4, .mui-h4
+{
+    font-size: 18px;
+}
+
+h5, .mui-h5
+{
+    font-size: 14px;
+    font-weight: normal;
+
+    color: #8f8f94;
+}
+
+h6, .mui-h6
+{
+    font-size: 12px;
+    font-weight: normal;
+
+    color: #8f8f94;
+}
+
+p
+{
+    font-size: 14px;
+
+    margin-top: 0;
+    margin-bottom: 10px;
+
+    color: #8f8f94;
+}
+
+.mui-row:before, .mui-row:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-row:after
+{
+    clear: both;
+}
+
+.mui-col-xs-1, .mui-col-sm-1, .mui-col-xs-2, .mui-col-sm-2, .mui-col-xs-3, .mui-col-sm-3, .mui-col-xs-4, .mui-col-sm-4, .mui-col-xs-5, .mui-col-sm-5, .mui-col-xs-6, .mui-col-sm-6, .mui-col-xs-7, .mui-col-sm-7, .mui-col-xs-8, .mui-col-sm-8, .mui-col-xs-9, .mui-col-sm-9, .mui-col-xs-10, .mui-col-sm-10, .mui-col-xs-11, .mui-col-sm-11, .mui-col-xs-12, .mui-col-sm-12
+{
+    position: relative;
+
+    min-height: 1px;
+}
+
+.mui-row > [class*='mui-col-']
+{
+    float: left;
+}
+
+.mui-col-xs-12
+{
+    width: 100%;
+}
+
+.mui-col-xs-11
+{
+    width: 91.66666667%;
+}
+
+.mui-col-xs-10
+{
+    width: 83.33333333%;
+}
+
+.mui-col-xs-9
+{
+    width: 75%;
+}
+
+.mui-col-xs-8
+{
+    width: 66.66666667%;
+}
+
+.mui-col-xs-7
+{
+    width: 58.33333333%;
+}
+
+.mui-col-xs-6
+{
+    width: 50%;
+}
+
+.mui-col-xs-5
+{
+    width: 41.66666667%;
+}
+
+.mui-col-xs-4
+{
+    width: 33.33333333%;
+}
+
+.mui-col-xs-3
+{
+    width: 25%;
+}
+
+.mui-col-xs-2
+{
+    width: 16.66666667%;
+}
+
+.mui-col-xs-1
+{
+    width: 8.33333333%;
+}
+
+@media (min-width: 400px)
+{
+    .mui-col-sm-12
+    {
+        width: 100%;
+    }
+
+    .mui-col-sm-11
+    {
+        width: 91.66666667%;
+    }
+
+    .mui-col-sm-10
+    {
+        width: 83.33333333%;
+    }
+
+    .mui-col-sm-9
+    {
+        width: 75%;
+    }
+
+    .mui-col-sm-8
+    {
+        width: 66.66666667%;
+    }
+
+    .mui-col-sm-7
+    {
+        width: 58.33333333%;
+    }
+
+    .mui-col-sm-6
+    {
+        width: 50%;
+    }
+
+    .mui-col-sm-5
+    {
+        width: 41.66666667%;
+    }
+
+    .mui-col-sm-4
+    {
+        width: 33.33333333%;
+    }
+
+    .mui-col-sm-3
+    {
+        width: 25%;
+    }
+
+    .mui-col-sm-2
+    {
+        width: 16.66666667%;
+    }
+
+    .mui-col-sm-1
+    {
+        width: 8.33333333%;
+    }
+}
+.mui-scroll-wrapper
+{
+    position: absolute;
+    z-index: 2;
+    top: 0;
+    bottom: 0;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+
+.mui-scroll
+{
+    position: absolute;
+    z-index: 1;
+
+    width: 100%;
+}
+
+.mui-scrollbar
+{
+    position: absolute;
+    z-index: 9998;
+
+    overflow: hidden;
+
+    -webkit-transition: 500ms;
+            transition: 500ms;
+    transform: translateZ(0px);
+    pointer-events: none;
+
+    opacity: 0;
+}
+
+.mui-scrollbar-vertical
+{
+    top: 0;
+    right: 1px;
+    bottom: 2px;
+
+    width: 4px;
+}
+.mui-scrollbar-vertical .mui-scrollbar-indicator
+{
+    width: 100%;
+}
+
+.mui-scrollbar-horizontal
+{
+    right: 2px;
+    bottom: 0;
+    left: 2px;
+
+    height: 4px;
+}
+.mui-scrollbar-horizontal .mui-scrollbar-indicator
+{
+    height: 100%;
+}
+
+.mui-scrollbar-indicator
+{
+    position: absolute;
+
+    display: block;
+
+    box-sizing: border-box;
+
+    -webkit-transition: .01s cubic-bezier(.1, .57, .1, 1);
+            transition: .01s cubic-bezier(.1, .57, .1, 1);
+    transform: translate(0px, 0px) translateZ(0px);
+
+    border: 1px solid rgba(255, 255, 255, .80196);
+    border-radius: 2px;
+    background: rgba(0, 0, 0, .39804);
+}
+
+.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper
+{
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll
+{
+    position: absolute;
+
+    width: 100%;
+}
+.mui-plus-pullrefresh .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-slider-group
+{
+    position: static;
+    top: auto;
+    bottom: auto;
+    left: auto;
+
+    overflow: auto;
+
+    width: auto;
+}
+.mui-plus-pullrefresh .mui-slider-group
+{
+    overflow: visible;
+}
+.mui-plus-pullrefresh .mui-scroll
+{
+    position: static;
+
+    width: auto;
+}
+
+.mui-off-canvas-wrap .mui-bar
+{
+    position: absolute !important;
+
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-off-canvas-wrap
+{
+    position: relative;
+    z-index: 1;
+
+    overflow: hidden;
+
+    width: 100%;
+    height: 100%;
+}
+.mui-off-canvas-wrap .mui-inner-wrap
+{
+    position: relative;
+    z-index: 1;
+
+    width: 100%;
+    height: 100%;
+}
+.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms;
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1);
+}
+.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left
+{
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+}
+.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right
+{
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+}
+.mui-off-canvas-wrap.mui-active
+{
+    overflow: hidden;
+
+    height: 100%;
+}
+.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop
+{
+    position: absolute;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    display: block;
+
+    transition: background 350ms cubic-bezier(.165, .84, .44, 1);
+
+    background: rgba(0, 0, 0, .4);
+    box-shadow: -4px 0 4px rgba(0, 0, 0, .5), 4px 0 4px rgba(0, 0, 0, .5);
+
+    -webkit-tap-highlight-color: transparent;
+}
+.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right
+{
+    z-index: 10000 !important;
+
+    -webkit-transform: translate3d(100%, 0px, 0px);
+}
+.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left
+{
+    z-index: 10000 !important;
+
+    -webkit-transform: translate3d(-100%, 0px, 0px);
+}
+
+.mui-off-canvas-left, .mui-off-canvas-right
+{
+    position: absolute;
+    z-index: -1;
+    top: 0;
+    bottom: 0;
+
+    visibility: hidden;
+
+    box-sizing: content-box;
+    width: 70%;
+    min-height: 100%;
+
+    background: #333;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-off-canvas-left.mui-transitioning, .mui-off-canvas-right.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1);
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1);
+}
+
+.mui-off-canvas-left
+{
+    left: 0;
+}
+
+.mui-off-canvas-right
+{
+    right: 0;
+}
+
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable
+{
+    background-color: #333;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
+{
+    width: 80%;
+
+    -webkit-transform: scale(.8);
+            transform: scale(.8);
+
+    opacity: .1;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left.mui-transitioning, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left
+{
+    -webkit-transform-origin: -100%;
+            transform-origin: -100%;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
+{
+    -webkit-transform-origin: 200%;
+            transform-origin: 200%;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-inner-wrap
+{
+    -webkit-transform: scale(.8);
+            transform: scale(.8);
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-right
+{
+    -webkit-transform: scale(1);
+            transform: scale(1);
+
+    opacity: 1;
+}
+
+.mui-loading .mui-spinner
+{
+    display: block;
+
+    margin: 0 auto;
+}
+
+.mui-spinner
+{
+    display: inline-block;
+
+    width: 24px;
+    height: 24px;
+
+    -webkit-transform-origin: 50%;
+            transform-origin: 50%;
+    -webkit-animation: spinner-spin 1s step-end infinite;
+            animation: spinner-spin 1s step-end infinite;
+}
+
+.mui-spinner:after
+{
+    display: block;
+
+    width: 100%;
+    height: 100%;
+
+    content: '';
+
+    background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%236c6c6c\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');
+    background-repeat: no-repeat;
+    background-position: 50%;
+    background-size: 100%;
+}
+
+.mui-spinner-white:after
+{
+    background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%23fff\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');
+}
+
+@-webkit-keyframes spinner-spin
+{
+    0%
+    {
+        -webkit-transform: rotate(0deg);
+    }
+
+    8.33333333%
+    {
+        -webkit-transform: rotate(30deg);
+    }
+
+    16.66666667%
+    {
+        -webkit-transform: rotate(60deg);
+    }
+
+    25%
+    {
+        -webkit-transform: rotate(90deg);
+    }
+
+    33.33333333%
+    {
+        -webkit-transform: rotate(120deg);
+    }
+
+    41.66666667%
+    {
+        -webkit-transform: rotate(150deg);
+    }
+
+    50%
+    {
+        -webkit-transform: rotate(180deg);
+    }
+
+    58.33333333%
+    {
+        -webkit-transform: rotate(210deg);
+    }
+
+    66.66666667%
+    {
+        -webkit-transform: rotate(240deg);
+    }
+
+    75%
+    {
+        -webkit-transform: rotate(270deg);
+    }
+
+    83.33333333%
+    {
+        -webkit-transform: rotate(300deg);
+    }
+
+    91.66666667%
+    {
+        -webkit-transform: rotate(330deg);
+    }
+
+    100%
+    {
+        -webkit-transform: rotate(360deg);
+    }
+}
+@keyframes spinner-spin
+{
+    0%
+    {
+        transform: rotate(0deg);
+    }
+
+    8.33333333%
+    {
+        transform: rotate(30deg);
+    }
+
+    16.66666667%
+    {
+        transform: rotate(60deg);
+    }
+
+    25%
+    {
+        transform: rotate(90deg);
+    }
+
+    33.33333333%
+    {
+        transform: rotate(120deg);
+    }
+
+    41.66666667%
+    {
+        transform: rotate(150deg);
+    }
+
+    50%
+    {
+        transform: rotate(180deg);
+    }
+
+    58.33333333%
+    {
+        transform: rotate(210deg);
+    }
+
+    66.66666667%
+    {
+        transform: rotate(240deg);
+    }
+
+    75%
+    {
+        transform: rotate(270deg);
+    }
+
+    83.33333333%
+    {
+        transform: rotate(300deg);
+    }
+
+    91.66666667%
+    {
+        transform: rotate(330deg);
+    }
+
+    100%
+    {
+        transform: rotate(360deg);
+    }
+}
+input[type='button'],
+input[type='submit'],
+input[type='reset'],
+button,
+.mui-btn
+{
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 1.42;
+
+    position: relative;
+
+    display: inline-block;
+
+    margin-bottom: 0;
+    padding: 6px 12px;
+
+    cursor: pointer;
+    -webkit-transition: all;
+            transition: all;
+    -webkit-transition-timing-function: linear;
+            transition-timing-function: linear;
+    -webkit-transition-duration: .2s;
+            transition-duration: .2s;
+    text-align: center;
+    vertical-align: top;
+    white-space: nowrap;
+
+    color: #333;
+    border: 1px solid #ccc;
+    border-radius: 3px;
+    border-top-left-radius: 3px;
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+    border-bottom-left-radius: 3px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+input[type='button']:enabled:active, input[type='button'].mui-active:enabled,
+input[type='submit']:enabled:active,
+input[type='submit'].mui-active:enabled,
+input[type='reset']:enabled:active,
+input[type='reset'].mui-active:enabled,
+button:enabled:active,
+button.mui-active:enabled,
+.mui-btn:enabled:active,
+.mui-btn.mui-active:enabled
+{
+    color: #fff;
+    background-color: #929292;
+}
+input[type='button']:disabled, input[type='button'].mui-disabled,
+input[type='submit']:disabled,
+input[type='submit'].mui-disabled,
+input[type='reset']:disabled,
+input[type='reset'].mui-disabled,
+button:disabled,
+button.mui-disabled,
+.mui-btn:disabled,
+.mui-btn.mui-disabled
+{
+    opacity: .6;
+}
+
+input[type='submit'],
+.mui-btn-primary,
+.mui-btn-blue
+{
+    color: #fff;
+    border: 1px solid #007aff;
+    background-color: #007aff;
+}
+input[type='submit']:enabled:active, input[type='submit'].mui-active:enabled,
+.mui-btn-primary:enabled:active,
+.mui-btn-primary.mui-active:enabled,
+.mui-btn-blue:enabled:active,
+.mui-btn-blue.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #0062cc;
+    background-color: #0062cc;
+}
+
+.mui-btn-positive,
+.mui-btn-success,
+.mui-btn-green
+{
+    color: #fff;
+    border: 1px solid #4cd964;
+    background-color: #4cd964;
+}
+.mui-btn-positive:enabled:active, .mui-btn-positive.mui-active:enabled,
+.mui-btn-success:enabled:active,
+.mui-btn-success.mui-active:enabled,
+.mui-btn-green:enabled:active,
+.mui-btn-green.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #2ac845;
+    background-color: #2ac845;
+}
+
+.mui-btn-warning,
+.mui-btn-yellow
+{
+    color: #fff;
+    border: 1px solid #f0ad4e;
+    background-color: #f0ad4e;
+}
+.mui-btn-warning:enabled:active, .mui-btn-warning.mui-active:enabled,
+.mui-btn-yellow:enabled:active,
+.mui-btn-yellow.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #ec971f;
+    background-color: #ec971f;
+}
+
+.mui-btn-negative,
+.mui-btn-danger,
+.mui-btn-red
+{
+    color: #fff;
+    border: 1px solid #dd524d;
+    background-color: #dd524d;
+}
+.mui-btn-negative:enabled:active, .mui-btn-negative.mui-active:enabled,
+.mui-btn-danger:enabled:active,
+.mui-btn-danger.mui-active:enabled,
+.mui-btn-red:enabled:active,
+.mui-btn-red.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #cf2d28;
+    background-color: #cf2d28;
+}
+
+.mui-btn-royal,
+.mui-btn-purple
+{
+    color: #fff;
+    border: 1px solid #8a6de9;
+    background-color: #8a6de9;
+}
+.mui-btn-royal:enabled:active, .mui-btn-royal.mui-active:enabled,
+.mui-btn-purple:enabled:active,
+.mui-btn-purple.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #6641e2;
+    background-color: #6641e2;
+}
+
+.mui-btn-grey
+{
+    color: #fff;
+    border: 1px solid #c7c7cc;
+    background-color: #c7c7cc;
+}
+.mui-btn-grey:enabled:active, .mui-btn-grey.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #acacb4;
+    background-color: #acacb4;
+}
+
+.mui-btn-outlined
+{
+    background-color: transparent;
+}
+.mui-btn-outlined.mui-btn-primary, .mui-btn-outlined.mui-btn-blue
+{
+    color: #007aff;
+}
+.mui-btn-outlined.mui-btn-positive, .mui-btn-outlined.mui-btn-success, .mui-btn-outlined.mui-btn-green
+{
+    color: #4cd964;
+}
+.mui-btn-outlined.mui-btn-warning, .mui-btn-outlined.mui-btn-yellow
+{
+    color: #f0ad4e;
+}
+.mui-btn-outlined.mui-btn-negative, .mui-btn-outlined.mui-btn-danger, .mui-btn-outlined.mui-btn-red
+{
+    color: #dd524d;
+}
+.mui-btn-outlined.mui-btn-royal, .mui-btn-outlined.mui-btn-purple
+{
+    color: #8a6de9;
+}
+.mui-btn-outlined.mui-btn-primary:enabled:active, .mui-btn-outlined.mui-btn-blue:enabled:active, .mui-btn-outlined.mui-btn-positive:enabled:active, .mui-btn-outlined.mui-btn-success:enabled:active, .mui-btn-outlined.mui-btn-green:enabled:active, .mui-btn-outlined.mui-btn-warning:enabled:active, .mui-btn-outlined.mui-btn-yellow:enabled:active, .mui-btn-outlined.mui-btn-negative:enabled:active, .mui-btn-outlined.mui-btn-danger:enabled:active, .mui-btn-outlined.mui-btn-red:enabled:active, .mui-btn-outlined.mui-btn-royal:enabled:active, .mui-btn-outlined.mui-btn-purple:enabled:active
+{
+    color: #fff;
+}
+
+.mui-btn-link
+{
+    padding-top: 6px;
+    padding-bottom: 6px;
+
+    color: #007aff;
+    border: 0;
+    background-color: transparent;
+}
+.mui-btn-link:enabled:active, .mui-btn-link.mui-active:enabled
+{
+    color: #0062cc;
+    background-color: transparent;
+}
+
+.mui-btn-block
+{
+    font-size: 18px;
+
+    display: block;
+
+    width: 100%;
+    margin-bottom: 10px;
+    padding: 15px 0;
+}
+
+.mui-btn .mui-badge
+{
+    font-size: 14px;
+
+    margin: -2px -4px -2px 4px;
+
+    background-color: rgba(0, 0, 0, .15);
+}
+
+.mui-btn .mui-badge-inverted,
+.mui-btn:enabled:active .mui-badge-inverted
+{
+    background-color: transparent;
+}
+
+.mui-btn-primary:enabled:active .mui-badge-inverted,
+.mui-btn-positive:enabled:active .mui-badge-inverted,
+.mui-btn-negative:enabled:active .mui-badge-inverted
+{
+    color: #fff;
+}
+
+.mui-btn-block .mui-badge
+{
+    position: absolute;
+    right: 0;
+
+    margin-right: 10px;
+}
+
+.mui-btn .mui-icon
+{
+    font-size: inherit;
+}
+
+.mui-btn.mui-icon
+{
+    font-size: 14px;
+    line-height: 1.42;
+}
+
+.mui-btn.mui-fab
+{
+    width: 56px;
+    height: 56px;
+    padding: 16px;
+
+    border-radius: 50%;
+    outline: none;
+}
+.mui-btn.mui-fab.mui-btn-mini
+{
+    width: 40px;
+    height: 40px;
+    padding: 8px;
+}
+.mui-btn.mui-fab .mui-icon
+{
+    font-size: 24px;
+    line-height: 24px;
+
+    width: 24px;
+    height: 24px;
+}
+
+.mui-btn .mui-spinner
+{
+    width: 14px;
+    height: 14px;
+
+    vertical-align: text-bottom;
+}
+
+.mui-btn-block .mui-spinner
+{
+    width: 22px;
+    height: 22px;
+}
+
+.mui-bar
+{
+    position: fixed;
+    z-index: 10;
+    right: 0;
+    left: 0;
+
+    height: 44px;
+    padding-right: 10px;
+    padding-left: 10px;
+
+    border-bottom: 0;
+    background-color: #f7f7f7;
+    -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .85);
+            box-shadow: 0 0 1px rgba(0, 0, 0, .85);
+
+    -webkit-backface-visibility: hidden;
+            backface-visibility: hidden;
+}
+
+.mui-bar .mui-title
+{
+    right: 40px;
+    left: 40px;
+
+    display: inline-block;
+    overflow: hidden;
+
+    width: auto;
+    margin: 0;
+
+    text-overflow: ellipsis;
+}
+.mui-bar .mui-backdrop
+{
+    background: none;
+}
+
+.mui-bar-header-secondary
+{
+    top: 44px;
+}
+
+.mui-bar-footer
+{
+    bottom: 0;
+}
+
+.mui-bar-footer-secondary
+{
+    bottom: 44px;
+}
+
+.mui-bar-footer-secondary-tab
+{
+    bottom: 50px;
+}
+
+.mui-bar-footer,
+.mui-bar-footer-secondary,
+.mui-bar-footer-secondary-tab
+{
+    border-top: 0;
+}
+
+.mui-bar-transparent
+{
+    top: 0;
+
+    background-color: rgba(247, 247, 247, 0);
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-bar-nav
+{
+    top: 0;
+
+    -webkit-box-shadow: 0 1px 6px #ccc;
+            box-shadow: 0 1px 6px #ccc;
+}
+.mui-bar-nav ~ .mui-content .mui-anchor
+{
+    display: block;
+    visibility: hidden;
+
+    height: 45px;
+    margin-top: -45px;
+}
+.mui-bar-nav.mui-bar .mui-icon
+{
+    margin-right: -10px;
+    margin-left: -10px;
+    padding-right: 10px;
+    padding-left: 10px;
+}
+
+.mui-title
+{
+    font-size: 17px;
+    font-weight: 500;
+    line-height: 44px;
+
+    position: absolute;
+
+    display: block;
+
+    width: 100%;
+    margin: 0 -10px;
+    padding: 0;
+
+    text-align: center;
+    white-space: nowrap;
+
+    color: #000;
+}
+
+.mui-title a
+{
+    color: inherit;
+}
+
+.mui-bar-tab
+{
+    bottom: 0;
+
+    display: table;
+
+    width: 100%;
+    height: 50px;
+    padding: 0;
+
+    table-layout: fixed;
+
+    border-top: 0;
+    border-bottom: 0;
+
+    -webkit-touch-callout: none;
+}
+.mui-bar-tab .mui-tab-item
+{
+    display: table-cell;
+    overflow: hidden;
+
+    width: 1%;
+    height: 50px;
+
+    text-align: center;
+    vertical-align: middle;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #929292;
+}
+.mui-bar-tab .mui-tab-item.mui-active
+{
+    color: #007aff;
+}
+.mui-bar-tab .mui-tab-item .mui-icon
+{
+    top: 3px;
+
+    width: 24px;
+    height: 24px;
+    padding-top: 0;
+    padding-bottom: 0;
+}
+.mui-bar-tab .mui-tab-item .mui-icon ~ .mui-tab-label
+{
+    font-size: 11px;
+
+    display: block;
+    overflow: hidden;
+
+    text-overflow: ellipsis;
+}
+.mui-bar-tab .mui-tab-item .mui-icon:active
+{
+    background: none;
+}
+
+.mui-focusin > .mui-bar-nav,
+.mui-focusin > .mui-bar-header-secondary
+{
+    position: absolute;
+}
+
+.mui-focusin > .mui-bar ~ .mui-content
+{
+    padding-bottom: 0;
+}
+
+.mui-bar .mui-btn
+{
+    font-weight: 400;
+
+    position: relative;
+    z-index: 20;
+    top: 7px;
+
+    margin-top: 0;
+    padding: 6px 12px 7px;
+}
+.mui-bar .mui-btn.mui-pull-right
+{
+    margin-left: 10px;
+}
+.mui-bar .mui-btn.mui-pull-left
+{
+    margin-right: 10px;
+}
+
+.mui-bar .mui-btn-link
+{
+    font-size: 16px;
+    line-height: 44px;
+
+    top: 0;
+
+    padding: 0;
+
+    color: #007aff;
+    border: 0;
+}
+.mui-bar .mui-btn-link:active, .mui-bar .mui-btn-link.mui-active
+{
+    color: #0062cc;
+}
+
+.mui-bar .mui-btn-block
+{
+    font-size: 16px;
+
+    top: 6px;
+
+    margin-bottom: 0;
+    padding: 5px 0;
+}
+
+.mui-bar .mui-btn-nav.mui-pull-left
+{
+    margin-left: -5px;
+}
+.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav
+{
+    margin-right: -3px;
+}
+.mui-bar .mui-btn-nav.mui-pull-right
+{
+    margin-right: -5px;
+}
+.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav
+{
+    margin-left: -3px;
+}
+.mui-bar .mui-btn-nav:active
+{
+    opacity: .3;
+}
+
+.mui-bar .mui-icon
+{
+    font-size: 24px;
+
+    position: relative;
+    z-index: 20;
+
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+.mui-bar .mui-icon:active
+{
+    opacity: .3;
+}
+.mui-bar .mui-btn .mui-icon
+{
+    top: 1px;
+
+    margin: 0;
+    padding: 0;
+}
+.mui-bar .mui-title .mui-icon
+{
+    margin: 0;
+    padding: 0;
+}
+.mui-bar .mui-title .mui-icon.mui-icon-caret
+{
+    top: 4px;
+
+    margin-left: -5px;
+}
+
+.mui-bar input[type='search']
+{
+    height: 29px;
+    margin: 6px 0;
+}
+
+.mui-bar .mui-input-row .mui-btn
+{
+    padding: 12px 10px;
+}
+
+.mui-bar .mui-search:before
+{
+    margin-top: -10px;
+}
+
+.mui-bar .mui-input-row .mui-input-clear ~ .mui-icon-clear,
+.mui-bar .mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    top: 0;
+    right: 12px;
+}
+
+.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear ~ .mui-icon-clear,
+.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    top: 0;
+    right: 0;
+}
+
+.mui-bar .mui-segmented-control
+{
+    top: 7px;
+
+    width: auto;
+    margin: 0 auto;
+}
+
+.mui-bar.mui-bar-header-secondary .mui-segmented-control
+{
+    top: 0;
+}
+
+.mui-badge
+{
+    font-size: 12px;
+    line-height: 1;
+
+    display: inline-block;
+
+    padding: 3px 6px;
+
+    color: #333;
+    border-radius: 100px;
+    background-color: rgba(0, 0, 0, .15);
+}
+.mui-badge.mui-badge-inverted
+{
+    padding: 0 5px 0 0;
+
+    color: #929292;
+    background-color: transparent;
+}
+
+.mui-badge-primary, .mui-badge-blue
+{
+    color: #fff;
+    background-color: #007aff;
+}
+.mui-badge-primary.mui-badge-inverted, .mui-badge-blue.mui-badge-inverted
+{
+    color: #007aff;
+    background-color: transparent;
+}
+
+.mui-badge-success, .mui-badge-green
+{
+    color: #fff;
+    background-color: #4cd964;
+}
+.mui-badge-success.mui-badge-inverted, .mui-badge-green.mui-badge-inverted
+{
+    color: #4cd964;
+    background-color: transparent;
+}
+
+.mui-badge-warning, .mui-badge-yellow
+{
+    color: #fff;
+    background-color: #f0ad4e;
+}
+.mui-badge-warning.mui-badge-inverted, .mui-badge-yellow.mui-badge-inverted
+{
+    color: #f0ad4e;
+    background-color: transparent;
+}
+
+.mui-badge-danger, .mui-badge-red
+{
+    color: #fff;
+    background-color: #dd524d;
+}
+.mui-badge-danger.mui-badge-inverted, .mui-badge-red.mui-badge-inverted
+{
+    color: #dd524d;
+    background-color: transparent;
+}
+
+.mui-badge-royal, .mui-badge-purple
+{
+    color: #fff;
+    background-color: #8a6de9;
+}
+.mui-badge-royal.mui-badge-inverted, .mui-badge-purple.mui-badge-inverted
+{
+    color: #8a6de9;
+    background-color: transparent;
+}
+
+.mui-icon .mui-badge
+{
+    font-size: 10px;
+    line-height: 1.4;
+
+    position: absolute;
+    top: -2px;
+    left: 100%;
+
+    margin-left: -10px;
+    padding: 1px 5px;
+
+    color: white;
+    background: red;
+}
+
+.mui-card
+{
+    font-size: 14px;
+
+    position: relative;
+
+    overflow: hidden;
+
+    margin: 10px;
+
+    border-radius: 2px;
+    background-color: white;
+    background-clip: padding-box;
+    box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
+}
+
+.mui-content > .mui-card:first-child
+{
+    margin-top: 15px;
+}
+
+.mui-card .mui-input-group:before, .mui-card .mui-input-group:after
+{
+    height: 0;
+}
+.mui-card .mui-input-group .mui-input-row:last-child:before, .mui-card .mui-input-group .mui-input-row:last-child:after
+{
+    height: 0;
+}
+
+.mui-card .mui-table-view
+{
+    margin-bottom: 0;
+
+    border-top: 0;
+    border-bottom: 0;
+    border-radius: 6px;
+}
+.mui-card .mui-table-view .mui-table-view-divider:first-child, .mui-card .mui-table-view .mui-table-view-cell:first-child
+{
+    top: 0;
+
+    border-top-left-radius: 6px;
+    border-top-right-radius: 6px;
+}
+.mui-card .mui-table-view .mui-table-view-divider:last-child, .mui-card .mui-table-view .mui-table-view-cell:last-child
+{
+    border-bottom-right-radius: 6px;
+    border-bottom-left-radius: 6px;
+}
+.mui-card .mui-table-view:before, .mui-card .mui-table-view:after
+{
+    height: 0;
+}
+
+.mui-card > .mui-table-view > .mui-table-view-cell:last-child:before, .mui-card > .mui-table-view > .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+
+.mui-card-header,
+.mui-card-footer
+{
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    min-height: 44px;
+    padding: 10px 15px;
+
+    -webkit-box-pack: justify;
+    -webkit-justify-content: space-between;
+            justify-content: space-between;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+.mui-card-header .mui-card-link,
+.mui-card-footer .mui-card-link
+{
+    line-height: 44px;
+
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 44px;
+    margin-top: -10px;
+    margin-bottom: -10px;
+
+    -webkit-transition-duration: .3s;
+            transition-duration: .3s;
+    text-decoration: none;
+
+    -webkit-box-pack: start;
+    -webkit-justify-content: flex-start;
+            justify-content: flex-start;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+
+.mui-card-header:after,
+.mui-card-footer:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-card-header
+{
+    font-size: 17px;
+
+    border-radius: 2px 2px 0 0;
+}
+.mui-card-header:after
+{
+    top: auto;
+    bottom: 0;
+}
+.mui-card-header > img:first-child
+{
+    font-size: 0;
+    line-height: 0;
+
+    float: left;
+
+    width: 34px;
+    height: 34px;
+}
+
+.mui-card-footer
+{
+    color: #6d6d72;
+    border-radius: 0 0 2px 2px;
+}
+
+.mui-card-content
+{
+    font-size: 14px;
+
+    position: relative;
+}
+
+.mui-card-content-inner
+{
+    position: relative;
+
+    padding: 15px;
+}
+
+.mui-card-media
+{
+    vertical-align: bottom;
+
+    color: #fff;
+    background-position: center;
+    background-size: cover;
+}
+
+.mui-card-header.mui-card-media
+{
+    display: block;
+
+    padding: 10px;
+}
+.mui-card-header.mui-card-media .mui-media-body
+{
+    font-size: 14px;
+    font-weight: 500;
+    line-height: 17px;
+
+    margin-bottom: 0;
+    margin-left: 44px;
+
+    color: #333;
+}
+.mui-card-header.mui-card-media .mui-media-body p
+{
+    font-size: 13px;
+
+    margin-bottom: 0;
+}
+
+.mui-table-view
+{
+    position: relative;
+
+    margin-top: 0;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    list-style: none;
+
+    background-color: #fff;
+}
+.mui-table-view:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view:before
+{
+    top: -1px;
+}
+
+.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon
+{
+    font-size: 20px;
+
+    margin-top: -1px;
+    margin-right: 5px;
+    margin-left: -5px;
+}
+.mui-table-view-icon .mui-table-view-cell:after
+{
+    left: 40px;
+}
+
+.mui-table-view-chevron .mui-table-view-cell
+{
+    padding-right: 65px;
+}
+.mui-table-view-chevron .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin-right: -65px;
+}
+
+.mui-table-view-radio .mui-table-view-cell
+{
+    padding-right: 65px;
+}
+.mui-table-view-radio .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin-right: -65px;
+}
+.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after
+{
+    font-size: 30px;
+    font-weight: 600;
+
+    right: 9px;
+
+    content: '';
+
+    color: #007aff;
+}
+.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after
+{
+    content: '\e472';
+}
+
+.mui-table-view-inverted
+{
+    color: #fff;
+    background: #333;
+}
+.mui-table-view-inverted:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted .mui-table-view-cell.mui-active
+{
+    background-color: #242424;
+}
+.mui-table-view-inverted .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background-color: #242424;
+}
+
+.mui-table-view-cell
+{
+    position: relative;
+
+    overflow: hidden;
+
+    padding: 11px 15px;
+
+    -webkit-touch-callout: none;
+}
+.mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view-cell.mui-radio input[type=radio], .mui-table-view-cell.mui-checkbox input[type=checkbox]
+{
+    top: 8px;
+}
+.mui-table-view-cell.mui-radio.mui-left, .mui-table-view-cell.mui-checkbox.mui-left
+{
+    padding-left: 58px;
+}
+.mui-table-view-cell.mui-active
+{
+    background-color: #eee;
+}
+.mui-table-view-cell:last-child:before, .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+.mui-table-view-cell > a:not(.mui-btn)
+{
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    margin: -11px -15px;
+    padding: inherit;
+
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: inherit;
+  /*&:active {
+      background-color: #eee;
+  }*/
+}
+.mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background-color: #eee;
+}
+.mui-table-view-cell p
+{
+    margin-bottom: 0;
+}
+
+.mui-table-view-cell.mui-transitioning > .mui-slider-handle, .mui-table-view-cell.mui-transitioning > .mui-slider-left .mui-btn, .mui-table-view-cell.mui-transitioning > .mui-slider-right .mui-btn
+{
+    -webkit-transition: -webkit-transform 300ms ease;
+            transition:         transform 300ms ease;
+}
+.mui-table-view-cell.mui-active > .mui-slider-handle
+{
+    background-color: #eee;
+}
+.mui-table-view-cell > .mui-slider-handle
+{
+    position: relative;
+
+    background-color: #fff;
+}
+.mui-table-view-cell > .mui-slider-handle.mui-navigate-right:after, .mui-table-view-cell > .mui-slider-handle .mui-navigate-right:after
+{
+    right: 0;
+}
+.mui-table-view-cell > .mui-slider-handle, .mui-table-view-cell > .mui-slider-left .mui-btn, .mui-table-view-cell > .mui-slider-right .mui-btn
+{
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+}
+.mui-table-view-cell > .mui-slider-left, .mui-table-view-cell > .mui-slider-right
+{
+    position: absolute;
+    top: 0;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 100%;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn, .mui-table-view-cell > .mui-slider-right > .mui-btn
+{
+    position: relative;
+    left: 0;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    padding: 0 30px;
+
+    color: #fff;
+    border: 0;
+    border-radius: 0;
+
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn:after, .mui-table-view-cell > .mui-slider-right > .mui-btn:after
+{
+    position: absolute;
+    z-index: -1;
+    top: 0;
+
+    width: 600%;
+    height: 100%;
+
+    content: '';
+
+    background: inherit;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn.mui-icon, .mui-table-view-cell > .mui-slider-right > .mui-btn.mui-icon
+{
+    font-size: 30px;
+}
+.mui-table-view-cell > .mui-slider-right
+{
+    right: 0;
+
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+    -webkit-transform: translateX(100%);
+            transform: translateX(100%);
+}
+.mui-table-view-cell > .mui-slider-left
+{
+    left: 0;
+
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+    -webkit-transform: translateX(-100%);
+            transform: translateX(-100%);
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn:after
+{
+    right: 100%;
+
+    margin-right: -1px;
+}
+
+.mui-table-view-divider
+{
+    font-weight: 500;
+
+    position: relative;
+
+    margin-top: -1px;
+    margin-left: 0;
+    padding-top: 6px;
+    padding-bottom: 6px;
+    padding-left: 15px;
+
+    color: #999;
+    background-color: #fafafa;
+}
+.mui-table-view-divider:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view-divider:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view .mui-media,
+.mui-table-view .mui-media-body
+{
+    overflow: hidden;
+}
+
+.mui-table-view .mui-media-large .mui-media-object
+{
+    line-height: 80px;
+
+    max-width: 80px;
+    height: 80px;
+}
+.mui-table-view .mui-media .mui-subtitle
+{
+    color: #000;
+}
+.mui-table-view .mui-media-object
+{
+    line-height: 42px;
+
+    max-width: 42px;
+    height: 42px;
+}
+.mui-table-view .mui-media-object.mui-pull-left
+{
+    margin-right: 10px;
+}
+.mui-table-view .mui-media-object.mui-pull-right
+{
+    margin-left: 10px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object
+{
+    line-height: 29px;
+
+    max-width: 29px;
+    height: 29px;
+    margin: -4px 0;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img
+{
+    line-height: 29px;
+
+    max-width: 29px;
+    height: 29px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left
+{
+    margin-right: 10px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon
+{
+    font-size: 29px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 55px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon:after
+{
+    height: 0 !important;
+}
+
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view
+{
+    display: block;
+}
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after
+{
+    height: 0 !important;
+}
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 70px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view-cell > .mui-btn,
+.mui-table-view-cell > .mui-badge,
+.mui-table-view-cell > .mui-switch,
+.mui-table-view-cell > a > .mui-btn,
+.mui-table-view-cell > a > .mui-badge,
+.mui-table-view-cell > a > .mui-switch
+{
+    position: absolute;
+    top: 50%;
+    right: 15px;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+}
+.mui-table-view-cell .mui-navigate-right > .mui-btn,
+.mui-table-view-cell .mui-navigate-right > .mui-badge,
+.mui-table-view-cell .mui-navigate-right > .mui-switch,
+.mui-table-view-cell .mui-push-left > .mui-btn,
+.mui-table-view-cell .mui-push-left > .mui-badge,
+.mui-table-view-cell .mui-push-left > .mui-switch,
+.mui-table-view-cell .mui-push-right > .mui-btn,
+.mui-table-view-cell .mui-push-right > .mui-badge,
+.mui-table-view-cell .mui-push-right > .mui-switch,
+.mui-table-view-cell > a .mui-navigate-right > .mui-btn,
+.mui-table-view-cell > a .mui-navigate-right > .mui-badge,
+.mui-table-view-cell > a .mui-navigate-right > .mui-switch,
+.mui-table-view-cell > a .mui-push-left > .mui-btn,
+.mui-table-view-cell > a .mui-push-left > .mui-badge,
+.mui-table-view-cell > a .mui-push-left > .mui-switch,
+.mui-table-view-cell > a .mui-push-right > .mui-btn,
+.mui-table-view-cell > a .mui-push-right > .mui-badge,
+.mui-table-view-cell > a .mui-push-right > .mui-switch
+{
+    right: 35px;
+}
+
+.mui-content > .mui-table-view:first-child
+{
+    margin-top: 15px;
+}
+
+.mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view-cell.mui-collapse .mui-table-view:after
+{
+    height: 0;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+.mui-table-view-cell.mui-collapse > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse > .mui-push-right:after
+{
+    content: '\e581';
+}
+.mui-table-view-cell.mui-collapse.mui-active
+{
+    margin-top: -1px;
+}
+.mui-table-view-cell.mui-collapse.mui-active .mui-table-view, .mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content
+{
+    display: block;
+}
+.mui-table-view-cell.mui-collapse.mui-active > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse.mui-active > .mui-push-right:after
+{
+    content: '\e580';
+}
+.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    margin-left: -31px;
+    padding-left: 47px;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content
+{
+    position: relative;
+
+    display: none;
+    overflow: hidden;
+
+    margin: 11px -15px -11px;
+    padding: 8px 15px;
+
+    -webkit-transition: height .35s ease;
+         -o-transition: height .35s ease;
+            transition: height .35s ease;
+
+    background: white;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-input-group, .mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
+{
+    width: auto;
+    height: auto;
+    margin: -8px -15px;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
+{
+    margin: -8px -16px;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view
+{
+    display: none;
+
+    margin-top: 11px;
+    margin-right: -15px;
+    margin-bottom: -11px;
+    margin-left: -15px;
+
+    border: 0;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron
+{
+    margin-right: -65px;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell
+{
+    padding-left: 31px;
+
+    background-position: 31px 100%;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 30px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view.mui-grid-view
+{
+    font-size: 0;
+
+    display: block;
+
+    width: 100%;
+    padding: 0 10px 10px 0;
+
+    white-space: normal;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell
+{
+    font-size: 17px;
+
+    display: inline-block;
+
+    margin-right: -4px;
+    padding: 10px 0 0 14px;
+
+    text-align: center;
+    vertical-align: middle;
+
+    background: none;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object
+{
+    width: 100%;
+    max-width: 100%;
+    height: auto;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: -10px 0 0 -14px;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn):active, .mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background: none;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body
+{
+    font-size: 15px;
+    line-height: 15px;
+
+    display: block;
+
+    width: 100%;
+    height: 15px;
+    margin-top: 8px;
+
+    text-overflow: ellipsis;
+
+    color: #333;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell:before, .mui-table-view.mui-grid-view .mui-table-view-cell:after
+{
+    height: 0;
+}
+
+.mui-grid-view.mui-grid-9
+{
+    margin: 0;
+    padding: 0;
+
+    border-top: 1px solid #eee;
+    border-left: 1px solid #eee;
+    background-color: #f2f2f2;
+}
+.mui-grid-view.mui-grid-9:before, .mui-grid-view.mui-grid-9:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-grid-view.mui-grid-9:after
+{
+    clear: both;
+}
+.mui-grid-view.mui-grid-9:after
+{
+    position: static;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell
+{
+    margin: 0;
+    padding: 11px 15px;
+
+    vertical-align: top;
+
+    border-right: 1px solid #eee;
+    border-bottom: 1px solid #eee;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active
+{
+    background-color: #eee;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: 0;
+    padding: 10px 0;
+}
+.mui-grid-view.mui-grid-9:before
+{
+    height: 0;
+}
+.mui-grid-view.mui-grid-9 .mui-media
+{
+    color: #797979;
+}
+.mui-grid-view.mui-grid-9 .mui-media .mui-icon
+{
+    font-size: 2.4em;
+
+    position: relative;
+}
+
+.mui-slider-cell
+{
+    position: relative;
+}
+.mui-slider-cell > .mui-slider-handle
+{
+    z-index: 1;
+}
+.mui-slider-cell > .mui-slider-left, .mui-slider-cell > .mui-slider-right
+{
+    position: absolute;
+    z-index: 0;
+    top: 0;
+    bottom: 0;
+}
+.mui-slider-cell > .mui-slider-left
+{
+    left: 0;
+}
+.mui-slider-cell > .mui-slider-right
+{
+    right: 0;
+}
+
+input,
+textarea,
+select
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    font-size: 17px;
+
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+}
+input:focus,
+textarea:focus,
+select:focus
+{
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+    -webkit-user-modify: read-write-plaintext-only;
+}
+
+select,
+textarea,
+input[type='text'],
+input[type='search'],
+input[type='password'],
+input[type='datetime'],
+input[type='datetime-local'],
+input[type='date'],
+input[type='month'],
+input[type='time'],
+input[type='week'],
+input[type='number'],
+input[type='email'],
+input[type='url'],
+input[type='tel'],
+input[type='color']
+{
+    line-height: 21px;
+
+    width: 100%;
+    height: 40px;
+    margin-bottom: 15px;
+    padding: 10px 15px;
+
+    -webkit-user-select: text;
+
+    border: 1px solid rgba(0, 0, 0, .2);
+    border-radius: 3px;
+    outline: none;
+    background-color: #fff;
+
+    -webkit-appearance: none;
+}
+
+input[type=number]::-webkit-inner-spin-button,
+input[type=number]::-webkit-outer-spin-button
+{
+    margin: 0;
+
+    -webkit-appearance: none;
+}
+
+input[type='search']
+{
+    font-size: 16px;
+
+    -webkit-box-sizing: border-box;
+            box-sizing: border-box;
+    height: 34px;
+
+    text-align: center;
+
+    border: 0;
+    border-radius: 6px;
+    background-color: rgba(0, 0, 0, .1);
+}
+
+input[type='search']:focus
+{
+    text-align: left;
+}
+
+textarea
+{
+    height: auto;
+
+    resize: none;
+}
+
+select
+{
+    font-size: 14px;
+
+    height: auto;
+    margin-top: 1px;
+
+    border: 0 !important;
+    background-color: #fff;
+}
+select:focus
+{
+    -webkit-user-modify: read-only;
+}
+
+.mui-input-group
+{
+    position: relative;
+
+    padding: 0;
+
+    border: 0;
+    background-color: #fff;
+}
+.mui-input-group:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-input-group:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-input-group input,
+.mui-input-group textarea
+{
+    margin-bottom: 0;
+
+    border: 0;
+    border-radius: 0;
+    background-color: transparent;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-input-group input[type='search']
+{
+    background: none;
+}
+
+.mui-input-group input:last-child
+{
+    background-image: none;
+}
+
+.mui-input-row
+{
+    clear: left;
+    overflow: hidden;
+}
+.mui-input-row select
+{
+    font-size: 17px;
+
+    height: 37px;
+    padding: 0;
+}
+
+.mui-input-row:last-child,
+.mui-input-row label + input, .mui-input-row .mui-btn + input
+{
+    background: none;
+}
+
+.mui-input-group .mui-input-row
+{
+    height: 40px;
+}
+.mui-input-group .mui-input-row:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-input-row label
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    line-height: 1.1;
+
+    float: left;
+
+    width: 35%;
+    padding: 11px 15px;
+}
+
+.mui-input-row label ~ input, .mui-input-row label ~ select, .mui-input-row label ~ textarea
+{
+    float: right;
+
+    width: 65%;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    border: 0;
+}
+
+.mui-input-row .mui-btn
+{
+    line-height: 1.1;
+
+    float: right;
+
+    width: 15%;
+    padding: 10px 15px;
+}
+
+.mui-input-row .mui-btn ~ input, .mui-input-row .mui-btn ~ select, .mui-input-row .mui-btn ~ textarea
+{
+    float: left;
+
+    width: 85%;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    border: 0;
+}
+
+.mui-button-row
+{
+    position: relative;
+
+    padding-top: 5px;
+
+    text-align: center;
+}
+
+.mui-input-group .mui-button-row
+{
+    height: 45px;
+}
+
+.mui-input-row
+{
+    position: relative;
+}
+.mui-input-row.mui-input-range
+{
+    overflow: visible;
+
+    padding-right: 20px;
+}
+.mui-input-row .mui-inline
+{
+    padding: 8px 0;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear, .mui-input-row .mui-input-speech ~ .mui-icon-speech, .mui-input-row .mui-input-password ~ .mui-icon-eye
+{
+    font-size: 20px;
+
+    position: absolute;
+    z-index: 1;
+    top: 10px;
+    right: 0;
+
+    width: 38px;
+    height: 38px;
+
+    text-align: center;
+
+    color: #999;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-active, .mui-input-row .mui-input-speech ~ .mui-icon-speech.mui-active, .mui-input-row .mui-input-password ~ .mui-icon-eye.mui-active
+{
+    color: #007aff;
+}
+.mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    font-size: 24px;
+
+    top: 8px;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear ~ .mui-icon-speech
+{
+    display: none;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-hidden ~ .mui-icon-speech
+{
+    display: inline-block;
+}
+.mui-input-row .mui-icon-speech ~ .mui-placeholder
+{
+    right: 38px;
+}
+.mui-input-row.mui-search .mui-icon-clear
+{
+    top: 7px;
+}
+.mui-input-row.mui-search .mui-icon-speech
+{
+    top: 5px;
+}
+
+.mui-radio, .mui-checkbox
+{
+    position: relative;
+}
+.mui-radio label, .mui-checkbox label
+{
+    display: inline-block;
+    float: none;
+
+    width: 100%;
+    padding-right: 58px;
+}
+
+.mui-radio.mui-left input[type='radio'], .mui-checkbox.mui-left input[type='checkbox']
+{
+    left: 20px;
+}
+
+.mui-radio.mui-left label, .mui-checkbox.mui-left label
+{
+    padding-right: 15px;
+    padding-left: 58px;
+}
+
+.mui-radio input[type='radio'], .mui-checkbox input[type='checkbox']
+{
+    position: absolute;
+    top: 4px;
+    right: 20px;
+
+    display: inline-block;
+
+    width: 28px;
+    height: 26px;
+
+    border: 0;
+    outline: 0 !important;
+    background-color: transparent;
+
+    -webkit-appearance: none;
+}
+.mui-radio input[type='radio'][disabled]:before, .mui-checkbox input[type='checkbox'][disabled]:before
+{
+    opacity: .3;
+}
+.mui-radio input[type='radio']:before, .mui-checkbox input[type='checkbox']:before
+{
+    font-family: Muiicons;
+    font-size: 28px;
+    font-weight: normal;
+    line-height: 1;
+
+    text-decoration: none;
+
+    color: #aaa;
+    border-radius: 0;
+    background: none;
+
+    -webkit-font-smoothing: antialiased;
+}
+.mui-radio input[type='radio']:checked:before, .mui-checkbox input[type='checkbox']:checked:before
+{
+    color: #007aff;
+}
+
+.mui-radio.mui-disabled label, .mui-radio label.mui-disabled, .mui-checkbox.mui-disabled label, .mui-checkbox label.mui-disabled
+{
+    opacity: .4;
+}
+
+.mui-radio input[type='radio']:before
+{
+    content: '\e411';
+}
+
+.mui-radio input[type='radio']:checked:before
+{
+    content: '\e441';
+}
+
+.mui-checkbox input[type='checkbox']:before
+{
+    content: '\e411';
+}
+
+.mui-checkbox input[type='checkbox']:checked:before
+{
+    content: '\e442';
+}
+
+.mui-select
+{
+    position: relative;
+}
+
+.mui-select:before
+{
+    font-family: Muiicons;
+
+    position: absolute;
+    top: 8px;
+    right: 21px;
+
+    content: '\e581';
+
+    color: rgba(170, 170, 170, .6);
+}
+
+.mui-input-row .mui-switch
+{
+    float: right;
+
+    margin-top: 5px;
+    margin-right: 20px;
+}
+
+.mui-input-range
+{
+  /*input[type="range"] {
+      -webkit-appearance: none;
+      background: #999;
+      height: 36px;
+      border-radius: 1px;
+      overflow: hidden;
+      margin-top: 2px;
+      margin-bottom: 2px;
+      outline:none;
+      position:relative;
+      width:100%;
+  }*/
+  /*input[type='range']::-webkit-slider-thumb {
+      -webkit-appearance: none!important;
+      opacity: 0.5;
+      height:28px;
+      width:28px;
+      border-radius: 50%;
+      background:#00b7fb;
+      position: relative;
+      pointer-events: none;
+      -webkit-box-sizing: border-box;
+      box-sizing: border-box;
+      &:before{
+          position: absolute;
+          top: 13px;
+          left: -2000px;
+          width: 2000px;
+          height: 2px;
+          background: #00b7fb;
+          content:' ';
+      }
+  }*/
+}
+.mui-input-range input[type='range']
+{
+    position: relative;
+
+    width: 100%;
+    height: 2px;
+    margin: 17px 0;
+    padding: 0;
+
+    cursor: pointer;
+
+    border: 0;
+    border-radius: 3px;
+    outline: none;
+    background-color: #999;
+
+    -webkit-appearance: none !important;
+}
+.mui-input-range input[type='range']::-webkit-slider-thumb
+{
+    width: 28px;
+    height: 28px;
+
+    border-color: #0062cc;
+    border-radius: 50%;
+    background-color: #007aff;
+    background-clip: padding-box;
+
+    -webkit-appearance: none !important;
+}
+.mui-input-range label ~ input[type='range']
+{
+    width: 65%;
+}
+.mui-input-range .mui-tooltip
+{
+    font-size: 36px;
+    line-height: 64px;
+
+    position: absolute;
+    z-index: 1;
+    top: -70px;
+
+    width: 64px;
+    height: 64px;
+
+    text-align: center;
+
+    opacity: .8;
+    color: #333;
+    border: 1px solid #ddd;
+    border-radius: 6px;
+    background-color: #fff;
+    text-shadow: 0 1px 0 #f3f3f3;
+}
+
+.mui-search
+{
+    position: relative;
+}
+.mui-search input[type='search']
+{
+    padding-left: 30px;
+}
+.mui-search .mui-placeholder
+{
+    font-size: 16px;
+    line-height: 34px;
+
+    position: absolute;
+    z-index: 1;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    display: inline-block;
+
+    height: 34px;
+
+    text-align: center;
+
+    color: #999;
+    border: 0;
+    border-radius: 6px;
+    background: none;
+}
+.mui-search .mui-placeholder .mui-icon
+{
+    font-size: 20px;
+
+    color: #333;
+}
+.mui-search:before
+{
+    font-family: Muiicons;
+    font-size: 20px;
+    font-weight: normal;
+
+    position: absolute;
+    top: 50%;
+    right: 50%;
+
+    display: none;
+
+    margin-top: -18px;
+    margin-right: 31px;
+
+    content: '\e466';
+}
+.mui-search.mui-active:before
+{
+    font-size: 20px;
+
+    right: auto;
+    left: 5px;
+
+    display: block;
+
+    margin-right: 0;
+}
+.mui-search.mui-active input[type='search']
+{
+    text-align: left;
+}
+.mui-search.mui-active .mui-placeholder
+{
+    display: none;
+}
+
+.mui-segmented-control
+{
+    font-size: 15px;
+    font-weight: 400;
+
+    position: relative;
+
+    display: table;
+    overflow: hidden;
+
+    width: 100%;
+
+    table-layout: fixed;
+
+    border: 1px solid #007aff;
+    border-radius: 3px;
+    background-color: transparent;
+
+    -webkit-touch-callout: none;
+}
+.mui-segmented-control.mui-segmented-control-vertical
+{
+    border-collapse: collapse;
+
+    border-width: 0;
+    border-radius: 0;
+}
+.mui-segmented-control.mui-segmented-control-vertical .mui-control-item
+{
+    display: block;
+
+    border-bottom: 1px solid #c8c7cc;
+    border-left-width: 0;
+}
+.mui-segmented-control.mui-scroll-wrapper
+{
+    height: 38px;
+}
+.mui-segmented-control.mui-scroll-wrapper .mui-scroll
+{
+    width: auto;
+    height: 40px;
+
+    white-space: nowrap;
+}
+.mui-segmented-control.mui-scroll-wrapper .mui-control-item
+{
+    display: inline-block;
+
+    width: auto;
+    padding: 0 20px;
+
+    border: 0;
+}
+.mui-segmented-control .mui-control-item
+{
+    line-height: 38px;
+
+    display: table-cell;
+    overflow: hidden;
+
+    width: 1%;
+
+    -webkit-transition: background-color .1s linear;
+            transition: background-color .1s linear;
+    text-align: center;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #007aff;
+    border-color: #007aff;
+    border-left: 1px solid #007aff;
+}
+.mui-segmented-control .mui-control-item:first-child
+{
+    border-left-width: 0;
+}
+.mui-segmented-control .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #007aff;
+}
+.mui-segmented-control.mui-segmented-control-inverted
+{
+    width: 100%;
+
+    border: 0;
+    border-radius: 0;
+}
+.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item
+{
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active
+{
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-segmented-control.mui-segmented-control-inverted .mui-control-item
+{
+    color: inherit;
+    border: 0;
+}
+.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #007aff;
+    border-bottom: 2px solid #007aff;
+    background: none;
+}
+.mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #007aff;
+}
+
+.mui-segmented-control-positive
+{
+    border: 1px solid #4cd964;
+}
+.mui-segmented-control-positive .mui-control-item
+{
+    color: #4cd964;
+    border-color: inherit;
+}
+.mui-segmented-control-positive .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #4cd964;
+}
+.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #4cd964;
+    border-bottom: 2px solid #4cd964;
+    background: none;
+}
+.mui-segmented-control-positive.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #4cd964;
+}
+
+.mui-segmented-control-negative
+{
+    border: 1px solid #dd524d;
+}
+.mui-segmented-control-negative .mui-control-item
+{
+    color: #dd524d;
+    border-color: inherit;
+}
+.mui-segmented-control-negative .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #dd524d;
+}
+.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #dd524d;
+    border-bottom: 2px solid #dd524d;
+    background: none;
+}
+.mui-segmented-control-negative.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #dd524d;
+}
+
+.mui-control-content
+{
+    position: relative;
+
+    display: none;
+}
+.mui-control-content.mui-active
+{
+    display: block;
+}
+
+.mui-popover
+{
+    position: absolute;
+    z-index: 999;
+
+    display: none;
+
+    width: 280px;
+
+    -webkit-transition: opacity .3s;
+            transition: opacity .3s;
+    -webkit-transition-property: opacity;
+            transition-property: opacity;
+    -webkit-transform: none;
+            transform: none;
+
+    opacity: 0;
+    border-radius: 7px;
+    background-color: #f7f7f7;
+    -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .1);
+            box-shadow: 0 0 15px rgba(0, 0, 0, .1);
+}
+.mui-popover .mui-popover-arrow
+{
+    position: absolute;
+    z-index: 1000;
+    top: -25px;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 26px;
+    height: 26px;
+}
+.mui-popover .mui-popover-arrow:after
+{
+    position: absolute;
+    top: 19px;
+    left: 0;
+
+    width: 26px;
+    height: 26px;
+
+    content: ' ';
+    -webkit-transform: rotate(45deg);
+            transform: rotate(45deg);
+
+    border-radius: 3px;
+    background: #f7f7f7;
+}
+.mui-popover .mui-popover-arrow.mui-bottom
+{
+    top: 100%;
+    left: -26px;
+
+    margin-top: -1px;
+}
+.mui-popover .mui-popover-arrow.mui-bottom:after
+{
+    top: -19px;
+    left: 0;
+}
+.mui-popover.mui-popover-action
+{
+    bottom: 0;
+
+    width: 100%;
+
+    -webkit-transition: -webkit-transform .3s, opacity .3s;
+            transition:         transform .3s, opacity .3s;
+    -webkit-transform: translate3d(0, 100%, 0);
+            transform: translate3d(0, 100%, 0);
+
+    border-radius: 0;
+    background: none;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+.mui-popover.mui-popover-action .mui-popover-arrow
+{
+    display: none;
+}
+.mui-popover.mui-popover-action.mui-popover-bottom
+{
+    position: fixed;
+}
+.mui-popover.mui-popover-action.mui-active
+{
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+}
+.mui-popover.mui-popover-action .mui-table-view
+{
+    margin: 8px;
+
+    text-align: center;
+
+    color: #007aff;
+    border-radius: 4px;
+}
+.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-popover.mui-popover-action .mui-table-view small
+{
+    font-weight: 400;
+    line-height: 1.3;
+
+    display: block;
+}
+.mui-popover.mui-active
+{
+    display: block;
+
+    opacity: 1;
+}
+.mui-popover .mui-bar ~ .mui-table-view
+{
+    padding-top: 44px;
+}
+
+.mui-backdrop
+{
+    position: fixed;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    background-color: rgba(0, 0, 0, .3);
+}
+
+.mui-bar-backdrop.mui-backdrop
+{
+    bottom: 50px;
+
+    background: none;
+}
+
+.mui-backdrop-action.mui-backdrop
+{
+    background-color: rgba(0, 0, 0, .3);
+}
+
+.mui-bar-backdrop.mui-backdrop, .mui-backdrop-action.mui-backdrop
+{
+    opacity: 0;
+}
+.mui-bar-backdrop.mui-backdrop.mui-active, .mui-backdrop-action.mui-backdrop.mui-active
+{
+    -webkit-transition: all .4s ease;
+            transition: all .4s ease;
+
+    opacity: 1;
+}
+
+.mui-popover .mui-btn-block
+{
+    margin-bottom: 5px;
+}
+.mui-popover .mui-btn-block:last-child
+{
+    margin-bottom: 0;
+}
+
+.mui-popover .mui-bar
+{
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-popover .mui-bar-nav
+{
+    border-bottom: 1px solid rgba(0, 0, 0, .15);
+    border-top-left-radius: 12px;
+    border-top-right-radius: 12px;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-popover .mui-scroll-wrapper
+{
+    margin: 7px 0;
+
+    border-radius: 7px;
+    background-clip: padding-box;
+}
+
+.mui-popover .mui-scroll .mui-table-view
+{
+    max-height: none;
+}
+
+.mui-popover .mui-table-view
+{
+    overflow: auto;
+
+    max-height: 300px;
+    margin-bottom: 0;
+
+    border-radius: 7px;
+    background-color: #f7f7f7;
+    background-image: none;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-popover .mui-table-view:before, .mui-popover .mui-table-view:after
+{
+    height: 0;
+}
+.mui-popover .mui-table-view .mui-table-view-cell:first-child,
+.mui-popover .mui-table-view .mui-table-view-cell:first-child > a:not(.mui-btn)
+{
+    border-top-left-radius: 12px;
+    border-top-right-radius: 12px;
+}
+.mui-popover .mui-table-view .mui-table-view-cell:last-child,
+.mui-popover .mui-table-view .mui-table-view-cell:last-child > a:not(.mui-btn)
+{
+    border-bottom-right-radius: 12px;
+    border-bottom-left-radius: 12px;
+}
+
+.mui-popover.mui-bar-popover .mui-table-view
+{
+    width: 106px;
+}
+.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell
+{
+    padding: 11px 15px 11px 15px;
+
+    background-position: 0 100%;
+}
+.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: -11px -15px -11px -15px;
+}
+
+.mui-popup-backdrop
+{
+    position: fixed;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+
+    opacity: 0;
+    background: rgba(0, 0, 0, .4);
+}
+.mui-popup-backdrop.mui-active
+{
+    opacity: 1;
+}
+
+.mui-popup
+{
+    position: fixed;
+    z-index: 10000;
+    top: 50%;
+    left: 50%;
+
+    display: none;
+    overflow: hidden;
+
+    width: 270px;
+
+    -webkit-transition-property: -webkit-transform,opacity;
+            transition-property:         transform,opacity;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1.185);
+            transform: translate3d(-50%, -50%, 0) scale(1.185);
+    text-align: center;
+
+    opacity: 0;
+    color: #000;
+    border-radius: 13px;
+}
+.mui-popup.mui-popup-in
+{
+    display: block;
+
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+
+    opacity: 1;
+}
+.mui-popup.mui-popup-out
+{
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+
+    opacity: 0;
+}
+
+.mui-popup-inner
+{
+    position: relative;
+
+    padding: 15px;
+
+    border-radius: 13px 13px 0 0;
+    background: rgba(255, 255, 255, .95);
+}
+.mui-popup-inner:after
+{
+    position: absolute;
+    z-index: 15;
+    top: auto;
+    right: auto;
+    bottom: 0;
+    left: 0;
+
+    display: block;
+
+    width: 100%;
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+    -webkit-transform-origin: 50% 100%;
+            transform-origin: 50% 100%;
+
+    background-color: rgba(0, 0, 0, .2);
+}
+
+.mui-popup-title
+{
+    font-size: 18px;
+    font-weight: 500;
+
+    text-align: center;
+}
+
+.mui-popup-title + .mui-popup-text
+{
+    font-family: inherit;
+    font-size: 14px;
+
+    margin: 5px 0 0;
+}
+
+.mui-popup-buttons
+{
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 44px;
+
+    -webkit-box-pack: center;
+    -webkit-justify-content: center;
+            justify-content: center;
+}
+
+.mui-popup-button
+{
+    font-size: 17px;
+    line-height: 44px;
+
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    box-sizing: border-box;
+    width: 100%;
+    height: 44px;
+    padding: 0 5px;
+
+    cursor: pointer;
+    text-align: center;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #007aff;
+    background: rgba(255, 255, 255, .95);
+
+    -webkit-box-flex: 1;
+}
+.mui-popup-button:after
+{
+    position: absolute;
+    z-index: 15;
+    top: 0;
+    right: 0;
+    bottom: auto;
+    left: auto;
+
+    display: block;
+
+    width: 1px;
+    height: 100%;
+
+    content: '';
+    -webkit-transform: scaleX(.5);
+            transform: scaleX(.5);
+    -webkit-transform-origin: 100% 50%;
+            transform-origin: 100% 50%;
+
+    background-color: rgba(0, 0, 0, .2);
+}
+.mui-popup-button:first-child
+{
+    border-radius: 0 0 0 13px;
+}
+.mui-popup-button:first-child:last-child
+{
+    border-radius: 0 0 13px 13px;
+}
+.mui-popup-button:last-child
+{
+    border-radius: 0 0 13px 0;
+}
+.mui-popup-button:last-child:after
+{
+    display: none;
+}
+.mui-popup-button.mui-popup-button-bold
+{
+    font-weight: 600;
+}
+
+.mui-popup-input input
+{
+    font-size: 14px;
+
+    width: 100%;
+    height: 26px;
+    margin: 15px 0 0;
+    padding: 0 5px;
+
+    border: 1px solid rgba(0, 0, 0, .3);
+    border-radius: 0;
+    background: #fff;
+}
+
+.mui-plus.mui-android .mui-popup-backdrop
+{
+    -webkit-transition-duration: 1ms;
+            transition-duration: 1ms;
+}
+
+.mui-plus.mui-android .mui-popup
+{
+    -webkit-transition-duration: 1ms;
+            transition-duration: 1ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+}
+
+/* === Progress Bar === */
+.mui-progressbar
+{
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    width: 100%;
+    height: 2px;
+
+    -webkit-transform-origin: center top;
+            transform-origin: center top;
+    vertical-align: middle;
+
+    border-radius: 2px;
+    background: #b6b6b6;
+
+    -webkit-transform-style: preserve-3d;
+            transform-style: preserve-3d;
+}
+.mui-progressbar span
+{
+    position: absolute;
+    top: 0;
+    left: 0;
+
+    width: 100%;
+    height: 100%;
+
+    -webkit-transition: 150ms;
+            transition: 150ms;
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+
+    background: #007aff;
+}
+.mui-progressbar.mui-progressbar-infinite:before
+{
+    position: absolute;
+    top: 0;
+    left: 0;
+
+    width: 100%;
+    height: 100%;
+
+    content: '';
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+    -webkit-transform-origin: left center;
+            transform-origin: left center;
+    -webkit-animation: mui-progressbar-infinite 1s linear infinite;
+            animation: mui-progressbar-infinite 1s linear infinite;
+
+    background: #007aff;
+}
+
+body > .mui-progressbar
+{
+    position: absolute;
+    z-index: 10000;
+    top: 44px;
+    left: 0;
+
+    border-radius: 0;
+}
+
+.mui-progressbar-in
+{
+    -webkit-animation: mui-progressbar-in 300ms forwards;
+            animation: mui-progressbar-in 300ms forwards;
+}
+
+.mui-progressbar-out
+{
+    -webkit-animation: mui-progressbar-out 300ms forwards;
+            animation: mui-progressbar-out 300ms forwards;
+}
+
+@-webkit-keyframes mui-progressbar-in
+{
+    from
+    {
+        -webkit-transform: scaleY(0);
+
+        opacity: 0;
+    }
+
+    to
+    {
+        -webkit-transform: scaleY(1);
+
+        opacity: 1;
+    }
+}
+@keyframes mui-progressbar-in
+{
+    from
+    {
+        transform: scaleY(0);
+
+        opacity: 0;
+    }
+
+    to
+    {
+        transform: scaleY(1);
+
+        opacity: 1;
+    }
+}
+@-webkit-keyframes mui-progressbar-out
+{
+    from
+    {
+        -webkit-transform: scaleY(1);
+
+        opacity: 1;
+    }
+
+    to
+    {
+        -webkit-transform: scaleY(0);
+
+        opacity: 0;
+    }
+}
+@keyframes mui-progressbar-out
+{
+    from
+    {
+        transform: scaleY(1);
+
+        opacity: 1;
+    }
+
+    to
+    {
+        transform: scaleY(0);
+
+        opacity: 0;
+    }
+}
+@-webkit-keyframes mui-progressbar-infinite
+{
+    0%
+    {
+        -webkit-transform: translate3d(-50%, 0, 0) scaleX(.5);
+    }
+
+    100%
+    {
+        -webkit-transform: translate3d(100%, 0, 0) scaleX(.5);
+    }
+}
+@keyframes mui-progressbar-infinite
+{
+    0%
+    {
+        transform: translate3d(-50%, 0, 0) scaleX(.5);
+    }
+
+    100%
+    {
+        transform: translate3d(100%, 0, 0) scaleX(.5);
+    }
+}
+.mui-pagination
+{
+    display: inline-block;
+
+    margin: 0 auto;
+    padding-left: 0;
+
+    border-radius: 6px;
+}
+.mui-pagination > li
+{
+    display: inline;
+}
+.mui-pagination > li > a,
+.mui-pagination > li > span
+{
+    line-height: 1.428571429;
+
+    position: relative;
+
+    float: left;
+
+    margin-left: -1px;
+    padding: 6px 12px;
+
+    text-decoration: none;
+
+    color: #007aff;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+.mui-pagination > li:first-child > a,
+.mui-pagination > li:first-child > span
+{
+    margin-left: 0;
+
+    border-top-left-radius: 6px;
+    border-bottom-left-radius: 6px;
+    background-clip: padding-box;
+}
+.mui-pagination > li:last-child > a,
+.mui-pagination > li:last-child > span
+{
+    border-top-right-radius: 6px;
+    border-bottom-right-radius: 6px;
+    background-clip: padding-box;
+}
+.mui-pagination > li:active > a, .mui-pagination > li:active > a:active,
+.mui-pagination > li:active > span,
+.mui-pagination > li:active > span:active,
+.mui-pagination > li.mui-active > a,
+.mui-pagination > li.mui-active > a:active,
+.mui-pagination > li.mui-active > span,
+.mui-pagination > li.mui-active > span:active
+{
+    z-index: 2;
+
+    cursor: default;
+
+    color: #fff;
+    border-color: #007aff;
+    background-color: #007aff;
+}
+.mui-pagination > li.mui-disabled > span,
+.mui-pagination > li.mui-disabled > span:active,
+.mui-pagination > li.mui-disabled > a,
+.mui-pagination > li.mui-disabled > a:active
+{
+    opacity: .6;
+    color: #777;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+
+.mui-pagination-lg > li > a,
+.mui-pagination-lg > li > span
+{
+    font-size: 18px;
+
+    padding: 10px 16px;
+}
+
+.mui-pagination-sm > li > a,
+.mui-pagination-sm > li > span
+{
+    font-size: 12px;
+
+    padding: 5px 10px;
+}
+
+.mui-pager
+{
+    padding-left: 0;
+
+    list-style: none;
+
+    text-align: center;
+}
+.mui-pager:before, .mui-pager:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-pager:after
+{
+    clear: both;
+}
+.mui-pager li
+{
+    display: inline;
+}
+.mui-pager li > a,
+.mui-pager li > span
+{
+    display: inline-block;
+
+    padding: 5px 14px;
+
+    border: 1px solid #ddd;
+    border-radius: 6px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+.mui-pager li:active > a, .mui-pager li:active > span, .mui-pager li.mui-active > a, .mui-pager li.mui-active > span
+{
+    cursor: default;
+    text-decoration: none;
+
+    color: #fff;
+    border-color: #007aff;
+    background-color: #007aff;
+}
+.mui-pager .mui-next > a,
+.mui-pager .mui-next > span
+{
+    float: right;
+}
+.mui-pager .mui-previous > a,
+.mui-pager .mui-previous > span
+{
+    float: left;
+}
+.mui-pager .mui-disabled > a,
+.mui-pager .mui-disabled > a:active,
+.mui-pager .mui-disabled > span,
+.mui-pager .mui-disabled > span:active
+{
+    opacity: .6;
+    color: #777;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+
+.mui-modal
+{
+    position: fixed;
+    z-index: 999;
+    top: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+    min-height: 100%;
+
+    -webkit-transition: -webkit-transform .25s, opacity 1ms .25s;
+            transition:         transform .25s, opacity 1ms .25s;
+    -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+            transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+    -webkit-transform: translate3d(0, 100%, 0);
+            transform: translate3d(0, 100%, 0);
+
+    opacity: 0;
+    background-color: #fff;
+}
+.mui-modal.mui-active
+{
+    height: 100%;
+
+    -webkit-transition: -webkit-transform .25s;
+            transition:         transform .25s;
+    -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+            transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+
+    opacity: 1;
+}
+
+.mui-android .mui-modal .mui-bar
+{
+    position: static;
+}
+
+.mui-android .mui-modal .mui-bar-nav ~ .mui-content
+{
+    padding-top: 0;
+}
+
+.mui-slider
+{
+    position: relative;
+    z-index: 1;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    border-bottom: 0;
+}
+.mui-slider .mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-group .mui-slider-item
+{
+    border-top: 1px solid #c8c7cc;
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-slider .mui-slider-group
+{
+    font-size: 0;
+
+    position: relative;
+
+    -webkit-transition: all 0s linear;
+            transition: all 0s linear;
+    white-space: nowrap;
+}
+.mui-slider .mui-slider-group .mui-slider-item
+{
+    font-size: 14px;
+
+    position: relative;
+
+    display: inline-block;
+
+    width: 100%;
+    height: 100%;
+
+    vertical-align: top;
+    white-space: normal;
+}
+.mui-slider .mui-slider-group .mui-slider-item > a:not(.mui-control-item)
+{
+    line-height: 0;
+
+    position: relative;
+
+    display: block;
+}
+.mui-slider .mui-slider-group .mui-slider-item img
+{
+    width: 100%;
+}
+.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before, .mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after
+{
+    height: 0;
+}
+.mui-slider .mui-slider-group.mui-slider-loop
+{
+    -webkit-transform: translate(-100%, 0px);
+            transform: translate(-100%, 0px);
+}
+
+.mui-slider-title
+{
+    line-height: 30px;
+
+    position: absolute;
+    bottom: 0;
+    left: 0;
+
+    width: 100%;
+    height: 30px;
+    margin: 0;
+
+    text-align: left;
+    text-indent: 12px;
+
+    opacity: .8;
+    background-color: #000;
+}
+
+.mui-slider-indicator
+{
+    position: absolute;
+    bottom: 8px;
+
+    width: 100%;
+
+    text-align: center;
+
+    background: none;
+}
+.mui-slider-indicator.mui-segmented-control
+{
+    position: relative;
+    bottom: auto;
+}
+.mui-slider-indicator .mui-indicator
+{
+    display: inline-block;
+
+    width: 6px;
+    height: 6px;
+    margin: 1px 6px;
+
+    cursor: pointer;
+
+    border-radius: 50%;
+    background: #aaa;
+    -webkit-box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
+            box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
+}
+.mui-slider-indicator .mui-active.mui-indicator
+{
+    background: #fff;
+}
+.mui-slider-indicator .mui-icon
+{
+    font-size: 20px;
+    line-height: 30px;
+
+    width: 40px;
+    height: 30px;
+    margin: 3px;
+
+    text-align: center;
+
+    border: 1px solid #ddd;
+}
+.mui-slider-indicator .mui-number
+{
+    line-height: 32px;
+
+    display: inline-block;
+
+    width: 58px;
+}
+.mui-slider-indicator .mui-number span
+{
+    color: #ff5053;
+}
+
+.mui-slider-progress-bar
+{
+    z-index: 1;
+
+    height: 2px;
+
+    -webkit-transform: translateZ(0);
+            transform: translateZ(0);
+}
+
+.mui-switch
+{
+    position: relative;
+
+    display: block;
+
+    width: 74px;
+    height: 30px;
+
+    -webkit-transition-timing-function: ease-in-out;
+            transition-timing-function: ease-in-out;
+    -webkit-transition-duration: .2s;
+            transition-duration: .2s;
+    -webkit-transition-property: background-color, border;
+            transition-property: background-color, border;
+
+    border: 2px solid #ddd;
+    border-radius: 20px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+.mui-switch.mui-disabled
+{
+    opacity: .3;
+}
+.mui-switch .mui-switch-handle
+{
+    position: absolute;
+    z-index: 1;
+    top: -1px;
+    left: -1px;
+
+    width: 28px;
+    height: 28px;
+
+    -webkit-transition: .2s ease-in-out;
+            transition: .2s ease-in-out;
+    -webkit-transition-property: -webkit-transform, width,left;
+            transition-property:         transform, width,left;
+
+    border-radius: 16px;
+    background-color: #fff;
+    background-clip: padding-box;
+    -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
+            box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
+}
+.mui-switch:before
+{
+    font-size: 13px;
+
+    position: absolute;
+    top: 3px;
+    right: 11px;
+
+    content: 'Off';
+    text-transform: uppercase;
+
+    color: #999;
+}
+.mui-switch.mui-dragging
+{
+    border-color: #f7f7f7;
+    background-color: #f7f7f7;
+}
+.mui-switch.mui-dragging .mui-switch-handle
+{
+    width: 38px;
+}
+.mui-switch.mui-dragging.mui-active .mui-switch-handle
+{
+    left: -11px;
+
+    width: 38px;
+}
+.mui-switch.mui-active
+{
+    border-color: #4cd964;
+    background-color: #4cd964;
+}
+.mui-switch.mui-active .mui-switch-handle
+{
+    -webkit-transform: translate(43px, 0);
+            transform: translate(43px, 0);
+}
+.mui-switch.mui-active:before
+{
+    right: auto;
+    left: 15px;
+
+    content: 'On';
+
+    color: #fff;
+}
+.mui-switch input[type='checkbox']
+{
+    display: none;
+}
+
+.mui-switch-mini
+{
+    width: 47px;
+}
+.mui-switch-mini:before
+{
+    display: none;
+}
+.mui-switch-mini.mui-active .mui-switch-handle
+{
+    -webkit-transform: translate(16px, 0);
+            transform: translate(16px, 0);
+}
+
+.mui-switch-blue.mui-active
+{
+    border: 2px solid #007aff;
+    background-color: #007aff;
+}
+
+.mui-content.mui-fade
+{
+    left: 0;
+
+    opacity: 0;
+}
+.mui-content.mui-fade.mui-in
+{
+    opacity: 1;
+}
+.mui-content.mui-sliding
+{
+    z-index: 2;
+
+    -webkit-transition: -webkit-transform .4s;
+            transition:         transform .4s;
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+}
+.mui-content.mui-sliding.mui-left
+{
+    z-index: 1;
+
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+}
+.mui-content.mui-sliding.mui-right
+{
+    z-index: 3;
+
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+}
+
+.mui-navigate-right:after,
+.mui-push-left:after,
+.mui-push-right:after
+{
+    font-family: Muiicons;
+    font-size: inherit;
+    line-height: 1;
+
+    position: absolute;
+    top: 50%;
+
+    display: inline-block;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+    text-decoration: none;
+
+    color: #bbb;
+
+    -webkit-font-smoothing: antialiased;
+}
+
+.mui-push-left:after
+{
+    left: 15px;
+
+    content: '\e582';
+}
+
+.mui-navigate-right:after,
+.mui-push-right:after
+{
+    right: 15px;
+
+    content: '\e583';
+}
+
+.mui-pull-top-pocket, .mui-pull-bottom-pocket
+{
+    position: absolute;
+    left: 0;
+
+    display: block;
+    visibility: hidden;
+    overflow: hidden;
+
+    width: 100%;
+    height: 50px;
+}
+
+.mui-plus-pullrefresh .mui-pull-top-pocket, .mui-plus-pullrefresh .mui-pull-bottom-pocket
+{
+    display: none;
+    visibility: visible;
+}
+
+.mui-pull-top-pocket
+{
+    top: 0;
+}
+
+.mui-bar-nav ~ .mui-content .mui-pull-top-pocket
+{
+    top: 44px;
+}
+
+.mui-bar-nav ~ .mui-bar-header-secondary ~ .mui-content .mui-pull-top-pocket
+{
+    top: 88px;
+}
+
+.mui-pull-bottom-pocket
+{
+    position: relative;
+    bottom: 0;
+
+    height: 40px;
+}
+.mui-pull-bottom-pocket .mui-pull-loading
+{
+    visibility: hidden;
+}
+.mui-pull-bottom-pocket .mui-pull-loading.mui-in
+{
+    display: inline-block;
+}
+
+.mui-pull
+{
+    font-weight: bold;
+
+    position: absolute;
+    right: 0;
+    bottom: 10px;
+    left: 0;
+
+    text-align: center;
+
+    color: #777;
+}
+
+.mui-pull-loading
+{
+    margin-right: 10px;
+
+    -webkit-transition: -webkit-transform .4s;
+            transition:         transform .4s;
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    vertical-align: middle;
+}
+
+.mui-pull-loading.mui-reverse
+{
+    -webkit-transform: rotate(180deg) translateZ(0);
+            transform: rotate(180deg) translateZ(0);
+}
+
+.mui-pull-caption
+{
+    font-size: 15px;
+    line-height: 24px;
+
+    position: relative;
+
+    display: inline-block;
+    overflow: visible;
+
+    margin-top: 0;
+
+    vertical-align: middle;
+}
+.mui-pull-caption span
+{
+    display: none;
+}
+.mui-pull-caption span.mui-in
+{
+    display: inline;
+}
+
+.mui-toast-container
+{
+    line-height: 17px;
+
+    position: fixed;
+    z-index: 9999;
+    bottom: 50px;
+    left: 50%;
+
+    -webkit-transition: opacity .3s;
+            transition: opacity .3s;
+    -webkit-transform: translate(-50%, 0);
+            transform: translate(-50%, 0);
+
+    opacity: 0;
+}
+.mui-toast-container.mui-active
+{
+    opacity: .9;
+}
+
+.mui-toast-message
+{
+    font-size: 14px;
+
+    padding: 10px 25px;
+
+    text-align: center;
+
+    color: #fff;
+    border-radius: 6px;
+    background-color: #323232;
+}
+
+.mui-numbox
+{
+    position: relative;
+
+    display: inline-block;
+    overflow: hidden;
+
+    width: 120px;
+    height: 35px;
+    padding: 0 40px 0 40px;
+
+    vertical-align: top;
+    vertical-align: middle;
+
+    border: solid 1px #bbb;
+    border-radius: 3px;
+    background-color: #efeff4;
+}
+.mui-numbox [class*=numbox-btn], .mui-numbox [class*=btn-numbox]
+{
+    font-size: 18px;
+    font-weight: normal;
+    line-height: 100%;
+
+    position: absolute;
+    top: 0;
+
+    overflow: hidden;
+
+    width: 40px;
+    height: 100%;
+    padding: 0;
+
+    color: #555;
+    border: none;
+    border-radius: 0;
+    background-color: #f9f9f9;
+}
+.mui-numbox [class*=numbox-btn]:active, .mui-numbox [class*=btn-numbox]:active
+{
+    background-color: #ccc;
+}
+.mui-numbox [class*=numbox-btn][disabled], .mui-numbox [class*=btn-numbox][disabled]
+{
+    color: #c0c0c0;
+}
+.mui-numbox .mui-numbox-btn-plus, .mui-numbox .mui-btn-numbox-plus
+{
+    right: 0;
+
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+}
+.mui-numbox .mui-numbox-btn-minus, .mui-numbox .mui-btn-numbox-minus
+{
+    left: 0;
+
+    border-top-left-radius: 3px;
+    border-bottom-left-radius: 3px;
+}
+.mui-numbox .mui-numbox-input, .mui-numbox .mui-input-numbox
+{
+    display: inline-block;
+    overflow: hidden;
+
+    width: 100% !important;
+    height: 100%;
+    margin: 0;
+    padding: 0 3px !important;
+
+    text-align: center;
+    text-overflow: ellipsis;
+    word-break: normal;
+
+    border: none !important;
+    border-right: solid 1px #ccc !important;
+    border-left: solid 1px #ccc !important;
+    border-radius: 0 !important;
+}
+
+.mui-input-row .mui-numbox
+{
+    float: right;
+
+    margin: 2px 8px;
+}
+
+@font-face {
+    font-family: Muiicons;
+    font-weight: normal;
+    font-style: normal;
+
+    src: url('../fonts/mui.ttf') format('truetype');
+}
+.mui-icon
+{
+    font-family: Muiicons;
+    font-size: 24px;
+    font-weight: normal;
+    font-style: normal;
+    line-height: 1;
+
+    display: inline-block;
+
+    text-decoration: none;
+
+    -webkit-font-smoothing: antialiased;
+}
+.mui-icon.mui-active
+{
+    color: #007aff;
+}
+.mui-icon.mui-right:before
+{
+    float: right;
+
+    padding-left: .2em;
+}
+
+.mui-icon-contact:before
+{
+    content: '\e100';
+}
+
+.mui-icon-person:before
+{
+    content: '\e101';
+}
+
+.mui-icon-personadd:before
+{
+    content: '\e102';
+}
+
+.mui-icon-contact-filled:before
+{
+    content: '\e130';
+}
+
+.mui-icon-person-filled:before
+{
+    content: '\e131';
+}
+
+.mui-icon-personadd-filled:before
+{
+    content: '\e132';
+}
+
+.mui-icon-phone:before
+{
+    content: '\e200';
+}
+
+.mui-icon-email:before
+{
+    content: '\e201';
+}
+
+.mui-icon-chatbubble:before
+{
+    content: '\e202';
+}
+
+.mui-icon-chatboxes:before
+{
+    content: '\e203';
+}
+
+.mui-icon-phone-filled:before
+{
+    content: '\e230';
+}
+
+.mui-icon-email-filled:before
+{
+    content: '\e231';
+}
+
+.mui-icon-chatbubble-filled:before
+{
+    content: '\e232';
+}
+
+.mui-icon-chatboxes-filled:before
+{
+    content: '\e233';
+}
+
+.mui-icon-weibo:before
+{
+    content: '\e260';
+}
+
+.mui-icon-weixin:before
+{
+    content: '\e261';
+}
+
+.mui-icon-pengyouquan:before
+{
+    content: '\e262';
+}
+
+.mui-icon-chat:before
+{
+    content: '\e263';
+}
+
+.mui-icon-qq:before
+{
+    content: '\e264';
+}
+
+.mui-icon-videocam:before
+{
+    content: '\e300';
+}
+
+.mui-icon-camera:before
+{
+    content: '\e301';
+}
+
+.mui-icon-mic:before
+{
+    content: '\e302';
+}
+
+.mui-icon-location:before
+{
+    content: '\e303';
+}
+
+.mui-icon-mic-filled:before, .mui-icon-speech:before
+{
+    content: '\e332';
+}
+
+.mui-icon-location-filled:before
+{
+    content: '\e333';
+}
+
+.mui-icon-micoff:before
+{
+    content: '\e360';
+}
+
+.mui-icon-image:before
+{
+    content: '\e363';
+}
+
+.mui-icon-map:before
+{
+    content: '\e364';
+}
+
+.mui-icon-compose:before
+{
+    content: '\e400';
+}
+
+.mui-icon-trash:before
+{
+    content: '\e401';
+}
+
+.mui-icon-upload:before
+{
+    content: '\e402';
+}
+
+.mui-icon-download:before
+{
+    content: '\e403';
+}
+
+.mui-icon-close:before
+{
+    content: '\e404';
+}
+
+.mui-icon-redo:before
+{
+    content: '\e405';
+}
+
+.mui-icon-undo:before
+{
+    content: '\e406';
+}
+
+.mui-icon-refresh:before
+{
+    content: '\e407';
+}
+
+.mui-icon-star:before
+{
+    content: '\e408';
+}
+
+.mui-icon-plus:before
+{
+    content: '\e409';
+}
+
+.mui-icon-minus:before
+{
+    content: '\e410';
+}
+
+.mui-icon-circle:before, .mui-icon-checkbox:before
+{
+    content: '\e411';
+}
+
+.mui-icon-close-filled:before, .mui-icon-clear:before
+{
+    content: '\e434';
+}
+
+.mui-icon-refresh-filled:before
+{
+    content: '\e437';
+}
+
+.mui-icon-star-filled:before
+{
+    content: '\e438';
+}
+
+.mui-icon-plus-filled:before
+{
+    content: '\e439';
+}
+
+.mui-icon-minus-filled:before
+{
+    content: '\e440';
+}
+
+.mui-icon-circle-filled:before
+{
+    content: '\e441';
+}
+
+.mui-icon-checkbox-filled:before
+{
+    content: '\e442';
+}
+
+.mui-icon-closeempty:before
+{
+    content: '\e460';
+}
+
+.mui-icon-refreshempty:before
+{
+    content: '\e461';
+}
+
+.mui-icon-reload:before
+{
+    content: '\e462';
+}
+
+.mui-icon-starhalf:before
+{
+    content: '\e463';
+}
+
+.mui-icon-spinner:before
+{
+    content: '\e464';
+}
+
+.mui-icon-spinner-cycle:before
+{
+    content: '\e465';
+}
+
+.mui-icon-search:before
+{
+    content: '\e466';
+}
+
+.mui-icon-plusempty:before
+{
+    content: '\e468';
+}
+
+.mui-icon-forward:before
+{
+    content: '\e470';
+}
+
+.mui-icon-back:before, .mui-icon-left-nav:before
+{
+    content: '\e471';
+}
+
+.mui-icon-checkmarkempty:before
+{
+    content: '\e472';
+}
+
+.mui-icon-home:before
+{
+    content: '\e500';
+}
+
+.mui-icon-navigate:before
+{
+    content: '\e501';
+}
+
+.mui-icon-gear:before
+{
+    content: '\e502';
+}
+
+.mui-icon-paperplane:before
+{
+    content: '\e503';
+}
+
+.mui-icon-info:before
+{
+    content: '\e504';
+}
+
+.mui-icon-help:before
+{
+    content: '\e505';
+}
+
+.mui-icon-locked:before
+{
+    content: '\e506';
+}
+
+.mui-icon-more:before
+{
+    content: '\e507';
+}
+
+.mui-icon-flag:before
+{
+    content: '\e508';
+}
+
+.mui-icon-home-filled:before
+{
+    content: '\e530';
+}
+
+.mui-icon-gear-filled:before
+{
+    content: '\e532';
+}
+
+.mui-icon-info-filled:before
+{
+    content: '\e534';
+}
+
+.mui-icon-help-filled:before
+{
+    content: '\e535';
+}
+
+.mui-icon-more-filled:before
+{
+    content: '\e537';
+}
+
+.mui-icon-settings:before
+{
+    content: '\e560';
+}
+
+.mui-icon-list:before
+{
+    content: '\e562';
+}
+
+.mui-icon-bars:before
+{
+    content: '\e563';
+}
+
+.mui-icon-loop:before
+{
+    content: '\e565';
+}
+
+.mui-icon-paperclip:before
+{
+    content: '\e567';
+}
+
+.mui-icon-eye:before
+{
+    content: '\e568';
+}
+
+.mui-icon-arrowup:before
+{
+    content: '\e580';
+}
+
+.mui-icon-arrowdown:before
+{
+    content: '\e581';
+}
+
+.mui-icon-arrowleft:before
+{
+    content: '\e582';
+}
+
+.mui-icon-arrowright:before
+{
+    content: '\e583';
+}
+
+.mui-icon-arrowthinup:before
+{
+    content: '\e584';
+}
+
+.mui-icon-arrowthindown:before
+{
+    content: '\e585';
+}
+
+.mui-icon-arrowthinleft:before
+{
+    content: '\e586';
+}
+
+.mui-icon-arrowthinright:before
+{
+    content: '\e587';
+}
+
+.mui-icon-pulldown:before
+{
+    content: '\e588';
+}
+
+.mui-fullscreen
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+}
+.mui-fullscreen.mui-slider .mui-slider-group
+{
+    height: 100%;
+}
+.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
+{
+    position: absolute;
+    top: 40px;
+    bottom: 0;
+
+    width: 100%;
+    height: auto;
+}
+.mui-fullscreen.mui-slider .mui-slider-item > a
+{
+    top: 50%;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+}
+.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item > a
+{
+    top: auto;
+
+    -webkit-transform: none;
+            transform: none;
+}
+
+.mui-bar-nav ~ .mui-content .mui-slider.mui-fullscreen
+{
+    top: 44px;
+}
+
+.mui-bar-tab ~ .mui-content .mui-slider.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
+{
+    bottom: 50px;
+}
+
+.mui-android.mui-android-4-0 input:focus,
+.mui-android.mui-android-4-0 textarea:focus
+{
+    -webkit-user-modify: inherit;
+}
+
+.mui-android.mui-android-4-2 input,
+.mui-android.mui-android-4-2 textarea, .mui-android.mui-android-4-3 input,
+.mui-android.mui-android-4-3 textarea
+{
+    -webkit-user-select: text;
+}
+
+.mui-ios .mui-table-view-cell
+{
+    -webkit-transform-style: preserve-3d;
+            transform-style: preserve-3d;
+}
+
+.mui-plus-visible, .mui-wechat-visible
+{
+    display: none !important;
+}
+
+.mui-plus-hidden, .mui-wechat-hidden
+{
+    display: block !important;
+}
+
+.mui-tab-item.mui-plus-hidden, .mui-tab-item.mui-wechat-hidden
+{
+    display: table-cell !important;
+}
+
+.mui-plus .mui-plus-visible, .mui-wechat .mui-wechat-visible
+{
+    display: block !important;
+}
+
+.mui-plus .mui-tab-item.mui-plus-visible, .mui-wechat .mui-tab-item.mui-wechat-visible
+{
+    display: table-cell !important;
+}
+
+.mui-plus .mui-plus-hidden, .mui-wechat .mui-wechat-hidden
+{
+    display: none !important;
+}
+
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav
+{
+    height: 64px;
+    padding-top: 20px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content
+{
+    padding-top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content .mui-pull-top-pocket
+{
+    top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary
+{
+    top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary ~ .mui-content
+{
+    padding-top: 94px;
+}
+
+.mui-iframe-wrapper
+{
+    position: absolute;
+    right: 0;
+    left: 0;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-iframe-wrapper iframe
+{
+    width: 100%;
+    height: 100%;
+
+    border: 0;
+}

File diff suppressed because it is too large
+ 4 - 0
hybrid/html/xuanfu/css/mui.min.css


BIN
hybrid/html/xuanfu/fonts/mui.ttf


BIN
hybrid/html/xuanfu/img/guaduandd.png


BIN
hybrid/html/xuanfu/img/jietong.png


BIN
hybrid/html/xuanfu/img/logo.png


BIN
hybrid/html/xuanfu/img/xinxi.png


BIN
hybrid/html/xuanfu/img/y800.mp3


Some files were not shown because too many files changed in this diff