From d1031a4da2b1b7f3f6c6ba8bed517228888ed8cc Mon Sep 17 00:00:00 2001 From: liaoxinyu Date: Tue, 6 May 2025 17:50:55 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 20 + .hbuilderx/launch.json | 33 + .vite/_cert.pem | 51 + .vite/deps/package.json | 1 + App.vue | 579 +++ LICENSE | 201 + README.md | 62 + androidPrivacy.json | 38 + api/emoji.js | 45 + api/friend.js | 48 + api/index.js | 13 + api/login.js | 65 + api/message.js | 291 ++ common/appUpdate.js | 865 ++++ common/config.js | 64 + common/scan.js | 72 + common/socket.js | 193 + components/.DS_Store | Bin 0 -> 6148 bytes components/Empty.vue | 53 + components/Tags.vue | 75 + components/breadcrum.vue | 63 + components/cu-custom.vue | 79 + components/get-qrcode.vue | 433 ++ components/im-touch.vue | 130 + components/im-user.vue | 46 + components/message/im-image.vue | 33 + components/message/im-input.vue | 957 ++++ components/message/im-item.vue | 35 + components/message/im-tab.vue | 50 + components/message/user-select.vue | 292 ++ .../mosowe-canvas-image.vue | 455 ++ components/mosowe-canvas-image/readme.md | 195 + components/mosowe-canvas-image/wxqrcode.js | 1623 +++++++ components/status.vue | 92 + components/yq-avatar/yq-avatar.vue | 1371 ++++++ favicon.ico | Bin 0 -> 9662 bytes hybrid/html/image/guaduan.png | Bin 0 -> 2087 bytes hybrid/html/image/jieting.png | Bin 0 -> 2299 bytes hybrid/html/image/speaker-off.png | Bin 0 -> 3624 bytes hybrid/html/image/speaker.png | Bin 0 -> 3686 bytes hybrid/html/image/video.png | Bin 0 -> 3333 bytes hybrid/html/image/voice-off.png | Bin 0 -> 4541 bytes hybrid/html/image/voice.png | Bin 0 -> 3654 bytes hybrid/html/image/wallpaper.png | Bin 0 -> 24430 bytes hybrid/html/index.html | 613 +++ hybrid/html/js/jsonly.js | 275 ++ hybrid/html/js/uni.webview.js | 1 + hybrid/html/js/utils.js | 11 + hybrid/html/js/vue.js | 1 + hybrid/html/rtc/adapter-latest.js | 3480 +++++++++++++++ hybrid/html/rtc/chrome/chrome_shim.js | 702 +++ hybrid/html/rtc/chrome/getdisplaymedia.js | 50 + hybrid/html/rtc/chrome/getusermedia.js | 188 + hybrid/html/rtc/common_shim.js | 433 ++ hybrid/html/rtc/firefox/firefox_shim.js | 296 ++ hybrid/html/rtc/firefox/getdisplaymedia.js | 36 + hybrid/html/rtc/firefox/getusermedia.js | 67 + hybrid/html/rtc/safari/safari_shim.js | 353 ++ hybrid/html/rtc/utils.js | 263 ++ hybrid/html/voice/calling.mp3 | Bin 0 -> 76213 bytes index.html | 20 + main.js | 54 + manifest.json | 192 + mixins/chat.js | 118 + .../android/uniplugin_fileSelect-release.aar | Bin 0 -> 40988 bytes .../DCTestUniPlugin.framework/DCTestUniPlugin | Bin 0 -> 47360 bytes .../ios/DCTestUniPlugin.framework/Info.plist | Bin 0 -> 766 bytes nativeplugins/lemonjk-FileSelect/package.json | 43 + package-lock.json | 722 +++ package.json | 24 + pages.json | 199 + pages/compass/index.vue | 79 + pages/compass/moments.vue | 140 + pages/contacts/detail.vue | 247 ++ pages/contacts/friend.vue | 150 + pages/contacts/group.vue | 89 + pages/contacts/index.vue | 410 ++ pages/contacts/search.vue | 88 + pages/index/index.vue | 254 ++ pages/index/qrcode.vue | 220 + pages/index/scan.vue | 34 + pages/index/search.vue | 112 + pages/index/userSelection.vue | 337 ++ pages/login/index.vue | 198 + pages/login/register.vue | 182 + pages/message/call.vue | 262 ++ pages/message/chat.vue | 1347 ++++++ pages/message/detail.vue | 638 +++ pages/message/emoji.vue | 225 + pages/message/group/groupUser.vue | 291 ++ pages/message/group/info.vue | 88 + pages/message/index.vue | 349 ++ pages/message/record.vue | 517 +++ pages/message/video.vue | 79 + pages/mine/about.vue | 110 + pages/mine/doc.vue | 114 + pages/mine/index.vue | 168 + pages/mine/profile.vue | 184 + pages/mine/secure.vue | 238 + pages/mine/setting.vue | 92 + pages/mine/webview.vue | 28 + static/css/animation.css | 184 + static/css/icon.css | 1226 ++++++ static/css/iconfont.css | 147 + static/css/main.css | 3912 +++++++++++++++++ static/css/reset.css | 342 ++ static/customicons.css | 20 + static/customicons.ttf | Bin 0 -> 2416 bytes static/fonts/iconfont.ttf | Bin 0 -> 10516 bytes static/fonts/iconfont.woff | Bin 0 -> 7228 bytes static/fonts/iconfont.woff2 | Bin 0 -> 6228 bytes static/image/empty.png | Bin 0 -> 8661 bytes static/image/group.png | Bin 0 -> 9347 bytes static/image/invite.png | Bin 0 -> 11656 bytes static/image/logo.png | Bin 0 -> 12683 bytes static/image/rocket.png | Bin 0 -> 31432 bytes static/image/tabbar/compass-active.svg | 2 + static/image/tabbar/compass.svg | 2 + static/image/tabbar/contacts-active.svg | 2 + static/image/tabbar/contacts.svg | 2 + static/image/tabbar/demo.png | Bin 0 -> 7671 bytes static/image/tabbar/message-active.svg | 2 + static/image/tabbar/message.svg | 2 + static/image/tabbar/mine-active.svg | 2 + static/image/tabbar/mine.svg | 2 + static/image/user-card-bg.jpg | Bin 0 -> 29335 bytes store/index.js | 5 + store/login.js | 42 + store/message.js | 146 + uni.scss | 1 + uni_modules/mp-html/README.md | 193 + uni_modules/mp-html/changelog.md | 129 + .../mp-html/components/mp-html/mp-html.vue | 498 +++ .../mp-html/components/mp-html/node/node.vue | 576 +++ .../mp-html/components/mp-html/parser.js | 1335 ++++++ uni_modules/mp-html/package.json | 76 + .../static/app-plus/mp-html/js/handler.js | 1 + .../app-plus/mp-html/js/uni.webview.min.js | 1 + .../static/app-plus/mp-html/local.html | 1 + uni_modules/mumu-recorder/changelog.md | 4 + .../mumu-recorder/mumu-recorder.vue | 114 + uni_modules/mumu-recorder/package.json | 87 + uni_modules/mumu-recorder/readme.md | 117 + uni_modules/u-ajax/README.md | 81 + uni_modules/u-ajax/changelog.md | 26 + uni_modules/u-ajax/js_sdk/index.d.ts | 105 + uni_modules/u-ajax/js_sdk/index.js | 9 + .../u-ajax/js_sdk/lib/adapters/Request.js | 58 + .../u-ajax/js_sdk/lib/adapters/http.js | 30 + uni_modules/u-ajax/js_sdk/lib/core/Ajax.js | 89 + .../js_sdk/lib/core/InterceptorManager.js | 34 + .../u-ajax/js_sdk/lib/core/dispatchRequest.js | 35 + .../u-ajax/js_sdk/lib/core/handleCancel.js | 35 + uni_modules/u-ajax/js_sdk/lib/defaults.js | 22 + .../u-ajax/js_sdk/lib/helpers/buildURL.js | 83 + .../u-ajax/js_sdk/lib/helpers/detachConfig.js | 36 + .../u-ajax/js_sdk/lib/helpers/isCallback.js | 8 + .../u-ajax/js_sdk/lib/helpers/mergeConfig.js | 41 + uni_modules/u-ajax/js_sdk/lib/utils.js | 92 + uni_modules/u-ajax/package.json | 71 + uni_modules/uni-badge/changelog.md | 29 + .../components/uni-badge/uni-badge.vue | 268 ++ uni_modules/uni-badge/package.json | 88 + uni_modules/uni-badge/readme.md | 10 + uni_modules/uni-breadcrumb/changelog.md | 6 + .../uni-breadcrumb-item.vue | 121 + .../uni-breadcrumb/uni-breadcrumb.vue | 41 + uni_modules/uni-breadcrumb/package.json | 88 + uni_modules/uni-breadcrumb/readme.md | 66 + uni_modules/uni-calendar/changelog.md | 16 + .../components/uni-calendar/calendar.js | 546 +++ .../components/uni-calendar/i18n/en.json | 12 + .../components/uni-calendar/i18n/index.js | 8 + .../components/uni-calendar/i18n/zh-Hans.json | 12 + .../components/uni-calendar/i18n/zh-Hant.json | 12 + .../uni-calendar/uni-calendar-item.vue | 188 + .../components/uni-calendar/uni-calendar.vue | 562 +++ .../components/uni-calendar/util.js | 350 ++ uni_modules/uni-calendar/package.json | 88 + uni_modules/uni-calendar/readme.md | 103 + uni_modules/uni-card/changelog.md | 26 + .../uni-card/components/uni-card/uni-card.vue | 270 ++ uni_modules/uni-card/package.json | 90 + uni_modules/uni-card/readme.md | 12 + uni_modules/uni-collapse/changelog.md | 36 + .../uni-collapse-item/uni-collapse-item.vue | 402 ++ .../components/uni-collapse/uni-collapse.vue | 147 + uni_modules/uni-collapse/package.json | 89 + uni_modules/uni-collapse/readme.md | 12 + uni_modules/uni-combox/changelog.md | 15 + .../components/uni-combox/uni-combox.vue | 275 ++ uni_modules/uni-combox/package.json | 90 + uni_modules/uni-combox/readme.md | 11 + uni_modules/uni-countdown/changelog.md | 24 + .../components/uni-countdown/i18n/en.json | 6 + .../components/uni-countdown/i18n/index.js | 8 + .../uni-countdown/i18n/zh-Hans.json | 6 + .../uni-countdown/i18n/zh-Hant.json | 6 + .../uni-countdown/uni-countdown.vue | 271 ++ uni_modules/uni-countdown/package.json | 86 + uni_modules/uni-countdown/readme.md | 10 + uni_modules/uni-data-checkbox/changelog.md | 43 + .../uni-data-checkbox/uni-data-checkbox.vue | 817 ++++ uni_modules/uni-data-checkbox/package.json | 87 + uni_modules/uni-data-checkbox/readme.md | 18 + uni_modules/uni-data-picker/changelog.md | 64 + .../components/uni-data-picker/keypress.js | 45 + .../uni-data-picker/uni-data-picker.vue | 554 +++ .../uni-data-pickerview/uni-data-picker.js | 563 +++ .../uni-data-pickerview.vue | 333 ++ uni_modules/uni-data-picker/package.json | 93 + uni_modules/uni-data-picker/readme.md | 22 + uni_modules/uni-data-select/changelog.md | 16 + .../uni-data-select/uni-data-select.vue | 426 ++ uni_modules/uni-data-select/package.json | 88 + uni_modules/uni-data-select/readme.md | 8 + uni_modules/uni-dateformat/changelog.md | 10 + .../components/uni-dateformat/date-format.js | 200 + .../uni-dateformat/uni-dateformat.vue | 88 + uni_modules/uni-dateformat/package.json | 88 + uni_modules/uni-dateformat/readme.md | 11 + uni_modules/uni-datetime-picker/changelog.md | 93 + .../uni-datetime-picker/calendar-item.vue | 185 + .../uni-datetime-picker/calendar.vue | 907 ++++ .../uni-datetime-picker/i18n/en.json | 22 + .../uni-datetime-picker/i18n/index.js | 8 + .../uni-datetime-picker/i18n/zh-Hans.json | 22 + .../uni-datetime-picker/i18n/zh-Hant.json | 22 + .../uni-datetime-picker/keypress.js | 45 + .../uni-datetime-picker/time-picker.vue | 927 ++++ .../uni-datetime-picker.vue | 1012 +++++ .../components/uni-datetime-picker/util.js | 410 ++ uni_modules/uni-datetime-picker/package.json | 90 + uni_modules/uni-datetime-picker/readme.md | 21 + uni_modules/uni-drawer/changelog.md | 13 + .../components/uni-drawer/keypress.js | 45 + .../components/uni-drawer/uni-drawer.vue | 183 + uni_modules/uni-drawer/package.json | 87 + uni_modules/uni-drawer/readme.md | 10 + uni_modules/uni-easyinput/changelog.md | 47 + .../components/uni-easyinput/common.js | 56 + .../uni-easyinput/uni-easyinput.vue | 593 +++ uni_modules/uni-easyinput/package.json | 90 + uni_modules/uni-easyinput/readme.md | 11 + uni_modules/uni-fab/changelog.md | 17 + .../uni-fab/components/uni-fab/uni-fab.vue | 475 ++ uni_modules/uni-fab/package.json | 87 + uni_modules/uni-fab/readme.md | 9 + uni_modules/uni-fav/changelog.md | 19 + .../uni-fav/components/uni-fav/i18n/en.json | 4 + .../uni-fav/components/uni-fav/i18n/index.js | 8 + .../components/uni-fav/i18n/zh-Hans.json | 4 + .../components/uni-fav/i18n/zh-Hant.json | 4 + .../uni-fav/components/uni-fav/uni-fav.vue | 161 + uni_modules/uni-fav/package.json | 89 + uni_modules/uni-fav/readme.md | 10 + uni_modules/uni-file-picker/changelog.md | 63 + .../uni-file-picker/choose-and-upload-file.js | 224 + .../uni-file-picker/uni-file-picker.vue | 656 +++ .../uni-file-picker/upload-file.vue | 325 ++ .../uni-file-picker/upload-image.vue | 292 ++ .../components/uni-file-picker/utils.js | 109 + uni_modules/uni-file-picker/package.json | 86 + uni_modules/uni-file-picker/readme.md | 11 + uni_modules/uni-forms/changelog.md | 86 + .../uni-forms-item/uni-forms-item.vue | 627 +++ .../components/uni-forms/uni-forms.vue | 397 ++ .../uni-forms/components/uni-forms/utils.js | 293 ++ .../components/uni-forms/validate.js | 486 ++ uni_modules/uni-forms/package.json | 91 + uni_modules/uni-forms/readme.md | 23 + uni_modules/uni-goods-nav/changelog.md | 18 + .../components/uni-goods-nav/i18n/en.json | 6 + .../components/uni-goods-nav/i18n/index.js | 8 + .../uni-goods-nav/i18n/zh-Hans.json | 6 + .../uni-goods-nav/i18n/zh-Hant.json | 6 + .../uni-goods-nav/uni-goods-nav.vue | 229 + uni_modules/uni-goods-nav/package.json | 88 + uni_modules/uni-goods-nav/readme.md | 10 + uni_modules/uni-grid/changelog.md | 13 + .../uni-grid-item/uni-grid-item.vue | 127 + .../uni-grid/components/uni-grid/uni-grid.vue | 142 + uni_modules/uni-grid/package.json | 86 + uni_modules/uni-grid/readme.md | 11 + uni_modules/uni-group/changelog.md | 16 + .../components/uni-group/uni-group.vue | 134 + uni_modules/uni-group/package.json | 87 + uni_modules/uni-group/readme.md | 9 + uni_modules/uni-icons/changelog.md | 22 + .../uni-icons/components/uni-icons/icons.js | 1169 +++++ .../components/uni-icons/uni-icons.vue | 96 + .../components/uni-icons/uniicons.css | 663 +++ .../components/uni-icons/uniicons.ttf | Bin 0 -> 35760 bytes uni_modules/uni-icons/package.json | 86 + uni_modules/uni-icons/readme.md | 8 + uni_modules/uni-indexed-list/changelog.md | 17 + .../uni-indexed-list-item.vue | 144 + .../uni-indexed-list/uni-indexed-list.vue | 367 ++ uni_modules/uni-indexed-list/package.json | 89 + uni_modules/uni-indexed-list/readme.md | 11 + uni_modules/uni-link/changelog.md | 17 + .../uni-link/components/uni-link/uni-link.vue | 128 + uni_modules/uni-link/package.json | 87 + uni_modules/uni-link/readme.md | 11 + uni_modules/uni-list/changelog.md | 20 + .../components/uni-list-ad/uni-list-ad.vue | 107 + .../uni-list-chat/uni-list-chat.scss | 58 + .../uni-list-chat/uni-list-chat.vue | 538 +++ .../uni-list-item/uni-list-item.vue | 454 ++ .../uni-list/components/uni-list/uni-list.vue | 108 + .../components/uni-list/uni-refresh.vue | 65 + .../components/uni-list/uni-refresh.wxs | 87 + uni_modules/uni-list/package.json | 91 + uni_modules/uni-list/readme.md | 346 ++ uni_modules/uni-load-more/changelog.md | 19 + .../components/uni-load-more/i18n/en.json | 5 + .../components/uni-load-more/i18n/index.js | 8 + .../uni-load-more/i18n/zh-Hans.json | 5 + .../uni-load-more/i18n/zh-Hant.json | 5 + .../uni-load-more/uni-load-more.vue | 399 ++ uni_modules/uni-load-more/package.json | 86 + uni_modules/uni-load-more/readme.md | 14 + uni_modules/uni-nav-bar/changelog.md | 41 + .../components/uni-nav-bar/uni-nav-bar.vue | 348 ++ .../components/uni-nav-bar/uni-status-bar.vue | 27 + uni_modules/uni-nav-bar/package.json | 89 + uni_modules/uni-nav-bar/readme.md | 15 + uni_modules/uni-notice-bar/changelog.md | 16 + .../uni-notice-bar/uni-notice-bar.vue | 394 ++ uni_modules/uni-notice-bar/package.json | 90 + uni_modules/uni-notice-bar/readme.md | 13 + uni_modules/uni-number-box/changelog.md | 25 + .../uni-number-box/uni-number-box.vue | 221 + uni_modules/uni-number-box/package.json | 85 + uni_modules/uni-number-box/readme.md | 13 + uni_modules/uni-pagination/changelog.md | 20 + .../components/uni-pagination/i18n/en.json | 4 + .../components/uni-pagination/i18n/es.json | 4 + .../components/uni-pagination/i18n/fr.json | 4 + .../components/uni-pagination/i18n/index.js | 12 + .../uni-pagination/i18n/zh-Hans.json | 4 + .../uni-pagination/i18n/zh-Hant.json | 4 + .../uni-pagination/uni-pagination.vue | 409 ++ uni_modules/uni-pagination/package.json | 86 + uni_modules/uni-pagination/readme.md | 13 + uni_modules/uni-popup/changelog.md | 60 + .../components/uni-popup-dialog/keypress.js | 45 + .../uni-popup-dialog/uni-popup-dialog.vue | 271 ++ .../uni-popup-message/uni-popup-message.vue | 143 + .../uni-popup-share/uni-popup-share.vue | 187 + .../components/uni-popup/i18n/en.json | 7 + .../components/uni-popup/i18n/index.js | 8 + .../components/uni-popup/i18n/zh-Hans.json | 7 + .../components/uni-popup/i18n/zh-Hant.json | 7 + .../components/uni-popup/keypress.js | 45 + .../uni-popup/components/uni-popup/popup.js | 26 + .../components/uni-popup/uni-popup.vue | 474 ++ uni_modules/uni-popup/package.json | 90 + uni_modules/uni-popup/readme.md | 17 + uni_modules/uni-rate/changelog.md | 25 + .../uni-rate/components/uni-rate/uni-rate.vue | 361 ++ uni_modules/uni-rate/package.json | 88 + uni_modules/uni-rate/readme.md | 12 + uni_modules/uni-row/changelog.md | 10 + .../uni-row/components/uni-col/uni-col.vue | 317 ++ .../uni-row/components/uni-row/uni-row.vue | 190 + uni_modules/uni-row/package.json | 87 + uni_modules/uni-row/readme.md | 10 + uni_modules/uni-scss/changelog.md | 8 + uni_modules/uni-scss/index.scss | 1 + uni_modules/uni-scss/package.json | 82 + uni_modules/uni-scss/readme.md | 4 + uni_modules/uni-scss/styles/index.scss | 7 + .../uni-scss/styles/setting/_border.scss | 3 + .../uni-scss/styles/setting/_color.scss | 66 + .../uni-scss/styles/setting/_radius.scss | 55 + .../uni-scss/styles/setting/_space.scss | 56 + .../uni-scss/styles/setting/_styles.scss | 167 + .../uni-scss/styles/setting/_text.scss | 24 + .../uni-scss/styles/setting/_variables.scss | 146 + .../uni-scss/styles/tools/functions.scss | 19 + uni_modules/uni-scss/theme.scss | 31 + uni_modules/uni-scss/variables.scss | 62 + uni_modules/uni-search-bar/changelog.md | 33 + .../components/uni-search-bar/i18n/en.json | 4 + .../components/uni-search-bar/i18n/index.js | 8 + .../uni-search-bar/i18n/zh-Hans.json | 4 + .../uni-search-bar/i18n/zh-Hant.json | 4 + .../uni-search-bar/uni-search-bar.vue | 298 ++ uni_modules/uni-search-bar/package.json | 89 + uni_modules/uni-search-bar/readme.md | 14 + uni_modules/uni-section/changelog.md | 2 + .../components/uni-section/uni-section.vue | 167 + uni_modules/uni-section/package.json | 87 + uni_modules/uni-section/readme.md | 8 + .../uni-segmented-control/changelog.md | 9 + .../uni-segmented-control.vue | 145 + .../uni-segmented-control/package.json | 87 + uni_modules/uni-segmented-control/readme.md | 13 + uni_modules/uni-steps/changelog.md | 16 + .../components/uni-steps/uni-steps.vue | 269 ++ uni_modules/uni-steps/package.json | 89 + uni_modules/uni-steps/readme.md | 13 + uni_modules/uni-swipe-action/changelog.md | 41 + .../uni-swipe-action-item/bindingx.js | 302 ++ .../components/uni-swipe-action-item/isPC.js | 12 + .../uni-swipe-action-item/mpalipay.js | 193 + .../uni-swipe-action-item/mpother.js | 259 ++ .../components/uni-swipe-action-item/mpwxs.js | 83 + .../uni-swipe-action-item/render.js | 270 ++ .../uni-swipe-action-item.vue | 347 ++ .../components/uni-swipe-action-item/wx.wxs | 341 ++ .../uni-swipe-action/uni-swipe-action.vue | 60 + uni_modules/uni-swipe-action/package.json | 87 + uni_modules/uni-swipe-action/readme.md | 11 + uni_modules/uni-swiper-dot/changelog.md | 12 + .../uni-swiper-dot/uni-swiper-dot.vue | 218 + uni_modules/uni-swiper-dot/package.json | 87 + uni_modules/uni-swiper-dot/readme.md | 11 + uni_modules/uni-table/changelog.md | 23 + .../components/uni-table/uni-table.vue | 455 ++ .../components/uni-tbody/uni-tbody.vue | 29 + .../uni-table/components/uni-td/uni-td.vue | 90 + .../components/uni-th/filter-dropdown.vue | 503 +++ .../uni-table/components/uni-th/uni-th.vue | 278 ++ .../components/uni-thead/uni-thead.vue | 129 + .../components/uni-tr/table-checkbox.vue | 179 + .../uni-table/components/uni-tr/uni-tr.vue | 171 + uni_modules/uni-table/i18n/en.json | 9 + uni_modules/uni-table/i18n/es.json | 9 + uni_modules/uni-table/i18n/fr.json | 9 + uni_modules/uni-table/i18n/index.js | 12 + uni_modules/uni-table/i18n/zh-Hans.json | 9 + uni_modules/uni-table/i18n/zh-Hant.json | 9 + uni_modules/uni-table/package.json | 86 + uni_modules/uni-table/readme.md | 13 + uni_modules/uni-tag/changelog.md | 21 + .../uni-tag/components/uni-tag/uni-tag.vue | 252 ++ uni_modules/uni-tag/package.json | 87 + uni_modules/uni-tag/readme.md | 13 + uni_modules/uni-test/changelog.md | 39 + .../uni-test/components/uni-test/uni-test.vue | 26 + uni_modules/uni-test/package.json | 83 + uni_modules/uni-test/readme.md | 10 + uni_modules/uni-title/changelog.md | 10 + .../components/uni-title/uni-title.vue | 171 + uni_modules/uni-title/package.json | 88 + uni_modules/uni-title/readme.md | 14 + uni_modules/uni-tooltip/changelog.md | 10 + .../components/uni-tooltip/uni-tooltip.vue | 68 + uni_modules/uni-tooltip/package.json | 88 + uni_modules/uni-tooltip/readme.md | 8 + uni_modules/uni-transition/changelog.md | 20 + .../uni-transition/createAnimation.js | 128 + .../uni-transition/uni-transition.vue | 277 ++ uni_modules/uni-transition/package.json | 87 + uni_modules/uni-transition/readme.md | 11 + uni_modules/uni-ui/changelog.md | 447 ++ .../uni-ui/components/uni-ui/uni-ui.vue | 7 + uni_modules/uni-ui/package.json | 129 + uni_modules/uni-ui/readme.md | 247 ++ utils/appUpdate.js | 830 ++++ utils/array.js | 63 + utils/edit.js | 449 ++ utils/emoji.js | 370 ++ utils/observer.js | 36 + utils/permission.js | 272 ++ utils/request.js | 138 + utils/utils.js | 928 ++++ 469 files changed, 74311 insertions(+) create mode 100644 .gitignore create mode 100644 .hbuilderx/launch.json create mode 100644 .vite/_cert.pem create mode 100644 .vite/deps/package.json create mode 100644 App.vue create mode 100644 LICENSE create mode 100644 README.md create mode 100644 androidPrivacy.json create mode 100644 api/emoji.js create mode 100644 api/friend.js create mode 100644 api/index.js create mode 100644 api/login.js create mode 100644 api/message.js create mode 100644 common/appUpdate.js create mode 100644 common/config.js create mode 100644 common/scan.js create mode 100644 common/socket.js create mode 100644 components/.DS_Store create mode 100644 components/Empty.vue create mode 100644 components/Tags.vue create mode 100644 components/breadcrum.vue create mode 100644 components/cu-custom.vue create mode 100644 components/get-qrcode.vue create mode 100644 components/im-touch.vue create mode 100644 components/im-user.vue create mode 100644 components/message/im-image.vue create mode 100644 components/message/im-input.vue create mode 100644 components/message/im-item.vue create mode 100644 components/message/im-tab.vue create mode 100644 components/message/user-select.vue create mode 100644 components/mosowe-canvas-image/mosowe-canvas-image.vue create mode 100644 components/mosowe-canvas-image/readme.md create mode 100644 components/mosowe-canvas-image/wxqrcode.js create mode 100644 components/status.vue create mode 100644 components/yq-avatar/yq-avatar.vue create mode 100644 favicon.ico create mode 100644 hybrid/html/image/guaduan.png create mode 100644 hybrid/html/image/jieting.png create mode 100644 hybrid/html/image/speaker-off.png create mode 100644 hybrid/html/image/speaker.png create mode 100644 hybrid/html/image/video.png create mode 100644 hybrid/html/image/voice-off.png create mode 100644 hybrid/html/image/voice.png create mode 100644 hybrid/html/image/wallpaper.png create mode 100644 hybrid/html/index.html create mode 100644 hybrid/html/js/jsonly.js create mode 100644 hybrid/html/js/uni.webview.js create mode 100644 hybrid/html/js/utils.js create mode 100644 hybrid/html/js/vue.js create mode 100644 hybrid/html/rtc/adapter-latest.js create mode 100644 hybrid/html/rtc/chrome/chrome_shim.js create mode 100644 hybrid/html/rtc/chrome/getdisplaymedia.js create mode 100644 hybrid/html/rtc/chrome/getusermedia.js create mode 100644 hybrid/html/rtc/common_shim.js create mode 100644 hybrid/html/rtc/firefox/firefox_shim.js create mode 100644 hybrid/html/rtc/firefox/getdisplaymedia.js create mode 100644 hybrid/html/rtc/firefox/getusermedia.js create mode 100644 hybrid/html/rtc/safari/safari_shim.js create mode 100644 hybrid/html/rtc/utils.js create mode 100644 hybrid/html/voice/calling.mp3 create mode 100644 index.html create mode 100644 main.js create mode 100644 manifest.json create mode 100644 mixins/chat.js create mode 100644 nativeplugins/lemonjk-FileSelect/android/uniplugin_fileSelect-release.aar create mode 100644 nativeplugins/lemonjk-FileSelect/ios/DCTestUniPlugin.framework/DCTestUniPlugin create mode 100644 nativeplugins/lemonjk-FileSelect/ios/DCTestUniPlugin.framework/Info.plist create mode 100644 nativeplugins/lemonjk-FileSelect/package.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pages.json create mode 100644 pages/compass/index.vue create mode 100644 pages/compass/moments.vue create mode 100644 pages/contacts/detail.vue create mode 100644 pages/contacts/friend.vue create mode 100644 pages/contacts/group.vue create mode 100644 pages/contacts/index.vue create mode 100644 pages/contacts/search.vue create mode 100644 pages/index/index.vue create mode 100644 pages/index/qrcode.vue create mode 100644 pages/index/scan.vue create mode 100644 pages/index/search.vue create mode 100644 pages/index/userSelection.vue create mode 100644 pages/login/index.vue create mode 100644 pages/login/register.vue create mode 100644 pages/message/call.vue create mode 100644 pages/message/chat.vue create mode 100644 pages/message/detail.vue create mode 100644 pages/message/emoji.vue create mode 100644 pages/message/group/groupUser.vue create mode 100644 pages/message/group/info.vue create mode 100644 pages/message/index.vue create mode 100644 pages/message/record.vue create mode 100644 pages/message/video.vue create mode 100644 pages/mine/about.vue create mode 100644 pages/mine/doc.vue create mode 100644 pages/mine/index.vue create mode 100644 pages/mine/profile.vue create mode 100644 pages/mine/secure.vue create mode 100644 pages/mine/setting.vue create mode 100644 pages/mine/webview.vue create mode 100644 static/css/animation.css create mode 100644 static/css/icon.css create mode 100644 static/css/iconfont.css create mode 100644 static/css/main.css create mode 100644 static/css/reset.css create mode 100644 static/customicons.css create mode 100644 static/customicons.ttf create mode 100644 static/fonts/iconfont.ttf create mode 100644 static/fonts/iconfont.woff create mode 100644 static/fonts/iconfont.woff2 create mode 100644 static/image/empty.png create mode 100644 static/image/group.png create mode 100644 static/image/invite.png create mode 100644 static/image/logo.png create mode 100644 static/image/rocket.png create mode 100644 static/image/tabbar/compass-active.svg create mode 100644 static/image/tabbar/compass.svg create mode 100644 static/image/tabbar/contacts-active.svg create mode 100644 static/image/tabbar/contacts.svg create mode 100644 static/image/tabbar/demo.png create mode 100644 static/image/tabbar/message-active.svg create mode 100644 static/image/tabbar/message.svg create mode 100644 static/image/tabbar/mine-active.svg create mode 100644 static/image/tabbar/mine.svg create mode 100644 static/image/user-card-bg.jpg create mode 100644 store/index.js create mode 100644 store/login.js create mode 100644 store/message.js create mode 100644 uni.scss create mode 100644 uni_modules/mp-html/README.md create mode 100644 uni_modules/mp-html/changelog.md create mode 100644 uni_modules/mp-html/components/mp-html/mp-html.vue create mode 100644 uni_modules/mp-html/components/mp-html/node/node.vue create mode 100644 uni_modules/mp-html/components/mp-html/parser.js create mode 100644 uni_modules/mp-html/package.json create mode 100644 uni_modules/mp-html/static/app-plus/mp-html/js/handler.js create mode 100644 uni_modules/mp-html/static/app-plus/mp-html/js/uni.webview.min.js create mode 100644 uni_modules/mp-html/static/app-plus/mp-html/local.html create mode 100644 uni_modules/mumu-recorder/changelog.md create mode 100644 uni_modules/mumu-recorder/components/mumu-recorder/mumu-recorder.vue create mode 100644 uni_modules/mumu-recorder/package.json create mode 100644 uni_modules/mumu-recorder/readme.md create mode 100644 uni_modules/u-ajax/README.md create mode 100644 uni_modules/u-ajax/changelog.md create mode 100644 uni_modules/u-ajax/js_sdk/index.d.ts create mode 100644 uni_modules/u-ajax/js_sdk/index.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/adapters/Request.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/adapters/http.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/core/Ajax.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/core/InterceptorManager.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/core/dispatchRequest.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/core/handleCancel.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/defaults.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/helpers/buildURL.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/helpers/detachConfig.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/helpers/isCallback.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/helpers/mergeConfig.js create mode 100644 uni_modules/u-ajax/js_sdk/lib/utils.js create mode 100644 uni_modules/u-ajax/package.json create mode 100644 uni_modules/uni-badge/changelog.md create mode 100644 uni_modules/uni-badge/components/uni-badge/uni-badge.vue create mode 100644 uni_modules/uni-badge/package.json create mode 100644 uni_modules/uni-badge/readme.md create mode 100644 uni_modules/uni-breadcrumb/changelog.md create mode 100644 uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue create mode 100644 uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue create mode 100644 uni_modules/uni-breadcrumb/package.json create mode 100644 uni_modules/uni-breadcrumb/readme.md create mode 100644 uni_modules/uni-calendar/changelog.md create mode 100644 uni_modules/uni-calendar/components/uni-calendar/calendar.js create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/en.json create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/index.js create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json create mode 100644 uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue create mode 100644 uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue create mode 100644 uni_modules/uni-calendar/components/uni-calendar/util.js create mode 100644 uni_modules/uni-calendar/package.json create mode 100644 uni_modules/uni-calendar/readme.md create mode 100644 uni_modules/uni-card/changelog.md create mode 100644 uni_modules/uni-card/components/uni-card/uni-card.vue create mode 100644 uni_modules/uni-card/package.json create mode 100644 uni_modules/uni-card/readme.md create mode 100644 uni_modules/uni-collapse/changelog.md create mode 100644 uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue create mode 100644 uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue create mode 100644 uni_modules/uni-collapse/package.json create mode 100644 uni_modules/uni-collapse/readme.md create mode 100644 uni_modules/uni-combox/changelog.md create mode 100644 uni_modules/uni-combox/components/uni-combox/uni-combox.vue create mode 100644 uni_modules/uni-combox/package.json create mode 100644 uni_modules/uni-combox/readme.md create mode 100644 uni_modules/uni-countdown/changelog.md create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/en.json create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/index.js create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json create mode 100644 uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue create mode 100644 uni_modules/uni-countdown/package.json create mode 100644 uni_modules/uni-countdown/readme.md create mode 100644 uni_modules/uni-data-checkbox/changelog.md create mode 100644 uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue create mode 100644 uni_modules/uni-data-checkbox/package.json create mode 100644 uni_modules/uni-data-checkbox/readme.md create mode 100644 uni_modules/uni-data-picker/changelog.md create mode 100644 uni_modules/uni-data-picker/components/uni-data-picker/keypress.js create mode 100644 uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue create mode 100644 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js create mode 100644 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue create mode 100644 uni_modules/uni-data-picker/package.json create mode 100644 uni_modules/uni-data-picker/readme.md create mode 100644 uni_modules/uni-data-select/changelog.md create mode 100644 uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue create mode 100644 uni_modules/uni-data-select/package.json create mode 100644 uni_modules/uni-data-select/readme.md create mode 100644 uni_modules/uni-dateformat/changelog.md create mode 100644 uni_modules/uni-dateformat/components/uni-dateformat/date-format.js create mode 100644 uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue create mode 100644 uni_modules/uni-dateformat/package.json create mode 100644 uni_modules/uni-dateformat/readme.md create mode 100644 uni_modules/uni-datetime-picker/changelog.md create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js create mode 100644 uni_modules/uni-datetime-picker/package.json create mode 100644 uni_modules/uni-datetime-picker/readme.md create mode 100644 uni_modules/uni-drawer/changelog.md create mode 100644 uni_modules/uni-drawer/components/uni-drawer/keypress.js create mode 100644 uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue create mode 100644 uni_modules/uni-drawer/package.json create mode 100644 uni_modules/uni-drawer/readme.md create mode 100644 uni_modules/uni-easyinput/changelog.md create mode 100644 uni_modules/uni-easyinput/components/uni-easyinput/common.js create mode 100644 uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue create mode 100644 uni_modules/uni-easyinput/package.json create mode 100644 uni_modules/uni-easyinput/readme.md create mode 100644 uni_modules/uni-fab/changelog.md create mode 100644 uni_modules/uni-fab/components/uni-fab/uni-fab.vue create mode 100644 uni_modules/uni-fab/package.json create mode 100644 uni_modules/uni-fab/readme.md create mode 100644 uni_modules/uni-fav/changelog.md create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/en.json create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/index.js create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json create mode 100644 uni_modules/uni-fav/components/uni-fav/uni-fav.vue create mode 100644 uni_modules/uni-fav/package.json create mode 100644 uni_modules/uni-fav/readme.md create mode 100644 uni_modules/uni-file-picker/changelog.md create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/utils.js create mode 100644 uni_modules/uni-file-picker/package.json create mode 100644 uni_modules/uni-file-picker/readme.md create mode 100644 uni_modules/uni-forms/changelog.md create mode 100644 uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue create mode 100644 uni_modules/uni-forms/components/uni-forms/uni-forms.vue create mode 100644 uni_modules/uni-forms/components/uni-forms/utils.js create mode 100644 uni_modules/uni-forms/components/uni-forms/validate.js create mode 100644 uni_modules/uni-forms/package.json create mode 100644 uni_modules/uni-forms/readme.md create mode 100644 uni_modules/uni-goods-nav/changelog.md create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue create mode 100644 uni_modules/uni-goods-nav/package.json create mode 100644 uni_modules/uni-goods-nav/readme.md create mode 100644 uni_modules/uni-grid/changelog.md create mode 100644 uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue create mode 100644 uni_modules/uni-grid/components/uni-grid/uni-grid.vue create mode 100644 uni_modules/uni-grid/package.json create mode 100644 uni_modules/uni-grid/readme.md create mode 100644 uni_modules/uni-group/changelog.md create mode 100644 uni_modules/uni-group/components/uni-group/uni-group.vue create mode 100644 uni_modules/uni-group/package.json create mode 100644 uni_modules/uni-group/readme.md create mode 100644 uni_modules/uni-icons/changelog.md create mode 100644 uni_modules/uni-icons/components/uni-icons/icons.js create mode 100644 uni_modules/uni-icons/components/uni-icons/uni-icons.vue create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.css create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.ttf create mode 100644 uni_modules/uni-icons/package.json create mode 100644 uni_modules/uni-icons/readme.md create mode 100644 uni_modules/uni-indexed-list/changelog.md create mode 100644 uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue create mode 100644 uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue create mode 100644 uni_modules/uni-indexed-list/package.json create mode 100644 uni_modules/uni-indexed-list/readme.md create mode 100644 uni_modules/uni-link/changelog.md create mode 100644 uni_modules/uni-link/components/uni-link/uni-link.vue create mode 100644 uni_modules/uni-link/package.json create mode 100644 uni_modules/uni-link/readme.md create mode 100644 uni_modules/uni-list/changelog.md create mode 100644 uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue create mode 100644 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss create mode 100644 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue create mode 100644 uni_modules/uni-list/components/uni-list-item/uni-list-item.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-list.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-refresh.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-refresh.wxs create mode 100644 uni_modules/uni-list/package.json create mode 100644 uni_modules/uni-list/readme.md create mode 100644 uni_modules/uni-load-more/changelog.md create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/en.json create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/index.js create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json create mode 100644 uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue create mode 100644 uni_modules/uni-load-more/package.json create mode 100644 uni_modules/uni-load-more/readme.md create mode 100644 uni_modules/uni-nav-bar/changelog.md create mode 100644 uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue create mode 100644 uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue create mode 100644 uni_modules/uni-nav-bar/package.json create mode 100644 uni_modules/uni-nav-bar/readme.md create mode 100644 uni_modules/uni-notice-bar/changelog.md create mode 100644 uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue create mode 100644 uni_modules/uni-notice-bar/package.json create mode 100644 uni_modules/uni-notice-bar/readme.md create mode 100644 uni_modules/uni-number-box/changelog.md create mode 100644 uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue create mode 100644 uni_modules/uni-number-box/package.json create mode 100644 uni_modules/uni-number-box/readme.md create mode 100644 uni_modules/uni-pagination/changelog.md create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/en.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/es.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/index.js create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue create mode 100644 uni_modules/uni-pagination/package.json create mode 100644 uni_modules/uni-pagination/readme.md create mode 100644 uni_modules/uni-popup/changelog.md create mode 100644 uni_modules/uni-popup/components/uni-popup-dialog/keypress.js create mode 100644 uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue create mode 100644 uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue create mode 100644 uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/en.json create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/index.js create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json create mode 100644 uni_modules/uni-popup/components/uni-popup/keypress.js create mode 100644 uni_modules/uni-popup/components/uni-popup/popup.js create mode 100644 uni_modules/uni-popup/components/uni-popup/uni-popup.vue create mode 100644 uni_modules/uni-popup/package.json create mode 100644 uni_modules/uni-popup/readme.md create mode 100644 uni_modules/uni-rate/changelog.md create mode 100644 uni_modules/uni-rate/components/uni-rate/uni-rate.vue create mode 100644 uni_modules/uni-rate/package.json create mode 100644 uni_modules/uni-rate/readme.md create mode 100644 uni_modules/uni-row/changelog.md create mode 100644 uni_modules/uni-row/components/uni-col/uni-col.vue create mode 100644 uni_modules/uni-row/components/uni-row/uni-row.vue create mode 100644 uni_modules/uni-row/package.json create mode 100644 uni_modules/uni-row/readme.md create mode 100644 uni_modules/uni-scss/changelog.md create mode 100644 uni_modules/uni-scss/index.scss create mode 100644 uni_modules/uni-scss/package.json create mode 100644 uni_modules/uni-scss/readme.md create mode 100644 uni_modules/uni-scss/styles/index.scss create mode 100644 uni_modules/uni-scss/styles/setting/_border.scss create mode 100644 uni_modules/uni-scss/styles/setting/_color.scss create mode 100644 uni_modules/uni-scss/styles/setting/_radius.scss create mode 100644 uni_modules/uni-scss/styles/setting/_space.scss create mode 100644 uni_modules/uni-scss/styles/setting/_styles.scss create mode 100644 uni_modules/uni-scss/styles/setting/_text.scss create mode 100644 uni_modules/uni-scss/styles/setting/_variables.scss create mode 100644 uni_modules/uni-scss/styles/tools/functions.scss create mode 100644 uni_modules/uni-scss/theme.scss create mode 100644 uni_modules/uni-scss/variables.scss create mode 100644 uni_modules/uni-search-bar/changelog.md create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue create mode 100644 uni_modules/uni-search-bar/package.json create mode 100644 uni_modules/uni-search-bar/readme.md create mode 100644 uni_modules/uni-section/changelog.md create mode 100644 uni_modules/uni-section/components/uni-section/uni-section.vue create mode 100644 uni_modules/uni-section/package.json create mode 100644 uni_modules/uni-section/readme.md create mode 100644 uni_modules/uni-segmented-control/changelog.md create mode 100644 uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue create mode 100644 uni_modules/uni-segmented-control/package.json create mode 100644 uni_modules/uni-segmented-control/readme.md create mode 100644 uni_modules/uni-steps/changelog.md create mode 100644 uni_modules/uni-steps/components/uni-steps/uni-steps.vue create mode 100644 uni_modules/uni-steps/package.json create mode 100644 uni_modules/uni-steps/readme.md create mode 100644 uni_modules/uni-swipe-action/changelog.md create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue create mode 100644 uni_modules/uni-swipe-action/package.json create mode 100644 uni_modules/uni-swipe-action/readme.md create mode 100644 uni_modules/uni-swiper-dot/changelog.md create mode 100644 uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue create mode 100644 uni_modules/uni-swiper-dot/package.json create mode 100644 uni_modules/uni-swiper-dot/readme.md create mode 100644 uni_modules/uni-table/changelog.md create mode 100644 uni_modules/uni-table/components/uni-table/uni-table.vue create mode 100644 uni_modules/uni-table/components/uni-tbody/uni-tbody.vue create mode 100644 uni_modules/uni-table/components/uni-td/uni-td.vue create mode 100644 uni_modules/uni-table/components/uni-th/filter-dropdown.vue create mode 100644 uni_modules/uni-table/components/uni-th/uni-th.vue create mode 100644 uni_modules/uni-table/components/uni-thead/uni-thead.vue create mode 100644 uni_modules/uni-table/components/uni-tr/table-checkbox.vue create mode 100644 uni_modules/uni-table/components/uni-tr/uni-tr.vue create mode 100644 uni_modules/uni-table/i18n/en.json create mode 100644 uni_modules/uni-table/i18n/es.json create mode 100644 uni_modules/uni-table/i18n/fr.json create mode 100644 uni_modules/uni-table/i18n/index.js create mode 100644 uni_modules/uni-table/i18n/zh-Hans.json create mode 100644 uni_modules/uni-table/i18n/zh-Hant.json create mode 100644 uni_modules/uni-table/package.json create mode 100644 uni_modules/uni-table/readme.md create mode 100644 uni_modules/uni-tag/changelog.md create mode 100644 uni_modules/uni-tag/components/uni-tag/uni-tag.vue create mode 100644 uni_modules/uni-tag/package.json create mode 100644 uni_modules/uni-tag/readme.md create mode 100644 uni_modules/uni-test/changelog.md create mode 100644 uni_modules/uni-test/components/uni-test/uni-test.vue create mode 100644 uni_modules/uni-test/package.json create mode 100644 uni_modules/uni-test/readme.md create mode 100644 uni_modules/uni-title/changelog.md create mode 100644 uni_modules/uni-title/components/uni-title/uni-title.vue create mode 100644 uni_modules/uni-title/package.json create mode 100644 uni_modules/uni-title/readme.md create mode 100644 uni_modules/uni-tooltip/changelog.md create mode 100644 uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue create mode 100644 uni_modules/uni-tooltip/package.json create mode 100644 uni_modules/uni-tooltip/readme.md create mode 100644 uni_modules/uni-transition/changelog.md create mode 100644 uni_modules/uni-transition/components/uni-transition/createAnimation.js create mode 100644 uni_modules/uni-transition/components/uni-transition/uni-transition.vue create mode 100644 uni_modules/uni-transition/package.json create mode 100644 uni_modules/uni-transition/readme.md create mode 100644 uni_modules/uni-ui/changelog.md create mode 100644 uni_modules/uni-ui/components/uni-ui/uni-ui.vue create mode 100644 uni_modules/uni-ui/package.json create mode 100644 uni_modules/uni-ui/readme.md create mode 100644 utils/appUpdate.js create mode 100644 utils/array.js create mode 100644 utils/edit.js create mode 100644 utils/emoji.js create mode 100644 utils/observer.js create mode 100644 utils/permission.js create mode 100644 utils/request.js create mode 100644 utils/utils.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db5c1f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Build and Release Folders +bin-debug/ +bin-release/ +[Oo]bj/ +[Bb]in/ + +# Other files and folders +.settings/ +/unpackage/ +node_modules +# Executables +*.swf +*.air +*.ipa +*.apk +*.zip + +# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` +# should NOT be excluded as they contain compiler settings and other important +# information for Eclipse / Flash Builder. diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..173ca9c --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,33 @@ +{ + // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version" : "0.0", + "configurations" : [ + { + "app-plus" : { + "launchtype" : "remote" + }, + "default" : { + "launchtype" : "local" + }, + "mp-weixin" : { + "launchtype" : "local" + }, + "type" : "uniCloud" + }, + { + "openVueDevtools" : false, + "playground" : "custom", + "type" : "uni-app:app-ios" + }, + { + "openVueDevtools" : false, + "playground" : "custom", + "type" : "uni-app:app-android" + }, + { + "openVueDevtools" : false, + "type" : "uni-app:h5" + } + ] +} diff --git a/.vite/_cert.pem b/.vite/_cert.pem new file mode 100644 index 0000000..8f5025b --- /dev/null +++ b/.vite/_cert.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA17mXxivjza/+LCpiNPKPTiiit0dcFiBAkOGN297tSiJjavsv +Pji04nGeBbi+z/2qb1+8/5r92QDy/Krp3xdHIuEGIwDll6UEa3Wcj3StqBnycAWc +JDlZ9dur7bpoVLF6O1/IeexfSIkqVkNmaKDS2kXKpllrgyx19ql3vXekFuFCwLIh +Ku6yLlcfEaKnWmd3h4vNV0X+q3ckK56w5IyPkxe6gOKpPbQ5TEB8J+w9X7u3MCKl +PfZPmLyJ53UzacPnkfH6SO+eHO+WSsauYtfnxfduuG7BzYndH6JO3A9m9GwIsM/o +N3WuMAk3DoFXK5dqnFhocXlsPizQOt+MZLYvLQIDAQABAoIBABo6VlmhvHCllSGJ +hacqVoIKLr5Zzrhh83ep9LVmxTLeO3gmUfgerN9bMPtBGvHuxWoFGdV54qMfmmtd +3FFjYyK6eSSIV2G4jnECO6a1aOenP/Keu/0re+SIcL7WixjA+zt8ycMJGgyXoK4c +Q7c01m3zTlArTwcDwNPchtJiWXDueQw0tjO2zdD2DA/hSohVUcgynJ6kDez1lQ35 +8p2LI0M4LGjn2NL5XN4PyarTvnslvG5Ik6Oo6wSTySqcddWHJm9+ozuVVqDrVqOY +R0bdm8g9PWDoPDiCLbx58c3MtFRoejBFhm3cQp16DEB1fbL20nnTQspXG5hvsYpP +uZEXbAECgYEA+pYztQ0+13BYoTxSMQMOUscxLigJXUcm3JnA8w95qG5jwkwosh52 +dqDNGAUmpeliokR0rI3xozXDsldX+onDGyExHHi8u9f03B7NMseoTK6edGjJEprl +syoAoGwg/GY6yle3yqEkRhchWxNYDewe+W1b6AK8JG7XMQEfU08r3rkCgYEA3GKZ +E212OyKgADaOVBqxwBN9bECxbne8KqsWRMnWN+cps0mqfPFrhDr62oqxwioh1ZAE +RWciBF7l5PrbaJ5NAjPuh6MzU6zBbJVkDqddySsbHExh69Uia81J1UG21GpPnjII +/h74dan6DYHJuxjFYDLqGrn81TCkd1JiikdfOhUCgYB4fTBvpebJgGOdY3vBxU5l +zxF+uBGIoGW3PNbiCFbe/fVJv4Tx4GPltnvnSNLEg+vBSlkvfzDo4Tkvz3+mIAeI +S/VpU0SsrbI3BTh1ajsqY+wc3SWRpJk+BLw4ZsWVlzI9iN/+tmzSptyLBkoYp6hd +FpBShr4gZotiLL/7Nt5JQQKBgQCZlKCGeGbHSRblbx96nuu2Jh7mnKLJj+lydq3b +HCkL5i0aQ0DrNzas/IkqWTMNU10mveksEHYVQ6jEDMlwO7kAyv30ShgPvLlCmU0U +JTBna4HGE7i9p1cIdxR36AaoOrnnTYkUxrJxFRYr6YGSv+10X6bjHy+BxhcnDCOd +p6VGDQKBgH+BVVOQ2I5ddO6ZICapfm6O3n32RPuSsZavvEE7T73kY0jY+gAf2q1j +KIZ9kH851D0q2ofmgly2lo9ctuV+4uq55wT07Bgz5UwTCoOQ8VE7sBC1aB6TP0ot +whW3ZXHQomC9aM+c11IcTsQAJ6suZfT7uZcazWhD8PN+BiluxTlm +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgIJA2BOZCd6yrSRMA0GCSqGSIb3DQEBCwUAMGkxFDASBgNV +BAMTC2V4YW1wbGUub3JnMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWEx +EzARBgNVBAcTCkJsYWNrc2J1cmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRl +c3QwHhcNMjIxMDIwMTI0MDUxWhcNMjIxMTE5MTI0MDUxWjBpMRQwEgYDVQQDEwtl +eGFtcGxlLm9yZzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYD +VQQHEwpCbGFja3NidXJnMQ0wCwYDVQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA17mXxivjza/+LCpiNPKPTiii +t0dcFiBAkOGN297tSiJjavsvPji04nGeBbi+z/2qb1+8/5r92QDy/Krp3xdHIuEG +IwDll6UEa3Wcj3StqBnycAWcJDlZ9dur7bpoVLF6O1/IeexfSIkqVkNmaKDS2kXK +pllrgyx19ql3vXekFuFCwLIhKu6yLlcfEaKnWmd3h4vNV0X+q3ckK56w5IyPkxe6 +gOKpPbQ5TEB8J+w9X7u3MCKlPfZPmLyJ53UzacPnkfH6SO+eHO+WSsauYtfnxfdu +uG7BzYndH6JO3A9m9GwIsM/oN3WuMAk3DoFXK5dqnFhocXlsPizQOt+MZLYvLQID +AQABo4GhMIGeMAsGA1UdDwQEAwIC9DAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYB +BQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDCDBcBgNVHREEVTBTgglsb2NhbGhvc3SC +FWxvY2FsaG9zdC5sb2NhbGRvbWFpboIGbHZoLm1lgggqLmx2aC5tZYIFWzo6MV2H +BH8AAAGHEP6AAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggEBAEEPfOUj +4+CbTnJwjZIqz+4Qo9X7RnMTkuuckTWC/f4h8IXSuqF3ximcnFWrDu5uEw3x1wLM +VHedWIhTUw908dHW4flTTJfI/hQg1samK7XefVfGx7/0uRJi2tiPf5ztI45/z6cC +0dQxGZEu4t7mfu0sbfjvKtngDCdF5ZWKy4jjEWdW7CsJ7BSWuyp4dP/FVW9ntPz8 +m+qYYTIUI3QHQe1RoMmOKK+1Nqs7YkfB/avebt+xdv2VOekefqmYudpwDMbaQ+Zk +boqW/+u1WBpsWeXob+Fhmp3nM+j3G6KyNkPRbGBZcgfkdGrPdM8AvOrdGEcrK3rT +QKRyGCwDZqQjLgg= +-----END CERTIFICATE----- diff --git a/.vite/deps/package.json b/.vite/deps/package.json new file mode 100644 index 0000000..7c34deb --- /dev/null +++ b/.vite/deps/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..bcd18cd --- /dev/null +++ b/App.vue @@ -0,0 +1,579 @@ + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..af06431 --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# Raingad-IM for uniapp + +技术栈:`vue3` + `pinia` + `color-UI` + +#### 目录结构 +``` +Raingad +├─api 接口目录 +│ ├─index.js 总的接口文件 +│ └─message.js 消息接口 +│ +├─common 公共目录 +│ ├─socket.js websocket配置 +│ └─config.js 服务器地址配置 +│ +│─components 符合vue组件规范的uni-app组件目录 +│ └─comp-a.vue 可复用的a组件 +│ +├─pages 业务页面文件存放的目录 +│ ├─index +│ │ └─index.vue index页面 +│ ├─message +│ │ └─index.vue 消息列表页面 +│ ├─ ... 更多目录 +│ └─contact +│ └─index.vue 联系人列表页面 +│ +├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此 +│ +├─uni_modules 存放[uni_module](/uni_modules)。 +│ +├─hybrid App端存放本地html文件的目录,详见 +│ +├─nativeplugins 远程插件目录 +│ +├─uniCloud 云函数目录,里面有unipush的推送功能,如果不需要可以删除(已删除) +│ +├─unpackage 非工程代码,一般存放运行或发行的编译结果 +│ +├─main.js Vue初始化入口文件 +├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期 +├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见 +├─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见 +└─uni.scss 这里是uni-app内置的常用样式变量 +``` + +#### 5.3+ 重要更新 +修改接口的时候,为了避免自己打包的H5被盗用,我们加入了域名加密认证。 +- 在 `/common/config.js` 中需要添加一个加密信息:hostToken,可以搜索定位到该字符串 +- hostToken信息需要将自己的域名md5加密 **两次**(域名md5加密一次后得到的值再md5加密一次)在拼接两个字符串,得到我们的Token。不会加密的去百度搜索md5在线加密,将域名输入后加密得到第一次加密后的Token,把加密后的值再重复加密一次即可。 + +加密格式如下: + +> "sha"+域名加密两次后的md5 + "bi" + +假如我们的域名是 `im.xxxxx.com` ,那么加密后就应该是:**sha** f9cb4d7d77719f068e7233e81690f39a **bi** + +加密好了把该token填写到hostToken中,这样就可以避免别人下载我们的h5页面,修改域名来使用我们的源码,如果不影响可以将相应的代码屏蔽掉或者使用其他更先进的算法。 + +#### 安装打包请直接参考文档 +文档全部迁移至以下地址: +所有文档地址: [接口文档地址](https://apifox.com/apidoc/shared-e563aed5-7578-4620-913f-f6746ece6067) 访问密码: raingad-im-doc \ No newline at end of file diff --git a/androidPrivacy.json b/androidPrivacy.json new file mode 100644 index 0000000..a7404db --- /dev/null +++ b/androidPrivacy.json @@ -0,0 +1,38 @@ +{ + "version" : "1", + "prompt" : "template", + "title" : "服务协议和隐私政策", + "message" : "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。
  你可阅读《服务协议》《隐私政策》了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。", + "buttonAccept" : "同意并接受", + "buttonRefuse" : "暂不同意", + "hrefLoader" : "system", + "backToExit" : "false", + "second" : { + "title" : "确认提示", + "message" : "  进入应用前,你需先同意《服务协议》《隐私政策》,否则将退出应用。", + "buttonAccept" : "同意并继续", + "buttonRefuse" : "退出应用" + }, + "disagreeMode" : { + "support" : false, + "loadNativePlugins" : false, + "visitorEntry" : false, + "showAlways" : false + }, + "styles" : { + "backgroundColor" : "#ffffff", + "borderRadius" : "5px", + "title" : { + "color" : "#000000" + }, + "buttonAccept" : { + "color" : "#00ff00" + }, + "buttonRefuse" : { + "color" : "#999999" + }, + "buttonVisitor" : { + "color" : "#999999" + } + } +} diff --git a/api/emoji.js b/api/emoji.js new file mode 100644 index 0000000..7524d77 --- /dev/null +++ b/api/emoji.js @@ -0,0 +1,45 @@ +// 统一请求路径前缀在libs/axios.js中修改 +import { + postRequest, + postJsonRequest, + apiUrl +} from '@/utils/request.js'; +let emojiApi = {} + +emojiApi.uploadEmoji=apiUrl+'/common/upload/uploadEmoji'; + +/** + * @desc 表情列表 + * @param {*} 参数 + */ +emojiApi.emojiList = (params) => { + return postJsonRequest('/enterprise/emoji/index', params) +} + +/** + * @desc 添加表情 + * @param {*} 参数 + */ +emojiApi.addEmoji = (params) => { + return postJsonRequest('/enterprise/emoji/add', params) +} + +/** + * @desc 删除表情 + * @param {*} 参数 + */ +emojiApi.delEmoji = (params) => { + return postJsonRequest('/enterprise/emoji/del', params) +} + + +/** + * @desc 移动表情 + * @param {*} 参数 + */ +emojiApi.moveEmoji = (params) => { + return postJsonRequest('/enterprise/emoji/move', params) +} + + +export default emojiApi; diff --git a/api/friend.js b/api/friend.js new file mode 100644 index 0000000..1eb24a5 --- /dev/null +++ b/api/friend.js @@ -0,0 +1,48 @@ +// 统一请求路径前缀在libs/axios.js中修改 +import { + postJsonRequest, + apiUrl +} from '@/utils/request.js'; +let friendApi = {} + +/** + * @desc 删除好友 + * @param {*} 参数 + */ +friendApi.delFriend = (params) => { + return postJsonRequest('/enterprise/friend/del', params) +} + +/** + * @desc 添加好友 + * @param {*} 参数 + */ +friendApi.addFriend = (params) => { + return postJsonRequest('/enterprise/friend/add', params) +} + +/** + * @desc 新朋友列表 + * @param {*} 参数 + */ +friendApi.applyList = (params) => { + return postJsonRequest('/enterprise/friend/index', params) +} + +/** + * @desc 同意或者拒绝请求 + * @param {*} 参数 + */ +friendApi.acceptApply = (params) => { + return postJsonRequest('/enterprise/friend/update', params) +} + +/** + * @desc 设置好有备注 + * @param {*} 参数 + */ +friendApi.setNickname = (params) => { + return postJsonRequest('/enterprise/friend/setNickname', params) +} + +export default friendApi; diff --git a/api/index.js b/api/index.js new file mode 100644 index 0000000..9f621b5 --- /dev/null +++ b/api/index.js @@ -0,0 +1,13 @@ +// 引入其他模块的接口 + +import msgApi from '@/api/message.js'; // 消息 +import LoginApi from '@/api/login.js'; //登录相关 +import friendApi from '@/api/friend.js'; //登录相关 +import emojiApi from '@/api/emoji.js'; //登录相关 +// 导出接口 +export default { + msgApi, + LoginApi, + friendApi, + emojiApi +} diff --git a/api/login.js b/api/login.js new file mode 100644 index 0000000..5e29cdb --- /dev/null +++ b/api/login.js @@ -0,0 +1,65 @@ +// 统一请求路径前缀在libs/axios.js中修改 +import { + postJsonRequest, + apiUrl +} from '@/utils/request.js'; +let LoginApi = {} + +/** + * @desc 登录接口 + * @param {*} 参数 + */ +LoginApi.login = (params) => { + return postJsonRequest('/common/Pub/login', params) +} + + +/** + * @desc 退出接口 + * @param {*} 参数 + */ +LoginApi.logout = (params) => { + return postJsonRequest('/common/Pub/logout', params) +} + +/** + * 注册用户 + * @param {*} data + */ +LoginApi.register = (params) => { + return postJsonRequest('/common/pub/register', params) +} + +/** + * @desc 绑定client_id + * @param {*} 参数 + */ +LoginApi.bindUid = (params) => { + return postJsonRequest('/common/Pub/bindUid', params) +} + +/** + * @desc 绑定群聊client_id + * @param {*} 参数 + */ +LoginApi.bindGroup = (params) => { + return postJsonRequest('common/pub/bindGroup', params) +} + +/** + * 获取全局配置 + * @param {*} data + */ +LoginApi.getSystemInfo = (params) => { + return postJsonRequest('/common/pub/getSystemInfo', params) +} + +/** + * 发送验证码 + * @param {*} data + */ +LoginApi.sendCode = (params) => { + return postJsonRequest('/common/pub/sendCode', params) +} + +export default LoginApi; diff --git a/api/message.js b/api/message.js new file mode 100644 index 0000000..e8b79c2 --- /dev/null +++ b/api/message.js @@ -0,0 +1,291 @@ +// 统一请求路径前缀在libs/axios.js中修改 +import { + postRequest, + postJsonRequest, + apiUrl +} from '@/utils/request.js'; +let msgApi = {} + +msgApi.uploadUrl=apiUrl+'/common/upload/uploadFile'; +// 上传头像 +msgApi.uploadAvatar=apiUrl+'/common/upload/uploadAvatar'; +/** + * @desc 普通消息列表(小程序) + * @param {*} 参数 + */ +msgApi.initContacts = (params) => { + return postJsonRequest('/enterprise/im/getContacts', params) +} + + + +/** + * @desc 普通消息列表(小程序) + * @param {*} 参数 + */ +msgApi.getMessageList = (params) => { + return postJsonRequest('/enterprise/im/getMessageList', params) +} + +/** + * @desc 设置聊天置顶 + * @param {*} 参数 + */ +msgApi.setChatTopAPI = (params) => { + return postJsonRequest('/enterprise/im/setChatTop', params) +} + +/** + * @desc 删除聊天 + * @param {*} 参数 + */ +msgApi.delChatAPI = (params) => { + return postJsonRequest('/enterprise/im/delChat', params) +} + +/** + * @desc 发送文本聊天消息 + * @param {*} 参数 + */ +msgApi.sendMessage = (params) => { + return postJsonRequest('/enterprise/im/sendMessage', params) +} + +/** + * @desc 转发聊天消息 + * @param {*} 参数 + */ +msgApi.forwardMessage = (params) => { + return postJsonRequest('/enterprise/im/forwardMessage', params) +} + +/** + * @desc 设置消息已读 + * @param {*} 参数 + */ +msgApi.setMsgIsRead = (params) => { + return postJsonRequest('/enterprise/im/setMsgIsRead', params) +} + +/** + * @desc 设置艾特消息已读 + * @param {*} 参数 + */ +msgApi.readAtMsg = (params) => { + return postJsonRequest('/enterprise/im/readAtMsg', params) +} + +/** + * 撤回消息 + * @param {*} data + */ +msgApi.undoMessage = (params) => { + return postJsonRequest('/enterprise/im/undoMessage', params) +} + +/** + * 删除消息 + * @param {*} data + */ +msgApi.delMessage = (params) => { + return postJsonRequest('/enterprise/im/delMessage', params) +} + + +/** + * 发送ws消息 + * @param {*} data + */ +msgApi.sendToMsg = (params) => { + return postJsonRequest('/enterprise/im/sendToMsg', params) +} + +/** + * 消息免打扰 + * @param {*} data + */ +msgApi.isNoticeAPI = (params) => { + return postJsonRequest('/enterprise/im/isNotice', params) +} + +/** + * 更新业务卡片 + * @param {*} data + */ +msgApi.updateCard = (params) => { + return postJsonRequest('/enterprise/im/updateCard', params) +} + +/** + * 同意或者忽略团队 + * @param {*} data + */ +msgApi.joinGroup = (params) => { + return postJsonRequest('/enterprise/group/joinGroup', params) +} + +/** + * 获取群成员 + * @param {*} data + */ +msgApi.groupUserList = (params) => { + return postJsonRequest('/enterprise/group/groupUserList', params) +} + +/** + * 修改群公告 + * @param {*} data + */ +msgApi.setNotice = (params) => { + return postJsonRequest('/enterprise/group/setNotice', params) +} +/** + * 群管理信息 + * @param {*} data + */ +msgApi.groupInfo = (params) => { + return postJsonRequest('/enterprise/group/groupInfo', params) +} + +/** + * 加入群聊 + * @param {*} data + */ +msgApi.joinGroup = (params) => { + return postJsonRequest('/enterprise/group/joinGroup', params) +} + + +/** + * 修改群管理信息 + * @param {*} data + */ +msgApi.groupSetting = (params) => { + return postJsonRequest('/enterprise/group/groupSetting', params) +} + +/** + * 转让管理权限 + * @param {*} data + */ +msgApi.changeOwner = (params) => { + return postJsonRequest('/enterprise/group/changeOwner', params) +} + +/** + * 获取全部人员 + * @param {*} data + */ +msgApi.getAllUser = (params) => { + return postJsonRequest('/enterprise/group/getAllUser', params) +} + +/** + * 创建群聊 + * @param {*} data + */ +msgApi.addGroup = (params) => { + return postJsonRequest('/enterprise/group/add', params) +} +/** + * 绑定群聊 + * @param {*} data + */ +msgApi.bindGroup = (params) => { + return postJsonRequest('/common/index/bindGroup', params) +} + +/** + * 修改群聊名字 + * @param {*} data + */ +msgApi.editGroupName = (params) => { + return postJsonRequest('/enterprise/group/editGroupName', params) +} +/** + * 添加群成员 + * @param {*} data + */ +msgApi.addGroupUser = (params) => { + return postJsonRequest('/enterprise/group/addGroupUser', params) +} + +/** + * 删除群成员 + * @param {*} data + */ +msgApi.removeUser = (params) => { + return postJsonRequest('/enterprise/group/removeUser', params) +} + +/** + * 删除群聊 + * @param {*} data + */ +msgApi.removeGroup = (params) => { + return postJsonRequest('/enterprise/group/removeGroup', params) +} + +/** + * 删除群聊聊天记录 + * @param {*} data + */ +msgApi.clearMessage = (params) => { + return postJsonRequest('/enterprise/group/clearMessage', params) +} + + +/** + * 设置/取消管理员 + * @param {*} data + */ +msgApi.setManager = (params) => { + return postJsonRequest('/enterprise/group/setManager', params) +} + +/** + * 设置禁言 + * @param {*} data + */ +msgApi.setNoSpeak = (params) => { + return postJsonRequest('/enterprise/group/setNoSpeak', params) +} + +/** + * 获取成员信息 + * @param {*} data + */ +msgApi.getUserInfo = (params) => { + return postJsonRequest('/enterprise/im/getUserInfo', params) +} + +// 搜索用户 +msgApi.searchUser= (params) =>{ + return postJsonRequest('enterprise/im/searchUser', params) +} + +// 修改用户信息 +msgApi.updateUserInfo= (params) =>{ + return postJsonRequest('enterprise/im/updateUserInfo', params) +} + +// 修改账号 +msgApi.editAccount= (params) =>{ + return postJsonRequest('enterprise/im/editAccount', params) +} + +// 修改密码 +msgApi.editPassword= (params) =>{ + return postJsonRequest('enterprise/im/editPassword', params) +} + +// 获取联系人信息 +msgApi.contactInfo= (params) =>{ + return postJsonRequest('enterprise/im/getContactInfo', params) +} + +// 获取公告信息 +msgApi.getAdminNotice= (params) =>{ + return postJsonRequest('enterprise/im/getAdminNotice', params) +} +export default msgApi; diff --git a/common/appUpdate.js b/common/appUpdate.js new file mode 100644 index 0000000..3ccaf0e --- /dev/null +++ b/common/appUpdate.js @@ -0,0 +1,865 @@ + +import config from "@/common/config.js" +import { postJsonRequest } from '@/utils/request.js'; + +const updateConfig=config.updateConfig; +const platform = uni.getSystemInfoSync().platform; +// 主颜色 +const $mainColor = updateConfig.bgColor ? updateConfig.bgColor : "FF5B78"; +// 弹窗图标url +const $iconUrl = updateConfig.iconUrl ? updateConfig.iconUrl : "/static/image/rocket.png"; + +const $checkUpdateUrl=updateConfig.url ? updateConfig.url : ""; + + +// 获取当前应用的版本号 +export const getCurrentNo = (callback) => { + // 获取本地应用资源版本号 + plus.runtime.getProperty(plus.runtime.appid,(inf) => { + callback && callback({ + versionCode: inf.versionCode, + versionName: inf.version + }); + }); +} +// 从服务器下载应用资源包(wgt文件) +const getDownload = (data)=>{ + let dtask; + if(data.updateType == 'forcibly' || data.updateType == 'solicit'){ + let popupData = { + progress: true, + buttonNum: 2 + }; + if(data.updateType == 'forcibly'){ + popupData.buttonNum = 0; + } + let lastProgressValue = 0; + let popupObj = downloadPopup(popupData); + dtask = plus.downloader.createDownload(data.downloadUrl, { + filename: "_doc/update/" + }, function(download, status) { + if (status == 200) { + popupObj.change({ + progressValue: 100, + progressTip:"正在安装文件...", + progress: true, + buttonNum: 0 + }); + plus.runtime.install(download.filename, {}, function() { + popupObj.change({ + contentText: "应用资源更新完成!", + buttonNum: 1, + progress: false + }); + }, function(e) { + popupObj.cancel(); + plus.nativeUI.alert("安装文件失败[" + e.code + "]:" + e.message); + }); + } else { + popupObj.change({ + contentText: "文件下载失败...", + buttonNum: 1, + progress: false + }); + } + }); + dtask.start(); + dtask.addEventListener("statechanged", function(task, status) { + switch (task.state) { + case 1: // 开始 + popupObj.change({ + progressValue:0, + progressTip:"准备下载...", + progress: true + }); + break; + case 2: // 已连接到服务器 + popupObj.change({ + progressValue:0, + progressTip:"开始下载...", + progress: true + }); + break; + case 3: + const progress = parseInt(task.downloadedSize / task.totalSize * 100); + if(progress - lastProgressValue >= 2){ + lastProgressValue = progress; + popupObj.change({ + progressValue:progress, + progressTip: "已下载" + progress + "%", + progress: true + }); + } + break; + } + }); + // 取消下载 + popupObj.cancelDownload = function(){ + dtask && dtask.abort(); + uni.showToast({ + title: "已取消下载", + icon:"none" + }); + } + // 重启APP + popupObj.reboot = function(){ + plus.runtime.restart(); + } + } else if(data.updateType == "silent"){ + dtask = plus.downloader.createDownload(data.downloadUrl, { + filename: "_doc/update/" + }, function(download, status) { + if (status == 200) { + plus.runtime.install(download.filename, {}, function() { + console.log("应用资源更新完成"); + }, function(e) { + plus.nativeUI.alert("安装文件失败[" + e.code + "]:" + e.message); + }); + } else { + plus.nativeUI.alert("文件下载失败..."); + } + }); + dtask.start(); + } +} +// 文字换行 +const drawtext = (text, maxWidth)=>{ + let textArr = text.split(""); + let len = textArr.length; + // 上个节点 + let previousNode = 0; + // 记录节点宽度 + let nodeWidth = 0; + // 文本换行数组 + let rowText = []; + // 如果是字母,侧保存长度 + let letterWidth = 0; + // 汉字宽度 + let chineseWidth = 14; + // otherFont宽度 + let otherWidth = 7; + for (let i = 0; i < len; i++) { + if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) { + if(letterWidth > 0){ + if(nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth){ + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }); + previousNode = i; + nodeWidth = chineseWidth; + letterWidth = 0; + } else { + nodeWidth += chineseWidth + letterWidth * otherWidth; + letterWidth = 0; + } + } else { + if(nodeWidth + chineseWidth > maxWidth){ + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }); + previousNode = i; + nodeWidth = chineseWidth; + }else{ + nodeWidth += chineseWidth; + } + } + } else { + if(/\n/g.test(textArr[i])){ + rowText.push({ + type: "break", + content: text.substring(previousNode, i) + }); + previousNode = i + 1; + nodeWidth = 0; + letterWidth = 0; + }else if(textArr[i] == "\\" && textArr[i + 1] == "n"){ + rowText.push({ + type: "break", + content: text.substring(previousNode, i) + }); + previousNode = i + 2; + nodeWidth = 0; + letterWidth = 0; + }else if(/[a-zA-Z0-9]/g.test(textArr[i])){ + letterWidth += 1; + if(nodeWidth + letterWidth * otherWidth > maxWidth){ + rowText.push({ + type: "text", + content: text.substring(previousNode, i + 1 - letterWidth) + }); + previousNode = i + 1 - letterWidth; + nodeWidth = letterWidth * otherWidth; + letterWidth = 0; + } + } else{ + if(nodeWidth + otherWidth > maxWidth){ + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }); + previousNode = i; + nodeWidth = otherWidth; + }else{ + nodeWidth += otherWidth; + } + } + } + } + if (previousNode < len) { + rowText.push({ + type: "text", + content: text.substring(previousNode, len) + }); + } + return rowText; +} +// 是否更新弹窗 +const updatePopup = (data, callback) => { + // 弹窗遮罩层 + let maskLayer = new plus.nativeObj.View("maskLayer", { //先创建遮罩层 + top: '0px', + left: '0px', + height: '100%', + width: '100%', + backgroundColor: 'rgba(0,0,0,0.5)' + }); + + // 以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心 + const screenWidth = plus.screen.resolutionWidth; + const screenHeight = plus.screen.resolutionHeight; + //弹窗容器宽度 + const popupViewWidth = screenWidth * 0.7; + // 弹窗容器的Padding + const viewContentPadding = 20; + // 弹窗容器的宽度 + const viewContentWidth = parseInt(popupViewWidth - (viewContentPadding * 2)); + // 描述的列表 + const descriptionList = drawtext(data.versionInfo, viewContentWidth); + // 弹窗容器高度 + let popupViewHeight = 80 + 20 + 20 + 90 + 10; + + let popupViewContentList = [{ + src: $iconUrl, + id: "logo", + tag: "img", + position: { + top: "0px", + left: (popupViewWidth - 124) / 2 + "px", + width: "124px", + height: "80px", + } + }, + { + tag: 'font', + id: 'title', + text: "发现新版本:" + data.versionName, + textStyles: { + size: '18px', + color: "#333", + weight: "bold", + whiteSpace: "normal" + }, + position: { + top: '90px', + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "30px", + } + }]; + const textHeight = 18; + let contentTop = 130; + descriptionList.forEach((item,index) => { + if(index > 0){ + popupViewHeight += textHeight; + contentTop += textHeight; + } + popupViewContentList.push({ + tag: 'font', + id: 'content' + index + 1, + text: item.content, + textStyles: { + size: '14px', + color: "#666", + lineSpacing: "50%", + align: "left" + }, + position: { + top: contentTop + "px", + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: textHeight + "px", + } + }); + if(item.type == "break"){ + contentTop += 10; + popupViewHeight += 10; + } + }); + + if(data.updateType == "forcibly"){ + popupViewContentList.push({ + tag: 'rect', //绘制底边按钮 + rectStyles:{ + radius: "6px", + color: $mainColor + }, + position:{ + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "30px" + } + }); + popupViewContentList.push({ + tag: 'font', + id: 'confirmText', + text: "立即升级", + textStyles: { + size: '14px', + color: "#FFF", + lineSpacing: "0%", + }, + position: { + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "30px" + } + }); + } else { + // 绘制底边按钮 + popupViewContentList.push({ + tag: 'rect', + id: 'cancelBox', + rectStyles: { + radius: "3px", + borderColor: "#f1f1f1", + borderWidth: "1px", + }, + position: { + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px", + } + }); + popupViewContentList.push({ + tag: 'rect', + id: 'confirmBox', + rectStyles: { + radius: "3px", + color: $mainColor, + }, + position: { + bottom: viewContentPadding + 'px', + left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px", + } + }); + popupViewContentList.push({ + tag: 'font', + id: 'cancelText', + text: "暂不升级", + textStyles: { + size: '14px', + color: "#666", + lineSpacing: "0%", + whiteSpace: "normal" + }, + position: { + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px", + } + }); + popupViewContentList.push({ + tag: 'font', + id: 'confirmText', + text: "立即升级", + textStyles: { + size: '14px', + color: "#FFF", + lineSpacing: "0%", + whiteSpace: "normal" + }, + position: { + bottom: viewContentPadding + 'px', + left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px", + } + }); + } + // 弹窗内容 + let popupView = new plus.nativeObj.View("popupView", { //创建底部图标菜单 + tag: "rect", + top: (screenHeight - popupViewHeight) / 2 + "px", + left: '15%', + height: popupViewHeight + "px", + width: "70%" + }); + // 绘制白色背景 + popupView.drawRect({ + color: "#FFFFFF", + radius: "8px" + }, { + top: "40px", + height: popupViewHeight - 40 + "px", + }); + + popupView.draw(popupViewContentList); + popupView.addEventListener("click", function(e) { + let maxTop = popupViewHeight - viewContentPadding; + let maxLeft = popupViewWidth - viewContentPadding; + let buttonWidth = (viewContentWidth - viewContentPadding) / 2; + if (e.clientY > maxTop - 30 && e.clientY < maxTop) { + if(data.updateType == "forcibly"){ + if(e.clientX > viewContentPadding && e.clientX < maxLeft){ + // 立即升级 + maskLayer.hide(); + popupView.hide(); + callback && callback(); + } + } else { + // 暂不升级 + if (e.clientX > viewContentPadding && e.clientX < maxLeft - buttonWidth - viewContentPadding) { + maskLayer.hide(); + popupView.hide(); + } else if (e.clientX > maxLeft - buttonWidth && e.clientX < maxLeft) { + // 立即升级 + maskLayer.hide(); + popupView.hide(); + callback && callback(); + } + } + + } + }); + if(data.updateType == "solicit"){ + // 点击遮罩层 + maskLayer.addEventListener("click", function() { //处理遮罩层点击 + maskLayer.hide(); + popupView.hide(); + }); + } + // 显示弹窗 + maskLayer.show(); + popupView.show(); +} +// 文件下载的弹窗绘图 +const downloadPopupDrawing =(data) => { + // 以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心 + const screenWidth = plus.screen.resolutionWidth; + const screenHeight = plus.screen.resolutionHeight; + //弹窗容器宽度 + const popupViewWidth = screenWidth * 0.7; + // 弹窗容器的Padding + const viewContentPadding = 20; + // 弹窗容器的宽度 + const viewContentWidth = popupViewWidth - (viewContentPadding * 2); + // 弹窗容器高度 + let popupViewHeight = viewContentPadding * 3 + 60; + let progressTip = data.progressTip || "准备下载..."; + let contentText = data.contentText || "正在为您更新,请耐心等待"; + let elementList = [ + { + tag: 'rect', //背景色 + color: '#FFFFFF', + rectStyles:{ + radius: "8px" + } + }, + { + tag: 'font', + id: 'title', + text: "升级APP", + textStyles: { + size: '16px', + color: "#333", + weight: "bold", + verticalAlign: "middle", + whiteSpace: "normal" + }, + position: { + top: viewContentPadding + 'px', + height: "30px", + } + }, + { + tag: 'font', + id: 'content', + text: contentText, + textStyles: { + size: '14px', + color: "#333", + verticalAlign: "middle", + whiteSpace: "normal" + }, + position: { + top: viewContentPadding * 2 + 30 + 'px', + height: "20px", + } + } + ]; + // 是否有进度条 + if(data.progress){ + popupViewHeight += viewContentPadding + 40; + elementList = elementList.concat([ + { + tag: 'font', + id: 'progressValue', + text: progressTip, + textStyles: { + size: '14px', + color: $mainColor, + whiteSpace: "normal" + }, + position: { + top: viewContentPadding * 4 + 20 + 'px', + height: "30px" + } + }, + { + tag: 'rect', //绘制进度条背景 + id: 'progressBg', + rectStyles:{ + radius: "4px", + borderColor: "#f1f1f1", + borderWidth: "1px", + }, + position:{ + top: viewContentPadding * 4 + 60 + 'px', + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "8px" + } + }, + ]); + } + if (data.buttonNum == 2) { + popupViewHeight += viewContentPadding + 30; + elementList = elementList.concat([ + { + tag: 'rect', //绘制底边按钮 + rectStyles:{ + radius: "3px", + borderColor: "#f1f1f1", + borderWidth: "1px", + }, + position:{ + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px" + } + }, + { + tag: 'rect', //绘制底边按钮 + rectStyles:{ + radius: "3px", + color: $mainColor + }, + position:{ + bottom: viewContentPadding + 'px', + left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px" + } + }, + { + tag: 'font', + id: 'cancelText', + text: "取消下载", + textStyles: { + size: '14px', + color: "#666", + lineSpacing: "0%", + whiteSpace: "normal" + }, + position: { + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px", + } + }, + { + tag: 'font', + id: 'confirmText', + text: "后台下载", + textStyles: { + size: '14px', + color: "#FFF", + lineSpacing: "0%", + whiteSpace: "normal" + }, + position: { + bottom: viewContentPadding + 'px', + left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px", + width: (viewContentWidth - viewContentPadding) / 2 + "px", + height: "30px", + } + } + ]); + } + if (data.buttonNum == 1) { + popupViewHeight += viewContentPadding + 40; + elementList = elementList.concat([ + { + tag: 'rect', //绘制底边按钮 + rectStyles:{ + radius: "6px", + color: $mainColor + }, + position:{ + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "40px" + } + }, + { + tag: 'font', + id: 'confirmText', + text: "关闭", + textStyles: { + size: '14px', + color: "#FFF", + lineSpacing: "0%", + }, + position: { + bottom: viewContentPadding + 'px', + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "40px" + } + } + ]); + } + return { + popupViewHeight:popupViewHeight, + popupViewWidth:popupViewWidth, + screenHeight:screenHeight, + viewContentWidth:viewContentWidth, + viewContentPadding:viewContentPadding, + elementList: elementList + }; +} +// 文件下载的弹窗 +const downloadPopup=(data)=>{ + // 弹窗遮罩层 + let maskLayer = new plus.nativeObj.View("maskLayer", { //先创建遮罩层 + top: '0px', + left: '0px', + height: '100%', + width: '100%', + backgroundColor: 'rgba(0,0,0,0.5)' + }); + let popupViewData = downloadPopupDrawing(data); + // 弹窗内容 + let popupView = new plus.nativeObj.View("popupView", { //创建底部图标菜单 + tag: "rect", + top: (popupViewData.screenHeight - popupViewData.popupViewHeight) / 2 + "px", + left: '15%', + height: popupViewData.popupViewHeight + "px", + width: "70%", + }); + let progressValue = 0; + let progressTip = 0; + let contentText = 0; + let buttonNum = 2; + if(data.buttonNum >= 0){ + buttonNum = data.buttonNum; + } + popupView.draw(popupViewData.elementList); + let callbackData = { + change: function(res) { + let progressElement = []; + if(res.progressValue){ + progressValue = res.progressValue; + // 绘制进度条 + progressElement.push({ + tag: 'rect', //绘制进度条背景 + id: 'progressValueBg', + rectStyles:{ + radius: "4px", + color: $mainColor + }, + position:{ + top: popupViewData.viewContentPadding * 4 + 60 + 'px', + left: popupViewData.viewContentPadding + "px", + width: popupViewData.viewContentWidth * (res.progressValue / 100) + "px", + height: "8px" + } + }); + } + if(res.progressTip){ + progressTip = res.progressTip; + progressElement.push({ + tag: 'font', + id: 'progressValue', + text: res.progressTip, + textStyles: { + size: '14px', + color: $mainColor, + whiteSpace: "normal" + }, + position: { + top: popupViewData.viewContentPadding * 4 + 20 + 'px', + height: "30px" + } + }); + } + if(res.contentText){ + contentText = res.contentText; + progressElement.push({ + tag: 'font', + id: 'content', + text: res.contentText, + textStyles: { + size: '16px', + color: "#333", + whiteSpace: "normal" + }, + position: { + top: popupViewData.viewContentPadding * 2 + 30 + 'px', + height: "30px", + } + }); + } + if(res.buttonNum >= 0 && buttonNum != res.buttonNum){ + buttonNum = res.buttonNum; + popupView.reset(); + popupViewData = downloadPopupDrawing(Object.assign({ + progressValue:progressValue, + progressTip:progressTip, + contentText:contentText, + },res)); + let newElement = []; + popupViewData.elementList.map((item,index) => { + let have = false; + progressElement.forEach((childItem,childIndex) => { + if(item.id == childItem.id){ + have = true; + } + }); + if(!have){ + newElement.push(item); + } + }); + progressElement = newElement.concat(progressElement); + popupView.setStyle({ + tag: "rect", + top: (popupViewData.screenHeight - popupViewData.popupViewHeight) / 2 + "px", + left: '15%', + height: popupViewData.popupViewHeight + "px", + width: "70%", + }); + popupView.draw(progressElement); + }else{ + popupView.draw(progressElement); + } + }, + cancel: function() { + maskLayer.hide(); + popupView.hide(); + } + } + popupView.addEventListener("click", function(e) { + let maxTop = popupViewData.popupViewHeight - popupViewData.viewContentPadding; + let maxLeft = popupViewData.popupViewWidth - popupViewData.viewContentPadding; + if (e.clientY > maxTop - 40 && e.clientY < maxTop) { + if(buttonNum == 1){ + // 单按钮 + if (e.clientX > popupViewData.viewContentPadding && e.clientX < maxLeft) { + maskLayer.hide(); + popupView.hide(); + callbackData.reboot(); + } + }else if(buttonNum == 2){ + // 双按钮 + let buttonWidth = (popupViewData.viewContentWidth - popupViewData.viewContentPadding) / 2; + if (e.clientX > popupViewData.viewContentPadding && e.clientX < maxLeft - buttonWidth - popupViewData.viewContentPadding) { + maskLayer.hide(); + popupView.hide(); + callbackData.cancelDownload(); + } else if (e.clientX > maxLeft - buttonWidth && e.clientX < maxLeft) { + maskLayer.hide(); + popupView.hide(); + } + } + } + }); + // 显示弹窗 + maskLayer.show(); + popupView.show(); + // 改变进度条 + return callbackData; +} + +export default (isPrompt = false)=>{ + + getCurrentNo(versionInfo => { + let httpData = { + release: versionInfo.versionCode, + // 版本名称 + version: versionInfo.versionName, + // setupPage参数说明(判断用户是不是从设置页面点击的更新,如果是设置页面点击的更新,有不要用静默更新了,不然用户点击没反应很奇怪的) + setupPage: isPrompt + }; + if (platform == "android") { + httpData.type = 1101; + } else { + httpData.type = 1102; + } + /* 接口入参说明 + * version: 应用当前版本号(已自动获取) + * versionName: 应用当前版本名称(已自动获取) + * type:平台(1101是安卓,1102是IOS) + */ + /****************以下是示例*******************/ + // 可以用自己项目的请求方法(接口自己找后台要,插件不提供) + postJsonRequest($checkUpdateUrl,httpData).then((e)=>{ + let res=e.data; + if (res && res.downloadUrl) { + if (res.updateType == "forcibly" || res.updateType == "silent") { + if (/\.wgt$/i.test(res.downloadUrl)) { + getDownload(res); + } else if(/\.html$/i.test(res.downloadUrl)){ + plus.runtime.openURL(res.downloadUrl); + } else { + if (platform == "android") { + getDownload(res); + } else { + plus.runtime.openURL(res.downloadUrl); + } + } + } else if(res.updateType == "solicit"){ + updatePopup(res, function() { + if (/\.wgt$/i.test(res.downloadUrl)) { + getDownload(res); + } else if(/\.html$/i.test(res.downloadUrl)){ + plus.runtime.openURL(res.downloadUrl); + } else { + if (platform == "android") { + getDownload(res); + } else { + plus.runtime.openURL(res.downloadUrl); + } + } + }); + } + } else if (isPrompt) { + uni.showToast({ + title: "暂无新版本", + icon: "none" + }); + } + }) + }); +} + diff --git a/common/config.js b/common/config.js new file mode 100644 index 0000000..0b9e16e --- /dev/null +++ b/common/config.js @@ -0,0 +1,64 @@ +import CryptoJS from "crypto-js"; + +// 如果为开启ssl证书,请修改为http协议 +let scheme ="https"; //协议头 +// 请将下面的域名替换成自己的服务器域名,如果有端口要把端口加上 +let host = 'im.raingad.com'; + +// 为了避免h5页面被其他人盗用,可以自由选择加密方式,详细教程查看readme.md文件 +let hostToken="shab0725962100bcedc1d0019ff780f2435bi"; + +// 是否开启H5的调试模式 +let isVConsole = false + +// 以下内容请勿修改 +// 以下内容请勿修改 +// 以下内容请勿修改 +// 以下内容请勿修改 + +// #ifdef MP-WEIXIN +let env = wx.getAccountInfoSync() + +if (env.miniProgram.envVersion == 'develop') { + isVConsole = true +} +// #endif +// #ifdef APP-PLUS || H5 +if (process.env.NODE_ENV === 'development') { + isVConsole = true +} +// #endif + +let apiUrl = scheme + '://' + host; +let wssUrl = (scheme == 'https' ? 'wss' :'ws') + '://' + host + '/wss'; + +let hostMd5=CryptoJS.MD5(CryptoJS.MD5(host).toString()).toString(); +if('sha'+hostMd5+'bi'!=hostToken){ + apiUrl = 'false'; + wssUrl = 'false'; +} + +// app更新的配置 +const updateConfig = { + url:apiUrl+'/common/pub/checkVersion', //检查版本的接口 + bgColor:'', //升级主色,按钮背景颜色 + iconUrl:'' //升级小图标 +} + +/* 检查版本需要返回的数据说明 + * | 参数名称 | 一定返回 | 类型 | 描述 + * | -------------|--------- | --------- | ------------- | + * | versionCode | y | int | 版本号 :20240331 | + * | versionName | y | String | 版本名称 :4.0.1 | + * | versionInfo | y | String | 版本信息 : 修复了bug | + * | updateType | y | String | forcibly = 强制更新, solicit = 弹窗确认更新, silent = 静默更新 | + * | downloadUrl | y | String | 版本下载链接(IOS安装包更新请放跳转store应用商店链接,安卓apk和wgt文件放文件下载链接) | + */ + + +export default { + apiUrl, + wssUrl, + isVConsole, + updateConfig +} \ No newline at end of file diff --git a/common/scan.js b/common/scan.js new file mode 100644 index 0000000..d900e71 --- /dev/null +++ b/common/scan.js @@ -0,0 +1,72 @@ +import { + apiUrl, + postJsonRequest, +} from '@/utils/request.js'; + +const verifyQr=(url)=>{ + let pathinfo=url.replace(apiUrl,''); + let pathParts = pathinfo.split('/'); // 使用斜杠字符分割字符串 + let lastPart = pathParts[pathParts.length - 1]; // 获取最后一组数据 + postJsonRequest(pathinfo,{realToken:lastPart}).then((res)=>{ + if(res.code==0){ + switch(res.data.action){ + case 'groupInfo': + uni.navigateTo({ + url: '/pages/message/group/info?group_id='+ res.data.id + }) + break; + case 'userInfo': + uni.navigateTo({ + url:"/pages/contacts/detail?id="+res.data.id + }) + break; + } + } + }) +} + +const scanQr=()=>{ + // #ifndef H5 + uni.scanCode({ + success: function (res) { + checkQr(res.result); + } + }); + // #endif + // #ifdef H5 + uni.navigateTo({ + url:'/pages/index/scan' + }) + // #endif +} + +const checkQr=(data)=>{ + // 如果识别出二维码是跟服务器的地址一样,就请求该接口 + if(data.includes(apiUrl)){ + verifyQr(data); + }else{ + uni.showModal({ + title: '已识别内容', + content: data, + confirmText:'复制内容', + success: function (e) { + if (e.confirm) { + uni.setClipboardData({ + data: data, + success: function () { + uni.showToast({ + title:'复制成功', + icon:'none' + }) + } + }); + } + } + }); + } +} + +export default { + scanQr, + checkQr +} \ No newline at end of file diff --git a/common/socket.js b/common/socket.js new file mode 100644 index 0000000..363aa23 --- /dev/null +++ b/common/socket.js @@ -0,0 +1,193 @@ +import api from '@/common/config.js' // 接口Api,图片地址等等配置,可根据自身情况引入,也可以直接在下面url填入你的 webSocket连接地址 +class socketIO { + constructor(data, time, url) { + this.socketTask = null + this.is_open_socket = false //避免重复连接 + this.url = url ? url : api.wssUrl //连接地址 + this.data = data ? data : null + this.connectNum = 1 // 重连次数 + this.traderDetailIndex = 100 // traderDetailIndex ==2 重连 + this.accountStateIndex = 100 // accountStateIndex ==1 重连 + this.followFlake = false // followFlake == true 重连 + this.init=false; + //心跳检测 + this.timeout = time ? time : 25000 //多少秒执行检测 + this.heartbeatInterval = null //检测服务器端是否还活着 + this.reconnectTimeOut = null //重连之后多久再次重连 + this.networkStatus=true + } + + CALLBACK = (res) => { + if(res.isConnected){ + this.traderDetailIndex=2; + this.connectSocketInit({type:'ping'}) + } + } + + // 进入这个页面的时候创建websocket连接【整个页面随时使用】 + connectSocketInit(data) { + this.data = data + this.socketTask = uni.connectSocket({ + url: this.url, + success: () => { + console.info("正准备建立websocket中..."); + // 返回实例 + return this.socketTask + }, + }); + this.socketTask.onOpen((res) => { + uni.$emit('socketStatus',true); + if(!this.networkStatus){ + // 连接成功后取消网络监听 + uni.offNetworkStatusChange(this.CALLBACK); + } + this.networkStatus=true; + this.connectNum = 1 + console.info("WebSocket连接正常!"); + this.send(data) + clearInterval(this.reconnectTimeOut) + clearInterval(this.heartbeatInterval) + this.is_open_socket = true; + this.start(); + // 注:只有连接正常打开中 ,才能正常收到消息 + this.socketTask.onMessage((e) => { + // 字符串转json + let res = JSON.parse(e.data); + if (res) { + uni.$emit('getPositonsOrder', res); + } + }); + }) + if(!this.init){ + // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接 + uni.onSocketError((res) => { + console.info(res,'WebSocket连接打开失败,请检查!'); + this.socketTask = null + this.is_open_socket = false; + clearInterval(this.heartbeatInterval) + clearInterval(this.reconnectTimeOut) + if (this.connectNum < 10) { + this.traderDetailIndex = 2 + this.reconnect(); + this.connectNum += 1 + } else { + uni.$emit('connectError'); + this.networkStatus=false + uni.onNetworkStatusChange(this.CALLBACK); + this.connectNum = 1 + } + }); + this.init=true; + } + // 这里仅是事件监听【如果socket关闭了会执行】 + this.socketTask.onClose(() => { + console.info("已经被关闭了-------") + clearInterval(this.heartbeatInterval) + clearInterval(this.reconnectTimeOut) + this.is_open_socket = false; + this.socketTask = null + if (this.connectNum < 5) { + this.reconnect(); + } else { + uni.$emit('connectError'); + this.networkStatus=false; + uni.onNetworkStatusChange(this.CALLBACK); + this.connectNum = 1 + } + + }) + } + // 主动关闭socket连接 + Close() { + if (!this.is_open_socket) { + return + } + this.socketTask.close({ + success() { + uni.showToast({ + title: 'SocketTask 关闭成功', + icon: "none" + }); + } + }); + } + //发送消息 + send(data) { + // 注:只有连接正常打开中 ,才能正常成功发送消息 + if (this.socketTask) { + this.socketTask.send({ + data: JSON.stringify(data), + async success() { + }, + }); + } + } + + // 检测状态 + checkStatus(){ + console.info("检查状态") + clearInterval(this.reconnectTimeOut) + if(!this.socketTask || [2,3].includes(this.socketTask.readyState)){ + console.info("未链接!") + return false; + } + return true; + } + + //开启心跳检测 + start() { + this.heartbeatInterval = setInterval(() => { + this.send({ + "type": "ping" + }); + }, this.timeout) + } + //重新连接 + reconnect() { + //停止发送心跳 + console.info('检查是否手动断开,并重新连接') + clearInterval(this.heartbeatInterval) + //如果不是人为关闭的话,进行重连 + if (!this.is_open_socket && (this.traderDetailIndex == 2 || this.accountStateIndex == 0 || this + .followFlake)) { + console.info("5秒后重新连接...") + this.reconnectTimeOut = setInterval(() => { + this.connectSocketInit(this.data); + }, 15000) + } + } + /** + * @description 将 scoket 数据进行过滤 + * @param {array} array + * @param {string} type 区分 弹窗 openposition 分为跟随和我的 + */ + arrayFilter(array, type = 'normal', signalId = 0) { + let arr1 = [] + let arr2 = [] + let obj = { + arr1: [], + arr2: [] + } + arr1 = array.filter(v => v.flwsig == true) + arr2 = array.filter(v => v.flwsig == false) + if (type == 'normal') { + if (signalId) { + arr1 = array.filter(v => v.flwsig == true && v.sigtraderid == signalId) + return arr1 + } else { + return arr1.concat(arr2) + } + } else { + if (signalId > 0) { + arr1 = array.filter(v => v.flwsig == true && v.sigtraderid == signalId) + obj.arr1 = arr1 + } else { + obj.arr1 = arr1 + } + obj.arr2 = arr2 + + return obj + } + } +} +export default socketIO \ No newline at end of file diff --git a/components/.DS_Store b/components/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..58ec18d948ad037950e9ff2d11d0e809927c9502 GIT binary patch literal 6148 zcmeHKyG{c^3>-s>2%40XThdTa)2yOUQ1b&2UQI+I5dBs8uKXE{A3{V24H69+OZMz~ zJ-4|j&M^R+zulh$GXPV%BeovK=I8DsJE)8i>3qf+Hn_zLUhy!h{yyQ{BRsPH8BbsN zSF82ialPJo%=4+n!!XYu}%m + + + + + + + {{noDatatext}} + + + + + + + + diff --git a/components/Tags.vue b/components/Tags.vue new file mode 100644 index 0000000..0d71a68 --- /dev/null +++ b/components/Tags.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/components/breadcrum.vue b/components/breadcrum.vue new file mode 100644 index 0000000..e0f2e03 --- /dev/null +++ b/components/breadcrum.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/components/cu-custom.vue b/components/cu-custom.vue new file mode 100644 index 0000000..5f8a3fd --- /dev/null +++ b/components/cu-custom.vue @@ -0,0 +1,79 @@ + + + \ No newline at end of file diff --git a/components/get-qrcode.vue b/components/get-qrcode.vue new file mode 100644 index 0000000..5aa8397 --- /dev/null +++ b/components/get-qrcode.vue @@ -0,0 +1,433 @@ + + + + + diff --git a/components/im-touch.vue b/components/im-touch.vue new file mode 100644 index 0000000..6077d5a --- /dev/null +++ b/components/im-touch.vue @@ -0,0 +1,130 @@ + + + \ No newline at end of file diff --git a/components/im-user.vue b/components/im-user.vue new file mode 100644 index 0000000..17501e5 --- /dev/null +++ b/components/im-user.vue @@ -0,0 +1,46 @@ + + + \ No newline at end of file diff --git a/components/message/im-image.vue b/components/message/im-image.vue new file mode 100644 index 0000000..0100754 --- /dev/null +++ b/components/message/im-image.vue @@ -0,0 +1,33 @@ + + \ No newline at end of file diff --git a/components/message/im-input.vue b/components/message/im-input.vue new file mode 100644 index 0000000..efc0b45 --- /dev/null +++ b/components/message/im-input.vue @@ -0,0 +1,957 @@ + + + + \ No newline at end of file diff --git a/components/message/im-item.vue b/components/message/im-item.vue new file mode 100644 index 0000000..8f1fefb --- /dev/null +++ b/components/message/im-item.vue @@ -0,0 +1,35 @@ + + + \ No newline at end of file diff --git a/components/message/im-tab.vue b/components/message/im-tab.vue new file mode 100644 index 0000000..d8e6b69 --- /dev/null +++ b/components/message/im-tab.vue @@ -0,0 +1,50 @@ + + + \ No newline at end of file diff --git a/components/message/user-select.vue b/components/message/user-select.vue new file mode 100644 index 0000000..0a6b644 --- /dev/null +++ b/components/message/user-select.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/components/mosowe-canvas-image/mosowe-canvas-image.vue b/components/mosowe-canvas-image/mosowe-canvas-image.vue new file mode 100644 index 0000000..10c108b --- /dev/null +++ b/components/mosowe-canvas-image/mosowe-canvas-image.vue @@ -0,0 +1,455 @@ + + + + + + \ No newline at end of file diff --git a/components/mosowe-canvas-image/readme.md b/components/mosowe-canvas-image/readme.md new file mode 100644 index 0000000..b2de74e --- /dev/null +++ b/components/mosowe-canvas-image/readme.md @@ -0,0 +1,195 @@ +## mosowe-canvas-image:一个可以制作多用途图片的插件(海报,二维码,分享图) + +### v1.2.0: +1. 添加透明度`globalAlpha`,值0-1; +2. 修改只能画一个圆形图片问题,画圆形图片时耗时较多,因为额外增加了一个canvas处理圆形图片,请注意`arcX`与`arcY`的说明; + +### v1.1.0: + +1. 添加本地图片渲染,已支持本地相册/相机 + https的网络图片,建议画布宽高:750*1330 +2. 添加导出图片的类型:`imgType`,可选值,jpg、png +3. 添加本地图片压缩功能:`compress`是否开启压缩,`compressSize`:压缩程度,默认2M,lists列表图片项需增加传参`file`, +4. 解决H5网络图片“canvasToTempFilePath:fail SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported”错误问题,图片服务器需支持“Access-Control-Allow-Origin: *” +5. 使用非solt插槽触发事件时,请确认`$ref`是否正确 +6. 示例增加参数编辑,使用前体验插件 + +#### 平台支持: + +| APP | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节跳动小程序 | QQ小程序 | +| :--: | :--: | :--------: | :----------: | :--------: | :------------: | :------: | +| √ | √ | √ | × | 未测 | 未测 | 未测 | + +#### 插件功能 + +1. 支持多图片绘制,多文本绘制,圆形图片绘制; +2. 支持矩形(线条)绘制; +3. 支持圆形绘制; +4. 支持二维码生成,项目用不上可以去插件内去除,毕竟这个插件携带的比较大,单纯用来生成二维码图片也是阔以的; +5. 支持绘图后预览。 + +多用于海报图,分享图; + +注意H5跨域问题及小程序白名单配置; + +图片是网络图片:https://....(require及import引入不了3Kb以上的绝对路径图片,若有大神知道处理方法,望不吝赐教,谢谢!) + +#### 属性 + +| 名称 | 类型 | 默认值 | 说明 | 版本 | +| ------------ | ---------------- | ------------ | -------------------------------------------------------- | ----- | +| width | Number \String | 200 | canvas画布宽度,也是导出图片宽度,单位px,值中不要带单位 | 1.0.0 | +| height | Number \String | 200 | canvas画布高度,也是导出图片高度,单位px,值中不要带单位 | 1.0.0 | +| showPreview | Boolean | false | 绘制完成后是否打开预览 | 1.0.0 | +| lists | Array | [] | 绘制的元素列表:图片,文字,矩形(线条),圆形,二维码 | 1.0.0 | +| imgType | String | jpg | 生成图片格式,可选:png | 1.1.0 | +| compress | Boolean | false | 是否开启图片压缩 | 1.1.0 | +| compressSize | Number\String | 2097152 (2M) | 超过多少M压缩 | 1.1.0 | + + + + +#### lists\属性 + +注意:图文先后顺序,底层的图片靠前,最上层的在最后,圆形图片放在最后,因为一旦绘制圆形,后续的元素都只在该圆形内显示,而超过圆形范围的将看不见。 + +| 名称 | 类型 | 必填 | 说明 |版本| +| :------- | :----- | :--- | :----------------------------------------------------------- |:----| +| type | String | 是 | 元素类型:`image`图片,`text`文本,`rect`矩形(线条),`arc`圆形,`qr`二维码 |1.0.0| +| content | String | 否 | image:图片路径(必填),text:文字(必填),qr:转二维码的数据(必填),rect及arc:非必填 |1.0.0| +| x | Number | 是 | X轴坐标,绘制圆形图片时:x = arcX - arcR |1.0.0| +| y | Number | 是 | Y轴坐标,绘制圆形图片时:y = arcY - arcR |1.0.0| +| width | Number | 否 | 图片、矩形(线条)、二维码宽度 |1.0.0| +| height | Number | 否 | 图片、矩形(线条)、二维码高度 |1.0.0| +| arc | Boolen | 否 | type=image时:是否绘制圆形图片 |1.0.0| +| arcX | Number | 否 | type=arc时:绘制圆形时中心点X轴坐标,type=image时,图片在圆形canvas的X坐标,多为负数,版本`1.2.0` |1.2.0| +| arcY | Number | 否 | type=arc时:绘制圆形时中心点Y轴坐标,type=image时,图片在圆形canvas的Y坐标,多为负数,版本`1.2.0` |1.2.0| +| arcR | Number | 否 | type=image、arc时:绘制圆形的半径 |1.0.0| +| color | String | 否 | 绘制文本、矩形(线条)的颜色,默认:#000000 |1.0.0| +| size | Number | 否 | 绘制文本的字号大小,默认:20 |1.0.0| +| align | String | 否 | 绘制文本的对齐方式,默认:left |1.0.0| +| maxWidth | Number | 否 | 绘制文本的最大宽度,文字长度超过该值会被压缩 |1.0.0| +| file | file | 否 | 选择本地图片的file文件,版本`1.1.0` |1.1.0| +| globalAlpha | Number | 否 | 透明度:0~1,默认1,版本`1.2.0` |1.2.0| + +#### slots + +| 名称 | 说明 | +| :------ | :--------------------------------- | +| default | 自定义插槽,点击此区会触发绘图事件 | + +#### 事件 + +| 名称 | 回调参数 | 说明 | +| ----------- | -------- | ------------------------------------ | +| canvasImage | url | 绘制成功后返回的本地地址,H5为base64 | + + + +#### 使用方式 + +若`page.json`中配置了`"easycom": true`,则无需`script`引入就可以使用,没有则需要引入。 + +1. 无slot:组件标签添加`ref`属性,采用父级调用子组件`createCanvas()`方法使用,见后文示例; +2. 有slot:slot区点击就会执行 + +#### 示例 + +```javascript +// js +data () { + return { + canvasUrl: '', + lists: [ + { + type: 'image', + content: 'https://www.zhonglixunqing.cn/images/uniapp/1.jpg', + width: 200, + height: 100, + x: 50, + y: 20, + }, + { + type: 'image', + content: 'https://www.zhonglixunqing.cn/images/uniapp/2.jpg', + width: 80, + height: 80, + x: 20, + y: 200, + arc: false, + arcX: 0, + arcY: 0, + arcR: 0 + }, + { + type: 'text', + content: '扫一扫,获取更多信息', + x: 120, + y: 250, + color: '#ff0000', + size: 10, + // maxWidth: 100, + // align: 'left', + }, + { + type: 'rect', + width: 1, + height: 100, + x: 0, + y: 10, + color: '#ff0000', + }, + { + type: 'image', + content: 'https://www.zhonglixunqing.cn/images/uniapp/3.jpg', + width: 100, + height: 100, + x: 200, + y: 200, + arc: true, + arcX: 250, + arcY: 250, + arcR: 50 + }, + ] + }; + }, + methods: { + beginCanvas () { + this.$refs.mosoweCanvasComponents.createCanvas(); + }, + _canvasImage (e) { + this.canvasUrl = e; + } + } +``` + +插件外独立按钮触发: + +```html + + + +``` + +slot插槽触发: + +```html + + + slot按钮的 + + +``` + +#### 预览地址 + diff --git a/components/mosowe-canvas-image/wxqrcode.js b/components/mosowe-canvas-image/wxqrcode.js new file mode 100644 index 0000000..739750c --- /dev/null +++ b/components/mosowe-canvas-image/wxqrcode.js @@ -0,0 +1,1623 @@ +//--------------------------------------------------------------------- +// +// QR Code Generator for JavaScript +// +// Copyright (c) 2009 Kazuhiko Arase +// +// URL: [url=http://www.d-project.com/]http://www.d-project.com/[/url] +// +// Licensed under the MIT license: +// [url=http://www.opensource.org/licenses/mit-license.php]http://www.opensource.org/licenses/mit-license.php[/url] +// +// The word 'QR Code' is registered trademark of +// DENSO WAVE INCORPORATED +// [url=http://www.denso-wave.com/qrcode/faqpatent-e.html]http://www.denso-wave.com/qrcode/faqpatent-e.html[/url] +// +//--------------------------------------------------------------------- + +//--------------------------------------------------------------------- +// qrcode +//代码第1588行为补充代码 +//修改人:chenxing +//2017-02-27 16:21:32 +//--------------------------------------------------------------------- + +/** + * qrcode + * @param typeNumber 1 to 40 + * @param errorCorrectLevel 'L','M','Q','H' + */ +var qrcode = function(typeNumber, errorCorrectLevel) { + + var PAD0 = 0xEC; + var PAD1 = 0x11; + + var _typeNumber = typeNumber; + var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel]; + var _modules = null; + var _moduleCount = 0; + var _dataCache = null; + var _dataList = new Array(); + + var _this = {}; + + var makeImpl = function(test, maskPattern) { + + _moduleCount = _typeNumber * 4 + 17; + _modules = function(moduleCount) { + var modules = new Array(moduleCount); + for (var row = 0; row < moduleCount; row += 1) { + modules[row] = new Array(moduleCount); + for (var col = 0; col < moduleCount; col += 1) { + modules[row][col] = null; + } + } + return modules; + }(_moduleCount); + + setupPositionProbePattern(0, 0); + setupPositionProbePattern(_moduleCount - 7, 0); + setupPositionProbePattern(0, _moduleCount - 7); + setupPositionAdjustPattern(); + setupTimingPattern(); + setupTypeInfo(test, maskPattern); + + if (_typeNumber >= 7) { + setupTypeNumber(test); + } + + if (_dataCache == null) { + _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList); + } + + mapData(_dataCache, maskPattern); + }; + + var setupPositionProbePattern = function(row, col) { + + for (var r = -1; r <= 7; r += 1) { + + if (row + r <= -1 || _moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c += 1) { + + if (col + c <= -1 || _moduleCount <= col + c) continue; + + if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) + || (0 <= c && c <= 6 && (r == 0 || r == 6) ) + || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + }; + + var getBestMaskPattern = function() { + + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i += 1) { + + makeImpl(true, i); + + var lostPoint = QRUtil.getLostPoint(_this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }; + + var setupTimingPattern = function() { + + for (var r = 8; r < _moduleCount - 8; r += 1) { + if (_modules[r][6] != null) { + continue; + } + _modules[r][6] = (r % 2 == 0); + } + + for (var c = 8; c < _moduleCount - 8; c += 1) { + if (_modules[6][c] != null) { + continue; + } + _modules[6][c] = (c % 2 == 0); + } + }; + + var setupPositionAdjustPattern = function() { + + var pos = QRUtil.getPatternPosition(_typeNumber); + + for (var i = 0; i < pos.length; i += 1) { + + for (var j = 0; j < pos.length; j += 1) { + + var row = pos[i]; + var col = pos[j]; + + if (_modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r += 1) { + + for (var c = -2; c <= 2; c += 1) { + + if (r == -2 || r == 2 || c == -2 || c == 2 + || (r == 0 && c == 0) ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + } + } + }; + + var setupTypeNumber = function(test) { + + var bits = QRUtil.getBCHTypeNumber(_typeNumber); + + for (var i = 0; i < 18; i += 1) { + var mod = (!test && ( (bits >> i) & 1) == 1); + _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i += 1) { + var mod = (!test && ( (bits >> i) & 1) == 1); + _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }; + + var setupTypeInfo = function(test, maskPattern) { + + var data = (_errorCorrectLevel << 3) | maskPattern; + var bits = QRUtil.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i += 1) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 6) { + _modules[i][8] = mod; + } else if (i < 8) { + _modules[i + 1][8] = mod; + } else { + _modules[_moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i += 1) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 8) { + _modules[8][_moduleCount - i - 1] = mod; + } else if (i < 9) { + _modules[8][15 - i - 1 + 1] = mod; + } else { + _modules[8][15 - i - 1] = mod; + } + } + + // fixed module + _modules[_moduleCount - 8][8] = (!test); + }; + + var mapData = function(data, maskPattern) { + + var inc = -1; + var row = _moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + var maskFunc = QRUtil.getMaskFunction(maskPattern); + + for (var col = _moduleCount - 1; col > 0; col -= 2) { + + if (col == 6) col -= 1; + + while (true) { + + for (var c = 0; c < 2; c += 1) { + + if (_modules[row][col - c] == null) { + + var dark = false; + + if (byteIndex < data.length) { + dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); + } + + var mask = maskFunc(row, col - c); + + if (mask) { + dark = !dark; + } + + _modules[row][col - c] = dark; + bitIndex -= 1; + + if (bitIndex == -1) { + byteIndex += 1; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || _moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + }; + + var createBytes = function(buffer, rsBlocks) { + + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r += 1) { + + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i += 1) { + dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]; + } + offset += dcCount; + + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); + var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i += 1) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0; + } + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < dcdata[r].length) { + data[index] = dcdata[r][i]; + index += 1; + } + } + } + + for (var i = 0; i < maxEcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < ecdata[r].length) { + data[index] = ecdata[r][i]; + index += 1; + } + } + } + + return data; + }; + + var createData = function(typeNumber, errorCorrectLevel, dataList) { + + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); + + var buffer = qrBitBuffer(); + + for (var i = 0; i < dataList.length; i += 1) { + var data = dataList[i]; + buffer.put(data.getMode(), 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error('code length overflow. (' + + buffer.getLengthInBits() + + '>' + + totalDataCount * 8 + + ')'); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD1, 8); + } + + return createBytes(buffer, rsBlocks); + }; + + _this.addData = function(data) { + var newData = qr8BitByte(data); + _dataList.push(newData); + _dataCache = null; + }; + + _this.isDark = function(row, col) { + if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) { + throw new Error(row + ',' + col); + } + return _modules[row][col]; + }; + + _this.getModuleCount = function() { + return _moduleCount; + }; + + _this.make = function() { + makeImpl(false, getBestMaskPattern() ); + }; + + _this.createTableTag = function(cellSize, margin) { + + cellSize = cellSize || 2; + margin = (typeof margin == 'undefined')? cellSize * 4 : margin; + + var qrHtml = ''; + + qrHtml += ''; + qrHtml += ''; + + for (var r = 0; r < _this.getModuleCount(); r += 1) { + + qrHtml += ''; + + for (var c = 0; c < _this.getModuleCount(); c += 1) { + qrHtml += ''; + } + + qrHtml += ''; + qrHtml += '
'; + } + + qrHtml += '
'; + + return qrHtml; + }; + + _this.createImgTag = function(cellSize, margin, size) { + + cellSize = cellSize || 2; + margin = (typeof margin == 'undefined')? cellSize * 4 : margin; + + var min = margin; + var max = _this.getModuleCount() * cellSize + margin; + + return createImgTag(size, size, function(x, y) { + if (min <= x && x < max && min <= y && y < max) { + var c = Math.floor( (x - min) / cellSize); + var r = Math.floor( (y - min) / cellSize); + return _this.isDark(r, c)? 0 : 1; + } else { + return 1; + } + } ); + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// qrcode.stringToBytes +//--------------------------------------------------------------------- + +qrcode.stringToBytes = function(s) { + var bytes = new Array(); + for (var i = 0; i < s.length; i += 1) { + var c = s.charCodeAt(i); + bytes.push(c & 0xff); + } + return bytes; +}; + +//--------------------------------------------------------------------- +// qrcode.createStringToBytes +//--------------------------------------------------------------------- + +/** + * @param unicodeData base64 string of byte array. + * [16bit Unicode],[16bit Bytes], ... + * @param numChars + */ +qrcode.createStringToBytes = function(unicodeData, numChars) { + + // create conversion map. + + var unicodeMap = function() { + + var bin = base64DecodeInputStream(unicodeData); + var read = function() { + var b = bin.read(); + if (b == -1) throw new Error(); + return b; + }; + + var count = 0; + var unicodeMap = {}; + while (true) { + var b0 = bin.read(); + if (b0 == -1) break; + var b1 = read(); + var b2 = read(); + var b3 = read(); + var k = String.fromCharCode( (b0 << 8) | b1); + var v = (b2 << 8) | b3; + unicodeMap[k] = v; + count += 1; + } + if (count != numChars) { + throw new Error(count + ' != ' + numChars); + } + + return unicodeMap; + }(); + + var unknownChar = '?'.charCodeAt(0); + + return function(s) { + var bytes = new Array(); + for (var i = 0; i < s.length; i += 1) { + var c = s.charCodeAt(i); + if (c < 128) { + bytes.push(c); + } else { + var b = unicodeMap[s.charAt(i)]; + if (typeof b == 'number') { + if ( (b & 0xff) == b) { + // 1byte + bytes.push(b); + } else { + // 2bytes + bytes.push(b >>> 8); + bytes.push(b & 0xff); + } + } else { + bytes.push(unknownChar); + } + } + } + return bytes; + }; +}; + +//--------------------------------------------------------------------- +// QRMode +//--------------------------------------------------------------------- + +var QRMode = { + MODE_NUMBER : 1 << 0, + MODE_ALPHA_NUM : 1 << 1, + MODE_8BIT_BYTE : 1 << 2, + MODE_KANJI : 1 << 3 +}; + +//--------------------------------------------------------------------- +// QRErrorCorrectLevel +//--------------------------------------------------------------------- + +var QRErrorCorrectLevel = { + L : 1, + M : 0, + Q : 3, + H : 2 +}; + +//--------------------------------------------------------------------- +// QRMaskPattern +//--------------------------------------------------------------------- + +var QRMaskPattern = { + PATTERN000 : 0, + PATTERN001 : 1, + PATTERN010 : 2, + PATTERN011 : 3, + PATTERN100 : 4, + PATTERN101 : 5, + PATTERN110 : 6, + PATTERN111 : 7 +}; + +//--------------------------------------------------------------------- +// QRUtil +//--------------------------------------------------------------------- + +var QRUtil = function() { + + var PATTERN_POSITION_TABLE = [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ]; + var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0); + var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0); + var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1); + + var _this = {}; + + var getBCHDigit = function(data) { + var digit = 0; + while (data != 0) { + digit += 1; + data >>>= 1; + } + return digit; + }; + + _this.getBCHTypeInfo = function(data) { + var d = data << 10; + while (getBCHDigit(d) - getBCHDigit(G15) >= 0) { + d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) ); + } + return ( (data << 10) | d) ^ G15_MASK; + }; + + _this.getBCHTypeNumber = function(data) { + var d = data << 12; + while (getBCHDigit(d) - getBCHDigit(G18) >= 0) { + d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) ); + } + return (data << 12) | d; + }; + + _this.getPatternPosition = function(typeNumber) { + return PATTERN_POSITION_TABLE[typeNumber - 1]; + }; + + _this.getMaskFunction = function(maskPattern) { + + switch (maskPattern) { + + case QRMaskPattern.PATTERN000 : + return function(i, j) { return (i + j) % 2 == 0; }; + case QRMaskPattern.PATTERN001 : + return function(i, j) { return i % 2 == 0; }; + case QRMaskPattern.PATTERN010 : + return function(i, j) { return j % 3 == 0; }; + case QRMaskPattern.PATTERN011 : + return function(i, j) { return (i + j) % 3 == 0; }; + case QRMaskPattern.PATTERN100 : + return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; }; + case QRMaskPattern.PATTERN101 : + return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; }; + case QRMaskPattern.PATTERN110 : + return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; }; + case QRMaskPattern.PATTERN111 : + return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; }; + + default : + throw new Error('bad maskPattern:' + maskPattern); + } + }; + + _this.getErrorCorrectPolynomial = function(errorCorrectLength) { + var a = qrPolynomial([1], 0); + for (var i = 0; i < errorCorrectLength; i += 1) { + a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) ); + } + return a; + }; + + _this.getLengthInBits = function(mode, type) { + + if (1 <= type && type < 10) { + + // 1 - 9 + + switch(mode) { + case QRMode.MODE_NUMBER : return 10; + case QRMode.MODE_ALPHA_NUM : return 9; + case QRMode.MODE_8BIT_BYTE : return 8; + case QRMode.MODE_KANJI : return 8; + default : + throw new Error('mode:' + mode); + } + + } else if (type < 27) { + + // 10 - 26 + + switch(mode) { + case QRMode.MODE_NUMBER : return 12; + case QRMode.MODE_ALPHA_NUM : return 11; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 10; + default : + throw new Error('mode:' + mode); + } + + } else if (type < 41) { + + // 27 - 40 + + switch(mode) { + case QRMode.MODE_NUMBER : return 14; + case QRMode.MODE_ALPHA_NUM : return 13; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 12; + default : + throw new Error('mode:' + mode); + } + + } else { + throw new Error('type:' + type); + } + }; + + _this.getLostPoint = function(qrcode) { + + var moduleCount = qrcode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount; col += 1) { + + var sameCount = 0; + var dark = qrcode.isDark(row, col); + + for (var r = -1; r <= 1; r += 1) { + + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c += 1) { + + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrcode.isDark(row + r, col + c) ) { + sameCount += 1; + } + } + } + + if (sameCount > 5) { + lostPoint += (3 + sameCount - 5); + } + } + }; + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row += 1) { + for (var col = 0; col < moduleCount - 1; col += 1) { + var count = 0; + if (qrcode.isDark(row, col) ) count += 1; + if (qrcode.isDark(row + 1, col) ) count += 1; + if (qrcode.isDark(row, col + 1) ) count += 1; + if (qrcode.isDark(row + 1, col + 1) ) count += 1; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount - 6; col += 1) { + if (qrcode.isDark(row, col) + && !qrcode.isDark(row, col + 1) + && qrcode.isDark(row, col + 2) + && qrcode.isDark(row, col + 3) + && qrcode.isDark(row, col + 4) + && !qrcode.isDark(row, col + 5) + && qrcode.isDark(row, col + 6) ) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount - 6; row += 1) { + if (qrcode.isDark(row, col) + && !qrcode.isDark(row + 1, col) + && qrcode.isDark(row + 2, col) + && qrcode.isDark(row + 3, col) + && qrcode.isDark(row + 4, col) + && !qrcode.isDark(row + 5, col) + && qrcode.isDark(row + 6, col) ) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount; row += 1) { + if (qrcode.isDark(row, col) ) { + darkCount += 1; + } + } + } + + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + }; + + return _this; +}(); + +//--------------------------------------------------------------------- +// QRMath +//--------------------------------------------------------------------- + +var QRMath = function() { + + var EXP_TABLE = new Array(256); + var LOG_TABLE = new Array(256); + + // initialize tables + for (var i = 0; i < 8; i += 1) { + EXP_TABLE[i] = 1 << i; + } + for (var i = 8; i < 256; i += 1) { + EXP_TABLE[i] = EXP_TABLE[i - 4] + ^ EXP_TABLE[i - 5] + ^ EXP_TABLE[i - 6] + ^ EXP_TABLE[i - 8]; + } + for (var i = 0; i < 255; i += 1) { + LOG_TABLE[EXP_TABLE[i] ] = i; + } + + var _this = {}; + + _this.glog = function(n) { + + if (n < 1) { + throw new Error('glog(' + n + ')'); + } + + return LOG_TABLE[n]; + }; + + _this.gexp = function(n) { + + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return EXP_TABLE[n]; + }; + + return _this; +}(); + +//--------------------------------------------------------------------- +// qrPolynomial +//--------------------------------------------------------------------- + +function qrPolynomial(num, shift) { + + if (typeof num.length == 'undefined') { + throw new Error(num.length + '/' + shift); + } + + var _num = function() { + var offset = 0; + while (offset < num.length && num[offset] == 0) { + offset += 1; + } + var _num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i += 1) { + _num[i] = num[i + offset]; + } + return _num; + }(); + + var _this = {}; + + _this.getAt = function(index) { + return _num[index]; + }; + + _this.getLength = function() { + return _num.length; + }; + + _this.multiply = function(e) { + + var num = new Array(_this.getLength() + e.getLength() - 1); + + for (var i = 0; i < _this.getLength(); i += 1) { + for (var j = 0; j < e.getLength(); j += 1) { + num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) ); + } + } + + return qrPolynomial(num, 0); + }; + + _this.mod = function(e) { + + if (_this.getLength() - e.getLength() < 0) { + return _this; + } + + var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) ); + + var num = new Array(_this.getLength() ); + for (var i = 0; i < _this.getLength(); i += 1) { + num[i] = _this.getAt(i); + } + + for (var i = 0; i < e.getLength(); i += 1) { + num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio); + } + + // recursive call + return qrPolynomial(num, 0).mod(e); + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// QRRSBlock +//--------------------------------------------------------------------- + +var QRRSBlock = function() { + + + // [1: [L, M, Q, H], ..] + var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]]; + + var qrRSBlock = function(totalCount, dataCount) { + var _this = {}; + _this.totalCount = totalCount; + _this.dataCount = dataCount; + return _this; + }; + + var _this = {}; + + var getRsBlockTable = function(typeNumber, errorCorrectLevel) { + + switch(errorCorrectLevel) { + case QRErrorCorrectLevel.L : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case QRErrorCorrectLevel.M : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case QRErrorCorrectLevel.Q : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case QRErrorCorrectLevel.H : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default : + return undefined; + } + }; + + _this.getRSBlocks = function(typeNumber, errorCorrectLevel) { + + var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel); + + if (typeof rsBlock == 'undefined') { + throw new Error('bad rs block [url=home.php?mod=space&uid=5302]@[/url] typeNumber:' + typeNumber + + '/errorCorrectLevel:' + errorCorrectLevel); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i += 1) { + + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j += 1) { + list.push(qrRSBlock(totalCount, dataCount) ); + } + } + + return list; + }; + + return _this; +}(); + +//--------------------------------------------------------------------- +// qrBitBuffer +//--------------------------------------------------------------------- + +var qrBitBuffer = function() { + + var _buffer = new Array(); + var _length = 0; + + var _this = {}; + + _this.getBuffer = function() { + return _buffer; + }; + + _this.getAt = function(index) { + var bufIndex = Math.floor(index / 8); + return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; + }; + + _this.put = function(num, length) { + for (var i = 0; i < length; i += 1) { + _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); + } + }; + + _this.getLengthInBits = function() { + return _length; + }; + + _this.putBit = function(bit) { + + var bufIndex = Math.floor(_length / 8); + if (_buffer.length <= bufIndex) { + _buffer.push(0); + } + + if (bit) { + _buffer[bufIndex] |= (0x80 >>> (_length % 8) ); + } + + _length += 1; + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// qr8BitByte +//--------------------------------------------------------------------- + +var qr8BitByte = function(data) { + + var _mode = QRMode.MODE_8BIT_BYTE; + var _data = data; + var _parsedData = []; + + var _this = {}; + + + // Added to support UTF-8 Characters + for (var i = 0, l = _data.length; i < l; i++) { + var byteArray = []; + var code = _data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + // Fix Unicode corruption bug + _parsedData.push(byteArray); + } + + _parsedData = Array.prototype.concat.apply([], _parsedData); + + if (_parsedData.length != _data.length) { + _parsedData.unshift(191); + _parsedData.unshift(187); + _parsedData.unshift(239); + } + + var _bytes = _parsedData; + + _this.getMode = function() { + return _mode; + }; + + _this.getLength = function(buffer) { + return _bytes.length; + }; + + _this.write = function(buffer) { + for (var i = 0; i < _bytes.length; i += 1) { + buffer.put(_bytes[i], 8); + } + }; + + return _this; +}; + +//===================================================================== +// GIF Support etc. +// + +//--------------------------------------------------------------------- +// byteArrayOutputStream +//--------------------------------------------------------------------- + +var byteArrayOutputStream = function() { + + var _bytes = new Array(); + + var _this = {}; + + _this.writeByte = function(b) { + _bytes.push(b & 0xff); + }; + + _this.writeShort = function(i) { + _this.writeByte(i); + _this.writeByte(i >>> 8); + }; + + _this.writeBytes = function(b, off, len) { + off = off || 0; + len = len || b.length; + for (var i = 0; i < len; i += 1) { + _this.writeByte(b[i + off]); + } + }; + + _this.writeString = function(s) { + for (var i = 0; i < s.length; i += 1) { + _this.writeByte(s.charCodeAt(i) ); + } + }; + + _this.toByteArray = function() { + return _bytes; + }; + + _this.toString = function() { + var s = ''; + s += '['; + for (var i = 0; i < _bytes.length; i += 1) { + if (i > 0) { + s += ','; + } + s += _bytes[i]; + } + s += ']'; + return s; + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// base64EncodeOutputStream +//--------------------------------------------------------------------- + +var base64EncodeOutputStream = function() { + + var _buffer = 0; + var _buflen = 0; + var _length = 0; + var _base64 = ''; + + var _this = {}; + + var writeEncoded = function(b) { + _base64 += String.fromCharCode(encode(b & 0x3f) ); + }; + + var encode = function(n) { + if (n < 0) { + // error. + } else if (n < 26) { + return 0x41 + n; + } else if (n < 52) { + return 0x61 + (n - 26); + } else if (n < 62) { + return 0x30 + (n - 52); + } else if (n == 62) { + return 0x2b; + } else if (n == 63) { + return 0x2f; + } + throw new Error('n:' + n); + }; + + _this.writeByte = function(n) { + + _buffer = (_buffer << 8) | (n & 0xff); + _buflen += 8; + _length += 1; + + while (_buflen >= 6) { + writeEncoded(_buffer >>> (_buflen - 6) ); + _buflen -= 6; + } + }; + + _this.flush = function() { + + if (_buflen > 0) { + writeEncoded(_buffer << (6 - _buflen) ); + _buffer = 0; + _buflen = 0; + } + + if (_length % 3 != 0) { + // padding + var padlen = 3 - _length % 3; + for (var i = 0; i < padlen; i += 1) { + _base64 += '='; + } + } + }; + + _this.toString = function() { + return _base64; + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// base64DecodeInputStream +//--------------------------------------------------------------------- + +var base64DecodeInputStream = function(str) { + + var _str = str; + var _pos = 0; + var _buffer = 0; + var _buflen = 0; + + var _this = {}; + + _this.read = function() { + + while (_buflen < 8) { + + if (_pos >= _str.length) { + if (_buflen == 0) { + return -1; + } + throw new Error('unexpected end of file./' + _buflen); + } + + var c = _str.charAt(_pos); + _pos += 1; + + if (c == '=') { + _buflen = 0; + return -1; + } else if (c.match(/^\s$/) ) { + // ignore if whitespace. + continue; + } + + _buffer = (_buffer << 6) | decode(c.charCodeAt(0) ); + _buflen += 6; + } + + var n = (_buffer >>> (_buflen - 8) ) & 0xff; + _buflen -= 8; + return n; + }; + + var decode = function(c) { + if (0x41 <= c && c <= 0x5a) { + return c - 0x41; + } else if (0x61 <= c && c <= 0x7a) { + return c - 0x61 + 26; + } else if (0x30 <= c && c <= 0x39) { + return c - 0x30 + 52; + } else if (c == 0x2b) { + return 62; + } else if (c == 0x2f) { + return 63; + } else { + throw new Error('c:' + c); + } + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// gifImage (B/W) +//--------------------------------------------------------------------- + +var gifImage = function(width, height) { + + var _width = width; + var _height = height; + var _data = new Array(width * height); + + var _this = {}; + + _this.setPixel = function(x, y, pixel) { + _data[y * _width + x] = pixel; + }; + + _this.write = function(out) { + + //--------------------------------- + // GIF Signature + + out.writeString('GIF87a'); + + //--------------------------------- + // Screen Descriptor + + out.writeShort(_width); + out.writeShort(_height); + + out.writeByte(0x80); // 2bit + out.writeByte(0); + out.writeByte(0); + + //--------------------------------- + // Global Color Map + + // black + out.writeByte(0x00); + out.writeByte(0x00); + out.writeByte(0x00); + + // white + out.writeByte(0xff); + out.writeByte(0xff); + out.writeByte(0xff); + + //--------------------------------- + // Image Descriptor + + out.writeString(','); + out.writeShort(0); + out.writeShort(0); + out.writeShort(_width); + out.writeShort(_height); + out.writeByte(0); + + //--------------------------------- + // Local Color Map + + //--------------------------------- + // Raster Data + + var lzwMinCodeSize = 2; + var raster = getLZWRaster(lzwMinCodeSize); + + out.writeByte(lzwMinCodeSize); + + var offset = 0; + + while (raster.length - offset > 255) { + out.writeByte(255); + out.writeBytes(raster, offset, 255); + offset += 255; + } + + out.writeByte(raster.length - offset); + out.writeBytes(raster, offset, raster.length - offset); + out.writeByte(0x00); + + //--------------------------------- + // GIF Terminator + out.writeString(';'); + }; + + var bitOutputStream = function(out) { + + var _out = out; + var _bitLength = 0; + var _bitBuffer = 0; + + var _this = {}; + + _this.write = function(data, length) { + + if ( (data >>> length) != 0) { + throw new Error('length over'); + } + + while (_bitLength + length >= 8) { + _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); + length -= (8 - _bitLength); + data >>>= (8 - _bitLength); + _bitBuffer = 0; + _bitLength = 0; + } + + _bitBuffer = (data << _bitLength) | _bitBuffer; + _bitLength = _bitLength + length; + }; + + _this.flush = function() { + if (_bitLength > 0) { + _out.writeByte(_bitBuffer); + } + }; + + return _this; + }; + + var getLZWRaster = function(lzwMinCodeSize) { + + var clearCode = 1 << lzwMinCodeSize; + var endCode = (1 << lzwMinCodeSize) + 1; + var bitLength = lzwMinCodeSize + 1; + + // Setup LZWTable + var table = lzwTable(); + + for (var i = 0; i < clearCode; i += 1) { + table.add(String.fromCharCode(i) ); + } + table.add(String.fromCharCode(clearCode) ); + table.add(String.fromCharCode(endCode) ); + + var byteOut = byteArrayOutputStream(); + var bitOut = bitOutputStream(byteOut); + + // clear code + bitOut.write(clearCode, bitLength); + + var dataIndex = 0; + + var s = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + while (dataIndex < _data.length) { + + var c = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + if (table.contains(s + c) ) { + + s = s + c; + + } else { + + bitOut.write(table.indexOf(s), bitLength); + + if (table.size() < 0xfff) { + + if (table.size() == (1 << bitLength) ) { + bitLength += 1; + } + + table.add(s + c); + } + + s = c; + } + } + + bitOut.write(table.indexOf(s), bitLength); + + // end code + bitOut.write(endCode, bitLength); + + bitOut.flush(); + + return byteOut.toByteArray(); + }; + + var lzwTable = function() { + + var _map = {}; + var _size = 0; + + var _this = {}; + + _this.add = function(key) { + if (_this.contains(key) ) { + throw new Error('dup key:' + key); + } + _map[key] = _size; + _size += 1; + }; + + _this.size = function() { + return _size; + }; + + _this.indexOf = function(key) { + return _map[key]; + }; + + _this.contains = function(key) { + return typeof _map[key] != 'undefined'; + }; + + return _this; + }; + + return _this; +}; + +var createImgTag = function(width, height, getPixel, alt) { + + var gif = gifImage(width, height); + for (var y = 0; y < height; y += 1) { + for (var x = 0; x < width; x += 1) { + gif.setPixel(x, y, getPixel(x, y) ); + } + } + + var b = byteArrayOutputStream(); + gif.write(b); + + var base64 = base64EncodeOutputStream(); + var bytes = b.toByteArray(); + for (var i = 0; i < bytes.length; i += 1) { + base64.writeByte(bytes[i]); + } + base64.flush(); + + var img = ''; + img += 'data:image/gif;base64,'; + img += base64; + + return img; +}; + +//--------------------------------------------------------------------- +// returns qrcode function. + +var createQrCodeImg = function(text, options) { + options = options || {}; + var typeNumber = options.typeNumber || 4; + var errorCorrectLevel = options.errorCorrectLevel || 'M'; + var size = options.size || 500; + + var qr; + + try { + qr = qrcode(typeNumber, errorCorrectLevel || 'M'); + qr.addData(text); + qr.make(); + } catch (e) { + if(typeNumber >= 40) { + throw new Error('Text too long to encode'); + } else { + return gen(text, { + size: size, + errorCorrectLevel: errorCorrectLevel, + typeNumber: typeNumber + 1 + }); + } + } + + // calc cellsize and margin + var cellsize = parseInt(size / qr.getModuleCount()); + var margin = parseInt((size - qr.getModuleCount() * cellsize) / 2); + + return qr.createImgTag(cellsize, margin, size); +}; +// var module = {}; 需要注释这一行,否则微信小程序无法使用 +export default { + createQrCodeImg : createQrCodeImg +}; \ No newline at end of file diff --git a/components/status.vue b/components/status.vue new file mode 100644 index 0000000..7b730ce --- /dev/null +++ b/components/status.vue @@ -0,0 +1,92 @@ + + + + + + diff --git a/components/yq-avatar/yq-avatar.vue b/components/yq-avatar/yq-avatar.vue new file mode 100644 index 0000000..c3f6790 --- /dev/null +++ b/components/yq-avatar/yq-avatar.vue @@ -0,0 +1,1371 @@ + + + + + diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..11ad3eb104b02ccc461b14e44f263f497804a597 GIT binary patch literal 9662 zcmeI2No-9~7{_l@&$G+nqpa27R4@W1Ev1RYnEl*8gI+)7`Vl5%c3Sy>#0hrm4eS|aahDOf%@a6 zJ}Qk`N|jOFl;7OZ-!G<8N{nKSywp0%Vf%rK9v8ItVic?4R+~+Qf!)|rtU3>3mrs>b z=CiQ07ajIowp}6Q7qi%}hLGL(h}fHlg+Gt}Hy90%zoyQfmj>(~2OP>AoHRybhi4u` zJ5K&cpmYWBvIwXvADlF%bS0o;_%a9Du6!Nv=??JqDfMKK;uwuBUrTqiV_Eh-k zbBde8Q^U)Dd#m>`EdNQ>{__2&h4lR?-r8P1nkv6?RZR(SJj;9bg!~VkSY}N0#kJ{k za+KKXuLGx-_`@EL|NC>GwGQa`1ayA0)$y5q?|{aa{c*0GU$(~kobS$UZvSa~Mdpt{ zPaE*Flj@2R`+D1f9}Peg_r0+R*fYYrT<_*K|3~=e*uEmR2(#D|=ojbJ{sE}m2<#o> zKmW;jHjlUxahr3})d+lh27JB;RBhoLM*BAh*}rIk?d!?dzPrVV0mU$5TXVSNL*3){ zpJe%aJAmdIa=Y@7a?rag{^rl5_y$fQ2Qa(*NWN9JIyn5wH7#$Fu)8yd2>+_!@VBwniD&Cr{aOdkEDMJJs|Hd|iNzVK zPy6b(*O6)d@~eJOz4^CX6Fmp*e|I};xpZ%1cR>DRecav5T*KNqnlIsd#_h*jz^TRF z+rE!~A<$OOn)o%@U9~|%Zj*b+uNuy;YgfwuC+6DR@z&RP^N`;^IRF$)^2hdOo!K`Q zxVf3NWOZ`BZ({rYPT*jszwBlX`J;dfIlzk(z?b{1?-`TgbW43Y7qulo#d==r%?Jj& znS*@k0GUdb1Jyf#SH;YWm+aiA`s~3jdyUogY3*yq1+5jEa^e2*{nyb8CfdJs_1V8; zAO3s1|CZN%4#gh!`$xH)LzwU1>Hg{Ez{XYlIM=;+v4{QswYd);%I6345QK9M^h`uH zRY3*y`3?EG82g^zu%F_vx9rzkLiPMitI#tnt4eKpf4fcZ)3o{jO2q=(G?;d*QtPs> GvHNfHAICZX literal 0 HcmV?d00001 diff --git a/hybrid/html/image/guaduan.png b/hybrid/html/image/guaduan.png new file mode 100644 index 0000000000000000000000000000000000000000..09f5a86b059e4fec8d4d40c795a252dbe7756903 GIT binary patch literal 2087 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 literal 0 HcmV?d00001 diff --git a/hybrid/html/image/video.png b/hybrid/html/image/video.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb7d0123967534b5091f0ec84fb181a7660d83a GIT binary patch literal 3333 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 iC>?QFxby!yJ^mwsoTejE02bD2B! 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 Nij}?PLv!DRe*!SJak&5h literal 0 HcmV?d00001 diff --git a/hybrid/html/image/wallpaper.png b/hybrid/html/image/wallpaper.png new file mode 100644 index 0000000000000000000000000000000000000000..0446a441bcc9c11db6f28bb5a3bab1578141a7ac GIT binary patch literal 24430 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 F008Pye9r&? literal 0 HcmV?d00001 diff --git a/hybrid/html/index.html b/hybrid/html/index.html new file mode 100644 index 0000000..589e1be --- /dev/null +++ b/hybrid/html/index.html @@ -0,0 +1,613 @@ + + + + + + + + + + + +
+
+ + + +
+
+ +
+ {{contact.displayName}} + + {{contact.displayName}} 正在请求与您{{is_video ? '视频' : '语音'}}通话 + 您正对 {{contact.displayName}} 发起{{is_video ? '视频' : '语音'}}通话 + + +
+
+
+ {{setCallTime()}} +
+
+
+ +
{{ voiceStatus ? '关闭' : '开启'}}麦克风
+
+
+ +
挂断
+
+
+ +
接听
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/hybrid/html/js/jsonly.js b/hybrid/html/js/jsonly.js new file mode 100644 index 0000000..4cb5434 --- /dev/null +++ b/hybrid/html/js/jsonly.js @@ -0,0 +1,275 @@ +var at, // The index of the current character + ch, // The current character + escapee = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' + }, + text, + + error = function(m) { + // Call error when something is wrong. + throw { + name: 'SyntaxError', + message: m, + at: at, + text: text + }; + }, + + next = function(c) { + // If a c parameter is provided, verify that it matches the current character. + if (c && c !== ch) { + error("Expected '" + c + "' instead of '" + ch + "'"); + } + + // Get the next character. When there are no more characters, + // return the empty string. + + ch = text.charAt(at); + at += 1; + return ch; + }, + + number = function() { + // Parse a number value. + var number, + string = ''; + + if (ch === '-') { + string = '-'; + next('-'); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (!isFinite(number)) { + error("Bad number"); + } else { + return number; + } + }, + + string = function() { + // Parse a string value. + var hex, + i, + string = '', + uffff; + + // When parsing for string values, we must look for " and \ characters. + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + error("Bad string"); + }, + + white = function() { + + // Skip whitespace. + + while (ch && ch <= ' ') { + next(); + } + }, + + word = function() { + + // true, false, or null. + + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error("Unexpected '" + ch + "'"); + }, + + value, // Place holder for the value function. + + array = function() { + + // Parse an array value. + + var array = []; + + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error("Bad array"); + }, + + object = function() { + + // Parse an object value. + + var key, + object = {}; + + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + if (Object.hasOwnProperty.call(object, key)) { + error('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error("Bad object"); + }; + +value = function() { + + // Parse a JSON value. It could be an object, an array, a string, a number, + // or a word. + + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } +}; + +// Return the json_parse function. It will have access to all of the above +// functions and variables. + +const jsonly = function(source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error("Syntax error"); + } + + // If there is a reviver function, we recursively walk the new structure, + // passing each name/value pair to the reviver function for possible + // transformation, starting with a temporary root object that holds the result + // in an empty key. If there is not a reviver function, we simply return the + // result. + + return typeof reviver === 'function' ? (function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({ + '': result + }, '')) : result; +}; diff --git a/hybrid/html/js/uni.webview.js b/hybrid/html/js/uni.webview.js new file mode 100644 index 0000000..328b91e --- /dev/null +++ b/hybrid/html/js/uni.webview.js @@ -0,0 +1 @@ +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).uni=n()}(this,(function(){"use strict";try{var e={};Object.defineProperty(e,"passive",{get:function(){!0}}),window.addEventListener("test-passive",null,e)}catch(e){}var n=Object.prototype.hasOwnProperty;function i(e,i){return n.call(e,i)}var t=[];function r(){return window.__dcloud_weex_postMessage||window.__dcloud_weex_}var o=function(e,n){var i={options:{timestamp:+new Date},name:e,arg:n};if(r()){if("postMessage"===e){var o={data:[n]};return window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessage(o):window.__dcloud_weex_.postMessage(JSON.stringify(o))}var a={type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}};window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessageToService(a):window.__dcloud_weex_.postMessageToService(JSON.stringify(a))}if(!window.plus)return window.parent.postMessage({type:"WEB_INVOKE_APPSERVICE",data:i,pageId:""},"*");if(0===t.length){var d=plus.webview.currentWebview();if(!d)throw new Error("plus.webview.currentWebview() is undefined");var s=d.parent(),w="";w=s?s.id:d.id,t.push(w)}if(plus.webview.getWebviewById("__uniapp__service"))plus.webview.postMessageToUniNView({type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}},"__uniapp__service");else{var u=JSON.stringify(i);plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat("WEB_INVOKE_APPSERVICE",'",').concat(u,",").concat(JSON.stringify(t),");"))}},a={navigateTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;o("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;o("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;o("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;o("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;o("redirectTo",{url:encodeURI(n)})},getEnv:function(e){r()?e({nvue:!0}):window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};o("postMessage",e.data||{})}},d=/uni-app/i.test(navigator.userAgent),s=/Html5Plus/i.test(navigator.userAgent),w=/complete|loaded|interactive/;var u=window.my&&navigator.userAgent.indexOf(["t","n","e","i","l","C","y","a","p","i","l","A"].reverse().join(""))>-1;var g=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var v=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var c=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var m=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var p=window.qa&&/quickapp/i.test(navigator.userAgent);var f=window.ks&&window.ks.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var l=window.tt&&window.tt.miniProgram&&/Lark|Feishu/i.test(navigator.userAgent);var _=window.jd&&window.jd.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var E=window.xhs&&window.xhs.miniProgram&&/xhsminiapp/i.test(navigator.userAgent);for(var h,P=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},b=[function(e){if(d||s)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&w.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),a},function(e){if(m)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(v)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(u){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(g)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(c)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(p){window.QaJSBridge&&window.QaJSBridge.invoke?setTimeout(e,0):document.addEventListener("QaJSBridgeReady",e);var n=window.qa;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(f)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.ks.miniProgram},function(e){if(l)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(_)return window.JDJSBridgeReady&&window.JDJSBridgeReady.invoke?setTimeout(e,0):document.addEventListener("JDJSBridgeReady",e),window.jd.miniProgram},function(e){if(E)return window.xhs.miniProgram},function(e){return document.addEventListener("DOMContentLoaded",e),a}],y=0;y!!n[e.toLowerCase()]:e=>!!n[e]}const n=t("Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt"),o=t("itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly");function r(e){if(T(e)){const t={};for(let n=0;n{if(e){const n=e.split(i);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}function c(e){let t="";if(A(e))t=e;else if(T(e))for(let n=0;nf(e,t)))}const h=(e,t)=>N(t)?{[`Map(${t.size})`]:[...t.entries()].reduce(((e,[t,n])=>(e[`${t} =>`]=n,e)),{})}:E(t)?{[`Set(${t.size})`]:[...t.values()]}:!O(t)||T(t)||R(t)?t:String(t),m={},g=[],v=()=>{},y=()=>!1,b=/^on[^a-z]/,_=e=>b.test(e),x=e=>e.startsWith("onUpdate:"),S=Object.assign,C=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},k=Object.prototype.hasOwnProperty,w=(e,t)=>k.call(e,t),T=Array.isArray,N=e=>"[object Map]"===B(e),E=e=>"[object Set]"===B(e),$=e=>e instanceof Date,F=e=>"function"==typeof e,A=e=>"string"==typeof e,M=e=>"symbol"==typeof e,O=e=>null!==e&&"object"==typeof e,I=e=>O(e)&&F(e.then)&&F(e.catch),P=Object.prototype.toString,B=e=>P.call(e),R=e=>"[object Object]"===B(e),V=e=>A(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,L=t(",key,ref,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),j=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},U=/-(\w)/g,H=j((e=>e.replace(U,((e,t)=>t?t.toUpperCase():"")))),D=/\B([A-Z])/g,W=j((e=>e.replace(D,"-$1").toLowerCase())),z=j((e=>e.charAt(0).toUpperCase()+e.slice(1))),K=j((e=>e?`on${z(e)}`:"")),G=(e,t)=>e!==t&&(e==e||t==t),q=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Z=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Q=new WeakMap,X=[];let Y;const ee=Symbol(""),te=Symbol("");function ne(e,t=m){(function(e){return e&&!0===e._isEffect})(e)&&(e=e.raw);const n=function(e,t){const n=function(){if(!n.active)return e();if(!X.includes(n)){se(n);try{return le.push(ie),ie=!0,X.push(n),Y=n,e()}finally{X.pop(),ae(),Y=X[X.length-1]}}};return n.id=re++,n.allowRecurse=!!t.allowRecurse,n._isEffect=!0,n.active=!0,n.raw=e,n.deps=[],n.options=t,n}(e,t);return t.lazy||n(),n}function oe(e){e.active&&(se(e),e.options.onStop&&e.options.onStop(),e.active=!1)}let re=0;function se(e){const{deps:t}=e;if(t.length){for(let n=0;n{e&&e.forEach((e=>{(e!==Y||e.allowRecurse)&&l.add(e)}))};if("clear"===t)i.forEach(c);else if("length"===n&&T(e))i.forEach(((e,t)=>{("length"===t||t>=o)&&c(e)}));else switch(void 0!==n&&c(i.get(n)),t){case"add":T(e)?V(n)&&c(i.get("length")):(c(i.get(ee)),N(e)&&c(i.get(te)));break;case"delete":T(e)||(c(i.get(ee)),N(e)&&c(i.get(te)));break;case"set":N(e)&&c(i.get(ee))}l.forEach((e=>{e.options.scheduler?e.options.scheduler(e):e()}))}const fe=t("__proto__,__v_isRef,__isVue"),de=new Set(Object.getOwnPropertyNames(Symbol).map((e=>Symbol[e])).filter(M)),he=_e(),me=_e(!1,!0),ge=_e(!0),ve=_e(!0,!0),ye=be();function be(){const e={};return["includes","indexOf","lastIndexOf"].forEach((t=>{e[t]=function(...e){const n=ct(this);for(let t=0,r=this.length;t{e[t]=function(...e){ce();const n=ct(this)[t].apply(this,e);return ae(),n}})),e}function _e(e=!1,t=!1){return function(n,o,r){if("__v_isReactive"===o)return!e;if("__v_isReadonly"===o)return e;if("__v_raw"===o&&r===(e?t?Ye:Xe:t?Qe:Ze).get(n))return n;const s=T(n);if(!e&&s&&w(ye,o))return Reflect.get(ye,o,r);const i=Reflect.get(n,o,r);if(M(o)?de.has(o):fe(o))return i;if(e||ue(n,0,o),t)return i;if(pt(i)){return!s||!V(o)?i.value:i}return O(i)?e?ot(i):tt(i):i}}function xe(e=!1){return function(t,n,o,r){let s=t[n];if(!e&&(o=ct(o),s=ct(s),!T(t)&&pt(s)&&!pt(o)))return s.value=o,!0;const i=T(t)&&V(n)?Number(n)!0,deleteProperty:(e,t)=>!0},ke=S({},Se,{get:me,set:xe(!0)}),we=S({},Ce,{get:ve}),Te=e=>O(e)?tt(e):e,Ne=e=>O(e)?ot(e):e,Ee=e=>e,$e=e=>Reflect.getPrototypeOf(e);function Fe(e,t,n=!1,o=!1){const r=ct(e=e.__v_raw),s=ct(t);t!==s&&!n&&ue(r,0,t),!n&&ue(r,0,s);const{has:i}=$e(r),l=o?Ee:n?Ne:Te;return i.call(r,t)?l(e.get(t)):i.call(r,s)?l(e.get(s)):void(e!==r&&e.get(t))}function Ae(e,t=!1){const n=this.__v_raw,o=ct(n),r=ct(e);return e!==r&&!t&&ue(o,0,e),!t&&ue(o,0,r),e===r?n.has(e):n.has(e)||n.has(r)}function Me(e,t=!1){return e=e.__v_raw,!t&&ue(ct(e),0,ee),Reflect.get(e,"size",e)}function Oe(e){e=ct(e);const t=ct(this);return $e(t).has.call(t,e)||(t.add(e),pe(t,"add",e,e)),this}function Ie(e,t){t=ct(t);const n=ct(this),{has:o,get:r}=$e(n);let s=o.call(n,e);s||(e=ct(e),s=o.call(n,e));const i=r.call(n,e);return n.set(e,t),s?G(t,i)&&pe(n,"set",e,t):pe(n,"add",e,t),this}function Pe(e){const t=ct(this),{has:n,get:o}=$e(t);let r=n.call(t,e);r||(e=ct(e),r=n.call(t,e)),o&&o.call(t,e);const s=t.delete(e);return r&&pe(t,"delete",e,void 0),s}function Be(){const e=ct(this),t=0!==e.size,n=e.clear();return t&&pe(e,"clear",void 0,void 0),n}function Re(e,t){return function(n,o){const r=this,s=r.__v_raw,i=ct(s),l=t?Ee:e?Ne:Te;return!e&&ue(i,0,ee),s.forEach(((e,t)=>n.call(o,l(e),l(t),r)))}}function Ve(e,t,n){return function(...o){const r=this.__v_raw,s=ct(r),i=N(s),l="entries"===e||e===Symbol.iterator&&i,c="keys"===e&&i,a=r[e](...o),u=n?Ee:t?Ne:Te;return!t&&ue(s,0,c?te:ee),{next(){const{value:e,done:t}=a.next();return t?{value:e,done:t}:{value:l?[u(e[0]),u(e[1])]:u(e),done:t}},[Symbol.iterator](){return this}}}}function Le(e){return function(...t){return"delete"!==e&&this}}function je(){const e={get(e){return Fe(this,e)},get size(){return Me(this)},has:Ae,add:Oe,set:Ie,delete:Pe,clear:Be,forEach:Re(!1,!1)},t={get(e){return Fe(this,e,!1,!0)},get size(){return Me(this)},has:Ae,add:Oe,set:Ie,delete:Pe,clear:Be,forEach:Re(!1,!0)},n={get(e){return Fe(this,e,!0)},get size(){return Me(this,!0)},has(e){return Ae.call(this,e,!0)},add:Le("add"),set:Le("set"),delete:Le("delete"),clear:Le("clear"),forEach:Re(!0,!1)},o={get(e){return Fe(this,e,!0,!0)},get size(){return Me(this,!0)},has(e){return Ae.call(this,e,!0)},add:Le("add"),set:Le("set"),delete:Le("delete"),clear:Le("clear"),forEach:Re(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach((r=>{e[r]=Ve(r,!1,!1),n[r]=Ve(r,!0,!1),t[r]=Ve(r,!1,!0),o[r]=Ve(r,!0,!0)})),[e,n,t,o]}const[Ue,He,De,We]=je();function ze(e,t){const n=t?e?We:De:e?He:Ue;return(t,o,r)=>"__v_isReactive"===o?!e:"__v_isReadonly"===o?e:"__v_raw"===o?t:Reflect.get(w(n,o)&&o in t?n:t,o,r)}const Ke={get:ze(!1,!1)},Ge={get:ze(!1,!0)},qe={get:ze(!0,!1)},Je={get:ze(!0,!0)},Ze=new WeakMap,Qe=new WeakMap,Xe=new WeakMap,Ye=new WeakMap;function et(e){return e.__v_skip||!Object.isExtensible(e)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}((e=>B(e).slice(8,-1))(e))}function tt(e){return e&&e.__v_isReadonly?e:rt(e,!1,Se,Ke,Ze)}function nt(e){return rt(e,!1,ke,Ge,Qe)}function ot(e){return rt(e,!0,Ce,qe,Xe)}function rt(e,t,n,o,r){if(!O(e))return e;if(e.__v_raw&&(!t||!e.__v_isReactive))return e;const s=r.get(e);if(s)return s;const i=et(e);if(0===i)return e;const l=new Proxy(e,2===i?o:n);return r.set(e,l),l}function st(e){return it(e)?st(e.__v_raw):!(!e||!e.__v_isReactive)}function it(e){return!(!e||!e.__v_isReadonly)}function lt(e){return st(e)||it(e)}function ct(e){return e&&ct(e.__v_raw)||e}function at(e){return J(e,"__v_skip",!0),e}const ut=e=>O(e)?tt(e):e;function pt(e){return Boolean(e&&!0===e.__v_isRef)}function ft(e){return ht(e)}class dt{constructor(e,t=!1){this._shallow=t,this.__v_isRef=!0,this._rawValue=t?e:ct(e),this._value=t?e:ut(e)}get value(){return ue(ct(this),0,"value"),this._value}set value(e){e=this._shallow?e:ct(e),G(e,this._rawValue)&&(this._rawValue=e,this._value=this._shallow?e:ut(e),pe(ct(this),"set","value",e))}}function ht(e,t=!1){return pt(e)?e:new dt(e,t)}function mt(e){return pt(e)?e.value:e}const gt={get:(e,t,n)=>mt(Reflect.get(e,t,n)),set:(e,t,n,o)=>{const r=e[t];return pt(r)&&!pt(n)?(r.value=n,!0):Reflect.set(e,t,n,o)}};function vt(e){return st(e)?e:new Proxy(e,gt)}class yt{constructor(e){this.__v_isRef=!0;const{get:t,set:n}=e((()=>ue(this,0,"value")),(()=>pe(this,"set","value")));this._get=t,this._set=n}get value(){return this._get()}set value(e){this._set(e)}}class bt{constructor(e,t){this._object=e,this._key=t,this.__v_isRef=!0}get value(){return this._object[this._key]}set value(e){this._object[this._key]=e}}function _t(e,t){return pt(e[t])?e[t]:new bt(e,t)}class xt{constructor(e,t,n){this._setter=t,this._dirty=!0,this.__v_isRef=!0,this.effect=ne(e,{lazy:!0,scheduler:()=>{this._dirty||(this._dirty=!0,pe(ct(this),"set","value"))}}),this.__v_isReadonly=n}get value(){const e=ct(this);return e._dirty&&(e._value=this.effect(),e._dirty=!1),ue(e,0,"value"),e._value}set value(e){this._setter(e)}}const St=[];function Ct(e,...t){ce();const n=St.length?St[St.length-1].component:null,o=n&&n.appContext.config.warnHandler,r=function(){let e=St[St.length-1];if(!e)return[];const t=[];for(;e;){const n=t[0];n&&n.vnode===e?n.recurseCount++:t.push({vnode:e,recurseCount:0});const o=e.component&&e.component.parent;e=o&&o.vnode}return t}();if(o)Tt(o,n,11,[e+t.join(""),n&&n.proxy,r.map((({vnode:e})=>`at <${Wr(n,e.type)}>`)).join("\n"),r]);else{const n=[`[Vue warn]: ${e}`,...t];r.length&&n.push("\n",...function(e){const t=[];return e.forEach(((e,n)=>{t.push(...0===n?[]:["\n"],...function({vnode:e,recurseCount:t}){const n=t>0?`... (${t} recursive calls)`:"",o=` at <${Wr(e.component,e.type,!!e.component&&null==e.component.parent)}`,r=">"+n;return e.props?[o,...kt(e.props),r]:[o+r]}(e))})),t}(r)),console.warn(...n)}ae()}function kt(e){const t=[],n=Object.keys(e);return n.slice(0,3).forEach((n=>{t.push(...wt(n,e[n]))})),n.length>3&&t.push(" ..."),t}function wt(e,t,n){return A(t)?(t=JSON.stringify(t),n?t:[`${e}=${t}`]):"number"==typeof t||"boolean"==typeof t||null==t?n?t:[`${e}=${t}`]:pt(t)?(t=wt(e,ct(t.value),!0),n?t:[`${e}=Ref<`,t,">"]):F(t)?[`${e}=fn${t.name?`<${t.name}>`:""}`]:(t=ct(t),n?t:[`${e}=`,t])}function Tt(e,t,n,o){let r;try{r=o?e(...o):e()}catch(s){Et(s,t,n)}return r}function Nt(e,t,n,o){if(F(e)){const r=Tt(e,t,n,o);return r&&I(r)&&r.catch((e=>{Et(e,t,n)})),r}const r=[];for(let s=0;s>>1;Jt(At[e])-1?At.splice(t,0,e):At.push(e),Wt()}}function Wt(){$t||Ft||(Ft=!0,jt=Lt.then(Zt))}function zt(e,t,n,o){T(e)?n.push(...e):t&&t.includes(e,e.allowRecurse?o+1:o)||n.push(e),Wt()}function Kt(e){zt(e,Rt,Bt,Vt)}function Gt(e,t=null){if(Ot.length){for(Ut=t,It=[...new Set(Ot)],Ot.length=0,Pt=0;PtJt(e)-Jt(t))),Vt=0;Vtnull==e.id?1/0:e.id;function Zt(e){Ft=!1,$t=!0,Gt(e),At.sort(((e,t)=>Jt(e)-Jt(t)));try{for(Mt=0;Mte.trim())):t&&(r=n.map(Z))}let l,c=o[l=K(t)]||o[l=K(H(t))];!c&&s&&(c=o[l=K(W(t))]),c&&Nt(c,e,6,r);const a=o[l+"Once"];if(a){if(e.emitted){if(e.emitted[l])return}else e.emitted={};e.emitted[l]=!0,Nt(a,e,6,r)}}function Xt(e,t,n=!1){const o=t.emitsCache,r=o.get(e);if(void 0!==r)return r;const s=e.emits;let i={},l=!1;if(!F(e)){const o=e=>{const n=Xt(e,t,!0);n&&(l=!0,S(i,n))};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}return s||l?(T(s)?s.forEach((e=>i[e]=null)):S(i,s),o.set(e,i),i):(o.set(e,null),null)}function Yt(e,t){return!(!e||!_(t))&&(t=t.slice(2).replace(/Once$/,""),w(e,t[0].toLowerCase()+t.slice(1))||w(e,W(t))||w(e,t))}let en=null,tn=null;function nn(e){const t=en;return en=e,tn=e&&e.type.__scopeId||null,t}function on(e,t=en,n){if(!t)return e;if(e._n)return e;const o=(...n)=>{o._d&&ar(-1);const r=nn(t),s=e(...n);return nn(r),o._d&&ar(1),s};return o._n=!0,o._c=!0,o._d=!0,o}function rn(e){const{type:t,vnode:n,proxy:o,withProxy:r,props:s,propsOptions:[i],slots:l,attrs:c,emit:a,render:u,renderCache:p,data:f,setupState:d,ctx:h,inheritAttrs:m}=e;let g;const v=nn(e);try{let e;if(4&n.shapeFlag){const t=r||o;g=br(u.call(t,t,p,s,d,f,h)),e=c}else{const n=t;0,g=br(n(s,n.length>1?{attrs:c,slots:l,emit:a}:null)),e=t.props?c:ln(c)}let v=g;if(e&&!1!==m){const t=Object.keys(e),{shapeFlag:n}=v;t.length&&(1&n||6&n)&&(i&&t.some(x)&&(e=cn(e,i)),v=vr(v,e))}0,n.dirs&&(v.dirs=v.dirs?v.dirs.concat(n.dirs):n.dirs),n.transition&&(v.transition=n.transition),g=v}catch(y){rr.length=0,Et(y,e,1),g=gr(nr)}return nn(v),g}function sn(e){let t;for(let n=0;n{let t;for(const n in e)("class"===n||"style"===n||_(n))&&((t||(t={}))[n]=e[n]);return t},cn=(e,t)=>{const n={};for(const o in e)x(o)&&o.slice(9)in t||(n[o]=e[o]);return n};function an(e,t,n){const o=Object.keys(t);if(o.length!==Object.keys(e).length)return!0;for(let r=0;r0?(fn(e,"onPending"),fn(e,"onFallback"),a(null,e.ssFallback,t,n,o,null,s,i),gn(f,e.ssFallback)):f.resolve()}(t,n,o,r,s,i,l,c,a):function(e,t,n,o,r,s,i,l,{p:c,um:a,o:{createElement:u}}){const p=t.suspense=e.suspense;p.vnode=t,t.el=e.el;const f=t.ssContent,d=t.ssFallback,{activeBranch:h,pendingBranch:m,isInFallback:g,isHydrating:v}=p;if(m)p.pendingBranch=f,fr(f,m)?(c(m,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0?p.resolve():g&&(c(h,d,n,o,r,null,s,i,l),gn(p,d))):(p.pendingId++,v?(p.isHydrating=!1,p.activeBranch=m):a(m,r,p),p.deps=0,p.effects.length=0,p.hiddenContainer=u("div"),g?(c(null,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0?p.resolve():(c(h,d,n,o,r,null,s,i,l),gn(p,d))):h&&fr(f,h)?(c(h,f,n,o,r,p,s,i,l),p.resolve(!0)):(c(null,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0&&p.resolve()));else if(h&&fr(f,h))c(h,f,n,o,r,p,s,i,l),gn(p,f);else if(fn(t,"onPending"),p.pendingBranch=f,p.pendingId++,c(null,f,p.hiddenContainer,null,r,p,s,i,l),p.deps<=0)p.resolve();else{const{timeout:e,pendingId:t}=p;e>0?setTimeout((()=>{p.pendingId===t&&p.fallback(d)}),e):0===e&&p.fallback(d)}}(e,t,n,o,r,i,l,c,a)},hydrate:function(e,t,n,o,r,s,i,l,c){const a=t.suspense=dn(t,o,n,e.parentNode,document.createElement("div"),null,r,s,i,l,!0),u=c(e,a.pendingBranch=t.ssContent,n,a,s,i);0===a.deps&&a.resolve();return u},create:dn,normalize:function(e){const{shapeFlag:t,children:n}=e,o=32&t;e.ssContent=hn(o?n.default:n),e.ssFallback=o?hn(n.fallback):gr(Comment)}};function fn(e,t){const n=e.props&&e.props[t];F(n)&&n()}function dn(e,t,n,o,r,s,i,l,c,a,u=!1){const{p:p,m:f,um:d,n:h,o:{parentNode:m,remove:g}}=a,v=Z(e.props&&e.props.timeout),y={vnode:e,parent:t,parentComponent:n,isSVG:i,container:o,hiddenContainer:r,anchor:s,deps:0,pendingId:0,timeout:"number"==typeof v?v:-1,activeBranch:null,pendingBranch:null,isInFallback:!0,isHydrating:u,isUnmounted:!1,effects:[],resolve(e=!1){const{vnode:t,activeBranch:n,pendingBranch:o,pendingId:r,effects:s,parentComponent:i,container:l}=y;if(y.isHydrating)y.isHydrating=!1;else if(!e){const e=n&&o.transition&&"out-in"===o.transition.mode;e&&(n.transition.afterLeave=()=>{r===y.pendingId&&f(o,l,t,0)});let{anchor:t}=y;n&&(t=h(n),d(n,i,y,!0)),e||f(o,l,t,0)}gn(y,o),y.pendingBranch=null,y.isInFallback=!1;let c=y.parent,a=!1;for(;c;){if(c.pendingBranch){c.effects.push(...s),a=!0;break}c=c.parent}a||Kt(s),y.effects=[],fn(t,"onResolve")},fallback(e){if(!y.pendingBranch)return;const{vnode:t,activeBranch:n,parentComponent:o,container:r,isSVG:s}=y;fn(t,"onFallback");const i=h(n),a=()=>{y.isInFallback&&(p(null,e,r,i,o,null,s,l,c),gn(y,e))},u=e.transition&&"out-in"===e.transition.mode;u&&(n.transition.afterLeave=a),y.isInFallback=!0,d(n,o,null,!0),u||a()},move(e,t,n){y.activeBranch&&f(y.activeBranch,e,t,n),y.container=e},next:()=>y.activeBranch&&h(y.activeBranch),registerDep(e,t){const n=!!y.pendingBranch;n&&y.deps++;const o=e.vnode.el;e.asyncDep.catch((t=>{Et(t,e,0)})).then((r=>{if(e.isUnmounted||y.isUnmounted||y.pendingId!==e.suspenseId)return;e.asyncResolved=!0;const{vnode:s}=e;Br(e,r),o&&(s.el=o);const l=!o&&e.subTree.el;t(e,s,m(o||e.subTree.el),o?null:h(e.subTree),y,i,c),l&&g(l),un(e,s.el),n&&0==--y.deps&&y.resolve()}))},unmount(e,t){y.isUnmounted=!0,y.activeBranch&&d(y.activeBranch,n,e,t),y.pendingBranch&&d(y.pendingBranch,n,e,t)}};return y}function hn(e){let t;if(F(e)){const n=e._c;n&&(e._d=!1,ir()),e=e(),n&&(e._d=!0,t=sr,lr())}if(T(e)){const t=sn(e);e=t}return e=br(e),t&&(e.dynamicChildren=t.filter((t=>t!==e))),e}function mn(e,t){t&&t.pendingBranch?T(e)?t.effects.push(...e):t.effects.push(e):Kt(e)}function gn(e,t){e.activeBranch=t;const{vnode:n,parentComponent:o}=e,r=n.el=t.el;o&&o.subTree===n&&(o.vnode.el=r,un(o,r))}function vn(e,t){if(Fr){let n=Fr.provides;const o=Fr.parent&&Fr.parent.provides;o===n&&(n=Fr.provides=Object.create(o)),n[e]=t}else;}function yn(e,t,n=!1){const o=Fr||en;if(o){const r=null==o.parent?o.vnode.appContext&&o.vnode.appContext.provides:o.parent.provides;if(r&&e in r)return r[e];if(arguments.length>1)return n&&F(t)?t.call(o.proxy):t}}function bn(e,t){return Sn(e,null,t)}const _n={};function xn(e,t,n){return Sn(e,t,n)}function Sn(e,t,{immediate:n,deep:o,flush:r,onTrack:s,onTrigger:i}=m,l=Fr){let c,a,u=!1,p=!1;if(pt(e)?(c=()=>e.value,u=!!e._shallow):st(e)?(c=()=>e,o=!0):T(e)?(p=!0,u=e.some(st),c=()=>e.map((e=>pt(e)?e.value:st(e)?wn(e):F(e)?Tt(e,l,2):void 0))):c=F(e)?t?()=>Tt(e,l,2):()=>{if(!l||!l.isUnmounted)return a&&a(),Nt(e,l,3,[f])}:v,t&&o){const e=c;c=()=>wn(e())}let f=e=>{a=y.options.onStop=()=>{Tt(e,l,4)}},d=p?[]:_n;const h=()=>{if(y.active)if(t){const e=y();(o||u||(p?e.some(((e,t)=>G(e,d[t]))):G(e,d)))&&(a&&a(),Nt(t,l,3,[e,d===_n?void 0:d,f]),d=e)}else y()};let g;h.allowRecurse=!!t,g="sync"===r?h:"post"===r?()=>Vo(h,l&&l.suspense):()=>{!l||l.isMounted?function(e){zt(e,It,Ot,Pt)}(h):h()};const y=ne(c,{lazy:!0,onTrack:s,onTrigger:i,scheduler:g});return Ur(y,l),t?n?h():d=y():"post"===r?Vo(y,l&&l.suspense):y(),()=>{oe(y),l&&C(l.effects,y)}}function Cn(e,t,n){const o=this.proxy,r=A(e)?e.includes(".")?kn(o,e):()=>o[e]:e.bind(o,o);let s;return F(t)?s=t:(s=t.handler,n=t),Sn(r,s.bind(o),n,this)}function kn(e,t){const n=t.split(".");return()=>{let t=e;for(let e=0;e{wn(e,t)}));else if(R(e))for(const n in e)wn(e[n],t);return e}function Tn(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return Zn((()=>{e.isMounted=!0})),Yn((()=>{e.isUnmounting=!0})),e}const Nn=[Function,Array],En={name:"BaseTransition",props:{mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Nn,onEnter:Nn,onAfterEnter:Nn,onEnterCancelled:Nn,onBeforeLeave:Nn,onLeave:Nn,onAfterLeave:Nn,onLeaveCancelled:Nn,onBeforeAppear:Nn,onAppear:Nn,onAfterAppear:Nn,onAppearCancelled:Nn},setup(e,{slots:t}){const n=Ar(),o=Tn();let r;return()=>{const s=t.default&&In(t.default(),!0);if(!s||!s.length)return;const i=ct(e),{mode:l}=i,c=s[0];if(o.isLeaving)return An(c);const a=Mn(c);if(!a)return An(c);const u=Fn(a,i,o,n);On(a,u);const p=n.subTree,f=p&&Mn(p);let d=!1;const{getTransitionKey:h}=a.type;if(h){const e=h();void 0===r?r=e:e!==r&&(r=e,d=!0)}if(f&&f.type!==nr&&(!fr(a,f)||d)){const e=Fn(f,i,o,n);if(On(f,e),"out-in"===l)return o.isLeaving=!0,e.afterLeave=()=>{o.isLeaving=!1,n.update()},An(c);"in-out"===l&&a.type!==nr&&(e.delayLeave=(e,t,n)=>{$n(o,f)[String(f.key)]=f,e._leaveCb=()=>{t(),e._leaveCb=void 0,delete u.delayedLeave},u.delayedLeave=n})}return c}}};function $n(e,t){const{leavingVNodes:n}=e;let o=n.get(t.type);return o||(o=Object.create(null),n.set(t.type,o)),o}function Fn(e,t,n,o){const{appear:r,mode:s,persisted:i=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:a,onEnterCancelled:u,onBeforeLeave:p,onLeave:f,onAfterLeave:d,onLeaveCancelled:h,onBeforeAppear:m,onAppear:g,onAfterAppear:v,onAppearCancelled:y}=t,b=String(e.key),_=$n(n,e),x=(e,t)=>{e&&Nt(e,o,9,t)},S={mode:s,persisted:i,beforeEnter(t){let o=l;if(!n.isMounted){if(!r)return;o=m||l}t._leaveCb&&t._leaveCb(!0);const s=_[b];s&&fr(e,s)&&s.el._leaveCb&&s.el._leaveCb(),x(o,[t])},enter(e){let t=c,o=a,s=u;if(!n.isMounted){if(!r)return;t=g||c,o=v||a,s=y||u}let i=!1;const l=e._enterCb=t=>{i||(i=!0,x(t?s:o,[e]),S.delayedLeave&&S.delayedLeave(),e._enterCb=void 0)};t?(t(e,l),t.length<=1&&l()):l()},leave(t,o){const r=String(e.key);if(t._enterCb&&t._enterCb(!0),n.isUnmounting)return o();x(p,[t]);let s=!1;const i=t._leaveCb=n=>{s||(s=!0,o(),x(n?h:d,[t]),t._leaveCb=void 0,_[r]===e&&delete _[r])};_[r]=e,f?(f(t,i),f.length<=1&&i()):i()},clone:e=>Fn(e,t,n,o)};return S}function An(e){if(Vn(e))return(e=vr(e)).children=null,e}function Mn(e){return Vn(e)?e.children?e.children[0]:void 0:e}function On(e,t){6&e.shapeFlag&&e.component?On(e.component.subTree,t):128&e.shapeFlag?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function In(e,t=!1){let n=[],o=0;for(let r=0;r1)for(let r=0;r!!e.type.__asyncLoader;function Rn(e,{vnode:{ref:t,props:n,children:o}}){const r=gr(e,n,o);return r.ref=t,r}const Vn=e=>e.type.__isKeepAlive,Ln={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=Ar(),o=n.ctx;if(!o.renderer)return t.default;const r=new Map,s=new Set;let i=null;const l=n.suspense,{renderer:{p:c,m:a,um:u,o:{createElement:p}}}=o,f=p("div");function d(e){zn(e),u(e,n,l)}function h(e){r.forEach(((t,n)=>{const o=Dr(t.type);!o||e&&e(o)||m(n)}))}function m(e){const t=r.get(e);i&&t.type===i.type?i&&zn(i):d(t),r.delete(e),s.delete(e)}o.activate=(e,t,n,o,r)=>{const s=e.component;a(e,t,n,0,l),c(s.vnode,e,t,n,s,l,o,e.slotScopeIds,r),Vo((()=>{s.isDeactivated=!1,s.a&&q(s.a);const t=e.props&&e.props.onVnodeMounted;t&&Do(t,s.parent,e)}),l)},o.deactivate=e=>{const t=e.component;a(e,f,null,1,l),Vo((()=>{t.da&&q(t.da);const n=e.props&&e.props.onVnodeUnmounted;n&&Do(n,t.parent,e),t.isDeactivated=!0}),l)},xn((()=>[e.include,e.exclude]),(([e,t])=>{e&&h((t=>jn(e,t))),t&&h((e=>!jn(t,e)))}),{flush:"post",deep:!0});let g=null;const v=()=>{null!=g&&r.set(g,Kn(n.subTree))};return Zn(v),Xn(v),Yn((()=>{r.forEach((e=>{const{subTree:t,suspense:o}=n,r=Kn(t);if(e.type!==r.type)d(e);else{zn(r);const e=r.component.da;e&&Vo(e,o)}}))})),()=>{if(g=null,!t.default)return null;const n=t.default(),o=n[0];if(n.length>1)return i=null,n;if(!(pr(o)&&(4&o.shapeFlag||128&o.shapeFlag)))return i=null,o;let l=Kn(o);const c=l.type,a=Dr(Bn(l)?l.type.__asyncResolved||{}:c),{include:u,exclude:p,max:f}=e;if(u&&(!a||!jn(u,a))||p&&a&&jn(p,a))return i=l,o;const d=null==l.key?c:l.key,h=r.get(d);return l.el&&(l=vr(l),128&o.shapeFlag&&(o.ssContent=l)),g=d,h?(l.el=h.el,l.component=h.component,l.transition&&On(l,l.transition),l.shapeFlag|=512,s.delete(d),s.add(d)):(s.add(d),f&&s.size>parseInt(f,10)&&m(s.values().next().value)),l.shapeFlag|=256,i=l,o}}};function jn(e,t){return T(e)?e.some((e=>jn(e,t))):A(e)?e.split(",").indexOf(t)>-1:!!e.test&&e.test(t)}function Un(e,t){Dn(e,"a",t)}function Hn(e,t){Dn(e,"da",t)}function Dn(e,t,n=Fr){const o=e.__wdc||(e.__wdc=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}e()});if(Gn(t,o,n),n){let e=n.parent;for(;e&&e.parent;)Vn(e.parent.vnode)&&Wn(o,t,n,e),e=e.parent}}function Wn(e,t,n,o){const r=Gn(t,e,o,!0);eo((()=>{C(o[t],r)}),n)}function zn(e){let t=e.shapeFlag;256&t&&(t-=256),512&t&&(t-=512),e.shapeFlag=t}function Kn(e){return 128&e.shapeFlag?e.ssContent:e}function Gn(e,t,n=Fr,o=!1){if(n){const r=n[e]||(n[e]=[]),s=t.__weh||(t.__weh=(...o)=>{if(n.isUnmounted)return;ce(),Mr(n);const r=Nt(t,n,e,o);return Mr(null),ae(),r});return o?r.unshift(s):r.push(s),s}}const qn=e=>(t,n=Fr)=>(!Pr||"sp"===e)&&Gn(e,t,n),Jn=qn("bm"),Zn=qn("m"),Qn=qn("bu"),Xn=qn("u"),Yn=qn("bum"),eo=qn("um"),to=qn("sp"),no=qn("rtg"),oo=qn("rtc");function ro(e,t=Fr){Gn("ec",e,t)}let so=!0;function io(e){const t=ao(e),n=e.proxy,o=e.ctx;so=!1,t.beforeCreate&&lo(t.beforeCreate,e,"bc");const{data:r,computed:s,methods:i,watch:l,provide:c,inject:a,created:u,beforeMount:p,mounted:f,beforeUpdate:d,updated:h,activated:m,deactivated:g,beforeUnmount:y,unmounted:b,render:_,renderTracked:x,renderTriggered:S,errorCaptured:C,serverPrefetch:k,expose:w,inheritAttrs:N,components:E,directives:$}=t;if(a&&function(e,t,n=v){T(e)&&(e=ho(e));for(const o in e){const n=e[o];t[o]=O(n)?"default"in n?yn(n.from||o,n.default,!0):yn(n.from||o):yn(n)}}(a,o,null),i)for(const v in i){const e=i[v];F(e)&&(o[v]=e.bind(n))}if(r){const t=r.call(n,n);O(t)&&(e.data=tt(t))}if(so=!0,s)for(const T in s){const e=s[T],t=zr({get:F(e)?e.bind(n,n):F(e.get)?e.get.bind(n,n):v,set:!F(e)&&F(e.set)?e.set.bind(n):v});Object.defineProperty(o,T,{enumerable:!0,configurable:!0,get:()=>t.value,set:e=>t.value=e})}if(l)for(const v in l)co(l[v],o,n,v);if(c){const e=F(c)?c.call(n):c;Reflect.ownKeys(e).forEach((t=>{vn(t,e[t])}))}function A(e,t){T(t)?t.forEach((t=>e(t.bind(n)))):t&&e(t.bind(n))}if(u&&lo(u,e,"c"),A(Jn,p),A(Zn,f),A(Qn,d),A(Xn,h),A(Un,m),A(Hn,g),A(ro,C),A(oo,x),A(no,S),A(Yn,y),A(eo,b),A(to,k),T(w))if(w.length){const t=e.exposed||(e.exposed={});w.forEach((e=>{Object.defineProperty(t,e,{get:()=>n[e],set:t=>n[e]=t})}))}else e.exposed||(e.exposed={});_&&e.render===v&&(e.render=_),null!=N&&(e.inheritAttrs=N),E&&(e.components=E),$&&(e.directives=$)}function lo(e,t,n){Nt(T(e)?e.map((e=>e.bind(t.proxy))):e.bind(t.proxy),t,n)}function co(e,t,n,o){const r=o.includes(".")?kn(n,o):()=>n[o];if(A(e)){const n=t[e];F(n)&&xn(r,n)}else if(F(e))xn(r,e.bind(n));else if(O(e))if(T(e))e.forEach((e=>co(e,t,n,o)));else{const o=F(e.handler)?e.handler.bind(n):t[e.handler];F(o)&&xn(r,o,e)}}function ao(e){const t=e.type,{mixins:n,extends:o}=t,{mixins:r,optionsCache:s,config:{optionMergeStrategies:i}}=e.appContext,l=s.get(t);let c;return l?c=l:r.length||n||o?(c={},r.length&&r.forEach((e=>uo(c,e,i,!0))),uo(c,t,i)):c=t,s.set(t,c),c}function uo(e,t,n,o=!1){const{mixins:r,extends:s}=t;s&&uo(e,s,n,!0),r&&r.forEach((t=>uo(e,t,n,!0)));for(const i in t)if(o&&"expose"===i);else{const o=po[i]||n&&n[i];e[i]=o?o(e[i],t[i]):t[i]}return e}const po={data:fo,props:go,emits:go,methods:go,computed:go,beforeCreate:mo,created:mo,beforeMount:mo,mounted:mo,beforeUpdate:mo,updated:mo,beforeDestroy:mo,destroyed:mo,activated:mo,deactivated:mo,errorCaptured:mo,serverPrefetch:mo,components:go,directives:go,watch:function(e,t){if(!e)return t;if(!t)return e;const n=S(Object.create(null),e);for(const o in t)n[o]=mo(e[o],t[o]);return n},provide:fo,inject:function(e,t){return go(ho(e),ho(t))}};function fo(e,t){return t?e?function(){return S(F(e)?e.call(this,this):e,F(t)?t.call(this,this):t)}:t:e}function ho(e){if(T(e)){const t={};for(let n=0;n{c=!0;const[n,o]=bo(e,t,!0);S(i,n),o&&l.push(...o)};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}if(!s&&!c)return o.set(e,g),g;if(T(s))for(let u=0;u-1,n[1]=o<0||t-1||w(n,"default"))&&l.push(e)}}}const a=[i,l];return o.set(e,a),a}function _o(e){return"$"!==e[0]}function xo(e){const t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:""}function So(e,t){return xo(e)===xo(t)}function Co(e,t){return T(t)?t.findIndex((t=>So(t,e))):F(t)&&So(t,e)?0:-1}const ko=e=>"_"===e[0]||"$stable"===e,wo=e=>T(e)?e.map(br):[br(e)],To=(e,t,n)=>{const o=on((e=>wo(t(e))),n);return o._c=!1,o},No=(e,t,n)=>{const o=e._ctx;for(const r in e){if(ko(r))continue;const n=e[r];if(F(n))t[r]=To(0,n,o);else if(null!=n){const e=wo(n);t[r]=()=>e}}},Eo=(e,t)=>{const n=wo(t);e.slots.default=()=>n};function $o(e,t,n,o){const r=e.dirs,s=t&&t.dirs;for(let i=0;i(s.has(e)||(e&&F(e.install)?(s.add(e),e.install(l,...t)):F(e)&&(s.add(e),e(l,...t))),l),mixin:e=>(r.mixins.includes(e)||r.mixins.push(e),l),component:(e,t)=>t?(r.components[e]=t,l):r.components[e],directive:(e,t)=>t?(r.directives[e]=t,l):r.directives[e],mount(s,c,a){if(!i){const u=gr(n,o);return u.appContext=r,c&&t?t(u,s):e(u,s,a),i=!0,l._container=s,s.__vue_app__=l,u.component.proxy}},unmount(){i&&(e(null,l._container),delete l._container.__vue_app__)},provide:(e,t)=>(r.provides[e]=t,l)};return l}}let Oo=!1;const Io=e=>/svg/.test(e.namespaceURI)&&"foreignObject"!==e.tagName,Po=e=>8===e.nodeType;function Bo(e){const{mt:t,p:n,o:{patchProp:o,nextSibling:r,parentNode:s,remove:i,insert:l,createComment:c}}=e,a=(n,o,i,l,c,m=!1)=>{const g=Po(n)&&"["===n.data,v=()=>d(n,o,i,l,c,g),{type:y,ref:b,shapeFlag:_}=o,x=n.nodeType;o.el=n;let S=null;switch(y){case tr:3!==x?S=v():(n.data!==o.children&&(Oo=!0,n.data=o.children),S=r(n));break;case nr:S=8!==x||g?v():r(n);break;case or:if(1===x){S=n;const e=!o.children.length;for(let t=0;t{l=l||!!t.dynamicChildren;const{type:c,props:a,patchFlag:u,shapeFlag:f,dirs:d}=t,h="input"===c&&d||"option"===c;if(h||-1!==u){if(d&&$o(t,null,n,"created"),a)if(h||!l||16&u||32&u)for(const t in a)(h&&t.endsWith("value")||_(t)&&!L(t))&&o(e,t,null,a[t]);else a.onClick&&o(e,"onClick",null,a.onClick);let c;if((c=a&&a.onVnodeBeforeMount)&&Do(c,n,t),d&&$o(t,null,n,"beforeMount"),((c=a&&a.onVnodeMounted)||d)&&mn((()=>{c&&Do(c,n,t),d&&$o(t,null,n,"mounted")}),r),16&f&&(!a||!a.innerHTML&&!a.textContent)){let o=p(e.firstChild,t,e,n,r,s,l);for(;o;){Oo=!0;const e=o;o=o.nextSibling,i(e)}}else 8&f&&e.textContent!==t.children&&(Oo=!0,e.textContent=t.children)}return e.nextSibling},p=(e,t,o,r,s,i,l)=>{l=l||!!t.dynamicChildren;const c=t.children,u=c.length;for(let p=0;p{const{slotScopeIds:u}=t;u&&(i=i?i.concat(u):u);const f=s(e),d=p(r(e),t,f,n,o,i,a);return d&&Po(d)&&"]"===d.data?r(t.anchor=d):(Oo=!0,l(t.anchor=c("]"),f,d),d)},d=(e,t,o,l,c,a)=>{if(Oo=!0,t.el=null,a){const t=h(e);for(;;){const n=r(e);if(!n||n===t)break;i(n)}}const u=r(e),p=s(e);return i(e),n(null,t,p,u,o,l,Io(p),c),u},h=e=>{let t=0;for(;e;)if((e=r(e))&&Po(e)&&("["===e.data&&t++,"]"===e.data)){if(0===t)return r(e);t--}return e};return[(e,t)=>{if(!t.hasChildNodes())return n(null,e,t),void qt();Oo=!1,a(t.firstChild,e,null,null,null),qt(),Oo&&console.error("Hydration completed but contains mismatches.")},a]}const Ro={scheduler:Dt,allowRecurse:!0},Vo=mn,Lo=(e,t,n,o,r=!1)=>{if(T(e))return void e.forEach(((e,s)=>Lo(e,t&&(T(t)?t[s]:t),n,o,r)));if(Bn(o)&&!r)return;const s=4&o.shapeFlag?jr(o.component)||o.component.proxy:o.el,i=r?null:s,{i:l,r:c}=e,a=t&&t.r,u=l.refs===m?l.refs={}:l.refs,p=l.setupState;if(null!=a&&a!==c&&(A(a)?(u[a]=null,w(p,a)&&(p[a]=null)):pt(a)&&(a.value=null)),A(c)){const e=()=>{u[c]=i,w(p,c)&&(p[c]=i)};i?(e.id=-1,Vo(e,n)):e()}else if(pt(c)){const e=()=>{c.value=i};i?(e.id=-1,Vo(e,n)):e()}else F(c)&&Tt(c,l,12,[i,u])};function jo(e){return Ho(e)}function Uo(e){return Ho(e,Bo)}function Ho(e,t){const{insert:n,remove:o,patchProp:r,forcePatchProp:s,createElement:i,createText:l,createComment:c,setText:a,setElementText:u,parentNode:p,nextSibling:f,setScopeId:d=v,cloneNode:h,insertStaticContent:y}=e,b=(e,t,n,o=null,r=null,s=null,i=!1,l=null,c=!!t.dynamicChildren)=>{e&&!fr(e,t)&&(o=Y(e),K(e,r,s,!0),e=null),-2===t.patchFlag&&(c=!1,t.dynamicChildren=null);const{type:a,ref:u,shapeFlag:p}=t;switch(a){case tr:_(e,t,n,o);break;case nr:x(e,t,n,o);break;case or:null==e&&C(t,n,o,i);break;case er:M(e,t,n,o,r,s,i,l,c);break;default:1&p?k(e,t,n,o,r,s,i,l,c):6&p?O(e,t,n,o,r,s,i,l,c):(64&p||128&p)&&a.process(e,t,n,o,r,s,i,l,c,te)}null!=u&&r&&Lo(u,e&&e.ref,s,t||e,!t)},_=(e,t,o,r)=>{if(null==e)n(t.el=l(t.children),o,r);else{const n=t.el=e.el;t.children!==e.children&&a(n,t.children)}},x=(e,t,o,r)=>{null==e?n(t.el=c(t.children||""),o,r):t.el=e.el},C=(e,t,n,o)=>{[e.el,e.anchor]=y(e.children,t,n,o)},k=(e,t,n,o,r,s,i,l,c)=>{i=i||"svg"===t.type,null==e?T(t,n,o,r,s,i,l,c):$(e,t,r,s,i,l,c)},T=(e,t,o,s,l,c,a,p)=>{let f,d;const{type:m,props:g,shapeFlag:v,transition:y,patchFlag:b,dirs:_}=e;if(e.el&&void 0!==h&&-1===b)f=e.el=h(e.el);else{if(f=e.el=i(e.type,c,g&&g.is,g),8&v?u(f,e.children):16&v&&E(e.children,f,null,s,l,c&&"foreignObject"!==m,a,p),_&&$o(e,null,s,"created"),g){for(const t in g)L(t)||r(f,t,null,g[t],c,e.children,s,l,X);(d=g.onVnodeBeforeMount)&&Do(d,s,e)}N(f,e,e.scopeId,a,s)}_&&$o(e,null,s,"beforeMount");const x=(!l||l&&!l.pendingBranch)&&y&&!y.persisted;x&&y.beforeEnter(f),n(f,t,o),((d=g&&g.onVnodeMounted)||x||_)&&Vo((()=>{d&&Do(d,s,e),x&&y.enter(f),_&&$o(e,null,s,"mounted")}),l)},N=(e,t,n,o,r)=>{if(n&&d(e,n),o)for(let s=0;s{for(let a=c;a{const a=t.el=e.el;let{patchFlag:p,dynamicChildren:f,dirs:d}=t;p|=16&e.patchFlag;const h=e.props||m,g=t.props||m;let v;if((v=g.onVnodeBeforeUpdate)&&Do(v,n,t,e),d&&$o(t,e,n,"beforeUpdate"),p>0){if(16&p)A(a,t,h,g,n,o,i);else if(2&p&&h.class!==g.class&&r(a,"class",null,g.class,i),4&p&&r(a,"style",h.style,g.style,i),8&p){const l=t.dynamicProps;for(let t=0;t{v&&Do(v,n,t,e),d&&$o(t,e,n,"updated")}),o)},F=(e,t,n,o,r,s,i)=>{for(let l=0;l{if(n!==o){for(const a in o){if(L(a))continue;const u=o[a],p=n[a];(u!==p||s&&s(e,a))&&r(e,a,p,u,c,t.children,i,l,X)}if(n!==m)for(const s in n)L(s)||s in o||r(e,s,n[s],null,c,t.children,i,l,X)}},M=(e,t,o,r,s,i,c,a,u)=>{const p=t.el=e?e.el:l(""),f=t.anchor=e?e.anchor:l("");let{patchFlag:d,dynamicChildren:h,slotScopeIds:m}=t;h&&(u=!0),m&&(a=a?a.concat(m):m),null==e?(n(p,o,r),n(f,o,r),E(t.children,o,f,s,i,c,a,u)):d>0&&64&d&&h&&e.dynamicChildren?(F(e.dynamicChildren,h,o,s,i,c,a),(null!=t.key||s&&t===s.subTree)&&Wo(e,t,!0)):j(e,t,o,f,s,i,c,a,u)},O=(e,t,n,o,r,s,i,l,c)=>{t.slotScopeIds=l,null==e?512&t.shapeFlag?r.ctx.activate(t,n,o,i,c):P(t,n,o,r,s,i,c):B(e,t,c)},P=(e,t,n,o,r,s,i)=>{const l=e.component=function(e,t,n){const o=e.type,r=(t?t.appContext:e.appContext)||Er,s={uid:$r++,vnode:e,type:o,parent:t,appContext:r,root:null,next:null,subTree:null,update:null,render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,effects:null,provides:t?t.provides:Object.create(r.provides),accessCache:null,renderCache:[],components:null,directives:null,propsOptions:bo(o,r),emitsOptions:Xt(o,r),emit:null,emitted:null,propsDefaults:m,inheritAttrs:o.inheritAttrs,ctx:m,data:m,props:m,attrs:m,slots:m,refs:m,setupState:m,setupContext:null,suspense:n,suspenseId:n?n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return s.ctx={_:s},s.root=t?t.root:s,s.emit=Qt.bind(null,s),s}(e,o,r);if(Vn(e)&&(l.ctx.renderer=te),function(e,t=!1){Pr=t;const{props:n,children:o}=e.vnode,r=Or(e);(function(e,t,n,o=!1){const r={},s={};J(s,dr,1),e.propsDefaults=Object.create(null),vo(e,t,r,s);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);e.props=n?o?r:nt(r):e.type.props?r:s,e.attrs=s})(e,n,r,t),((e,t)=>{if(32&e.vnode.shapeFlag){const n=t._;n?(e.slots=ct(t),J(t,"_",n)):No(t,e.slots={})}else e.slots={},t&&Eo(e,t);J(e.slots,dr,1)})(e,o);const s=r?function(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=at(new Proxy(e.ctx,Tr));const{setup:o}=n;if(o){const n=e.setupContext=o.length>1?Lr(e):null;Fr=e,ce();const r=Tt(o,e,0,[e.props,n]);if(ae(),Fr=null,I(r)){const n=()=>{Fr=null};if(r.then(n,n),t)return r.then((t=>{Br(e,t)})).catch((t=>{Et(t,e,0)}));e.asyncDep=r}else Br(e,r)}else Vr(e)}(e,t):void 0;Pr=!1}(l),l.asyncDep){if(r&&r.registerDep(l,R),!e.el){const e=l.subTree=gr(nr);x(null,e,t,n)}}else R(l,e,t,n,r,s,i)},B=(e,t,n)=>{const o=t.component=e.component;if(function(e,t,n){const{props:o,children:r,component:s}=e,{props:i,children:l,patchFlag:c}=t,a=s.emitsOptions;if(t.dirs||t.transition)return!0;if(!(n&&c>=0))return!(!r&&!l||l&&l.$stable)||o!==i&&(o?!i||an(o,i,a):!!i);if(1024&c)return!0;if(16&c)return o?an(o,i,a):!!i;if(8&c){const e=t.dynamicProps;for(let t=0;tMt&&At.splice(t,1)}(o.update),o.update()}else t.component=e.component,t.el=e.el,o.vnode=t},R=(e,t,n,o,r,s,i)=>{e.update=ne((function(){if(e.isMounted){let t,{next:n,bu:o,u:l,parent:c,vnode:a}=e,u=n;n?(n.el=a.el,V(e,n,i)):n=a,o&&q(o),(t=n.props&&n.props.onVnodeBeforeUpdate)&&Do(t,c,n,a);const f=rn(e),d=e.subTree;e.subTree=f,b(d,f,p(d.el),Y(d),e,r,s),n.el=f.el,null===u&&un(e,f.el),l&&Vo(l,r),(t=n.props&&n.props.onVnodeUpdated)&&Vo((()=>Do(t,c,n,a)),r)}else{let i;const{el:l,props:c}=t,{bm:a,m:u,parent:p}=e;if(a&&q(a),(i=c&&c.onVnodeBeforeMount)&&Do(i,p,t),l&&se){const n=()=>{e.subTree=rn(e),se(l,e.subTree,e,r,null)};Bn(t)?t.type.__asyncLoader().then((()=>!e.isUnmounted&&n())):n()}else{const i=e.subTree=rn(e);b(null,i,n,o,e,r,s),t.el=i.el}if(u&&Vo(u,r),i=c&&c.onVnodeMounted){const e=t;Vo((()=>Do(i,p,e)),r)}256&t.shapeFlag&&e.a&&Vo(e.a,r),e.isMounted=!0,t=n=o=null}}),Ro)},V=(e,t,n)=>{t.component=e;const o=e.vnode.props;e.vnode=t,e.next=null,function(e,t,n,o){const{props:r,attrs:s,vnode:{patchFlag:i}}=e,l=ct(r),[c]=e.propsOptions;let a=!1;if(!(o||i>0)||16&i){let o;vo(e,t,r,s)&&(a=!0);for(const s in l)t&&(w(t,s)||(o=W(s))!==s&&w(t,o))||(c?!n||void 0===n[s]&&void 0===n[o]||(r[s]=yo(c,l,s,void 0,e,!0)):delete r[s]);if(s!==l)for(const e in s)t&&w(t,e)||(delete s[e],a=!0)}else if(8&i){const n=e.vnode.dynamicProps;for(let o=0;o{const{vnode:o,slots:r}=e;let s=!0,i=m;if(32&o.shapeFlag){const e=t._;e?n&&1===e?s=!1:(S(r,t),n||1!==e||delete r._):(s=!t.$stable,No(t,r)),i=t}else t&&(Eo(e,t),i={default:1});if(s)for(const l in r)ko(l)||l in i||delete r[l]})(e,t.children,n),ce(),Gt(void 0,e.update),ae()},j=(e,t,n,o,r,s,i,l,c=!1)=>{const a=e&&e.children,p=e?e.shapeFlag:0,f=t.children,{patchFlag:d,shapeFlag:h}=t;if(d>0){if(128&d)return void D(a,f,n,o,r,s,i,l,c);if(256&d)return void U(a,f,n,o,r,s,i,l,c)}8&h?(16&p&&X(a,r,s),f!==a&&u(n,f)):16&p?16&h?D(a,f,n,o,r,s,i,l,c):X(a,r,s,!0):(8&p&&u(n,""),16&h&&E(f,n,o,r,s,i,l,c))},U=(e,t,n,o,r,s,i,l,c)=>{const a=(e=e||g).length,u=(t=t||g).length,p=Math.min(a,u);let f;for(f=0;fu?X(e,r,s,!0,!1,p):E(t,n,o,r,s,i,l,c,p)},D=(e,t,n,o,r,s,i,l,c)=>{let a=0;const u=t.length;let p=e.length-1,f=u-1;for(;a<=p&&a<=f;){const o=e[a],u=t[a]=c?_r(t[a]):br(t[a]);if(!fr(o,u))break;b(o,u,n,null,r,s,i,l,c),a++}for(;a<=p&&a<=f;){const o=e[p],a=t[f]=c?_r(t[f]):br(t[f]);if(!fr(o,a))break;b(o,a,n,null,r,s,i,l,c),p--,f--}if(a>p){if(a<=f){const e=f+1,p=ef)for(;a<=p;)K(e[a],r,s,!0),a++;else{const d=a,h=a,m=new Map;for(a=h;a<=f;a++){const e=t[a]=c?_r(t[a]):br(t[a]);null!=e.key&&m.set(e.key,a)}let v,y=0;const _=f-h+1;let x=!1,S=0;const C=new Array(_);for(a=0;a<_;a++)C[a]=0;for(a=d;a<=p;a++){const o=e[a];if(y>=_){K(o,r,s,!0);continue}let u;if(null!=o.key)u=m.get(o.key);else for(v=h;v<=f;v++)if(0===C[v-h]&&fr(o,t[v])){u=v;break}void 0===u?K(o,r,s,!0):(C[u-h]=a+1,u>=S?S=u:x=!0,b(o,t[u],n,null,r,s,i,l,c),y++)}const k=x?function(e){const t=e.slice(),n=[0];let o,r,s,i,l;const c=e.length;for(o=0;o0&&(t[o]=n[s-1]),n[s]=o)}}s=n.length,i=n[s-1];for(;s-- >0;)n[s]=i,i=t[i];return n}(C):g;for(v=k.length-1,a=_-1;a>=0;a--){const e=h+a,p=t[e],f=e+1{const{el:i,type:l,transition:c,children:a,shapeFlag:u}=e;if(6&u)return void z(e.component.subTree,t,o,r);if(128&u)return void e.suspense.move(t,o,r);if(64&u)return void l.move(e,t,o,te);if(l===er){n(i,t,o);for(let e=0;e{let s;for(;e&&e!==t;)s=f(e),n(e,o,r),e=s;n(t,o,r)})(e,t,o);if(2!==r&&1&u&&c)if(0===r)c.beforeEnter(i),n(i,t,o),Vo((()=>c.enter(i)),s);else{const{leave:e,delayLeave:r,afterLeave:s}=c,l=()=>n(i,t,o),a=()=>{e(i,(()=>{l(),s&&s()}))};r?r(i,l,a):a()}else n(i,t,o)},K=(e,t,n,o=!1,r=!1)=>{const{type:s,props:i,ref:l,children:c,dynamicChildren:a,shapeFlag:u,patchFlag:p,dirs:f}=e;if(null!=l&&Lo(l,null,n,e,!0),256&u)return void t.ctx.deactivate(e);const d=1&u&&f;let h;if((h=i&&i.onVnodeBeforeUnmount)&&Do(h,t,e),6&u)Q(e.component,n,o);else{if(128&u)return void e.suspense.unmount(n,o);d&&$o(e,null,t,"beforeUnmount"),64&u?e.type.remove(e,t,n,r,te,o):a&&(s!==er||p>0&&64&p)?X(a,t,n,!1,!0):(s===er&&(128&p||256&p)||!r&&16&u)&&X(c,t,n),o&&G(e)}((h=i&&i.onVnodeUnmounted)||d)&&Vo((()=>{h&&Do(h,t,e),d&&$o(e,null,t,"unmounted")}),n)},G=e=>{const{type:t,el:n,anchor:r,transition:s}=e;if(t===er)return void Z(n,r);if(t===or)return void(({el:e,anchor:t})=>{let n;for(;e&&e!==t;)n=f(e),o(e),e=n;o(t)})(e);const i=()=>{o(n),s&&!s.persisted&&s.afterLeave&&s.afterLeave()};if(1&e.shapeFlag&&s&&!s.persisted){const{leave:t,delayLeave:o}=s,r=()=>t(n,i);o?o(e.el,i,r):r()}else i()},Z=(e,t)=>{let n;for(;e!==t;)n=f(e),o(e),e=n;o(t)},Q=(e,t,n)=>{const{bum:o,effects:r,update:s,subTree:i,um:l}=e;if(o&&q(o),r)for(let c=0;c{e.isUnmounted=!0}),t),t&&t.pendingBranch&&!t.isUnmounted&&e.asyncDep&&!e.asyncResolved&&e.suspenseId===t.pendingId&&(t.deps--,0===t.deps&&t.resolve())},X=(e,t,n,o=!1,r=!1,s=0)=>{for(let i=s;i6&e.shapeFlag?Y(e.component.subTree):128&e.shapeFlag?e.suspense.next():f(e.anchor||e.el),ee=(e,t,n)=>{null==e?t._vnode&&K(t._vnode,null,null,!0):b(t._vnode||null,e,t,null,null,null,n),qt(),t._vnode=e},te={p:b,um:K,m:z,r:G,mt:P,mc:E,pc:j,pbc:F,n:Y,o:e};let re,se;return t&&([re,se]=t(te)),{render:ee,hydrate:re,createApp:Mo(ee,re)}}function Do(e,t,n,o=null){Nt(e,t,7,[n,o])}function Wo(e,t,n=!1){const o=e.children,r=t.children;if(T(o)&&T(r))for(let s=0;se&&(e.disabled||""===e.disabled),Ko=e=>"undefined"!=typeof SVGElement&&e instanceof SVGElement,Go=(e,t)=>{const n=e&&e.to;if(A(n)){if(t){return t(n)}return null}return n};function qo(e,t,n,{o:{insert:o},m:r},s=2){0===s&&o(e.targetAnchor,t,n);const{el:i,anchor:l,shapeFlag:c,children:a,props:u}=e,p=2===s;if(p&&o(i,t,n),(!p||zo(u))&&16&c)for(let f=0;f{16&v&&u(y,e,t,r,s,i,l,c)};g?b(n,a):p&&b(p,f)}else{t.el=e.el;const o=t.anchor=e.anchor,u=t.target=e.target,d=t.targetAnchor=e.targetAnchor,m=zo(e.props),v=m?n:u,y=m?o:d;if(i=i||Ko(u),b?(f(e.dynamicChildren,b,v,r,s,i,l),Wo(e,t,!0)):c||p(e,t,v,y,r,s,i,l,!1),g)m||qo(t,n,o,a,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const e=t.target=Go(t.props,h);e&&qo(t,e,null,a,0)}else m&&qo(t,u,d,a,1)}},remove(e,t,n,o,{um:r,o:{remove:s}},i){const{shapeFlag:l,children:c,anchor:a,targetAnchor:u,target:p,props:f}=e;if(p&&s(u),(i||!zo(f))&&(s(a),16&l))for(let d=0;d0?sr||g:null,lr(),cr>0&&sr&&sr.push(s),s}function pr(e){return!!e&&!0===e.__v_isVNode}function fr(e,t){return e.type===t.type&&e.key===t.key}const dr="__vInternal",hr=({key:e})=>null!=e?e:null,mr=({ref:e})=>null!=e?A(e)||pt(e)||F(e)?{i:en,r:e}:e:null,gr=function(e,t=null,n=null,o=0,s=null,i=!1){e&&e!==Qo||(e=nr);if(pr(e)){const o=vr(e,t,!0);return n&&xr(o,n),o}l=e,F(l)&&"__vccOpts"in l&&(e=e.__vccOpts);var l;if(t){(lt(t)||dr in t)&&(t=S({},t));let{class:e,style:n}=t;e&&!A(e)&&(t.class=c(e)),O(n)&&(lt(n)&&!T(n)&&(n=S({},n)),t.style=r(n))}const a=A(e)?1:(e=>e.__isSuspense)(e)?128:(e=>e.__isTeleport)(e)?64:O(e)?4:F(e)?2:0,u={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&hr(t),ref:t&&mr(t),scopeId:tn,slotScopeIds:null,children:null,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,shapeFlag:a,patchFlag:o,dynamicProps:s,dynamicChildren:null,appContext:null};xr(u,n),128&a&&e.normalize(u);cr>0&&!i&&sr&&(o>0||6&a)&&32!==o&&sr.push(u);return u};function vr(e,t,n=!1){const{props:o,ref:r,patchFlag:s,children:i}=e,l=t?Sr(o||{},t):o;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&hr(l),ref:t&&t.ref?n&&r?T(r)?r.concat(mr(t)):[r,mr(t)]:mr(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==er?-1===s?16:16|s:s,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&vr(e.ssContent),ssFallback:e.ssFallback&&vr(e.ssFallback),el:e.el,anchor:e.anchor}}function yr(e=" ",t=0){return gr(tr,null,e,t)}function br(e){return null==e||"boolean"==typeof e?gr(nr):T(e)?gr(er,null,e.slice()):"object"==typeof e?_r(e):gr(tr,null,String(e))}function _r(e){return null===e.el?e:vr(e)}function xr(e,t){let n=0;const{shapeFlag:o}=e;if(null==t)t=null;else if(T(t))n=16;else if("object"==typeof t){if(1&o||64&o){const n=t.default;return void(n&&(n._c&&(n._d=!1),xr(e,n()),n._c&&(n._d=!0)))}{n=32;const o=t._;o||dr in t?3===o&&en&&(1===en.slots._?t._=1:(t._=2,e.patchFlag|=1024)):t._ctx=en}}else F(t)?(t={default:t,_ctx:en},n=32):(t=String(t),64&o?(n=16,t=[yr(t)]):n=8);e.children=t,e.shapeFlag|=n}function Sr(...e){const t=S({},e[0]);for(let n=1;n!pr(e)||e.type!==nr&&!(e.type===er&&!Cr(e.children))))?e:null}const kr=e=>e?Or(e)?jr(e)||e.proxy:kr(e.parent):null,wr=S(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>kr(e.parent),$root:e=>kr(e.root),$emit:e=>e.emit,$options:e=>ao(e),$forceUpdate:e=>()=>Dt(e.update),$nextTick:e=>Ht.bind(e.proxy),$watch:e=>Cn.bind(e)}),Tr={get({_:e},t){const{ctx:n,setupState:o,data:r,props:s,accessCache:i,type:l,appContext:c}=e;let a;if("$"!==t[0]){const l=i[t];if(void 0!==l)switch(l){case 0:return o[t];case 1:return r[t];case 3:return n[t];case 2:return s[t]}else{if(o!==m&&w(o,t))return i[t]=0,o[t];if(r!==m&&w(r,t))return i[t]=1,r[t];if((a=e.propsOptions[0])&&w(a,t))return i[t]=2,s[t];if(n!==m&&w(n,t))return i[t]=3,n[t];so&&(i[t]=4)}}const u=wr[t];let p,f;return u?("$attrs"===t&&ue(e,0,t),u(e)):(p=l.__cssModules)&&(p=p[t])?p:n!==m&&w(n,t)?(i[t]=3,n[t]):(f=c.config.globalProperties,w(f,t)?f[t]:void 0)},set({_:e},t,n){const{data:o,setupState:r,ctx:s}=e;if(r!==m&&w(r,t))r[t]=n;else if(o!==m&&w(o,t))o[t]=n;else if(w(e.props,t))return!1;return("$"!==t[0]||!(t.slice(1)in e))&&(s[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:o,appContext:r,propsOptions:s}},i){let l;return void 0!==n[i]||e!==m&&w(e,i)||t!==m&&w(t,i)||(l=s[0])&&w(l,i)||w(o,i)||w(wr,i)||w(r.config.globalProperties,i)}},Nr=S({},Tr,{get(e,t){if(t!==Symbol.unscopables)return Tr.get(e,t,e)},has:(e,t)=>"_"!==t[0]&&!n(t)}),Er=Fo();let $r=0;let Fr=null;const Ar=()=>Fr||en,Mr=e=>{Fr=e};function Or(e){return 4&e.vnode.shapeFlag}let Ir,Pr=!1;function Br(e,t,n){F(t)?e.render=t:O(t)&&(e.setupState=vt(t)),Vr(e)}function Rr(e){Ir=e}function Vr(e,t,n){const o=e.type;if(!e.render){if(Ir&&!o.render){const t=o.template;if(t){const{isCustomElement:n,compilerOptions:r}=e.appContext.config,{delimiters:s,compilerOptions:i}=o,l=S(S({isCustomElement:n,delimiters:s},r),i);o.render=Ir(t,l)}}e.render=o.render||v,e.render._rc&&(e.withProxy=new Proxy(e.ctx,Nr))}Fr=e,ce(),io(e),ae(),Fr=null}function Lr(e){const t=t=>{e.exposed=t||{}};return{attrs:e.attrs,slots:e.slots,emit:e.emit,expose:t}}function jr(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(vt(at(e.exposed)),{get:(t,n)=>n in t?t[n]:n in wr?wr[n](e):void 0}))}function Ur(e,t=Fr){t&&(t.effects||(t.effects=[])).push(e)}const Hr=/(?:^|[-_])(\w)/g;function Dr(e){return F(e)&&e.displayName||e.name}function Wr(e,t,n=!1){let o=Dr(t);if(!o&&t.__file){const e=t.__file.match(/([^/\\]+)\.\w+$/);e&&(o=e[1])}if(!o&&e&&e.parent){const n=e=>{for(const n in e)if(e[n]===t)return n};o=n(e.components||e.parent.type.components)||n(e.appContext.components)}return o?o.replace(Hr,(e=>e.toUpperCase())).replace(/[-_]/g,""):n?"App":"Anonymous"}function zr(e){const t=function(e){let t,n;return F(e)?(t=e,n=v):(t=e.get,n=e.set),new xt(t,n,F(e)||!e.set)}(e);return Ur(t.effect),t}function Kr(){return null}const Gr=Kr;function qr(){const e=Ar();return e.setupContext||(e.setupContext=Lr(e))}function Jr(e,t,n){const o=arguments.length;return 2===o?O(t)&&!T(t)?pr(t)?gr(e,null,[t]):gr(e,t):gr(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):3===o&&pr(n)&&(n=[n]),gr(e,t,n))}const Zr=Symbol("");const Qr="3.1.5",Xr="undefined"!=typeof document?document:null,Yr=new Map,es={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const r=t?Xr.createElementNS("http://www.w3.org/2000/svg",e):Xr.createElement(e,n?{is:n}:void 0);return"select"===e&&o&&null!=o.multiple&&r.setAttribute("multiple",o.multiple),r},createText:e=>Xr.createTextNode(e),createComment:e=>Xr.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Xr.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},cloneNode(e){const t=e.cloneNode(!0);return"_value"in e&&(t._value=e._value),t},insertStaticContent(e,t,n,o){const r=n?n.previousSibling:t.lastChild;let s=Yr.get(e);if(!s){const t=Xr.createElement("template");if(t.innerHTML=o?`${e}`:e,s=t.content,o){const e=s.firstChild;for(;e.firstChild;)s.appendChild(e.firstChild);s.removeChild(e)}Yr.set(e,s)}return t.insertBefore(s.cloneNode(!0),n),[r?r.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};const ts=/\s*!important$/;function ns(e,t,n){if(T(n))n.forEach((n=>ns(e,t,n)));else if(t.startsWith("--"))e.setProperty(t,n);else{const o=function(e,t){const n=rs[t];if(n)return n;let o=H(t);if("filter"!==o&&o in e)return rs[t]=o;o=z(o);for(let r=0;rdocument.createEvent("Event").timeStamp&&(is=()=>performance.now());const e=navigator.userAgent.match(/firefox\/(\d+)/i);ls=!!(e&&Number(e[1])<=53)}let cs=0;const as=Promise.resolve(),us=()=>{cs=0};function ps(e,t,n,o){e.addEventListener(t,n,o)}function fs(e,t,n,o,r=null){const s=e._vei||(e._vei={}),i=s[t];if(o&&i)i.value=o;else{const[n,l]=function(e){let t;if(ds.test(e)){let n;for(t={};n=e.match(ds);)e=e.slice(0,e.length-n[0].length),t[n[0].toLowerCase()]=!0}return[W(e.slice(2)),t]}(t);if(o){ps(e,n,s[t]=function(e,t){const n=e=>{const o=e.timeStamp||is();(ls||o>=n.attached-1)&&Nt(function(e,t){if(T(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map((e=>t=>!t._stopped&&e(t)))}return t}(e,n.value),t,5,[e])};return n.value=e,n.attached=(()=>cs||(as.then(us),cs=is()))(),n}(o,r),l)}else i&&(!function(e,t,n,o){e.removeEventListener(t,n,o)}(e,n,i,l),s[t]=void 0)}}const ds=/(?:Once|Passive|Capture)$/;const hs=/^on[a-z]/;function ms(e,t){if(128&e.shapeFlag){const n=e.suspense;e=n.activeBranch,n.pendingBranch&&!n.isHydrating&&n.effects.push((()=>{ms(n.activeBranch,t)}))}for(;e.component;)e=e.component.subTree;if(1&e.shapeFlag&&e.el)gs(e.el,t);else if(e.type===er)e.children.forEach((e=>ms(e,t)));else if(e.type===or){let{el:n,anchor:o}=e;for(;n&&(gs(n,t),n!==o);)n=n.nextSibling}}function gs(e,t){if(1===e.nodeType){const n=e.style;for(const e in t)n.setProperty(`--${e}`,t[e])}}const vs="transition",ys="animation",bs=(e,{slots:t})=>Jr(En,ks(e),t);bs.displayName="Transition";const _s={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},xs=bs.props=S({},En.props,_s),Ss=(e,t=[])=>{T(e)?e.forEach((e=>e(...t))):e&&e(...t)},Cs=e=>!!e&&(T(e)?e.some((e=>e.length>1)):e.length>1);function ks(e){const t={};for(const S in e)S in _s||(t[S]=e[S]);if(!1===e.css)return t;const{name:n="v",type:o,duration:r,enterFromClass:s=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=s,appearActiveClass:a=i,appearToClass:u=l,leaveFromClass:p=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:d=`${n}-leave-to`}=e,h=function(e){if(null==e)return null;if(O(e))return[ws(e.enter),ws(e.leave)];{const t=ws(e);return[t,t]}}(r),m=h&&h[0],g=h&&h[1],{onBeforeEnter:v,onEnter:y,onEnterCancelled:b,onLeave:_,onLeaveCancelled:x,onBeforeAppear:C=v,onAppear:k=y,onAppearCancelled:w=b}=t,T=(e,t,n)=>{Ns(e,t?u:l),Ns(e,t?a:i),n&&n()},N=(e,t)=>{Ns(e,d),Ns(e,f),t&&t()},E=e=>(t,n)=>{const r=e?k:y,i=()=>T(t,e,n);Ss(r,[t,i]),Es((()=>{Ns(t,e?c:s),Ts(t,e?u:l),Cs(r)||Fs(t,o,m,i)}))};return S(t,{onBeforeEnter(e){Ss(v,[e]),Ts(e,s),Ts(e,i)},onBeforeAppear(e){Ss(C,[e]),Ts(e,c),Ts(e,a)},onEnter:E(!1),onAppear:E(!0),onLeave(e,t){const n=()=>N(e,t);Ts(e,p),Is(),Ts(e,f),Es((()=>{Ns(e,p),Ts(e,d),Cs(_)||Fs(e,o,g,n)})),Ss(_,[e,n])},onEnterCancelled(e){T(e,!1),Ss(b,[e])},onAppearCancelled(e){T(e,!0),Ss(w,[e])},onLeaveCancelled(e){N(e),Ss(x,[e])}})}function ws(e){return Z(e)}function Ts(e,t){t.split(/\s+/).forEach((t=>t&&e.classList.add(t))),(e._vtc||(e._vtc=new Set)).add(t)}function Ns(e,t){t.split(/\s+/).forEach((t=>t&&e.classList.remove(t)));const{_vtc:n}=e;n&&(n.delete(t),n.size||(e._vtc=void 0))}function Es(e){requestAnimationFrame((()=>{requestAnimationFrame(e)}))}let $s=0;function Fs(e,t,n,o){const r=e._endId=++$s,s=()=>{r===e._endId&&o()};if(n)return setTimeout(s,n);const{type:i,timeout:l,propCount:c}=As(e,t);if(!i)return o();const a=i+"end";let u=0;const p=()=>{e.removeEventListener(a,f),s()},f=t=>{t.target===e&&++u>=c&&p()};setTimeout((()=>{u(n[e]||"").split(", "),r=o("transitionDelay"),s=o("transitionDuration"),i=Ms(r,s),l=o("animationDelay"),c=o("animationDuration"),a=Ms(l,c);let u=null,p=0,f=0;t===vs?i>0&&(u=vs,p=i,f=s.length):t===ys?a>0&&(u=ys,p=a,f=c.length):(p=Math.max(i,a),u=p>0?i>a?vs:ys:null,f=u?u===vs?s.length:c.length:0);return{type:u,timeout:p,propCount:f,hasTransform:u===vs&&/\b(transform|all)(,|$)/.test(n.transitionProperty)}}function Ms(e,t){for(;e.lengthOs(t)+Os(e[n]))))}function Os(e){return 1e3*Number(e.slice(0,-1).replace(",","."))}function Is(){return document.body.offsetHeight}const Ps=new WeakMap,Bs=new WeakMap,Rs={name:"TransitionGroup",props:S({},xs,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=Ar(),o=Tn();let r,s;return Xn((()=>{if(!r.length)return;const t=e.moveClass||`${e.name||"v"}-move`;if(!function(e,t,n){const o=e.cloneNode();e._vtc&&e._vtc.forEach((e=>{e.split(/\s+/).forEach((e=>e&&o.classList.remove(e)))}));n.split(/\s+/).forEach((e=>e&&o.classList.add(e))),o.style.display="none";const r=1===t.nodeType?t:t.parentNode;r.appendChild(o);const{hasTransform:s}=As(o);return r.removeChild(o),s}(r[0].el,n.vnode.el,t))return;r.forEach(Vs),r.forEach(Ls);const o=r.filter(js);Is(),o.forEach((e=>{const n=e.el,o=n.style;Ts(n,t),o.transform=o.webkitTransform=o.transitionDuration="";const r=n._moveCb=e=>{e&&e.target!==n||e&&!/transform$/.test(e.propertyName)||(n.removeEventListener("transitionend",r),n._moveCb=null,Ns(n,t))};n.addEventListener("transitionend",r)}))})),()=>{const i=ct(e),l=ks(i);let c=i.tag||er;r=s,s=t.default?In(t.default()):[];for(let e=0;e{const t=e.props["onUpdate:modelValue"];return T(t)?e=>q(t,e):t};function Hs(e){e.target.composing=!0}function Ds(e){const t=e.target;t.composing&&(t.composing=!1,function(e,t){const n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}(t,"input"))}const Ws={created(e,{modifiers:{lazy:t,trim:n,number:o}},r){e._assign=Us(r);const s=o||"number"===e.type;ps(e,t?"change":"input",(t=>{if(t.target.composing)return;let o=e.value;n?o=o.trim():s&&(o=Z(o)),e._assign(o)})),n&&ps(e,"change",(()=>{e.value=e.value.trim()})),t||(ps(e,"compositionstart",Hs),ps(e,"compositionend",Ds),ps(e,"change",Ds))},mounted(e,{value:t}){e.value=null==t?"":t},beforeUpdate(e,{value:t,modifiers:{trim:n,number:o}},r){if(e._assign=Us(r),e.composing)return;if(document.activeElement===e){if(n&&e.value.trim()===t)return;if((o||"number"===e.type)&&Z(e.value)===t)return}const s=null==t?"":t;e.value!==s&&(e.value=s)}},zs={deep:!0,created(e,t,n){e._assign=Us(n),ps(e,"change",(()=>{const t=e._modelValue,n=Zs(e),o=e.checked,r=e._assign;if(T(t)){const e=d(t,n),s=-1!==e;if(o&&!s)r(t.concat(n));else if(!o&&s){const n=[...t];n.splice(e,1),r(n)}}else if(E(t)){const e=new Set(t);o?e.add(n):e.delete(n),r(e)}else r(Qs(e,o))}))},mounted:Ks,beforeUpdate(e,t,n){e._assign=Us(n),Ks(e,t,n)}};function Ks(e,{value:t,oldValue:n},o){e._modelValue=t,T(t)?e.checked=d(t,o.props.value)>-1:E(t)?e.checked=t.has(o.props.value):t!==n&&(e.checked=f(t,Qs(e,!0)))}const Gs={created(e,{value:t},n){e.checked=f(t,n.props.value),e._assign=Us(n),ps(e,"change",(()=>{e._assign(Zs(e))}))},beforeUpdate(e,{value:t,oldValue:n},o){e._assign=Us(o),t!==n&&(e.checked=f(t,o.props.value))}},qs={deep:!0,created(e,{value:t,modifiers:{number:n}},o){const r=E(t);ps(e,"change",(()=>{const t=Array.prototype.filter.call(e.options,(e=>e.selected)).map((e=>n?Z(Zs(e)):Zs(e)));e._assign(e.multiple?r?new Set(t):t:t[0])})),e._assign=Us(o)},mounted(e,{value:t}){Js(e,t)},beforeUpdate(e,t,n){e._assign=Us(n)},updated(e,{value:t}){Js(e,t)}};function Js(e,t){const n=e.multiple;if(!n||T(t)||E(t)){for(let o=0,r=e.options.length;o-1:t.has(s);else if(f(Zs(r),t))return void(e.selectedIndex!==o&&(e.selectedIndex=o))}n||-1===e.selectedIndex||(e.selectedIndex=-1)}}function Zs(e){return"_value"in e?e._value:e.value}function Qs(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Xs={created(e,t,n){Ys(e,t,n,null,"created")},mounted(e,t,n){Ys(e,t,n,null,"mounted")},beforeUpdate(e,t,n,o){Ys(e,t,n,o,"beforeUpdate")},updated(e,t,n,o){Ys(e,t,n,o,"updated")}};function Ys(e,t,n,o,r){let s;switch(e.tagName){case"SELECT":s=qs;break;case"TEXTAREA":s=Ws;break;default:switch(n.props&&n.props.type){case"checkbox":s=zs;break;case"radio":s=Gs;break;default:s=Ws}}const i=s[r];i&&i(e,t,n,o)}const ei=["ctrl","shift","alt","meta"],ti={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&0!==e.button,middle:e=>"button"in e&&1!==e.button,right:e=>"button"in e&&2!==e.button,exact:(e,t)=>ei.some((n=>e[`${n}Key`]&&!t.includes(n)))},ni={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},oi={beforeMount(e,{value:t},{transition:n}){e._vod="none"===e.style.display?"":e.style.display,n&&t?n.beforeEnter(e):ri(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:o}){!t!=!n&&(o?t?(o.beforeEnter(e),ri(e,!0),o.enter(e)):o.leave(e,(()=>{ri(e,!1)})):ri(e,t))},beforeUnmount(e,{value:t}){ri(e,t)}};function ri(e,t){e.style.display=t?e._vod:"none"}const si=S({patchProp:(e,t,n,r,s=!1,i,l,c,a)=>{switch(t){case"class":!function(e,t,n){const o=e._vtc;o&&(t=(t?[t,...o]:[...o]).join(" ")),null==t?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}(e,r,s);break;case"style":!function(e,t,n){const o=e.style;if(n)if(A(n)){if(t!==n){const t=o.display;o.cssText=n,"_vod"in e&&(o.display=t)}}else{for(const e in n)ns(o,e,n[e]);if(t&&!A(t))for(const e in t)null==n[e]&&ns(o,e,"")}else e.removeAttribute("style")}(e,n,r);break;default:_(t)?x(t)||fs(e,t,0,r,l):function(e,t,n,o){if(o)return"innerHTML"===t||!!(t in e&&hs.test(t)&&F(n));if("spellcheck"===t||"draggable"===t)return!1;if("form"===t)return!1;if("list"===t&&"INPUT"===e.tagName)return!1;if("type"===t&&"TEXTAREA"===e.tagName)return!1;if(hs.test(t)&&A(n))return!1;return t in e}(e,t,r,s)?function(e,t,n,o,r,s,i){if("innerHTML"===t||"textContent"===t)return o&&i(o,r,s),void(e[t]=null==n?"":n);if("value"===t&&"PROGRESS"!==e.tagName){e._value=n;const o=null==n?"":n;return e.value!==o&&(e.value=o),void(null==n&&e.removeAttribute(t))}if(""===n||null==n){const o=typeof e[t];if(""===n&&"boolean"===o)return void(e[t]=!0);if(null==n&&"string"===o)return e[t]="",void e.removeAttribute(t);if("number"===o){try{e[t]=0}catch(l){}return void e.removeAttribute(t)}}try{e[t]=n}catch(c){}}(e,t,r,i,l,c,a):("true-value"===t?e._trueValue=r:"false-value"===t&&(e._falseValue=r),function(e,t,n,r,s){if(r&&t.startsWith("xlink:"))null==n?e.removeAttributeNS(ss,t.slice(6,t.length)):e.setAttributeNS(ss,t,n);else{const r=o(t);null==n||r&&!1===n?e.removeAttribute(t):e.setAttribute(t,r?"":n)}}(e,t,r,s))}},forcePatchProp:(e,t)=>"value"===t},es);let ii,li=!1;function ci(){return ii||(ii=jo(si))}function ai(){return ii=li?ii:Uo(si),li=!0,ii}function ui(e){if(A(e)){return document.querySelector(e)}return e}function pi(e){throw e}function fi(e){}function di(e,t,n,o){const r=new SyntaxError(String(e));return r.code=e,r.loc=t,r}const hi=Symbol(""),mi=Symbol(""),gi=Symbol(""),vi=Symbol(""),yi=Symbol(""),bi=Symbol(""),_i=Symbol(""),xi=Symbol(""),Si=Symbol(""),Ci=Symbol(""),ki=Symbol(""),wi=Symbol(""),Ti=Symbol(""),Ni=Symbol(""),Ei=Symbol(""),$i=Symbol(""),Fi=Symbol(""),Ai=Symbol(""),Mi=Symbol(""),Oi=Symbol(""),Ii=Symbol(""),Pi=Symbol(""),Bi=Symbol(""),Ri=Symbol(""),Vi=Symbol(""),Li=Symbol(""),ji=Symbol(""),Ui=Symbol(""),Hi=Symbol(""),Di=Symbol(""),Wi=Symbol(""),zi=Symbol(""),Ki={[hi]:"Fragment",[mi]:"Teleport",[gi]:"Suspense",[vi]:"KeepAlive",[yi]:"BaseTransition",[bi]:"openBlock",[_i]:"createBlock",[xi]:"createVNode",[Si]:"createCommentVNode",[Ci]:"createTextVNode",[ki]:"createStaticVNode",[wi]:"resolveComponent",[Ti]:"resolveDynamicComponent",[Ni]:"resolveDirective",[Ei]:"resolveFilter",[$i]:"withDirectives",[Fi]:"renderList",[Ai]:"renderSlot",[Mi]:"createSlots",[Oi]:"toDisplayString",[Ii]:"mergeProps",[Pi]:"toHandlers",[Bi]:"camelize",[Ri]:"capitalize",[Vi]:"toHandlerKey",[Li]:"setBlockTracking",[ji]:"pushScopeId",[Ui]:"popScopeId",[Hi]:"withScopeId",[Di]:"withCtx",[Wi]:"unref",[zi]:"isRef"};const Gi={source:"",start:{line:1,column:1,offset:0},end:{line:1,column:1,offset:0}};function qi(e,t,n,o,r,s,i,l=!1,c=!1,a=Gi){return e&&(l?(e.helper(bi),e.helper(_i)):e.helper(xi),i&&e.helper($i)),{type:13,tag:t,props:n,children:o,patchFlag:r,dynamicProps:s,directives:i,isBlock:l,disableTracking:c,loc:a}}function Ji(e,t=Gi){return{type:17,loc:t,elements:e}}function Zi(e,t=Gi){return{type:15,loc:t,properties:e}}function Qi(e,t){return{type:16,loc:Gi,key:A(e)?Xi(e,!0):e,value:t}}function Xi(e,t,n=Gi,o=0){return{type:4,loc:n,content:e,isStatic:t,constType:t?3:o}}function Yi(e,t=Gi){return{type:8,loc:t,children:e}}function el(e,t=[],n=Gi){return{type:14,loc:n,callee:e,arguments:t}}function tl(e,t,n=!1,o=!1,r=Gi){return{type:18,params:e,returns:t,newline:n,isSlot:o,loc:r}}function nl(e,t,n,o=!0){return{type:19,test:e,consequent:t,alternate:n,newline:o,loc:Gi}}const ol=e=>4===e.type&&e.isStatic,rl=(e,t)=>e===t||e===W(t);function sl(e){return rl(e,"Teleport")?mi:rl(e,"Suspense")?gi:rl(e,"KeepAlive")?vi:rl(e,"BaseTransition")?yi:void 0}const il=/^\d|[^\$\w]/,ll=e=>!il.test(e),cl=/[A-Za-z_$\xA0-\uFFFF]/,al=/[\.\?\w$\xA0-\uFFFF]/,ul=/\s+[.[]\s*|\s*[.[]\s+/g,pl=e=>{e=e.trim().replace(ul,(e=>e.trim()));let t=0,n=[],o=0,r=0,s=null;for(let i=0;i4===e.key.type&&e.key.content===n))}e||r.properties.unshift(t),o=r}else o=el(n.helper(Ii),[Zi([t]),r]);13===e.type?e.props=o:e.arguments[2]=o}function Cl(e,t){return`_${t}_${e.replace(/[^\w]/g,"_")}`}const kl=/&(gt|lt|amp|apos|quot);/g,wl={gt:">",lt:"<",amp:"&",apos:"'",quot:'"'},Tl={delimiters:["{{","}}"],getNamespace:()=>0,getTextMode:()=>0,isVoidTag:y,isPreTag:y,isCustomElement:y,decodeEntities:e=>e.replace(kl,((e,t)=>wl[t])),onError:pi,onWarn:fi,comments:!1};function Nl(e,t={}){const n=function(e,t){const n=S({},Tl);for(const o in t)n[o]=t[o]||Tl[o];return{options:n,column:1,line:1,offset:0,originalSource:e,source:e,inPre:!1,inVPre:!1,onWarn:n.onWarn}}(e,t),o=Ul(n);return function(e,t=Gi){return{type:0,children:e,helpers:[],components:[],directives:[],hoists:[],imports:[],cached:0,temps:0,codegenNode:void 0,loc:t}}(El(n,0,[]),Hl(n,o))}function El(e,t,n){const o=Dl(n),r=o?o.ns:0,s=[];for(;!ql(e,t,n);){const i=e.source;let l;if(0===t||1===t)if(!e.inVPre&&Wl(i,e.options.delimiters[0]))l=Vl(e,t);else if(0===t&&"<"===i[0])if(1===i.length);else if("!"===i[1])l=Wl(i,"\x3c!--")?Al(e):Wl(i,""===i[2]){zl(e,3);continue}if(/[a-z]/i.test(i[2])){Pl(e,1,o);continue}l=Ml(e)}else/[a-z]/i.test(i[1])?l=Ol(e,n):"?"===i[1]&&(l=Ml(e));if(l||(l=Ll(e,t)),T(l))for(let e=0;e/.exec(e.source);if(o){n=e.source.slice(4,o.index);const t=e.source.slice(0,o.index);let r=1,s=0;for(;-1!==(s=t.indexOf("\x3c!--",r));)zl(e,s-r+1),r=s+1;zl(e,o.index+o[0].length-r+1)}else n=e.source.slice(4),zl(e,e.source.length);return{type:3,content:n,loc:Hl(e,t)}}function Ml(e){const t=Ul(e),n="?"===e.source[1]?1:2;let o;const r=e.source.indexOf(">");return-1===r?(o=e.source.slice(n),zl(e,e.source.length)):(o=e.source.slice(n,r),zl(e,r+1)),{type:3,content:o,loc:Hl(e,t)}}function Ol(e,t){const n=e.inPre,o=e.inVPre,r=Dl(t),s=Pl(e,0,r),i=e.inPre&&!n,l=e.inVPre&&!o;if(s.isSelfClosing||e.options.isVoidTag(s.tag))return e.options.isPreTag(s.tag)&&(e.inPre=!1),s;t.push(s);const c=e.options.getTextMode(s,r),a=El(e,c,t);if(t.pop(),s.children=a,Jl(e.source,s.tag))Pl(e,1,r);else if(0===e.source.length&&"script"===s.tag.toLowerCase()){const e=a[0];e&&Wl(e.loc.source,"\x3c!--")}return s.loc=Hl(e,s.loc.start),i&&(e.inPre=!1),l&&(e.inVPre=!1),s}const Il=t("if,else,else-if,for,slot");function Pl(e,t,n){const o=Ul(e),r=/^<\/?([a-z][^\t\r\n\f />]*)/i.exec(e.source),s=r[1],i=e.options.getNamespace(s,n);zl(e,r[0].length),Kl(e);const l=Ul(e),c=e.source;e.options.isPreTag(s)&&(e.inPre=!0);let a=Bl(e,t);0===t&&!e.inVPre&&a.some((e=>7===e.type&&"pre"===e.name))&&(e.inVPre=!0,S(e,l),e.source=c,a=Bl(e,t).filter((e=>"v-pre"!==e.name)));let u=!1;if(0===e.source.length||(u=Wl(e.source,"/>"),zl(e,u?2:1)),1===t)return;let p=0;return e.inVPre||("slot"===s?p=2:"template"===s?a.some((e=>7===e.type&&Il(e.name)))&&(p=3):function(e,t,n){const o=n.options;if(o.isCustomElement(e))return!1;if("component"===e||/^[A-Z]/.test(e)||sl(e)||o.isBuiltInComponent&&o.isBuiltInComponent(e)||o.isNativeTag&&!o.isNativeTag(e))return!0;for(let r=0;r0&&!Wl(e.source,">")&&!Wl(e.source,"/>");){if(Wl(e.source,"/")){zl(e,1),Kl(e);continue}const r=Rl(e,o);0===t&&n.push(r),/^[^\t\r\n\f />]/.test(e.source),Kl(e)}return n}function Rl(e,t){const n=Ul(e),o=/^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(e.source)[0];t.has(o),t.add(o);{const e=/["'<]/g;let t;for(;t=e.exec(o););}let r;zl(e,o.length),/^[\t\r\n\f ]*=/.test(e.source)&&(Kl(e),zl(e,1),Kl(e),r=function(e){const t=Ul(e);let n;const o=e.source[0],r='"'===o||"'"===o;if(r){zl(e,1);const t=e.source.indexOf(o);-1===t?n=jl(e,e.source.length,4):(n=jl(e,t,4),zl(e,1))}else{const t=/^[^\t\r\n\f >]+/.exec(e.source);if(!t)return;const o=/["'<=`]/g;let r;for(;r=o.exec(t[0]););n=jl(e,t[0].length,4)}return{content:n,isQuoted:r,loc:Hl(e,t)}}(e));const s=Hl(e,n);if(!e.inVPre&&/^(v-|:|@|#)/.test(o)){const t=/(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(o);let i,l=t[1]||(Wl(o,":")?"bind":Wl(o,"@")?"on":"slot");if(t[2]){const r="slot"===l,s=o.lastIndexOf(t[2]),c=Hl(e,Gl(e,n,s),Gl(e,n,s+t[2].length+(r&&t[3]||"").length));let a=t[2],u=!0;a.startsWith("[")?(u=!1,a.endsWith("]"),a=a.substr(1,a.length-2)):r&&(a+=t[3]||""),i={type:4,content:a,isStatic:u,constType:u?3:0,loc:c}}if(r&&r.isQuoted){const e=r.loc;e.start.offset++,e.start.column++,e.end=dl(e.start,r.content),e.source=e.source.slice(1,-1)}const c=t[3]?t[3].substr(1).split("."):[];return{type:7,name:l,exp:r&&{type:4,content:r.content,isStatic:!1,constType:0,loc:r.loc},arg:i,modifiers:c,loc:s}}return{type:6,name:o,value:r&&{type:2,content:r.content,loc:r.loc},loc:s}}function Vl(e,t){const[n,o]=e.options.delimiters,r=e.source.indexOf(o,n.length);if(-1===r)return;const s=Ul(e);zl(e,n.length);const i=Ul(e),l=Ul(e),c=r-n.length,a=e.source.slice(0,c),u=jl(e,c,t),p=u.trim(),f=u.indexOf(p);f>0&&hl(i,a,f);return hl(l,a,c-(u.length-p.length-f)),zl(e,o.length),{type:5,content:{type:4,isStatic:!1,constType:0,content:p,loc:Hl(e,i,l)},loc:Hl(e,s)}}function Ll(e,t){const n=["<",e.options.delimiters[0]];3===t&&n.push("]]>");let o=e.source.length;for(let s=0;st&&(o=t)}const r=Ul(e);return{type:2,content:jl(e,o,t),loc:Hl(e,r)}}function jl(e,t,n){const o=e.source.slice(0,t);return zl(e,t),2===n||3===n||-1===o.indexOf("&")?o:e.options.decodeEntities(o,4===n)}function Ul(e){const{column:t,line:n,offset:o}=e;return{column:t,line:n,offset:o}}function Hl(e,t,n){return{start:t,end:n=n||Ul(e),source:e.originalSource.slice(t.offset,n.offset)}}function Dl(e){return e[e.length-1]}function Wl(e,t){return e.startsWith(t)}function zl(e,t){const{source:n}=e;hl(e,n,t),e.source=n.slice(t)}function Kl(e){const t=/^[\t\r\n\f ]+/.exec(e.source);t&&zl(e,t[0].length)}function Gl(e,t,n){return dl(t,e.originalSource.slice(t.offset,n),n)}function ql(e,t,n){const o=e.source;switch(t){case 0:if(Wl(o,"=0;--e)if(Jl(o,n[e].tag))return!0;break;case 1:case 2:{const e=Dl(n);if(e&&Jl(o,e.tag))return!0;break}case 3:if(Wl(o,"]]>"))return!0}return!o}function Jl(e,t){return Wl(e,"]/.test(e[2+t.length]||">")}function Zl(e,t){Xl(e,t,Ql(e,e.children[0]))}function Ql(e,t){const{children:n}=e;return 1===n.length&&1===t.type&&!xl(t)}function Xl(e,t,n=!1){let o=!1,r=!0;const{children:s}=e;for(let i=0;i0){if(s<3&&(r=!1),s>=2){e.codegenNode.patchFlag="-1",e.codegenNode=t.hoist(e.codegenNode),o=!0;continue}}else{const n=e.codegenNode;if(13===n.type){const o=nc(n);if((!o||512===o||1===o)&&ec(e,t)>=2){const o=tc(e);o&&(n.props=t.hoist(o))}}}}else if(12===e.type){const n=Yl(e.content,t);n>0&&(n<3&&(r=!1),n>=2&&(e.codegenNode=t.hoist(e.codegenNode),o=!0))}if(1===e.type){const n=1===e.tagType;n&&t.scopes.vSlot++,Xl(e,t),n&&t.scopes.vSlot--}else if(11===e.type)Xl(e,t,1===e.children.length);else if(9===e.type)for(let n=0;n1)for(let r=0;r`_${Ki[k.helper(e)]}`,replaceNode(e){k.parent.children[k.childIndex]=k.currentNode=e},removeNode(e){const t=e?k.parent.children.indexOf(e):k.currentNode?k.childIndex:-1;e&&e!==k.currentNode?k.childIndex>t&&(k.childIndex--,k.onNodeRemoved()):(k.currentNode=null,k.onNodeRemoved()),k.parent.children.splice(t,1)},onNodeRemoved:()=>{},addIdentifiers(e){},removeIdentifiers(e){},hoist(e){k.hoists.push(e);const t=Xi(`_hoisted_${k.hoists.length}`,!1,e.loc,2);return t.hoisted=e,t},cache:(e,t=!1)=>function(e,t,n=!1){return{type:20,index:e,value:t,isVNode:n,loc:Gi}}(++k.cached,e,t)};return k}function rc(e,t){const n=oc(e,t);sc(e,n),t.hoistStatic&&Zl(e,n),t.ssr||function(e,t){const{helper:n,removeHelper:o}=t,{children:r}=e;if(1===r.length){const t=r[0];if(Ql(e,t)&&t.codegenNode){const r=t.codegenNode;13===r.type&&(r.isBlock||(o(xi),r.isBlock=!0,n(bi),n(_i))),e.codegenNode=r}else e.codegenNode=t}else if(r.length>1){let o=64;e.codegenNode=qi(t,n(hi),void 0,e.children,o+"",void 0,void 0,!0)}}(e,n),e.helpers=[...n.helpers.keys()],e.components=[...n.components],e.directives=[...n.directives],e.imports=n.imports,e.hoists=n.hoists,e.temps=n.temps,e.cached=n.cached}function sc(e,t){t.currentNode=e;const{nodeTransforms:n}=t,o=[];for(let s=0;s{n--};for(;nt===e:t=>e.test(t);return(e,o)=>{if(1===e.type){const{props:r}=e;if(3===e.tagType&&r.some(bl))return;const s=[];for(let i=0;i`_${Ki[e]}`,push(e,t){p.code+=e},indent(){f(++p.indentLevel)},deindent(e=!1){e?--p.indentLevel:f(--p.indentLevel)},newline(){f(p.indentLevel)}};function f(e){p.push("\n"+" ".repeat(e))}return p}(e,t);t.onContextCreated&&t.onContextCreated(n);const{mode:o,push:r,prefixIdentifiers:s,indent:i,deindent:l,newline:c,ssr:a}=n,u=e.helpers.length>0,p=!s&&"module"!==o;!function(e,t){const{push:n,newline:o,runtimeGlobalName:r}=t,s=r,i=e=>`${Ki[e]}: _${Ki[e]}`;if(e.helpers.length>0&&(n(`const _Vue = ${s}\n`),e.hoists.length)){n(`const { ${[xi,Si,Ci,ki].filter((t=>e.helpers.includes(t))).map(i).join(", ")} } = _Vue\n`)}(function(e,t){if(!e.length)return;t.pure=!0;const{push:n,newline:o}=t;o(),e.forEach(((e,r)=>{e&&(n(`const _hoisted_${r+1} = `),fc(e,t),o())})),t.pure=!1})(e.hoists,t),o(),n("return ")}(e,n);if(r(`function ${a?"ssrRender":"render"}(${(a?["_ctx","_push","_parent","_attrs"]:["_ctx","_cache"]).join(", ")}) {`),i(),p&&(r("with (_ctx) {"),i(),u&&(r(`const { ${e.helpers.map((e=>`${Ki[e]}: _${Ki[e]}`)).join(", ")} } = _Vue`),r("\n"),c())),e.components.length&&(ac(e.components,"component",n),(e.directives.length||e.temps>0)&&c()),e.directives.length&&(ac(e.directives,"directive",n),e.temps>0&&c()),e.temps>0){r("let ");for(let t=0;t0?", ":""}_temp${t}`)}return(e.components.length||e.directives.length||e.temps)&&(r("\n"),c()),a||r("return "),e.codegenNode?fc(e.codegenNode,n):r("null"),p&&(l(),r("}")),l(),r("}"),{ast:e,code:n.code,preamble:"",map:n.map?n.map.toJSON():void 0}}function ac(e,t,{helper:n,push:o,newline:r,isTS:s}){const i=n("component"===t?wi:Ni);for(let l=0;l3||!1;t.push("["),n&&t.indent(),pc(e,t,n),n&&t.deindent(),t.push("]")}function pc(e,t,n=!1,o=!0){const{push:r,newline:s}=t;for(let i=0;ie||"null"))}([s,i,l,c,a]),t),n(")"),p&&n(")");u&&(n(", "),fc(u,t),n(")"))}(e,t);break;case 14:!function(e,t){const{push:n,helper:o,pure:r}=t,s=A(e.callee)?e.callee:o(e.callee);r&&n(lc);n(s+"(",e),pc(e.arguments,t),n(")")}(e,t);break;case 15:!function(e,t){const{push:n,indent:o,deindent:r,newline:s}=t,{properties:i}=e;if(!i.length)return void n("{}",e);const l=i.length>1||!1;n(l?"{":"{ "),l&&o();for(let c=0;c "),(c||l)&&(n("{"),o());i?(c&&n("return "),T(i)?uc(i,t):fc(i,t)):l&&fc(l,t);(c||l)&&(r(),n("}"));a&&n(")")}(e,t);break;case 19:!function(e,t){const{test:n,consequent:o,alternate:r,newline:s}=e,{push:i,indent:l,deindent:c,newline:a}=t;if(4===n.type){const e=!ll(n.content);e&&i("("),dc(n,t),e&&i(")")}else i("("),fc(n,t),i(")");s&&l(),t.indentLevel++,s||i(" "),i("? "),fc(o,t),t.indentLevel--,s&&a(),s||i(" "),i(": ");const u=19===r.type;u||t.indentLevel++;fc(r,t),u||t.indentLevel--;s&&c(!0)}(e,t);break;case 20:!function(e,t){const{push:n,helper:o,indent:r,deindent:s,newline:i}=t;n(`_cache[${e.index}] || (`),e.isVNode&&(r(),n(`${o(Li)}(-1),`),i());n(`_cache[${e.index}] = `),fc(e.value,t),e.isVNode&&(n(","),i(),n(`${o(Li)}(1),`),i(),n(`_cache[${e.index}]`),s());n(")")}(e,t)}}function dc(e,t){const{content:n,isStatic:o}=e;t.push(o?JSON.stringify(n):n,e)}function hc(e,t){for(let n=0;nfunction(e,t,n,o){if(!("else"===t.name||t.exp&&t.exp.content.trim())){t.exp=Xi("true",!1,t.exp?t.exp.loc:e.loc)}if("if"===t.name){const r=vc(e,t),s={type:9,loc:e.loc,branches:[r]};if(n.replaceNode(s),o)return o(s,r,!0)}else{const r=n.parent.children;let s=r.indexOf(e);for(;s-- >=-1;){const i=r[s];if(!i||2!==i.type||i.content.trim().length){if(i&&9===i.type){n.removeNode();const r=vc(e,t);i.branches.push(r);const s=o&&o(i,r,!1);sc(r,n),s&&s(),n.currentNode=null}break}n.removeNode(i)}}}(e,t,n,((e,t,o)=>{const r=n.parent.children;let s=r.indexOf(e),i=0;for(;s-- >=0;){const e=r[s];e&&9===e.type&&(i+=e.branches.length)}return()=>{if(o)e.codegenNode=yc(t,i,n);else{(function(e){for(;;)if(19===e.type){if(19!==e.alternate.type)return e;e=e.alternate}else 20===e.type&&(e=e.value)}(e.codegenNode)).alternate=yc(t,i+e.branches.length-1,n)}}}))));function vc(e,t){return{type:10,loc:e.loc,condition:"else"===t.name?void 0:t.exp,children:3!==e.tagType||ml(e,"for")?[e]:e.children,userKey:gl(e,"key")}}function yc(e,t,n){return e.condition?nl(e.condition,bc(e,t,n),el(n.helper(Si),['""',"true"])):bc(e,t,n)}function bc(e,t,n){const{helper:o,removeHelper:r}=n,s=Qi("key",Xi(`${t}`,!1,Gi,2)),{children:i}=e,l=i[0];if(1!==i.length||1!==l.type){if(1===i.length&&11===l.type){const e=l.codegenNode;return Sl(e,s,n),e}{let t=64;return qi(n,o(hi),Zi([s]),i,t+"",void 0,void 0,!0,!1,e.loc)}}{const e=l.codegenNode;return 13!==e.type||e.isBlock||(r(xi),e.isBlock=!0,o(bi),o(_i)),Sl(e,s,n),e}}const _c=ic("for",((e,t,n)=>{const{helper:o,removeHelper:r}=n;return function(e,t,n,o){if(!t.exp)return;const r=kc(t.exp);if(!r)return;const{scopes:s}=n,{source:i,value:l,key:c,index:a}=r,u={type:11,loc:t.loc,source:i,valueAlias:l,keyAlias:c,objectIndexAlias:a,parseResult:r,children:_l(e)?e.children:[e]};n.replaceNode(u),s.vFor++;const p=o&&o(u);return()=>{s.vFor--,p&&p()}}(e,t,n,(t=>{const s=el(o(Fi),[t.source]),i=gl(e,"key"),l=i?Qi("key",6===i.type?Xi(i.value.content,!0):i.exp):null,c=4===t.source.type&&t.source.constType>0,a=c?64:i?128:256;return t.codegenNode=qi(n,o(hi),void 0,s,a+"",void 0,void 0,!0,!c,e.loc),()=>{let i;const a=_l(e),{children:u}=t,p=1!==u.length||1!==u[0].type,f=xl(e)?e:a&&1===e.children.length&&xl(e.children[0])?e.children[0]:null;f?(i=f.codegenNode,a&&l&&Sl(i,l,n)):p?i=qi(n,o(hi),l?Zi([l]):void 0,e.children,"64",void 0,void 0,!0):(i=u[0].codegenNode,a&&l&&Sl(i,l,n),i.isBlock!==!c&&(i.isBlock?(r(bi),r(_i)):r(xi)),i.isBlock=!c,i.isBlock?(o(bi),o(_i)):o(xi)),s.arguments.push(tl(Tc(t.parseResult),i,!0))}}))}));const xc=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,Sc=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Cc=/^\(|\)$/g;function kc(e,t){const n=e.loc,o=e.content,r=o.match(xc);if(!r)return;const[,s,i]=r,l={source:wc(n,i.trim(),o.indexOf(i,s.length)),value:void 0,key:void 0,index:void 0};let c=s.trim().replace(Cc,"").trim();const a=s.indexOf(c),u=c.match(Sc);if(u){c=c.replace(Sc,"").trim();const e=u[1].trim();let t;if(e&&(t=o.indexOf(e,a+c.length),l.key=wc(n,e,t)),u[2]){const r=u[2].trim();r&&(l.index=wc(n,r,o.indexOf(r,l.key?t+e.length:a+c.length)))}}return c&&(l.value=wc(n,c,a)),l}function wc(e,t,n){return Xi(t,!1,fl(e,n,t.length))}function Tc({value:e,key:t,index:n}){const o=[];return e&&o.push(e),t&&(e||o.push(Xi("_",!1)),o.push(t)),n&&(t||(e||o.push(Xi("_",!1)),o.push(Xi("__",!1))),o.push(n)),o}const Nc=Xi("undefined",!1),Ec=(e,t)=>{if(1===e.type&&(1===e.tagType||3===e.tagType)){const n=ml(e,"slot");if(n)return t.scopes.vSlot++,()=>{t.scopes.vSlot--}}},$c=(e,t,n)=>tl(e,t,!1,!0,t.length?t[0].loc:n);function Fc(e,t,n=$c){t.helper(Di);const{children:o,loc:r}=e,s=[],i=[];let l=t.scopes.vSlot>0||t.scopes.vFor>0;const c=ml(e,"slot",!0);if(c){const{arg:e,exp:t}=c;e&&!ol(e)&&(l=!0),s.push(Qi(e||Xi("default",!0),n(t,o,r)))}let a=!1,u=!1;const p=[],f=new Set;for(let m=0;mQi("default",n(e,t,r));a?p.length&&p.some((e=>Oc(e)))&&(u||s.push(e(void 0,p))):s.push(e(void 0,o))}const d=l?2:Mc(e.children)?3:1;let h=Zi(s.concat(Qi("_",Xi(d+"",!1))),r);return i.length&&(h=el(t.helper(Mi),[h,Ji(i)])),{slots:h,hasDynamicSlots:l}}function Ac(e,t){return Zi([Qi("name",e),Qi("fn",t)])}function Mc(e){for(let t=0;tfunction(){if(1!==(e=t.currentNode).type||0!==e.tagType&&1!==e.tagType)return;const{tag:n,props:o}=e,r=1===e.tagType;let s=r?function(e,t,n=!1){let{tag:o}=e;const r=Lc(o),s=gl(e,"is");if(s)if(r){const e=6===s.type?s.value&&Xi(s.value.content,!0):s.exp;if(e)return el(t.helper(Ti),[e])}else 6===s.type&&s.value.content.startsWith("vue:")&&(o=s.value.content.slice(4));const i=!r&&ml(e,"is");if(i&&i.exp)return el(t.helper(Ti),[i.exp]);const l=sl(o)||t.isBuiltInComponent(o);if(l)return n||t.helper(l),l;return t.helper(wi),t.components.add(o),Cl(o,"component")}(e,t):`"${n}"`;let i,l,c,a,u,p,f=0,d=O(s)&&s.callee===Ti||s===mi||s===gi||!r&&("svg"===n||"foreignObject"===n||gl(e,"key",!0));if(o.length>0){const n=Bc(e,t);i=n.props,f=n.patchFlag,u=n.dynamicPropNames;const o=n.directives;p=o&&o.length?Ji(o.map((e=>function(e,t){const n=[],o=Ic.get(e);o?n.push(t.helperString(o)):(t.helper(Ni),t.directives.add(e.name),n.push(Cl(e.name,"directive")));const{loc:r}=e;e.exp&&n.push(e.exp);e.arg&&(e.exp||n.push("void 0"),n.push(e.arg));if(Object.keys(e.modifiers).length){e.arg||(e.exp||n.push("void 0"),n.push("void 0"));const t=Xi("true",!1,r);n.push(Zi(e.modifiers.map((e=>Qi(e,t))),r))}return Ji(n,e.loc)}(e,t)))):void 0}if(e.children.length>0){s===vi&&(d=!0,f|=1024);if(r&&s!==mi&&s!==vi){const{slots:n,hasDynamicSlots:o}=Fc(e,t);l=n,o&&(f|=1024)}else if(1===e.children.length&&s!==mi){const n=e.children[0],o=n.type,r=5===o||8===o;r&&0===Yl(n,t)&&(f|=1),l=r||2===o?n:e.children}else l=e.children}0!==f&&(c=String(f),u&&u.length&&(a=function(e){let t="[";for(let n=0,o=e.length;n{if(ol(e)){const o=e.content,r=_(o);if(i||!r||"onclick"===o.toLowerCase()||"onUpdate:modelValue"===o||L(o)||(h=!0),r&&L(o)&&(g=!0),20===n.type||(4===n.type||8===n.type)&&Yl(n,t)>0)return;"ref"===o?p=!0:"class"!==o||i?"style"!==o||i?"key"===o||v.includes(o)||v.push(o):d=!0:f=!0}else m=!0};for(let _=0;_1?el(t.helper(Ii),c,s):c[0]):l.length&&(b=Zi(Rc(l),s)),m?u|=16:(f&&(u|=2),d&&(u|=4),v.length&&(u|=8),h&&(u|=32)),0!==u&&32!==u||!(p||g||a.length>0)||(u|=512),{props:b,directives:a,patchFlag:u,dynamicPropNames:v}}function Rc(e){const t=new Map,n=[];for(let o=0;o{if(xl(e)){const{children:n,loc:o}=e,{slotName:r,slotProps:s}=function(e,t){let n,o='"default"';const r=[];for(let s=0;s0){const{props:o,directives:s}=Bc(e,t,r);n=o}return{slotName:o,slotProps:n}}(e,t),i=[t.prefixIdentifiers?"_ctx.$slots":"$slots",r];s&&i.push(s),n.length&&(s||i.push("{}"),i.push(tl([],n,!1,!1,o))),t.scopeId&&!t.slotted&&(s||i.push("{}"),n.length||i.push("undefined"),i.push("true")),e.codegenNode=el(t.helper(Ai),i,o)}};const Uc=/^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/,Hc=(e,t,n,o)=>{const{loc:r,modifiers:s,arg:i}=e;let l;if(4===i.type)if(i.isStatic){l=Xi(K(H(i.content)),!0,i.loc)}else l=Yi([`${n.helperString(Vi)}(`,i,")"]);else l=i,l.children.unshift(`${n.helperString(Vi)}(`),l.children.push(")");let c=e.exp;c&&!c.content.trim()&&(c=void 0);let a=n.cacheHandlers&&!c;if(c){const e=pl(c.content),t=!(e||Uc.test(c.content)),n=c.content.includes(";");(t||a&&e)&&(c=Yi([`${t?"$event":"(...args)"} => ${n?"{":"("}`,c,n?"}":")"]))}let u={props:[Qi(l,c||Xi("() => {}",!1,r))]};return o&&(u=o(u)),a&&(u.props[0].value=n.cache(u.props[0].value)),u},Dc=(e,t,n)=>{const{exp:o,modifiers:r,loc:s}=e,i=e.arg;return 4!==i.type?(i.children.unshift("("),i.children.push(') || ""')):i.isStatic||(i.content=`${i.content} || ""`),r.includes("camel")&&(4===i.type?i.content=i.isStatic?H(i.content):`${n.helperString(Bi)}(${i.content})`:(i.children.unshift(`${n.helperString(Bi)}(`),i.children.push(")"))),!o||4===o.type&&!o.content.trim()?{props:[Qi(i,Xi("",!0,s))]}:{props:[Qi(i,o)]}},Wc=(e,t)=>{if(0===e.type||1===e.type||11===e.type||10===e.type)return()=>{const n=e.children;let o,r=!1;for(let e=0;e7===e.type&&!t.directiveTransforms[e.name])))))for(let e=0;e{if(1===e.type&&ml(e,"once",!0)){if(zc.has(e))return;return zc.add(e),t.helper(Li),()=>{const e=t.currentNode;e.codegenNode&&(e.codegenNode=t.cache(e.codegenNode,!0))}}},Gc=(e,t,n)=>{const{exp:o,arg:r}=e;if(!o)return qc();const s=o.loc.source,i=4===o.type?o.content:s;if(!i.trim()||!pl(i))return qc();const l=r||Xi("modelValue",!0),c=r?ol(r)?`onUpdate:${r.content}`:Yi(['"onUpdate:" + ',r]):"onUpdate:modelValue";let a;a=Yi([`${n.isTS?"($event: any)":"$event"} => (`,o," = $event)"]);const u=[Qi(l,e.exp),Qi(c,a)];if(e.modifiers.length&&1===t.tagType){const t=e.modifiers.map((e=>(ll(e)?e:JSON.stringify(e))+": true")).join(", "),n=r?ol(r)?`${r.content}Modifiers`:Yi([r,' + "Modifiers"']):"modelModifiers";u.push(Qi(n,Xi(`{ ${t} }`,!1,e.loc,2)))}return qc(u)};function qc(e=[]){return{props:e}}function Jc(e,t={}){const n=t.onError||pi,o="module"===t.mode;!0===t.prefixIdentifiers?n(di(45)):o&&n(di(46));t.cacheHandlers&&n(di(47)),t.scopeId&&!o&&n(di(48));const r=A(e)?Nl(e,t):e,[s,i]=[[Kc,gc,_c,jc,Pc,Ec,Wc],{on:Hc,bind:Dc,model:Gc}];return rc(r,S({},t,{prefixIdentifiers:false,nodeTransforms:[...s,...t.nodeTransforms||[]],directiveTransforms:S({},i,t.directiveTransforms||{})})),cc(r,S({},t,{prefixIdentifiers:false}))}const Zc=Symbol(""),Qc=Symbol(""),Xc=Symbol(""),Yc=Symbol(""),ea=Symbol(""),ta=Symbol(""),na=Symbol(""),oa=Symbol(""),ra=Symbol(""),sa=Symbol("");var ia;let la;ia={[Zc]:"vModelRadio",[Qc]:"vModelCheckbox",[Xc]:"vModelText",[Yc]:"vModelSelect",[ea]:"vModelDynamic",[ta]:"withModifiers",[na]:"withKeys",[oa]:"vShow",[ra]:"Transition",[sa]:"TransitionGroup"},Object.getOwnPropertySymbols(ia).forEach((e=>{Ki[e]=ia[e]}));const ca=t("style,iframe,script,noscript",!0),aa={isVoidTag:p,isNativeTag:e=>a(e)||u(e),isPreTag:e=>"pre"===e,decodeEntities:function(e,t=!1){return la||(la=document.createElement("div")),t?(la.innerHTML=`
`,la.children[0].getAttribute("foo")):(la.innerHTML=e,la.textContent)},isBuiltInComponent:e=>rl(e,"Transition")?ra:rl(e,"TransitionGroup")?sa:void 0,getNamespace(e,t){let n=t?t.ns:0;if(t&&2===n)if("annotation-xml"===t.tag){if("svg"===e)return 1;t.props.some((e=>6===e.type&&"encoding"===e.name&&null!=e.value&&("text/html"===e.value.content||"application/xhtml+xml"===e.value.content)))&&(n=0)}else/^m(?:[ions]|text)$/.test(t.tag)&&"mglyph"!==e&&"malignmark"!==e&&(n=0);else t&&1===n&&("foreignObject"!==t.tag&&"desc"!==t.tag&&"title"!==t.tag||(n=0));if(0===n){if("svg"===e)return 1;if("math"===e)return 2}return n},getTextMode({tag:e,ns:t}){if(0===t){if("textarea"===e||"title"===e)return 1;if(ca(e))return 2}return 0}},ua=(e,t)=>{const n=l(e);return Xi(JSON.stringify(n),!1,t,3)};const pa=t("passive,once,capture"),fa=t("stop,prevent,self,ctrl,shift,alt,meta,exact,middle"),da=t("left,right"),ha=t("onkeyup,onkeydown,onkeypress",!0),ma=(e,t)=>ol(e)&&"onclick"===e.content.toLowerCase()?Xi(t,!0):4!==e.type?Yi(["(",e,`) === "onClick" ? "${t}" : (`,e,")"]):e,ga=(e,t)=>{1!==e.type||0!==e.tagType||"script"!==e.tag&&"style"!==e.tag||t.removeNode()},va=[e=>{1===e.type&&e.props.forEach(((t,n)=>{6===t.type&&"style"===t.name&&t.value&&(e.props[n]={type:7,name:"bind",arg:Xi("style",!0,t.loc),exp:ua(t.value.content,t.loc),modifiers:[],loc:t.loc})}))}],ya={cloak:()=>({props:[]}),html:(e,t,n)=>{const{exp:o,loc:r}=e;return t.children.length&&(t.children.length=0),{props:[Qi(Xi("innerHTML",!0,r),o||Xi("",!0))]}},text:(e,t,n)=>{const{exp:o,loc:r}=e;return t.children.length&&(t.children.length=0),{props:[Qi(Xi("textContent",!0),o?el(n.helperString(Oi),[o],r):Xi("",!0))]}},model:(e,t,n)=>{const o=Gc(e,t,n);if(!o.props.length||1===t.tagType)return o;const{tag:r}=t,s=n.isCustomElement(r);if("input"===r||"textarea"===r||"select"===r||s){let e=Xc,i=!1;if("input"===r||s){const n=gl(t,"type");if(n){if(7===n.type)e=ea;else if(n.value)switch(n.value.content){case"radio":e=Zc;break;case"checkbox":e=Qc;break;case"file":i=!0}}else(function(e){return e.props.some((e=>!(7!==e.type||"bind"!==e.name||e.arg&&4===e.arg.type&&e.arg.isStatic)))})(t)&&(e=ea)}else"select"===r&&(e=Yc);i||(o.needRuntime=n.helper(e))}return o.props=o.props.filter((e=>!(4===e.key.type&&"modelValue"===e.key.content))),o},on:(e,t,n)=>Hc(e,0,n,(t=>{const{modifiers:o}=e;if(!o.length)return t;let{key:r,value:s}=t.props[0];const{keyModifiers:i,nonKeyModifiers:l,eventOptionModifiers:c}=((e,t,n,o)=>{const r=[],s=[],i=[];for(let l=0;l({props:[],needRuntime:n.helper(oa)})};const ba=Object.create(null);function _a(e,t){if(!A(e)){if(!e.nodeType)return v;e=e.innerHTML}const n=e,o=ba[n];if(o)return o;if("#"===e[0]){const t=document.querySelector(e);e=t?t.innerHTML:""}const{code:r}=function(e,t={}){return Jc(e,S({},aa,t,{nodeTransforms:[ga,...va,...t.nodeTransforms||[]],directiveTransforms:S({},ya,t.directiveTransforms||{}),transformHoist:null}))}(e,S({hoistStatic:!0,onError:void 0,onWarn:v},t)),s=new Function(r)();return s._rc=!0,ba[n]=s}return Rr(_a),e.BaseTransition=En,e.Comment=nr,e.Fragment=er,e.KeepAlive=Ln,e.Static=or,e.Suspense=pn,e.Teleport=Jo,e.Text=tr,e.Transition=bs,e.TransitionGroup=Rs,e.callWithAsyncErrorHandling=Nt,e.callWithErrorHandling=Tt,e.camelize=H,e.capitalize=z,e.cloneVNode=vr,e.compatUtils=null,e.compile=_a,e.computed=zr,e.createApp=(...e)=>{const t=ci().createApp(...e),{mount:n}=t;return t.mount=e=>{const o=ui(e);if(!o)return;const r=t._component;F(r)||r.render||r.template||(r.template=o.innerHTML),o.innerHTML="";const s=n(o,!1,o instanceof SVGElement);return o instanceof Element&&(o.removeAttribute("v-cloak"),o.setAttribute("data-v-app","")),s},t},e.createBlock=ur,e.createCommentVNode=function(e="",t=!1){return t?(ir(),ur(nr,null,e)):gr(nr,null,e)},e.createHydrationRenderer=Uo,e.createRenderer=jo,e.createSSRApp=(...e)=>{const t=ai().createApp(...e),{mount:n}=t;return t.mount=e=>{const t=ui(e);if(t)return n(t,!0,t instanceof SVGElement)},t},e.createSlots=function(e,t){for(let n=0;n{let e;return a||(e=a=t().catch((e=>{if(e=e instanceof Error?e:new Error(String(e)),l)return new Promise(((t,n)=>{l(e,(()=>t((u++,a=null,p()))),(()=>n(e)),u+1)}));throw e})).then((t=>e!==a&&a?a:(t&&(t.__esModule||"Module"===t[Symbol.toStringTag])&&(t=t.default),c=t,t))))};return Pn({name:"AsyncComponentWrapper",__asyncLoader:p,get __asyncResolved(){return c},setup(){const e=Fr;if(c)return()=>Rn(c,e);const t=t=>{a=null,Et(t,e,13,!o)};if(i&&e.suspense)return p().then((t=>()=>Rn(t,e))).catch((e=>(t(e),()=>o?gr(o,{error:e}):null)));const l=ft(!1),u=ft(),f=ft(!!r);return r&&setTimeout((()=>{f.value=!1}),r),null!=s&&setTimeout((()=>{if(!l.value&&!u.value){const e=new Error(`Async component timed out after ${s}ms.`);t(e),u.value=e}}),s),p().then((()=>{l.value=!0,e.parent&&Vn(e.parent.vnode)&&Dt(e.parent.update)})).catch((e=>{t(e),u.value=e})),()=>l.value&&c?Rn(c,e):u.value&&o?gr(o,{error:u.value}):n&&!f.value?gr(n):void 0}})},e.defineComponent=Pn,e.defineEmit=Gr,e.defineEmits=Kr,e.defineExpose=function(e){},e.defineProps=function(){return null},e.getCurrentInstance=Ar,e.getTransitionRawChildren=In,e.h=Jr,e.handleError=Et,e.hydrate=(...e)=>{ai().hydrate(...e)},e.initCustomFormatter=function(){},e.inject=yn,e.isProxy=lt,e.isReactive=st,e.isReadonly=it,e.isRef=pt,e.isRuntimeOnly=()=>!Ir,e.isVNode=pr,e.markRaw=at,e.mergeDefaults=function(e,t){for(const n in t){const o=e[n];o?o.default=t[n]:null===o&&(e[n]={default:t[n]})}return e},e.mergeProps=Sr,e.nextTick=Ht,e.onActivated=Un,e.onBeforeMount=Jn,e.onBeforeUnmount=Yn,e.onBeforeUpdate=Qn,e.onDeactivated=Hn,e.onErrorCaptured=ro,e.onMounted=Zn,e.onRenderTracked=oo,e.onRenderTriggered=no,e.onServerPrefetch=to,e.onUnmounted=eo,e.onUpdated=Xn,e.openBlock=ir,e.popScopeId=function(){tn=null},e.provide=vn,e.proxyRefs=vt,e.pushScopeId=function(e){tn=e},e.queuePostFlushCb=Kt,e.reactive=tt,e.readonly=ot,e.ref=ft,e.registerRuntimeCompiler=Rr,e.render=(...e)=>{ci().render(...e)},e.renderList=function(e,t){let n;if(T(e)||A(e)){n=new Array(e.length);for(let o=0,r=e.length;onull==e?"":O(e)?JSON.stringify(e,h,2):String(e),e.toHandlerKey=K,e.toHandlers=function(e){const t={};for(const n in e)t[K(n)]=e[n];return t},e.toRaw=ct,e.toRef=_t,e.toRefs=function(e){const t=T(e)?new Array(e.length):{};for(const n in e)t[n]=_t(e,n);return t},e.transformVNodeArgs=function(e){},e.triggerRef=function(e){pe(ct(e),"set","value",void 0)},e.unref=mt,e.useAttrs=function(){return qr().attrs},e.useContext=function(){return qr()},e.useCssModule=function(e="$style"){return m},e.useCssVars=function(e){const t=Ar();if(!t)return;const n=()=>ms(t.subTree,e(t.proxy));Zn((()=>bn(n,{flush:"post"}))),Xn(n)},e.useSSRContext=()=>{},e.useSlots=function(){return qr().slots},e.useTransitionState=Tn,e.vModelCheckbox=zs,e.vModelDynamic=Xs,e.vModelRadio=Gs,e.vModelSelect=qs,e.vModelText=Ws,e.vShow=oi,e.version=Qr,e.warn=Ct,e.watch=xn,e.watchEffect=bn,e.withAsyncContext=function(e){const t=Ar();let n=e();return Mr(null),I(n)&&(n=n.catch((e=>{throw Mr(t),e}))),[n,()=>Mr(t)]},e.withCtx=on,e.withDefaults=function(e,t){return null},e.withDirectives=function(e,t){if(null===en)return e;const n=en.proxy,o=e.dirs||(e.dirs=[]);for(let r=0;rn=>{if(!("key"in n))return;const o=W(n.key);return t.some((e=>e===o||ni[e]===o))?e(n):void 0},e.withModifiers=(e,t)=>(n,...o)=>{for(let e=0;eon,Object.defineProperty(e,"__esModule",{value:!0}),e}({}); diff --git a/hybrid/html/rtc/adapter-latest.js b/hybrid/html/rtc/adapter-latest.js new file mode 100644 index 0000000..c9e2741 --- /dev/null +++ b/hybrid/html/rtc/adapter-latest.js @@ -0,0 +1,3480 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.adapter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 0 && arguments[0] !== undefined ? arguments[0] : {}, + window = _ref.window; + + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { + shimChrome: true, + shimFirefox: true, + shimSafari: true + }; + + // Utils. + var logging = utils.log; + var browserDetails = utils.detectBrowser(window); + + var adapter = { + browserDetails: browserDetails, + commonShim: commonShim, + extractVersion: utils.extractVersion, + disableLog: utils.disableLog, + disableWarnings: utils.disableWarnings, + // Expose sdp as a convenience. For production apps include directly. + sdp: sdp + }; + + // Shim browser if found. + switch (browserDetails.browser) { + case 'chrome': + if (!chromeShim || !chromeShim.shimPeerConnection || !options.shimChrome) { + logging('Chrome shim is not included in this adapter release.'); + return adapter; + } + if (browserDetails.version === null) { + logging('Chrome shim can not determine version, not shimming.'); + return adapter; + } + logging('adapter.js shimming chrome.'); + // Export to the adapter global object visible in the browser. + adapter.browserShim = chromeShim; + + // Must be called before shimPeerConnection. + commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails); + commonShim.shimParameterlessSetLocalDescription(window, browserDetails); + + chromeShim.shimGetUserMedia(window, browserDetails); + chromeShim.shimMediaStream(window, browserDetails); + chromeShim.shimPeerConnection(window, browserDetails); + chromeShim.shimOnTrack(window, browserDetails); + chromeShim.shimAddTrackRemoveTrack(window, browserDetails); + chromeShim.shimGetSendersWithDtmf(window, browserDetails); + chromeShim.shimGetStats(window, browserDetails); + chromeShim.shimSenderReceiverGetStats(window, browserDetails); + chromeShim.fixNegotiationNeeded(window, browserDetails); + + commonShim.shimRTCIceCandidate(window, browserDetails); + commonShim.shimConnectionState(window, browserDetails); + commonShim.shimMaxMessageSize(window, browserDetails); + commonShim.shimSendThrowTypeError(window, browserDetails); + commonShim.removeExtmapAllowMixed(window, browserDetails); + break; + case 'firefox': + if (!firefoxShim || !firefoxShim.shimPeerConnection || !options.shimFirefox) { + logging('Firefox shim is not included in this adapter release.'); + return adapter; + } + logging('adapter.js shimming firefox.'); + // Export to the adapter global object visible in the browser. + adapter.browserShim = firefoxShim; + + // Must be called before shimPeerConnection. + commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails); + commonShim.shimParameterlessSetLocalDescription(window, browserDetails); + + firefoxShim.shimGetUserMedia(window, browserDetails); + firefoxShim.shimPeerConnection(window, browserDetails); + firefoxShim.shimOnTrack(window, browserDetails); + firefoxShim.shimRemoveStream(window, browserDetails); + firefoxShim.shimSenderGetStats(window, browserDetails); + firefoxShim.shimReceiverGetStats(window, browserDetails); + firefoxShim.shimRTCDataChannel(window, browserDetails); + firefoxShim.shimAddTransceiver(window, browserDetails); + firefoxShim.shimGetParameters(window, browserDetails); + firefoxShim.shimCreateOffer(window, browserDetails); + firefoxShim.shimCreateAnswer(window, browserDetails); + + commonShim.shimRTCIceCandidate(window, browserDetails); + commonShim.shimConnectionState(window, browserDetails); + commonShim.shimMaxMessageSize(window, browserDetails); + commonShim.shimSendThrowTypeError(window, browserDetails); + break; + case 'safari': + if (!safariShim || !options.shimSafari) { + logging('Safari shim is not included in this adapter release.'); + return adapter; + } + logging('adapter.js shimming safari.'); + // Export to the adapter global object visible in the browser. + adapter.browserShim = safariShim; + + // Must be called before shimCallbackAPI. + commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails); + commonShim.shimParameterlessSetLocalDescription(window, browserDetails); + + safariShim.shimRTCIceServerUrls(window, browserDetails); + safariShim.shimCreateOfferLegacy(window, browserDetails); + safariShim.shimCallbacksAPI(window, browserDetails); + safariShim.shimLocalStreamsAPI(window, browserDetails); + safariShim.shimRemoteStreamsAPI(window, browserDetails); + safariShim.shimTrackEventTransceiver(window, browserDetails); + safariShim.shimGetUserMedia(window, browserDetails); + safariShim.shimAudioContext(window, browserDetails); + + commonShim.shimRTCIceCandidate(window, browserDetails); + commonShim.shimMaxMessageSize(window, browserDetails); + commonShim.shimSendThrowTypeError(window, browserDetails); + commonShim.removeExtmapAllowMixed(window, browserDetails); + break; + default: + logging('Unsupported browser!'); + break; + } + + return adapter; +} + +// Browser shims. + +},{"./chrome/chrome_shim":3,"./common_shim":6,"./firefox/firefox_shim":7,"./safari/safari_shim":10,"./utils":11,"sdp":12}],3:[function(require,module,exports){ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _getusermedia = require('./getusermedia'); + +Object.defineProperty(exports, 'shimGetUserMedia', { + enumerable: true, + get: function get() { + return _getusermedia.shimGetUserMedia; + } +}); + +var _getdisplaymedia = require('./getdisplaymedia'); + +Object.defineProperty(exports, 'shimGetDisplayMedia', { + enumerable: true, + get: function get() { + return _getdisplaymedia.shimGetDisplayMedia; + } +}); +exports.shimMediaStream = shimMediaStream; +exports.shimOnTrack = shimOnTrack; +exports.shimGetSendersWithDtmf = shimGetSendersWithDtmf; +exports.shimGetStats = shimGetStats; +exports.shimSenderReceiverGetStats = shimSenderReceiverGetStats; +exports.shimAddTrackRemoveTrackWithNative = shimAddTrackRemoveTrackWithNative; +exports.shimAddTrackRemoveTrack = shimAddTrackRemoveTrack; +exports.shimPeerConnection = shimPeerConnection; +exports.fixNegotiationNeeded = fixNegotiationNeeded; + +var _utils = require('../utils.js'); + +var utils = _interopRequireWildcard(_utils); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function shimMediaStream(window) { + window.MediaStream = window.MediaStream || window.webkitMediaStream; +} + +function shimOnTrack(window) { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) { + Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', { + get: function get() { + return this._ontrack; + }, + set: function set(f) { + if (this._ontrack) { + this.removeEventListener('track', this._ontrack); + } + this.addEventListener('track', this._ontrack = f); + }, + + enumerable: true, + configurable: true + }); + var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() { + var _this = this; + + if (!this._ontrackpoly) { + this._ontrackpoly = function (e) { + // onaddstream does not fire when a track is added to an existing + // stream. But stream.onaddtrack is implemented so we use that. + e.stream.addEventListener('addtrack', function (te) { + var receiver = void 0; + if (window.RTCPeerConnection.prototype.getReceivers) { + receiver = _this.getReceivers().find(function (r) { + return r.track && r.track.id === te.track.id; + }); + } else { + receiver = { track: te.track }; + } + + var event = new Event('track'); + event.track = te.track; + event.receiver = receiver; + event.transceiver = { receiver: receiver }; + event.streams = [e.stream]; + _this.dispatchEvent(event); + }); + e.stream.getTracks().forEach(function (track) { + var receiver = void 0; + if (window.RTCPeerConnection.prototype.getReceivers) { + receiver = _this.getReceivers().find(function (r) { + return r.track && r.track.id === track.id; + }); + } else { + receiver = { track: track }; + } + var event = new Event('track'); + event.track = track; + event.receiver = receiver; + event.transceiver = { receiver: receiver }; + event.streams = [e.stream]; + _this.dispatchEvent(event); + }); + }; + this.addEventListener('addstream', this._ontrackpoly); + } + return origSetRemoteDescription.apply(this, arguments); + }; + } else { + // even if RTCRtpTransceiver is in window, it is only used and + // emitted in unified-plan. Unfortunately this means we need + // to unconditionally wrap the event. + utils.wrapPeerConnectionEvent(window, 'track', function (e) { + if (!e.transceiver) { + Object.defineProperty(e, 'transceiver', { value: { receiver: e.receiver } }); + } + return e; + }); + } +} + +function shimGetSendersWithDtmf(window) { + // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack. + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection && !('getSenders' in window.RTCPeerConnection.prototype) && 'createDTMFSender' in window.RTCPeerConnection.prototype) { + var shimSenderWithDtmf = function shimSenderWithDtmf(pc, track) { + return { + track: track, + get dtmf() { + if (this._dtmf === undefined) { + if (track.kind === 'audio') { + this._dtmf = pc.createDTMFSender(track); + } else { + this._dtmf = null; + } + } + return this._dtmf; + }, + _pc: pc + }; + }; + + // augment addTrack when getSenders is not available. + if (!window.RTCPeerConnection.prototype.getSenders) { + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + this._senders = this._senders || []; + return this._senders.slice(); // return a copy of the internal state. + }; + var origAddTrack = window.RTCPeerConnection.prototype.addTrack; + window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) { + var sender = origAddTrack.apply(this, arguments); + if (!sender) { + sender = shimSenderWithDtmf(this, track); + this._senders.push(sender); + } + return sender; + }; + + var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack; + window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { + origRemoveTrack.apply(this, arguments); + var idx = this._senders.indexOf(sender); + if (idx !== -1) { + this._senders.splice(idx, 1); + } + }; + } + var origAddStream = window.RTCPeerConnection.prototype.addStream; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + var _this2 = this; + + this._senders = this._senders || []; + origAddStream.apply(this, [stream]); + stream.getTracks().forEach(function (track) { + _this2._senders.push(shimSenderWithDtmf(_this2, track)); + }); + }; + + var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; + window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { + var _this3 = this; + + this._senders = this._senders || []; + origRemoveStream.apply(this, [stream]); + + stream.getTracks().forEach(function (track) { + var sender = _this3._senders.find(function (s) { + return s.track === track; + }); + if (sender) { + // remove sender + _this3._senders.splice(_this3._senders.indexOf(sender), 1); + } + }); + }; + } else if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection && 'getSenders' in window.RTCPeerConnection.prototype && 'createDTMFSender' in window.RTCPeerConnection.prototype && window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) { + var origGetSenders = window.RTCPeerConnection.prototype.getSenders; + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + var _this4 = this; + + var senders = origGetSenders.apply(this, []); + senders.forEach(function (sender) { + return sender._pc = _this4; + }); + return senders; + }; + + Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', { + get: function get() { + if (this._dtmf === undefined) { + if (this.track.kind === 'audio') { + this._dtmf = this._pc.createDTMFSender(this.track); + } else { + this._dtmf = null; + } + } + return this._dtmf; + } + }); + } +} + +function shimGetStats(window) { + if (!window.RTCPeerConnection) { + return; + } + + var origGetStats = window.RTCPeerConnection.prototype.getStats; + window.RTCPeerConnection.prototype.getStats = function getStats() { + var _this5 = this; + + var _arguments = Array.prototype.slice.call(arguments), + selector = _arguments[0], + onSucc = _arguments[1], + onErr = _arguments[2]; + + // If selector is a function then we are in the old style stats so just + // pass back the original getStats format to avoid breaking old users. + + + if (arguments.length > 0 && typeof selector === 'function') { + return origGetStats.apply(this, arguments); + } + + // When spec-style getStats is supported, return those when called with + // either no arguments or the selector argument is null. + if (origGetStats.length === 0 && (arguments.length === 0 || typeof selector !== 'function')) { + return origGetStats.apply(this, []); + } + + var fixChromeStats_ = function fixChromeStats_(response) { + var standardReport = {}; + var reports = response.result(); + reports.forEach(function (report) { + var standardStats = { + id: report.id, + timestamp: report.timestamp, + type: { + localcandidate: 'local-candidate', + remotecandidate: 'remote-candidate' + }[report.type] || report.type + }; + report.names().forEach(function (name) { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + + return standardReport; + }; + + // shim getStats with maplike support + var makeMapStats = function makeMapStats(stats) { + return new Map(Object.keys(stats).map(function (key) { + return [key, stats[key]]; + })); + }; + + if (arguments.length >= 2) { + var successCallbackWrapper_ = function successCallbackWrapper_(response) { + onSucc(makeMapStats(fixChromeStats_(response))); + }; + + return origGetStats.apply(this, [successCallbackWrapper_, selector]); + } + + // promise-support + return new Promise(function (resolve, reject) { + origGetStats.apply(_this5, [function (response) { + resolve(makeMapStats(fixChromeStats_(response))); + }, reject]); + }).then(onSucc, onErr); + }; +} + +function shimSenderReceiverGetStats(window) { + if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) { + return; + } + + // shim sender stats. + if (!('getStats' in window.RTCRtpSender.prototype)) { + var origGetSenders = window.RTCPeerConnection.prototype.getSenders; + if (origGetSenders) { + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + var _this6 = this; + + var senders = origGetSenders.apply(this, []); + senders.forEach(function (sender) { + return sender._pc = _this6; + }); + return senders; + }; + } + + var origAddTrack = window.RTCPeerConnection.prototype.addTrack; + if (origAddTrack) { + window.RTCPeerConnection.prototype.addTrack = function addTrack() { + var sender = origAddTrack.apply(this, arguments); + sender._pc = this; + return sender; + }; + } + window.RTCRtpSender.prototype.getStats = function getStats() { + var sender = this; + return this._pc.getStats().then(function (result) { + return ( + /* Note: this will include stats of all senders that + * send a track with the same id as sender.track as + * it is not possible to identify the RTCRtpSender. + */ + utils.filterStats(result, sender.track, true) + ); + }); + }; + } + + // shim receiver stats. + if (!('getStats' in window.RTCRtpReceiver.prototype)) { + var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers; + if (origGetReceivers) { + window.RTCPeerConnection.prototype.getReceivers = function getReceivers() { + var _this7 = this; + + var receivers = origGetReceivers.apply(this, []); + receivers.forEach(function (receiver) { + return receiver._pc = _this7; + }); + return receivers; + }; + } + utils.wrapPeerConnectionEvent(window, 'track', function (e) { + e.receiver._pc = e.srcElement; + return e; + }); + window.RTCRtpReceiver.prototype.getStats = function getStats() { + var receiver = this; + return this._pc.getStats().then(function (result) { + return utils.filterStats(result, receiver.track, false); + }); + }; + } + + if (!('getStats' in window.RTCRtpSender.prototype && 'getStats' in window.RTCRtpReceiver.prototype)) { + return; + } + + // shim RTCPeerConnection.getStats(track). + var origGetStats = window.RTCPeerConnection.prototype.getStats; + window.RTCPeerConnection.prototype.getStats = function getStats() { + if (arguments.length > 0 && arguments[0] instanceof window.MediaStreamTrack) { + var track = arguments[0]; + var sender = void 0; + var receiver = void 0; + var err = void 0; + this.getSenders().forEach(function (s) { + if (s.track === track) { + if (sender) { + err = true; + } else { + sender = s; + } + } + }); + this.getReceivers().forEach(function (r) { + if (r.track === track) { + if (receiver) { + err = true; + } else { + receiver = r; + } + } + return r.track === track; + }); + if (err || sender && receiver) { + return Promise.reject(new DOMException('There are more than one sender or receiver for the track.', 'InvalidAccessError')); + } else if (sender) { + return sender.getStats(); + } else if (receiver) { + return receiver.getStats(); + } + return Promise.reject(new DOMException('There is no sender or receiver for the track.', 'InvalidAccessError')); + } + return origGetStats.apply(this, arguments); + }; +} + +function shimAddTrackRemoveTrackWithNative(window) { + // shim addTrack/removeTrack with native variants in order to make + // the interactions with legacy getLocalStreams behave as in other browsers. + // Keeps a mapping stream.id => [stream, rtpsenders...] + window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() { + var _this8 = this; + + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + return Object.keys(this._shimmedLocalStreams).map(function (streamId) { + return _this8._shimmedLocalStreams[streamId][0]; + }); + }; + + var origAddTrack = window.RTCPeerConnection.prototype.addTrack; + window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) { + if (!stream) { + return origAddTrack.apply(this, arguments); + } + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + + var sender = origAddTrack.apply(this, arguments); + if (!this._shimmedLocalStreams[stream.id]) { + this._shimmedLocalStreams[stream.id] = [stream, sender]; + } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) { + this._shimmedLocalStreams[stream.id].push(sender); + } + return sender; + }; + + var origAddStream = window.RTCPeerConnection.prototype.addStream; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + var _this9 = this; + + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + + stream.getTracks().forEach(function (track) { + var alreadyExists = _this9.getSenders().find(function (s) { + return s.track === track; + }); + if (alreadyExists) { + throw new DOMException('Track already exists.', 'InvalidAccessError'); + } + }); + var existingSenders = this.getSenders(); + origAddStream.apply(this, arguments); + var newSenders = this.getSenders().filter(function (newSender) { + return existingSenders.indexOf(newSender) === -1; + }); + this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders); + }; + + var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; + window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + delete this._shimmedLocalStreams[stream.id]; + return origRemoveStream.apply(this, arguments); + }; + + var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack; + window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { + var _this10 = this; + + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + if (sender) { + Object.keys(this._shimmedLocalStreams).forEach(function (streamId) { + var idx = _this10._shimmedLocalStreams[streamId].indexOf(sender); + if (idx !== -1) { + _this10._shimmedLocalStreams[streamId].splice(idx, 1); + } + if (_this10._shimmedLocalStreams[streamId].length === 1) { + delete _this10._shimmedLocalStreams[streamId]; + } + }); + } + return origRemoveTrack.apply(this, arguments); + }; +} + +function shimAddTrackRemoveTrack(window, browserDetails) { + if (!window.RTCPeerConnection) { + return; + } + // shim addTrack and removeTrack. + if (window.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) { + return shimAddTrackRemoveTrackWithNative(window); + } + + // also shim pc.getLocalStreams when addTrack is shimmed + // to return the original streams. + var origGetLocalStreams = window.RTCPeerConnection.prototype.getLocalStreams; + window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() { + var _this11 = this; + + var nativeStreams = origGetLocalStreams.apply(this); + this._reverseStreams = this._reverseStreams || {}; + return nativeStreams.map(function (stream) { + return _this11._reverseStreams[stream.id]; + }); + }; + + var origAddStream = window.RTCPeerConnection.prototype.addStream; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + var _this12 = this; + + this._streams = this._streams || {}; + this._reverseStreams = this._reverseStreams || {}; + + stream.getTracks().forEach(function (track) { + var alreadyExists = _this12.getSenders().find(function (s) { + return s.track === track; + }); + if (alreadyExists) { + throw new DOMException('Track already exists.', 'InvalidAccessError'); + } + }); + // Add identity mapping for consistency with addTrack. + // Unless this is being used with a stream from addTrack. + if (!this._reverseStreams[stream.id]) { + var newStream = new window.MediaStream(stream.getTracks()); + this._streams[stream.id] = newStream; + this._reverseStreams[newStream.id] = stream; + stream = newStream; + } + origAddStream.apply(this, [stream]); + }; + + var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; + window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { + this._streams = this._streams || {}; + this._reverseStreams = this._reverseStreams || {}; + + origRemoveStream.apply(this, [this._streams[stream.id] || stream]); + delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id]; + delete this._streams[stream.id]; + }; + + window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) { + var _this13 = this; + + if (this.signalingState === 'closed') { + throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError'); + } + var streams = [].slice.call(arguments, 1); + if (streams.length !== 1 || !streams[0].getTracks().find(function (t) { + return t === track; + })) { + // this is not fully correct but all we can manage without + // [[associated MediaStreams]] internal slot. + throw new DOMException('The adapter.js addTrack polyfill only supports a single ' + ' stream which is associated with the specified track.', 'NotSupportedError'); + } + + var alreadyExists = this.getSenders().find(function (s) { + return s.track === track; + }); + if (alreadyExists) { + throw new DOMException('Track already exists.', 'InvalidAccessError'); + } + + this._streams = this._streams || {}; + this._reverseStreams = this._reverseStreams || {}; + var oldStream = this._streams[stream.id]; + if (oldStream) { + // this is using odd Chrome behaviour, use with caution: + // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815 + // Note: we rely on the high-level addTrack/dtmf shim to + // create the sender with a dtmf sender. + oldStream.addTrack(track); + + // Trigger ONN async. + Promise.resolve().then(function () { + _this13.dispatchEvent(new Event('negotiationneeded')); + }); + } else { + var newStream = new window.MediaStream([track]); + this._streams[stream.id] = newStream; + this._reverseStreams[newStream.id] = stream; + this.addStream(newStream); + } + return this.getSenders().find(function (s) { + return s.track === track; + }); + }; + + // replace the internal stream id with the external one and + // vice versa. + function replaceInternalStreamId(pc, description) { + var sdp = description.sdp; + Object.keys(pc._reverseStreams || []).forEach(function (internalId) { + var externalStream = pc._reverseStreams[internalId]; + var internalStream = pc._streams[externalStream.id]; + sdp = sdp.replace(new RegExp(internalStream.id, 'g'), externalStream.id); + }); + return new RTCSessionDescription({ + type: description.type, + sdp: sdp + }); + } + function replaceExternalStreamId(pc, description) { + var sdp = description.sdp; + Object.keys(pc._reverseStreams || []).forEach(function (internalId) { + var externalStream = pc._reverseStreams[internalId]; + var internalStream = pc._streams[externalStream.id]; + sdp = sdp.replace(new RegExp(externalStream.id, 'g'), internalStream.id); + }); + return new RTCSessionDescription({ + type: description.type, + sdp: sdp + }); + } + ['createOffer', 'createAnswer'].forEach(function (method) { + var nativeMethod = window.RTCPeerConnection.prototype[method]; + var methodObj = _defineProperty({}, method, function () { + var _this14 = this; + + var args = arguments; + var isLegacyCall = arguments.length && typeof arguments[0] === 'function'; + if (isLegacyCall) { + return nativeMethod.apply(this, [function (description) { + var desc = replaceInternalStreamId(_this14, description); + args[0].apply(null, [desc]); + }, function (err) { + if (args[1]) { + args[1].apply(null, err); + } + }, arguments[2]]); + } + return nativeMethod.apply(this, arguments).then(function (description) { + return replaceInternalStreamId(_this14, description); + }); + }); + window.RTCPeerConnection.prototype[method] = methodObj[method]; + }); + + var origSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription; + window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() { + if (!arguments.length || !arguments[0].type) { + return origSetLocalDescription.apply(this, arguments); + } + arguments[0] = replaceExternalStreamId(this, arguments[0]); + return origSetLocalDescription.apply(this, arguments); + }; + + // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier + + var origLocalDescription = Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype, 'localDescription'); + Object.defineProperty(window.RTCPeerConnection.prototype, 'localDescription', { + get: function get() { + var description = origLocalDescription.get.apply(this); + if (description.type === '') { + return description; + } + return replaceInternalStreamId(this, description); + } + }); + + window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { + var _this15 = this; + + if (this.signalingState === 'closed') { + throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError'); + } + // We can not yet check for sender instanceof RTCRtpSender + // since we shim RTPSender. So we check if sender._pc is set. + if (!sender._pc) { + throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.', 'TypeError'); + } + var isLocal = sender._pc === this; + if (!isLocal) { + throw new DOMException('Sender was not created by this connection.', 'InvalidAccessError'); + } + + // Search for the native stream the senders track belongs to. + this._streams = this._streams || {}; + var stream = void 0; + Object.keys(this._streams).forEach(function (streamid) { + var hasTrack = _this15._streams[streamid].getTracks().find(function (track) { + return sender.track === track; + }); + if (hasTrack) { + stream = _this15._streams[streamid]; + } + }); + + if (stream) { + if (stream.getTracks().length === 1) { + // if this is the last track of the stream, remove the stream. This + // takes care of any shimmed _senders. + this.removeStream(this._reverseStreams[stream.id]); + } else { + // relying on the same odd chrome behaviour as above. + stream.removeTrack(sender.track); + } + this.dispatchEvent(new Event('negotiationneeded')); + } + }; +} + +function shimPeerConnection(window, browserDetails) { + if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) { + // very basic support for old versions. + window.RTCPeerConnection = window.webkitRTCPeerConnection; + } + if (!window.RTCPeerConnection) { + return; + } + + // shim implicit creation of RTCSessionDescription/RTCIceCandidate + if (browserDetails.version < 53) { + ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) { + var nativeMethod = window.RTCPeerConnection.prototype[method]; + var methodObj = _defineProperty({}, method, function () { + arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]); + return nativeMethod.apply(this, arguments); + }); + window.RTCPeerConnection.prototype[method] = methodObj[method]; + }); + } +} + +// Attempt to fix ONN in plan-b mode. +function fixNegotiationNeeded(window, browserDetails) { + utils.wrapPeerConnectionEvent(window, 'negotiationneeded', function (e) { + var pc = e.target; + if (browserDetails.version < 72 || pc.getConfiguration && pc.getConfiguration().sdpSemantics === 'plan-b') { + if (pc.signalingState !== 'stable') { + return; + } + } + return e; + }); +} + +},{"../utils.js":11,"./getdisplaymedia":4,"./getusermedia":5}],4:[function(require,module,exports){ +/* + * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.shimGetDisplayMedia = shimGetDisplayMedia; +function shimGetDisplayMedia(window, getSourceId) { + if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) { + return; + } + if (!window.navigator.mediaDevices) { + return; + } + // getSourceId is a function that returns a promise resolving with + // the sourceId of the screen/window/tab to be shared. + if (typeof getSourceId !== 'function') { + console.error('shimGetDisplayMedia: getSourceId argument is not ' + 'a function'); + return; + } + window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) { + return getSourceId(constraints).then(function (sourceId) { + var widthSpecified = constraints.video && constraints.video.width; + var heightSpecified = constraints.video && constraints.video.height; + var frameRateSpecified = constraints.video && constraints.video.frameRate; + constraints.video = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: sourceId, + maxFrameRate: frameRateSpecified || 3 + } + }; + if (widthSpecified) { + constraints.video.mandatory.maxWidth = widthSpecified; + } + if (heightSpecified) { + constraints.video.mandatory.maxHeight = heightSpecified; + } + return window.navigator.mediaDevices.getUserMedia(constraints); + }); + }; +} + +},{}],5:[function(require,module,exports){ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.shimGetUserMedia = shimGetUserMedia; + +var _utils = require('../utils.js'); + +var utils = _interopRequireWildcard(_utils); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var logging = utils.log; + +function shimGetUserMedia(window, browserDetails) { + var navigator = window && window.navigator; + + if (!navigator.mediaDevices) { + return; + } + + var constraintsToChrome_ = function constraintsToChrome_(c) { + if ((typeof c === 'undefined' ? 'undefined' : _typeof(c)) !== 'object' || c.mandatory || c.optional) { + return c; + } + var cc = {}; + Object.keys(c).forEach(function (key) { + if (key === 'require' || key === 'advanced' || key === 'mediaSource') { + return; + } + var r = _typeof(c[key]) === 'object' ? c[key] : { ideal: c[key] }; + if (r.exact !== undefined && typeof r.exact === 'number') { + r.min = r.max = r.exact; + } + var oldname_ = function oldname_(prefix, name) { + if (prefix) { + return prefix + name.charAt(0).toUpperCase() + name.slice(1); + } + return name === 'deviceId' ? 'sourceId' : name; + }; + if (r.ideal !== undefined) { + cc.optional = cc.optional || []; + var oc = {}; + if (typeof r.ideal === 'number') { + oc[oldname_('min', key)] = r.ideal; + cc.optional.push(oc); + oc = {}; + oc[oldname_('max', key)] = r.ideal; + cc.optional.push(oc); + } else { + oc[oldname_('', key)] = r.ideal; + cc.optional.push(oc); + } + } + if (r.exact !== undefined && typeof r.exact !== 'number') { + cc.mandatory = cc.mandatory || {}; + cc.mandatory[oldname_('', key)] = r.exact; + } else { + ['min', 'max'].forEach(function (mix) { + if (r[mix] !== undefined) { + cc.mandatory = cc.mandatory || {}; + cc.mandatory[oldname_(mix, key)] = r[mix]; + } + }); + } + }); + if (c.advanced) { + cc.optional = (cc.optional || []).concat(c.advanced); + } + return cc; + }; + + var shimConstraints_ = function shimConstraints_(constraints, func) { + if (browserDetails.version >= 61) { + return func(constraints); + } + constraints = JSON.parse(JSON.stringify(constraints)); + if (constraints && _typeof(constraints.audio) === 'object') { + var remap = function remap(obj, a, b) { + if (a in obj && !(b in obj)) { + obj[b] = obj[a]; + delete obj[a]; + } + }; + constraints = JSON.parse(JSON.stringify(constraints)); + remap(constraints.audio, 'autoGainControl', 'googAutoGainControl'); + remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression'); + constraints.audio = constraintsToChrome_(constraints.audio); + } + if (constraints && _typeof(constraints.video) === 'object') { + // Shim facingMode for mobile & surface pro. + var face = constraints.video.facingMode; + face = face && ((typeof face === 'undefined' ? 'undefined' : _typeof(face)) === 'object' ? face : { ideal: face }); + var getSupportedFacingModeLies = browserDetails.version < 66; + + if (face && (face.exact === 'user' || face.exact === 'environment' || face.ideal === 'user' || face.ideal === 'environment') && !(navigator.mediaDevices.getSupportedConstraints && navigator.mediaDevices.getSupportedConstraints().facingMode && !getSupportedFacingModeLies)) { + delete constraints.video.facingMode; + var matches = void 0; + if (face.exact === 'environment' || face.ideal === 'environment') { + matches = ['back', 'rear']; + } else if (face.exact === 'user' || face.ideal === 'user') { + matches = ['front']; + } + if (matches) { + // Look for matches in label, or use last cam for back (typical). + return navigator.mediaDevices.enumerateDevices().then(function (devices) { + devices = devices.filter(function (d) { + return d.kind === 'videoinput'; + }); + var dev = devices.find(function (d) { + return matches.some(function (match) { + return d.label.toLowerCase().includes(match); + }); + }); + if (!dev && devices.length && matches.includes('back')) { + dev = devices[devices.length - 1]; // more likely the back cam + } + if (dev) { + constraints.video.deviceId = face.exact ? { exact: dev.deviceId } : { ideal: dev.deviceId }; + } + constraints.video = constraintsToChrome_(constraints.video); + logging('chrome: ' + JSON.stringify(constraints)); + return func(constraints); + }); + } + } + constraints.video = constraintsToChrome_(constraints.video); + } + logging('chrome: ' + JSON.stringify(constraints)); + return func(constraints); + }; + + var shimError_ = function shimError_(e) { + if (browserDetails.version >= 64) { + return e; + } + return { + name: { + PermissionDeniedError: 'NotAllowedError', + PermissionDismissedError: 'NotAllowedError', + InvalidStateError: 'NotAllowedError', + DevicesNotFoundError: 'NotFoundError', + ConstraintNotSatisfiedError: 'OverconstrainedError', + TrackStartError: 'NotReadableError', + MediaDeviceFailedDueToShutdown: 'NotAllowedError', + MediaDeviceKillSwitchOn: 'NotAllowedError', + TabCaptureError: 'AbortError', + ScreenCaptureError: 'AbortError', + DeviceCaptureError: 'AbortError' + }[e.name] || e.name, + message: e.message, + constraint: e.constraint || e.constraintName, + toString: function toString() { + return this.name + (this.message && ': ') + this.message; + } + }; + }; + + var getUserMedia_ = function getUserMedia_(constraints, onSuccess, onError) { + shimConstraints_(constraints, function (c) { + navigator.webkitGetUserMedia(c, onSuccess, function (e) { + if (onError) { + onError(shimError_(e)); + } + }); + }); + }; + navigator.getUserMedia = getUserMedia_.bind(navigator); + + // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia + // function which returns a Promise, it does not accept spec-style + // constraints. + if (navigator.mediaDevices.getUserMedia) { + var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); + navigator.mediaDevices.getUserMedia = function (cs) { + return shimConstraints_(cs, function (c) { + return origGetUserMedia(c).then(function (stream) { + if (c.audio && !stream.getAudioTracks().length || c.video && !stream.getVideoTracks().length) { + stream.getTracks().forEach(function (track) { + track.stop(); + }); + throw new DOMException('', 'NotFoundError'); + } + return stream; + }, function (e) { + return Promise.reject(shimError_(e)); + }); + }); + }; + } +} + +},{"../utils.js":11}],6:[function(require,module,exports){ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.shimRTCIceCandidate = shimRTCIceCandidate; +exports.shimMaxMessageSize = shimMaxMessageSize; +exports.shimSendThrowTypeError = shimSendThrowTypeError; +exports.shimConnectionState = shimConnectionState; +exports.removeExtmapAllowMixed = removeExtmapAllowMixed; +exports.shimAddIceCandidateNullOrEmpty = shimAddIceCandidateNullOrEmpty; +exports.shimParameterlessSetLocalDescription = shimParameterlessSetLocalDescription; + +var _sdp = require('sdp'); + +var _sdp2 = _interopRequireDefault(_sdp); + +var _utils = require('./utils'); + +var utils = _interopRequireWildcard(_utils); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function shimRTCIceCandidate(window) { + // foundation is arbitrarily chosen as an indicator for full support for + // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface + if (!window.RTCIceCandidate || window.RTCIceCandidate && 'foundation' in window.RTCIceCandidate.prototype) { + return; + } + + var NativeRTCIceCandidate = window.RTCIceCandidate; + window.RTCIceCandidate = function RTCIceCandidate(args) { + // Remove the a= which shouldn't be part of the candidate string. + if ((typeof args === 'undefined' ? 'undefined' : _typeof(args)) === 'object' && args.candidate && args.candidate.indexOf('a=') === 0) { + args = JSON.parse(JSON.stringify(args)); + args.candidate = args.candidate.substr(2); + } + + if (args.candidate && args.candidate.length) { + // Augment the native candidate with the parsed fields. + var nativeCandidate = new NativeRTCIceCandidate(args); + var parsedCandidate = _sdp2.default.parseCandidate(args.candidate); + var augmentedCandidate = Object.assign(nativeCandidate, parsedCandidate); + + // Add a serializer that does not serialize the extra attributes. + augmentedCandidate.toJSON = function toJSON() { + return { + candidate: augmentedCandidate.candidate, + sdpMid: augmentedCandidate.sdpMid, + sdpMLineIndex: augmentedCandidate.sdpMLineIndex, + usernameFragment: augmentedCandidate.usernameFragment + }; + }; + return augmentedCandidate; + } + return new NativeRTCIceCandidate(args); + }; + window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype; + + // Hook up the augmented candidate in onicecandidate and + // addEventListener('icecandidate', ...) + utils.wrapPeerConnectionEvent(window, 'icecandidate', function (e) { + if (e.candidate) { + Object.defineProperty(e, 'candidate', { + value: new window.RTCIceCandidate(e.candidate), + writable: 'false' + }); + } + return e; + }); +} + +function shimMaxMessageSize(window, browserDetails) { + if (!window.RTCPeerConnection) { + return; + } + + if (!('sctp' in window.RTCPeerConnection.prototype)) { + Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', { + get: function get() { + return typeof this._sctp === 'undefined' ? null : this._sctp; + } + }); + } + + var sctpInDescription = function sctpInDescription(description) { + if (!description || !description.sdp) { + return false; + } + var sections = _sdp2.default.splitSections(description.sdp); + sections.shift(); + return sections.some(function (mediaSection) { + var mLine = _sdp2.default.parseMLine(mediaSection); + return mLine && mLine.kind === 'application' && mLine.protocol.indexOf('SCTP') !== -1; + }); + }; + + var getRemoteFirefoxVersion = function getRemoteFirefoxVersion(description) { + // TODO: Is there a better solution for detecting Firefox? + var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/); + if (match === null || match.length < 2) { + return -1; + } + var version = parseInt(match[1], 10); + // Test for NaN (yes, this is ugly) + return version !== version ? -1 : version; + }; + + var getCanSendMaxMessageSize = function getCanSendMaxMessageSize(remoteIsFirefox) { + // Every implementation we know can send at least 64 KiB. + // Note: Although Chrome is technically able to send up to 256 KiB, the + // data does not reach the other peer reliably. + // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419 + var canSendMaxMessageSize = 65536; + if (browserDetails.browser === 'firefox') { + if (browserDetails.version < 57) { + if (remoteIsFirefox === -1) { + // FF < 57 will send in 16 KiB chunks using the deprecated PPID + // fragmentation. + canSendMaxMessageSize = 16384; + } else { + // However, other FF (and RAWRTC) can reassemble PPID-fragmented + // messages. Thus, supporting ~2 GiB when sending. + canSendMaxMessageSize = 2147483637; + } + } else if (browserDetails.version < 60) { + // Currently, all FF >= 57 will reset the remote maximum message size + // to the default value when a data channel is created at a later + // stage. :( + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 + canSendMaxMessageSize = browserDetails.version === 57 ? 65535 : 65536; + } else { + // FF >= 60 supports sending ~2 GiB + canSendMaxMessageSize = 2147483637; + } + } + return canSendMaxMessageSize; + }; + + var getMaxMessageSize = function getMaxMessageSize(description, remoteIsFirefox) { + // Note: 65536 bytes is the default value from the SDP spec. Also, + // every implementation we know supports receiving 65536 bytes. + var maxMessageSize = 65536; + + // FF 57 has a slightly incorrect default remote max message size, so + // we need to adjust it here to avoid a failure when sending. + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697 + if (browserDetails.browser === 'firefox' && browserDetails.version === 57) { + maxMessageSize = 65535; + } + + var match = _sdp2.default.matchPrefix(description.sdp, 'a=max-message-size:'); + if (match.length > 0) { + maxMessageSize = parseInt(match[0].substr(19), 10); + } else if (browserDetails.browser === 'firefox' && remoteIsFirefox !== -1) { + // If the maximum message size is not present in the remote SDP and + // both local and remote are Firefox, the remote peer can receive + // ~2 GiB. + maxMessageSize = 2147483637; + } + return maxMessageSize; + }; + + var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() { + this._sctp = null; + // Chrome decided to not expose .sctp in plan-b mode. + // As usual, adapter.js has to do an 'ugly worakaround' + // to cover up the mess. + if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) { + var _getConfiguration = this.getConfiguration(), + sdpSemantics = _getConfiguration.sdpSemantics; + + if (sdpSemantics === 'plan-b') { + Object.defineProperty(this, 'sctp', { + get: function get() { + return typeof this._sctp === 'undefined' ? null : this._sctp; + }, + + enumerable: true, + configurable: true + }); + } + } + + if (sctpInDescription(arguments[0])) { + // Check if the remote is FF. + var isFirefox = getRemoteFirefoxVersion(arguments[0]); + + // Get the maximum message size the local peer is capable of sending + var canSendMMS = getCanSendMaxMessageSize(isFirefox); + + // Get the maximum message size of the remote peer. + var remoteMMS = getMaxMessageSize(arguments[0], isFirefox); + + // Determine final maximum message size + var maxMessageSize = void 0; + if (canSendMMS === 0 && remoteMMS === 0) { + maxMessageSize = Number.POSITIVE_INFINITY; + } else if (canSendMMS === 0 || remoteMMS === 0) { + maxMessageSize = Math.max(canSendMMS, remoteMMS); + } else { + maxMessageSize = Math.min(canSendMMS, remoteMMS); + } + + // Create a dummy RTCSctpTransport object and the 'maxMessageSize' + // attribute. + var sctp = {}; + Object.defineProperty(sctp, 'maxMessageSize', { + get: function get() { + return maxMessageSize; + } + }); + this._sctp = sctp; + } + + return origSetRemoteDescription.apply(this, arguments); + }; +} + +function shimSendThrowTypeError(window) { + if (!(window.RTCPeerConnection && 'createDataChannel' in window.RTCPeerConnection.prototype)) { + return; + } + + // Note: Although Firefox >= 57 has a native implementation, the maximum + // message size can be reset for all data channels at a later stage. + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 + + function wrapDcSend(dc, pc) { + var origDataChannelSend = dc.send; + dc.send = function send() { + var data = arguments[0]; + var length = data.length || data.size || data.byteLength; + if (dc.readyState === 'open' && pc.sctp && length > pc.sctp.maxMessageSize) { + throw new TypeError('Message too large (can send a maximum of ' + pc.sctp.maxMessageSize + ' bytes)'); + } + return origDataChannelSend.apply(dc, arguments); + }; + } + var origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel; + window.RTCPeerConnection.prototype.createDataChannel = function createDataChannel() { + var dataChannel = origCreateDataChannel.apply(this, arguments); + wrapDcSend(dataChannel, this); + return dataChannel; + }; + utils.wrapPeerConnectionEvent(window, 'datachannel', function (e) { + wrapDcSend(e.channel, e.target); + return e; + }); +} + +/* shims RTCConnectionState by pretending it is the same as iceConnectionState. + * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12 + * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect + * since DTLS failures would be hidden. See + * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827 + * for the Firefox tracking bug. + */ +function shimConnectionState(window) { + if (!window.RTCPeerConnection || 'connectionState' in window.RTCPeerConnection.prototype) { + return; + } + var proto = window.RTCPeerConnection.prototype; + Object.defineProperty(proto, 'connectionState', { + get: function get() { + return { + completed: 'connected', + checking: 'connecting' + }[this.iceConnectionState] || this.iceConnectionState; + }, + + enumerable: true, + configurable: true + }); + Object.defineProperty(proto, 'onconnectionstatechange', { + get: function get() { + return this._onconnectionstatechange || null; + }, + set: function set(cb) { + if (this._onconnectionstatechange) { + this.removeEventListener('connectionstatechange', this._onconnectionstatechange); + delete this._onconnectionstatechange; + } + if (cb) { + this.addEventListener('connectionstatechange', this._onconnectionstatechange = cb); + } + }, + + enumerable: true, + configurable: true + }); + + ['setLocalDescription', 'setRemoteDescription'].forEach(function (method) { + var origMethod = proto[method]; + proto[method] = function () { + if (!this._connectionstatechangepoly) { + this._connectionstatechangepoly = function (e) { + var pc = e.target; + if (pc._lastConnectionState !== pc.connectionState) { + pc._lastConnectionState = pc.connectionState; + var newEvent = new Event('connectionstatechange', e); + pc.dispatchEvent(newEvent); + } + return e; + }; + this.addEventListener('iceconnectionstatechange', this._connectionstatechangepoly); + } + return origMethod.apply(this, arguments); + }; + }); +} + +function removeExtmapAllowMixed(window, browserDetails) { + /* remove a=extmap-allow-mixed for webrtc.org < M71 */ + if (!window.RTCPeerConnection) { + return; + } + if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) { + return; + } + if (browserDetails.browser === 'safari' && browserDetails.version >= 605) { + return; + } + var nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription(desc) { + if (desc && desc.sdp && desc.sdp.indexOf('\na=extmap-allow-mixed') !== -1) { + var sdp = desc.sdp.split('\n').filter(function (line) { + return line.trim() !== 'a=extmap-allow-mixed'; + }).join('\n'); + // Safari enforces read-only-ness of RTCSessionDescription fields. + if (window.RTCSessionDescription && desc instanceof window.RTCSessionDescription) { + arguments[0] = new window.RTCSessionDescription({ + type: desc.type, + sdp: sdp + }); + } else { + desc.sdp = sdp; + } + } + return nativeSRD.apply(this, arguments); + }; +} + +function shimAddIceCandidateNullOrEmpty(window, browserDetails) { + // Support for addIceCandidate(null or undefined) + // as well as addIceCandidate({candidate: "", ...}) + // https://bugs.chromium.org/p/chromium/issues/detail?id=978582 + // Note: must be called before other polyfills which change the signature. + if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) { + return; + } + var nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate; + if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) { + return; + } + window.RTCPeerConnection.prototype.addIceCandidate = function addIceCandidate() { + if (!arguments[0]) { + if (arguments[1]) { + arguments[1].apply(null); + } + return Promise.resolve(); + } + // Firefox 68+ emits and processes {candidate: "", ...}, ignore + // in older versions. + // Native support for ignoring exists for Chrome M77+. + // Safari ignores as well, exact version unknown but works in the same + // version that also ignores addIceCandidate(null). + if ((browserDetails.browser === 'chrome' && browserDetails.version < 78 || browserDetails.browser === 'firefox' && browserDetails.version < 68 || browserDetails.browser === 'safari') && arguments[0] && arguments[0].candidate === '') { + return Promise.resolve(); + } + return nativeAddIceCandidate.apply(this, arguments); + }; +} + +// Note: Make sure to call this ahead of APIs that modify +// setLocalDescription.length +function shimParameterlessSetLocalDescription(window, browserDetails) { + if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) { + return; + } + var nativeSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription; + if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) { + return; + } + window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() { + var _this = this; + + var desc = arguments[0] || {}; + if ((typeof desc === 'undefined' ? 'undefined' : _typeof(desc)) !== 'object' || desc.type && desc.sdp) { + return nativeSetLocalDescription.apply(this, arguments); + } + // The remaining steps should technically happen when SLD comes off the + // RTCPeerConnection's operations chain (not ahead of going on it), but + // this is too difficult to shim. Instead, this shim only covers the + // common case where the operations chain is empty. This is imperfect, but + // should cover many cases. Rationale: Even if we can't reduce the glare + // window to zero on imperfect implementations, there's value in tapping + // into the perfect negotiation pattern that several browsers support. + desc = { type: desc.type, sdp: desc.sdp }; + if (!desc.type) { + switch (this.signalingState) { + case 'stable': + case 'have-local-offer': + case 'have-remote-pranswer': + desc.type = 'offer'; + break; + default: + desc.type = 'answer'; + break; + } + } + if (desc.sdp || desc.type !== 'offer' && desc.type !== 'answer') { + return nativeSetLocalDescription.apply(this, [desc]); + } + var func = desc.type === 'offer' ? this.createOffer : this.createAnswer; + return func.apply(this).then(function (d) { + return nativeSetLocalDescription.apply(_this, [d]); + }); + }; +} + +},{"./utils":11,"sdp":12}],7:[function(require,module,exports){ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _getusermedia = require('./getusermedia'); + +Object.defineProperty(exports, 'shimGetUserMedia', { + enumerable: true, + get: function get() { + return _getusermedia.shimGetUserMedia; + } +}); + +var _getdisplaymedia = require('./getdisplaymedia'); + +Object.defineProperty(exports, 'shimGetDisplayMedia', { + enumerable: true, + get: function get() { + return _getdisplaymedia.shimGetDisplayMedia; + } +}); +exports.shimOnTrack = shimOnTrack; +exports.shimPeerConnection = shimPeerConnection; +exports.shimSenderGetStats = shimSenderGetStats; +exports.shimReceiverGetStats = shimReceiverGetStats; +exports.shimRemoveStream = shimRemoveStream; +exports.shimRTCDataChannel = shimRTCDataChannel; +exports.shimAddTransceiver = shimAddTransceiver; +exports.shimGetParameters = shimGetParameters; +exports.shimCreateOffer = shimCreateOffer; +exports.shimCreateAnswer = shimCreateAnswer; + +var _utils = require('../utils'); + +var utils = _interopRequireWildcard(_utils); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function shimOnTrack(window) { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) { + Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { + get: function get() { + return { receiver: this.receiver }; + } + }); + } +} + +function shimPeerConnection(window, browserDetails) { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== 'object' || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) { + return; // probably media.peerconnection.enabled=false in about:config + } + if (!window.RTCPeerConnection && window.mozRTCPeerConnection) { + // very basic support for old versions. + window.RTCPeerConnection = window.mozRTCPeerConnection; + } + + if (browserDetails.version < 53) { + // shim away need for obsolete RTCIceCandidate/RTCSessionDescription. + ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) { + var nativeMethod = window.RTCPeerConnection.prototype[method]; + var methodObj = _defineProperty({}, method, function () { + arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]); + return nativeMethod.apply(this, arguments); + }); + window.RTCPeerConnection.prototype[method] = methodObj[method]; + }); + } + + var modernStatsTypes = { + inboundrtp: 'inbound-rtp', + outboundrtp: 'outbound-rtp', + candidatepair: 'candidate-pair', + localcandidate: 'local-candidate', + remotecandidate: 'remote-candidate' + }; + + var nativeGetStats = window.RTCPeerConnection.prototype.getStats; + window.RTCPeerConnection.prototype.getStats = function getStats() { + var _arguments = Array.prototype.slice.call(arguments), + selector = _arguments[0], + onSucc = _arguments[1], + onErr = _arguments[2]; + + return nativeGetStats.apply(this, [selector || null]).then(function (stats) { + if (browserDetails.version < 53 && !onSucc) { + // Shim only promise getStats with spec-hyphens in type names + // Leave callback version alone; misc old uses of forEach before Map + try { + stats.forEach(function (stat) { + stat.type = modernStatsTypes[stat.type] || stat.type; + }); + } catch (e) { + if (e.name !== 'TypeError') { + throw e; + } + // Avoid TypeError: "type" is read-only, in old versions. 34-43ish + stats.forEach(function (stat, i) { + stats.set(i, Object.assign({}, stat, { + type: modernStatsTypes[stat.type] || stat.type + })); + }); + } + } + return stats; + }).then(onSucc, onErr); + }; +} + +function shimSenderGetStats(window) { + if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) { + return; + } + if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) { + return; + } + var origGetSenders = window.RTCPeerConnection.prototype.getSenders; + if (origGetSenders) { + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + var _this = this; + + var senders = origGetSenders.apply(this, []); + senders.forEach(function (sender) { + return sender._pc = _this; + }); + return senders; + }; + } + + var origAddTrack = window.RTCPeerConnection.prototype.addTrack; + if (origAddTrack) { + window.RTCPeerConnection.prototype.addTrack = function addTrack() { + var sender = origAddTrack.apply(this, arguments); + sender._pc = this; + return sender; + }; + } + window.RTCRtpSender.prototype.getStats = function getStats() { + return this.track ? this._pc.getStats(this.track) : Promise.resolve(new Map()); + }; +} + +function shimReceiverGetStats(window) { + if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) { + return; + } + if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) { + return; + } + var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers; + if (origGetReceivers) { + window.RTCPeerConnection.prototype.getReceivers = function getReceivers() { + var _this2 = this; + + var receivers = origGetReceivers.apply(this, []); + receivers.forEach(function (receiver) { + return receiver._pc = _this2; + }); + return receivers; + }; + } + utils.wrapPeerConnectionEvent(window, 'track', function (e) { + e.receiver._pc = e.srcElement; + return e; + }); + window.RTCRtpReceiver.prototype.getStats = function getStats() { + return this._pc.getStats(this.track); + }; +} + +function shimRemoveStream(window) { + if (!window.RTCPeerConnection || 'removeStream' in window.RTCPeerConnection.prototype) { + return; + } + window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { + var _this3 = this; + + utils.deprecated('removeStream', 'removeTrack'); + this.getSenders().forEach(function (sender) { + if (sender.track && stream.getTracks().includes(sender.track)) { + _this3.removeTrack(sender); + } + }); + }; +} + +function shimRTCDataChannel(window) { + // rename DataChannel to RTCDataChannel (native fix in FF60): + // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851 + if (window.DataChannel && !window.RTCDataChannel) { + window.RTCDataChannel = window.DataChannel; + } +} + +function shimAddTransceiver(window) { + // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 + // Firefox ignores the init sendEncodings options passed to addTransceiver + // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 + if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection)) { + return; + } + var origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver; + if (origAddTransceiver) { + window.RTCPeerConnection.prototype.addTransceiver = function addTransceiver() { + this.setParametersPromises = []; + var initParameters = arguments[1]; + var shouldPerformCheck = initParameters && 'sendEncodings' in initParameters; + if (shouldPerformCheck) { + // If sendEncodings params are provided, validate grammar + initParameters.sendEncodings.forEach(function (encodingParam) { + if ('rid' in encodingParam) { + var ridRegex = /^[a-z0-9]{0,16}$/i; + if (!ridRegex.test(encodingParam.rid)) { + throw new TypeError('Invalid RID value provided.'); + } + } + if ('scaleResolutionDownBy' in encodingParam) { + if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) { + throw new RangeError('scale_resolution_down_by must be >= 1.0'); + } + } + if ('maxFramerate' in encodingParam) { + if (!(parseFloat(encodingParam.maxFramerate) >= 0)) { + throw new RangeError('max_framerate must be >= 0.0'); + } + } + }); + } + var transceiver = origAddTransceiver.apply(this, arguments); + if (shouldPerformCheck) { + // Check if the init options were applied. If not we do this in an + // asynchronous way and save the promise reference in a global object. + // This is an ugly hack, but at the same time is way more robust than + // checking the sender parameters before and after the createOffer + // Also note that after the createoffer we are not 100% sure that + // the params were asynchronously applied so we might miss the + // opportunity to recreate offer. + var sender = transceiver.sender; + + var params = sender.getParameters(); + if (!('encodings' in params) || + // Avoid being fooled by patched getParameters() below. + params.encodings.length === 1 && Object.keys(params.encodings[0]).length === 0) { + params.encodings = initParameters.sendEncodings; + sender.sendEncodings = initParameters.sendEncodings; + this.setParametersPromises.push(sender.setParameters(params).then(function () { + delete sender.sendEncodings; + }).catch(function () { + delete sender.sendEncodings; + })); + } + } + return transceiver; + }; + } +} + +function shimGetParameters(window) { + if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCRtpSender)) { + return; + } + var origGetParameters = window.RTCRtpSender.prototype.getParameters; + if (origGetParameters) { + window.RTCRtpSender.prototype.getParameters = function getParameters() { + var params = origGetParameters.apply(this, arguments); + if (!('encodings' in params)) { + params.encodings = [].concat(this.sendEncodings || [{}]); + } + return params; + }; + } +} + +function shimCreateOffer(window) { + // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 + // Firefox ignores the init sendEncodings options passed to addTransceiver + // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 + if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection)) { + return; + } + var origCreateOffer = window.RTCPeerConnection.prototype.createOffer; + window.RTCPeerConnection.prototype.createOffer = function createOffer() { + var _this4 = this, + _arguments2 = arguments; + + if (this.setParametersPromises && this.setParametersPromises.length) { + return Promise.all(this.setParametersPromises).then(function () { + return origCreateOffer.apply(_this4, _arguments2); + }).finally(function () { + _this4.setParametersPromises = []; + }); + } + return origCreateOffer.apply(this, arguments); + }; +} + +function shimCreateAnswer(window) { + // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 + // Firefox ignores the init sendEncodings options passed to addTransceiver + // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 + if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCPeerConnection)) { + return; + } + var origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer; + window.RTCPeerConnection.prototype.createAnswer = function createAnswer() { + var _this5 = this, + _arguments3 = arguments; + + if (this.setParametersPromises && this.setParametersPromises.length) { + return Promise.all(this.setParametersPromises).then(function () { + return origCreateAnswer.apply(_this5, _arguments3); + }).finally(function () { + _this5.setParametersPromises = []; + }); + } + return origCreateAnswer.apply(this, arguments); + }; +} + +},{"../utils":11,"./getdisplaymedia":8,"./getusermedia":9}],8:[function(require,module,exports){ +/* + * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.shimGetDisplayMedia = shimGetDisplayMedia; +function shimGetDisplayMedia(window, preferredMediaSource) { + if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) { + return; + } + if (!window.navigator.mediaDevices) { + return; + } + window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) { + if (!(constraints && constraints.video)) { + var err = new DOMException('getDisplayMedia without video ' + 'constraints is undefined'); + err.name = 'NotFoundError'; + // from https://heycam.github.io/webidl/#idl-DOMException-error-names + err.code = 8; + return Promise.reject(err); + } + if (constraints.video === true) { + constraints.video = { mediaSource: preferredMediaSource }; + } else { + constraints.video.mediaSource = preferredMediaSource; + } + return window.navigator.mediaDevices.getUserMedia(constraints); + }; +} + +},{}],9:[function(require,module,exports){ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.shimGetUserMedia = shimGetUserMedia; + +var _utils = require('../utils'); + +var utils = _interopRequireWildcard(_utils); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function shimGetUserMedia(window, browserDetails) { + var navigator = window && window.navigator; + var MediaStreamTrack = window && window.MediaStreamTrack; + + navigator.getUserMedia = function (constraints, onSuccess, onError) { + // Replace Firefox 44+'s deprecation warning with unprefixed version. + utils.deprecated('navigator.getUserMedia', 'navigator.mediaDevices.getUserMedia'); + navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError); + }; + + if (!(browserDetails.version > 55 && 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) { + var remap = function remap(obj, a, b) { + if (a in obj && !(b in obj)) { + obj[b] = obj[a]; + delete obj[a]; + } + }; + + var nativeGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); + navigator.mediaDevices.getUserMedia = function (c) { + if ((typeof c === 'undefined' ? 'undefined' : _typeof(c)) === 'object' && _typeof(c.audio) === 'object') { + c = JSON.parse(JSON.stringify(c)); + remap(c.audio, 'autoGainControl', 'mozAutoGainControl'); + remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression'); + } + return nativeGetUserMedia(c); + }; + + if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) { + var nativeGetSettings = MediaStreamTrack.prototype.getSettings; + MediaStreamTrack.prototype.getSettings = function () { + var obj = nativeGetSettings.apply(this, arguments); + remap(obj, 'mozAutoGainControl', 'autoGainControl'); + remap(obj, 'mozNoiseSuppression', 'noiseSuppression'); + return obj; + }; + } + + if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) { + var nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints; + MediaStreamTrack.prototype.applyConstraints = function (c) { + if (this.kind === 'audio' && (typeof c === 'undefined' ? 'undefined' : _typeof(c)) === 'object') { + c = JSON.parse(JSON.stringify(c)); + remap(c, 'autoGainControl', 'mozAutoGainControl'); + remap(c, 'noiseSuppression', 'mozNoiseSuppression'); + } + return nativeApplyConstraints.apply(this, [c]); + }; + } + } +} + +},{"../utils":11}],10:[function(require,module,exports){ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.shimLocalStreamsAPI = shimLocalStreamsAPI; +exports.shimRemoteStreamsAPI = shimRemoteStreamsAPI; +exports.shimCallbacksAPI = shimCallbacksAPI; +exports.shimGetUserMedia = shimGetUserMedia; +exports.shimConstraints = shimConstraints; +exports.shimRTCIceServerUrls = shimRTCIceServerUrls; +exports.shimTrackEventTransceiver = shimTrackEventTransceiver; +exports.shimCreateOfferLegacy = shimCreateOfferLegacy; +exports.shimAudioContext = shimAudioContext; + +var _utils = require('../utils'); + +var utils = _interopRequireWildcard(_utils); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function shimLocalStreamsAPI(window) { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== 'object' || !window.RTCPeerConnection) { + return; + } + if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) { + window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() { + if (!this._localStreams) { + this._localStreams = []; + } + return this._localStreams; + }; + } + if (!('addStream' in window.RTCPeerConnection.prototype)) { + var _addTrack = window.RTCPeerConnection.prototype.addTrack; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + var _this = this; + + if (!this._localStreams) { + this._localStreams = []; + } + if (!this._localStreams.includes(stream)) { + this._localStreams.push(stream); + } + // Try to emulate Chrome's behaviour of adding in audio-video order. + // Safari orders by track id. + stream.getAudioTracks().forEach(function (track) { + return _addTrack.call(_this, track, stream); + }); + stream.getVideoTracks().forEach(function (track) { + return _addTrack.call(_this, track, stream); + }); + }; + + window.RTCPeerConnection.prototype.addTrack = function addTrack(track) { + var _this2 = this; + + for (var _len = arguments.length, streams = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + streams[_key - 1] = arguments[_key]; + } + + if (streams) { + streams.forEach(function (stream) { + if (!_this2._localStreams) { + _this2._localStreams = [stream]; + } else if (!_this2._localStreams.includes(stream)) { + _this2._localStreams.push(stream); + } + }); + } + return _addTrack.apply(this, arguments); + }; + } + if (!('removeStream' in window.RTCPeerConnection.prototype)) { + window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { + var _this3 = this; + + if (!this._localStreams) { + this._localStreams = []; + } + var index = this._localStreams.indexOf(stream); + if (index === -1) { + return; + } + this._localStreams.splice(index, 1); + var tracks = stream.getTracks(); + this.getSenders().forEach(function (sender) { + if (tracks.includes(sender.track)) { + _this3.removeTrack(sender); + } + }); + }; + } +} + +function shimRemoteStreamsAPI(window) { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== 'object' || !window.RTCPeerConnection) { + return; + } + if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) { + window.RTCPeerConnection.prototype.getRemoteStreams = function getRemoteStreams() { + return this._remoteStreams ? this._remoteStreams : []; + }; + } + if (!('onaddstream' in window.RTCPeerConnection.prototype)) { + Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', { + get: function get() { + return this._onaddstream; + }, + set: function set(f) { + var _this4 = this; + + if (this._onaddstream) { + this.removeEventListener('addstream', this._onaddstream); + this.removeEventListener('track', this._onaddstreampoly); + } + this.addEventListener('addstream', this._onaddstream = f); + this.addEventListener('track', this._onaddstreampoly = function (e) { + e.streams.forEach(function (stream) { + if (!_this4._remoteStreams) { + _this4._remoteStreams = []; + } + if (_this4._remoteStreams.includes(stream)) { + return; + } + _this4._remoteStreams.push(stream); + var event = new Event('addstream'); + event.stream = stream; + _this4.dispatchEvent(event); + }); + }); + } + }); + var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() { + var pc = this; + if (!this._onaddstreampoly) { + this.addEventListener('track', this._onaddstreampoly = function (e) { + e.streams.forEach(function (stream) { + if (!pc._remoteStreams) { + pc._remoteStreams = []; + } + if (pc._remoteStreams.indexOf(stream) >= 0) { + return; + } + pc._remoteStreams.push(stream); + var event = new Event('addstream'); + event.stream = stream; + pc.dispatchEvent(event); + }); + }); + } + return origSetRemoteDescription.apply(pc, arguments); + }; + } +} + +function shimCallbacksAPI(window) { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== 'object' || !window.RTCPeerConnection) { + return; + } + var prototype = window.RTCPeerConnection.prototype; + var origCreateOffer = prototype.createOffer; + var origCreateAnswer = prototype.createAnswer; + var setLocalDescription = prototype.setLocalDescription; + var setRemoteDescription = prototype.setRemoteDescription; + var addIceCandidate = prototype.addIceCandidate; + + prototype.createOffer = function createOffer(successCallback, failureCallback) { + var options = arguments.length >= 2 ? arguments[2] : arguments[0]; + var promise = origCreateOffer.apply(this, [options]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + + prototype.createAnswer = function createAnswer(successCallback, failureCallback) { + var options = arguments.length >= 2 ? arguments[2] : arguments[0]; + var promise = origCreateAnswer.apply(this, [options]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + + var withCallback = function withCallback(description, successCallback, failureCallback) { + var promise = setLocalDescription.apply(this, [description]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + prototype.setLocalDescription = withCallback; + + withCallback = function withCallback(description, successCallback, failureCallback) { + var promise = setRemoteDescription.apply(this, [description]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + prototype.setRemoteDescription = withCallback; + + withCallback = function withCallback(candidate, successCallback, failureCallback) { + var promise = addIceCandidate.apply(this, [candidate]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + prototype.addIceCandidate = withCallback; +} + +function shimGetUserMedia(window) { + var navigator = window && window.navigator; + + if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + // shim not needed in Safari 12.1 + var mediaDevices = navigator.mediaDevices; + var _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices); + navigator.mediaDevices.getUserMedia = function (constraints) { + return _getUserMedia(shimConstraints(constraints)); + }; + } + + if (!navigator.getUserMedia && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) { + navigator.mediaDevices.getUserMedia(constraints).then(cb, errcb); + }.bind(navigator); + } +} + +function shimConstraints(constraints) { + if (constraints && constraints.video !== undefined) { + return Object.assign({}, constraints, { video: utils.compactObject(constraints.video) }); + } + + return constraints; +} + +function shimRTCIceServerUrls(window) { + if (!window.RTCPeerConnection) { + return; + } + // migrate from non-spec RTCIceServer.url to RTCIceServer.urls + var OrigPeerConnection = window.RTCPeerConnection; + window.RTCPeerConnection = function RTCPeerConnection(pcConfig, pcConstraints) { + if (pcConfig && pcConfig.iceServers) { + var newIceServers = []; + for (var i = 0; i < pcConfig.iceServers.length; i++) { + var server = pcConfig.iceServers[i]; + if (!server.hasOwnProperty('urls') && server.hasOwnProperty('url')) { + utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls'); + server = JSON.parse(JSON.stringify(server)); + server.urls = server.url; + delete server.url; + newIceServers.push(server); + } else { + newIceServers.push(pcConfig.iceServers[i]); + } + } + pcConfig.iceServers = newIceServers; + } + return new OrigPeerConnection(pcConfig, pcConstraints); + }; + window.RTCPeerConnection.prototype = OrigPeerConnection.prototype; + // wrap static methods. Currently just generateCertificate. + if ('generateCertificate' in OrigPeerConnection) { + Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', { + get: function get() { + return OrigPeerConnection.generateCertificate; + } + }); + } +} + +function shimTrackEventTransceiver(window) { + // Add event.transceiver member over deprecated event.receiver + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) { + Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { + get: function get() { + return { receiver: this.receiver }; + } + }); + } +} + +function shimCreateOfferLegacy(window) { + var origCreateOffer = window.RTCPeerConnection.prototype.createOffer; + window.RTCPeerConnection.prototype.createOffer = function createOffer(offerOptions) { + if (offerOptions) { + if (typeof offerOptions.offerToReceiveAudio !== 'undefined') { + // support bit values + offerOptions.offerToReceiveAudio = !!offerOptions.offerToReceiveAudio; + } + var audioTransceiver = this.getTransceivers().find(function (transceiver) { + return transceiver.receiver.track.kind === 'audio'; + }); + if (offerOptions.offerToReceiveAudio === false && audioTransceiver) { + if (audioTransceiver.direction === 'sendrecv') { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection('sendonly'); + } else { + audioTransceiver.direction = 'sendonly'; + } + } else if (audioTransceiver.direction === 'recvonly') { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection('inactive'); + } else { + audioTransceiver.direction = 'inactive'; + } + } + } else if (offerOptions.offerToReceiveAudio === true && !audioTransceiver) { + this.addTransceiver('audio'); + } + + if (typeof offerOptions.offerToReceiveVideo !== 'undefined') { + // support bit values + offerOptions.offerToReceiveVideo = !!offerOptions.offerToReceiveVideo; + } + var videoTransceiver = this.getTransceivers().find(function (transceiver) { + return transceiver.receiver.track.kind === 'video'; + }); + if (offerOptions.offerToReceiveVideo === false && videoTransceiver) { + if (videoTransceiver.direction === 'sendrecv') { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection('sendonly'); + } else { + videoTransceiver.direction = 'sendonly'; + } + } else if (videoTransceiver.direction === 'recvonly') { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection('inactive'); + } else { + videoTransceiver.direction = 'inactive'; + } + } + } else if (offerOptions.offerToReceiveVideo === true && !videoTransceiver) { + this.addTransceiver('video'); + } + } + return origCreateOffer.apply(this, arguments); + }; +} + +function shimAudioContext(window) { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== 'object' || window.AudioContext) { + return; + } + window.AudioContext = window.webkitAudioContext; +} + +},{"../utils":11}],11:[function(require,module,exports){ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.extractVersion = extractVersion; +exports.wrapPeerConnectionEvent = wrapPeerConnectionEvent; +exports.disableLog = disableLog; +exports.disableWarnings = disableWarnings; +exports.log = log; +exports.deprecated = deprecated; +exports.detectBrowser = detectBrowser; +exports.compactObject = compactObject; +exports.walkStats = walkStats; +exports.filterStats = filterStats; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var logDisabled_ = true; +var deprecationWarnings_ = true; + +/** + * Extract browser version out of the provided user agent string. + * + * @param {!string} uastring userAgent string. + * @param {!string} expr Regular expression used as match criteria. + * @param {!number} pos position in the version string to be returned. + * @return {!number} browser version. + */ +function extractVersion(uastring, expr, pos) { + var match = uastring.match(expr); + return match && match.length >= pos && parseInt(match[pos], 10); +} + +// Wraps the peerconnection event eventNameToWrap in a function +// which returns the modified event object (or false to prevent +// the event). +function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) { + if (!window.RTCPeerConnection) { + return; + } + var proto = window.RTCPeerConnection.prototype; + var nativeAddEventListener = proto.addEventListener; + proto.addEventListener = function (nativeEventName, cb) { + if (nativeEventName !== eventNameToWrap) { + return nativeAddEventListener.apply(this, arguments); + } + var wrappedCallback = function wrappedCallback(e) { + var modifiedEvent = wrapper(e); + if (modifiedEvent) { + if (cb.handleEvent) { + cb.handleEvent(modifiedEvent); + } else { + cb(modifiedEvent); + } + } + }; + this._eventMap = this._eventMap || {}; + if (!this._eventMap[eventNameToWrap]) { + this._eventMap[eventNameToWrap] = new Map(); + } + this._eventMap[eventNameToWrap].set(cb, wrappedCallback); + return nativeAddEventListener.apply(this, [nativeEventName, wrappedCallback]); + }; + + var nativeRemoveEventListener = proto.removeEventListener; + proto.removeEventListener = function (nativeEventName, cb) { + if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[eventNameToWrap]) { + return nativeRemoveEventListener.apply(this, arguments); + } + if (!this._eventMap[eventNameToWrap].has(cb)) { + return nativeRemoveEventListener.apply(this, arguments); + } + var unwrappedCb = this._eventMap[eventNameToWrap].get(cb); + this._eventMap[eventNameToWrap].delete(cb); + if (this._eventMap[eventNameToWrap].size === 0) { + delete this._eventMap[eventNameToWrap]; + } + if (Object.keys(this._eventMap).length === 0) { + delete this._eventMap; + } + return nativeRemoveEventListener.apply(this, [nativeEventName, unwrappedCb]); + }; + + Object.defineProperty(proto, 'on' + eventNameToWrap, { + get: function get() { + return this['_on' + eventNameToWrap]; + }, + set: function set(cb) { + if (this['_on' + eventNameToWrap]) { + this.removeEventListener(eventNameToWrap, this['_on' + eventNameToWrap]); + delete this['_on' + eventNameToWrap]; + } + if (cb) { + this.addEventListener(eventNameToWrap, this['_on' + eventNameToWrap] = cb); + } + }, + + enumerable: true, + configurable: true + }); +} + +function disableLog(bool) { + if (typeof bool !== 'boolean') { + return new Error('Argument type: ' + (typeof bool === 'undefined' ? 'undefined' : _typeof(bool)) + '. Please use a boolean.'); + } + logDisabled_ = bool; + return bool ? 'adapter.js logging disabled' : 'adapter.js logging enabled'; +} + +/** + * Disable or enable deprecation warnings + * @param {!boolean} bool set to true to disable warnings. + */ +function disableWarnings(bool) { + if (typeof bool !== 'boolean') { + return new Error('Argument type: ' + (typeof bool === 'undefined' ? 'undefined' : _typeof(bool)) + '. Please use a boolean.'); + } + deprecationWarnings_ = !bool; + return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled'); +} + +function log() { + if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object') { + if (logDisabled_) { + return; + } + if (typeof console !== 'undefined' && typeof console.log === 'function') { + console.log.apply(console, arguments); + } + } +} + +/** + * Shows a deprecation warning suggesting the modern and spec-compatible API. + */ +function deprecated(oldMethod, newMethod) { + if (!deprecationWarnings_) { + return; + } + console.warn(oldMethod + ' is deprecated, please use ' + newMethod + ' instead.'); +} + +/** + * Browser detector. + * + * @return {object} result containing browser and version + * properties. + */ +function detectBrowser(window) { + // Returned result object. + var result = { browser: null, version: null }; + + // Fail early if it's not a browser + if (typeof window === 'undefined' || !window.navigator) { + result.browser = 'Not a browser.'; + return result; + } + + var navigator = window.navigator; + + + if (navigator.mozGetUserMedia) { + // Firefox. + result.browser = 'firefox'; + result.version = extractVersion(navigator.userAgent, /Firefox\/(\d+)\./, 1); + } else if (navigator.webkitGetUserMedia || window.isSecureContext === false && window.webkitRTCPeerConnection && !window.RTCIceGatherer) { + // Chrome, Chromium, Webview, Opera. + // Version matches Chrome/WebRTC version. + // Chrome 74 removed webkitGetUserMedia on http as well so we need the + // more complicated fallback to webkitRTCPeerConnection. + result.browser = 'chrome'; + result.version = extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2); + } else if (window.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) { + // Safari. + result.browser = 'safari'; + result.version = extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1); + result.supportsUnifiedPlan = window.RTCRtpTransceiver && 'currentDirection' in window.RTCRtpTransceiver.prototype; + } else { + // Default fallthrough: not supported. + result.browser = 'Not a supported browser.'; + return result; + } + + return result; +} + +/** + * Checks if something is an object. + * + * @param {*} val The something you want to check. + * @return true if val is an object, false otherwise. + */ +function isObject(val) { + return Object.prototype.toString.call(val) === '[object Object]'; +} + +/** + * Remove all empty objects and undefined values + * from a nested object -- an enhanced and vanilla version + * of Lodash's `compact`. + */ +function compactObject(data) { + if (!isObject(data)) { + return data; + } + + return Object.keys(data).reduce(function (accumulator, key) { + var isObj = isObject(data[key]); + var value = isObj ? compactObject(data[key]) : data[key]; + var isEmptyObject = isObj && !Object.keys(value).length; + if (value === undefined || isEmptyObject) { + return accumulator; + } + return Object.assign(accumulator, _defineProperty({}, key, value)); + }, {}); +} + +/* iterates the stats graph recursively. */ +function walkStats(stats, base, resultSet) { + if (!base || resultSet.has(base.id)) { + return; + } + resultSet.set(base.id, base); + Object.keys(base).forEach(function (name) { + if (name.endsWith('Id')) { + walkStats(stats, stats.get(base[name]), resultSet); + } else if (name.endsWith('Ids')) { + base[name].forEach(function (id) { + walkStats(stats, stats.get(id), resultSet); + }); + } + }); +} + +/* filter getStats for a sender/receiver track. */ +function filterStats(result, track, outbound) { + var streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp'; + var filteredResult = new Map(); + if (track === null) { + return filteredResult; + } + var trackStats = []; + result.forEach(function (value) { + if (value.type === 'track' && value.trackIdentifier === track.id) { + trackStats.push(value); + } + }); + trackStats.forEach(function (trackStat) { + result.forEach(function (stats) { + if (stats.type === streamStatsType && stats.trackId === trackStat.id) { + walkStats(result, stats, filteredResult); + } + }); + }); + return filteredResult; +} + +},{}],12:[function(require,module,exports){ +/* eslint-env node */ +'use strict'; + +// SDP helpers. + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var SDPUtils = {}; + +// Generate an alphanumeric identifier for cname or mids. +// TODO: use UUIDs instead? https://gist.github.com/jed/982883 +SDPUtils.generateIdentifier = function () { + return Math.random().toString(36).substr(2, 10); +}; + +// The RTCP CNAME used by all peerconnections from the same JS. +SDPUtils.localCName = SDPUtils.generateIdentifier(); + +// Splits SDP into lines, dealing with both CRLF and LF. +SDPUtils.splitLines = function (blob) { + return blob.trim().split('\n').map(function (line) { + return line.trim(); + }); +}; +// Splits SDP into sessionpart and mediasections. Ensures CRLF. +SDPUtils.splitSections = function (blob) { + var parts = blob.split('\nm='); + return parts.map(function (part, index) { + return (index > 0 ? 'm=' + part : part).trim() + '\r\n'; + }); +}; + +// Returns the session description. +SDPUtils.getDescription = function (blob) { + var sections = SDPUtils.splitSections(blob); + return sections && sections[0]; +}; + +// Returns the individual media sections. +SDPUtils.getMediaSections = function (blob) { + var sections = SDPUtils.splitSections(blob); + sections.shift(); + return sections; +}; + +// Returns lines that start with a certain prefix. +SDPUtils.matchPrefix = function (blob, prefix) { + return SDPUtils.splitLines(blob).filter(function (line) { + return line.indexOf(prefix) === 0; + }); +}; + +// Parses an ICE candidate line. Sample input: +// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8 +// rport 55996" +// Input can be prefixed with a=. +SDPUtils.parseCandidate = function (line) { + var parts = void 0; + // Parse both variants. + if (line.indexOf('a=candidate:') === 0) { + parts = line.substring(12).split(' '); + } else { + parts = line.substring(10).split(' '); + } + + var candidate = { + foundation: parts[0], + component: { 1: 'rtp', 2: 'rtcp' }[parts[1]] || parts[1], + protocol: parts[2].toLowerCase(), + priority: parseInt(parts[3], 10), + ip: parts[4], + address: parts[4], // address is an alias for ip. + port: parseInt(parts[5], 10), + // skip parts[6] == 'typ' + type: parts[7] + }; + + for (var i = 8; i < parts.length; i += 2) { + switch (parts[i]) { + case 'raddr': + candidate.relatedAddress = parts[i + 1]; + break; + case 'rport': + candidate.relatedPort = parseInt(parts[i + 1], 10); + break; + case 'tcptype': + candidate.tcpType = parts[i + 1]; + break; + case 'ufrag': + candidate.ufrag = parts[i + 1]; // for backward compatibility. + candidate.usernameFragment = parts[i + 1]; + break; + default: + // extension handling, in particular ufrag. Don't overwrite. + if (candidate[parts[i]] === undefined) { + candidate[parts[i]] = parts[i + 1]; + } + break; + } + } + return candidate; +}; + +// Translates a candidate object into SDP candidate attribute. +// This does not include the a= prefix! +SDPUtils.writeCandidate = function (candidate) { + var sdp = []; + sdp.push(candidate.foundation); + + var component = candidate.component; + if (component === 'rtp') { + sdp.push(1); + } else if (component === 'rtcp') { + sdp.push(2); + } else { + sdp.push(component); + } + sdp.push(candidate.protocol.toUpperCase()); + sdp.push(candidate.priority); + sdp.push(candidate.address || candidate.ip); + sdp.push(candidate.port); + + var type = candidate.type; + sdp.push('typ'); + sdp.push(type); + if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) { + sdp.push('raddr'); + sdp.push(candidate.relatedAddress); + sdp.push('rport'); + sdp.push(candidate.relatedPort); + } + if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') { + sdp.push('tcptype'); + sdp.push(candidate.tcpType); + } + if (candidate.usernameFragment || candidate.ufrag) { + sdp.push('ufrag'); + sdp.push(candidate.usernameFragment || candidate.ufrag); + } + return 'candidate:' + sdp.join(' '); +}; + +// Parses an ice-options line, returns an array of option tags. +// Sample input: +// a=ice-options:foo bar +SDPUtils.parseIceOptions = function (line) { + return line.substr(14).split(' '); +}; + +// Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input: +// a=rtpmap:111 opus/48000/2 +SDPUtils.parseRtpMap = function (line) { + var parts = line.substr(9).split(' '); + var parsed = { + payloadType: parseInt(parts.shift(), 10) // was: id + }; + + parts = parts[0].split('/'); + + parsed.name = parts[0]; + parsed.clockRate = parseInt(parts[1], 10); // was: clockrate + parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1; + // legacy alias, got renamed back to channels in ORTC. + parsed.numChannels = parsed.channels; + return parsed; +}; + +// Generates a rtpmap line from RTCRtpCodecCapability or +// RTCRtpCodecParameters. +SDPUtils.writeRtpMap = function (codec) { + var pt = codec.payloadType; + if (codec.preferredPayloadType !== undefined) { + pt = codec.preferredPayloadType; + } + var channels = codec.channels || codec.numChannels || 1; + return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n'; +}; + +// Parses a extmap line (headerextension from RFC 5285). Sample input: +// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset +// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset +SDPUtils.parseExtmap = function (line) { + var parts = line.substr(9).split(' '); + return { + id: parseInt(parts[0], 10), + direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv', + uri: parts[1] + }; +}; + +// Generates an extmap line from RTCRtpHeaderExtensionParameters or +// RTCRtpHeaderExtension. +SDPUtils.writeExtmap = function (headerExtension) { + return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + '\r\n'; +}; + +// Parses a fmtp line, returns dictionary. Sample input: +// a=fmtp:96 vbr=on;cng=on +// Also deals with vbr=on; cng=on +SDPUtils.parseFmtp = function (line) { + var parsed = {}; + var kv = void 0; + var parts = line.substr(line.indexOf(' ') + 1).split(';'); + for (var j = 0; j < parts.length; j++) { + kv = parts[j].trim().split('='); + parsed[kv[0].trim()] = kv[1]; + } + return parsed; +}; + +// Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters. +SDPUtils.writeFmtp = function (codec) { + var line = ''; + var pt = codec.payloadType; + if (codec.preferredPayloadType !== undefined) { + pt = codec.preferredPayloadType; + } + if (codec.parameters && Object.keys(codec.parameters).length) { + var params = []; + Object.keys(codec.parameters).forEach(function (param) { + if (codec.parameters[param] !== undefined) { + params.push(param + '=' + codec.parameters[param]); + } else { + params.push(param); + } + }); + line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n'; + } + return line; +}; + +// Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input: +// a=rtcp-fb:98 nack rpsi +SDPUtils.parseRtcpFb = function (line) { + var parts = line.substr(line.indexOf(' ') + 1).split(' '); + return { + type: parts.shift(), + parameter: parts.join(' ') + }; +}; + +// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters. +SDPUtils.writeRtcpFb = function (codec) { + var lines = ''; + var pt = codec.payloadType; + if (codec.preferredPayloadType !== undefined) { + pt = codec.preferredPayloadType; + } + if (codec.rtcpFeedback && codec.rtcpFeedback.length) { + // FIXME: special handling for trr-int? + codec.rtcpFeedback.forEach(function (fb) { + lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n'; + }); + } + return lines; +}; + +// Parses a RFC 5576 ssrc media attribute. Sample input: +// a=ssrc:3735928559 cname:something +SDPUtils.parseSsrcMedia = function (line) { + var sp = line.indexOf(' '); + var parts = { + ssrc: parseInt(line.substr(7, sp - 7), 10) + }; + var colon = line.indexOf(':', sp); + if (colon > -1) { + parts.attribute = line.substr(sp + 1, colon - sp - 1); + parts.value = line.substr(colon + 1); + } else { + parts.attribute = line.substr(sp + 1); + } + return parts; +}; + +// Parse a ssrc-group line (see RFC 5576). Sample input: +// a=ssrc-group:semantics 12 34 +SDPUtils.parseSsrcGroup = function (line) { + var parts = line.substr(13).split(' '); + return { + semantics: parts.shift(), + ssrcs: parts.map(function (ssrc) { + return parseInt(ssrc, 10); + }) + }; +}; + +// Extracts the MID (RFC 5888) from a media section. +// Returns the MID or undefined if no mid line was found. +SDPUtils.getMid = function (mediaSection) { + var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0]; + if (mid) { + return mid.substr(6); + } +}; + +// Parses a fingerprint line for DTLS-SRTP. +SDPUtils.parseFingerprint = function (line) { + var parts = line.substr(14).split(' '); + return { + algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge. + value: parts[1].toUpperCase() // the definition is upper-case in RFC 4572. + }; +}; + +// Extracts DTLS parameters from SDP media section or sessionpart. +// FIXME: for consistency with other functions this should only +// get the fingerprint line as input. See also getIceParameters. +SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) { + var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:'); + // Note: a=setup line is ignored since we use the 'auto' role in Edge. + return { + role: 'auto', + fingerprints: lines.map(SDPUtils.parseFingerprint) + }; +}; + +// Serializes DTLS parameters to SDP. +SDPUtils.writeDtlsParameters = function (params, setupType) { + var sdp = 'a=setup:' + setupType + '\r\n'; + params.fingerprints.forEach(function (fp) { + sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n'; + }); + return sdp; +}; + +// Parses a=crypto lines into +// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members +SDPUtils.parseCryptoLine = function (line) { + var parts = line.substr(9).split(' '); + return { + tag: parseInt(parts[0], 10), + cryptoSuite: parts[1], + keyParams: parts[2], + sessionParams: parts.slice(3) + }; +}; + +SDPUtils.writeCryptoLine = function (parameters) { + return 'a=crypto:' + parameters.tag + ' ' + parameters.cryptoSuite + ' ' + (_typeof(parameters.keyParams) === 'object' ? SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') + '\r\n'; +}; + +// Parses the crypto key parameters into +// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam* +SDPUtils.parseCryptoKeyParams = function (keyParams) { + if (keyParams.indexOf('inline:') !== 0) { + return null; + } + var parts = keyParams.substr(7).split('|'); + return { + keyMethod: 'inline', + keySalt: parts[0], + lifeTime: parts[1], + mkiValue: parts[2] ? parts[2].split(':')[0] : undefined, + mkiLength: parts[2] ? parts[2].split(':')[1] : undefined + }; +}; + +SDPUtils.writeCryptoKeyParams = function (keyParams) { + return keyParams.keyMethod + ':' + keyParams.keySalt + (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') + (keyParams.mkiValue && keyParams.mkiLength ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength : ''); +}; + +// Extracts all SDES parameters. +SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) { + var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=crypto:'); + return lines.map(SDPUtils.parseCryptoLine); +}; + +// Parses ICE information from SDP media section or sessionpart. +// FIXME: for consistency with other functions this should only +// get the ice-ufrag and ice-pwd lines as input. +SDPUtils.getIceParameters = function (mediaSection, sessionpart) { + var ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-ufrag:')[0]; + var pwd = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-pwd:')[0]; + if (!(ufrag && pwd)) { + return null; + } + return { + usernameFragment: ufrag.substr(12), + password: pwd.substr(10) + }; +}; + +// Serializes ICE parameters to SDP. +SDPUtils.writeIceParameters = function (params) { + var sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n'; + if (params.iceLite) { + sdp += 'a=ice-lite\r\n'; + } + return sdp; +}; + +// Parses the SDP media section and returns RTCRtpParameters. +SDPUtils.parseRtpParameters = function (mediaSection) { + var description = { + codecs: [], + headerExtensions: [], + fecMechanisms: [], + rtcp: [] + }; + var lines = SDPUtils.splitLines(mediaSection); + var mline = lines[0].split(' '); + for (var i = 3; i < mline.length; i++) { + // find all codecs from mline[3..] + var pt = mline[i]; + var rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0]; + if (rtpmapline) { + var codec = SDPUtils.parseRtpMap(rtpmapline); + var fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' '); + // Only the first a=fmtp: is considered. + codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {}; + codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb); + description.codecs.push(codec); + // parse FEC mechanisms from rtpmap lines. + switch (codec.name.toUpperCase()) { + case 'RED': + case 'ULPFEC': + description.fecMechanisms.push(codec.name.toUpperCase()); + break; + default: + // only RED and ULPFEC are recognized as FEC mechanisms. + break; + } + } + } + SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function (line) { + description.headerExtensions.push(SDPUtils.parseExtmap(line)); + }); + // FIXME: parse rtcp. + return description; +}; + +// Generates parts of the SDP media section describing the capabilities / +// parameters. +SDPUtils.writeRtpDescription = function (kind, caps) { + var sdp = ''; + + // Build the mline. + sdp += 'm=' + kind + ' '; + sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs. + sdp += ' UDP/TLS/RTP/SAVPF '; + sdp += caps.codecs.map(function (codec) { + if (codec.preferredPayloadType !== undefined) { + return codec.preferredPayloadType; + } + return codec.payloadType; + }).join(' ') + '\r\n'; + + sdp += 'c=IN IP4 0.0.0.0\r\n'; + sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n'; + + // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb. + caps.codecs.forEach(function (codec) { + sdp += SDPUtils.writeRtpMap(codec); + sdp += SDPUtils.writeFmtp(codec); + sdp += SDPUtils.writeRtcpFb(codec); + }); + var maxptime = 0; + caps.codecs.forEach(function (codec) { + if (codec.maxptime > maxptime) { + maxptime = codec.maxptime; + } + }); + if (maxptime > 0) { + sdp += 'a=maxptime:' + maxptime + '\r\n'; + } + + if (caps.headerExtensions) { + caps.headerExtensions.forEach(function (extension) { + sdp += SDPUtils.writeExtmap(extension); + }); + } + // FIXME: write fecMechanisms. + return sdp; +}; + +// Parses the SDP media section and returns an array of +// RTCRtpEncodingParameters. +SDPUtils.parseRtpEncodingParameters = function (mediaSection) { + var encodingParameters = []; + var description = SDPUtils.parseRtpParameters(mediaSection); + var hasRed = description.fecMechanisms.indexOf('RED') !== -1; + var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1; + + // filter a=ssrc:... cname:, ignore PlanB-msid + var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { + return SDPUtils.parseSsrcMedia(line); + }).filter(function (parts) { + return parts.attribute === 'cname'; + }); + var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc; + var secondarySsrc = void 0; + + var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(function (line) { + var parts = line.substr(17).split(' '); + return parts.map(function (part) { + return parseInt(part, 10); + }); + }); + if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) { + secondarySsrc = flows[0][1]; + } + + description.codecs.forEach(function (codec) { + if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) { + var encParam = { + ssrc: primarySsrc, + codecPayloadType: parseInt(codec.parameters.apt, 10) + }; + if (primarySsrc && secondarySsrc) { + encParam.rtx = { ssrc: secondarySsrc }; + } + encodingParameters.push(encParam); + if (hasRed) { + encParam = JSON.parse(JSON.stringify(encParam)); + encParam.fec = { + ssrc: primarySsrc, + mechanism: hasUlpfec ? 'red+ulpfec' : 'red' + }; + encodingParameters.push(encParam); + } + } + }); + if (encodingParameters.length === 0 && primarySsrc) { + encodingParameters.push({ + ssrc: primarySsrc + }); + } + + // we support both b=AS and b=TIAS but interpret AS as TIAS. + var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b='); + if (bandwidth.length) { + if (bandwidth[0].indexOf('b=TIAS:') === 0) { + bandwidth = parseInt(bandwidth[0].substr(7), 10); + } else if (bandwidth[0].indexOf('b=AS:') === 0) { + // use formula from JSEP to convert b=AS to TIAS value. + bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95 - 50 * 40 * 8; + } else { + bandwidth = undefined; + } + encodingParameters.forEach(function (params) { + params.maxBitrate = bandwidth; + }); + } + return encodingParameters; +}; + +// parses http://draft.ortc.org/#rtcrtcpparameters* +SDPUtils.parseRtcpParameters = function (mediaSection) { + var rtcpParameters = {}; + + // Gets the first SSRC. Note that with RTX there might be multiple + // SSRCs. + var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { + return SDPUtils.parseSsrcMedia(line); + }).filter(function (obj) { + return obj.attribute === 'cname'; + })[0]; + if (remoteSsrc) { + rtcpParameters.cname = remoteSsrc.value; + rtcpParameters.ssrc = remoteSsrc.ssrc; + } + + // Edge uses the compound attribute instead of reducedSize + // compound is !reducedSize + var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize'); + rtcpParameters.reducedSize = rsize.length > 0; + rtcpParameters.compound = rsize.length === 0; + + // parses the rtcp-mux attrіbute. + // Note that Edge does not support unmuxed RTCP. + var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux'); + rtcpParameters.mux = mux.length > 0; + + return rtcpParameters; +}; + +SDPUtils.writeRtcpParameters = function (rtcpParameters) { + var sdp = ''; + if (rtcpParameters.reducedSize) { + sdp += 'a=rtcp-rsize\r\n'; + } + if (rtcpParameters.mux) { + sdp += 'a=rtcp-mux\r\n'; + } + if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) { + sdp += 'a=ssrc:' + rtcpParameters.ssrc + ' cname:' + rtcpParameters.cname + '\r\n'; + } + return sdp; +}; + +// parses either a=msid: or a=ssrc:... msid lines and returns +// the id of the MediaStream and MediaStreamTrack. +SDPUtils.parseMsid = function (mediaSection) { + var parts = void 0; + var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:'); + if (spec.length === 1) { + parts = spec[0].substr(7).split(' '); + return { stream: parts[0], track: parts[1] }; + } + var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { + return SDPUtils.parseSsrcMedia(line); + }).filter(function (msidParts) { + return msidParts.attribute === 'msid'; + }); + if (planB.length > 0) { + parts = planB[0].value.split(' '); + return { stream: parts[0], track: parts[1] }; + } +}; + +// SCTP +// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back +// to draft-ietf-mmusic-sctp-sdp-05 +SDPUtils.parseSctpDescription = function (mediaSection) { + var mline = SDPUtils.parseMLine(mediaSection); + var maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:'); + var maxMessageSize = void 0; + if (maxSizeLine.length > 0) { + maxMessageSize = parseInt(maxSizeLine[0].substr(19), 10); + } + if (isNaN(maxMessageSize)) { + maxMessageSize = 65536; + } + var sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:'); + if (sctpPort.length > 0) { + return { + port: parseInt(sctpPort[0].substr(12), 10), + protocol: mline.fmt, + maxMessageSize: maxMessageSize + }; + } + var sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:'); + if (sctpMapLines.length > 0) { + var parts = sctpMapLines[0].substr(10).split(' '); + return { + port: parseInt(parts[0], 10), + protocol: parts[1], + maxMessageSize: maxMessageSize + }; + } +}; + +// SCTP +// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers +// support by now receiving in this format, unless we originally parsed +// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line +// protocol of DTLS/SCTP -- without UDP/ or TCP/) +SDPUtils.writeSctpDescription = function (media, sctp) { + var output = []; + if (media.protocol !== 'DTLS/SCTP') { + output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n']; + } else { + output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n']; + } + if (sctp.maxMessageSize !== undefined) { + output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n'); + } + return output.join(''); +}; + +// Generate a session ID for SDP. +// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1 +// recommends using a cryptographically random +ve 64-bit value +// but right now this should be acceptable and within the right range +SDPUtils.generateSessionId = function () { + return Math.random().toString().substr(2, 21); +}; + +// Write boiler plate for start of SDP +// sessId argument is optional - if not supplied it will +// be generated randomly +// sessVersion is optional and defaults to 2 +// sessUser is optional and defaults to 'thisisadapterortc' +SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) { + var sessionId = void 0; + var version = sessVer !== undefined ? sessVer : 2; + if (sessId) { + sessionId = sessId; + } else { + sessionId = SDPUtils.generateSessionId(); + } + var user = sessUser || 'thisisadapterortc'; + // FIXME: sess-id should be an NTP timestamp. + return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n'; +}; + +// Gets the direction from the mediaSection or the sessionpart. +SDPUtils.getDirection = function (mediaSection, sessionpart) { + // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv. + var lines = SDPUtils.splitLines(mediaSection); + for (var i = 0; i < lines.length; i++) { + switch (lines[i]) { + case 'a=sendrecv': + case 'a=sendonly': + case 'a=recvonly': + case 'a=inactive': + return lines[i].substr(2); + default: + // FIXME: What should happen here? + } + } + if (sessionpart) { + return SDPUtils.getDirection(sessionpart); + } + return 'sendrecv'; +}; + +SDPUtils.getKind = function (mediaSection) { + var lines = SDPUtils.splitLines(mediaSection); + var mline = lines[0].split(' '); + return mline[0].substr(2); +}; + +SDPUtils.isRejected = function (mediaSection) { + return mediaSection.split(' ', 2)[1] === '0'; +}; + +SDPUtils.parseMLine = function (mediaSection) { + var lines = SDPUtils.splitLines(mediaSection); + var parts = lines[0].substr(2).split(' '); + return { + kind: parts[0], + port: parseInt(parts[1], 10), + protocol: parts[2], + fmt: parts.slice(3).join(' ') + }; +}; + +SDPUtils.parseOLine = function (mediaSection) { + var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0]; + var parts = line.substr(2).split(' '); + return { + username: parts[0], + sessionId: parts[1], + sessionVersion: parseInt(parts[2], 10), + netType: parts[3], + addressType: parts[4], + address: parts[5] + }; +}; + +// a very naive interpretation of a valid SDP. +SDPUtils.isValidSDP = function (blob) { + if (typeof blob !== 'string' || blob.length === 0) { + return false; + } + var lines = SDPUtils.splitLines(blob); + for (var i = 0; i < lines.length; i++) { + if (lines[i].length < 2 || lines[i].charAt(1) !== '=') { + return false; + } + // TODO: check the modifier a bit more. + } + return true; +}; + +// Expose public methods. +if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { + module.exports = SDPUtils; +} +},{}]},{},[1])(1) +}); \ No newline at end of file diff --git a/hybrid/html/rtc/chrome/chrome_shim.js b/hybrid/html/rtc/chrome/chrome_shim.js new file mode 100644 index 0000000..55717ef --- /dev/null +++ b/hybrid/html/rtc/chrome/chrome_shim.js @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + /* eslint-env node */ +'use strict'; +import * as utils from '../utils.js'; + +export {shimGetUserMedia} from './getusermedia'; +export {shimGetDisplayMedia} from './getdisplaymedia'; + +export function shimMediaStream(window) { + window.MediaStream = window.MediaStream || window.webkitMediaStream; +} + +export function shimOnTrack(window) { + if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in + window.RTCPeerConnection.prototype)) { + Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', { + get() { + return this._ontrack; + }, + set(f) { + if (this._ontrack) { + this.removeEventListener('track', this._ontrack); + } + this.addEventListener('track', this._ontrack = f); + }, + enumerable: true, + configurable: true + }); + const origSetRemoteDescription = + window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = + function setRemoteDescription() { + if (!this._ontrackpoly) { + this._ontrackpoly = (e) => { + // onaddstream does not fire when a track is added to an existing + // stream. But stream.onaddtrack is implemented so we use that. + e.stream.addEventListener('addtrack', te => { + let receiver; + if (window.RTCPeerConnection.prototype.getReceivers) { + receiver = this.getReceivers() + .find(r => r.track && r.track.id === te.track.id); + } else { + receiver = {track: te.track}; + } + + const event = new Event('track'); + event.track = te.track; + event.receiver = receiver; + event.transceiver = {receiver}; + event.streams = [e.stream]; + this.dispatchEvent(event); + }); + e.stream.getTracks().forEach(track => { + let receiver; + if (window.RTCPeerConnection.prototype.getReceivers) { + receiver = this.getReceivers() + .find(r => r.track && r.track.id === track.id); + } else { + receiver = {track}; + } + const event = new Event('track'); + event.track = track; + event.receiver = receiver; + event.transceiver = {receiver}; + event.streams = [e.stream]; + this.dispatchEvent(event); + }); + }; + this.addEventListener('addstream', this._ontrackpoly); + } + return origSetRemoteDescription.apply(this, arguments); + }; + } else { + // even if RTCRtpTransceiver is in window, it is only used and + // emitted in unified-plan. Unfortunately this means we need + // to unconditionally wrap the event. + utils.wrapPeerConnectionEvent(window, 'track', e => { + if (!e.transceiver) { + Object.defineProperty(e, 'transceiver', + {value: {receiver: e.receiver}}); + } + return e; + }); + } +} + +export function shimGetSendersWithDtmf(window) { + // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack. + if (typeof window === 'object' && window.RTCPeerConnection && + !('getSenders' in window.RTCPeerConnection.prototype) && + 'createDTMFSender' in window.RTCPeerConnection.prototype) { + const shimSenderWithDtmf = function(pc, track) { + return { + track, + get dtmf() { + if (this._dtmf === undefined) { + if (track.kind === 'audio') { + this._dtmf = pc.createDTMFSender(track); + } else { + this._dtmf = null; + } + } + return this._dtmf; + }, + _pc: pc + }; + }; + + // augment addTrack when getSenders is not available. + if (!window.RTCPeerConnection.prototype.getSenders) { + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + this._senders = this._senders || []; + return this._senders.slice(); // return a copy of the internal state. + }; + const origAddTrack = window.RTCPeerConnection.prototype.addTrack; + window.RTCPeerConnection.prototype.addTrack = + function addTrack(track, stream) { + let sender = origAddTrack.apply(this, arguments); + if (!sender) { + sender = shimSenderWithDtmf(this, track); + this._senders.push(sender); + } + return sender; + }; + + const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack; + window.RTCPeerConnection.prototype.removeTrack = + function removeTrack(sender) { + origRemoveTrack.apply(this, arguments); + const idx = this._senders.indexOf(sender); + if (idx !== -1) { + this._senders.splice(idx, 1); + } + }; + } + const origAddStream = window.RTCPeerConnection.prototype.addStream; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + this._senders = this._senders || []; + origAddStream.apply(this, [stream]); + stream.getTracks().forEach(track => { + this._senders.push(shimSenderWithDtmf(this, track)); + }); + }; + + const origRemoveStream = window.RTCPeerConnection.prototype.removeStream; + window.RTCPeerConnection.prototype.removeStream = + function removeStream(stream) { + this._senders = this._senders || []; + origRemoveStream.apply(this, [stream]); + + stream.getTracks().forEach(track => { + const sender = this._senders.find(s => s.track === track); + if (sender) { // remove sender + this._senders.splice(this._senders.indexOf(sender), 1); + } + }); + }; + } else if (typeof window === 'object' && window.RTCPeerConnection && + 'getSenders' in window.RTCPeerConnection.prototype && + 'createDTMFSender' in window.RTCPeerConnection.prototype && + window.RTCRtpSender && + !('dtmf' in window.RTCRtpSender.prototype)) { + const origGetSenders = window.RTCPeerConnection.prototype.getSenders; + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + const senders = origGetSenders.apply(this, []); + senders.forEach(sender => sender._pc = this); + return senders; + }; + + Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', { + get() { + if (this._dtmf === undefined) { + if (this.track.kind === 'audio') { + this._dtmf = this._pc.createDTMFSender(this.track); + } else { + this._dtmf = null; + } + } + return this._dtmf; + } + }); + } +} + +export function shimGetStats(window) { + if (!window.RTCPeerConnection) { + return; + } + + const origGetStats = window.RTCPeerConnection.prototype.getStats; + window.RTCPeerConnection.prototype.getStats = function getStats() { + const [selector, onSucc, onErr] = arguments; + + // If selector is a function then we are in the old style stats so just + // pass back the original getStats format to avoid breaking old users. + if (arguments.length > 0 && typeof selector === 'function') { + return origGetStats.apply(this, arguments); + } + + // When spec-style getStats is supported, return those when called with + // either no arguments or the selector argument is null. + if (origGetStats.length === 0 && (arguments.length === 0 || + typeof selector !== 'function')) { + return origGetStats.apply(this, []); + } + + const fixChromeStats_ = function(response) { + const standardReport = {}; + const reports = response.result(); + reports.forEach(report => { + const standardStats = { + id: report.id, + timestamp: report.timestamp, + type: { + localcandidate: 'local-candidate', + remotecandidate: 'remote-candidate' + }[report.type] || report.type + }; + report.names().forEach(name => { + standardStats[name] = report.stat(name); + }); + standardReport[standardStats.id] = standardStats; + }); + + return standardReport; + }; + + // shim getStats with maplike support + const makeMapStats = function(stats) { + return new Map(Object.keys(stats).map(key => [key, stats[key]])); + }; + + if (arguments.length >= 2) { + const successCallbackWrapper_ = function(response) { + onSucc(makeMapStats(fixChromeStats_(response))); + }; + + return origGetStats.apply(this, [successCallbackWrapper_, + selector]); + } + + // promise-support + return new Promise((resolve, reject) => { + origGetStats.apply(this, [ + function(response) { + resolve(makeMapStats(fixChromeStats_(response))); + }, reject]); + }).then(onSucc, onErr); + }; +} + +export function shimSenderReceiverGetStats(window) { + if (!(typeof window === 'object' && window.RTCPeerConnection && + window.RTCRtpSender && window.RTCRtpReceiver)) { + return; + } + + // shim sender stats. + if (!('getStats' in window.RTCRtpSender.prototype)) { + const origGetSenders = window.RTCPeerConnection.prototype.getSenders; + if (origGetSenders) { + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + const senders = origGetSenders.apply(this, []); + senders.forEach(sender => sender._pc = this); + return senders; + }; + } + + const origAddTrack = window.RTCPeerConnection.prototype.addTrack; + if (origAddTrack) { + window.RTCPeerConnection.prototype.addTrack = function addTrack() { + const sender = origAddTrack.apply(this, arguments); + sender._pc = this; + return sender; + }; + } + window.RTCRtpSender.prototype.getStats = function getStats() { + const sender = this; + return this._pc.getStats().then(result => + /* Note: this will include stats of all senders that + * send a track with the same id as sender.track as + * it is not possible to identify the RTCRtpSender. + */ + utils.filterStats(result, sender.track, true)); + }; + } + + // shim receiver stats. + if (!('getStats' in window.RTCRtpReceiver.prototype)) { + const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers; + if (origGetReceivers) { + window.RTCPeerConnection.prototype.getReceivers = + function getReceivers() { + const receivers = origGetReceivers.apply(this, []); + receivers.forEach(receiver => receiver._pc = this); + return receivers; + }; + } + utils.wrapPeerConnectionEvent(window, 'track', e => { + e.receiver._pc = e.srcElement; + return e; + }); + window.RTCRtpReceiver.prototype.getStats = function getStats() { + const receiver = this; + return this._pc.getStats().then(result => + utils.filterStats(result, receiver.track, false)); + }; + } + + if (!('getStats' in window.RTCRtpSender.prototype && + 'getStats' in window.RTCRtpReceiver.prototype)) { + return; + } + + // shim RTCPeerConnection.getStats(track). + const origGetStats = window.RTCPeerConnection.prototype.getStats; + window.RTCPeerConnection.prototype.getStats = function getStats() { + if (arguments.length > 0 && + arguments[0] instanceof window.MediaStreamTrack) { + const track = arguments[0]; + let sender; + let receiver; + let err; + this.getSenders().forEach(s => { + if (s.track === track) { + if (sender) { + err = true; + } else { + sender = s; + } + } + }); + this.getReceivers().forEach(r => { + if (r.track === track) { + if (receiver) { + err = true; + } else { + receiver = r; + } + } + return r.track === track; + }); + if (err || (sender && receiver)) { + return Promise.reject(new DOMException( + 'There are more than one sender or receiver for the track.', + 'InvalidAccessError')); + } else if (sender) { + return sender.getStats(); + } else if (receiver) { + return receiver.getStats(); + } + return Promise.reject(new DOMException( + 'There is no sender or receiver for the track.', + 'InvalidAccessError')); + } + return origGetStats.apply(this, arguments); + }; +} + +export function shimAddTrackRemoveTrackWithNative(window) { + // shim addTrack/removeTrack with native variants in order to make + // the interactions with legacy getLocalStreams behave as in other browsers. + // Keeps a mapping stream.id => [stream, rtpsenders...] + window.RTCPeerConnection.prototype.getLocalStreams = + function getLocalStreams() { + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + return Object.keys(this._shimmedLocalStreams) + .map(streamId => this._shimmedLocalStreams[streamId][0]); + }; + + const origAddTrack = window.RTCPeerConnection.prototype.addTrack; + window.RTCPeerConnection.prototype.addTrack = + function addTrack(track, stream) { + if (!stream) { + return origAddTrack.apply(this, arguments); + } + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + + const sender = origAddTrack.apply(this, arguments); + if (!this._shimmedLocalStreams[stream.id]) { + this._shimmedLocalStreams[stream.id] = [stream, sender]; + } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) { + this._shimmedLocalStreams[stream.id].push(sender); + } + return sender; + }; + + const origAddStream = window.RTCPeerConnection.prototype.addStream; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + + stream.getTracks().forEach(track => { + const alreadyExists = this.getSenders().find(s => s.track === track); + if (alreadyExists) { + throw new DOMException('Track already exists.', + 'InvalidAccessError'); + } + }); + const existingSenders = this.getSenders(); + origAddStream.apply(this, arguments); + const newSenders = this.getSenders() + .filter(newSender => existingSenders.indexOf(newSender) === -1); + this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders); + }; + + const origRemoveStream = window.RTCPeerConnection.prototype.removeStream; + window.RTCPeerConnection.prototype.removeStream = + function removeStream(stream) { + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + delete this._shimmedLocalStreams[stream.id]; + return origRemoveStream.apply(this, arguments); + }; + + const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack; + window.RTCPeerConnection.prototype.removeTrack = + function removeTrack(sender) { + this._shimmedLocalStreams = this._shimmedLocalStreams || {}; + if (sender) { + Object.keys(this._shimmedLocalStreams).forEach(streamId => { + const idx = this._shimmedLocalStreams[streamId].indexOf(sender); + if (idx !== -1) { + this._shimmedLocalStreams[streamId].splice(idx, 1); + } + if (this._shimmedLocalStreams[streamId].length === 1) { + delete this._shimmedLocalStreams[streamId]; + } + }); + } + return origRemoveTrack.apply(this, arguments); + }; +} + +export function shimAddTrackRemoveTrack(window, browserDetails) { + if (!window.RTCPeerConnection) { + return; + } + // shim addTrack and removeTrack. + if (window.RTCPeerConnection.prototype.addTrack && + browserDetails.version >= 65) { + return shimAddTrackRemoveTrackWithNative(window); + } + + // also shim pc.getLocalStreams when addTrack is shimmed + // to return the original streams. + const origGetLocalStreams = window.RTCPeerConnection.prototype + .getLocalStreams; + window.RTCPeerConnection.prototype.getLocalStreams = + function getLocalStreams() { + const nativeStreams = origGetLocalStreams.apply(this); + this._reverseStreams = this._reverseStreams || {}; + return nativeStreams.map(stream => this._reverseStreams[stream.id]); + }; + + const origAddStream = window.RTCPeerConnection.prototype.addStream; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + this._streams = this._streams || {}; + this._reverseStreams = this._reverseStreams || {}; + + stream.getTracks().forEach(track => { + const alreadyExists = this.getSenders().find(s => s.track === track); + if (alreadyExists) { + throw new DOMException('Track already exists.', + 'InvalidAccessError'); + } + }); + // Add identity mapping for consistency with addTrack. + // Unless this is being used with a stream from addTrack. + if (!this._reverseStreams[stream.id]) { + const newStream = new window.MediaStream(stream.getTracks()); + this._streams[stream.id] = newStream; + this._reverseStreams[newStream.id] = stream; + stream = newStream; + } + origAddStream.apply(this, [stream]); + }; + + const origRemoveStream = window.RTCPeerConnection.prototype.removeStream; + window.RTCPeerConnection.prototype.removeStream = + function removeStream(stream) { + this._streams = this._streams || {}; + this._reverseStreams = this._reverseStreams || {}; + + origRemoveStream.apply(this, [(this._streams[stream.id] || stream)]); + delete this._reverseStreams[(this._streams[stream.id] ? + this._streams[stream.id].id : stream.id)]; + delete this._streams[stream.id]; + }; + + window.RTCPeerConnection.prototype.addTrack = + function addTrack(track, stream) { + if (this.signalingState === 'closed') { + throw new DOMException( + 'The RTCPeerConnection\'s signalingState is \'closed\'.', + 'InvalidStateError'); + } + const streams = [].slice.call(arguments, 1); + if (streams.length !== 1 || + !streams[0].getTracks().find(t => t === track)) { + // this is not fully correct but all we can manage without + // [[associated MediaStreams]] internal slot. + throw new DOMException( + 'The adapter.js addTrack polyfill only supports a single ' + + ' stream which is associated with the specified track.', + 'NotSupportedError'); + } + + const alreadyExists = this.getSenders().find(s => s.track === track); + if (alreadyExists) { + throw new DOMException('Track already exists.', + 'InvalidAccessError'); + } + + this._streams = this._streams || {}; + this._reverseStreams = this._reverseStreams || {}; + const oldStream = this._streams[stream.id]; + if (oldStream) { + // this is using odd Chrome behaviour, use with caution: + // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815 + // Note: we rely on the high-level addTrack/dtmf shim to + // create the sender with a dtmf sender. + oldStream.addTrack(track); + + // Trigger ONN async. + Promise.resolve().then(() => { + this.dispatchEvent(new Event('negotiationneeded')); + }); + } else { + const newStream = new window.MediaStream([track]); + this._streams[stream.id] = newStream; + this._reverseStreams[newStream.id] = stream; + this.addStream(newStream); + } + return this.getSenders().find(s => s.track === track); + }; + + // replace the internal stream id with the external one and + // vice versa. + function replaceInternalStreamId(pc, description) { + let sdp = description.sdp; + Object.keys(pc._reverseStreams || []).forEach(internalId => { + const externalStream = pc._reverseStreams[internalId]; + const internalStream = pc._streams[externalStream.id]; + sdp = sdp.replace(new RegExp(internalStream.id, 'g'), + externalStream.id); + }); + return new RTCSessionDescription({ + type: description.type, + sdp + }); + } + function replaceExternalStreamId(pc, description) { + let sdp = description.sdp; + Object.keys(pc._reverseStreams || []).forEach(internalId => { + const externalStream = pc._reverseStreams[internalId]; + const internalStream = pc._streams[externalStream.id]; + sdp = sdp.replace(new RegExp(externalStream.id, 'g'), + internalStream.id); + }); + return new RTCSessionDescription({ + type: description.type, + sdp + }); + } + ['createOffer', 'createAnswer'].forEach(function(method) { + const nativeMethod = window.RTCPeerConnection.prototype[method]; + const methodObj = {[method]() { + const args = arguments; + const isLegacyCall = arguments.length && + typeof arguments[0] === 'function'; + if (isLegacyCall) { + return nativeMethod.apply(this, [ + (description) => { + const desc = replaceInternalStreamId(this, description); + args[0].apply(null, [desc]); + }, + (err) => { + if (args[1]) { + args[1].apply(null, err); + } + }, arguments[2] + ]); + } + return nativeMethod.apply(this, arguments) + .then(description => replaceInternalStreamId(this, description)); + }}; + window.RTCPeerConnection.prototype[method] = methodObj[method]; + }); + + const origSetLocalDescription = + window.RTCPeerConnection.prototype.setLocalDescription; + window.RTCPeerConnection.prototype.setLocalDescription = + function setLocalDescription() { + if (!arguments.length || !arguments[0].type) { + return origSetLocalDescription.apply(this, arguments); + } + arguments[0] = replaceExternalStreamId(this, arguments[0]); + return origSetLocalDescription.apply(this, arguments); + }; + + // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier + + const origLocalDescription = Object.getOwnPropertyDescriptor( + window.RTCPeerConnection.prototype, 'localDescription'); + Object.defineProperty(window.RTCPeerConnection.prototype, + 'localDescription', { + get() { + const description = origLocalDescription.get.apply(this); + if (description.type === '') { + return description; + } + return replaceInternalStreamId(this, description); + } + }); + + window.RTCPeerConnection.prototype.removeTrack = + function removeTrack(sender) { + if (this.signalingState === 'closed') { + throw new DOMException( + 'The RTCPeerConnection\'s signalingState is \'closed\'.', + 'InvalidStateError'); + } + // We can not yet check for sender instanceof RTCRtpSender + // since we shim RTPSender. So we check if sender._pc is set. + if (!sender._pc) { + throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + + 'does not implement interface RTCRtpSender.', 'TypeError'); + } + const isLocal = sender._pc === this; + if (!isLocal) { + throw new DOMException('Sender was not created by this connection.', + 'InvalidAccessError'); + } + + // Search for the native stream the senders track belongs to. + this._streams = this._streams || {}; + let stream; + Object.keys(this._streams).forEach(streamid => { + const hasTrack = this._streams[streamid].getTracks() + .find(track => sender.track === track); + if (hasTrack) { + stream = this._streams[streamid]; + } + }); + + if (stream) { + if (stream.getTracks().length === 1) { + // if this is the last track of the stream, remove the stream. This + // takes care of any shimmed _senders. + this.removeStream(this._reverseStreams[stream.id]); + } else { + // relying on the same odd chrome behaviour as above. + stream.removeTrack(sender.track); + } + this.dispatchEvent(new Event('negotiationneeded')); + } + }; +} + +export function shimPeerConnection(window, browserDetails) { + if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) { + // very basic support for old versions. + window.RTCPeerConnection = window.webkitRTCPeerConnection; + } + if (!window.RTCPeerConnection) { + return; + } + + // shim implicit creation of RTCSessionDescription/RTCIceCandidate + if (browserDetails.version < 53) { + ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'] + .forEach(function(method) { + const nativeMethod = window.RTCPeerConnection.prototype[method]; + const methodObj = {[method]() { + arguments[0] = new ((method === 'addIceCandidate') ? + window.RTCIceCandidate : + window.RTCSessionDescription)(arguments[0]); + return nativeMethod.apply(this, arguments); + }}; + window.RTCPeerConnection.prototype[method] = methodObj[method]; + }); + } +} + +// Attempt to fix ONN in plan-b mode. +export function fixNegotiationNeeded(window, browserDetails) { + utils.wrapPeerConnectionEvent(window, 'negotiationneeded', e => { + const pc = e.target; + if (browserDetails.version < 72 || (pc.getConfiguration && + pc.getConfiguration().sdpSemantics === 'plan-b')) { + if (pc.signalingState !== 'stable') { + return; + } + } + return e; + }); +} diff --git a/hybrid/html/rtc/chrome/getdisplaymedia.js b/hybrid/html/rtc/chrome/getdisplaymedia.js new file mode 100644 index 0000000..1e8f6ec --- /dev/null +++ b/hybrid/html/rtc/chrome/getdisplaymedia.js @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; +export function shimGetDisplayMedia(window, getSourceId) { + if (window.navigator.mediaDevices && + 'getDisplayMedia' in window.navigator.mediaDevices) { + return; + } + if (!(window.navigator.mediaDevices)) { + return; + } + // getSourceId is a function that returns a promise resolving with + // the sourceId of the screen/window/tab to be shared. + if (typeof getSourceId !== 'function') { + console.error('shimGetDisplayMedia: getSourceId argument is not ' + + 'a function'); + return; + } + window.navigator.mediaDevices.getDisplayMedia = + function getDisplayMedia(constraints) { + return getSourceId(constraints) + .then(sourceId => { + const widthSpecified = constraints.video && constraints.video.width; + const heightSpecified = constraints.video && + constraints.video.height; + const frameRateSpecified = constraints.video && + constraints.video.frameRate; + constraints.video = { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: sourceId, + maxFrameRate: frameRateSpecified || 3 + } + }; + if (widthSpecified) { + constraints.video.mandatory.maxWidth = widthSpecified; + } + if (heightSpecified) { + constraints.video.mandatory.maxHeight = heightSpecified; + } + return window.navigator.mediaDevices.getUserMedia(constraints); + }); + }; +} diff --git a/hybrid/html/rtc/chrome/getusermedia.js b/hybrid/html/rtc/chrome/getusermedia.js new file mode 100644 index 0000000..ad834ff --- /dev/null +++ b/hybrid/html/rtc/chrome/getusermedia.js @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; +import * as utils from '../utils.js'; +const logging = utils.log; + +export function shimGetUserMedia(window, browserDetails) { + const navigator = window && window.navigator; + + if (!navigator.mediaDevices) { + return; + } + + const constraintsToChrome_ = function(c) { + if (typeof c !== 'object' || c.mandatory || c.optional) { + return c; + } + const cc = {}; + Object.keys(c).forEach(key => { + if (key === 'require' || key === 'advanced' || key === 'mediaSource') { + return; + } + const r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]}; + if (r.exact !== undefined && typeof r.exact === 'number') { + r.min = r.max = r.exact; + } + const oldname_ = function(prefix, name) { + if (prefix) { + return prefix + name.charAt(0).toUpperCase() + name.slice(1); + } + return (name === 'deviceId') ? 'sourceId' : name; + }; + if (r.ideal !== undefined) { + cc.optional = cc.optional || []; + let oc = {}; + if (typeof r.ideal === 'number') { + oc[oldname_('min', key)] = r.ideal; + cc.optional.push(oc); + oc = {}; + oc[oldname_('max', key)] = r.ideal; + cc.optional.push(oc); + } else { + oc[oldname_('', key)] = r.ideal; + cc.optional.push(oc); + } + } + if (r.exact !== undefined && typeof r.exact !== 'number') { + cc.mandatory = cc.mandatory || {}; + cc.mandatory[oldname_('', key)] = r.exact; + } else { + ['min', 'max'].forEach(mix => { + if (r[mix] !== undefined) { + cc.mandatory = cc.mandatory || {}; + cc.mandatory[oldname_(mix, key)] = r[mix]; + } + }); + } + }); + if (c.advanced) { + cc.optional = (cc.optional || []).concat(c.advanced); + } + return cc; + }; + + const shimConstraints_ = function(constraints, func) { + if (browserDetails.version >= 61) { + return func(constraints); + } + constraints = JSON.parse(JSON.stringify(constraints)); + if (constraints && typeof constraints.audio === 'object') { + const remap = function(obj, a, b) { + if (a in obj && !(b in obj)) { + obj[b] = obj[a]; + delete obj[a]; + } + }; + constraints = JSON.parse(JSON.stringify(constraints)); + remap(constraints.audio, 'autoGainControl', 'googAutoGainControl'); + remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression'); + constraints.audio = constraintsToChrome_(constraints.audio); + } + if (constraints && typeof constraints.video === 'object') { + // Shim facingMode for mobile & surface pro. + let face = constraints.video.facingMode; + face = face && ((typeof face === 'object') ? face : {ideal: face}); + const getSupportedFacingModeLies = browserDetails.version < 66; + + if ((face && (face.exact === 'user' || face.exact === 'environment' || + face.ideal === 'user' || face.ideal === 'environment')) && + !(navigator.mediaDevices.getSupportedConstraints && + navigator.mediaDevices.getSupportedConstraints().facingMode && + !getSupportedFacingModeLies)) { + delete constraints.video.facingMode; + let matches; + if (face.exact === 'environment' || face.ideal === 'environment') { + matches = ['back', 'rear']; + } else if (face.exact === 'user' || face.ideal === 'user') { + matches = ['front']; + } + if (matches) { + // Look for matches in label, or use last cam for back (typical). + return navigator.mediaDevices.enumerateDevices() + .then(devices => { + devices = devices.filter(d => d.kind === 'videoinput'); + let dev = devices.find(d => matches.some(match => + d.label.toLowerCase().includes(match))); + if (!dev && devices.length && matches.includes('back')) { + dev = devices[devices.length - 1]; // more likely the back cam + } + if (dev) { + constraints.video.deviceId = face.exact ? {exact: dev.deviceId} : + {ideal: dev.deviceId}; + } + constraints.video = constraintsToChrome_(constraints.video); + logging('chrome: ' + JSON.stringify(constraints)); + return func(constraints); + }); + } + } + constraints.video = constraintsToChrome_(constraints.video); + } + logging('chrome: ' + JSON.stringify(constraints)); + return func(constraints); + }; + + const shimError_ = function(e) { + if (browserDetails.version >= 64) { + return e; + } + return { + name: { + PermissionDeniedError: 'NotAllowedError', + PermissionDismissedError: 'NotAllowedError', + InvalidStateError: 'NotAllowedError', + DevicesNotFoundError: 'NotFoundError', + ConstraintNotSatisfiedError: 'OverconstrainedError', + TrackStartError: 'NotReadableError', + MediaDeviceFailedDueToShutdown: 'NotAllowedError', + MediaDeviceKillSwitchOn: 'NotAllowedError', + TabCaptureError: 'AbortError', + ScreenCaptureError: 'AbortError', + DeviceCaptureError: 'AbortError' + }[e.name] || e.name, + message: e.message, + constraint: e.constraint || e.constraintName, + toString() { + return this.name + (this.message && ': ') + this.message; + } + }; + }; + + const getUserMedia_ = function(constraints, onSuccess, onError) { + shimConstraints_(constraints, c => { + navigator.webkitGetUserMedia(c, onSuccess, e => { + if (onError) { + onError(shimError_(e)); + } + }); + }); + }; + navigator.getUserMedia = getUserMedia_.bind(navigator); + + // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia + // function which returns a Promise, it does not accept spec-style + // constraints. + if (navigator.mediaDevices.getUserMedia) { + const origGetUserMedia = navigator.mediaDevices.getUserMedia. + bind(navigator.mediaDevices); + navigator.mediaDevices.getUserMedia = function(cs) { + return shimConstraints_(cs, c => origGetUserMedia(c).then(stream => { + if (c.audio && !stream.getAudioTracks().length || + c.video && !stream.getVideoTracks().length) { + stream.getTracks().forEach(track => { + track.stop(); + }); + throw new DOMException('', 'NotFoundError'); + } + return stream; + }, e => Promise.reject(shimError_(e)))); + }; + } +} diff --git a/hybrid/html/rtc/common_shim.js b/hybrid/html/rtc/common_shim.js new file mode 100644 index 0000000..9211145 --- /dev/null +++ b/hybrid/html/rtc/common_shim.js @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +import SDPUtils from 'sdp'; +import * as utils from './utils'; + +export function shimRTCIceCandidate(window) { + // foundation is arbitrarily chosen as an indicator for full support for + // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface + if (!window.RTCIceCandidate || (window.RTCIceCandidate && 'foundation' in + window.RTCIceCandidate.prototype)) { + return; + } + + const NativeRTCIceCandidate = window.RTCIceCandidate; + window.RTCIceCandidate = function RTCIceCandidate(args) { + // Remove the a= which shouldn't be part of the candidate string. + if (typeof args === 'object' && args.candidate && + args.candidate.indexOf('a=') === 0) { + args = JSON.parse(JSON.stringify(args)); + args.candidate = args.candidate.substr(2); + } + + if (args.candidate && args.candidate.length) { + // Augment the native candidate with the parsed fields. + const nativeCandidate = new NativeRTCIceCandidate(args); + const parsedCandidate = SDPUtils.parseCandidate(args.candidate); + const augmentedCandidate = Object.assign(nativeCandidate, + parsedCandidate); + + // Add a serializer that does not serialize the extra attributes. + augmentedCandidate.toJSON = function toJSON() { + return { + candidate: augmentedCandidate.candidate, + sdpMid: augmentedCandidate.sdpMid, + sdpMLineIndex: augmentedCandidate.sdpMLineIndex, + usernameFragment: augmentedCandidate.usernameFragment, + }; + }; + return augmentedCandidate; + } + return new NativeRTCIceCandidate(args); + }; + window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype; + + // Hook up the augmented candidate in onicecandidate and + // addEventListener('icecandidate', ...) + utils.wrapPeerConnectionEvent(window, 'icecandidate', e => { + if (e.candidate) { + Object.defineProperty(e, 'candidate', { + value: new window.RTCIceCandidate(e.candidate), + writable: 'false' + }); + } + return e; + }); +} + +export function shimMaxMessageSize(window, browserDetails) { + if (!window.RTCPeerConnection) { + return; + } + + if (!('sctp' in window.RTCPeerConnection.prototype)) { + Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', { + get() { + return typeof this._sctp === 'undefined' ? null : this._sctp; + } + }); + } + + const sctpInDescription = function(description) { + if (!description || !description.sdp) { + return false; + } + const sections = SDPUtils.splitSections(description.sdp); + sections.shift(); + return sections.some(mediaSection => { + const mLine = SDPUtils.parseMLine(mediaSection); + return mLine && mLine.kind === 'application' + && mLine.protocol.indexOf('SCTP') !== -1; + }); + }; + + const getRemoteFirefoxVersion = function(description) { + // TODO: Is there a better solution for detecting Firefox? + const match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/); + if (match === null || match.length < 2) { + return -1; + } + const version = parseInt(match[1], 10); + // Test for NaN (yes, this is ugly) + return version !== version ? -1 : version; + }; + + const getCanSendMaxMessageSize = function(remoteIsFirefox) { + // Every implementation we know can send at least 64 KiB. + // Note: Although Chrome is technically able to send up to 256 KiB, the + // data does not reach the other peer reliably. + // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419 + let canSendMaxMessageSize = 65536; + if (browserDetails.browser === 'firefox') { + if (browserDetails.version < 57) { + if (remoteIsFirefox === -1) { + // FF < 57 will send in 16 KiB chunks using the deprecated PPID + // fragmentation. + canSendMaxMessageSize = 16384; + } else { + // However, other FF (and RAWRTC) can reassemble PPID-fragmented + // messages. Thus, supporting ~2 GiB when sending. + canSendMaxMessageSize = 2147483637; + } + } else if (browserDetails.version < 60) { + // Currently, all FF >= 57 will reset the remote maximum message size + // to the default value when a data channel is created at a later + // stage. :( + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 + canSendMaxMessageSize = + browserDetails.version === 57 ? 65535 : 65536; + } else { + // FF >= 60 supports sending ~2 GiB + canSendMaxMessageSize = 2147483637; + } + } + return canSendMaxMessageSize; + }; + + const getMaxMessageSize = function(description, remoteIsFirefox) { + // Note: 65536 bytes is the default value from the SDP spec. Also, + // every implementation we know supports receiving 65536 bytes. + let maxMessageSize = 65536; + + // FF 57 has a slightly incorrect default remote max message size, so + // we need to adjust it here to avoid a failure when sending. + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697 + if (browserDetails.browser === 'firefox' + && browserDetails.version === 57) { + maxMessageSize = 65535; + } + + const match = SDPUtils.matchPrefix(description.sdp, + 'a=max-message-size:'); + if (match.length > 0) { + maxMessageSize = parseInt(match[0].substr(19), 10); + } else if (browserDetails.browser === 'firefox' && + remoteIsFirefox !== -1) { + // If the maximum message size is not present in the remote SDP and + // both local and remote are Firefox, the remote peer can receive + // ~2 GiB. + maxMessageSize = 2147483637; + } + return maxMessageSize; + }; + + const origSetRemoteDescription = + window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = + function setRemoteDescription() { + this._sctp = null; + // Chrome decided to not expose .sctp in plan-b mode. + // As usual, adapter.js has to do an 'ugly worakaround' + // to cover up the mess. + if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) { + const {sdpSemantics} = this.getConfiguration(); + if (sdpSemantics === 'plan-b') { + Object.defineProperty(this, 'sctp', { + get() { + return typeof this._sctp === 'undefined' ? null : this._sctp; + }, + enumerable: true, + configurable: true, + }); + } + } + + if (sctpInDescription(arguments[0])) { + // Check if the remote is FF. + const isFirefox = getRemoteFirefoxVersion(arguments[0]); + + // Get the maximum message size the local peer is capable of sending + const canSendMMS = getCanSendMaxMessageSize(isFirefox); + + // Get the maximum message size of the remote peer. + const remoteMMS = getMaxMessageSize(arguments[0], isFirefox); + + // Determine final maximum message size + let maxMessageSize; + if (canSendMMS === 0 && remoteMMS === 0) { + maxMessageSize = Number.POSITIVE_INFINITY; + } else if (canSendMMS === 0 || remoteMMS === 0) { + maxMessageSize = Math.max(canSendMMS, remoteMMS); + } else { + maxMessageSize = Math.min(canSendMMS, remoteMMS); + } + + // Create a dummy RTCSctpTransport object and the 'maxMessageSize' + // attribute. + const sctp = {}; + Object.defineProperty(sctp, 'maxMessageSize', { + get() { + return maxMessageSize; + } + }); + this._sctp = sctp; + } + + return origSetRemoteDescription.apply(this, arguments); + }; +} + +export function shimSendThrowTypeError(window) { + if (!(window.RTCPeerConnection && + 'createDataChannel' in window.RTCPeerConnection.prototype)) { + return; + } + + // Note: Although Firefox >= 57 has a native implementation, the maximum + // message size can be reset for all data channels at a later stage. + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 + + function wrapDcSend(dc, pc) { + const origDataChannelSend = dc.send; + dc.send = function send() { + const data = arguments[0]; + const length = data.length || data.size || data.byteLength; + if (dc.readyState === 'open' && + pc.sctp && length > pc.sctp.maxMessageSize) { + throw new TypeError('Message too large (can send a maximum of ' + + pc.sctp.maxMessageSize + ' bytes)'); + } + return origDataChannelSend.apply(dc, arguments); + }; + } + const origCreateDataChannel = + window.RTCPeerConnection.prototype.createDataChannel; + window.RTCPeerConnection.prototype.createDataChannel = + function createDataChannel() { + const dataChannel = origCreateDataChannel.apply(this, arguments); + wrapDcSend(dataChannel, this); + return dataChannel; + }; + utils.wrapPeerConnectionEvent(window, 'datachannel', e => { + wrapDcSend(e.channel, e.target); + return e; + }); +} + + +/* shims RTCConnectionState by pretending it is the same as iceConnectionState. + * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12 + * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect + * since DTLS failures would be hidden. See + * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827 + * for the Firefox tracking bug. + */ +export function shimConnectionState(window) { + if (!window.RTCPeerConnection || + 'connectionState' in window.RTCPeerConnection.prototype) { + return; + } + const proto = window.RTCPeerConnection.prototype; + Object.defineProperty(proto, 'connectionState', { + get() { + return { + completed: 'connected', + checking: 'connecting' + }[this.iceConnectionState] || this.iceConnectionState; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(proto, 'onconnectionstatechange', { + get() { + return this._onconnectionstatechange || null; + }, + set(cb) { + if (this._onconnectionstatechange) { + this.removeEventListener('connectionstatechange', + this._onconnectionstatechange); + delete this._onconnectionstatechange; + } + if (cb) { + this.addEventListener('connectionstatechange', + this._onconnectionstatechange = cb); + } + }, + enumerable: true, + configurable: true + }); + + ['setLocalDescription', 'setRemoteDescription'].forEach((method) => { + const origMethod = proto[method]; + proto[method] = function() { + if (!this._connectionstatechangepoly) { + this._connectionstatechangepoly = e => { + const pc = e.target; + if (pc._lastConnectionState !== pc.connectionState) { + pc._lastConnectionState = pc.connectionState; + const newEvent = new Event('connectionstatechange', e); + pc.dispatchEvent(newEvent); + } + return e; + }; + this.addEventListener('iceconnectionstatechange', + this._connectionstatechangepoly); + } + return origMethod.apply(this, arguments); + }; + }); +} + +export function removeExtmapAllowMixed(window, browserDetails) { + /* remove a=extmap-allow-mixed for webrtc.org < M71 */ + if (!window.RTCPeerConnection) { + return; + } + if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) { + return; + } + if (browserDetails.browser === 'safari' && browserDetails.version >= 605) { + return; + } + const nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = + function setRemoteDescription(desc) { + if (desc && desc.sdp && desc.sdp.indexOf('\na=extmap-allow-mixed') !== -1) { + const sdp = desc.sdp.split('\n').filter((line) => { + return line.trim() !== 'a=extmap-allow-mixed'; + }).join('\n'); + // Safari enforces read-only-ness of RTCSessionDescription fields. + if (window.RTCSessionDescription && + desc instanceof window.RTCSessionDescription) { + arguments[0] = new window.RTCSessionDescription({ + type: desc.type, + sdp, + }); + } else { + desc.sdp = sdp; + } + } + return nativeSRD.apply(this, arguments); + }; +} + +export function shimAddIceCandidateNullOrEmpty(window, browserDetails) { + // Support for addIceCandidate(null or undefined) + // as well as addIceCandidate({candidate: "", ...}) + // https://bugs.chromium.org/p/chromium/issues/detail?id=978582 + // Note: must be called before other polyfills which change the signature. + if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) { + return; + } + const nativeAddIceCandidate = + window.RTCPeerConnection.prototype.addIceCandidate; + if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) { + return; + } + window.RTCPeerConnection.prototype.addIceCandidate = + function addIceCandidate() { + if (!arguments[0]) { + if (arguments[1]) { + arguments[1].apply(null); + } + return Promise.resolve(); + } + // Firefox 68+ emits and processes {candidate: "", ...}, ignore + // in older versions. + // Native support for ignoring exists for Chrome M77+. + // Safari ignores as well, exact version unknown but works in the same + // version that also ignores addIceCandidate(null). + if (((browserDetails.browser === 'chrome' && browserDetails.version < 78) + || (browserDetails.browser === 'firefox' + && browserDetails.version < 68) + || (browserDetails.browser === 'safari')) + && arguments[0] && arguments[0].candidate === '') { + return Promise.resolve(); + } + return nativeAddIceCandidate.apply(this, arguments); + }; +} + +// Note: Make sure to call this ahead of APIs that modify +// setLocalDescription.length +export function shimParameterlessSetLocalDescription(window, browserDetails) { + if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) { + return; + } + const nativeSetLocalDescription = + window.RTCPeerConnection.prototype.setLocalDescription; + if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) { + return; + } + window.RTCPeerConnection.prototype.setLocalDescription = + function setLocalDescription() { + let desc = arguments[0] || {}; + if (typeof desc !== 'object' || (desc.type && desc.sdp)) { + return nativeSetLocalDescription.apply(this, arguments); + } + // The remaining steps should technically happen when SLD comes off the + // RTCPeerConnection's operations chain (not ahead of going on it), but + // this is too difficult to shim. Instead, this shim only covers the + // common case where the operations chain is empty. This is imperfect, but + // should cover many cases. Rationale: Even if we can't reduce the glare + // window to zero on imperfect implementations, there's value in tapping + // into the perfect negotiation pattern that several browsers support. + desc = {type: desc.type, sdp: desc.sdp}; + if (!desc.type) { + switch (this.signalingState) { + case 'stable': + case 'have-local-offer': + case 'have-remote-pranswer': + desc.type = 'offer'; + break; + default: + desc.type = 'answer'; + break; + } + } + if (desc.sdp || (desc.type !== 'offer' && desc.type !== 'answer')) { + return nativeSetLocalDescription.apply(this, [desc]); + } + const func = desc.type === 'offer' ? this.createOffer : this.createAnswer; + return func.apply(this) + .then(d => nativeSetLocalDescription.apply(this, [d])); + }; +} diff --git a/hybrid/html/rtc/firefox/firefox_shim.js b/hybrid/html/rtc/firefox/firefox_shim.js new file mode 100644 index 0000000..8c8548f --- /dev/null +++ b/hybrid/html/rtc/firefox/firefox_shim.js @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +import * as utils from '../utils'; +export {shimGetUserMedia} from './getusermedia'; +export {shimGetDisplayMedia} from './getdisplaymedia'; + +export function shimOnTrack(window) { + if (typeof window === 'object' && window.RTCTrackEvent && + ('receiver' in window.RTCTrackEvent.prototype) && + !('transceiver' in window.RTCTrackEvent.prototype)) { + Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { + get() { + return {receiver: this.receiver}; + } + }); + } +} + +export function shimPeerConnection(window, browserDetails) { + if (typeof window !== 'object' || + !(window.RTCPeerConnection || window.mozRTCPeerConnection)) { + return; // probably media.peerconnection.enabled=false in about:config + } + if (!window.RTCPeerConnection && window.mozRTCPeerConnection) { + // very basic support for old versions. + window.RTCPeerConnection = window.mozRTCPeerConnection; + } + + if (browserDetails.version < 53) { + // shim away need for obsolete RTCIceCandidate/RTCSessionDescription. + ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'] + .forEach(function(method) { + const nativeMethod = window.RTCPeerConnection.prototype[method]; + const methodObj = {[method]() { + arguments[0] = new ((method === 'addIceCandidate') ? + window.RTCIceCandidate : + window.RTCSessionDescription)(arguments[0]); + return nativeMethod.apply(this, arguments); + }}; + window.RTCPeerConnection.prototype[method] = methodObj[method]; + }); + } + + const modernStatsTypes = { + inboundrtp: 'inbound-rtp', + outboundrtp: 'outbound-rtp', + candidatepair: 'candidate-pair', + localcandidate: 'local-candidate', + remotecandidate: 'remote-candidate' + }; + + const nativeGetStats = window.RTCPeerConnection.prototype.getStats; + window.RTCPeerConnection.prototype.getStats = function getStats() { + const [selector, onSucc, onErr] = arguments; + return nativeGetStats.apply(this, [selector || null]) + .then(stats => { + if (browserDetails.version < 53 && !onSucc) { + // Shim only promise getStats with spec-hyphens in type names + // Leave callback version alone; misc old uses of forEach before Map + try { + stats.forEach(stat => { + stat.type = modernStatsTypes[stat.type] || stat.type; + }); + } catch (e) { + if (e.name !== 'TypeError') { + throw e; + } + // Avoid TypeError: "type" is read-only, in old versions. 34-43ish + stats.forEach((stat, i) => { + stats.set(i, Object.assign({}, stat, { + type: modernStatsTypes[stat.type] || stat.type + })); + }); + } + } + return stats; + }) + .then(onSucc, onErr); + }; +} + +export function shimSenderGetStats(window) { + if (!(typeof window === 'object' && window.RTCPeerConnection && + window.RTCRtpSender)) { + return; + } + if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) { + return; + } + const origGetSenders = window.RTCPeerConnection.prototype.getSenders; + if (origGetSenders) { + window.RTCPeerConnection.prototype.getSenders = function getSenders() { + const senders = origGetSenders.apply(this, []); + senders.forEach(sender => sender._pc = this); + return senders; + }; + } + + const origAddTrack = window.RTCPeerConnection.prototype.addTrack; + if (origAddTrack) { + window.RTCPeerConnection.prototype.addTrack = function addTrack() { + const sender = origAddTrack.apply(this, arguments); + sender._pc = this; + return sender; + }; + } + window.RTCRtpSender.prototype.getStats = function getStats() { + return this.track ? this._pc.getStats(this.track) : + Promise.resolve(new Map()); + }; +} + +export function shimReceiverGetStats(window) { + if (!(typeof window === 'object' && window.RTCPeerConnection && + window.RTCRtpSender)) { + return; + } + if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) { + return; + } + const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers; + if (origGetReceivers) { + window.RTCPeerConnection.prototype.getReceivers = function getReceivers() { + const receivers = origGetReceivers.apply(this, []); + receivers.forEach(receiver => receiver._pc = this); + return receivers; + }; + } + utils.wrapPeerConnectionEvent(window, 'track', e => { + e.receiver._pc = e.srcElement; + return e; + }); + window.RTCRtpReceiver.prototype.getStats = function getStats() { + return this._pc.getStats(this.track); + }; +} + +export function shimRemoveStream(window) { + if (!window.RTCPeerConnection || + 'removeStream' in window.RTCPeerConnection.prototype) { + return; + } + window.RTCPeerConnection.prototype.removeStream = + function removeStream(stream) { + utils.deprecated('removeStream', 'removeTrack'); + this.getSenders().forEach(sender => { + if (sender.track && stream.getTracks().includes(sender.track)) { + this.removeTrack(sender); + } + }); + }; +} + +export function shimRTCDataChannel(window) { + // rename DataChannel to RTCDataChannel (native fix in FF60): + // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851 + if (window.DataChannel && !window.RTCDataChannel) { + window.RTCDataChannel = window.DataChannel; + } +} + +export function shimAddTransceiver(window) { + // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 + // Firefox ignores the init sendEncodings options passed to addTransceiver + // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 + if (!(typeof window === 'object' && window.RTCPeerConnection)) { + return; + } + const origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver; + if (origAddTransceiver) { + window.RTCPeerConnection.prototype.addTransceiver = + function addTransceiver() { + this.setParametersPromises = []; + const initParameters = arguments[1]; + const shouldPerformCheck = initParameters && + 'sendEncodings' in initParameters; + if (shouldPerformCheck) { + // If sendEncodings params are provided, validate grammar + initParameters.sendEncodings.forEach((encodingParam) => { + if ('rid' in encodingParam) { + const ridRegex = /^[a-z0-9]{0,16}$/i; + if (!ridRegex.test(encodingParam.rid)) { + throw new TypeError('Invalid RID value provided.'); + } + } + if ('scaleResolutionDownBy' in encodingParam) { + if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) { + throw new RangeError('scale_resolution_down_by must be >= 1.0'); + } + } + if ('maxFramerate' in encodingParam) { + if (!(parseFloat(encodingParam.maxFramerate) >= 0)) { + throw new RangeError('max_framerate must be >= 0.0'); + } + } + }); + } + const transceiver = origAddTransceiver.apply(this, arguments); + if (shouldPerformCheck) { + // Check if the init options were applied. If not we do this in an + // asynchronous way and save the promise reference in a global object. + // This is an ugly hack, but at the same time is way more robust than + // checking the sender parameters before and after the createOffer + // Also note that after the createoffer we are not 100% sure that + // the params were asynchronously applied so we might miss the + // opportunity to recreate offer. + const {sender} = transceiver; + const params = sender.getParameters(); + if (!('encodings' in params) || + // Avoid being fooled by patched getParameters() below. + (params.encodings.length === 1 && + Object.keys(params.encodings[0]).length === 0)) { + params.encodings = initParameters.sendEncodings; + sender.sendEncodings = initParameters.sendEncodings; + this.setParametersPromises.push(sender.setParameters(params) + .then(() => { + delete sender.sendEncodings; + }).catch(() => { + delete sender.sendEncodings; + }) + ); + } + } + return transceiver; + }; + } +} + +export function shimGetParameters(window) { + if (!(typeof window === 'object' && window.RTCRtpSender)) { + return; + } + const origGetParameters = window.RTCRtpSender.prototype.getParameters; + if (origGetParameters) { + window.RTCRtpSender.prototype.getParameters = + function getParameters() { + const params = origGetParameters.apply(this, arguments); + if (!('encodings' in params)) { + params.encodings = [].concat(this.sendEncodings || [{}]); + } + return params; + }; + } +} + +export function shimCreateOffer(window) { + // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 + // Firefox ignores the init sendEncodings options passed to addTransceiver + // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 + if (!(typeof window === 'object' && window.RTCPeerConnection)) { + return; + } + const origCreateOffer = window.RTCPeerConnection.prototype.createOffer; + window.RTCPeerConnection.prototype.createOffer = function createOffer() { + if (this.setParametersPromises && this.setParametersPromises.length) { + return Promise.all(this.setParametersPromises) + .then(() => { + return origCreateOffer.apply(this, arguments); + }) + .finally(() => { + this.setParametersPromises = []; + }); + } + return origCreateOffer.apply(this, arguments); + }; +} + +export function shimCreateAnswer(window) { + // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 + // Firefox ignores the init sendEncodings options passed to addTransceiver + // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 + if (!(typeof window === 'object' && window.RTCPeerConnection)) { + return; + } + const origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer; + window.RTCPeerConnection.prototype.createAnswer = function createAnswer() { + if (this.setParametersPromises && this.setParametersPromises.length) { + return Promise.all(this.setParametersPromises) + .then(() => { + return origCreateAnswer.apply(this, arguments); + }) + .finally(() => { + this.setParametersPromises = []; + }); + } + return origCreateAnswer.apply(this, arguments); + }; +} diff --git a/hybrid/html/rtc/firefox/getdisplaymedia.js b/hybrid/html/rtc/firefox/getdisplaymedia.js new file mode 100644 index 0000000..0ecce44 --- /dev/null +++ b/hybrid/html/rtc/firefox/getdisplaymedia.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +export function shimGetDisplayMedia(window, preferredMediaSource) { + if (window.navigator.mediaDevices && + 'getDisplayMedia' in window.navigator.mediaDevices) { + return; + } + if (!(window.navigator.mediaDevices)) { + return; + } + window.navigator.mediaDevices.getDisplayMedia = + function getDisplayMedia(constraints) { + if (!(constraints && constraints.video)) { + const err = new DOMException('getDisplayMedia without video ' + + 'constraints is undefined'); + err.name = 'NotFoundError'; + // from https://heycam.github.io/webidl/#idl-DOMException-error-names + err.code = 8; + return Promise.reject(err); + } + if (constraints.video === true) { + constraints.video = {mediaSource: preferredMediaSource}; + } else { + constraints.video.mediaSource = preferredMediaSource; + } + return window.navigator.mediaDevices.getUserMedia(constraints); + }; +} diff --git a/hybrid/html/rtc/firefox/getusermedia.js b/hybrid/html/rtc/firefox/getusermedia.js new file mode 100644 index 0000000..fe4de50 --- /dev/null +++ b/hybrid/html/rtc/firefox/getusermedia.js @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ +'use strict'; + +import * as utils from '../utils'; + +export function shimGetUserMedia(window, browserDetails) { + const navigator = window && window.navigator; + const MediaStreamTrack = window && window.MediaStreamTrack; + + navigator.getUserMedia = function(constraints, onSuccess, onError) { + // Replace Firefox 44+'s deprecation warning with unprefixed version. + utils.deprecated('navigator.getUserMedia', + 'navigator.mediaDevices.getUserMedia'); + navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError); + }; + + if (!(browserDetails.version > 55 && + 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) { + const remap = function(obj, a, b) { + if (a in obj && !(b in obj)) { + obj[b] = obj[a]; + delete obj[a]; + } + }; + + const nativeGetUserMedia = navigator.mediaDevices.getUserMedia. + bind(navigator.mediaDevices); + navigator.mediaDevices.getUserMedia = function(c) { + if (typeof c === 'object' && typeof c.audio === 'object') { + c = JSON.parse(JSON.stringify(c)); + remap(c.audio, 'autoGainControl', 'mozAutoGainControl'); + remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression'); + } + return nativeGetUserMedia(c); + }; + + if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) { + const nativeGetSettings = MediaStreamTrack.prototype.getSettings; + MediaStreamTrack.prototype.getSettings = function() { + const obj = nativeGetSettings.apply(this, arguments); + remap(obj, 'mozAutoGainControl', 'autoGainControl'); + remap(obj, 'mozNoiseSuppression', 'noiseSuppression'); + return obj; + }; + } + + if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) { + const nativeApplyConstraints = + MediaStreamTrack.prototype.applyConstraints; + MediaStreamTrack.prototype.applyConstraints = function(c) { + if (this.kind === 'audio' && typeof c === 'object') { + c = JSON.parse(JSON.stringify(c)); + remap(c, 'autoGainControl', 'mozAutoGainControl'); + remap(c, 'noiseSuppression', 'mozNoiseSuppression'); + } + return nativeApplyConstraints.apply(this, [c]); + }; + } + } +} diff --git a/hybrid/html/rtc/safari/safari_shim.js b/hybrid/html/rtc/safari/safari_shim.js new file mode 100644 index 0000000..a552ddf --- /dev/null +++ b/hybrid/html/rtc/safari/safari_shim.js @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +'use strict'; +import * as utils from '../utils'; + +export function shimLocalStreamsAPI(window) { + if (typeof window !== 'object' || !window.RTCPeerConnection) { + return; + } + if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) { + window.RTCPeerConnection.prototype.getLocalStreams = + function getLocalStreams() { + if (!this._localStreams) { + this._localStreams = []; + } + return this._localStreams; + }; + } + if (!('addStream' in window.RTCPeerConnection.prototype)) { + const _addTrack = window.RTCPeerConnection.prototype.addTrack; + window.RTCPeerConnection.prototype.addStream = function addStream(stream) { + if (!this._localStreams) { + this._localStreams = []; + } + if (!this._localStreams.includes(stream)) { + this._localStreams.push(stream); + } + // Try to emulate Chrome's behaviour of adding in audio-video order. + // Safari orders by track id. + stream.getAudioTracks().forEach(track => _addTrack.call(this, track, + stream)); + stream.getVideoTracks().forEach(track => _addTrack.call(this, track, + stream)); + }; + + window.RTCPeerConnection.prototype.addTrack = + function addTrack(track, ...streams) { + if (streams) { + streams.forEach((stream) => { + if (!this._localStreams) { + this._localStreams = [stream]; + } else if (!this._localStreams.includes(stream)) { + this._localStreams.push(stream); + } + }); + } + return _addTrack.apply(this, arguments); + }; + } + if (!('removeStream' in window.RTCPeerConnection.prototype)) { + window.RTCPeerConnection.prototype.removeStream = + function removeStream(stream) { + if (!this._localStreams) { + this._localStreams = []; + } + const index = this._localStreams.indexOf(stream); + if (index === -1) { + return; + } + this._localStreams.splice(index, 1); + const tracks = stream.getTracks(); + this.getSenders().forEach(sender => { + if (tracks.includes(sender.track)) { + this.removeTrack(sender); + } + }); + }; + } +} + +export function shimRemoteStreamsAPI(window) { + if (typeof window !== 'object' || !window.RTCPeerConnection) { + return; + } + if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) { + window.RTCPeerConnection.prototype.getRemoteStreams = + function getRemoteStreams() { + return this._remoteStreams ? this._remoteStreams : []; + }; + } + if (!('onaddstream' in window.RTCPeerConnection.prototype)) { + Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', { + get() { + return this._onaddstream; + }, + set(f) { + if (this._onaddstream) { + this.removeEventListener('addstream', this._onaddstream); + this.removeEventListener('track', this._onaddstreampoly); + } + this.addEventListener('addstream', this._onaddstream = f); + this.addEventListener('track', this._onaddstreampoly = (e) => { + e.streams.forEach(stream => { + if (!this._remoteStreams) { + this._remoteStreams = []; + } + if (this._remoteStreams.includes(stream)) { + return; + } + this._remoteStreams.push(stream); + const event = new Event('addstream'); + event.stream = stream; + this.dispatchEvent(event); + }); + }); + } + }); + const origSetRemoteDescription = + window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = + function setRemoteDescription() { + const pc = this; + if (!this._onaddstreampoly) { + this.addEventListener('track', this._onaddstreampoly = function(e) { + e.streams.forEach(stream => { + if (!pc._remoteStreams) { + pc._remoteStreams = []; + } + if (pc._remoteStreams.indexOf(stream) >= 0) { + return; + } + pc._remoteStreams.push(stream); + const event = new Event('addstream'); + event.stream = stream; + pc.dispatchEvent(event); + }); + }); + } + return origSetRemoteDescription.apply(pc, arguments); + }; + } +} + +export function shimCallbacksAPI(window) { + if (typeof window !== 'object' || !window.RTCPeerConnection) { + return; + } + const prototype = window.RTCPeerConnection.prototype; + const origCreateOffer = prototype.createOffer; + const origCreateAnswer = prototype.createAnswer; + const setLocalDescription = prototype.setLocalDescription; + const setRemoteDescription = prototype.setRemoteDescription; + const addIceCandidate = prototype.addIceCandidate; + + prototype.createOffer = + function createOffer(successCallback, failureCallback) { + const options = (arguments.length >= 2) ? arguments[2] : arguments[0]; + const promise = origCreateOffer.apply(this, [options]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + + prototype.createAnswer = + function createAnswer(successCallback, failureCallback) { + const options = (arguments.length >= 2) ? arguments[2] : arguments[0]; + const promise = origCreateAnswer.apply(this, [options]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + + let withCallback = function(description, successCallback, failureCallback) { + const promise = setLocalDescription.apply(this, [description]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + prototype.setLocalDescription = withCallback; + + withCallback = function(description, successCallback, failureCallback) { + const promise = setRemoteDescription.apply(this, [description]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + prototype.setRemoteDescription = withCallback; + + withCallback = function(candidate, successCallback, failureCallback) { + const promise = addIceCandidate.apply(this, [candidate]); + if (!failureCallback) { + return promise; + } + promise.then(successCallback, failureCallback); + return Promise.resolve(); + }; + prototype.addIceCandidate = withCallback; +} + +export function shimGetUserMedia(window) { + const navigator = window && window.navigator; + + if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + // shim not needed in Safari 12.1 + const mediaDevices = navigator.mediaDevices; + const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices); + navigator.mediaDevices.getUserMedia = (constraints) => { + return _getUserMedia(shimConstraints(constraints)); + }; + } + + if (!navigator.getUserMedia && navigator.mediaDevices && + navigator.mediaDevices.getUserMedia) { + navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) { + navigator.mediaDevices.getUserMedia(constraints) + .then(cb, errcb); + }.bind(navigator); + } +} + +export function shimConstraints(constraints) { + if (constraints && constraints.video !== undefined) { + return Object.assign({}, + constraints, + {video: utils.compactObject(constraints.video)} + ); + } + + return constraints; +} + +export function shimRTCIceServerUrls(window) { + if (!window.RTCPeerConnection) { + return; + } + // migrate from non-spec RTCIceServer.url to RTCIceServer.urls + const OrigPeerConnection = window.RTCPeerConnection; + window.RTCPeerConnection = + function RTCPeerConnection(pcConfig, pcConstraints) { + if (pcConfig && pcConfig.iceServers) { + const newIceServers = []; + for (let i = 0; i < pcConfig.iceServers.length; i++) { + let server = pcConfig.iceServers[i]; + if (!server.hasOwnProperty('urls') && + server.hasOwnProperty('url')) { + utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls'); + server = JSON.parse(JSON.stringify(server)); + server.urls = server.url; + delete server.url; + newIceServers.push(server); + } else { + newIceServers.push(pcConfig.iceServers[i]); + } + } + pcConfig.iceServers = newIceServers; + } + return new OrigPeerConnection(pcConfig, pcConstraints); + }; + window.RTCPeerConnection.prototype = OrigPeerConnection.prototype; + // wrap static methods. Currently just generateCertificate. + if ('generateCertificate' in OrigPeerConnection) { + Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', { + get() { + return OrigPeerConnection.generateCertificate; + } + }); + } +} + +export function shimTrackEventTransceiver(window) { + // Add event.transceiver member over deprecated event.receiver + if (typeof window === 'object' && window.RTCTrackEvent && + 'receiver' in window.RTCTrackEvent.prototype && + !('transceiver' in window.RTCTrackEvent.prototype)) { + Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { + get() { + return {receiver: this.receiver}; + } + }); + } +} + +export function shimCreateOfferLegacy(window) { + const origCreateOffer = window.RTCPeerConnection.prototype.createOffer; + window.RTCPeerConnection.prototype.createOffer = + function createOffer(offerOptions) { + if (offerOptions) { + if (typeof offerOptions.offerToReceiveAudio !== 'undefined') { + // support bit values + offerOptions.offerToReceiveAudio = + !!offerOptions.offerToReceiveAudio; + } + const audioTransceiver = this.getTransceivers().find(transceiver => + transceiver.receiver.track.kind === 'audio'); + if (offerOptions.offerToReceiveAudio === false && audioTransceiver) { + if (audioTransceiver.direction === 'sendrecv') { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection('sendonly'); + } else { + audioTransceiver.direction = 'sendonly'; + } + } else if (audioTransceiver.direction === 'recvonly') { + if (audioTransceiver.setDirection) { + audioTransceiver.setDirection('inactive'); + } else { + audioTransceiver.direction = 'inactive'; + } + } + } else if (offerOptions.offerToReceiveAudio === true && + !audioTransceiver) { + this.addTransceiver('audio', {direction: 'recvonly'}); + } + + if (typeof offerOptions.offerToReceiveVideo !== 'undefined') { + // support bit values + offerOptions.offerToReceiveVideo = + !!offerOptions.offerToReceiveVideo; + } + const videoTransceiver = this.getTransceivers().find(transceiver => + transceiver.receiver.track.kind === 'video'); + if (offerOptions.offerToReceiveVideo === false && videoTransceiver) { + if (videoTransceiver.direction === 'sendrecv') { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection('sendonly'); + } else { + videoTransceiver.direction = 'sendonly'; + } + } else if (videoTransceiver.direction === 'recvonly') { + if (videoTransceiver.setDirection) { + videoTransceiver.setDirection('inactive'); + } else { + videoTransceiver.direction = 'inactive'; + } + } + } else if (offerOptions.offerToReceiveVideo === true && + !videoTransceiver) { + this.addTransceiver('video', {direction: 'recvonly'}); + } + } + return origCreateOffer.apply(this, arguments); + }; +} + +export function shimAudioContext(window) { + if (typeof window !== 'object' || window.AudioContext) { + return; + } + window.AudioContext = window.webkitAudioContext; +} + diff --git a/hybrid/html/rtc/utils.js b/hybrid/html/rtc/utils.js new file mode 100644 index 0000000..bcafbfb --- /dev/null +++ b/hybrid/html/rtc/utils.js @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + /* eslint-env node */ +'use strict'; + +let logDisabled_ = true; +let deprecationWarnings_ = true; + +/** + * Extract browser version out of the provided user agent string. + * + * @param {!string} uastring userAgent string. + * @param {!string} expr Regular expression used as match criteria. + * @param {!number} pos position in the version string to be returned. + * @return {!number} browser version. + */ +export function extractVersion(uastring, expr, pos) { + const match = uastring.match(expr); + return match && match.length >= pos && parseInt(match[pos], 10); +} + +// Wraps the peerconnection event eventNameToWrap in a function +// which returns the modified event object (or false to prevent +// the event). +export function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) { + if (!window.RTCPeerConnection) { + return; + } + const proto = window.RTCPeerConnection.prototype; + const nativeAddEventListener = proto.addEventListener; + proto.addEventListener = function(nativeEventName, cb) { + if (nativeEventName !== eventNameToWrap) { + return nativeAddEventListener.apply(this, arguments); + } + const wrappedCallback = (e) => { + const modifiedEvent = wrapper(e); + if (modifiedEvent) { + if (cb.handleEvent) { + cb.handleEvent(modifiedEvent); + } else { + cb(modifiedEvent); + } + } + }; + this._eventMap = this._eventMap || {}; + if (!this._eventMap[eventNameToWrap]) { + this._eventMap[eventNameToWrap] = new Map(); + } + this._eventMap[eventNameToWrap].set(cb, wrappedCallback); + return nativeAddEventListener.apply(this, [nativeEventName, + wrappedCallback]); + }; + + const nativeRemoveEventListener = proto.removeEventListener; + proto.removeEventListener = function(nativeEventName, cb) { + if (nativeEventName !== eventNameToWrap || !this._eventMap + || !this._eventMap[eventNameToWrap]) { + return nativeRemoveEventListener.apply(this, arguments); + } + if (!this._eventMap[eventNameToWrap].has(cb)) { + return nativeRemoveEventListener.apply(this, arguments); + } + const unwrappedCb = this._eventMap[eventNameToWrap].get(cb); + this._eventMap[eventNameToWrap].delete(cb); + if (this._eventMap[eventNameToWrap].size === 0) { + delete this._eventMap[eventNameToWrap]; + } + if (Object.keys(this._eventMap).length === 0) { + delete this._eventMap; + } + return nativeRemoveEventListener.apply(this, [nativeEventName, + unwrappedCb]); + }; + + Object.defineProperty(proto, 'on' + eventNameToWrap, { + get() { + return this['_on' + eventNameToWrap]; + }, + set(cb) { + if (this['_on' + eventNameToWrap]) { + this.removeEventListener(eventNameToWrap, + this['_on' + eventNameToWrap]); + delete this['_on' + eventNameToWrap]; + } + if (cb) { + this.addEventListener(eventNameToWrap, + this['_on' + eventNameToWrap] = cb); + } + }, + enumerable: true, + configurable: true + }); +} + +export function disableLog(bool) { + if (typeof bool !== 'boolean') { + return new Error('Argument type: ' + typeof bool + + '. Please use a boolean.'); + } + logDisabled_ = bool; + return (bool) ? 'adapter.js logging disabled' : + 'adapter.js logging enabled'; +} + +/** + * Disable or enable deprecation warnings + * @param {!boolean} bool set to true to disable warnings. + */ +export function disableWarnings(bool) { + if (typeof bool !== 'boolean') { + return new Error('Argument type: ' + typeof bool + + '. Please use a boolean.'); + } + deprecationWarnings_ = !bool; + return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled'); +} + +export function log() { + if (typeof window === 'object') { + if (logDisabled_) { + return; + } + if (typeof console !== 'undefined' && typeof console.log === 'function') { + console.log.apply(console, arguments); + } + } +} + +/** + * Shows a deprecation warning suggesting the modern and spec-compatible API. + */ +export function deprecated(oldMethod, newMethod) { + if (!deprecationWarnings_) { + return; + } + console.warn(oldMethod + ' is deprecated, please use ' + newMethod + + ' instead.'); +} + +/** + * Browser detector. + * + * @return {object} result containing browser and version + * properties. + */ +export function detectBrowser(window) { + // Returned result object. + const result = {browser: null, version: null}; + + // Fail early if it's not a browser + if (typeof window === 'undefined' || !window.navigator) { + result.browser = 'Not a browser.'; + return result; + } + + const {navigator} = window; + + if (navigator.mozGetUserMedia) { // Firefox. + result.browser = 'firefox'; + result.version = extractVersion(navigator.userAgent, + /Firefox\/(\d+)\./, 1); + } else if (navigator.webkitGetUserMedia || + (window.isSecureContext === false && window.webkitRTCPeerConnection && + !window.RTCIceGatherer)) { + // Chrome, Chromium, Webview, Opera. + // Version matches Chrome/WebRTC version. + // Chrome 74 removed webkitGetUserMedia on http as well so we need the + // more complicated fallback to webkitRTCPeerConnection. + result.browser = 'chrome'; + result.version = extractVersion(navigator.userAgent, + /Chrom(e|ium)\/(\d+)\./, 2); + } else if (window.RTCPeerConnection && + navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) { // Safari. + result.browser = 'safari'; + result.version = extractVersion(navigator.userAgent, + /AppleWebKit\/(\d+)\./, 1); + result.supportsUnifiedPlan = window.RTCRtpTransceiver && + 'currentDirection' in window.RTCRtpTransceiver.prototype; + } else { // Default fallthrough: not supported. + result.browser = 'Not a supported browser.'; + return result; + } + + return result; +} + +/** + * Checks if something is an object. + * + * @param {*} val The something you want to check. + * @return true if val is an object, false otherwise. + */ +function isObject(val) { + return Object.prototype.toString.call(val) === '[object Object]'; +} + +/** + * Remove all empty objects and undefined values + * from a nested object -- an enhanced and vanilla version + * of Lodash's `compact`. + */ +export function compactObject(data) { + if (!isObject(data)) { + return data; + } + + return Object.keys(data).reduce(function(accumulator, key) { + const isObj = isObject(data[key]); + const value = isObj ? compactObject(data[key]) : data[key]; + const isEmptyObject = isObj && !Object.keys(value).length; + if (value === undefined || isEmptyObject) { + return accumulator; + } + return Object.assign(accumulator, {[key]: value}); + }, {}); +} + +/* iterates the stats graph recursively. */ +export function walkStats(stats, base, resultSet) { + if (!base || resultSet.has(base.id)) { + return; + } + resultSet.set(base.id, base); + Object.keys(base).forEach(name => { + if (name.endsWith('Id')) { + walkStats(stats, stats.get(base[name]), resultSet); + } else if (name.endsWith('Ids')) { + base[name].forEach(id => { + walkStats(stats, stats.get(id), resultSet); + }); + } + }); +} + +/* filter getStats for a sender/receiver track. */ +export function filterStats(result, track, outbound) { + const streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp'; + const filteredResult = new Map(); + if (track === null) { + return filteredResult; + } + const trackStats = []; + result.forEach(value => { + if (value.type === 'track' && + value.trackIdentifier === track.id) { + trackStats.push(value); + } + }); + trackStats.forEach(trackStat => { + result.forEach(stats => { + if (stats.type === streamStatsType && stats.trackId === trackStat.id) { + walkStats(result, stats, filteredResult); + } + }); + }); + return filteredResult; +} + diff --git a/hybrid/html/voice/calling.mp3 b/hybrid/html/voice/calling.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3fadd006e35ba3f3e7fcb76557c13c2d4939c351 GIT binary patch literal 76213 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 EPvKs + + + + + + + + + +
+ + + diff --git a/main.js b/main.js new file mode 100644 index 0000000..2aec5ba --- /dev/null +++ b/main.js @@ -0,0 +1,54 @@ + +// #ifdef H5 +import quill from "quill"; +window.Quill = quill; +// #endif + +// #ifndef VUE3 +import Vue from 'vue' +import App from './App' + +Vue.config.productionTip = false + +import cuCustom from './components/cu-custom' +Vue.component('cu-custom',cuCustom) + + +App.mpType = 'app' + +const app = new Vue({ + ...App +}) +app.$mount() +// #endif + + + +// #ifdef VUE3 +import { createSSRApp } from 'vue' +import App from './App.vue' +import cuCustom from './components/cu-custom' +import util from '@/utils/utils.js' +import store from './store' +import '@/utils/request' +import api from '@/api/index.js'; +import socketIO from '@/common/socket.js'; +import Empty from "@/components/Empty.vue" //通用空状态 +import Tags from "@/components/Tags.vue" //通用标签 + +export function createApp() { + const app = createSSRApp(App) + app.config.globalProperties.appStatus=true; + app.config.globalProperties.$util = util; + app.config.globalProperties.$api = api; + app.config.globalProperties.$store = store; + app.config.globalProperties.socketIo = new socketIO() + app.component('cu-custom',cuCustom) + app.component('Empty',Empty) + app.component('Tags',Tags) + app.use(store) + return { + app + } +} +// #endif \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..433c893 --- /dev/null +++ b/manifest.json @@ -0,0 +1,192 @@ +{ + "name" : "Raingad-IM", + "appid" : "__UNI__D1E78EC", + "description" : "聊天小应用", + "versionName" : "5.5.2", + "versionCode" : 20250107, + "transformPx" : false, + "app-plus" : { + /* 5+App特有相关 */ + "usingComponents" : true, + "nvueCompiler" : "uni-app", + "compilerVersion" : 3, + "nvueStyleCompiler" : "uni-app", + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + "modules" : { + "VideoPlayer" : {}, + "Record" : {}, + "UIWebview" : {}, + "Camera" : {}, + "Barcode" : {}, + "Push" : {} + }, + /* 模块配置 */ + "distribute" : { + /* 应用发布信息 */ + "android" : { + /* android打包配置 */ + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ], + "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ], + "minSdkVersion" : 21, + "targetSdkVersion" : "" + }, + "ios" : { + "dSYMs" : false, + "privacyDescription" : { + "NSPhotoLibraryUsageDescription" : "需要发送图片消息", + "NSPhotoLibraryAddUsageDescription" : "需要下载图片或者视频", + "NSCameraUsageDescription" : "需要拍照照片或者视频发送给好友", + "NSMicrophoneUsageDescription" : "需要和好友语音通话或者发送语音消息", + "NSLocationWhenInUseUsageDescription" : "APP将要获取你的位置信息,用于保持APP的活跃,并不会记录您的位置。是否允许?", + "NSLocationAlwaysUsageDescription" : "App将要在后台持续获取您的位置,用于保持APP的活跃,并不会记录您的位置。是否允许?", + "NSLocationAlwaysAndWhenInUseUsageDescription" : "APP将要获取你的位置信息,用于保持APP的活跃,并不会记录您的位置。是否允许?" + }, + "UIBackgroundModes" : "audio,location" + }, + /* ios打包配置 */ + "sdkConfigs" : { + "ad" : {}, + "push" : {}, + "maps" : {}, + "geolocation" : { + "system" : { + "__platform__" : [ "ios", "android" ] + } + } + }, + "icons" : { + "android" : { + "hdpi" : "unpackage/res/icons/72x72.png", + "xhdpi" : "unpackage/res/icons/96x96.png", + "xxhdpi" : "unpackage/res/icons/144x144.png", + "xxxhdpi" : "unpackage/res/icons/192x192.png" + }, + "ios" : { + "appstore" : "unpackage/res/icons/1024x1024.png", + "ipad" : { + "app" : "unpackage/res/icons/76x76.png", + "app@2x" : "unpackage/res/icons/152x152.png", + "notification" : "unpackage/res/icons/20x20.png", + "notification@2x" : "unpackage/res/icons/40x40.png", + "proapp@2x" : "unpackage/res/icons/167x167.png", + "settings" : "unpackage/res/icons/29x29.png", + "settings@2x" : "unpackage/res/icons/58x58.png", + "spotlight" : "unpackage/res/icons/40x40.png", + "spotlight@2x" : "unpackage/res/icons/80x80.png" + }, + "iphone" : { + "app@2x" : "unpackage/res/icons/120x120.png", + "app@3x" : "unpackage/res/icons/180x180.png", + "notification@2x" : "unpackage/res/icons/40x40.png", + "notification@3x" : "unpackage/res/icons/60x60.png", + "settings@2x" : "unpackage/res/icons/58x58.png", + "settings@3x" : "unpackage/res/icons/87x87.png", + "spotlight@2x" : "unpackage/res/icons/80x80.png", + "spotlight@3x" : "unpackage/res/icons/120x120.png" + } + } + }, + "splashscreen" : { + "useOriginalMsgbox" : true + } + }, + "nativePlugins" : { + "lemonjk-FileSelect" : { + "__plugin_info__" : { + "name" : "FileSelect", + "description" : "文件选取插件", + "platforms" : "Android,iOS", + "url" : "", + "android_package_name" : "", + "ios_bundle_id" : "", + "isCloud" : false, + "bought" : -1, + "pid" : "", + "parameters" : {} + } + }, + "Ba-KeepAlive" : { + "__plugin_info__" : { + "name" : "安卓保活(采用多种主流技术) Ba-KeepAlive", + "description" : "原生保活插件,支持市面上大部分机型,Android4.4到13.0 。为定位、推送、websocket、定时任务、蓝牙、聊天等保驾护航(**注意:**不保证支持所有机型和场景,建议先试用再购买)", + "platforms" : "Android", + "url" : "https://ext.dcloud.net.cn/plugin?id=9423", + "android_package_name" : "uni.UNID1E78EC", + "ios_bundle_id" : "", + "isCloud" : true, + "bought" : 1, + "pid" : "9423", + "parameters" : {} + } + } + } + }, + /* SDK配置 */ + "quickapp" : {}, + /* 快应用特有相关 */ + "mp-weixin" : { + /* 小程序特有相关 */ + "appid" : "wxd36ac7a23fbfcfea", + "setting" : { + "urlCheck" : false, + "minified" : true, + "ignoreDevUnusedFiles" : false, + "ignoreUploadUnusedFiles" : false + }, + "lazyCodeLoading" : "requiredComponents", + "usingComponents" : true, + "permission" : {}, + "unipush" : { + "enable" : false + }, + "libVersion" : "latest" + }, + "vueVersion" : "3", + "h5" : { + "router" : { + "mode" : "hash", + "base" : "./" + }, + "devServer" : { + "https" : false, + "port" : "" + }, + "title" : "raingad-IM", + "unipush" : { + "enable" : false + }, + "sdkConfigs" : { + "maps" : {} + } + }, + "fallbackLocale" : "zh-Hans" +} diff --git a/mixins/chat.js b/mixins/chat.js new file mode 100644 index 0000000..c8f6c07 --- /dev/null +++ b/mixins/chat.js @@ -0,0 +1,118 @@ +export const chat = { + data() { + return { + + } + }, + created: function() { + + }, + methods: { + // 播放视频,禁止多个同时播放 + handlePlay (item) { + uni.navigateTo({ + url: '/pages/message/video?name='+item.fileName+'&src='+encodeURI(item.content), + animationType:"slide-in-bottom" + }); + }, + // 文件预览 + previewFile(item){ + if(this.islongPress){ + return; + } + this.curMsg=item; + this.modelName='preview'; + }, + preview(val){ + let item=this.curMsg; + let audioExt=['mp3','wav','acc']; + let extension = item.content.split('.').pop().toLowerCase(); + if(audioExt.includes(extension) || val==2){ + uni.navigateTo({ + url: '/pages/mine/webview?title=文件预览&src='+encodeURIComponent(item.preview), + animationType:"slide-in-bottom" + }); + return; + } + // #ifdef APP-PLUS || MP-WEIXIN + let exts=['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx']; + if(exts.includes(extension)){ + uni.showLoading({title: '文件加载中'}); + uni.downloadFile({ + url: item.content, + success: function (res) { + uni.hideLoading(); + var filePath = res.tempFilePath; + uni.openDocument({ + filePath: filePath, + showMenu: true, + success: function (res) { + console.info('打开文档成功'); + } + }); + }, + fail() { + uni.hideLoading(); + } + }); + }else{ + uni.showToast({ + title:'该文件不支持预览!', + icon:'none' + }) + } + // #endif + + // #ifdef H5 + const tempLink = document.createElement("a"); + tempLink.style.display = "none"; + tempLink.href = item.download; + tempLink.setAttribute("download", item.fileName); + tempLink.setAttribute("target", "_blank"); + document.body.appendChild(tempLink); + tempLink.click(); + document.body.removeChild(tempLink); + // #endif + }, + // 图片预览 + showImgs : function(e){ + var imgs = []; + var imgsCurrent = e.currentTarget.dataset.img; + for (var i = 0; i < this.messageList.length; i++) { + if (this.messageList[i].type == 'image' || this.messageList[i].type == 'emoji') { + imgs.push(this.messageList[i].content); + } + } + uni.previewImage({urls : imgs, current : imgsCurrent}); + }, + openLocation(item){ + uni.openLocation({ + latitude: item.latitude, + longitude: item.longitude, + success: function () { + console.log('success'); + } + }); + }, + // 打开用户详情 + openContact(item){ + uni.navigateTo({ + url:"/pages/contacts/detail?id="+item.id + }) + }, + // 自动解析消息中的表情 + emojiToHtml(str){ + let emojiMap=this.emojiMap; + return str.replace(/\[!(\w+)\]/gi, function (str, match) { + var file = match; + return emojiMap[file] ? "") : "[!".concat(match, "]"); + }); + }, + fileSize(size){ + return this.$util.getFileSize(size); + }, + sendTime:function(mstime){ + return this.$util.timeFormat(mstime); + }, + } +} diff --git a/nativeplugins/lemonjk-FileSelect/android/uniplugin_fileSelect-release.aar b/nativeplugins/lemonjk-FileSelect/android/uniplugin_fileSelect-release.aar new file mode 100644 index 0000000000000000000000000000000000000000..c556c2feacb3bda9e1e1d0473f0555c6fc042b6b GIT binary patch literal 40988 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⪙6UbtAUrI&$4`Uq%?&b7&$BY9H_J) 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 kvgjFlj" + ], + "abis": [ + "armeabi-v7a", + "arm64-v8a" + ], + "minSdkVersion": 21 + }, + "ios": { + "plugins": [ + { + "type": "module", + "name": "lemonjk-FileSelect", + "class": "TestModule" + } + ], + "integrateType": "framework", + "deploymentTarget": "11.0" + } + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e4c7b6a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,722 @@ +{ + "name": "Raingad-IM", + "version": "5.5.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "Raingad-IM", + "version": "5.5.0", + "license": "ISC", + "dependencies": { + "crypto-js": "^4.2.0", + "jsqr": "^1.4.0", + "pinia": "^2.0.23", + "quill": "^1.3.7", + "vconsole": "^3.15.1" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz", + "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==" + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz", + "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, + "node_modules/deep-equal": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/deep-equal/-/deep-equal-1.1.2.tgz", + "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", + "dependencies": { + "is-arguments": "^1.1.1", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.5.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jsqr": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/jsqr/-/jsqr-1.4.0.tgz", + "integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==" + }, + "node_modules/mutation-observer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mutation-observer/-/mutation-observer-1.0.3.tgz", + "integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA==" + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" + }, + "node_modules/pinia": { + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.23.tgz", + "integrity": "sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==", + "dependencies": { + "@vue/devtools-api": "^6.4.4", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.2.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/quill": { + "version": "1.3.7", + "resolved": "https://registry.npmmirror.com/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "dependencies": { + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" + } + }, + "node_modules/quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmmirror.com/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", + "dependencies": { + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/vconsole": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/vconsole/-/vconsole-3.15.1.tgz", + "integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "copy-text-to-clipboard": "^3.0.1", + "core-js": "^3.11.0", + "mutation-observer": "^1.0.3" + } + }, + "node_modules/vue": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==", + "peer": true + }, + "node_modules/vue-demi": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", + "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + } + }, + "dependencies": { + "@babel/runtime": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@vue/devtools-api": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz", + "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==" + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" + }, + "copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==" + }, + "core-js": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz", + "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==" + }, + "crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, + "deep-equal": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/deep-equal/-/deep-equal-1.1.2.tgz", + "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", + "requires": { + "is-arguments": "^1.1.1", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.5.1" + } + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "jsqr": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/jsqr/-/jsqr-1.4.0.tgz", + "integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==" + }, + "mutation-observer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mutation-observer/-/mutation-observer-1.0.3.tgz", + "integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA==" + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" + }, + "pinia": { + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.23.tgz", + "integrity": "sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==", + "requires": { + "@vue/devtools-api": "^6.4.4", + "vue-demi": "*" + } + }, + "quill": { + "version": "1.3.7", + "resolved": "https://registry.npmmirror.com/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "requires": { + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" + } + }, + "quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmmirror.com/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", + "requires": { + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" + } + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + } + }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "requires": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + } + }, + "vconsole": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/vconsole/-/vconsole-3.15.1.tgz", + "integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==", + "requires": { + "@babel/runtime": "^7.17.2", + "copy-text-to-clipboard": "^3.0.1", + "core-js": "^3.11.0", + "mutation-observer": "^1.0.3" + } + }, + "vue": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==", + "peer": true + }, + "vue-demi": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", + "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "requires": {} + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d7e352a --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "Raingad-IM", + "version": "5.5.2", + "description": "一款基于vue3.0的uniapp即时聊天工具", + "logo": "/static/image/logo.png", + "author": "Raingad", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://gitee.com/raingad/instant-chat-uniapp.git" + }, + "keywords": [], + "license": "ISC", + "dependencies": { + "crypto-js": "^4.2.0", + "jsqr": "^1.4.0", + "pinia": "^2.0.23", + "quill": "^1.3.7", + "vconsole": "^3.15.1" + } +} diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..8cbbbe4 --- /dev/null +++ b/pages.json @@ -0,0 +1,199 @@ +{ + "pages": [ + { + "path": "pages/index/index", + "style": { + "navigationBarTitleText": "首页" + } + }, + { + "path": "pages/message/chat", + "style": { + "navigationBarTitleText": "聊天" + // "enablePullDownRefresh": true + } + }, + { + "path": "pages/message/emoji", + "style": { + "navigationBarTitleText": "表情" + } + }, + { + "path": "pages/contacts/index", + "style": { + "navigationBarTitleText": "联系人" + } + }, + { + "path": "pages/message/detail", + "style": { + "navigationBarTitleText": "聊天信息" + } + }, + { + "path": "pages/message/record", + "style": { + "navigationBarTitleText": "聊天记录" + } + }, + { + "path": "pages/contacts/detail", + "style": { + "navigationBarTitleText": "用户信息" + } + }, + { + "path": "pages/contacts/friend", + "style": { + "navigationBarTitleText": "新朋友" + } + }, + { + "path": "pages/contacts/search", + "style": { + "navigationBarTitleText": "搜索朋友" + } + }, + { + "path": "pages/login/index", + "style": { + "navigationBarTitleText": "登录" + } + }, + { + "path": "pages/login/register", + "style": { + "navigationBarTitleText": "注册" + } + }, + { + "path": "pages/message/call", + "style": { + "navigationBarTitleText": "通话" + } + }, + { + "path": "pages/message/video", + "style": { + "navigationBarTitleText": "视频播放" + } + }, + { + "path": "pages/index/userSelection", + "style": { + "navigationBarTitleText": "用户选择" + } + }, + { + "path": "pages/message/group/groupUser", + "style": { + "navigationBarTitleText": "群聊成员管理" + } + }, + { + "path": "pages/index/qrcode", + "style": { + "navigationBarTitleText": "群二维码" + } + }, + { + "path": "pages/message/group/info", + "style": { + "navigationBarTitleText": "群信息" + } + }, + { + "path": "pages/contacts/group", + "style": { + "navigationBarTitleText": "群聊列表" + } + }, + { + "path": "pages/index/search", + "style": { + "navigationBarTitleText": "搜索" + } + }, + { + "path": "pages/index/scan", + "style": { + "navigationBarTitleText": "扫描" + } + }, + { + "path": "pages/mine/webview", + "style": { + "navigationBarTitleText": "浏览器", + "navigationStyle":"default" + } + }, + { + "path": "pages/compass/moments", + "style": { + "navigationBarTitleText": "朋友圈" + } + }, + { + "path": "pages/mine/profile", + "style": { + "navigationBarTitleText": "个人信息" + } + }, + { + "path": "pages/mine/secure", + "style": { + "navigationBarTitleText": "安全" + } + }, + { + "path": "pages/mine/about", + "style": { + "navigationBarTitleText": "关于" + } + }, + { + "path": "pages/mine/setting", + "style": { + "navigationBarTitleText": "设置" + } + }, + { + "path": "pages/mine/doc", + "style": { + "navigationBarTitleText": "帮助文档" + } + } + ], + "globalStyle": { + "navigationStyle": "custom", + "navigationBarTextStyle": "black", + "navigationBarTitleText": "uni-app", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8", + "app-plus": { + "background": "#efeff4" + } + }, + "tabBar": { + "custom": true, + "color": "#333", + "selectedColor": "#1AAD19", + "borderStyle": "black", + "backgroundColor": "#FFFFFF", + "list": [{ + "pagePath": "pages/index/index", + "iconPath": "static/image/tabbar/demo.png", + "selectedIconPath": "static/image/tabbar/demo.png", + "text": "首页" + }, + + { + "pagePath": "pages/contacts/index", + "iconPath": "static/image/tabbar/demo.png", + "selectedIconPath": "static/image/tabbar/demo.png", + "text": "通讯录" + } + ] + } +} diff --git a/pages/compass/index.vue b/pages/compass/index.vue new file mode 100644 index 0000000..d1f8316 --- /dev/null +++ b/pages/compass/index.vue @@ -0,0 +1,79 @@ + + + + + \ No newline at end of file diff --git a/pages/compass/moments.vue b/pages/compass/moments.vue new file mode 100644 index 0000000..f971af9 --- /dev/null +++ b/pages/compass/moments.vue @@ -0,0 +1,140 @@ + + + + + \ No newline at end of file diff --git a/pages/contacts/detail.vue b/pages/contacts/detail.vue new file mode 100644 index 0000000..1ffff2b --- /dev/null +++ b/pages/contacts/detail.vue @@ -0,0 +1,247 @@ + + + + + diff --git a/pages/contacts/friend.vue b/pages/contacts/friend.vue new file mode 100644 index 0000000..b8ed3a5 --- /dev/null +++ b/pages/contacts/friend.vue @@ -0,0 +1,150 @@ + + + + + \ No newline at end of file diff --git a/pages/contacts/group.vue b/pages/contacts/group.vue new file mode 100644 index 0000000..8834571 --- /dev/null +++ b/pages/contacts/group.vue @@ -0,0 +1,89 @@ + + + + + \ No newline at end of file diff --git a/pages/contacts/index.vue b/pages/contacts/index.vue new file mode 100644 index 0000000..5a37cb9 --- /dev/null +++ b/pages/contacts/index.vue @@ -0,0 +1,410 @@ + + + + + \ No newline at end of file diff --git a/pages/contacts/search.vue b/pages/contacts/search.vue new file mode 100644 index 0000000..bf060ee --- /dev/null +++ b/pages/contacts/search.vue @@ -0,0 +1,88 @@ + + + + + \ No newline at end of file diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..97855c1 --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,254 @@ + + + + + \ No newline at end of file diff --git a/pages/index/qrcode.vue b/pages/index/qrcode.vue new file mode 100644 index 0000000..7a17081 --- /dev/null +++ b/pages/index/qrcode.vue @@ -0,0 +1,220 @@ + + + diff --git a/pages/index/scan.vue b/pages/index/scan.vue new file mode 100644 index 0000000..5467eba --- /dev/null +++ b/pages/index/scan.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/pages/index/search.vue b/pages/index/search.vue new file mode 100644 index 0000000..39f6589 --- /dev/null +++ b/pages/index/search.vue @@ -0,0 +1,112 @@ + + + + + \ No newline at end of file diff --git a/pages/index/userSelection.vue b/pages/index/userSelection.vue new file mode 100644 index 0000000..697274a --- /dev/null +++ b/pages/index/userSelection.vue @@ -0,0 +1,337 @@ + + + + + diff --git a/pages/login/index.vue b/pages/login/index.vue new file mode 100644 index 0000000..efff432 --- /dev/null +++ b/pages/login/index.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/pages/login/register.vue b/pages/login/register.vue new file mode 100644 index 0000000..f63bf85 --- /dev/null +++ b/pages/login/register.vue @@ -0,0 +1,182 @@ + + + + + diff --git a/pages/message/call.vue b/pages/message/call.vue new file mode 100644 index 0000000..4936585 --- /dev/null +++ b/pages/message/call.vue @@ -0,0 +1,262 @@ + + + + + diff --git a/pages/message/chat.vue b/pages/message/chat.vue new file mode 100644 index 0000000..d06d2ef --- /dev/null +++ b/pages/message/chat.vue @@ -0,0 +1,1347 @@ + + + + + + + + diff --git a/pages/message/detail.vue b/pages/message/detail.vue new file mode 100644 index 0000000..38af0cf --- /dev/null +++ b/pages/message/detail.vue @@ -0,0 +1,638 @@ + + + + + + diff --git a/pages/message/emoji.vue b/pages/message/emoji.vue new file mode 100644 index 0000000..9b4cb7d --- /dev/null +++ b/pages/message/emoji.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/pages/message/group/groupUser.vue b/pages/message/group/groupUser.vue new file mode 100644 index 0000000..a47cb6d --- /dev/null +++ b/pages/message/group/groupUser.vue @@ -0,0 +1,291 @@ + + + diff --git a/pages/message/group/info.vue b/pages/message/group/info.vue new file mode 100644 index 0000000..099847c --- /dev/null +++ b/pages/message/group/info.vue @@ -0,0 +1,88 @@ + + + diff --git a/pages/message/index.vue b/pages/message/index.vue new file mode 100644 index 0000000..355a3fa --- /dev/null +++ b/pages/message/index.vue @@ -0,0 +1,349 @@ + + + + + diff --git a/pages/message/record.vue b/pages/message/record.vue new file mode 100644 index 0000000..ab2eeb5 --- /dev/null +++ b/pages/message/record.vue @@ -0,0 +1,517 @@ + + + + + + diff --git a/pages/message/video.vue b/pages/message/video.vue new file mode 100644 index 0000000..2229bd6 --- /dev/null +++ b/pages/message/video.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/pages/mine/about.vue b/pages/mine/about.vue new file mode 100644 index 0000000..81a04ca --- /dev/null +++ b/pages/mine/about.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/pages/mine/doc.vue b/pages/mine/doc.vue new file mode 100644 index 0000000..16404da --- /dev/null +++ b/pages/mine/doc.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/pages/mine/index.vue b/pages/mine/index.vue new file mode 100644 index 0000000..9b744e2 --- /dev/null +++ b/pages/mine/index.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/pages/mine/profile.vue b/pages/mine/profile.vue new file mode 100644 index 0000000..85b4b0a --- /dev/null +++ b/pages/mine/profile.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/pages/mine/secure.vue b/pages/mine/secure.vue new file mode 100644 index 0000000..cdb88e0 --- /dev/null +++ b/pages/mine/secure.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/pages/mine/setting.vue b/pages/mine/setting.vue new file mode 100644 index 0000000..7e44822 --- /dev/null +++ b/pages/mine/setting.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/pages/mine/webview.vue b/pages/mine/webview.vue new file mode 100644 index 0000000..ee9bf1c --- /dev/null +++ b/pages/mine/webview.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/static/css/animation.css b/static/css/animation.css new file mode 100644 index 0000000..931bb51 --- /dev/null +++ b/static/css/animation.css @@ -0,0 +1,184 @@ +/* + Animation 微动画 + 基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28 + */ + +/* css 滤镜 控制黑白底色gif的 */ +.gif-black{ + mix-blend-mode: screen; +} +.gif-white{ + mix-blend-mode: multiply; +} + + +/* Animation css */ +[class*=animation-] { + animation-duration: .5s; + animation-timing-function: ease-out; + animation-fill-mode: both +} + +.animation-fade { + animation-name: fade; + animation-duration: .8s; + animation-timing-function: linear +} + +.animation-scale-up { + animation-name: scale-up +} + +.animation-scale-down { + animation-name: scale-down +} + +.animation-slide-top { + animation-name: slide-top +} + +.animation-slide-bottom { + animation-name: slide-bottom +} + +.animation-slide-left { + animation-name: slide-left +} + +.animation-slide-right { + animation-name: slide-right +} + +.animation-shake { + animation-name: shake +} + +.animation-reverse { + animation-direction: reverse +} + +@keyframes fade { + 0% { + opacity: 0 + } + + 100% { + opacity: 1 + } +} + +@keyframes scale-up { + 0% { + opacity: 0; + transform: scale(.2) + } + + 100% { + opacity: 1; + transform: scale(1) + } +} + +@keyframes scale-down { + 0% { + opacity: 0; + transform: scale(1.8) + } + + 100% { + opacity: 1; + transform: scale(1) + } +} + +@keyframes slide-top { + 0% { + opacity: 0; + transform: translateY(-100%) + } + + 100% { + opacity: 1; + transform: translateY(0) + } +} + +@keyframes slide-bottom { + 0% { + opacity: 0; + transform: translateY(100%) + } + + 100% { + opacity: 1; + transform: translateY(0) + } +} + +@keyframes shake { + + 0%, + 100% { + transform: translateX(0) + } + + 10% { + transform: translateX(-9px) + } + + 20% { + transform: translateX(8px) + } + + 30% { + transform: translateX(-7px) + } + + 40% { + transform: translateX(6px) + } + + 50% { + transform: translateX(-5px) + } + + 60% { + transform: translateX(4px) + } + + 70% { + transform: translateX(-3px) + } + + 80% { + transform: translateX(2px) + } + + 90% { + transform: translateX(-1px) + } +} + +@keyframes slide-left { + 0% { + opacity: 0; + transform: translateX(-100%) + } + + 100% { + opacity: 1; + transform: translateX(0) + } +} + +@keyframes slide-right { + 0% { + opacity: 0; + transform: translateX(100%) + } + + 100% { + opacity: 1; + transform: translateX(0) + } +} \ No newline at end of file diff --git a/static/css/icon.css b/static/css/icon.css new file mode 100644 index 0000000..16ed121 --- /dev/null +++ b/static/css/icon.css @@ -0,0 +1,1226 @@ +@keyframes cuIcon-spin { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +.cuIconfont-spin { + -webkit-animation: cuIcon-spin 2s infinite linear; + animation: cuIcon-spin 2s infinite linear; + display: inline-block; +} + +.cuIconfont-pulse { + -webkit-animation: cuIcon-spin 1s infinite steps(8); + animation: cuIcon-spin 1s infinite steps(8); + display: inline-block; +} + +[class*="cuIcon-"] { + font-family: "cuIcon"; + font-size: inherit; + font-style: normal; +} + +@font-face { + font-family: "cuIcon"; + src: url('//at.alicdn.com/t/font_533566_yfq2d9wdij.eot?t=1545239985831'); + /* IE9*/ + src: url('//at.alicdn.com/t/font_533566_yfq2d9wdij.eot?t=1545239985831#iefix') format('embedded-opentype'), + /* IE6-IE8 */ + url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'), + url('//at.alicdn.com/t/font_533566_yfq2d9wdij.ttf?t=1545239985831') format('truetype'), + /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ + url('//at.alicdn.com/t/font_533566_yfq2d9wdij.svg?t=1545239985831#cuIconfont') format('svg'); + /* iOS 4.1- */ +} + +.cuIcon-appreciate:before { + content: "\e644"; +} + +.cuIcon-check:before { + content: "\e645"; +} + +.cuIcon-close:before { + content: "\e646"; +} + +.cuIcon-edit:before { + content: "\e649"; +} + +.cuIcon-emoji:before { + content: "\e64a"; +} + +.cuIcon-favorfill:before { + content: "\e64b"; +} + +.cuIcon-favor:before { + content: "\e64c"; +} + +.cuIcon-loading:before { + content: "\e64f"; +} + +.cuIcon-locationfill:before { + content: "\e650"; +} + +.cuIcon-location:before { + content: "\e651"; +} + +.cuIcon-phone:before { + content: "\e652"; +} + +.cuIcon-roundcheckfill:before { + content: "\e656"; +} + +.cuIcon-roundcheck:before { + content: "\e657"; +} + +.cuIcon-roundclosefill:before { + content: "\e658"; +} + +.cuIcon-roundclose:before { + content: "\e659"; +} + +.cuIcon-roundrightfill:before { + content: "\e65a"; +} + +.cuIcon-roundright:before { + content: "\e65b"; +} + +.cuIcon-search:before { + content: "\e65c"; +} + +.cuIcon-taxi:before { + content: "\e65d"; +} + +.cuIcon-timefill:before { + content: "\e65e"; +} + +.cuIcon-time:before { + content: "\e65f"; +} + +.cuIcon-unfold:before { + content: "\e661"; +} + +.cuIcon-warnfill:before { + content: "\e662"; +} + +.cuIcon-warn:before { + content: "\e663"; +} + +.cuIcon-camerafill:before { + content: "\e664"; +} + +.cuIcon-camera:before { + content: "\e665"; +} + +.cuIcon-commentfill:before { + content: "\e666"; +} + +.cuIcon-comment:before { + content: "\e667"; +} + +.cuIcon-likefill:before { + content: "\e668"; +} + +.cuIcon-like:before { + content: "\e669"; +} + +.cuIcon-notificationfill:before { + content: "\e66a"; +} + +.cuIcon-notification:before { + content: "\e66b"; +} + +.cuIcon-order:before { + content: "\e66c"; +} + +.cuIcon-samefill:before { + content: "\e66d"; +} + +.cuIcon-same:before { + content: "\e66e"; +} + +.cuIcon-deliver:before { + content: "\e671"; +} + +.cuIcon-evaluate:before { + content: "\e672"; +} + +.cuIcon-pay:before { + content: "\e673"; +} + +.cuIcon-send:before { + content: "\e675"; +} + +.cuIcon-shop:before { + content: "\e676"; +} + +.cuIcon-ticket:before { + content: "\e677"; +} + +.cuIcon-back:before { + content: "\e679"; +} + +.cuIcon-cascades:before { + content: "\e67c"; +} + +.cuIcon-discover:before { + content: "\e67e"; +} + +.cuIcon-list:before { + content: "\e682"; +} + +.cuIcon-more:before { + content: "\e684"; +} + +.cuIcon-scan:before { + content: "\e689"; +} + +.cuIcon-settings:before { + content: "\e68a"; +} + +.cuIcon-questionfill:before { + content: "\e690"; +} + +.cuIcon-question:before { + content: "\e691"; +} + +.cuIcon-shopfill:before { + content: "\e697"; +} + +.cuIcon-form:before { + content: "\e699"; +} + +.cuIcon-pic:before { + content: "\e69b"; +} + +.cuIcon-filter:before { + content: "\e69c"; +} + +.cuIcon-footprint:before { + content: "\e69d"; +} + +.cuIcon-top:before { + content: "\e69e"; +} + +.cuIcon-pulldown:before { + content: "\e69f"; +} + +.cuIcon-pullup:before { + content: "\e6a0"; +} + +.cuIcon-right:before { + content: "\e6a3"; +} + +.cuIcon-refresh:before { + content: "\e6a4"; +} + +.cuIcon-moreandroid:before { + content: "\e6a5"; +} + +.cuIcon-deletefill:before { + content: "\e6a6"; +} + +.cuIcon-refund:before { + content: "\e6ac"; +} + +.cuIcon-cart:before { + content: "\e6af"; +} + +.cuIcon-qrcode:before { + content: "\e6b0"; +} + +.cuIcon-remind:before { + content: "\e6b2"; +} + +.cuIcon-delete:before { + content: "\e6b4"; +} + +.cuIcon-profile:before { + content: "\e6b7"; +} + +.cuIcon-home:before { + content: "\e6b8"; +} + +.cuIcon-cartfill:before { + content: "\e6b9"; +} + +.cuIcon-discoverfill:before { + content: "\e6ba"; +} + +.cuIcon-homefill:before { + content: "\e6bb"; +} + +.cuIcon-message:before { + content: "\e6bc"; +} + +.cuIcon-addressbook:before { + content: "\e6bd"; +} + +.cuIcon-link:before { + content: "\e6bf"; +} + +.cuIcon-lock:before { + content: "\e6c0"; +} + +.cuIcon-unlock:before { + content: "\e6c2"; +} + +.cuIcon-vip:before { + content: "\e6c3"; +} + +.cuIcon-weibo:before { + content: "\e6c4"; +} + +.cuIcon-activity:before { + content: "\e6c5"; +} + +.cuIcon-friendaddfill:before { + content: "\e6c9"; +} + +.cuIcon-friendadd:before { + content: "\e6ca"; +} + +.cuIcon-friendfamous:before { + content: "\e6cb"; +} + +.cuIcon-friend:before { + content: "\e6cc"; +} + +.cuIcon-goods:before { + content: "\e6cd"; +} + +.cuIcon-selection:before { + content: "\e6ce"; +} + +.cuIcon-explore:before { + content: "\e6d2"; +} + +.cuIcon-present:before { + content: "\e6d3"; +} + +.cuIcon-squarecheckfill:before { + content: "\e6d4"; +} + +.cuIcon-square:before { + content: "\e6d5"; +} + +.cuIcon-squarecheck:before { + content: "\e6d6"; +} + +.cuIcon-round:before { + content: "\e6d7"; +} + +.cuIcon-roundaddfill:before { + content: "\e6d8"; +} + +.cuIcon-roundadd:before { + content: "\e6d9"; +} + +.cuIcon-add:before { + content: "\e6da"; +} + +.cuIcon-notificationforbidfill:before { + content: "\e6db"; +} + +.cuIcon-explorefill:before { + content: "\e6dd"; +} + +.cuIcon-fold:before { + content: "\e6de"; +} + +.cuIcon-game:before { + content: "\e6df"; +} + +.cuIcon-redpacket:before { + content: "\e6e0"; +} + +.cuIcon-selectionfill:before { + content: "\e6e1"; +} + +.cuIcon-similar:before { + content: "\e6e2"; +} + +.cuIcon-appreciatefill:before { + content: "\e6e3"; +} + +.cuIcon-infofill:before { + content: "\e6e4"; +} + +.cuIcon-info:before { + content: "\e6e5"; +} + +.cuIcon-forwardfill:before { + content: "\e6ea"; +} + +.cuIcon-forward:before { + content: "\e6eb"; +} + +.cuIcon-rechargefill:before { + content: "\e6ec"; +} + +.cuIcon-recharge:before { + content: "\e6ed"; +} + +.cuIcon-vipcard:before { + content: "\e6ee"; +} + +.cuIcon-voice:before { + content: "\e6ef"; +} + +.cuIcon-voicefill:before { + content: "\e6f0"; +} + +.cuIcon-friendfavor:before { + content: "\e6f1"; +} + +.cuIcon-wifi:before { + content: "\e6f2"; +} + +.cuIcon-share:before { + content: "\e6f3"; +} + +.cuIcon-wefill:before { + content: "\e6f4"; +} + +.cuIcon-we:before { + content: "\e6f5"; +} + +.cuIcon-lightauto:before { + content: "\e6f6"; +} + +.cuIcon-lightforbid:before { + content: "\e6f7"; +} + +.cuIcon-lightfill:before { + content: "\e6f8"; +} + +.cuIcon-camerarotate:before { + content: "\e6f9"; +} + +.cuIcon-light:before { + content: "\e6fa"; +} + +.cuIcon-barcode:before { + content: "\e6fb"; +} + +.cuIcon-flashlightclose:before { + content: "\e6fc"; +} + +.cuIcon-flashlightopen:before { + content: "\e6fd"; +} + +.cuIcon-searchlist:before { + content: "\e6fe"; +} + +.cuIcon-service:before { + content: "\e6ff"; +} + +.cuIcon-sort:before { + content: "\e700"; +} + +.cuIcon-down:before { + content: "\e703"; +} + +.cuIcon-mobile:before { + content: "\e704"; +} + +.cuIcon-mobilefill:before { + content: "\e705"; +} + +.cuIcon-copy:before { + content: "\e706"; +} + +.cuIcon-countdownfill:before { + content: "\e707"; +} + +.cuIcon-countdown:before { + content: "\e708"; +} + +.cuIcon-noticefill:before { + content: "\e709"; +} + +.cuIcon-notice:before { + content: "\e70a"; +} + +.cuIcon-upstagefill:before { + content: "\e70e"; +} + +.cuIcon-upstage:before { + content: "\e70f"; +} + +.cuIcon-babyfill:before { + content: "\e710"; +} + +.cuIcon-baby:before { + content: "\e711"; +} + +.cuIcon-brandfill:before { + content: "\e712"; +} + +.cuIcon-brand:before { + content: "\e713"; +} + +.cuIcon-choicenessfill:before { + content: "\e714"; +} + +.cuIcon-choiceness:before { + content: "\e715"; +} + +.cuIcon-clothesfill:before { + content: "\e716"; +} + +.cuIcon-clothes:before { + content: "\e717"; +} + +.cuIcon-creativefill:before { + content: "\e718"; +} + +.cuIcon-creative:before { + content: "\e719"; +} + +.cuIcon-female:before { + content: "\e71a"; +} + +.cuIcon-keyboard:before { + content: "\e71b"; +} + +.cuIcon-male:before { + content: "\e71c"; +} + +.cuIcon-newfill:before { + content: "\e71d"; +} + +.cuIcon-new:before { + content: "\e71e"; +} + +.cuIcon-pullleft:before { + content: "\e71f"; +} + +.cuIcon-pullright:before { + content: "\e720"; +} + +.cuIcon-rankfill:before { + content: "\e721"; +} + +.cuIcon-rank:before { + content: "\e722"; +} + +.cuIcon-bad:before { + content: "\e723"; +} + +.cuIcon-cameraadd:before { + content: "\e724"; +} + +.cuIcon-focus:before { + content: "\e725"; +} + +.cuIcon-friendfill:before { + content: "\e726"; +} + +.cuIcon-cameraaddfill:before { + content: "\e727"; +} + +.cuIcon-apps:before { + content: "\e729"; +} + +.cuIcon-paintfill:before { + content: "\e72a"; +} + +.cuIcon-paint:before { + content: "\e72b"; +} + +.cuIcon-picfill:before { + content: "\e72c"; +} + +.cuIcon-refresharrow:before { + content: "\e72d"; +} + +.cuIcon-colorlens:before { + content: "\e6e6"; +} + +.cuIcon-markfill:before { + content: "\e730"; +} + +.cuIcon-mark:before { + content: "\e731"; +} + +.cuIcon-presentfill:before { + content: "\e732"; +} + +.cuIcon-repeal:before { + content: "\e733"; +} + +.cuIcon-album:before { + content: "\e734"; +} + +.cuIcon-peoplefill:before { + content: "\e735"; +} + +.cuIcon-people:before { + content: "\e736"; +} + +.cuIcon-servicefill:before { + content: "\e737"; +} + +.cuIcon-repair:before { + content: "\e738"; +} + +.cuIcon-file:before { + content: "\e739"; +} + +.cuIcon-repairfill:before { + content: "\e73a"; +} + +.cuIcon-taoxiaopu:before { + content: "\e73b"; +} + +.cuIcon-weixin:before { + content: "\e612"; +} + +.cuIcon-attentionfill:before { + content: "\e73c"; +} + +.cuIcon-attention:before { + content: "\e73d"; +} + +.cuIcon-commandfill:before { + content: "\e73e"; +} + +.cuIcon-command:before { + content: "\e73f"; +} + +.cuIcon-communityfill:before { + content: "\e740"; +} + +.cuIcon-community:before { + content: "\e741"; +} + +.cuIcon-read:before { + content: "\e742"; +} + +.cuIcon-calendar:before { + content: "\e74a"; +} + +.cuIcon-cut:before { + content: "\e74b"; +} + +.cuIcon-magic:before { + content: "\e74c"; +} + +.cuIcon-backwardfill:before { + content: "\e74d"; +} + +.cuIcon-playfill:before { + content: "\e74f"; +} + +.cuIcon-stop:before { + content: "\e750"; +} + +.cuIcon-tagfill:before { + content: "\e751"; +} + +.cuIcon-tag:before { + content: "\e752"; +} + +.cuIcon-group:before { + content: "\e753"; +} + +.cuIcon-all:before { + content: "\e755"; +} + +.cuIcon-backdelete:before { + content: "\e756"; +} + +.cuIcon-hotfill:before { + content: "\e757"; +} + +.cuIcon-hot:before { + content: "\e758"; +} + +.cuIcon-post:before { + content: "\e759"; +} + +.cuIcon-radiobox:before { + content: "\e75b"; +} + +.cuIcon-rounddown:before { + content: "\e75c"; +} + +.cuIcon-upload:before { + content: "\e75d"; +} + +.cuIcon-writefill:before { + content: "\e760"; +} + +.cuIcon-write:before { + content: "\e761"; +} + +.cuIcon-radioboxfill:before { + content: "\e763"; +} + +.cuIcon-punch:before { + content: "\e764"; +} + +.cuIcon-shake:before { + content: "\e765"; +} + +.cuIcon-move:before { + content: "\e768"; +} + +.cuIcon-safe:before { + content: "\e769"; +} + +.cuIcon-activityfill:before { + content: "\e775"; +} + +.cuIcon-crownfill:before { + content: "\e776"; +} + +.cuIcon-crown:before { + content: "\e777"; +} + +.cuIcon-goodsfill:before { + content: "\e778"; +} + +.cuIcon-messagefill:before { + content: "\e779"; +} + +.cuIcon-profilefill:before { + content: "\e77a"; +} + +.cuIcon-sound:before { + content: "\e77b"; +} + +.cuIcon-sponsorfill:before { + content: "\e77c"; +} + +.cuIcon-sponsor:before { + content: "\e77d"; +} + +.cuIcon-upblock:before { + content: "\e77e"; +} + +.cuIcon-weblock:before { + content: "\e77f"; +} + +.cuIcon-weunblock:before { + content: "\e780"; +} + +.cuIcon-my:before { + content: "\e78b"; +} + +.cuIcon-myfill:before { + content: "\e78c"; +} + +.cuIcon-emojifill:before { + content: "\e78d"; +} + +.cuIcon-emojiflashfill:before { + content: "\e78e"; +} + +.cuIcon-flashbuyfill:before { + content: "\e78f"; +} + +.cuIcon-text:before { + content: "\e791"; +} + +.cuIcon-goodsfavor:before { + content: "\e794"; +} + +.cuIcon-musicfill:before { + content: "\e795"; +} + +.cuIcon-musicforbidfill:before { + content: "\e796"; +} + +.cuIcon-card:before { + content: "\e624"; +} + +.cuIcon-triangledownfill:before { + content: "\e79b"; +} + +.cuIcon-triangleupfill:before { + content: "\e79c"; +} + +.cuIcon-roundleftfill-copy:before { + content: "\e79e"; +} + +.cuIcon-font:before { + content: "\e76a"; +} + +.cuIcon-title:before { + content: "\e82f"; +} + +.cuIcon-recordfill:before { + content: "\e7a4"; +} + +.cuIcon-record:before { + content: "\e7a6"; +} + +.cuIcon-cardboardfill:before { + content: "\e7a9"; +} + +.cuIcon-cardboard:before { + content: "\e7aa"; +} + +.cuIcon-formfill:before { + content: "\e7ab"; +} + +.cuIcon-coin:before { + content: "\e7ac"; +} + +.cuIcon-cardboardforbid:before { + content: "\e7af"; +} + +.cuIcon-circlefill:before { + content: "\e7b0"; +} + +.cuIcon-circle:before { + content: "\e7b1"; +} + +.cuIcon-attentionforbid:before { + content: "\e7b2"; +} + +.cuIcon-attentionforbidfill:before { + content: "\e7b3"; +} + +.cuIcon-attentionfavorfill:before { + content: "\e7b4"; +} + +.cuIcon-attentionfavor:before { + content: "\e7b5"; +} + +.cuIcon-titles:before { + content: "\e701"; +} + +.cuIcon-icloading:before { + content: "\e67a"; +} + +.cuIcon-full:before { + content: "\e7bc"; +} + +.cuIcon-mail:before { + content: "\e7bd"; +} + +.cuIcon-peoplelist:before { + content: "\e7be"; +} + +.cuIcon-goodsnewfill:before { + content: "\e7bf"; +} + +.cuIcon-goodsnew:before { + content: "\e7c0"; +} + +.cuIcon-medalfill:before { + content: "\e7c1"; +} + +.cuIcon-medal:before { + content: "\e7c2"; +} + +.cuIcon-newsfill:before { + content: "\e7c3"; +} + +.cuIcon-newshotfill:before { + content: "\e7c4"; +} + +.cuIcon-newshot:before { + content: "\e7c5"; +} + +.cuIcon-news:before { + content: "\e7c6"; +} + +.cuIcon-videofill:before { + content: "\e7c7"; +} + +.cuIcon-video:before { + content: "\e7c8"; +} + +.cuIcon-exit:before { + content: "\e7cb"; +} + +.cuIcon-skinfill:before { + content: "\e7cc"; +} + +.cuIcon-skin:before { + content: "\e7cd"; +} + +.cuIcon-moneybagfill:before { + content: "\e7ce"; +} + +.cuIcon-usefullfill:before { + content: "\e7cf"; +} + +.cuIcon-usefull:before { + content: "\e7d0"; +} + +.cuIcon-moneybag:before { + content: "\e7d1"; +} + +.cuIcon-redpacket_fill:before { + content: "\e7d3"; +} + +.cuIcon-subscription:before { + content: "\e7d4"; +} + +.cuIcon-loading1:before { + content: "\e633"; +} + +.cuIcon-github:before { + content: "\e692"; +} + +.cuIcon-global:before { + content: "\e7eb"; +} + +.cuIcon-settingsfill:before { + content: "\e6ab"; +} + +.cuIcon-back_android:before { + content: "\e7ed"; +} + +.cuIcon-expressman:before { + content: "\e7ef"; +} + +.cuIcon-evaluate_fill:before { + content: "\e7f0"; +} + +.cuIcon-group_fill:before { + content: "\e7f5"; +} + +.cuIcon-play_forward_fill:before { + content: "\e7f6"; +} + +.cuIcon-deliver_fill:before { + content: "\e7f7"; +} + +.cuIcon-notice_forbid_fill:before { + content: "\e7f8"; +} + +.cuIcon-fork:before { + content: "\e60c"; +} + +.cuIcon-pick:before { + content: "\e7fa"; +} + +.cuIcon-wenzi:before { + content: "\e6a7"; +} + +.cuIcon-ellipse:before { + content: "\e600"; +} + +.cuIcon-qr_code:before { + content: "\e61b"; +} + +.cuIcon-dianhua:before { + content: "\e64d"; +} + +.cuIcon-cuIcon:before { + content: "\e602"; +} + +.cuIcon-loading2:before { + content: "\e7f1"; +} + +.cuIcon-btn:before { + content: "\e601"; +} diff --git a/static/css/iconfont.css b/static/css/iconfont.css new file mode 100644 index 0000000..d8b5d04 --- /dev/null +++ b/static/css/iconfont.css @@ -0,0 +1,147 @@ +@font-face { + font-family: "iconfont"; /* Project id 3565944 */ + src: url('../fonts/iconfont.woff2?t=1693989529907') format('woff2'), + url('../fonts/iconfont.woff?t=1693989529907') format('woff'), + url('../fonts/iconfont.ttf?t=1693989529907') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-web:before { + content: "\e68b"; +} + +.icon-ico:before { + content: "\e646"; +} + +.icon-speaker:before { + content: "\e600"; +} + +.icon-ai16:before { + content: "\e684"; +} + +.icon-no-speaker:before { + content: "\e867"; +} + +.icon-iconqiehuanjingtou:before { + content: "\e60d"; +} + +.icon-maikefeng:before { + content: "\e62c"; +} + +.icon-maikefeng1:before { + content: "\e62f"; +} + +.icon-zhaoxiangjiqiehuan:before { + content: "\e866"; +} + +.icon-im-yuyin:before { + content: "\e667"; +} + +.icon-im-file:before { + content: "\e617"; +} + +.icon-im-picture:before { + content: "\e618"; +} + +.icon-im-qcard:before { + content: "\e619"; +} + +.icon-im-signout:before { + content: "\e61a"; +} + +.icon-im-add:before { + content: "\e61b"; +} + +.icon-im-news:before { + content: "\e61c"; +} + +.icon-im-emoji:before { + content: "\e61d"; +} + +.icon-im-grcard:before { + content: "\e61e"; +} + +.icon-im-call:before { + content: "\e61f"; +} + +.icon-im-video:before { + content: "\e620"; +} + +.icon-im-at:before { + content: "\e621"; +} + +.icon-im-search:before { + content: "\e622"; +} + +.icon-im-more:before { + content: "\e627"; +} + +.icon-im-group:before { + content: "\e628"; +} + +.icon-im-meeting:before { + content: "\e629"; +} + +.icon-im-addfriends:before { + content: "\e62a"; +} + +.icon-im-plusmeeeting:before { + content: "\e62b"; +} + +.icon-im_extend:before { + content: "\e62d"; +} + +.icon-im-shrink:before { + content: "\e62e"; +} + +.icon-im-password:before { + content: "\e633"; +} + +.icon-im-end:before { + content: "\e634"; +} + +.icon-im-deldte:before { + content: "\e636"; +} + +.icon-im-videocall:before { + content: "\e637"; +} + diff --git a/static/css/main.css b/static/css/main.css new file mode 100644 index 0000000..514d9c9 --- /dev/null +++ b/static/css/main.css @@ -0,0 +1,3912 @@ +/* + ColorUi for uniApp v2.1.6 | by 文晓港 2019-05-31 10:44:24 + 仅供学习交流,如作它用所承受的法律责任一概与作者无关 + + *使用ColorUi开发扩展与插件时,请注明基于ColorUi开发 + + (QQ交流群:240787041) +*/ + +/* ================== + 初始化 + ==================== */ +body { + background-color: #f1f1f1; + font-size: 28upx; + color: #333333; + font-family: Helvetica Neue, Helvetica, sans-serif; +} + +view, +scroll-view, +swiper, +button, +input, +textarea, +label, +navigator, +image { + box-sizing: border-box; +} + +.round { + border-radius: 5000upx; +} + +.radius { + border-radius: 6upx; +} + +/* ================== + 图片 + ==================== */ + +image { + max-width: 100%; + display: inline-block; + position: relative; + z-index: 0; +} + +image.loading::before { + content: ""; + background-color: #f5f5f5; + display: block; + position: absolute; + width: 100%; + height: 100%; + z-index: -2; +} + +image.loading::after { + content: "\e7f1"; + font-family: "cuIcon"; + position: absolute; + top: 0; + left: 0; + width: 32upx; + height: 32upx; + line-height: 32upx; + right: 0; + bottom: 0; + z-index: -1; + font-size: 32upx; + margin: auto; + color: #ccc; + -webkit-animation: cuIcon-spin 2s infinite linear; + animation: cuIcon-spin 2s infinite linear; + display: block; +} + +.response { + width: 100%; +} + +/* ================== + 开关 + ==================== */ + +switch, +checkbox, +radio { + position: relative; +} + +switch::after, +switch::before { + font-family: "cuIcon"; + content: "\e645"; + position: absolute; + color: #ffffff !important; + top: 0%; + left: 0upx; + font-size: 26upx; + line-height: 26px; + width: 50%; + text-align: center; + pointer-events: none; + transform: scale(0, 0); + transition: all 0.3s ease-in-out 0s; + z-index: 9; + bottom: 0; + height: 26px; + margin: auto; +} + +switch::before { + content: "\e646"; + right: 0; + transform: scale(1, 1); + left: auto; +} + +switch[checked]::after, +switch.checked::after { + transform: scale(1, 1); +} + +switch[checked]::before, +switch.checked::before { + transform: scale(0, 0); +} + +/* #ifndef MP-ALIPAY */ +radio::before, +checkbox::before { + font-family: "cuIcon"; + content: "\e645"; + position: absolute; + color: #ffffff !important; + top: 50%; + margin-top: -8px; + right: 5px; + font-size: 32upx; + line-height: 16px; + pointer-events: none; + transform: scale(1, 1); + transition: all 0.3s ease-in-out 0s; + z-index: 9; +} + +radio .wx-radio-input, +checkbox .wx-checkbox-input, +radio .uni-radio-input, +checkbox .uni-checkbox-input { + margin: 0; + width: 24px; + height: 24px; +} + +checkbox.round .wx-checkbox-input, +checkbox.round .uni-checkbox-input { + border-radius: 100upx; +} + +/* #endif */ + +switch[checked]::before { + transform: scale(0, 0); +} + +switch .wx-switch-input, +switch .uni-switch-input { + border: none; + padding: 0 24px; + width: 48px; + height: 26px; + margin: 0; + border-radius: 100upx; +} + +switch .wx-switch-input:not([class*="bg-"]), +switch .uni-switch-input:not([class*="bg-"]) { + background: #8799a3 !important; +} + +switch .wx-switch-input::after, +switch .uni-switch-input::after { + margin: auto; + width: 26px; + height: 26px; + border-radius: 100upx; + left: 0upx; + top: 0upx; + bottom: 0upx; + position: absolute; + transform: scale(0.9, 0.9); + transition: all 0.1s ease-in-out 0s; +} + +switch .wx-switch-input.wx-switch-input-checked::after, +switch .uni-switch-input.uni-switch-input-checked::after { + margin: auto; + left: 22px; + box-shadow: none; + transform: scale(0.9, 0.9); +} + +radio-group { + display: inline-block; +} + + + +switch.radius .wx-switch-input::after, +switch.radius .wx-switch-input, +switch.radius .wx-switch-input::before, +switch.radius .uni-switch-input::after, +switch.radius .uni-switch-input, +switch.radius .uni-switch-input::before { + border-radius: 10upx; +} + +switch .wx-switch-input::before, +radio.radio::before, +checkbox .wx-checkbox-input::before, +radio .wx-radio-input::before, +switch .uni-switch-input::before, +radio.radio::before, +checkbox .uni-checkbox-input::before, +radio .uni-radio-input::before { + display: none; +} + +radio.radio[checked]::after, +radio.radio .uni-radio-input-checked::after { + content: ""; + background-color: transparent; + display: block; + position: absolute; + width: 8px; + height: 8px; + z-index: 999; + top: 0upx; + left: 0upx; + right: 0; + bottom: 0; + margin: auto; + border-radius: 200upx; + /* #ifndef MP */ + border: 7px solid #ffffff !important; + /* #endif */ + + /* #ifdef MP */ + border: 8px solid #ffffff !important; + /* #endif */ +} + +.switch-sex::after { + content: "\e71c"; +} + +.switch-sex::before { + content: "\e71a"; +} + +.switch-sex .wx-switch-input, +.switch-sex .uni-switch-input { + background: #e54d42 !important; + border-color: #e54d42 !important; +} + +.switch-sex[checked] .wx-switch-input, +.switch-sex.checked .uni-switch-input { + background: #0081ff !important; + border-color: #0081ff !important; +} + +switch.red[checked] .wx-switch-input.wx-switch-input-checked, +checkbox.red[checked] .wx-checkbox-input, +radio.red[checked] .wx-radio-input, +switch.red.checked .uni-switch-input.uni-switch-input-checked, +checkbox.red.checked .uni-checkbox-input, +radio.red.checked .uni-radio-input { + background-color: #e54d42 !important; + border-color: #e54d42 !important; + color: #ffffff !important; +} + +switch.orange[checked] .wx-switch-input, +checkbox.orange[checked] .wx-checkbox-input, +radio.orange[checked] .wx-radio-input, +switch.orange.checked .uni-switch-input, +checkbox.orange.checked .uni-checkbox-input, +radio.orange.checked .uni-radio-input { + background-color: #f37b1d !important; + border-color: #f37b1d !important; + color: #ffffff !important; +} + +switch.yellow[checked] .wx-switch-input, +checkbox.yellow[checked] .wx-checkbox-input, +radio.yellow[checked] .wx-radio-input, +switch.yellow.checked .uni-switch-input, +checkbox.yellow.checked .uni-checkbox-input, +radio.yellow.checked .uni-radio-input { + background-color: #fbbd08 !important; + border-color: #fbbd08 !important; + color: #333333 !important; +} + +switch.olive[checked] .wx-switch-input, +checkbox.olive[checked] .wx-checkbox-input, +radio.olive[checked] .wx-radio-input, +switch.olive.checked .uni-switch-input, +checkbox.olive.checked .uni-checkbox-input, +radio.olive.checked .uni-radio-input { + background-color: #8dc63f !important; + border-color: #8dc63f !important; + color: #ffffff !important; +} + +switch.green[checked] .wx-switch-input, +switch[checked] .wx-switch-input, +checkbox.green[checked] .wx-checkbox-input, +checkbox[checked] .wx-checkbox-input, +radio.green[checked] .wx-radio-input, +radio[checked] .wx-radio-input, +switch.green.checked .uni-switch-input, +switch.checked .uni-switch-input, +checkbox.green.checked .uni-checkbox-input, +checkbox.checked .uni-checkbox-input, +radio.green.checked .uni-radio-input, +radio.checked .uni-radio-input { + background-color: #39b54a !important; + border-color: #39b54a !important; + color: #ffffff !important; + border-color: #39B54A !important; +} + +switch.cyan[checked] .wx-switch-input, +checkbox.cyan[checked] .wx-checkbox-input, +radio.cyan[checked] .wx-radio-input, +switch.cyan.checked .uni-switch-input, +checkbox.cyan.checked .uni-checkbox-input, +radio.cyan.checked .uni-radio-input { + background-color: #1cbbb4 !important; + border-color: #1cbbb4 !important; + color: #ffffff !important; +} + +switch.blue[checked] .wx-switch-input, +checkbox.blue[checked] .wx-checkbox-input, +radio.blue[checked] .wx-radio-input, +switch.blue.checked .uni-switch-input, +checkbox.blue.checked .uni-checkbox-input, +radio.blue.checked .uni-radio-input { + background-color: #0081ff !important; + border-color: #0081ff !important; + color: #ffffff !important; +} + +switch.purple[checked] .wx-switch-input, +checkbox.purple[checked] .wx-checkbox-input, +radio.purple[checked] .wx-radio-input, +switch.purple.checked .uni-switch-input, +checkbox.purple.checked .uni-checkbox-input, +radio.purple.checked .uni-radio-input { + background-color: #6739b6 !important; + border-color: #6739b6 !important; + color: #ffffff !important; +} + +switch.mauve[checked] .wx-switch-input, +checkbox.mauve[checked] .wx-checkbox-input, +radio.mauve[checked] .wx-radio-input, +switch.mauve.checked .uni-switch-input, +checkbox.mauve.checked .uni-checkbox-input, +radio.mauve.checked .uni-radio-input { + background-color: #9c26b0 !important; + border-color: #9c26b0 !important; + color: #ffffff !important; +} + +switch.pink[checked] .wx-switch-input, +checkbox.pink[checked] .wx-checkbox-input, +radio.pink[checked] .wx-radio-input, +switch.pink.checked .uni-switch-input, +checkbox.pink.checked .uni-checkbox-input, +radio.pink.checked .uni-radio-input { + background-color: #e03997 !important; + border-color: #e03997 !important; + color: #ffffff !important; +} + +switch.brown[checked] .wx-switch-input, +checkbox.brown[checked] .wx-checkbox-input, +radio.brown[checked] .wx-radio-input, +switch.brown.checked .uni-switch-input, +checkbox.brown.checked .uni-checkbox-input, +radio.brown.checked .uni-radio-input { + background-color: #a5673f !important; + border-color: #a5673f !important; + color: #ffffff !important; +} + +switch.grey[checked] .wx-switch-input, +checkbox.grey[checked] .wx-checkbox-input, +radio.grey[checked] .wx-radio-input, +switch.grey.checked .uni-switch-input, +checkbox.grey.checked .uni-checkbox-input, +radio.grey.checked .uni-radio-input { + background-color: #8799a3 !important; + border-color: #8799a3 !important; + color: #ffffff !important; +} + +switch.gray[checked] .wx-switch-input, +checkbox.gray[checked] .wx-checkbox-input, +radio.gray[checked] .wx-radio-input, +switch.gray.checked .uni-switch-input, +checkbox.gray.checked .uni-checkbox-input, +radio.gray.checked .uni-radio-input { + background-color: #f0f0f0 !important; + border-color: #f0f0f0 !important; + color: #333333 !important; +} + +switch.black[checked] .wx-switch-input, +checkbox.black[checked] .wx-checkbox-input, +radio.black[checked] .wx-radio-input, +switch.black.checked .uni-switch-input, +checkbox.black.checked .uni-checkbox-input, +radio.black.checked .uni-radio-input { + background-color: #333333 !important; + border-color: #333333 !important; + color: #ffffff !important; +} + +switch.white[checked] .wx-switch-input, +checkbox.white[checked] .wx-checkbox-input, +radio.white[checked] .wx-radio-input, +switch.white.checked .uni-switch-input, +checkbox.white.checked .uni-checkbox-input, +radio.white.checked .uni-radio-input { + background-color: #ffffff !important; + border-color: #ffffff !important; + color: #333333 !important; +} + +/* ================== + 边框 + ==================== */ + +/* -- 实线 -- */ + +.solid, +.solid-top, +.solid-right, +.solid-bottom, +.solid-left, +.solids, +.solids-top, +.solids-right, +.solids-bottom, +.solids-left, +.dashed, +.dashed-top, +.dashed-right, +.dashed-bottom, +.dashed-left { + position: relative; +} + +.solid::after, +.solid-top::after, +.solid-right::after, +.solid-bottom::after, +.solid-left::after, +.solids::after, +.solids-top::after, +.solids-right::after, +.solids-bottom::after, +.solids-left::after, +.dashed::after, +.dashed-top::after, +.dashed-right::after, +.dashed-bottom::after, +.dashed-left::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border-radius: inherit; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; +} + +.solid::after { + border: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-top::after { + border-top: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-right::after { + border-right: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-bottom::after { + border-bottom: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-left::after { + border-left: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solids::after { + border: 8upx solid #eee; +} + +.solids-top::after { + border-top: 8upx solid #eee; +} + +.solids-right::after { + border-right: 8upx solid #eee; +} + +.solids-bottom::after { + border-bottom: 8upx solid #eee; +} + +.solids-left::after { + border-left: 8upx solid #eee; +} + +/* -- 虚线 -- */ + +.dashed::after { + border: 1upx dashed #ddd; +} + +.dashed-top::after { + border-top: 1upx dashed #ddd; +} + +.dashed-right::after { + border-right: 1upx dashed #ddd; +} + +.dashed-bottom::after { + border-bottom: 1upx dashed #ddd; +} + +.dashed-left::after { + border-left: 1upx dashed #ddd; +} + +/* -- 阴影 -- */ + +.shadow[class*='white'] { + --ShadowSize: 0 1upx 6upx; +} + +.shadow-lg { + --ShadowSize: 0upx 40upx 100upx 0upx; +} + +.shadow-warp { + position: relative; + box-shadow: 0 0 10upx rgba(0, 0, 0, 0.1); +} + +.shadow-warp:before, +.shadow-warp:after { + position: absolute; + content: ""; + top: 20upx; + bottom: 30upx; + left: 20upx; + width: 50%; + box-shadow: 0 30upx 20upx rgba(0, 0, 0, 0.2); + transform: rotate(-3deg); + z-index: -1; +} + +.shadow-warp:after { + right: 20upx; + left: auto; + transform: rotate(3deg); +} + +.shadow-blur { + position: relative; +} + +.shadow-blur::before { + content: ""; + display: block; + background: inherit; + filter: blur(10upx); + position: absolute; + width: 100%; + height: 100%; + top: 10upx; + left: 10upx; + z-index: -1; + opacity: 0.4; + transform-origin: 0 0; + border-radius: inherit; + transform: scale(1, 1); +} + +/* ================== + 按钮 + ==================== */ + +.cu-btn { + position: relative; + border: 0upx; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 0 30upx; + font-size: 28upx; + height: 64upx; + line-height: 1; + text-align: center; + text-decoration: none; + overflow: visible; + margin-left: initial; + transform: translate(0upx, 0upx); + margin-right: initial; +} + +.cu-btn::after { + display: none; +} + +.cu-btn:not([class*="bg-"]) { + background-color: #f0f0f0; +} + +.cu-btn[class*="line"] { + background-color: transparent; +} + +.cu-btn[class*="line"]::after { + content: " "; + display: block; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1upx solid currentColor; + transform: scale(0.5); + transform-origin: 0 0; + box-sizing: border-box; + border-radius: 12upx; + z-index: 1; + pointer-events: none; +} + +.cu-btn.round[class*="line"]::after { + border-radius: 1000upx; +} + +.cu-btn[class*="lines"]::after { + border: 6upx solid currentColor; +} + +.cu-btn[class*="bg-"]::after { + display: none; +} + +.cu-btn.sm { + padding: 0 20upx; + font-size: 20upx; + height: 48upx; +} + +.cu-btn.lg { + padding: 0 40upx; + font-size: 32upx; + height: 80upx; +} + +.cu-btn.cuIcon.sm { + width: 48upx; + height: 48upx; +} + +.cu-btn.cuIcon { + width: 64upx; + height: 64upx; + border-radius: 500upx; + padding: 0; +} + +button.cuIcon.lg { + width: 80upx; + height: 80upx; +} + +.cu-btn.shadow-blur::before { + top: 4upx; + left: 4upx; + filter: blur(6upx); + opacity: 0.6; +} + +.cu-btn.button-hover { + transform: translate(1upx, 1upx); +} + +.block { + display: block; +} + +.cu-btn.block { + display: flex; +} + +.cu-btn[disabled] { + opacity: 0.6; + color: #ffffff; +} + +/* ================== + 徽章 + ==================== */ + +.cu-tag { + font-size: 24upx; + vertical-align: middle; + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 0upx 16upx; + height: 48upx; + font-family: Helvetica Neue, Helvetica, sans-serif; + white-space: nowrap; +} + +.cu-tag:not([class*="bg"]):not([class*="line"]) { + background-color: #f1f1f1; +} + +.cu-tag[class*="line-"]::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1upx solid currentColor; + transform: scale(0.5); + transform-origin: 0 0; + box-sizing: border-box; + border-radius: inherit; + z-index: 1; + pointer-events: none; +} + +.cu-tag.radius[class*="line"]::after { + border-radius: 12upx; +} + +.cu-tag.round[class*="line"]::after { + border-radius: 1000upx; +} + +.cu-tag[class*="line-"]::after { + border-radius: 0; +} + +.cu-tag+.cu-tag { + margin-left: 10upx; +} + +.cu-tag.sm { + font-size: 20upx; + padding: 0upx 12upx; + height: 32upx; +} + +.cu-capsule { + display: inline-flex; + vertical-align: middle; +} + +.cu-capsule+.cu-capsule { + margin-left: 10upx; +} + +.cu-capsule .cu-tag { + margin: 0; +} + +.cu-capsule .cu-tag[class*="line-"]:last-child::after { + border-left: 0upx solid transparent; +} + +.cu-capsule .cu-tag[class*="line-"]:first-child::after { + border-right: 0upx solid transparent; +} + +.cu-capsule.radius .cu-tag:first-child { + border-top-left-radius: 6upx; + border-bottom-left-radius: 6upx; +} + +.cu-capsule.radius .cu-tag:last-child::after, +.cu-capsule.radius .cu-tag[class*="line-"] { + border-top-right-radius: 12upx; + border-bottom-right-radius: 12upx; +} + +.cu-capsule.round .cu-tag:first-child { + border-top-left-radius: 200upx; + border-bottom-left-radius: 200upx; + text-indent: 4upx; +} + +.cu-capsule.round .cu-tag:last-child::after, +.cu-capsule.round .cu-tag:last-child { + border-top-right-radius: 200upx; + border-bottom-right-radius: 200upx; + text-indent: -4upx; +} + +.cu-tag.badge { + border-radius: 200upx; + position: absolute; + top: 0upx; + right: -10upx; + font-size: 20upx; + padding: 0upx 10upx; + height: 32upx; + color: #ffffff; +} + +.cu-tag.badge:not([class*="bg-"]) { + background-color: #dd514c; +} + +.cu-tag:empty:not([class*="cuIcon-"]) { + padding: 0upx; + width: 16upx; + height: 16upx; + top: -4upx; + right: -4upx; +} + +.cu-tag[class*="cuIcon-"] { + width: 32upx; + height: 32upx; + top: -4upx; + right: -4upx; +} + +/* ================== + 头像 + ==================== */ + +.cu-avatar { + font-variant: small-caps; + margin: 0; + padding: 0; + display: inline-flex; + text-align: center; + justify-content: center; + align-items: center; +/* background-color: #ccc; */ + color: #ffffff; + white-space: nowrap; + position: relative; + width: 64upx; + height: 64upx; + background-size: cover; + background-position: center; + vertical-align: middle; + font-size: 1.5em; +} + +.cu-avatar.sm { + width: 48upx; + height: 48upx; + font-size: 1em; +} + +.cu-avatar.lg { + width: 96upx; + height: 96upx; + font-size: 2em; +} + +.cu-avatar.xl { + width: 128upx; + height: 128upx; + font-size: 2.5em; +} + +.cu-avatar .avatar-text { + font-size: 0.4em; +} + +.cu-avatar-group { + direction: rtl; + unicode-bidi: bidi-override; + padding: 0 10upx 0 40upx; + display: inline-block; +} + +.cu-avatar-group .cu-avatar { + margin-left: -30upx; + border: 4upx solid #f1f1f1; + vertical-align: middle; +} + +.cu-avatar-group .cu-avatar.sm { + margin-left: -20upx; + border: 1upx solid #f1f1f1; +} + +/* ================== + 进度条 + ==================== */ + +.cu-progress { + overflow: hidden; + height: 28upx; + background-color: #ebeef5; + display: inline-flex; + align-items: center; + width: 100%; +} + +.cu-progress+view, +.cu-progress+text { + line-height: 1; +} + +.cu-progress.xs { + height: 10upx; +} + +.cu-progress.sm { + height: 20upx; +} + +.cu-progress view { + width: 0; + height: 100%; + align-items: center; + display: flex; + justify-items: flex-end; + justify-content: space-around; + font-size: 20upx; + color: #ffffff; + transition: width 0.6s ease; +} + +.cu-progress text { + align-items: center; + display: flex; + font-size: 20upx; + color: #333333; + text-indent: 10upx; +} + +.cu-progress.text-progress { + padding-right: 60upx; +} + +.cu-progress.striped view { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 72upx 72upx; +} + +.cu-progress.active view { + animation: progress-stripes 2s linear infinite; +} + +@keyframes progress-stripes { + from { + background-position: 72upx 0; + } + + to { + background-position: 0 0; + } +} + +/* ================== + 加载 + ==================== */ + +.cu-load { + display: block; + line-height: 3em; + text-align: center; +} + +.cu-load::before { + font-family: "cuIcon"; + display: inline-block; + margin-right: 6upx; +} + +.cu-load.loading::before { + content: "\e67a"; + animation: cuIcon-spin 2s infinite linear; +} + +.cu-load.loading::after { + content: "加载中..."; +} + +.cu-load.over::before { + content: "\e64a"; +} + +.cu-load.over::after { + content: "没有更多了"; +} + +.cu-load.erro::before { + content: "\e658"; +} + +.cu-load.erro::after { + content: "加载失败"; +} + +.cu-load.load-cuIcon::before { + font-size: 32upx; +} + +.cu-load.load-cuIcon::after { + display: none; +} + +.cu-load.load-cuIcon.over { + display: none; +} + +.cu-load.load-modal { + position: fixed; + top: 0; + right: 0; + bottom: 140upx; + left: 0; + margin: auto; + width: 260upx; + height: 260upx; + background-color: #ffffff; + border-radius: 10upx; + box-shadow: 0 0 0upx 2000upx rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + font-size: 28upx; + z-index: 9999; + line-height: 2.4em; +} + +.cu-load.load-modal [class*="cuIcon-"] { + font-size: 60upx; +} + +.cu-load.load-modal image { + width: 70upx; + height: 70upx; +} + +.cu-load.load-modal::after { + content: ""; + position: absolute; + background-color: #ffffff; + border-radius: 50%; + width: 200upx; + height: 200upx; + font-size: 10px; + border-top: 6upx solid rgba(0, 0, 0, 0.05); + border-right: 6upx solid rgba(0, 0, 0, 0.05); + border-bottom: 6upx solid rgba(0, 0, 0, 0.05); + border-left: 6upx solid #f37b1d; + animation: cuIcon-spin 1s infinite linear; + z-index: -1; +} + +.load-progress { + pointer-events: none; + top: 0; + position: fixed; + width: 100%; + left: 0; + z-index: 2000; +} + +.load-progress.hide { + display: none; +} + +.load-progress .load-progress-bar { + position: relative; + width: 100%; + height: 4upx; + overflow: hidden; + transition: all 200ms ease 0s; +} + +.load-progress .load-progress-spinner { + position: absolute; + top: 10upx; + right: 10upx; + z-index: 2000; + display: block; +} + +.load-progress .load-progress-spinner::after { + content: ""; + display: block; + width: 24upx; + height: 24upx; + -webkit-box-sizing: border-box; + box-sizing: border-box; + border: solid 4upx transparent; + border-top-color: inherit; + border-left-color: inherit; + border-radius: 50%; + -webkit-animation: load-progress-spinner 0.4s linear infinite; + animation: load-progress-spinner 0.4s linear infinite; +} + +@-webkit-keyframes load-progress-spinner { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes load-progress-spinner { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +/* ================== + 列表 + ==================== */ +.grayscale { + filter: grayscale(1); +} + +.cu-list+.cu-list { + margin-top: 30upx +} + +.cu-list>.cu-item { + transition: all .6s ease-in-out 0s; + transform: translateX(0upx) +} + +.cu-list>.cu-item.move-cur { + transform: translateX(-260upx) +} + +.cu-list>.cu-item .move { + position: absolute; + right: 0; + display: flex; + width: 260upx; + height: 100%; + transform: translateX(100%) +} + +.cu-list>.cu-item .move view { + display: flex; + flex: 1; + justify-content: center; + align-items: center +} + +.cu-list.menu-avatar { + overflow: hidden; +} + +.cu-list.menu-avatar>.cu-item { + position: relative; + display: flex; + padding-right: 10upx; + height: 140upx; + background-color: #ffffff; + justify-content: flex-end; + align-items: center +} + +.cu-list.menu-avatar>.cu-item>.cu-avatar { + position: absolute; + left: 30upx +} + +.cu-list.menu-avatar>.cu-item .flex .text-cut { + max-width: 510upx +} + +.cu-list.menu-avatar>.cu-item .content { + position: absolute; + left: 146upx; + width: calc(100% - 96upx - 60upx - 120upx - 20upx); + line-height: 1.6em; +} + +.cu-list.menu-avatar>.cu-item .content.flex-sub { + width: calc(100% - 96upx - 60upx - 20upx); +} + +.cu-list.menu-avatar>.cu-item .content>view:first-child { + font-size: 30upx; + display: flex; + align-items: center +} + +.cu-list.menu-avatar>.cu-item .content .cu-tag.sm { + display: inline-block; + margin-left: 10upx; + height: 28upx; + font-size: 16upx; + line-height: 32upx +} + +.cu-list.menu-avatar>.cu-item .action { + width: 120upx; + text-align: right +} + +.cu-list.menu-avatar>.cu-item .action view+view { + margin-top: 10upx +} + +.cu-list.menu-avatar.comment>.cu-item .content { + position: relative; + left: 0; + width: auto; + flex: 1; +} + +.cu-list.menu-avatar.comment>.cu-item { + padding: 30upx 30upx 30upx 120upx; + height: auto +} + +.cu-list.menu-avatar.comment .cu-avatar { + align-self: flex-start +} + +.cu-list.menu>.cu-item { + position: relative; + display: flex; + padding: 0 30upx; + min-height: 100upx; + background-color: #ffffff; + justify-content: space-between; + align-items: center +} + +.cu-list.menu>.cu-item:last-child:after { + border: none +} + +.cu-list.menu-avatar>.cu-item:after, +.cu-list.menu>.cu-item:after { + position: absolute; + top: 0; + left: 0; + box-sizing: border-box; + width: 200%; + height: 200%; + border-bottom: 1upx solid #ddd; + border-radius: inherit; + content: " "; + transform: scale(.5); + transform-origin: 0 0; + pointer-events: none +} + +.cu-list.menu>.cu-item.grayscale { + background-color: #f5f5f5 +} + +.cu-list.menu>.cu-item.cur { + background-color: #fcf7e9 +} + +.cu-list.menu>.cu-item.arrow { + padding-right: 90upx +} + +.cu-list.menu>.cu-item.arrow:before { + position: absolute; + top: 0; + right: 30upx; + bottom: 0; + display: block; + margin: auto; + width: 30upx; + height: 30upx; + color: #8799a3; + content: "\e6a3"; + text-align: center; + font-size: 34upx; + font-family: cuIcon; + line-height: 30upx +} + +.cu-list.menu>.cu-item button.content { + padding: 0; + background-color: transparent; + justify-content: flex-start +} + +.cu-list.menu>.cu-item button.content:after { + display: none +} + +.cu-list.menu>.cu-item .cu-avatar-group .cu-avatar { + border-color: #ffffff +} + +.cu-list.menu>.cu-item .content>view:first-child { + display: flex; + align-items: center +} + +.cu-list.menu>.cu-item .content>text[class*=cuIcon] { + display: inline-block; + margin-right: 10upx; + width: 1.6em; + text-align: center +} + +.cu-list.menu>.cu-item .content>image { + display: inline-block; + margin-right: 10upx; + width: 1.6em; + height: 1.6em; + vertical-align: middle +} + +.cu-list.menu>.cu-item .content { + font-size: 30upx; + line-height: 1.6em; + flex: 1 +} + +.cu-list.menu>.cu-item .content .cu-tag.sm { + display: inline-block; + margin-left: 10upx; + height: 28upx; + font-size: 16upx; + line-height: 32upx +} + +.cu-list.menu>.cu-item .action .cu-tag:empty { + right: 10upx +} + +.cu-list.menu { + display: block; + overflow: hidden +} + +.cu-list.menu.sm-border>.cu-item:after { + left: 30upx; + width: calc(200% - 120upx) +} + +.cu-list.grid>.cu-item { + position: relative; + display: flex; + padding: 20upx 0 30upx; + transition-duration: 0s; + flex-direction: column +} + +.cu-list.grid>.cu-item:after { + position: absolute; + top: 0; + left: 0; + box-sizing: border-box; + width: 200%; + height: 200%; + border-right: 1px solid rgba(0, 0, 0, .1); + border-bottom: 1px solid rgba(0, 0, 0, .1); + border-radius: inherit; + content: " "; + transform: scale(.5); + transform-origin: 0 0; + pointer-events: none +} + +.cu-list.grid>.cu-item text { + display: block; + margin-top: 10upx; + color: #888; + font-size: 26upx; + line-height: 40upx +} + +.cu-list.grid>.cu-item [class*=cuIcon] { + position: relative; + display: block; + margin-top: 20upx; + width: 100%; + font-size: 48upx +} + +.cu-list.grid>.cu-item .cu-tag { + right: auto; + left: 50%; + margin-left: 20upx +} + +.cu-list.grid { + background-color: #ffffff; + text-align: center +} + +.cu-list.grid.no-border>.cu-item { + padding-top: 10upx; + padding-bottom: 20upx +} + +.cu-list.grid.no-border>.cu-item:after { + border: none +} + +.cu-list.grid.no-border { + padding: 20upx 10upx +} + +.cu-list.grid.col-3>.cu-item:nth-child(3n):after, +.cu-list.grid.col-4>.cu-item:nth-child(4n):after, +.cu-list.grid.col-5>.cu-item:nth-child(5n):after { + border-right-width: 0 +} + +.cu-list.card-menu { + overflow: hidden; + margin-right: 30upx; + margin-left: 30upx; + border-radius: 20upx +} + + +/* ================== + 操作条 + ==================== */ + +.cu-bar { + display: flex; + position: relative; + align-items: center; + min-height: 100upx; + justify-content: space-between; +} + +.cu-bar .action { + display: flex; + align-items: center; + height: 100%; + justify-content: center; + max-width: 100%; +} + +.cu-bar .action.border-title { + position: relative; + top: -10upx; +} + +.cu-bar .action.border-title text[class*="bg-"]:last-child { + position: absolute; + bottom: -0.5rem; + min-width: 2rem; + height: 6upx; + left: 0; +} + +.cu-bar .action.sub-title { + position: relative; + top: -0.2rem; +} + +.cu-bar .action.sub-title text { + position: relative; + z-index: 1; +} + +.cu-bar .action.sub-title text[class*="bg-"]:last-child { + position: absolute; + display: inline-block; + bottom: -0.2rem; + border-radius: 6upx; + width: 100%; + height: 0.6rem; + left: 0.6rem; + opacity: 0.3; + z-index: 0; +} + +.cu-bar .action.sub-title text[class*="text-"]:last-child { + position: absolute; + display: inline-block; + bottom: -0.7rem; + left: 0.5rem; + opacity: 0.2; + z-index: 0; + text-align: right; + font-weight: 900; + font-size: 36upx; +} + +.cu-bar.justify-center .action.border-title text:last-child, +.cu-bar.justify-center .action.sub-title text:last-child { + left: 0; + right: 0; + margin: auto; + text-align: center; +} + +.cu-bar .action:first-child { + margin-left: 30upx; + font-size: 30upx; +} + +.cu-bar .action text.text-cut { + text-align: left; + width: 100%; +} + +.cu-bar .cu-avatar:first-child { + margin-left: 20upx; +} + +.cu-bar .action:first-child>text[class*="cuIcon-"] { + margin-left: -0.3em; + margin-right: 0.3em; +} + +.cu-bar .action:last-child { + margin-right: 30upx; +} + +.cu-bar .action>text[class*="cuIcon-"], +.cu-bar .action>view[class*="cuIcon-"] { + font-size: 36upx; +} + +.cu-bar .action>text[class*="cuIcon-"]+text[class*="cuIcon-"] { + margin-left: 0.5em; +} + +.cu-bar .content { + position: absolute; + text-align: center; + width: calc(100% - 340upx); + left: 0; + right: 0; + bottom: 0; + top: 0; + margin: auto; + height: 60upx; + font-size: 32upx; + line-height: 60upx; + cursor: none; + pointer-events: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.cu-bar.ios .content { + bottom: 7px; + height: 30px; + font-size: 32upx; + line-height: 30px; +} + +.cu-bar.btn-group { + justify-content: space-around; +} + +.cu-bar.btn-group button { + padding: 20upx 32upx; +} + +.cu-bar.btn-group button { + flex: 1; + margin: 0 20upx; + max-width: 50%; +} + +.cu-bar .search-form { + background-color: #f5f5f5; + line-height: 64upx; + height: 64upx; + font-size: 24upx; + color: #333333; + flex: 1; + display: flex; + align-items: center; + margin: 0 30upx; +} + +.cu-bar .search-form+.action { + margin-right: 30upx; +} + +.cu-bar .search-form input { + flex: 1; + padding-right: 30upx; + height: 64upx; + line-height: 64upx; + font-size: 26upx; + background-color: transparent; +} + +.cu-bar .search-form [class*="cuIcon-"] { + margin: 0 0.5em 0 0.8em; +} + +.cu-bar .search-form [class*="cuIcon-"]::before { + top: 0upx; +} + +.cu-bar.fixed, +.nav.fixed { + position: fixed; + width: 100%; + top: 0; + z-index: 1024; + box-shadow: 0 1upx 6upx rgba(0, 0, 0, 0.1); +} + +.cu-bar.foot { + position: fixed; + width: 100%; + bottom: 0; + z-index: 1024; + box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1); +} + +.cu-bar.tabbar { + padding: 0; + height: calc(100upx + env(safe-area-inset-bottom) / 2); + padding-bottom: calc(env(safe-area-inset-bottom) / 2); +} + +.cu-tabbar-height { + min-height: 100upx; + height: calc(100upx + env(safe-area-inset-bottom) / 2); +} + +.cu-bar.tabbar.shadow { + box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1); +} + +.cu-bar.tabbar .action { + font-size: 22upx; + position: relative; + flex: 1; + text-align: center; + padding: 0; + display: block; + height: auto; + line-height: 1; + margin: 0; + background-color: inherit; + overflow: initial; +} + +.cu-bar.tabbar.shop .action { + width: 140upx; + flex: initial; +} + +.cu-bar.tabbar .action.add-action { + position: relative; + z-index: 2; + padding-top: 50upx; +} + +.cu-bar.tabbar .action.add-action [class*="cuIcon-"] { + position: absolute; + width: 70upx; + z-index: 2; + height: 70upx; + border-radius: 50%; + line-height: 70upx; + font-size: 50upx; + top: -35upx; + left: 0; + right: 0; + margin: auto; + padding: 0; +} + +.cu-bar.tabbar .action.add-action::after { + content: ""; + position: absolute; + width: 100upx; + height: 100upx; + top: -50upx; + left: 0; + right: 0; + margin: auto; + box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08); + border-radius: 50upx; + background-color: inherit; + z-index: 0; +} + +.cu-bar.tabbar .action.add-action::before { + content: ""; + position: absolute; + width: 100upx; + height: 30upx; + bottom: 30upx; + left: 0; + right: 0; + margin: auto; + background-color: inherit; + z-index: 1; +} + +.cu-bar.tabbar .btn-group { + flex: 1; + display: flex; + justify-content: space-around; + align-items: center; + padding: 0 10upx; +} + +.cu-bar.tabbar button.action::after { + border: 0; +} + +.cu-bar.tabbar .action [class*="cuIcon-"] { + width: 100upx; + position: relative; + display: block; + height: auto; + margin: 0 auto 10upx; + text-align: center; + font-size: 40upx; +} + +.cu-bar.tabbar .action .cuIcon-cu-image { + margin: 0 auto; +} + +.cu-bar.tabbar .action .cuIcon-cu-image image { + width: 50upx; + height: 50upx; + display: inline-block; +} + +.cu-bar.tabbar .submit { + align-items: center; + display: flex; + justify-content: center; + text-align: center; + position: relative; + flex: 2; + align-self: stretch; +} + +.cu-bar.tabbar .submit:last-child { + flex: 2.6; +} + +.cu-bar.tabbar .submit+.submit { + flex: 2; +} + +.cu-bar.tabbar.border .action::before { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + transform: scale(0.5); + transform-origin: 0 0; + border-right: 1upx solid rgba(0, 0, 0, 0.1); + z-index: 3; +} + +.cu-bar.tabbar.border .action:last-child:before { + display: none; +} + +.cu-bar.input { + padding-right: 20upx; + background-color: #ffffff; +} + +.cu-bar.input input { + overflow: initial; + line-height: 64upx; + height: 64upx; + min-height: 64upx; + flex: 1; + font-size: 30upx; + margin: 0 20upx; +} + +.cu-bar.input .action { + margin-left: 20upx; +} + +.cu-bar.input .action [class*="cuIcon-"] { + font-size: 48upx; +} + +.cu-bar.input input+.action { + margin-right: 20upx; + margin-left: 0upx; +} + +.cu-bar.input .action:first-child [class*="cuIcon-"] { + margin-left: 0upx; +} + +.cu-custom { + display: block; + position: relative; +} + +.cu-custom .cu-bar .content { + width: calc(100% - 440upx); +} + +/* #ifdef MP-ALIPAY */ +.cu-custom .cu-bar .action .cuIcon-back { + opacity: 0; +} + +/* #endif */ + +.cu-custom .cu-bar .content image { + height: 60upx; + width: 240upx; +} + +.cu-custom .cu-bar { + min-height: 0px; + /* #ifdef MP-WEIXIN */ + padding-right: 220upx; + /* #endif */ + /* #ifdef MP-ALIPAY */ + padding-right: 150upx; + /* #endif */ + box-shadow: 0upx 0upx 0upx; + z-index: 101; +} + +.cu-custom .cu-bar .border-custom { + position: relative; + background: rgba(0, 0, 0, 0.15); + border-radius: 1000upx; + height: 30px; +} + +.cu-custom .cu-bar .border-custom::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border-radius: inherit; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; + border: 1upx solid #ffffff; + opacity: 0.5; +} + +.cu-custom .cu-bar .border-custom::before { + content: " "; + width: 1upx; + height: 110%; + position: absolute; + top: 22.5%; + left: 0; + right: 0; + margin: auto; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; + opacity: 0.6; + background-color: #ffffff; +} + +.cu-custom .cu-bar .border-custom text { + display: block; + flex: 1; + margin: auto !important; + text-align: center; + font-size: 34upx; +} + +/* ================== + 导航栏 + ==================== */ + +.nav { + white-space: nowrap; +} + +::-webkit-scrollbar { + display: none; +} + +.nav .cu-item { + height: 90upx; + display: inline-block; + line-height: 90upx; + margin: 0 10upx; + padding: 0 20upx; +} + +.nav .cu-item.cur { + border-bottom: 4upx solid; +} + +/* ================== + 时间轴 + ==================== */ + +.cu-timeline { + display: block; + background-color: #ffffff; +} + +.cu-timeline .cu-time { + width: 120upx; + text-align: center; + padding: 20upx 0; + font-size: 26upx; + color: #888; + display: block; +} + +.cu-timeline>.cu-item { + padding: 30upx 30upx 30upx 120upx; + position: relative; + display: block; + z-index: 0; +} + +.cu-timeline>.cu-item:not([class*="text-"]) { + color: #ccc; +} + +.cu-timeline>.cu-item::after { + content: ""; + display: block; + position: absolute; + width: 1upx; + background-color: #ddd; + left: 60upx; + height: 100%; + top: 0; + z-index: 8; +} + +.cu-timeline>.cu-item::before { + font-family: "cuIcon"; + display: block; + position: absolute; + top: 36upx; + z-index: 9; + background-color: #ffffff; + width: 50upx; + height: 50upx; + text-align: center; + border: none; + line-height: 50upx; + left: 36upx; +} + +.cu-timeline>.cu-item:not([class*="cuIcon-"])::before { + content: "\e763"; +} + +.cu-timeline>.cu-item[class*="cuIcon-"]::before { + background-color: #ffffff; + width: 50upx; + height: 50upx; + text-align: center; + border: none; + line-height: 50upx; + left: 36upx; +} + +.cu-timeline>.cu-item>.content { + padding: 30upx; + border-radius: 6upx; + display: block; + line-height: 1.6; +} + +.cu-timeline>.cu-item>.content:not([class*="bg-"]) { + background-color: #f1f1f1; + color: #333333; +} + +.cu-timeline>.cu-item>.content+.content { + margin-top: 20upx; +} + +/* ================== + 聊天 + ==================== */ + +.cu-chat { + display: flex; + flex-direction: column; +} + +.cu-chat .cu-item { + display: flex; + padding: 30upx 30upx 70upx; + position: relative; +} + +.cu-chat .cu-item>.cu-avatar { + width: 80upx; + height: 80upx; +} + +.cu-chat .cu-item>.main { + max-width: calc(100% - 260upx); + margin: 0 40upx; + display: flex; + align-items: center; +} + +.cu-chat .cu-item>image { + height: 320upx; +} + +.cu-chat .cu-item>.main .content { + padding: 20upx; + border-radius: 6upx; + display: inline-flex; + max-width: 100%; + align-items: center; + font-size: 30upx; + position: relative; + min-height: 80upx; + line-height: 40upx; + text-align: left; +} + +.cu-chat .cu-item>.main .content:not([class*="bg-"]) { + background-color: #ffffff; + color: #333333; +} + +.cu-chat .cu-item .date { + position: absolute; + font-size: 24upx; + color: #8799a3; + width: calc(100% - 320upx); + bottom: 20upx; + left: 160upx; +} + +.cu-chat .cu-item .action { + padding: 0 30upx; + display: flex; + align-items: center; +} + +.cu-chat .cu-item>.main .content::after { + content: ""; + top: 27upx; + transform: rotate(45deg); + position: absolute; + z-index: 100; + display: inline-block; + overflow: hidden; + width: 24upx; + height: 24upx; + left: -12upx; + right: initial; + background-color: inherit; +} + +.cu-chat .cu-item.self>.main .content::after { + left: auto; + right: -12upx; +} + +.cu-chat .cu-item>.main .content::before { + content: ""; + top: 30upx; + transform: rotate(45deg); + position: absolute; + z-index: -1; + display: inline-block; + overflow: hidden; + width: 24upx; + height: 24upx; + left: -12upx; + right: initial; + background-color: inherit; + filter: blur(5upx); + opacity: 0.3; +} + +.cu-chat .cu-item>.main .content:not([class*="bg-"])::before { + background-color: #333333; + opacity: 0.1; +} + +.cu-chat .cu-item.self>.main .content::before { + left: auto; + right: -12upx; +} + +.cu-chat .cu-item.self { + justify-content: flex-end; + text-align: right; +} + +.cu-chat .cu-info { + display: inline-block; + margin: 20upx auto; + font-size: 24upx; + padding: 8upx 12upx; + background-color: rgba(0, 0, 0, 0.2); + border-radius: 6upx; + color: #ffffff; + max-width: 400upx; + line-height: 1.4; +} + +/* ================== + 卡片 + ==================== */ + +.cu-card { + display: block; + overflow: hidden; +} + +.cu-card>.cu-item { + display: block; + background-color: #ffffff; + overflow: hidden; + border-radius: 10upx; + margin: 30upx; +} + +.cu-card>.cu-item.shadow-blur { + overflow: initial; +} + +.cu-card.no-card>.cu-item { + margin: 0upx; + border-radius: 0upx; +} + +.cu-card .grid.grid-square { + margin-bottom: -20upx; +} + +.cu-card.case .image { + position: relative; +} + +.cu-card.case .image image { + width: 100%; +} + +.cu-card.case .image .cu-tag { + position: absolute; + right: 0; + top: 0; +} + +.cu-card.case .image .cu-bar { + position: absolute; + bottom: 0; + width: 100%; + background-color: transparent; + padding: 0upx 30upx; +} + +.cu-card.case.no-card .image { + margin: 30upx 30upx 0; + overflow: hidden; + border-radius: 10upx; +} + +.cu-card.dynamic { + display: block; +} + +.cu-card.dynamic>.cu-item { + display: block; + background-color: #ffffff; + overflow: hidden; +} + +.cu-card.dynamic>.cu-item>.text-content { + padding: 0 30upx 0; + max-height: 6.4em; + overflow: hidden; + font-size: 30upx; + margin-bottom: 20upx; +} + +.cu-card.dynamic>.cu-item .square-img { + width: 100%; + height: 200upx; + border-radius: 6upx; +} + +.cu-card.dynamic>.cu-item .only-img { + width: 100%; + height: 320upx; + border-radius: 6upx; +} + +/* card.dynamic>.cu-item .comment { + padding: 20upx; + background-color: #f1f1f1; + margin: 0 30upx 30upx; + border-radius: 6upx; +} */ + +.cu-card.article { + display: block; +} + +.cu-card.article>.cu-item { + padding-bottom: 30upx; +} + +.cu-card.article>.cu-item .title { + font-size: 30upx; + font-weight: 900; + color: #333333; + line-height: 100upx; + padding: 0 30upx; +} + +.cu-card.article>.cu-item .content { + display: flex; + padding: 0 30upx; +} + +.cu-card.article>.cu-item .content>image { + width: 240upx; + height: 6.4em; + margin-right: 20upx; + border-radius: 6upx; +} + +.cu-card.article>.cu-item .content .desc { + flex: 1; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.cu-card.article>.cu-item .content .text-content { + font-size: 28upx; + color: #888; + height: 4.8em; + overflow: hidden; +} + +/* ================== + 表单 + ==================== */ + +.cu-form-group { + background-color: #ffffff; + padding: 1upx 30upx; + display: flex; + align-items: center; + min-height: 100upx; + justify-content: space-between; +} + +.cu-form-group+.cu-form-group { + border-top: 1upx solid #eee; +} + +.cu-form-group .title { + text-align: justify; + padding-right: 30upx; + font-size: 30upx; + position: relative; + height: 60upx; + line-height: 60upx; +} + +.cu-form-group input { + flex: 1; + font-size: 30upx; + color: #555; + padding-right: 20upx; +} + +.cu-form-group>text[class*="cuIcon-"] { + font-size: 36upx; + padding: 0; + box-sizing: border-box; +} + +.cu-form-group textarea { + margin: 32upx 0 30upx; + height: 4.6em; + width: 100%; + line-height: 1.2em; + flex: 1; + font-size: 28upx; + padding: 0; +} + +.cu-form-group.align-start .title { + height: 1em; + margin-top: 32upx; + line-height: 1em; +} + +.cu-form-group picker { + flex: 1; + padding-right: 40upx; + overflow: hidden; + position: relative; +} + +.cu-form-group picker .picker { + line-height: 100upx; + font-size: 28upx; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + width: 100%; + text-align: right; +} + +.cu-form-group picker::after { + font-family: cuIcon; + display: block; + content: "\e6a3"; + position: absolute; + font-size: 34upx; + color: #8799a3; + line-height: 100upx; + width: 60upx; + text-align: center; + top: 0; + bottom: 0; + right: -20upx; + margin: auto; +} + +.cu-form-group textarea[disabled], +.cu-form-group textarea[disabled] .placeholder { + color: transparent; +} + +/* ================== + 模态窗口 + ==================== */ + +.cu-modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1110; + opacity: 0; + outline: 0; + text-align: center; + -ms-transform: scale(1.185); + transform: scale(1.185); + backface-visibility: hidden; + perspective: 2000upx; + background: rgba(0, 0, 0, 0.6); + transition: all 0.3s ease-in-out 0s; + pointer-events: none; +} + +.cu-modal::before { + content: "\200B"; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +.cu-modal.show { + opacity: 1; + transition-duration: 0.3s; + -ms-transform: scale(1); + transform: scale(1); + overflow-x: hidden; + overflow-y: auto; + pointer-events: auto; +} + +.cu-dialog { + position: relative; + display: inline-block; + vertical-align: middle; + margin-left: auto; + margin-right: auto; + width: 680upx; + max-width: 100%; + background-color: #f8f8f8; + border-radius: 10upx; + overflow: hidden; +} + +.cu-modal.bottom-modal::before { + vertical-align: bottom; +} + +.cu-modal.bottom-modal .cu-dialog { + width: 100%; + border-radius: 0; +} + +.cu-modal.bottom-modal { + margin-bottom: -1000upx; +} + +.cu-modal.bottom-modal.show { + margin-bottom: 0; +} + +.cu-modal.drawer-modal { + transform: scale(1); + display: flex; +} + +.cu-modal.drawer-modal .cu-dialog { + height: 100%; + min-width: 200upx; + border-radius: 0; + margin: initial; + transition-duration: 0.3s; +} + +.cu-modal.drawer-modal.justify-start .cu-dialog { + transform: translateX(-100%); +} + +.cu-modal.drawer-modal.justify-end .cu-dialog { + transform: translateX(100%); +} + +.cu-modal.drawer-modal.show .cu-dialog { + transform: translateX(0%); +} +.cu-modal .cu-dialog>.cu-bar:first-child .action{ + min-width: 100rpx; + margin-right: 0; + min-height: 100rpx; +} +/* ================== + 轮播 + ==================== */ +swiper .a-swiper-dot { + display: inline-block; + width: 16upx; + height: 16upx; + background: rgba(0, 0, 0, .3); + border-radius: 50%; + vertical-align: middle; +} + +swiper[class*="-dot"] .wx-swiper-dots, +swiper[class*="-dot"] .a-swiper-dots, +swiper[class*="-dot"] .uni-swiper-dots { + display: flex; + align-items: center; + width: 100%; + justify-content: center; +} + +swiper.square-dot .wx-swiper-dot, +swiper.square-dot .a-swiper-dot, +swiper.square-dot .uni-swiper-dot { + background-color: #ffffff; + opacity: 0.4; + width: 10upx; + height: 10upx; + border-radius: 20upx; + margin: 0 8upx !important; +} + +swiper.square-dot .wx-swiper-dot.wx-swiper-dot-active, +swiper.square-dot .a-swiper-dot.a-swiper-dot-active, +swiper.square-dot .uni-swiper-dot.uni-swiper-dot-active { + opacity: 1; + width: 30upx; +} + +swiper.round-dot .wx-swiper-dot, +swiper.round-dot .a-swiper-dot, +swiper.round-dot .uni-swiper-dot { + width: 10upx; + height: 10upx; + position: relative; + margin: 4upx 8upx !important; +} + +swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active::after, +swiper.round-dot .a-swiper-dot.a-swiper-dot-active::after, +swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active::after { + content: ""; + position: absolute; + width: 10upx; + height: 10upx; + top: 0upx; + left: 0upx; + right: 0; + bottom: 0; + margin: auto; + background-color: #ffffff; + border-radius: 20upx; +} + +swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active, +swiper.round-dot .a-swiper-dot.a-swiper-dot-active, +swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active { + width: 18upx; + height: 18upx; +} + +.screen-swiper { + min-height: 375upx; +} + +.screen-swiper image, +.screen-swiper video, +.swiper-item image, +.swiper-item video { + width: 100%; + display: block; + height: 100%; + margin: 0; + pointer-events: none; +} + +.card-swiper { + height: 420upx !important; +} + +.card-swiper swiper-item { + width: 610upx !important; + left: 70upx; + box-sizing: border-box; + padding: 40upx 0upx 70upx; + overflow: initial; +} + +.card-swiper swiper-item .swiper-item { + width: 100%; + display: block; + height: 100%; + border-radius: 10upx; + transform: scale(0.9); + transition: all 0.2s ease-in 0s; + overflow: hidden; +} + +.card-swiper swiper-item.cur .swiper-item { + transform: none; + transition: all 0.2s ease-in 0s; +} + + +.tower-swiper { + height: 420upx; + position: relative; + max-width: 750upx; + overflow: hidden; +} + +.tower-swiper .tower-item { + position: absolute; + width: 300upx; + height: 380upx; + top: 0; + bottom: 0; + left: 50%; + margin: auto; + transition: all 0.2s ease-in 0s; + opacity: 1; +} + +.tower-swiper .tower-item.none { + opacity: 0; +} + +.tower-swiper .tower-item .swiper-item { + width: 100%; + height: 100%; + border-radius: 6upx; + overflow: hidden; +} + +/* ================== + 步骤条 + ==================== */ + +.cu-steps { + display: flex; +} + +scroll-view.cu-steps { + display: block; + white-space: nowrap; +} + +scroll-view.cu-steps .cu-item { + display: inline-block; +} + +.cu-steps .cu-item { + flex: 1; + text-align: center; + position: relative; + min-width: 100upx; +} + +.cu-steps .cu-item:not([class*="text-"]) { + color: #8799a3; +} + +.cu-steps .cu-item [class*="cuIcon-"], +.cu-steps .cu-item .num { + display: block; + font-size: 40upx; + line-height: 80upx; +} + +.cu-steps .cu-item::before, +.cu-steps .cu-item::after, +.cu-steps.steps-arrow .cu-item::before, +.cu-steps.steps-arrow .cu-item::after { + content: ""; + display: block; + position: absolute; + height: 0px; + width: calc(100% - 80upx); + border-bottom: 1px solid #ccc; + left: calc(0px - (100% - 80upx) / 2); + top: 40upx; + z-index: 0; +} + +.cu-steps.steps-arrow .cu-item::before, +.cu-steps.steps-arrow .cu-item::after { + content: "\e6a3"; + font-family: 'cuIcon'; + height: 30upx; + border-bottom-width: 0px; + line-height: 30upx; + top: 0; + bottom: 0; + margin: auto; + color: #ccc; +} + +.cu-steps.steps-bottom .cu-item::before, +.cu-steps.steps-bottom .cu-item::after { + bottom: 40upx; + top: initial; +} + +.cu-steps .cu-item::after { + border-bottom: 1px solid currentColor; + width: 0px; + transition: all 0.3s ease-in-out 0s; +} + +.cu-steps .cu-item[class*="text-"]::after { + width: calc(100% - 80upx); + color: currentColor; +} + +.cu-steps .cu-item:first-child::before, +.cu-steps .cu-item:first-child::after { + display: none; +} + +.cu-steps .cu-item .num { + width: 40upx; + height: 40upx; + border-radius: 50%; + line-height: 40upx; + margin: 20upx auto; + font-size: 24upx; + border: 1px solid currentColor; + position: relative; + overflow: hidden; +} + +.cu-steps .cu-item[class*="text-"] .num { + background-color: currentColor; +} + +.cu-steps .cu-item .num::before, +.cu-steps .cu-item .num::after { + content: attr(data-index); + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + transition: all 0.3s ease-in-out 0s; + transform: translateY(0upx); +} + +.cu-steps .cu-item[class*="text-"] .num::before { + transform: translateY(-40upx); + color: #ffffff; +} + +.cu-steps .cu-item .num::after { + transform: translateY(40upx); + color: #ffffff; + transition: all 0.3s ease-in-out 0s; +} + +.cu-steps .cu-item[class*="text-"] .num::after { + content: "\e645"; + font-family: 'cuIcon'; + color: #ffffff; + transform: translateY(0upx); +} + +.cu-steps .cu-item[class*="text-"] .num.err::after { + content: "\e646"; +} + +/* ================== + 布局 + ==================== */ + +/* -- flex弹性布局 -- */ + +.flex { + display: flex; +} + +.basis-xs { + flex-basis: 20%; +} + +.basis-sm { + flex-basis: 40%; +} + +.basis-df { + flex-basis: 50%; +} + +.basis-lg { + flex-basis: 60%; +} + +.basis-xl { + flex-basis: 80%; +} + +.flex-sub { + flex: 1; +} + +.flex-twice { + flex: 2; +} + +.flex-treble { + flex: 3; +} + +.flex-direction { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.align-start { + align-items: flex-start; +} + +.align-end { + align-items: flex-end; +} + +.align-center { + align-items: center; +} + +.align-stretch { + align-items: stretch; +} + +.self-start { + align-self: flex-start; +} + +.self-center { + align-self: flex-center; +} + +.self-end { + align-self: flex-end; +} + +.self-stretch { + align-self: stretch; +} + +.align-stretch { + align-items: stretch; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-around { + justify-content: space-around; +} + +/* grid布局 */ + +.grid { + display: flex; + flex-wrap: wrap; +} + +.grid.grid-square { + overflow: hidden; +} + +.grid.grid-square .cu-tag { + position: absolute; + right: 0; + top: 0; + border-bottom-left-radius: 6upx; + padding: 6upx 12upx; + height: auto; + background-color: rgba(0, 0, 0, 0.5); +} + +.grid.grid-square>view>text[class*="cuIcon-"] { + font-size: 52upx; + position: absolute; + color: #8799a3; + margin: auto; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.grid.grid-square>view { + margin-right: 20upx; + margin-bottom: 20upx; + border-radius: 6upx; + position: relative; + overflow: hidden; +} +.grid.grid-square>view.bg-img image { + width: 100%; + height: 100%; + position: absolute; +} +.grid.col-1.grid-square>view { + padding-bottom: 100%; + height: 0; + margin-right: 0; +} + +.grid.col-2.grid-square>view { + padding-bottom: calc((100% - 20upx)/2); + height: 0; + width: calc((100% - 20upx)/2); +} + +.grid.col-3.grid-square>view { + padding-bottom: calc((100% - 40upx)/3); + height: 0; + width: calc((100% - 40upx)/3); +} + +.grid.col-4.grid-square>view { + padding-bottom: calc((100% - 60upx)/4); + height: 0; + width: calc((100% - 60upx)/4); +} + +.grid.col-5.grid-square>view { + padding-bottom: calc((100% - 80upx)/5); + height: 0; + width: calc((100% - 80upx)/5); +} + +.grid.col-2.grid-square>view:nth-child(2n), +.grid.col-3.grid-square>view:nth-child(3n), +.grid.col-4.grid-square>view:nth-child(4n), +.grid.col-5.grid-square>view:nth-child(5n) { + margin-right: 0; +} + +.grid.col-1>view { + width: 100%; +} + +.grid.col-2>view { + width: 50%; +} + +.grid.col-3>view { + width: 33.33%; +} + +.grid.col-4>view { + width: 25%; +} + +.grid.col-5>view { + width: 20%; +} + +/* -- 内外边距 -- */ + +.margin-0 { + margin: 0; +} + +.margin-xs { + margin: 10upx; +} + +.margin-sm { + margin: 20upx; +} + +.margin { + margin: 30upx; +} + +.margin-lg { + margin: 40upx; +} + +.margin-xl { + margin: 50upx; +} + +.margin-top-xs { + margin-top: 10upx; +} + +.margin-top-sm { + margin-top: 20upx; +} + +.margin-top { + margin-top: 30upx; +} + +.margin-top-lg { + margin-top: 40upx; +} + +.margin-top-xl { + margin-top: 50upx; +} + +.margin-right-xs { + margin-right: 10upx; +} + +.margin-right-sm { + margin-right: 20upx; +} + +.margin-right { + margin-right: 30upx; +} + +.margin-right-lg { + margin-right: 40upx; +} + +.margin-right-xl { + margin-right: 50upx; +} + +.margin-bottom-xs { + margin-bottom: 10upx; +} + +.margin-bottom-sm { + margin-bottom: 20upx; +} + +.margin-bottom { + margin-bottom: 30upx; +} + +.margin-bottom-lg { + margin-bottom: 40upx; +} + +.margin-bottom-xl { + margin-bottom: 50upx; +} + +.margin-left-xs { + margin-left: 10upx; +} + +.margin-left-sm { + margin-left: 20upx; +} + +.margin-left { + margin-left: 30upx; +} + +.margin-left-lg { + margin-left: 40upx; +} + +.margin-left-xl { + margin-left: 50upx; +} + +.margin-lr-xs { + margin-left: 10upx; + margin-right: 10upx; +} + +.margin-lr-sm { + margin-left: 20upx; + margin-right: 20upx; +} + +.margin-lr { + margin-left: 30upx; + margin-right: 30upx; +} + +.margin-lr-lg { + margin-left: 40upx; + margin-right: 40upx; +} + +.margin-lr-xl { + margin-left: 50upx; + margin-right: 50upx; +} + +.margin-tb-xs { + margin-top: 10upx; + margin-bottom: 10upx; +} + +.margin-tb-sm { + margin-top: 20upx; + margin-bottom: 20upx; +} + +.margin-tb { + margin-top: 30upx; + margin-bottom: 30upx; +} + +.margin-tb-lg { + margin-top: 40upx; + margin-bottom: 40upx; +} + +.margin-tb-xl { + margin-top: 50upx; + margin-bottom: 50upx; +} + +.padding-0 { + padding: 0; +} + +.padding-xs { + padding: 10upx; +} + +.padding-sm { + padding: 20upx; +} + +.padding { + padding: 30upx; +} + +.padding-lg { + padding: 40upx; +} + +.padding-xl { + padding: 50upx; +} + +.padding-top-xs { + padding-top: 10upx; +} + +.padding-top-sm { + padding-top: 20upx; +} + +.padding-top { + padding-top: 30upx; +} + +.padding-top-lg { + padding-top: 40upx; +} + +.padding-top-xl { + padding-top: 50upx; +} + +.padding-right-xs { + padding-right: 10upx; +} + +.padding-right-sm { + padding-right: 20upx; +} + +.padding-right { + padding-right: 30upx; +} + +.padding-right-lg { + padding-right: 40upx; +} + +.padding-right-xl { + padding-right: 50upx; +} + +.padding-bottom-xs { + padding-bottom: 10upx; +} + +.padding-bottom-sm { + padding-bottom: 20upx; +} + +.padding-bottom { + padding-bottom: 30upx; +} + +.padding-bottom-lg { + padding-bottom: 40upx; +} + +.padding-bottom-xl { + padding-bottom: 50upx; +} + +.padding-left-xs { + padding-left: 10upx; +} + +.padding-left-sm { + padding-left: 20upx; +} + +.padding-left { + padding-left: 30upx; +} + +.padding-left-lg { + padding-left: 40upx; +} + +.padding-left-xl { + padding-left: 50upx; +} + +.padding-lr-xs { + padding-left: 10upx; + padding-right: 10upx; +} + +.padding-lr-sm { + padding-left: 20upx; + padding-right: 20upx; +} + +.padding-lr { + padding-left: 30upx; + padding-right: 30upx; +} + +.padding-lr-lg { + padding-left: 40upx; + padding-right: 40upx; +} + +.padding-lr-xl { + padding-left: 50upx; + padding-right: 50upx; +} + +.padding-tb-xs { + padding-top: 10upx; + padding-bottom: 10upx; +} + +.padding-tb-sm { + padding-top: 20upx; + padding-bottom: 20upx; +} + +.padding-tb { + padding-top: 30upx; + padding-bottom: 30upx; +} + +.padding-tb-lg { + padding-top: 40upx; + padding-bottom: 40upx; +} + +.padding-tb-xl { + padding-top: 50upx; + padding-bottom: 50upx; +} + +/* -- 浮动 -- */ + +.cf::after, +.cf::before { + content: " "; + display: table; +} + +.cf::after { + clear: both; +} + +.fl { + float: left; +} + +.fr { + float: right; +} + +/* ================== + 背景 + ==================== */ + +.line-red::after, +.lines-red::after { + border-color: #e54d42; +} + +.line-orange::after, +.lines-orange::after { + border-color: #f37b1d; +} + +.line-yellow::after, +.lines-yellow::after { + border-color: #fbbd08; +} + +.line-olive::after, +.lines-olive::after { + border-color: #8dc63f; +} + +.line-green::after, +.lines-green::after { + border-color: #39b54a; +} + +.line-cyan::after, +.lines-cyan::after { + border-color: #1cbbb4; +} + +.line-blue::after, +.lines-blue::after { + border-color: #0081ff; +} + +.line-purple::after, +.lines-purple::after { + border-color: #6739b6; +} + +.line-mauve::after, +.lines-mauve::after { + border-color: #9c26b0; +} + +.line-pink::after, +.lines-pink::after { + border-color: #e03997; +} + +.line-brown::after, +.lines-brown::after { + border-color: #a5673f; +} + +.line-grey::after, +.lines-grey::after { + border-color: #8799a3; +} + +.line-gray::after, +.lines-gray::after { + border-color: #aaaaaa; +} + +.line-black::after, +.lines-black::after { + border-color: #333333; +} + +.line-white::after, +.lines-white::after { + border-color: #ffffff; +} + +.bg-red { + background-color: #e54d42; + color: #ffffff; +} + +.bg-orange { + background-color: #f37b1d; + color: #ffffff; +} + +.bg-yellow { + background-color: #fbbd08; + color: #333333; +} + +.bg-olive { + background-color: #8dc63f; + color: #ffffff; +} + +.bg-green { + background-color: #39b54a; + color: #ffffff; +} + +.bg-cyan { + background-color: #1cbbb4; + color: #ffffff; +} + +.bg-blue { + background-color: #0081ff; + color: #ffffff; +} + +.bg-purple { + background-color: #6739b6; + color: #ffffff; +} + +.bg-mauve { + background-color: #9c26b0; + color: #ffffff; +} + +.bg-pink { + background-color: #e03997; + color: #ffffff; +} + +.bg-brown { + background-color: #a5673f; + color: #ffffff; +} + +.bg-grey { + background-color: #8799a3; + color: #ffffff; +} + +.bg-gray { + background-color: #f0f0f0; + color: #333333; +} + +.bg-black { + background-color: #333333; + color: #ffffff; +} + +.bg-white { + background-color: #ffffff; + color: #666666; +} + +.bg-shadeTop { + background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.01)); + color: #ffffff; +} + +.bg-shadeBottom { + background-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 1)); + color: #ffffff; +} + +.bg-red.light { + color: #e54d42; + background-color: #fadbd9; +} + +.bg-orange.light { + color: #f37b1d; + background-color: #fde6d2; +} + +.bg-yellow.light { + color: #fbbd08; + background-color: #fef2ced2; +} + +.bg-olive.light { + color: #8dc63f; + background-color: #e8f4d9; +} + +.bg-green.light { + color: #39b54a; + background-color: #d7f0dbff; +} + +.bg-cyan.light { + color: #1cbbb4; + background-color: #d2f1f0; +} + +.bg-blue.light { + color: #0081ff; + background-color: #cce6ff; +} + +.bg-purple.light { + color: #6739b6; + background-color: #e1d7f0; +} + +.bg-mauve.light { + color: #9c26b0; + background-color: #ebd4ef; +} + +.bg-pink.light { + color: #e03997; + background-color: #f9d7ea; +} + +.bg-brown.light { + color: #a5673f; + background-color: #ede1d9; +} + +.bg-grey.light { + color: #8799a3; + background-color: #e7ebed; +} + +.bg-gradual-red { + background-image: linear-gradient(45deg, #f43f3b, #ec008c); + color: #ffffff; +} + +.bg-gradual-orange { + background-image: linear-gradient(45deg, #ff9700, #ed1c24); + color: #ffffff; +} + +.bg-gradual-green { + background-image: linear-gradient(45deg, #39b54a, #8dc63f); + color: #ffffff; +} + +.bg-gradual-purple { + background-image: linear-gradient(45deg, #9000ff, #5e00ff); + color: #ffffff; +} + +.bg-gradual-pink { + background-image: linear-gradient(45deg, #ec008c, #6739b6); + color: #ffffff; +} + +.bg-gradual-blue { + background-image: linear-gradient(45deg, #0081ff, #1cbbb4); + color: #ffffff; +} + +.shadow[class*="-red"] { + box-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2); +} + +.shadow[class*="-orange"] { + box-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2); +} + +.shadow[class*="-yellow"] { + box-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2); +} + +.shadow[class*="-olive"] { + box-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2); +} + +.shadow[class*="-green"] { + box-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2); +} + +.shadow[class*="-cyan"] { + box-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2); +} + +.shadow[class*="-blue"] { + box-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2); +} + +.shadow[class*="-purple"] { + box-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2); +} + +.shadow[class*="-mauve"] { + box-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2); +} + +.shadow[class*="-pink"] { + box-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2); +} + +.shadow[class*="-brown"] { + box-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2); +} + +.shadow[class*="-grey"] { + box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.shadow[class*="-gray"] { + box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.shadow[class*="-black"] { + box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2); +} + +.shadow[class*="-white"] { + box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2); +} + +.text-shadow[class*="-red"] { + text-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2); +} + +.text-shadow[class*="-orange"] { + text-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2); +} + +.text-shadow[class*="-yellow"] { + text-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2); +} + +.text-shadow[class*="-olive"] { + text-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2); +} + +.text-shadow[class*="-green"] { + text-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2); +} + +.text-shadow[class*="-cyan"] { + text-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2); +} + +.text-shadow[class*="-blue"] { + text-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2); +} + +.text-shadow[class*="-purple"] { + text-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2); +} + +.text-shadow[class*="-mauve"] { + text-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2); +} + +.text-shadow[class*="-pink"] { + text-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2); +} + +.text-shadow[class*="-brown"] { + text-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2); +} + +.text-shadow[class*="-grey"] { + text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.text-shadow[class*="-gray"] { + text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.text-shadow[class*="-black"] { + text-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2); +} + +.bg-img { + background-size: cover; + background-position: center; + background-repeat: no-repeat; +} + +.bg-mask { + background-color: #333333; + position: relative; +} + +.bg-mask::after { + content: ""; + border-radius: inherit; + width: 100%; + height: 100%; + display: block; + background-color: rgba(0, 0, 0, 0.4); + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; +} + +.bg-mask view, +.bg-mask cover-view { + z-index: 5; + position: relative; +} + +.bg-video { + position: relative; +} + +.bg-video video { + display: block; + height: 100%; + width: 100%; + -o-object-fit: cover; + object-fit: cover; + position: absolute; + top: 0; + z-index: 0; + pointer-events: none; +} + +/* ================== + 文本 + ==================== */ + +.text-xs { + font-size: 20upx; +} + +.text-sm { + font-size: 24upx; +} + +.text-df { + font-size: 28upx; +} + +.text-lg { + font-size: 32upx; +} + +.text-xl { + font-size: 36upx; +} + +.text-xxl { + font-size: 44upx; +} + +.text-sl { + font-size: 80upx; +} + +.text-xsl { + font-size: 120upx; +} + +.text-Abc { + text-transform: Capitalize; +} + +.text-ABC { + text-transform: Uppercase; +} + +.text-abc { + text-transform: Lowercase; +} + +.text-price::before { + content: "¥"; + font-size: 80%; + margin-right: 4upx; +} + +.text-cut { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.text-bold { + font-weight: bold; +} + +.text-center { + text-align: center; +} + +.text-content { + line-height: 1.6; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-red, +.line-red, +.lines-red { + color: #e54d42; +} + +.text-orange, +.line-orange, +.lines-orange { + color: #f37b1d; +} + +.text-yellow, +.line-yellow, +.lines-yellow { + color: #fbbd08; +} + +.text-olive, +.line-olive, +.lines-olive { + color: #8dc63f; +} + +.text-green, +.line-green, +.lines-green { + color: #39b54a; +} + +.text-cyan, +.line-cyan, +.lines-cyan { + color: #1cbbb4; +} + +.text-blue, +.line-blue, +.lines-blue { + color: #0081ff; +} + +.text-purple, +.line-purple, +.lines-purple { + color: #6739b6; +} + +.text-mauve, +.line-mauve, +.lines-mauve { + color: #9c26b0; +} + +.text-pink, +.line-pink, +.lines-pink { + color: #e03997; +} + +.text-brown, +.line-brown, +.lines-brown { + color: #a5673f; +} + +.text-grey, +.line-grey, +.lines-grey { + color: #8799a3; +} + +.text-gray, +.line-gray, +.lines-gray { + color: #aaaaaa; +} + +.text-black, +.line-black, +.lines-black { + color: #333333; +} + +.text-white, +.line-white, +.lines-white { + color: #ffffff; +} diff --git a/static/css/reset.css b/static/css/reset.css new file mode 100644 index 0000000..4e865ad --- /dev/null +++ b/static/css/reset.css @@ -0,0 +1,342 @@ +.fr { + float: right; +} + +.fl { + float: left; +} + +/*文字单行溢出省略号 + Name: style_text-overflow + Example: class="text-overflow" +*/ +.text-overflow{overflow:hidden !important;text-overflow:ellipsis;white-space:nowrap !important} +/*线条 + Name: style_line + Example: class="line" +*/ +/* .line{font-size: 0rpx; line-height: 0rpx; border-top: solid 2rpx #eee; float: none} */ +/*外边距 + Name: style_margin + Example: class="mt-5|mt-10..." + Explain: .mt表示上边距|.mb表示下边距|.ml表示左边距|.mr表示右边距 +*/ +.m-5{margin:10rpx}.m-10{margin:20rpx}.m-15{margin:30rpx}.m-20{margin:40rpx}.m-25{margin:50rpx}.m-30{margin:60rpx}.m-35{margin:70rpx}.m-40{margin:80rpx}.m-50{margin:100rpx} +.mt-5{margin-top:10rpx}.mt-10{margin-top:20rpx}.mt-15{margin-top:30rpx}.mt-20{margin-top:40rpx}.mt-25{margin-top:50rpx}.mt-30{margin-top:60rpx}.mt-35{margin-top:70rpx}.mt-40{margin-top:80rpx}.mt-50{margin-top:100rpx} +.mb-5{margin-bottom:10rpx}.mb-10{margin-bottom:20rpx}.mb-15{margin-bottom:30rpx}.mb-20{margin-bottom:40rpx}.mb-30{margin-bottom:60rpx}.mb-40{margin-bottom:80rpx}.mb-50{margin-bottom:100rpx} +.ml-5{margin-left:10rpx}.ml-10{margin-left:20rpx}.ml-15{margin-left:30rpx}.ml-20{margin-left:40rpx}.ml-30{margin-left:60rpx}.ml-40{margin-left:80rpx}.ml-50{margin-left:100rpx} +.mr-5{margin-right:10rpx}.mr-10{margin-right:20rpx}.mr-15{margin-right:30rpx}.mr-20{margin-right:40rpx}.mr-30{margin-right:60rpx}.mr-40{margin-right:80rpx}.mr-50{margin-right:100rpx} +/*内填充 + Name: style_padding + Example: class="pt-5|pt-10|……" + Explain: .pt表示上填充|.pb表示下填充|.pl表示左填充|.pr表示右填充 +*/ +.pt-5{padding-top:10rpx}.pt-10{padding-top:20rpx}.pt-15{padding-top:30rpx}.pt-20{padding-top:40rpx}.pt-30{padding-top:60rpx}.pt-40{padding-top:80rpx} +.pb-5{padding-bottom:10rpx}.pb-10{padding-bottom:20rpx}.pb-15{padding-bottom:30rpx}.pb-20{padding-bottom:40rpx}.pb-30{padding-bottom:60rpx}.pb-40{padding-bottom:80rpx} +.pl-5{padding-left:10rpx}.pl-10{padding-left:20rpx}.pl-15{padding-left:30rpx}.pl-20{padding-left:40rpx}.pl-30{padding-left:60rpx}.pl-40{padding-left:80rpx} +.pr-5{padding-right:10rpx}.pr-10{padding-right:20rpx}.pr-15{padding-right:30rpx}.pr-20{padding-right:40rpx}.pr-30{padding-right:60rpx}.pr-40{padding-right:80rpx} +.pd-5{padding:10rpx}.pd-10{padding:20rpx}.pd-15{padding:30rpx}.pd-20{padding:40rpx}.pd-30{padding:60rpx}.pd-40{padding:80rpx} + +/* 边框,css3圆角 + Name: style-border + Example: class="bk_gray radius" + Explain: .bk_gray 边框|radius 圆角|round 椭圆 | circle 圆形 +*/ +.radius-2{border-radius:4rpx}.radius-4{border-radius:8rpx}.radius-6{ border-radius:12rpx}.radius-8{ border-radius:16rpx}.radius-10{ border-radius:20rpx}.radius-12{ border-radius:24rpx}.radius-14{ border-radius:28rpx}.radius-16{ border-radius:32rpx}.radius-18{ border-radius:36rpx}.radius-20{ border-radius:40rpx}.radius-round{border-radius:50%; overflow:hidden} + +/*css3阴影 + Name: style_shadow + Example: class="box_shadow|text-shadow" + Explain: box_shadow 块级元素阴影,全局样式,可用在表格,文本框,文本域,div等块级元素上。 + text-shadow 文字阴影 +*/ +.box-shadow{-webkit-box-shadow:0 4rpx 8rpx rgba(0,0,0,0.1);box-shadow:0 4rpx 8rpx rgba(0,0,0,0.1)} +.text-shadow{-webkit-text-shadow:0 0 4rpx rgba(0,0,0,0.2);text-shadow:0 0 4rpx rgba(0,0,0,0.2)} +/*行内分割竖线 + Name: style_pipe + Example: | +*/ +.pipe{margin:0 10rpx;color:#CCC;font-size:20rpx!important} +/*文字尺寸 + Name: style_font-size + Example: class="f-12|f-14|f-16|f-18|f-20|f-24|f-26|f-28|f-30" + Explain: 12rpx字体|14rpx字体|16rpx字体|18rpx字体|20rpx字体|24rpx字体|26rpx字体|28rpx字体|30rpx字体 +*/ +.f-10{font-size:20rpx}.f-11{font-size:22rpx}.f-12{font-size:24rpx}.f-13{font-size:26rpx}.f-14{font-size:28rpx}.f-16{font-size:32rpx}.f-18{font-size:36rpx}.f-20{font-size:40rpx}.f-24{font-size:48rpx}.f-26{font-size:52rpx}.f-28{font-size:56rpx}.f-30{font-size:60rpx}.f-32{font-size:64rpx}.f-36{font-size:72rpx}.f-40{font-size:80rpx} + +/*3.1.14 文字行距 + Name: mod_line-height + Example: class="lh-16|lh-18|lh-20|lh-22|lh-24|lh-26|lh-28|lh-30" + Explain: 16rpx行高|18rpx行高|20rpx行高|22rpx行高|24rpx行高|26rpx行高|30rpx行高 +*/ +.lh-16{line-height:32rpx}.lh-18{line-height:36rpx}.lh-20{line-height:40rpx}.lh-22{line-height:44rpx}.lh-24{line-height:48rpx}.lh-26{line-height:52rpx}.lh-28{line-height:56rpx}.lh-30{line-height:60rpx}.lh-10x{line-height:1.0}.lh-12x{line-height:1.2}.lh-15x{line-height:1.5}.lh-18x{line-height:1.8}.lh-20x{line-height:2.0}.lh-30x{line-height:3.0} + +/*3.1.15 文字颜色 + Name: style_color + Example: class="c-primary|c-sub|c-success|c-danger|c-warning|c-333|c-666|c-999|c-red|c-green|c-blue|c-white|c-black|c-orange" + Explain: 主要颜色|次主色|强调色—成功|强调色—危险|强调色—警告色|强调色—错误色|次主色—浅黑|辅助色—灰色|标准色—红色|标准色—绿色|标准色—蓝色|标准色—白色|标准色—黑色|标准色—橙色 +*/ + +/*主要颜色*/ +.c-primary,.c-primary a,a.c-primary{color:#409EFF} +.c-primary a:hover,a.c-primary:hover{ color:#409EFF} + +/*次主色*/ +.c-secondary,.c-secondary a,a.c-secondary{color:#175CFF} +.c-secondary a:hover,a.c-secondary:hover{ color:#175CFF} + +/*强调色—成功*/ +.c-success,.c-success a,a.c-success{color:#67C23A} +.c-success a:hover,a.c-success:hover{ color:#67C23A} + +/*强调色—危险*/ +.c-danger,.c-danger a,a.c-danger{color:#F56C6C} +.c-danger a:hover,a.c-danger:hover{ color:#F56C6C} + +/*强调色—警告*/ +.c-warning,.c-warning a,a.c-warning{color:#FFAA00} +.c-warning a:hover,a.c-warning:hover{ color:#FFAA00} + + +/*辅助色—浅黑*/ +.c-333,.c-333 a,a.c-333{color:#252438} +.c-333 a:hover,a.c-333:hover{ color:#252438} + +/*辅助色—灰色*/ +.c-666,.c-666 a,a.c-666{color:#606066} +.c-666 a:hover,a.c-666:hover{ color:#606066} +.c-999,.c-999 a,a.c-999{color:#909199} +.c-999 a:hover,a.c-999:hover{color:#909199} + +.c-remark,.c-remark a,a.c-remark{color:#C0C2CC} +.c-remark a:hover,a.c-remark:hover{color:#C0C2CC} + +/*标准色—红色*/ +.c-red,.c-red a,a.c-red{color:red} +.c-red a:hover,a.c-red:hover{ color:red} +/*标准色—绿色*/ +.c-green,.c-green a,a.c-green{color:green} +.c-red a:hover,a.c-red:hover{color:green} +/*标准色—蓝色*/ +.c-blue,.c-blue a,a.c-blue{color:blue} +.c-blue a:hover,a.c-blue:hover{color:blue} +/*标准色—白色*/ +.c-white,.c-white a,a.c-white{color: white !important;} +.c-white a:hover,a.c-white:hover{color:white} +/*标准色—黑色*/ +.c-black,.c-black a{color:black} +.c-black a:hover,a.c-black:hover{color:black} +/*标准色—橙色*/ +.c-orange,.c-orange a,a.c-orange{color:orange} +.c-orange a:hover,a.c-orange:hover{color:orange} + +/* 渐变色 */ +/* 翠柳 */ +.linear-green {background: linear-gradient(45deg, #87DE0E 0%, #64BD38 100%) !important;} +/* 麦黄 */ +.linear-yellow {background: linear-gradient(45deg, #FBB437 0%, #FDD36D 100%) !important;} +/* 靛青 */ +.linear-blue {background: linear-gradient(45deg, #3485FF 0%, #1C68FF 100%) !important;} +/* 魅红 */ +.linear-red {background: linear-gradient(45deg, #F43F3B 0%, #EC008C 100%) !important;} +/* 鎏金 */ +.linear-orange {background: linear-gradient(45deg, #Ff9700 0%, #ed1c24 100%) !important;} +/* 惑紫 */ +.linear-purple {background: linear-gradient(45deg, #9000ff 0%, #5e00ff 100%) !important;} +/* 霞彩 */ +.linear-pink {background: linear-gradient(45deg, #EC008C 0%, #6739b6 100%) !important;} + + +/* flex布局 */ + +.im-flex { + display: flex; +} + +.im-border-box { + box-sizing: border-box; +} + +.im-rows { + flex-direction: row; +} + +.im-rows-reverse{ + flex-direction: row-reverse !important; +} + +.im-columns { + flex-direction: column; +} + +.im-wrap { + flex-direction: row; + flex-wrap: wrap; +} + +.im-nowrap { + flex-direction: row; + flex-wrap: nowrap; +} + +.im-columns-reverse{ + flex-direction:column-reverse !important; +} + + +.im-space-around { + justify-content: space-around; +} + +.im-space-between { + justify-content: space-between; +} + +.im-justify-content-start { + justify-content: flex-start; +} + +.im-justify-content-center { + justify-content: center; +} + +.im-justify-content-end { + justify-content: flex-end; +} + +.im-align-items-start { + align-items: flex-start; +} + +.im-align-items-center { + align-items: center; +} + +.im-align-items-end { + align-items: flex-end; +} + +.im-align-content-start { + align-content: flex-start; +} + +.im-align-content-center { + align-content: center; +} + +.im-align-content-end { + align-content: flex-end; +} + +.im-flex1 { + flex: 1; +} + +.rotate45{transform:rotate(45deg);} +.rotate90{transform:rotate(90deg);} +.rotate135{transform:rotate(135deg);} +.rotate180{transform:rotate(180deg);} +.rotate225{transform:rotate(225deg);} +.rotate270{transform:rotate(270deg);} +.rotate315{transform:rotate(315deg);} +.rotate360{transform:rotate(360deg);} + +.online-status{ + position:absolute; + bottom:-16rpx; + right:-20rpx; + border-radius: 50%; + border:solid 7rpx #fff; + height:40rpx; + width:40rpx; + background-color: limegreen; +} +.online-status-small{ + position:absolute; + bottom:-10rpx; + right:-15rpx; + border-radius: 50%; + border:solid 4rpx #fff; + height:30rpx; + width:30rpx; + background-color: limegreen; +} + +/* 分割线 */ + .parting-line-5{ + padding:5rpx; + background: #f5f5f5; + } + .parting-line-10{ + padding:10rpx; + background: #f5f5f5; + } + .parting-line-15{ + padding:15rpx; + background: #f5f5f5; + } + .parting-line-20{ + padding:20rpx; + background: #f5f5f5; + } + /* colorUI样式重写 */ +.cu-list.menu-avatar>.cu-item:after{ + position: absolute; + top: 0; + left: 0; + box-sizing: border-box; + width: 200%; + height:1px; + border-bottom: 1px solid #eee; + border-radius: inherit; + content: " "; + transform: scale(.5); + transform-origin: 0 0; + pointer-events: none; + } + + .cu-avatar.md { + width: 72upx; + height: 72upx; + font-size: 1.5em; + } + + .cu-list>.cu-item.move-cur.first { + transform: translateX(-150upx) !important; + } + + .cu-list>.cu-item .move.first { + width: 150upx !important; + } + + .cu-list>.cu-item.move-cur.second { + transform: translateX(-300upx) !important; + } + + .cu-list>.cu-item .move.second { + width: 300upx !important; + } + + .cu-list>.cu-item.move-cur.third { + transform: translateX(-450upx) !important; + } + + .cu-list>.cu-item .move.third { + width: 450upx !important; + } + + .emoji-image{ + margin: 0 6rpx; + } + + .manage-content{ + text-align: left; + } + + .bg-main-bar{ + background-color: #f5f5f5; + } + + rich-text{ + word-break: break-all; + } \ No newline at end of file diff --git a/static/customicons.css b/static/customicons.css new file mode 100644 index 0000000..14ed5fa --- /dev/null +++ b/static/customicons.css @@ -0,0 +1,20 @@ +@font-face { + font-family: "customicons"; /* Project id 2878519 */ + src:url('/static/customicons.ttf') format('truetype'); +} + +.customicons { + font-family: "customicons" !important; +} + +.youxi:before { + content: "\e60e"; +} + +.wenjian:before { + content: "\e60f"; +} + +.zhuanfa:before { + content: "\e610"; +} diff --git a/static/customicons.ttf b/static/customicons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a3c8ab9f22d18d5d605503eda314e5d2a31fdfc0 GIT binary patch literal 2416 zcmd^A%WoS+82@H>?IgD2#K~q|hdkDH>bQB>&f0O>=25F@5|GlQX`8fENObGiPEx<* zIHl>yDoB8U!lAtvAt9k$df{KC1gT1(TA*@aKU;Z8A_c6Yj%<0Ab$%Pq=pKvad z-A@0oKRQn&-bGc{Qu=Do+{0<;!iM5&AR2xX-va&;wQns~zS&B(8f^c>xHVfy>O!2V zuzd$(TTZ`OWbJet@*^0lc|DhE{bb?+k@a&TAyX`DmiI>vrzUh9wW#VtLONPQPcgH{GfcG%HCo!>rVIv8K7)wAe(G9W~W6s*} z5MlL3;c^>AXo`e0v-20pnbpgA>V(Zx`M)vCu4i=kuX|?D<5C8Ok=0}+EcYWmqwucq z9k>tcJ$p@N7UdY3K%*@M)z9zF77#b3%z!fxHdq^cAvWrY zjm5{}(W73UQ-HKbh-#b|iyQiGC8|vcP=ZB(`A1^`pS7F$eO6f+XC1Pl#U~jwSS-Z6 zoYdm6fFb2Ts4UG+2aoy3eJ4h)WHMJqPWZ+ggv;Y`8Ne>v?K0a?dV7a@d%xnHstS*S!80>UHNq5P zcT^Cf-6E!7v@~-j7+e|8elTC7!G#HLb7P0n=yWzJ9gWT2iG@K%Yp-64j#evA{TmZG zWJPwUm;la=mS?v1K>SNwq9YWdlSr<&p0z19Zlu(!^)Mr=JSzZ7)T_mjuz=s|>kl!c zB@l~)Q)H`{IH*LH!r`TeI(%*{!Lr8Sps0GoVXsi(ZM7mhk8cX!KdH!FU9!mAbI=zO zP#q6W0#>gAiixoIV3!-P``)ng_~q*Du3#5l{`J@HiH~s`$rPj0xaF>5@3G|gDTd`t z2}&`saAq1brJKoCUtp5O z;^K01ht1M-_H0vw)#X+iuR9#q9aYKR<`5;DCw%I1?(O?_+2N4wrR4G}CnNsOmL?^| z?r41nJAO^`vqW__v>3uGEQc3DyKNq9yhk|YJmP6uSZGw-E=vQP_BpOMS9fi$j;5~R zmD%KpS-b3(?Z^BHZ8{R|>1<(-tEK86+@Y}Cr!9vT!UsEbw=A*jY1`o&ywm0}zN$9* z)x4>Q+QHOsI)0nBn^>R*ddb8hc%O+S-~kg`@aNM^Yz04QVjB(OyQ}-O!($Prh)GSD zCqQqSm{BWzW@3Sy^o5B<@ZXwP0{+Rw7E);6#8&VJCbrQEYc{c+0xUUQO6ld)s(Ni( zT~8MB=|aAI*q={jwz7KZaCq3Sq)MCXg}gcviX2jNseGz*=w|aqMk|-oYPwX&sk88x z%4Q2{u~gVdCCj0;a=Cai9OmS z&fu!b!m{+7^jYf_XqRXcdfcZoHN+IGM+T-)9_ZH9MG(} zz7$rH1y-?vT($u}Noa>?&9ExsItb%AjOS24WW<@{KiqoZ|NR#gi3v<(60?v^AJ&GW i+l8&0>&^ObYFtuIC+Gpxs*A((`E@KK=o#Msw}} literal 0 HcmV?d00001 diff --git a/static/fonts/iconfont.ttf b/static/fonts/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9a171b54bee03852bb2224972a8d19046f6b1cb9 GIT binary patch literal 10516 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 literal 0 HcmV?d00001 diff --git a/static/fonts/iconfont.woff2 b/static/fonts/iconfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..a32fcc08a1b673f4e97d73b5c2852739e010a548 GIT binary patch literal 6228 zcmV-a7^~-ZPew8T0RR9102ovN3jhEB04Wpz02l-S0RR9100000000000000000000 z0000SR0d!GhX4w_RI)VzHUcCAfdmUg00bZfgl7kXA{%caGo!-B0f10^M6&<-fIAeQ za0ThWF|jeRV(HeECSx1lBvUy7S+`EXfkJ>n37$-6OKMV6hRlDQ?asruH5%4$BEOuF{vL*Q}(*N~I{ z=gvcUp8md_`~Gk7Kq3eOZ}KMEDNP$+Ho^$QW#fjYIsJDRfxAn{B}7P^Uu-Ht*Z+%69MYV59sd8_z16q%$U++dpIp@{Ox+k;LJ&av^jG5ji08Lg{<*j= zg@QV%bkOx6plI4W(|>sTRLc{Ppf)+i_JW|QOvr1l*x- zFF$5u3Wl#RlGzyFTlN1&sn{Aaus59T5YW8=9#}9gm{0C>!@Ws8y$4 zgGNo7wP+QzX%}_q)TNtI;0Ev)o`W=zmMI6wg`yrPumLQT3gDp}fFjfapbW|dD2MVe zMFc(oR6+#+RZt;7HBszCakcl8D0VB4c0t^TqfC0f1Fd&40i~*q-WC|c`0vQLw4ge68iewTJ ziotOZkRInG%M=eNE|n_3VtA#EOfVW)PNhezY4gNIv?L0enDEF!HsYuWd!bv)I;XoE zhbEOB(}zK8EoWu9F)Na}SYk}}eiClkjRIMTMIo8LWSWGs^=wVI=bISpz?PRZ@mhOv6+oF#Ub)7dPg zne6t+B_-Tng9yu>nal${EeS&dW?f--vzo03;XlWfz|93iTd z+He3?zNd>Z)5BVO=;@F^toi z=)>DE>Gw1BVOtgA0Jczd^&`ADRIN)>+agzb*4T+an<)p_&zcGfEJ87`-LHGsm?4D1 zX^fw<$}0~^UYDJ)ml>zG0y%2lAE5KImUp&<$pL230Apc5q3iRChq%@li|vzV=b z3z)28Pux;Wq_A!RTrAeKN_4&d_5J&h#JT{IT02fu`Fp$WL_hsmRk`cj>BAX}AkmSh zx9={Jf;^gdcjE4N75n{K#7l@sA=XkJ3r?2XLw@BVsJT#nbeO~uATilsnCH4*hs26w z3*4@o^+QG?n!=`J{+I*q+PFtW1jB4MnToh5hS)x>vb^b-)bZ*Qh$uugchAfncU1=N&L zmR4cYfh^o8u#DQwXmffd%Kti<1x)F=T-uBO- z$^}{U6?x5GIxkK`@~Ri=Cmx~nK9X#Py%$O3mc?Aap;i+wE=G?x`l|98lKnTigzofB1RQ+lBvauSnEzDkb4sO8=WKzyG%W^KJCz2cqA; zy0;=B#hCSJaP?Hu?SYNpxxBA?_~Fml`kfytia5`^L<$^S!fbpQFJgcC!7q_?`M10L z_@@xiNd<(Ws-#6(Nx2nWc56B$p%1(_)2*%&&#M!Q_A`NV*JZlx6;4wliV2QcpTO*d z>uVaHpd6sYfc5dc%!X$*nnf6GZS%^Nnbqh-5{&!4fUoU{doi8Xd z_&WL`sP__MR%zQcdGVvyEa6vZ16n{_Uv0?r+#4w$m~ey{Z#)n3DLRPA5ePAvKu)i0 zO%x9k#n4x8)`G*WqTsb5PF7^)l*3JBd9%F8s zgAacWlE2a?GWagal{dzff%UrSf3!;$d!81T(mCkylJ+ci7DatANx%g=`pbFS(~;jt zPIK>DB0xK4l|2?_V%xdT$stHyA8nvjC}mPkd7CJy;QnkbaNB^Ko_{DZn7V*R*M(*S zR7@kI+~>(CQPm39+s~e`5Xv=Hs9Dax&@unAr;i^eE>MS?2rz$-H$wE+#ZH?i(zA{h z$(}@ulT@<=sWH`bo$_(sWKwIzp;Vl*5#ZAs-Oo!aX!cB=S0V)W8u!f5+Dz%xRYeh@ zOJd3>7#eWg^oG)qBqAdeqF*p#wczd6$%gh1gqv*M;@rOCO_$2Ya@n%!E-Cn&P*~wq zN>c$PuhjZUkbStjpgkM4hGEMpICZZtQM659UqIgS=DOj=XPkZGU+=co3rA1;CziVm6f5q#@msmaufgsR*(?sy0zId682Y0*BGw zPaS_MMt}K5|2tsuFOR(cmi?RsYQrgag{h7tHFpJkCz9m`D$*gT%Hv<&_WXQK`7&kP z_Nx`g^F*N-s$pj&w5lKj-C^Zt4ZMA?;EotLTMqzb03j*rBFcWAQX{AERYs=@ z95DS!Z971%pm@Vy;wf>xZSupe8Ah|Tneh|d(a~pj-4+kw{!0zn#^ry=2hQ~-IH7^@ zYM_FPUFT*W_-q6AfZ8i9l0pRh9f16f{?UU#IFt$#a%H60lh||93FH-#MSFl1YS9;Y za+!{H(R%0^x3mOz&`y|HJfZjg(Z(jhI02G2F@~uR&<%av*<5fH<5mp(WZnu0FeIt8 zv>jaJ*MMq(58FgCAEPqYF1UsS5uj86ui@Gx!UX6&POy7TZs|cDl4E-*&nY9ZQR80jj}He`FrT1A^{V%JSVD)1Gf{ES@pbt%qlB z6JS7qTo+L8Y6%1g3d3IVb^silc#VbZH96)7u@*FB6ITc~{(Zjg?QS+1HX*^T{dm$G zzytS?LF6-lOLTknO$P^;^+?tgXn4eNW%B6>Y~_rSDO`x4z9Z1#M^i ziDpuf^~69Fm=2n_n+6q~FdZ~ip})h#J~B3iIuq?K*U%X*1e!DH6AcN1gaDG6j1i!3BfUuF>ynnWu7 zmqH81$!sV*xhJJaQq+6ii)Dfb(F}k z7vbah=bPfd%Z=Kg@t!2cKd~>PAq|ZpthbaA${Ui>e@MdW- zo-WtPqV^Ofp_R-VvMFX|GJ1C{i<0Zo@nYa$@-e=CmxlKT{VrBcIvv%?F zdaOVz3W~;ysSUmC3zC!(VO7$`ja5$3wil#ro!Q}SA7{%VE20goTk)AN#MsJ6v_*if zdMMP}HYz`b5aHwy?Uh0R8nIKg0=^+M-F=VFG3U^?oe9p-^t z2u=-oUO8&dZ14QHW=qOZ_w~QKCS;o%hacv1I%D-(7A9`6bem`AHf5q~e8RmijMhMv+DWf^ zS*TZJf)Yp)J^Z}Xo*U(7YQlcgyHLNV;AZ@ndpVt3K3b2tGNzePANC>Hd+G$1$4A0f#+DzvR0M%#p&=&%8N zGoqY~e93r(;EHa-AOEQ(=2%Cv^dZi1*jfim&&Nc0h)fnD=bsX&%9i-@>z^MY1J_o* zcLdj+*a@9jWG$cA8)f6E;l=W>xhk@89<@h@jZcZo#wF{17xZ5faxawW-!I<@;l+yNN(gR8aJ=90NbV;*~^?q&mVD?8x5mt zDC5-CqsP-@+s)eIfQPZ)MNgaXJG*JqS^sfbZ)RDyWYqPG=3V_US(JJ9Iic|#!6mEZ z$A!l;H}BE+QVyu=np6jAz48!VPq^35o3akD`hChhz|hZilgaufYKfP!oYj~V*N8_D zo{x9*5g8l9?DJq-_`^N9V_<|R#%vo+CyLNI%B?Q?!r*3lUc76pi%YC){3S~+`j73- zOO*63v?uOotll}^Eq7;XN3Ql$>6tZa&PY!N<#nXS*lBG818joq*gxWC2lp8d3Y3CR zO|XLYr&{u*)KMzsTT-rvB0MSOMv_n!3!vQhW>k1Uq%0S16}H;?4vU=Ex}tmD71+88 z4+=Mn4j9xXQ^*~QizheucihyoeB*1+1dCn8RAb767ekv=Y&&c!zYiQnGP1}5K#W??-` z`>;855w`(5jy%Q|(K+l|_5O&%`*q-mIy_+$9Ny{}4|3fSlic#1>zbJN)3-j$i}h#- zI1ujCG8W)pQSPS!YX9sG8`T>^tdUC=F{_TD#VJ?HcbjmeE@9s7Jx!C|) zPuj`m7=j%?DR^AP+jDOf??}0%je+i+!pP1$D$ByI$j;8D z!*)$5$)eP*MPyxvuigQB?1o+;*G*$gCy~)6P~*O6)x)#e+Y)LuZ>3uqxz5%vk*tMj ziBUYgFh9vpz$kev$-iw{=hl;X`7c@u?fvD?a!%$8KE*64CqEgZhjpbuAQghTl3kx$ zxiBZ~CS`IiShpfI03Y4XNLUZR)b1dl0OVR9JJF3|36u~yj zRBH)GDg=HDEXWQt*#Z6mub23$#R-Yr&Pw`M8CqfeZxc$&_)2b4yz;No&Ow#`X6tNP z{=WZI9meWU;at>mc$CDD6v4ki>3%(VV{%*1c<8AC0FQn?+mo|Eb9;(HgJwX{+zS4A zT2SjvY*P0mI4DKzT8a_1rC3R?%?%w*@yg7m1j$@V(U`TMO)V? zDj%^(yTEHXWFE@CvjSS}+LXDzldNRFd9hkCgn8Gl@fP<47AsD?1c{QQAVn#Ya;cC? zsgml@!-#p9VTBz|EW!;h{0Jh9DB?(B87aHM!Nh1XaVFIW1@a`&(fRrqUivR#)qd8=6V9M7?-)e2FB7M38_ yF@f5&a#QQFNd#Vn#nm6|<;7PNmobH6fgTSjb&)M+4nkFnr4?Lkp5w-?0002er1wJr literal 0 HcmV?d00001 diff --git a/static/image/empty.png b/static/image/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..39886b60a44d93598fa425ca4e517b5d047c924b GIT binary patch literal 8661 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 J()}yq{{i|dYw-X8 literal 0 HcmV?d00001 diff --git a/static/image/invite.png b/static/image/invite.png new file mode 100644 index 0000000000000000000000000000000000000000..91b0b2e0fb56740bb27f62d803dad19ba4a64226 GIT binary patch literal 11656 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 O5Z>;TZM8Ku=KlaQHMSZ6 literal 0 HcmV?d00001 diff --git a/static/image/logo.png b/static/image/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..093d10c7a33d32008f199974d91e2a03b1961dc1 GIT binary patch literal 12683 zcmcJ0c|6qb_vm}ZzC>9QB2D&vXRMW&%F-Yr%NTo>2_fsqmdestDp@~S5<*3?4n9!| zl|9?26cLl1Ecbb<&*%Q`eck)J-+%7s)#uf`pXWU1oab!MInQ}YFf%dS$9#wxf}njE zqmx(&LV}-2h>;%rwH(~H3I1Xt7+vs(Ahy5Z{}Jg@Z2S;J_uj+8I>6fatR~*qTNdZ+ z>*OLE>`egB5TvCWOu*qUxdaG1xwv`wXp1b=H;V{+IBSbosTj)}6Hd6edl-fIxtNET zSl~l0;WeB^bajNaf;9mGZyS5TLeSC>;zl2K6ARF>CNR22U6p9rAl z=j^J9J$dR6E%2o+;vNt{(3F!43JQ`9Qj+!cbCXlh(9n>RSCms!lmQSj{#ShhaKSP@ z{zw18aMHye@8>}X@bL8!hB4xte6Iv(ivUi4Z^4`JFIpe}KVkv`lMBWX

D(;Vu0G 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 Zokhh`#L?LM@IRNp7?_-VeBANc{{Y-{KY0KE literal 0 HcmV?d00001 diff --git a/static/image/rocket.png b/static/image/rocket.png new file mode 100644 index 0000000000000000000000000000000000000000..33d6c48e175f0b7909d7247df138333a8c4a1b25 GIT binary patch literal 31432 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

KK$o2iTH2ASNC_?Q|Tr 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 literal 0 HcmV?d00001 diff --git a/static/image/tabbar/compass-active.svg b/static/image/tabbar/compass-active.svg new file mode 100644 index 0000000..663e44e --- /dev/null +++ b/static/image/tabbar/compass-active.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/tabbar/compass.svg b/static/image/tabbar/compass.svg new file mode 100644 index 0000000..b2efb28 --- /dev/null +++ b/static/image/tabbar/compass.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/tabbar/contacts-active.svg b/static/image/tabbar/contacts-active.svg new file mode 100644 index 0000000..33ffee1 --- /dev/null +++ b/static/image/tabbar/contacts-active.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/tabbar/contacts.svg b/static/image/tabbar/contacts.svg new file mode 100644 index 0000000..3cc0f4e --- /dev/null +++ b/static/image/tabbar/contacts.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/tabbar/demo.png b/static/image/tabbar/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..3f0a8dc29869888278b98ee0697645c75f864a57 GIT binary patch literal 7671 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 K=n@s{$o~iAp`0oJ literal 0 HcmV?d00001 diff --git a/static/image/tabbar/message-active.svg b/static/image/tabbar/message-active.svg new file mode 100644 index 0000000..8c4438b --- /dev/null +++ b/static/image/tabbar/message-active.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/tabbar/message.svg b/static/image/tabbar/message.svg new file mode 100644 index 0000000..eddf7e4 --- /dev/null +++ b/static/image/tabbar/message.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/tabbar/mine-active.svg b/static/image/tabbar/mine-active.svg new file mode 100644 index 0000000..56d53f0 --- /dev/null +++ b/static/image/tabbar/mine-active.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/tabbar/mine.svg b/static/image/tabbar/mine.svg new file mode 100644 index 0000000..9a212ca --- /dev/null +++ b/static/image/tabbar/mine.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/static/image/user-card-bg.jpg b/static/image/user-card-bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ab4be9dd9d741a37bf307020289e6bf3eb5e6c21 GIT binary patch literal 29335 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 L7^I`&`Skw*elTRp literal 0 HcmV?d00001 diff --git a/store/index.js b/store/index.js new file mode 100644 index 0000000..94e2432 --- /dev/null +++ b/store/index.js @@ -0,0 +1,5 @@ +import { createPinia } from 'pinia' + +const store = createPinia() + +export default store diff --git a/store/login.js b/store/login.js new file mode 100644 index 0000000..1f54f1d --- /dev/null +++ b/store/login.js @@ -0,0 +1,42 @@ +import { defineStore } from 'pinia' +import LoginApi from '@/api/login.js' +export const useloginStore = defineStore({ + id: 'login', // id必填,且需要唯一 + state: () => { + return { + userInfo:uni.getStorageSync('userInfo') ? uni.getStorageSync('userInfo') : {}, + globalConfig:uni.getStorageSync('globalConfig') ? uni.getStorageSync('globalConfig') : [], + appSetting:uni.getStorageSync('appSetting') ? uni.getStorageSync('appSetting') : [], + multiport:false + } + }, + // actions 用来修改 state + actions: { + login(userInfo) { + // 登陆后本地保存登录信息 + uni.setStorageSync('userInfo', userInfo) + this.userInfo = userInfo; + // 登陆后需要触发一次更新联系人 + uni.$emit('socketStatus',true); + + }, + logout() { + uni.removeStorageSync('userInfo'); + uni.removeStorageSync("authToken"); + this.userInfo = {}; + uni.reLaunch({ + url: "/pages/login/index" + }) + }, + getGlobalConfig(){ + LoginApi.getSystemInfo().then((res)=>{ + this.globalConfig=res.data; + uni.setStorageSync('globalConfig',res.data) + }) + }, + setAppSetting(setting){ + uni.setStorageSync('appSetting', setting) + this.appSetting = setting + } + } +}) diff --git a/store/message.js b/store/message.js new file mode 100644 index 0000000..0659f62 --- /dev/null +++ b/store/message.js @@ -0,0 +1,146 @@ +import { defineStore } from 'pinia' +import utils from '@/utils/utils.js'; +import msgApi from '@/api/message.js'; +export const useMsgStore = defineStore({ + id: 'message', // id必填,且需要唯一 + state: () => { + return { + pushSocket: '', + chatSocket: '', + instantSocket: '', + webrtc:'', + topContacts:[], + contacts: [], //所有联系人 + chatList:[], //聊天列表 + wsSendData: '', + unread: 0, + sysUnread:0, + msgAt:0, + newMessage:{}, + msgList:[], + webrtcLock:false + } + }, + // actions 用来修改 state + actions: { + catchSocketAction(data){ + this.chatSocket = data; + if (data.is_group == 2) { + this.unread += 1; + } + }, + updateUnread (data) { + this.unread = parseInt(data); + }, + //初始化联系人 + initContacts (data) { + let contacts=utils.sortContacts(data); + let topContacts=[]; + let otherContacts=[]; + let unread=0; + let msgAt=0; + let mainContacts={}; + contacts.forEach((item, index) => { + if (item.lastContent && item.is_notice==1) { + unread += item.unread; + } + if (item.is_at) { + msgAt += item.is_at; + } + if(item.lastContent && !['text','event','location','contact'].includes(item.type)){ + item.lastContent=utils.getMsgType(item.type); + } + if(item.index=='群聊'){ + item.index="#"; + } + mainContacts[item.id] =item; + if (item.is_top == 1) { + topContacts.push(item) + }else{ + otherContacts.push(item) + } + }) + this.unread=unread; + this.msgAt=msgAt; + this.contacts =topContacts.concat(otherContacts); + uni.setStorageSync('allContacts',this.contacts); + uni.setStorageSync('mainContacts',mainContacts); + }, + //更新联系人 + updateContacts (data) { + const contacts = uni.getStorageSync('allContacts'); + // 更新联系人 + contacts.forEach((item, index) => { + let contact = contacts[index]; + if (item.id == data.id) { + contacts[index] = Object.assign(contact, data); + } + }) + this.initContacts(contacts); + }, + //添加联系人 + appendContacts (data) { + // 检查是否有该联系人,有就更新,没有就增加 + const mainContacts = uni.getStorageSync('mainContacts'); + if(mainContacts[data.id]){ + return this.updateContacts(data); + } + const contacts = uni.getStorageSync('allContacts'); + contacts.push(data); + this.initContacts(contacts); + }, + //删除联系人 + deleteContacts (data) { + const contacts = JSON.parse(JSON.stringify(this.contacts)); + const newContacts = contacts.filter(obj => obj.id != data.id); + this.contacts=newContacts; + const mainContacts=uni.getStorageSync('mainContacts'); + delete mainContacts[data.id]; + uni.setStorageSync('allContacts',this.contacts); + uni.setStorageSync('mianContacts',mianContacts); + }, + // 初始化当前页面的消息列表 + initMsg(data){ + this.msgList=data; + }, + // 检查是否存在此消息,有的则跳过,没有就更新 + checkMsg(msg){ + let msgList=this.msgList; + let hasMsg=false; + msgList.forEach((item, index) => { + if (item.id==msg.id) { + hasMsg=true; + } + }) + if(!hasMsg){ + this.msgList.push(msg); + } + }, + getContact(id,message){ + if(!id){ + let contacts=uni.getStorageSync('allContacts'); + return contacts; + }else{ + let contacts=uni.getStorageSync('mainContacts'); + let contact = contacts[id]; + if(!contact && message && message.contactInfo){ + contact = message.contactInfo; + this.appendContacts(contact); + } + return contact; + } + }, + getChatList(){ + let contacts=uni.getStorageSync('allContacts'); + this.chatList =contacts.filter(obj => obj.lastContent); + return this.chatList; + }, + // 新消息推送 + appendMsg(message){ + this.newMessage=message; + }, + wsSend (data) { + this.wsSendData = data; + } + } +}) diff --git a/uni.scss b/uni.scss new file mode 100644 index 0000000..c24ca6b --- /dev/null +++ b/uni.scss @@ -0,0 +1 @@ +@import '@/uni_modules/uni-scss/variables.scss'; \ No newline at end of file diff --git a/uni_modules/mp-html/README.md b/uni_modules/mp-html/README.md new file mode 100644 index 0000000..dcfcc2c --- /dev/null +++ b/uni_modules/mp-html/README.md @@ -0,0 +1,193 @@ +## 为减小组件包的大小,默认组件包中不包含编辑、latex 公式等扩展功能,需要使用扩展功能的请参考下方的 插件扩展 栏的说明 + +## 功能介绍 +- 全端支持(含 `v3、NVUE`) +- 支持丰富的标签(包括 `table`、`video`、`svg` 等) +- 支持丰富的事件效果(自动预览图片、链接处理等) +- 支持设置占位图(加载中、出错时、预览时) +- 支持锚点跳转、长按复制等丰富功能 +- 支持大部分 *html* 实体 +- 丰富的插件(关键词搜索、内容编辑、`latex` 公式等) +- 效率高、容错性强且轻量化 + +查看 [功能介绍](https://jin-yufeng.gitee.io/mp-html/#/overview/feature) 了解更多 + +## 使用方法 +- `uni_modules` 方式 + 1. 点击右上角的 `使用 HBuilder X 导入插件` 按钮直接导入项目或点击 `下载插件 ZIP` 按钮下载插件包并解压到项目的 `uni_modules/mp-html` 目录下 + 2. 在需要使用页面的 `(n)vue` 文件中添加 + ```html + + + ``` + ```javascript + export default { + data() { + return { + html: '

Hello World!
' + } + } + } + ``` + 3. 需要更新版本时在 `HBuilder X` 中右键 `uni_modules/mp-html` 目录选择 `从插件市场更新` 即可 + +- 源码方式 + 1. 从 [github](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 或 [gitee](https://gitee.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 下载源码 + 插件市场的 **非 uni_modules 版本** 无法更新,不建议从插件市场获取 + 2. 在需要使用页面的 `(n)vue` 文件中添加 + ```html + + ``` + ```javascript + import mpHtml from '@/components/mp-html/mp-html' + export default { + // HBuilderX 2.5.5+ 可以通过 easycom 自动引入 + components: { + mpHtml + }, + data() { + return { + html: '
Hello World!
' + } + } + } + ``` + +- npm 方式 + 1. 在项目根目录下执行 + ```bash + npm install mp-html + ``` + 2. 在需要使用页面的 `(n)vue` 文件中添加 + ```html + + ``` + ```javascript + import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html' + export default { + // 不可省略 + components: { + mpHtml + }, + data() { + return { + html: '
Hello World!
' + } + } + } + ``` + 3. 需要更新版本时执行以下命令即可 + ```bash + npm update mp-html + ``` + + 使用 *cli* 方式运行的项目,通过 *npm* 方式引入时,需要在 *vue.config.js* 中配置 *transpileDependencies*,详情可见 [#330](https://github.com/jin-yufeng/mp-html/issues/330#issuecomment-913617687) + 如果在 **nvue** 中使用还要将 `dist/uni-app/static` 目录下的内容拷贝到项目的 `static` 目录下,否则无法运行 + +查看 [快速开始](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart) 了解更多 + +## 组件属性 + +| 属性 | 类型 | 默认值 | 说明 | +|:---:|:---:|:---:|---| +| container-style | String | | 容器的样式([2.1.0+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v210)) | +| content | String | | 用于渲染的 html 字符串 | +| copy-link | Boolean | true | 是否允许外部链接被点击时自动复制 | +| domain | String | | 主域名(用于链接拼接) | +| error-img | String | | 图片出错时的占位图链接 | +| lazy-load | Boolean | false | 是否开启图片懒加载 | +| loading-img | String | | 图片加载过程中的占位图链接 | +| pause-video | Boolean | true | 是否在播放一个视频时自动暂停其他视频 | +| preview-img | Boolean | true | 是否允许图片被点击时自动预览 | +| scroll-table | Boolean | false | 是否给每个表格添加一个滚动层使其能单独横向滚动 | +| selectable | Boolean | false | 是否开启文本长按复制 | +| set-title | Boolean | true | 是否将 title 标签的内容设置到页面标题 | +| show-img-menu | Boolean | true | 是否允许图片被长按时显示菜单 | +| tag-style | Object | | 设置标签的默认样式 | +| use-anchor | Boolean | false | 是否使用锚点链接 | + +查看 [属性](https://jin-yufeng.gitee.io/mp-html/#/basic/prop) 了解更多 + +## 组件事件 + +| 名称 | 触发时机 | +|:---:|---| +| load | dom 树加载完毕时 | +| ready | 图片加载完毕时 | +| error | 发生渲染错误时 | +| imgtap | 图片被点击时 | +| linktap | 链接被点击时 | +| play | 音视频播放时 | + +查看 [事件](https://jin-yufeng.gitee.io/mp-html/#/basic/event) 了解更多 + +## api +组件实例上提供了一些 `api` 方法可供调用 + +| 名称 | 作用 | +|:---:|---| +| in | 将锚点跳转的范围限定在一个 scroll-view 内 | +| navigateTo | 锚点跳转 | +| getText | 获取文本内容 | +| getRect | 获取富文本内容的位置和大小 | +| setContent | 设置富文本内容 | +| imgList | 获取所有图片的数组 | +| pauseMedia | 暂停播放音视频([2.2.2+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v222)) | +| setPlaybackRate | 设置音视频播放速率([2.4.0+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v240)) | + +查看 [api](https://jin-yufeng.gitee.io/mp-html/#/advanced/api) 了解更多 + +## 插件扩展 +除基本功能外,本组件还提供了丰富的扩展,可按照需要选用 + +| 名称 | 作用 | +|:---:|---| +| audio | 音乐播放器 | +| editable | 富文本 **编辑**([示例项目](https://mp-html.oss-cn-hangzhou.aliyuncs.com/editable.zip)) | +| emoji | 解析 emoji | +| highlight | 代码块高亮显示 | +| markdown | 渲染 markdown | +| search | 关键词搜索 | +| style | 匹配 style 标签中的样式 | +| txv-video | 使用腾讯视频 | +| img-cache | 图片缓存 by [@PentaTea](https://github.com/PentaTea) | +| latex | 渲染 latex 公式 by [@Zeng-J](https://github.com/Zeng-J) | + +从插件市场导入的包中 **不含有** 扩展插件,使用插件需通过微信小程序 `富文本插件` 获取或参考以下方法进行打包: +1. 获取完整组件包 + ```bash + npm install mp-html + ``` +2. 编辑 `tools/config.js` 中的 `plugins` 项,选择需要的插件 +3. 生成新的组件包 + 在 `node_modules/mp-html` 目录下执行 + ```bash + npm install + npm run build:uni-app + ``` +4. 拷贝 `dist/uni-app` 中的内容到项目根目录 + +查看 [插件](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin) 了解更多 + +## 关于 nvue +`nvue` 使用原生渲染,不支持部分 `css` 样式,为实现和 `html` 相同的效果,组件内部通过 `web-view` 进行渲染,性能上差于原生,根据 `weex` 官方建议,`web` 标签仅应用在非常规的降级场景。因此,如果通过原生的方式(如 `richtext`)能够满足需要,则不建议使用本组件,如果有较多的富文本内容,则可以直接使用 `vue` 页面 +由于渲染方式与其他端不同,有以下限制: +1. 不支持 `lazy-load` 属性 +2. 视频不支持全屏播放 +3. 如果在 `flex-direction: row` 的容器中使用,需要给组件设置宽度或设置 `flex: 1` 占满剩余宽度 + +纯 `nvue` 模式下,[此问题](https://ask.dcloud.net.cn/question/119678) 修复前,不支持通过 `uni_modules` 引入,需要本地引入(将 [dist/uni-app](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 中的内容拷贝到项目根目录下) + +## 立即体验 +![富文本插件](https://mp-html.oss-cn-hangzhou.aliyuncs.com/qrcode.jpg) + +## 问题反馈 +遇到问题时,请先查阅 [常见问题](https://jin-yufeng.gitee.io/mp-html/#/question/faq) 和 [issue](https://github.com/jin-yufeng/mp-html/issues) 中是否已有相同的问题 +可通过 [issue](https://github.com/jin-yufeng/mp-html/issues/new/choose) 、插件问答或发送邮件到 [mp_html@126.com](mailto:mp_html@126.com) 提问,不建议在评论区提问(不方便回复) +提问请严格按照 [issue 模板](https://github.com/jin-yufeng/mp-html/issues/new/choose) ,描述清楚使用环境、`html` 内容或可复现的 `demo` 项目以及复现方式,对于 **描述不清**、**无法复现** 或重复的问题将不予回复 + +欢迎加入 `QQ` 交流群: +群1(已满):`699734691` +群2:`778239129` + +查看 [问题反馈](https://jin-yufeng.gitee.io/mp-html/#/question/feedback) 了解更多 diff --git a/uni_modules/mp-html/changelog.md b/uni_modules/mp-html/changelog.md new file mode 100644 index 0000000..e313d38 --- /dev/null +++ b/uni_modules/mp-html/changelog.md @@ -0,0 +1,129 @@ +## v2.4.2(2023-05-14) +1. `A` `editable` 插件支持修改文字颜色 [详细](https://github.com/jin-yufeng/mp-html/issues/254) +2. `F` 修复了 `svg` 中有 `style` 不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/505) +3. `F` 修复了使用旧版编译器可能报错 `Bad attr nodes` 的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/472) +4. `F` 修复了 `app` 端可能出现无法读取 `lazyLoad` 的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/513) +5. `F` 修复了 `editable` 插件在点击换图时未拼接 `domain` 的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/497) by [@TwoKe945](https://github.com/TwoKe945) +6. `F` 修复了 `latex` 插件部分情况下不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/515) +7. `F` 修复了 `editable` 插件点击音视频时其他标签框不消失的问题 +## v2.4.1(2022-12-25) +1. `F` 修复了没有图片时 `ready` 事件可能不触发的问题 +2. `F` 修复了加载过程中可能出现 `Root label not found` 错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/470) +3. `F` 修复了 `audio` 插件退出页面可能会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/457) +4. `F` 修复了 `vue3` 运行到 `app` 在 `HBuilder X 3.6.10` 以上报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/480) +5. `F` 修复了 `nvue` 端链接中包含 `%22` 时可能无法显示的问题 +6. `F` 修复了 `vue3` 使用 `highlight` 插件可能报错的问题 +## v2.4.0(2022-08-27) +1. `A` 增加了 [setPlaybackRate](https://jin-yufeng.gitee.io/mp-html/#/advanced/api#setPlaybackRate) 的 `api`,可以设置音视频的播放速率 [详细](https://github.com/jin-yufeng/mp-html/issues/452) +2. `A` 示例小程序代码开源 [详细](https://github.com/jin-yufeng/mp-html-demo) +3. `U` 优化 `ready` 事件触发时机,未设置懒加载的情况下基本可以准确触发 [详细](https://github.com/jin-yufeng/mp-html/issues/195) +4. `U` `highlight` 插件在编辑状态下不进行高亮处理,便于编辑 +5. `F` 修复了 `flex` 布局下图片大小可能不正确的问题 +6. `F` 修复了 `selectable` 属性没有设置 `force` 也可能出现渲染异常的问题 +7. `F` 修复了表格中的图片大小可能不正确的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/448) +8. `F` 修复了含有合并单元格的表格可能无法设置竖直对齐的问题 +9. `F` 修复了 `editable` 插件在 `scroll-view` 中使用时工具条位置可能不正确的问题 +10. `F` 修复了 `vue3` 使用 [search](advanced/plugin#search) 插件可能导致错误换行的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/449) +## v2.3.2(2022-08-13) +1. `A` 增加 [latex](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#latex) 插件,可以渲染数学公式 [详细](https://github.com/jin-yufeng/mp-html/pull/447) by [@Zeng-J](https://github.com/Zeng-J) +2. `U` 优化根节点下有很多标签的长内容渲染速度 +3. `U` `highlight` 插件适配 `lang-xxx` 格式 +4. `F` 修复了 `table` 标签设置 `border` 属性后可能无法修改边框样式的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/439) by [@zouxingjie](https://github.com/zouxingjie) +5. `F` 修复了 `editable` 插件输入连续空格无效的问题 +6. `F` 修复了 `vue3` 图片设置 `inline` 会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/438) +7. `F` 修复了 `vue3` 使用 `table` 可能报错的问题 +## v2.3.1(2022-05-20) +1. `U` `app` 端支持使用本地图片 +2. `U` 优化了微信小程序 `selectable` 属性在 `ios` 端的处理 [详细](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable) +3. `F` 修复了 `editable` 插件不在顶部时 `tooltip` 位置可能错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/430) +4. `F` 修复了 `vue3` 运行到微信小程序可能报错丢失内容的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/414) +5. `F` 修复了 `vue3` 部分标签可能被错误换行的问题 +6. `F` 修复了 `editable` 插件 `app` 端插入视频无法预览的问题 +## v2.3.0(2022-04-01) +1. `A` 增加了 `play` 事件,音视频播放时触发,可用于与页面其他音视频进行互斥播放 [详细](basic/event#play) +2. `U` `show-img-menu` 属性支持控制预览时是否长按弹出菜单 +3. `U` 优化 `wxs` 处理,提高渲染性能 [详细](https://developers.weixin.qq.com/community/develop/article/doc/0006cc2b204740f601bd43fa25a413) +4. `U` `video` 标签支持 `object-fit` 属性 +5. `U` 增加支持一些常用实体编码 [详细](https://github.com/jin-yufeng/mp-html/issues/418) +6. `F` 修复了图片仅设置高度可能不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/410) +7. `F` 修复了 `video` 标签高度设置为 `auto` 不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/411) +8. `F` 修复了使用 `grid` 布局时可能样式错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/413) +9. `F` 修复了含有合并单元格的表格部分情况下显示异常的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/417) +10. `F` 修复了 `editable` 插件连续插入内容时顺序不正确的问题 +11. `F` 修复了 `uni-app` 包 `vue3` 使用 `audio` 插件报错的问题 +12. `F` 修复了 `uni-app` 包 `highlight` 插件使用自定义的 `prism.min.js` 报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/416) +## v2.2.2(2022-02-26) +1. `A` 增加了 [pauseMedia](https://jin-yufeng.gitee.io/mp-html/#/advanced/api#pauseMedia) 的 `api`,可用于暂停播放音视频 [详细](https://github.com/jin-yufeng/mp-html/issues/317) +2. `U` 优化了长内容的加载速度 +3. `U` 适配 `vue3` [#389](https://github.com/jin-yufeng/mp-html/issues/389)、[#398](https://github.com/jin-yufeng/mp-html/pull/398) by [@zhouhuafei](https://github.com/zhouhuafei)、[#400](https://github.com/jin-yufeng/mp-html/issues/400) +4. `F` 修复了小程序端图片高度设置为百分比时可能不显示的问题 +5. `F` 修复了 `highlight` 插件部分情况下可能显示不完整的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/403) +## v2.2.1(2021-12-24) +1. `A` `editable` 插件增加上下移动标签功能 +2. `U` `editable` 插件支持在文本中间光标处插入内容 +3. `F` 修复了 `nvue` 端设置 `margin` 后可能导致高度不正确的问题 +4. `F` 修复了 `highlight` 插件使用压缩版的 `prism.css` 可能导致背景失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/367) +5. `F` 修复了编辑状态下使用 `emoji` 插件内容为空时可能报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/371) +6. `F` 修复了使用 `editable` 插件后将 `selectable` 属性设置为 `force` 不生效的问题 +## v2.2.0(2021-10-12) +1. `A` 增加 `customElements` 配置项,便于添加自定义功能性标签 [详细](https://github.com/jin-yufeng/mp-html/issues/350) +2. `A` `editable` 插件增加切换音视频自动播放状态的功能 [详细](https://github.com/jin-yufeng/mp-html/pull/341) by [@leeseett](https://github.com/leeseett) +3. `A` `editable` 插件删除媒体标签时触发 `remove` 事件,便于删除已上传的文件 +4. `U` `editable` 插件 `insertImg` 方法支持同时插入多张图片 [详细](https://github.com/jin-yufeng/mp-html/issues/342) +5. `U` `editable` 插入图片和音视频时支持拼接 `domian` 主域名 +6. `F` 修复了内部链接参数中包含 `://` 时被认为是外部链接的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/356) +7. `F` 修复了部分 `svg` 标签名或属性名大小写不正确时不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/351) +8. `F` 修复了 `nvue` 页面运行到非 `app` 平台时可能样式错误的问题 +## v2.1.5(2021-08-13) +1. `A` 增加支持标签的 `dir` 属性 +2. `F` 修复了 `ruby` 标签文字与拼音没有居中对齐的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/325) +3. `F` 修复了音视频标签内有 `a` 标签时可能无法播放的问题 +4. `F` 修复了 `externStyle` 中的 `class` 名包含下划线或数字时可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326) +5. `F` 修复了 `h5` 端引入 `externStyle` 可能不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326) +## v2.1.4(2021-07-14) +1. `F` 修复了 `rt` 标签无法设置样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/318) +2. `F` 修复了表格中有单元格同时合并行和列时可能显示不正确的问题 +3. `F` 修复了 `app` 端无法关闭图片长按菜单的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/322) +4. `F` 修复了 `editable` 插件只能添加图片链接不能修改的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/312) by [@leeseett](https://github.com/leeseett) +## v2.1.3(2021-06-12) +1. `A` `editable` 插件增加 `insertTable` 方法 +2. `U` `editable` 插件支持编辑表格中的空白单元格 [详细](https://github.com/jin-yufeng/mp-html/issues/310) +3. `F` 修复了 `externStyle` 中使用伪类可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/298) +4. `F` 修复了多个组件同时使用时 `tag-style` 属性时可能互相影响的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/305) by [@woodguoyu](https://github.com/woodguoyu) +5. `F` 修复了包含 `linearGradient` 的 `svg` 可能无法显示的问题 +6. `F` 修复了编译到头条小程序时可能报错的问题 +7. `F` 修复了 `nvue` 端不触发 `click` 事件的问题 +8. `F` 修复了 `editable` 插件尾部插入时无法撤销的问题 +9. `F` 修复了 `editable` 插件的 `insertHtml` 方法只能在末尾插入的问题 +10. `F` 修复了 `editable` 插件插入音频不显示的问题 +## v2.1.2(2021-04-24) +1. `A` 增加了 [img-cache](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#img-cache) 插件,可以在 `app` 端缓存图片 [详细](https://github.com/jin-yufeng/mp-html/issues/292) by [@PentaTea](https://github.com/PentaTea) +2. `U` 支持通过 `container-style` 属性设置 `white-space` 来保留连续空格和换行符 [详细](https://jin-yufeng.gitee.io/mp-html/#/question/faq#space) +3. `U` 代码风格符合 [standard](https://standardjs.com) 标准 +4. `U` `editable` 插件编辑状态下支持预览视频 [详细](https://github.com/jin-yufeng/mp-html/issues/286) +5. `F` 修复了 `svg` 标签内嵌 `svg` 时无法显示的问题 +6. `F` 修复了编译到支付宝和头条小程序时部分区域不可复制的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/291) +## v2.1.1(2021-04-09) +1. 修复了对 `p` 标签设置 `tag-style` 可能不生效的问题 +2. 修复了 `svg` 标签中的文本无法显示的问题 +3. 修复了使用 `editable` 插件编辑表格时可能报错的问题 +4. 修复了使用 `highlight` 插件运行到头条小程序时可能没有样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/280) +5. 修复了使用 `editable` 插件 `editable` 属性为 `false` 时会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/284) +6. 修复了 `style` 插件连续子选择器失效的问题 +7. 修复了 `editable` 插件无法修改图片和字体大小的问题 +## v2.1.0.2(2021-03-21) +修复了 `nvue` 端使用可能报错的问题 +## v2.1.0(2021-03-20) +1. `A` 增加了 [container-style](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#container-style) 属性 [详细](https://gitee.com/jin-yufeng/mp-html/pulls/1) +2. `A` 增加支持 `strike` 标签 +3. `A` `editable` 插件增加 `placeholder` 属性 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable) +4. `A` `editable` 插件增加 `insertHtml` 方法 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable) +5. `U` 外部样式支持标签名选择器 [详细](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart#setting) +6. `F` 修复了 `nvue` 端部分情况下可能不显示的问题 +## v2.0.5(2021-03-12) +1. `U` [linktap](https://jin-yufeng.gitee.io/mp-html/#/basic/event#linktap) 事件增加返回内部文本内容 `innerText` [详细](https://github.com/jin-yufeng/mp-html/issues/271) +2. `U` [selectable](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable) 属性设置为 `force` 时能够在微信 `iOS` 端生效(文本块会变成 `inline-block`) [详细](https://github.com/jin-yufeng/mp-html/issues/267) +3. `F` 修复了部分情况下竖向无法滚动的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/182) +4. `F` 修复了多次修改富文本数据时部分内容可能不显示的问题 +5. `F` 修复了 [腾讯视频](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#txv-video) 插件可能无法播放的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/265) +6. `F` 修复了 [highlight](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#highlight) 插件没有设置高亮语言时没有应用默认样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/276) by [@fuzui](https://github.com/fuzui) diff --git a/uni_modules/mp-html/components/mp-html/mp-html.vue b/uni_modules/mp-html/components/mp-html/mp-html.vue new file mode 100644 index 0000000..d4cad07 --- /dev/null +++ b/uni_modules/mp-html/components/mp-html/mp-html.vue @@ -0,0 +1,498 @@ + + + + + diff --git a/uni_modules/mp-html/components/mp-html/node/node.vue b/uni_modules/mp-html/components/mp-html/node/node.vue new file mode 100644 index 0000000..c8fa062 --- /dev/null +++ b/uni_modules/mp-html/components/mp-html/node/node.vue @@ -0,0 +1,576 @@ +